added gdImageColorReplaceThreshold. (see FS#170)
- added gd_color.[ch] for internal usemaster
parent
2b567ef37e
commit
b14559beb7
|
@ -3,6 +3,8 @@ SET (LIBGD_SRC_FILES
|
|||
gd.c
|
||||
gdfx.c
|
||||
gdfx.h
|
||||
gd_color.c
|
||||
gd_color.h
|
||||
gd_color_map.c
|
||||
gd_color_map.h
|
||||
gd_crop.c
|
||||
|
|
|
@ -13,7 +13,7 @@ include_HEADERS = gd.h gdfx.h gd_io.h gdcache.h gdfontg.h gdfontl.h gdfontmb.h g
|
|||
|
||||
lib_LTLIBRARIES = libgd.la
|
||||
|
||||
libgd_la_SOURCES = gd.c gd_color_map.c gd_transform.c gdfx.c gd_security.c gd_gd.c gd_gd2.c gd_io.c gd_io_dp.c gd_gif_in.c gd_gif_out.c gd_io_file.c gd_io_ss.c gd_jpeg.c gd_png.c gd_ss.c gd_topal.c gd_wbmp.c gdcache.c gdfontg.c gdfontl.c gdfontmb.c gdfonts.c gdfontt.c gdft.c gdhelpers.c gdhelpers.h gdkanji.c gdtables.c gdxpm.c jisx0208.h wbmp.c wbmp.h
|
||||
libgd_la_SOURCES = gd.c gd_color.c gd_color_map.c gd_transform.c gdfx.c gd_security.c gd_gd.c gd_gd2.c gd_io.c gd_io_dp.c gd_gif_in.c gd_gif_out.c gd_io_file.c gd_io_ss.c gd_jpeg.c gd_png.c gd_ss.c gd_topal.c gd_wbmp.c gdcache.c gdfontg.c gdfontl.c gdfontmb.c gdfonts.c gdfontt.c gdft.c gdhelpers.c gdhelpers.h gdkanji.c gdtables.c gdxpm.c jisx0208.h wbmp.c wbmp.h
|
||||
|
||||
libgd_la_LDFLAGS = -version-info 2:0:0 $(XTRA_LDFLAGS)
|
||||
|
||||
|
|
32
src/gd.c
32
src/gd.c
|
@ -10,6 +10,7 @@
|
|||
/* 2.03: don't include zlib here or we can't build without PNG */
|
||||
#include "gd.h"
|
||||
#include "gdhelpers.h"
|
||||
#include "gd_color.h"
|
||||
|
||||
/* 2.0.12: this now checks the clipping rectangle */
|
||||
#define gdImageBoundsSafeMacro(im, x, y) (!((((y) < (im)->cy1) || ((y) > (im)->cy2)) || (((x) < (im)->cx1) || ((x) > (im)->cx2))))
|
||||
|
@ -706,6 +707,37 @@ BGD_DECLARE(int) gdImageColorReplace (gdImagePtr im, int src, int dst)
|
|||
return n;
|
||||
}
|
||||
|
||||
BGD_DECLARE(int) gdImageColorReplaceThreshold (gdImagePtr im, int src, int dst, float threshold)
|
||||
{
|
||||
register int x, y;
|
||||
int 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 (gdColorMatch(im, src, pixel(im, x, y), threshold)) { \
|
||||
gdImageSetPixel(im, x, y, dst); \
|
||||
n++; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
if (im->trueColor) {
|
||||
REPLACING_LOOP(gdImageTrueColorPixel);
|
||||
} else {
|
||||
REPLACING_LOOP(gdImagePalettePixel);
|
||||
}
|
||||
|
||||
#undef REPLACING_LOOP
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static int colorCmp (const void *x, const void *y)
|
||||
{
|
||||
int a = *(int const *)x;
|
||||
|
|
1
src/gd.h
1
src/gd.h
|
@ -587,6 +587,7 @@ 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) gdImageColorReplaceThreshold(gdImagePtr im, int src, int dst, float threshold);
|
||||
BGD_DECLARE(int) gdImageColorReplaceArray(gdImagePtr im, int len, int *src, int *dst);
|
||||
BGD_DECLARE(int) gdImageColorReplaceCallback(gdImagePtr im, int (*callback)(gdImagePtr imx, int src));
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
#include "gd.h"
|
||||
#include "gd_color.h"
|
||||
|
||||
int gdColorMatch(gdImagePtr im, int col1, int col2, float threshold)
|
||||
{
|
||||
const int dr = gdImageRed(im, col1) - gdImageRed(im, col2);
|
||||
const int dg = gdImageGreen(im, col1) - gdImageGreen(im, col2);
|
||||
const int db = gdImageBlue(im, col1) - gdImageBlue(im, col2);
|
||||
const int da = gdImageAlpha(im, col1) - gdImageAlpha(im, col2);
|
||||
const int dist = dr * dr + dg * dg + db * db + da * da;
|
||||
|
||||
return (100.0 * dist / 195075) < threshold;
|
||||
}
|
||||
|
||||
/*
|
||||
* To be implemented when we have more image formats.
|
||||
* Buffer like gray8 gray16 or rgb8 will require some tweak
|
||||
* and can be done in this function (called from the autocrop
|
||||
* function. (Pierre)
|
||||
*/
|
||||
#if 0
|
||||
static int colors_equal (const int col1, const in col2)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef GD_COLOR_H
|
||||
#define GD_COLOR_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int gdColorMatch(gdImagePtr im, int col1, int col2, float threshold);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -10,9 +10,9 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include "gd.h"
|
||||
#include "gd_color.h"
|
||||
|
||||
static int gdGuessBackgroundColorFromCorners(gdImagePtr im, int *color);
|
||||
static int gdColorMatch(gdImagePtr im, int col1, int col2, float threshold);
|
||||
|
||||
BGD_DECLARE(gdImagePtr) gdImageCrop(gdImagePtr src, const gdRect *crop)
|
||||
{
|
||||
|
@ -228,27 +228,3 @@ static int gdGuessBackgroundColorFromCorners(gdImagePtr im, int *color)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int gdColorMatch(gdImagePtr im, int col1, int col2, float threshold)
|
||||
{
|
||||
const int dr = gdImageRed(im, col1) - gdImageRed(im, col2);
|
||||
const int dg = gdImageGreen(im, col1) - gdImageGreen(im, col2);
|
||||
const int db = gdImageBlue(im, col1) - gdImageBlue(im, col2);
|
||||
const int da = gdImageAlpha(im, col1) - gdImageAlpha(im, col2);
|
||||
const int dist = dr * dr + dg * dg + db * db + da * da;
|
||||
|
||||
return (100.0 * dist / 195075) < threshold;
|
||||
}
|
||||
|
||||
/*
|
||||
* To be implemented when we have more image formats.
|
||||
* Buffer like gray8 gray16 or rgb8 will require some tweak
|
||||
* and can be done in this function (called from the autocrop
|
||||
* function. (Pierre)
|
||||
*/
|
||||
#if 0
|
||||
static int colors_equal (const int col1, const in col2)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -19,16 +19,40 @@ static int callback(gdImagePtr im, int src)
|
|||
|
||||
static void run_tests(gdImagePtr im, int *error)
|
||||
{
|
||||
int white, black, c, d;
|
||||
int black, \
|
||||
white, \
|
||||
cosmic_latte, \
|
||||
cream, \
|
||||
ivory, \
|
||||
magnolia, \
|
||||
old_lace, \
|
||||
seashell, \
|
||||
yellow, \
|
||||
red, \
|
||||
c, d;
|
||||
int src[2], dst[2];
|
||||
int n;
|
||||
|
||||
#define COLOR(name, r, g, b) name = gdImageColorAllocateAlpha(im, r, g, b, gdAlphaOpaque)
|
||||
COLOR(black, 0, 0, 0);
|
||||
COLOR(white, 0xFF, 0xFF, 0xFF);
|
||||
COLOR(cosmic_latte, 0xFF, 0xF8, 0xE7);
|
||||
COLOR(cream, 0xFF, 0xFD, 0xD0);
|
||||
COLOR(ivory, 0xFF, 0xFF, 0xF0);
|
||||
COLOR(magnolia, 0xF8, 0xF4, 0xFF);
|
||||
COLOR(old_lace, 0xFD, 0xF5, 0xE6);
|
||||
COLOR(seashell, 0xFF, 0xF5, 0xEE);
|
||||
COLOR(yellow, 0xFF, 0xFF, 0);
|
||||
COLOR(red, 0xFF, 0, 0);
|
||||
#undef COLOR
|
||||
|
||||
#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)); \
|
||||
|
@ -38,8 +62,6 @@ static void run_tests(gdImagePtr im, int *error)
|
|||
} \
|
||||
} 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);
|
||||
|
@ -85,6 +107,26 @@ static void run_tests(gdImagePtr im, int *error)
|
|||
CHECK_PIXEL(2, 3, d);
|
||||
CHECK_PIXEL(4, 4, d);
|
||||
|
||||
#define INITIALIZE_IMAGE() \
|
||||
gdImageSetClip(im, 0, 0, 4, 4); \
|
||||
gdImageFilledRectangle(im, 0, 0, 4, 4, black); \
|
||||
gdImageFilledRectangle(im, 1, 1, 3, 3, white); \
|
||||
gdImageSetPixel(im, 1, 1, cosmic_latte); \
|
||||
gdImageSetPixel(im, 1, 2, cream); \
|
||||
gdImageSetPixel(im, 2, 1, ivory); \
|
||||
gdImageSetPixel(im, 2, 2, magnolia); \
|
||||
gdImageSetPixel(im, 3, 1, old_lace); \
|
||||
gdImageSetPixel(im, 3, 2, seashell)
|
||||
|
||||
INITIALIZE_IMAGE();
|
||||
n = gdImageColorReplaceThreshold(im, white, yellow, 2.0);
|
||||
CHECK_VALUE(n, 9);
|
||||
CHECK_PIXEL(0, 0, black);
|
||||
CHECK_PIXEL(1, 1, yellow);
|
||||
CHECK_PIXEL(2, 2, yellow);
|
||||
CHECK_PIXEL(3, 3, yellow);
|
||||
|
||||
#undef INITIALIZE_IMAGE
|
||||
#undef CHECK_VALUE
|
||||
#undef CHECK_PIXEL
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue