added gdImageColorReplace, gdImageColorReplaceArray, and gdImageColorReplaceCallback. (see FS#170)

master
tabe 2008-11-16 03:25:33 +00:00
parent 9225b25e8e
commit fc32e572cd
8 changed files with 237 additions and 1 deletions

113
src/gd.c
View File

@ -675,6 +675,119 @@ BGD_DECLARE(void) gdImagePaletteCopy (gdImagePtr to, gdImagePtr from)
}
BGD_DECLARE(int) gdImageColorReplace (gdImagePtr im, int src, int dst)
{
int x, y, n = 0;
if (src == dst) {
return 0;
}
#define REPLACING_LOOP(pixel) do { \
for (y = im->cy1; y <= im->cy2; y++) { \
for (x = im->cx1; x <= im->cx2; x++) { \
if (pixel(im, x, y) == src) { \
gdImageSetPixel(im, x, y, dst); \
n++; \
} \
} \
} \
} while (0)
if (im->trueColor) {
REPLACING_LOOP(gdImageTrueColorPixel);
} else {
REPLACING_LOOP(gdImagePalettePixel);
}
#undef REPLACING_LOOP
return n;
}
BGD_DECLARE(int) gdImageColorReplaceArray (gdImagePtr im, unsigned int len, int *src, int *dst)
{
int x, y, c, n = 0;
unsigned int i;
if (len == 0) {
return 0;
}
if (src == dst) {
return 0;
}
#define REPLACING_LOOP(pixel) do { \
for (y = im->cy1; y <= im->cy2; y++) { \
for (x = im->cx1; x <= im->cx2; x++) { \
c = pixel(im, x, y); \
for (i = 0; i < len; i++) { \
if (c == src[i] && c != dst[i]) { \
gdImageSetPixel(im, x, y, dst[i]); \
n++; \
break; \
} \
} \
} \
} \
} while (0)
if (im->trueColor) {
REPLACING_LOOP(gdImageTrueColorPixel);
} else {
REPLACING_LOOP(gdImagePalettePixel);
}
#undef REPLACING_LOOP
return n;
}
BGD_DECLARE(int) gdImageColorReplaceCallback (gdImagePtr im, int (*callback)(gdImagePtr imx, int src))
{
int x, y, c, d, n = 0;
if (!callback) {
return 0;
}
if (im->trueColor) {
for (y = im->cy1; y <= im->cy2; y++) {
for (x = im->cx1; x <= im->cx2; x++) {
c = gdImageTrueColorPixel(im, x, y);
if ( (d = callback(im, c)) != c) {
gdImageSetPixel(im, x, y, d);
n++;
}
}
}
} else { /* palette */
int *sarr, *darr;
unsigned int k, len = 0;
sarr = (int *)gdCalloc(im->colorsTotal, sizeof(int));
if (!sarr) {
return -1;
}
for (c = 0; c < im->colorsTotal; c++) {
if (!im->open[c]) {
sarr[len++] = c;
}
}
darr = (int *)gdCalloc(len, sizeof(int));
if (!darr) {
gdFree(sarr);
return -1;
}
for (k = 0; k < len; k++) {
darr[k] = callback(im, sarr[k]);
}
n = gdImageColorReplaceArray(im, k, sarr, darr);
gdFree(darr);
gdFree(sarr);
}
return n;
}
/* 2.0.10: before the drawing routines, some code to clip points that are
* outside the drawing window. Nick Atty (nick@canalplan.org.uk)
*

View File

@ -585,6 +585,11 @@ BGD_DECLARE(void) gdImageTrueColorToPalette (gdImagePtr im, int ditherFlag,
BGD_DECLARE(void) gdImageColorTransparent (gdImagePtr im, int color);
BGD_DECLARE(void) gdImagePaletteCopy (gdImagePtr dst, gdImagePtr src);
BGD_DECLARE(int) gdImageColorReplace(gdImagePtr im, int src, int dst);
BGD_DECLARE(int) gdImageColorReplaceArray(gdImagePtr im, unsigned int len, int *src, int *dst);
BGD_DECLARE(int) gdImageColorReplaceCallback(gdImagePtr im, int (*callback)(gdImagePtr imx, int src));
BGD_DECLARE(void) gdImageGif (gdImagePtr im, FILE * out);
BGD_DECLARE(void) gdImagePng (gdImagePtr im, FILE * out);
BGD_DECLARE(void) gdImagePngCtx (gdImagePtr im, gdIOCtx * out);

View File

@ -25,6 +25,7 @@ if (BUILD_TEST)
gdimagearc
gdimagecolorclosest
gdimagecolorexact
gdimagecolorreplace
gdimagecolorresolve
gdimagecolordeallocate
gdimagecolortransparent

View File

@ -1,7 +1,7 @@
## Process this file with automake to produce Makefile.in -*-Makefile-*-
AUTOMAKE_OPTIONS = foreign 1.7
SUBDIRS = gd2 gdimagecolordeallocate gdimagecolortransparent gdimagefill gdimagefilltoborder gdtest jpeg gdimagearc gdimagecolorexact gdimagecopy gdimagefilledellipse gdimageline gdtiled freetype gdimagecolorclosest gdimagecolorresolve gdimagecopyrotated gdimagefilledrectangle gdimagerectangle gif png xpm
SUBDIRS = gd2 gdimagecolordeallocate gdimagecolortransparent gdimagefill gdimagefilltoborder gdtest jpeg gdimagearc gdimagecolorexact gdimagecopy gdimagefilledellipse gdimageline gdtiled freetype gdimagecolorclosest gdimagecolorreplace gdimagecolorresolve gdimagecopyrotated gdimagefilledrectangle gdimagerectangle gif png xpm
EXTRA_DIST = CMakeLists.txt

View File

@ -0,0 +1,5 @@
CMakeFiles
DartTestfile.txt
Makefile
cmake_install.cmake
gdimagecolorreplace

View File

@ -0,0 +1,9 @@
SET(TESTS_FILES
gdimagecolorreplace
)
FOREACH(test_name ${TESTS_FILES})
add_executable(${test_name} "${test_name}.c")
target_link_libraries (${test_name} gdTest ${GDTESTS_TARGET_LINK})
ADD_TEST("${test_name}" ${EXECUTABLE_OUTPUT_PATH}/${test_name})
ENDFOREACH(test_name)

View File

@ -0,0 +1,3 @@
## Process this file with automake to produce Makefile.in -*-Makefile-*-
EXTRA_DIST = CMakeLists.txt gdimagecolorreplace.c

View File

@ -0,0 +1,100 @@
#include <gd.h>
#include <stdio.h>
#include "gdtest.h"
static int callback(gdImagePtr im, int src)
{
int r, g, b;
r = gdImageRed(im, src);
g = gdImageGreen(im, src);
b = gdImageBlue(im, src);
if (b & 0xFF) {
return gdImageColorResolve(im, 0x0F & r, 0x0F & g, 0);
} else {
return -1;
}
}
static void run_tests(gdImagePtr im, int *error)
{
int white, black, c, d;
int src[2], dst[2];
int n;
#define CHECK_VALUE(n, expected) do { \
if (gdTestAssert((n) == (expected)) != 1) { \
printf("%d is expected, but %d\n", expected, n); \
*error = -1; \
} \
} while (0)
#define CHECK_PIXEL(x, y, expected) do { \
gdImageSetClip(im, 0, 0, 4, 4); \
c = gdImageGetPixel(im, (x), (y)); \
if (gdTestAssert(c == (expected)) != 1) { \
printf("%d is expected, but %d\n", expected, c); \
*error = -1; \
} \
} while (0)
white = gdImageColorAllocate(im, 0xFF, 0xFF, 0xFF);
black = gdImageColorAllocate(im, 0, 0, 0);
c = gdImageColorAllocate(im, 0xFF, 0, 0xFF);
gdImageFilledRectangle(im, 0, 0, 4, 4, white);
gdImageFilledRectangle(im, 0, 0, 3, 3, black);
n = gdImageColorReplace(im, white, c);
CHECK_VALUE(n, 9);
CHECK_PIXEL(0, 0, black);
CHECK_PIXEL(2, 3, black);
CHECK_PIXEL(4, 4, c);
gdImageSetClip(im, 1, 1, 3, 3);
n = gdImageColorReplace(im, black, c);
CHECK_VALUE(n, 9);
CHECK_PIXEL(0, 0, black);
CHECK_PIXEL(2, 3, c);
src[0] = black;
src[1] = c;
dst[0] = c;
dst[1] = white;
gdImageSetClip(im, 0, 0, 4, 4);
n = gdImageColorReplaceArray(im, 2, src, dst);
CHECK_VALUE(n, 25);
CHECK_PIXEL(0, 0, c);
CHECK_PIXEL(2, 3, white);
CHECK_PIXEL(4, 4, white);
gdImageSetClip(im, 1, 1, 4, 4);
n = gdImageColorReplaceCallback(im, callback);
CHECK_VALUE(n, 16);
CHECK_PIXEL(0, 0, c);
CHECK_PIXEL(0, 4, white);
d = gdImageColorExact(im, 0x0F, 0x0F, 0);
if (gdTestAssert(d > 0) != 1) {
*error = -1;
}
CHECK_PIXEL(2, 3, d);
CHECK_PIXEL(4, 4, d);
#undef CHECK_VALUE
#undef CHECK_PIXEL
}
int main()
{
gdImagePtr im;
int error = 0;
/* true color */
im = gdImageCreateTrueColor(5, 5);
run_tests(im, &error);
gdImageDestroy(im);
/* palette */
im = gdImageCreate(5, 5);
run_tests(im, &error);
gdImageDestroy(im);
return error;
}