added gdImageColorReplace, gdImageColorReplaceArray, and gdImageColorReplaceCallback. (see FS#170)
parent
9225b25e8e
commit
fc32e572cd
113
src/gd.c
113
src/gd.c
|
@ -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)
|
||||
*
|
||||
|
|
5
src/gd.h
5
src/gd.h
|
@ -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);
|
||||
|
|
|
@ -25,6 +25,7 @@ if (BUILD_TEST)
|
|||
gdimagearc
|
||||
gdimagecolorclosest
|
||||
gdimagecolorexact
|
||||
gdimagecolorreplace
|
||||
gdimagecolorresolve
|
||||
gdimagecolordeallocate
|
||||
gdimagecolortransparent
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
CMakeFiles
|
||||
DartTestfile.txt
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
gdimagecolorreplace
|
|
@ -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)
|
|
@ -0,0 +1,3 @@
|
|||
## Process this file with automake to produce Makefile.in -*-Makefile-*-
|
||||
|
||||
EXTRA_DIST = CMakeLists.txt gdimagecolorreplace.c
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue