From e50ce5c67a84191be1c6fb503d86c78944afa12b Mon Sep 17 00:00:00 2001
From: sam <sam@92316355-f0b4-4df1-b90c-862c8a59935f>
Date: Sat, 16 Aug 2008 00:53:50 +0000
Subject: [PATCH]   * color.c: implement pipi_brightness() and pipi_contrast().
   * pipi.c: add --brightness and --contrast.

git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@2725 92316355-f0b4-4df1-b90c-862c8a59935f
---
 pipi/context.c      |  40 +++++++++++
 pipi/filter/color.c | 172 ++++++++++++++++++++++++++++++++++++++++++++
 pipi/paint/tile.c   |   2 +
 pipi/pipi.h         |   2 +
 src/pipi.c          |  16 +++++
 5 files changed, 232 insertions(+)

diff --git a/pipi/context.c b/pipi/context.c
index 3450fb5..80e7562 100644
--- a/pipi/context.c
+++ b/pipi/context.c
@@ -218,6 +218,46 @@ int pipi_command(pipi_context_t *ctx, char const *cmd, ...)
         pipi_free(src);
         ctx->images[ctx->nimages - 1] = dst;
     }
+    else if(!strcmp(cmd, "brightness"))
+    {
+        pipi_image_t *src, *dst;
+        char const *arg;
+        va_list ap;
+        double val;
+
+        if(ctx->nimages < 1)
+            return -1;
+        va_start(ap, cmd);
+        arg = va_arg(ap, char const *);
+        va_end(ap);
+        val = atof(arg);
+        src = ctx->images[ctx->nimages - 1];
+        dst = pipi_brightness(src, val);
+        if(dst == NULL)
+            return -1;
+        pipi_free(src);
+        ctx->images[ctx->nimages - 1] = dst;
+    }
+    else if(!strcmp(cmd, "contrast"))
+    {
+        pipi_image_t *src, *dst;
+        char const *arg;
+        va_list ap;
+        double val;
+
+        if(ctx->nimages < 1)
+            return -1;
+        va_start(ap, cmd);
+        arg = va_arg(ap, char const *);
+        va_end(ap);
+        val = atof(arg);
+        src = ctx->images[ctx->nimages - 1];
+        dst = pipi_contrast(src, val);
+        if(dst == NULL)
+            return -1;
+        pipi_free(src);
+        ctx->images[ctx->nimages - 1] = dst;
+    }
     else if(!strcmp(cmd, "mean"))
     {
         pipi_image_t *dst;
diff --git a/pipi/filter/color.c b/pipi/filter/color.c
index cc16e5e..30806cf 100644
--- a/pipi/filter/color.c
+++ b/pipi/filter/color.c
@@ -27,6 +27,178 @@
 #include "pipi.h"
 #include "pipi_internals.h"
 
+pipi_image_t *pipi_brightness(pipi_image_t *src, double val)
+{
+    pipi_image_t *dst;
+    pipi_pixels_t *srcp, *dstp;
+    float *srcdata, *dstdata;
+    int x, y, w, h, gray;
+
+    w = src->w;
+    h = src->h;
+
+    gray = (src->last_modified == PIPI_PIXELS_Y_F);
+
+    srcp = gray ? pipi_getpixels(src, PIPI_PIXELS_Y_F)
+                : pipi_getpixels(src, PIPI_PIXELS_RGBA_F);
+    srcdata = (float *)srcp->pixels;
+
+    dst = pipi_new(w, h);
+    dstp = gray ? pipi_getpixels(dst, PIPI_PIXELS_Y_F)
+                : pipi_getpixels(dst, PIPI_PIXELS_RGBA_F);
+    dstdata = (float *)dstp->pixels;
+
+    if(val >= 0.0)
+    {
+        for(y = 0; y < h; y++)
+        {
+            for(x = 0; x < w; x++)
+            {
+                if(gray)
+                {
+                    double p = srcdata[y * w + x];
+                    dstdata[y * w + x] = p < 1. - val ? p + val : 1.;
+                }
+                else
+                {
+                    double p;
+                    int d = 4 * (y * w + x);
+
+                    p = srcdata[d];
+                    dstdata[d] = p < 1. - val ? p + val : 1.;
+                    p = srcdata[d + 1];
+                    dstdata[d + 1] = p < 1. - val ? p + val : 1.;
+                    p = srcdata[d + 2];
+                    dstdata[d + 2] = p < 1. - val ? p + val : 1.;
+                    p = srcdata[d + 3];
+                    dstdata[d + 3] = p < 1. - val ? p + val : 1.;
+                }
+            }
+        }
+    }
+    else
+    {
+        for(y = 0; y < h; y++)
+        {
+            for(x = 0; x < w; x++)
+            {
+                if(gray)
+                {
+                    double p = srcdata[y * w + x];
+                    dstdata[y * w + x] = p > -val ? p + val : 0.;
+                }
+                else
+                {
+                    double p;
+                    int d = 4 * (y * w + x);
+
+                    p = srcdata[d];
+                    dstdata[d] = p > -val ? p + val : 0.;
+                    p = srcdata[d + 1];
+                    dstdata[d + 1] = p > -val ? p + val : 0.;
+                    p = srcdata[d + 2];
+                    dstdata[d + 2] = p > -val ? p + val : 0.;
+                    p = srcdata[d + 3];
+                    dstdata[d + 3] = p > -val ? p + val : 0.;
+                }
+            }
+        }
+    }
+
+    return dst;
+}
+
+pipi_image_t *pipi_contrast(pipi_image_t *src, double val)
+{
+    pipi_image_t *dst;
+    pipi_pixels_t *srcp, *dstp;
+    float *srcdata, *dstdata;
+    int x, y, w, h, gray;
+
+    w = src->w;
+    h = src->h;
+
+    gray = (src->last_modified == PIPI_PIXELS_Y_F);
+
+    srcp = gray ? pipi_getpixels(src, PIPI_PIXELS_Y_F)
+                : pipi_getpixels(src, PIPI_PIXELS_RGBA_F);
+    srcdata = (float *)srcp->pixels;
+
+    dst = pipi_new(w, h);
+    dstp = gray ? pipi_getpixels(dst, PIPI_PIXELS_Y_F)
+                : pipi_getpixels(dst, PIPI_PIXELS_RGBA_F);
+    dstdata = (float *)dstp->pixels;
+
+    if(val >= 0.0)
+    {
+        if(val > 0.99999)
+            val = 0.99999;
+
+        val = 1. / (1. - val);
+
+        for(y = 0; y < h; y++)
+        {
+            for(x = 0; x < w; x++)
+            {
+                if(gray)
+                {
+                    double p = (srcdata[y * w + x] - 0.5) * val + 0.5;
+                    dstdata[y * w + x] = p < 0. ? 0. : p > 1. ? 1. : p;
+                }
+                else
+                {
+                    double p;
+                    int d = 4 * (y * w + x);
+
+                    p = (srcdata[d] - 0.5) * val + 0.5;
+                    dstdata[d] = p < 0. ? 0. : p > 1. ? 1. : p;
+                    p = (srcdata[d + 1] - 0.5) * val + 0.5;
+                    dstdata[d + 1] = p < 0. ? 0. : p > 1. ? 1. : p;
+                    p = (srcdata[d + 2] - 0.5) * val + 0.5;
+                    dstdata[d + 2] = p < 0. ? 0. : p > 1. ? 1. : p;
+                    p = (srcdata[d + 3] - 0.5) * val + 0.5;
+                    dstdata[d + 3] = p < 0. ? 0. : p > 1. ? 1. : p;
+                }
+            }
+        }
+    }
+    else
+    {
+        if(val < -1.)
+            val = -1.;
+
+        val = 1. + val;
+
+        for(y = 0; y < h; y++)
+        {
+            for(x = 0; x < w; x++)
+            {
+                if(gray)
+                {
+                    double p = srcdata[y * w + x];
+                    dstdata[y * w + x] = (p - 0.5) * val + 0.5;
+                }
+                else
+                {
+                    double p;
+                    int d = 4 * (y * w + x);
+
+                    p = srcdata[d];
+                    dstdata[d] = (p - 0.5) * val + 0.5;
+                    p = srcdata[d + 1];
+                    dstdata[d + 1] = (p - 0.5) * val + 0.5;
+                    p = srcdata[d + 2];
+                    dstdata[d + 2] = (p - 0.5) * val + 0.5;
+                    p = srcdata[d + 3];
+                    dstdata[d + 3] = (p - 0.5) * val + 0.5;
+                }
+            }
+        }
+    }
+
+    return dst;
+}
+
 pipi_image_t *pipi_invert(pipi_image_t *src)
 {
     pipi_image_t *dst;
diff --git a/pipi/paint/tile.c b/pipi/paint/tile.c
index 52e8538..f47a362 100644
--- a/pipi/paint/tile.c
+++ b/pipi/paint/tile.c
@@ -19,6 +19,8 @@
 #include "config.h"
 #include "common.h"
 
+#include <strings.h>
+
 #include "pipi.h"
 #include "pipi_internals.h"
 
diff --git a/pipi/pipi.h b/pipi/pipi.h
index c0819f0..0517b66 100644
--- a/pipi/pipi.h
+++ b/pipi/pipi.h
@@ -122,6 +122,8 @@ extern pipi_image_t *pipi_gaussian_blur_ext(pipi_image_t *,
                                             float, float, float, float, float);
 extern pipi_image_t *pipi_box_blur(pipi_image_t *, int);
 extern pipi_image_t *pipi_box_blur_ext(pipi_image_t *, int, int);
+extern pipi_image_t *pipi_brightness(pipi_image_t *, double);
+extern pipi_image_t *pipi_contrast(pipi_image_t *, double);
 extern pipi_image_t *pipi_autocontrast(pipi_image_t *);
 extern pipi_image_t *pipi_invert(pipi_image_t *);
 
diff --git a/src/pipi.c b/src/pipi.c
index 9ed9169..c27857b 100644
--- a/src/pipi.c
+++ b/src/pipi.c
@@ -70,6 +70,22 @@ int main(int argc, char *argv[])
             if(pipi_command(ctx, "gray") != 0)
                 return EXIT_FAILURE;
         }
+        else if(!strcmp(argv[0], "--brightness"))
+        {
+            if(argv[1] == NULL)
+                return EXIT_FAILURE;
+            if(pipi_command(ctx, "brightness", argv[1]) != 0)
+                return EXIT_FAILURE;
+            argv++;
+        }
+        else if(!strcmp(argv[0], "--contrast"))
+        {
+            if(argv[1] == NULL)
+                return EXIT_FAILURE;
+            if(pipi_command(ctx, "contrast", argv[1]) != 0)
+                return EXIT_FAILURE;
+            argv++;
+        }
         else if(!strcmp(argv[0], "--autocontrast"))
         {
             if(pipi_command(ctx, "autocontrast") != 0)