From 3dba2d0198332de71c40c900ac58c1d7e4d2048b Mon Sep 17 00:00:00 2001
From: sam <sam@92316355-f0b4-4df1-b90c-862c8a59935f>
Date: Thu, 28 Aug 2008 17:19:30 +0000
Subject: [PATCH]   * Add pipi_order, to transform any image into an ordered
 dithering matrix.

git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@2790 92316355-f0b4-4df1-b90c-862c8a59935f
---
 pipi/context.c        |  9 +++++++
 pipi/dither/ordered.c | 57 +++++++++++++++++++++++++++++++++++++++++++
 pipi/pipi.h           |  2 ++
 src/pipi.c            |  5 ++++
 4 files changed, 73 insertions(+)

diff --git a/pipi/context.c b/pipi/context.c
index f2053ea..6b38f5d 100644
--- a/pipi/context.c
+++ b/pipi/context.c
@@ -391,6 +391,15 @@ int pipi_command(pipi_context_t *ctx, char const *cmd, ...)
         ctx->images[ctx->nimages - 1] = pipi_rotate270(tmp);
         pipi_free(tmp);
     }
+    else if(!strcmp(cmd, "order"))
+    {
+        pipi_image_t *tmp;
+        if(ctx->nimages < 1)
+            return -1;
+        tmp = ctx->images[ctx->nimages - 1];
+        ctx->images[ctx->nimages - 1] = pipi_order(tmp);
+        pipi_free(tmp);
+    }
     else if(!strcmp(cmd, "split"))
     {
         pipi_image_t *src;
diff --git a/pipi/dither/ordered.c b/pipi/dither/ordered.c
index 781d6b3..0fc7c14 100644
--- a/pipi/dither/ordered.c
+++ b/pipi/dither/ordered.c
@@ -19,6 +19,8 @@
 #include "config.h"
 #include "common.h"
 
+#include <stdlib.h>
+
 #include "pipi.h"
 #include "pipi_internals.h"
 
@@ -56,3 +58,58 @@ pipi_image_t *pipi_dither_ordered(pipi_image_t *img, pipi_image_t *kernel)
     return dst;
 }
 
+typedef struct
+{
+    int x, y;
+    double val;
+}
+dot_t;
+
+static int cmpdot(const void *p1, const void *p2)
+{
+    return ((dot_t const *)p1)->val > ((dot_t const *)p2)->val;
+}
+
+pipi_image_t *pipi_order(pipi_image_t *src)
+{
+    double epsilon;
+    pipi_image_t *dst;
+    pipi_pixels_t *dstp, *srcp;
+    float *dstdata, *srcdata;
+    dot_t *circle;
+    int x, y, w, h, n;
+
+    w = src->w;
+    h = src->h;
+    epsilon = 1. / (w * h + 1);
+
+    srcp = pipi_getpixels(src, PIPI_PIXELS_Y_F);
+    srcdata = (float *)srcp->pixels;
+
+    dst = pipi_new(w, h);
+    dstp = pipi_getpixels(dst, PIPI_PIXELS_Y_F);
+    dstdata = (float *)dstp->pixels;
+
+    circle = malloc(w * h * sizeof(dot_t));
+
+    for(y = 0; y < h; y++)
+        for(x = 0; x < w; x++)
+        {
+            circle[y * w + x].x = x;
+            circle[y * w + x].y = y;
+            circle[y * w + x].val = srcdata[y * w + x];
+        }
+    qsort(circle, w * h, sizeof(dot_t), cmpdot);
+
+    for(n = 0; n < w * h; n++)
+    {
+        x = circle[n].x;
+        y = circle[n].y;
+        dstdata[y * w + x] = (float)(n + 1) * epsilon;
+    }
+
+    free(circle);
+
+    return dst;
+}
+
diff --git a/pipi/pipi.h b/pipi/pipi.h
index 49f970d..d9ada04 100644
--- a/pipi/pipi.h
+++ b/pipi/pipi.h
@@ -150,6 +150,8 @@ extern pipi_image_t *pipi_median_ext(pipi_image_t *, int, int);
 extern pipi_image_t *pipi_dilate(pipi_image_t *);
 extern pipi_image_t *pipi_erode(pipi_image_t *);
 
+extern pipi_image_t *pipi_order(pipi_image_t *);
+
 extern pipi_image_t *pipi_tile(pipi_image_t *, int, int);
 extern int pipi_flood_fill(pipi_image_t *,
                            int, int, float, float, float, float);
diff --git a/src/pipi.c b/src/pipi.c
index 0f55deb..230744c 100644
--- a/src/pipi.c
+++ b/src/pipi.c
@@ -115,6 +115,11 @@ int main(int argc, char *argv[])
             if(pipi_command(ctx, "autocontrast") != 0)
                 return EXIT_FAILURE;
         }
+        else if(!strcmp(argv[0], "--order"))
+        {
+            if(pipi_command(ctx, "order") != 0)
+                return EXIT_FAILURE;
+        }
         else if(!strcmp(argv[0], "--hflip"))
         {
             if(pipi_command(ctx, "hflip") != 0)