From da84205cde20a5a5101cfb0237e2b0bab83dbf21 Mon Sep 17 00:00:00 2001 From: sam Date: Wed, 13 Aug 2008 20:26:11 +0000 Subject: [PATCH] * subadd.c: add pipi_sub() and pipi_add() as another way to combine two images. git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@2708 92316355-f0b4-4df1-b90c-862c8a59935f --- pipi/Makefile.am | 3 +- pipi/combine/subadd.c | 122 ++++++++++++++++++++++++++++++++++++++++++ pipi/context.c | 30 +++++++++++ pipi/pipi.h | 2 + src/pipi.c | 10 ++++ 5 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 pipi/combine/subadd.c diff --git a/pipi/Makefile.am b/pipi/Makefile.am index 621135d..c0a8450 100644 --- a/pipi/Makefile.am +++ b/pipi/Makefile.am @@ -41,7 +41,8 @@ codec_sources = # Submodules combine_sources = \ combine/mean.c \ - combine/minmax.c + combine/minmax.c \ + combine/subadd.c filter_sources = \ filter/autocontrast.c \ diff --git a/pipi/combine/subadd.c b/pipi/combine/subadd.c new file mode 100644 index 0000000..5496535 --- /dev/null +++ b/pipi/combine/subadd.c @@ -0,0 +1,122 @@ +/* + * libpipi Proper image processing implementation library + * Copyright (c) 2004-2008 Sam Hocevar + * All Rights Reserved + * + * $Id$ + * + * This library is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + */ + +/* + * subadd.c: sub and add computation functions + */ + +#include "config.h" +#include "common.h" + +#include "pipi.h" +#include "pipi_internals.h" + +pipi_image_t *pipi_sub(pipi_image_t *img1, pipi_image_t *img2) +{ + pipi_image_t *dst; + pipi_pixels_t *img1p, *img2p, *dstp; + float *img1data, *img2data, *dstdata; + int x, y, w, h; + + if(img1->w != img2->w || img1->h != img2->h) + return NULL; + + w = img1->w; + h = img1->h; + + dst = pipi_new(w, h); + dstp = pipi_getpixels(dst, PIPI_PIXELS_RGBA_F); + dstdata = (float *)dstp->pixels; + + img1p = pipi_getpixels(img1, PIPI_PIXELS_RGBA_F); + img1data = (float *)img1p->pixels; + img2p = pipi_getpixels(img2, PIPI_PIXELS_RGBA_F); + img2data = (float *)img2p->pixels; + + for(y = 0; y < h; y++) + { + for(x = 0; x < w; x++) + { + float p, q; + + p = img1data[4 * (y * w + x)]; + q = img2data[4 * (y * w + x)]; + dstdata[4 * (y * w + x)] = p < q ? 0 : p - q; + + p = img1data[4 * (y * w + x) + 1]; + q = img2data[4 * (y * w + x) + 1]; + dstdata[4 * (y * w + x) + 1] = p < q ? 0 : p - q; + + p = img1data[4 * (y * w + x) + 2]; + q = img2data[4 * (y * w + x) + 2]; + dstdata[4 * (y * w + x) + 2] = p < q ? 0 : p - q; + + p = img1data[4 * (y * w + x) + 3]; + q = img2data[4 * (y * w + x) + 3]; + dstdata[4 * (y * w + x) + 3] = p < q ? 0 : p - q; + } + } + + return dst; +} + +pipi_image_t *pipi_add(pipi_image_t *img1, pipi_image_t *img2) +{ + pipi_image_t *dst; + pipi_pixels_t *img1p, *img2p, *dstp; + float *img1data, *img2data, *dstdata; + int x, y, w, h; + + if(img1->w != img2->w || img1->h != img2->h) + return NULL; + + w = img1->w; + h = img1->h; + + dst = pipi_new(w, h); + dstp = pipi_getpixels(dst, PIPI_PIXELS_RGBA_F); + dstdata = (float *)dstp->pixels; + + img1p = pipi_getpixels(img1, PIPI_PIXELS_RGBA_F); + img1data = (float *)img1p->pixels; + img2p = pipi_getpixels(img2, PIPI_PIXELS_RGBA_F); + img2data = (float *)img2p->pixels; + + for(y = 0; y < h; y++) + { + for(x = 0; x < w; x++) + { + float p, q; + + p = img1data[4 * (y * w + x)]; + q = img2data[4 * (y * w + x)]; + dstdata[4 * (y * w + x)] = (p + q < 1.) ? p + q : 1.; + + p = img1data[4 * (y * w + x) + 1]; + q = img2data[4 * (y * w + x) + 1]; + dstdata[4 * (y * w + x) + 1] = (p + q < 1.) ? p + q : 1.; + + p = img1data[4 * (y * w + x) + 2]; + q = img2data[4 * (y * w + x) + 2]; + dstdata[4 * (y * w + x) + 2] = (p + q < 1.) ? p + q : 1.; + + p = img1data[4 * (y * w + x) + 3]; + q = img2data[4 * (y * w + x) + 3]; + dstdata[4 * (y * w + x) + 3] = (p + q < 1.) ? p + q : 1.; + } + } + + return dst; +} + diff --git a/pipi/context.c b/pipi/context.c index 7e273a1..e822f1a 100644 --- a/pipi/context.c +++ b/pipi/context.c @@ -146,6 +146,36 @@ int pipi_command(pipi_context_t *ctx, char const *cmd, ...) ctx->images[ctx->nimages - 2] = dst; ctx->nimages--; } + else if(!strcmp(cmd, "sub")) + { + pipi_image_t *dst; + + if(ctx->nimages < 2) + return -1; + dst = pipi_sub(ctx->images[ctx->nimages - 2], + ctx->images[ctx->nimages - 1]); + if(dst == NULL) + return -1; + pipi_free(ctx->images[ctx->nimages - 2]); + pipi_free(ctx->images[ctx->nimages - 1]); + ctx->images[ctx->nimages - 2] = dst; + ctx->nimages--; + } + else if(!strcmp(cmd, "add")) + { + pipi_image_t *dst; + + if(ctx->nimages < 2) + return -1; + dst = pipi_add(ctx->images[ctx->nimages - 2], + ctx->images[ctx->nimages - 1]); + if(dst == NULL) + return -1; + pipi_free(ctx->images[ctx->nimages - 2]); + pipi_free(ctx->images[ctx->nimages - 1]); + ctx->images[ctx->nimages - 2] = dst; + ctx->nimages--; + } else if(!strcmp(cmd, "min")) { pipi_image_t *dst; diff --git a/pipi/pipi.h b/pipi/pipi.h index a9ccc91..7f5a375 100644 --- a/pipi/pipi.h +++ b/pipi/pipi.h @@ -88,6 +88,8 @@ extern pipi_image_t *pipi_resize(pipi_image_t *, int, int); extern pipi_image_t *pipi_mean(pipi_image_t *, pipi_image_t *); extern pipi_image_t *pipi_min(pipi_image_t *, pipi_image_t *); extern pipi_image_t *pipi_max(pipi_image_t *, pipi_image_t *); +extern pipi_image_t *pipi_sub(pipi_image_t *, pipi_image_t *); +extern pipi_image_t *pipi_add(pipi_image_t *, pipi_image_t *); extern pipi_image_t *pipi_convolution(pipi_image_t *, int, int, double[]); extern pipi_image_t *pipi_gaussian_blur(pipi_image_t *, float); diff --git a/src/pipi.c b/src/pipi.c index 26e22a6..d2463dd 100644 --- a/src/pipi.c +++ b/src/pipi.c @@ -66,6 +66,16 @@ int main(int argc, char *argv[]) if(pipi_command(ctx, "max") != 0) return EXIT_FAILURE; } + else if(!strcmp(argv[0], "--sub")) + { + if(pipi_command(ctx, "sub") != 0) + return EXIT_FAILURE; + } + else if(!strcmp(argv[0], "--add")) + { + if(pipi_command(ctx, "add") != 0) + return EXIT_FAILURE; + } else if(!strcmp(argv[0], "--output") || !strcmp(argv[0], "-o")) { if(argv[1] == NULL)