Annotation of embedaddon/php/ext/gd/libgd/gd_filter.c, revision 1.1
1.1 ! misho 1: #if HAVE_GD_BUNDLED
! 2: # include "gd.h"
! 3: #else
! 4: # include <gd.h>
! 5: #endif
! 6:
! 7: #include "gd_intern.h"
! 8:
! 9: /* Filters function added on 2003/12
! 10: * by Pierre-Alain Joye (pierre@php.net)
! 11: **/
! 12: /* Begin filters function */
! 13: #define GET_PIXEL_FUNCTION(src)(src->trueColor?gdImageGetTrueColorPixel:gdImageGetPixel)
! 14:
! 15: /* invert src image */
! 16: int gdImageNegate(gdImagePtr src)
! 17: {
! 18: int x, y;
! 19: int r,g,b,a;
! 20: int new_pxl, pxl;
! 21: typedef int (*FuncPtr)(gdImagePtr, int, int);
! 22: FuncPtr f;
! 23:
! 24: if (src==NULL) {
! 25: return 0;
! 26: }
! 27:
! 28: f = GET_PIXEL_FUNCTION(src);
! 29:
! 30: for (y=0; y<src->sy; ++y) {
! 31: for (x=0; x<src->sx; ++x) {
! 32: pxl = f (src, x, y);
! 33: r = gdImageRed(src, pxl);
! 34: g = gdImageGreen(src, pxl);
! 35: b = gdImageBlue(src, pxl);
! 36: a = gdImageAlpha(src, pxl);
! 37:
! 38: new_pxl = gdImageColorAllocateAlpha(src, 255-r, 255-g, 255-b, a);
! 39: if (new_pxl == -1) {
! 40: new_pxl = gdImageColorClosestAlpha(src, 255-r, 255-g, 255-b, a);
! 41: }
! 42: gdImageSetPixel (src, x, y, new_pxl);
! 43: }
! 44: }
! 45: return 1;
! 46: }
! 47:
! 48: /* Convert the image src to a grayscale image */
! 49: int gdImageGrayScale(gdImagePtr src)
! 50: {
! 51: int x, y;
! 52: int r,g,b,a;
! 53: int new_pxl, pxl;
! 54: typedef int (*FuncPtr)(gdImagePtr, int, int);
! 55: FuncPtr f;
! 56: f = GET_PIXEL_FUNCTION(src);
! 57:
! 58: if (src==NULL) {
! 59: return 0;
! 60: }
! 61:
! 62: for (y=0; y<src->sy; ++y) {
! 63: for (x=0; x<src->sx; ++x) {
! 64: pxl = f (src, x, y);
! 65: r = gdImageRed(src, pxl);
! 66: g = gdImageGreen(src, pxl);
! 67: b = gdImageBlue(src, pxl);
! 68: a = gdImageAlpha(src, pxl);
! 69: r = g = b = (int) (.299 * r + .587 * g + .114 * b);
! 70:
! 71: new_pxl = gdImageColorAllocateAlpha(src, r, g, b, a);
! 72: if (new_pxl == -1) {
! 73: new_pxl = gdImageColorClosestAlpha(src, r, g, b, a);
! 74: }
! 75: gdImageSetPixel (src, x, y, new_pxl);
! 76: }
! 77: }
! 78: return 1;
! 79: }
! 80:
! 81: /* Set the brightness level <level> for the image src */
! 82: int gdImageBrightness(gdImagePtr src, int brightness)
! 83: {
! 84: int x, y;
! 85: int r,g,b,a;
! 86: int new_pxl, pxl;
! 87: typedef int (*FuncPtr)(gdImagePtr, int, int);
! 88: FuncPtr f;
! 89: f = GET_PIXEL_FUNCTION(src);
! 90:
! 91: if (src==NULL || (brightness < -255 || brightness>255)) {
! 92: return 0;
! 93: }
! 94:
! 95: if (brightness==0) {
! 96: return 1;
! 97: }
! 98:
! 99: for (y=0; y<src->sy; ++y) {
! 100: for (x=0; x<src->sx; ++x) {
! 101: pxl = f (src, x, y);
! 102:
! 103: r = gdImageRed(src, pxl);
! 104: g = gdImageGreen(src, pxl);
! 105: b = gdImageBlue(src, pxl);
! 106: a = gdImageAlpha(src, pxl);
! 107:
! 108: r = r + brightness;
! 109: g = g + brightness;
! 110: b = b + brightness;
! 111:
! 112: r = (r > 255)? 255 : ((r < 0)? 0:r);
! 113: g = (g > 255)? 255 : ((g < 0)? 0:g);
! 114: b = (b > 255)? 255 : ((b < 0)? 0:b);
! 115:
! 116: new_pxl = gdImageColorAllocateAlpha(src, (int)r, (int)g, (int)b, a);
! 117: if (new_pxl == -1) {
! 118: new_pxl = gdImageColorClosestAlpha(src, (int)r, (int)g, (int)b, a);
! 119: }
! 120: gdImageSetPixel (src, x, y, new_pxl);
! 121: }
! 122: }
! 123: return 1;
! 124: }
! 125:
! 126:
! 127: int gdImageContrast(gdImagePtr src, double contrast)
! 128: {
! 129: int x, y;
! 130: int r,g,b,a;
! 131: double rf,gf,bf;
! 132: int new_pxl, pxl;
! 133: typedef int (*FuncPtr)(gdImagePtr, int, int);
! 134:
! 135: FuncPtr f;
! 136: f = GET_PIXEL_FUNCTION(src);
! 137:
! 138: if (src==NULL) {
! 139: return 0;
! 140: }
! 141:
! 142: contrast = (double)(100.0-contrast)/100.0;
! 143: contrast = contrast*contrast;
! 144:
! 145: for (y=0; y<src->sy; ++y) {
! 146: for (x=0; x<src->sx; ++x) {
! 147: pxl = f(src, x, y);
! 148:
! 149: r = gdImageRed(src, pxl);
! 150: g = gdImageGreen(src, pxl);
! 151: b = gdImageBlue(src, pxl);
! 152: a = gdImageAlpha(src, pxl);
! 153:
! 154: rf = (double)r/255.0;
! 155: rf = rf-0.5;
! 156: rf = rf*contrast;
! 157: rf = rf+0.5;
! 158: rf = rf*255.0;
! 159:
! 160: bf = (double)b/255.0;
! 161: bf = bf-0.5;
! 162: bf = bf*contrast;
! 163: bf = bf+0.5;
! 164: bf = bf*255.0;
! 165:
! 166: gf = (double)g/255.0;
! 167: gf = gf-0.5;
! 168: gf = gf*contrast;
! 169: gf = gf+0.5;
! 170: gf = gf*255.0;
! 171:
! 172: rf = (rf > 255.0)? 255.0 : ((rf < 0.0)? 0.0:rf);
! 173: gf = (gf > 255.0)? 255.0 : ((gf < 0.0)? 0.0:gf);
! 174: bf = (bf > 255.0)? 255.0 : ((bf < 0.0)? 0.0:bf);
! 175:
! 176: new_pxl = gdImageColorAllocateAlpha(src, (int)rf, (int)gf, (int)bf, a);
! 177: if (new_pxl == -1) {
! 178: new_pxl = gdImageColorClosestAlpha(src, (int)rf, (int)gf, (int)bf, a);
! 179: }
! 180: gdImageSetPixel (src, x, y, new_pxl);
! 181: }
! 182: }
! 183: return 1;
! 184: }
! 185:
! 186:
! 187: int gdImageColor(gdImagePtr src, const int red, const int green, const int blue, const int alpha)
! 188: {
! 189: int x, y;
! 190: int new_pxl, pxl;
! 191: typedef int (*FuncPtr)(gdImagePtr, int, int);
! 192: FuncPtr f;
! 193:
! 194: if (src == NULL) {
! 195: return 0;
! 196: }
! 197:
! 198: f = GET_PIXEL_FUNCTION(src);
! 199:
! 200: for (y=0; y<src->sy; ++y) {
! 201: for (x=0; x<src->sx; ++x) {
! 202: int r,g,b,a;
! 203:
! 204: pxl = f(src, x, y);
! 205: r = gdImageRed(src, pxl);
! 206: g = gdImageGreen(src, pxl);
! 207: b = gdImageBlue(src, pxl);
! 208: a = gdImageAlpha(src, pxl);
! 209:
! 210: r = r + red;
! 211: g = g + green;
! 212: b = b + blue;
! 213: a = a + alpha;
! 214:
! 215: r = (r > 255)? 255 : ((r < 0)? 0 : r);
! 216: g = (g > 255)? 255 : ((g < 0)? 0 : g);
! 217: b = (b > 255)? 255 : ((b < 0)? 0 : b);
! 218: a = (a > 127)? 127 : ((a < 0)? 0 : a);
! 219:
! 220: new_pxl = gdImageColorAllocateAlpha(src, r, g, b, a);
! 221: if (new_pxl == -1) {
! 222: new_pxl = gdImageColorClosestAlpha(src, r, g, b, a);
! 223: }
! 224: gdImageSetPixel (src, x, y, new_pxl);
! 225: }
! 226: }
! 227: return 1;
! 228: }
! 229:
! 230: int gdImageConvolution(gdImagePtr src, float filter[3][3], float filter_div, float offset)
! 231: {
! 232: int x, y, i, j, new_a;
! 233: float new_r, new_g, new_b;
! 234: int new_pxl, pxl=0;
! 235: gdImagePtr srcback;
! 236: typedef int (*FuncPtr)(gdImagePtr, int, int);
! 237: FuncPtr f;
! 238:
! 239: if (src==NULL) {
! 240: return 0;
! 241: }
! 242:
! 243: /* We need the orinal image with each safe neoghb. pixel */
! 244: srcback = gdImageCreateTrueColor (src->sx, src->sy);
! 245: if (srcback==NULL) {
! 246: return 0;
! 247: }
! 248:
! 249: gdImageSaveAlpha(srcback, 1);
! 250: new_pxl = gdImageColorAllocateAlpha(srcback, 0, 0, 0, 127);
! 251: gdImageFill(srcback, 0, 0, new_pxl);
! 252:
! 253: gdImageCopy(srcback, src,0,0,0,0,src->sx,src->sy);
! 254:
! 255: f = GET_PIXEL_FUNCTION(src);
! 256:
! 257: for ( y=0; y<src->sy; y++) {
! 258: for(x=0; x<src->sx; x++) {
! 259: new_r = new_g = new_b = 0;
! 260: new_a = gdImageAlpha(srcback, pxl);
! 261:
! 262: for (j=0; j<3; j++) {
! 263: int yv = MIN(MAX(y - 1 + j, 0), src->sy - 1);
! 264: for (i=0; i<3; i++) {
! 265: pxl = f(srcback, MIN(MAX(x - 1 + i, 0), src->sx - 1), yv);
! 266: new_r += (float)gdImageRed(srcback, pxl) * filter[j][i];
! 267: new_g += (float)gdImageGreen(srcback, pxl) * filter[j][i];
! 268: new_b += (float)gdImageBlue(srcback, pxl) * filter[j][i];
! 269: }
! 270: }
! 271:
! 272: new_r = (new_r/filter_div)+offset;
! 273: new_g = (new_g/filter_div)+offset;
! 274: new_b = (new_b/filter_div)+offset;
! 275:
! 276: new_r = (new_r > 255.0f)? 255.0f : ((new_r < 0.0f)? 0.0f:new_r);
! 277: new_g = (new_g > 255.0f)? 255.0f : ((new_g < 0.0f)? 0.0f:new_g);
! 278: new_b = (new_b > 255.0f)? 255.0f : ((new_b < 0.0f)? 0.0f:new_b);
! 279:
! 280: new_pxl = gdImageColorAllocateAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a);
! 281: if (new_pxl == -1) {
! 282: new_pxl = gdImageColorClosestAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a);
! 283: }
! 284: gdImageSetPixel (src, x, y, new_pxl);
! 285: }
! 286: }
! 287: gdImageDestroy(srcback);
! 288: return 1;
! 289: }
! 290:
! 291: int gdImageSelectiveBlur( gdImagePtr src)
! 292: {
! 293: int x, y, i, j;
! 294: float new_r, new_g, new_b;
! 295: int new_pxl, cpxl, pxl, new_a=0;
! 296: float flt_r [3][3];
! 297: float flt_g [3][3];
! 298: float flt_b [3][3];
! 299: float flt_r_sum, flt_g_sum, flt_b_sum;
! 300:
! 301: gdImagePtr srcback;
! 302: typedef int (*FuncPtr)(gdImagePtr, int, int);
! 303: FuncPtr f;
! 304:
! 305: if (src==NULL) {
! 306: return 0;
! 307: }
! 308:
! 309: /* We need the orinal image with each safe neoghb. pixel */
! 310: srcback = gdImageCreateTrueColor (src->sx, src->sy);
! 311: if (srcback==NULL) {
! 312: return 0;
! 313: }
! 314: gdImageCopy(srcback, src,0,0,0,0,src->sx,src->sy);
! 315:
! 316: f = GET_PIXEL_FUNCTION(src);
! 317:
! 318: for(y = 0; y<src->sy; y++) {
! 319: for (x=0; x<src->sx; x++) {
! 320: flt_r_sum = flt_g_sum = flt_b_sum = 0.0;
! 321: cpxl = f(src, x, y);
! 322:
! 323: for (j=0; j<3; j++) {
! 324: for (i=0; i<3; i++) {
! 325: if ((j == 1) && (i == 1)) {
! 326: flt_r[1][1] = flt_g[1][1] = flt_b[1][1] = 0.5;
! 327: } else {
! 328: pxl = f(src, x-(3>>1)+i, y-(3>>1)+j);
! 329: new_a = gdImageAlpha(srcback, pxl);
! 330:
! 331: new_r = ((float)gdImageRed(srcback, cpxl)) - ((float)gdImageRed (srcback, pxl));
! 332:
! 333: if (new_r < 0.0f) {
! 334: new_r = -new_r;
! 335: }
! 336: if (new_r != 0) {
! 337: flt_r[j][i] = 1.0f/new_r;
! 338: } else {
! 339: flt_r[j][i] = 1.0f;
! 340: }
! 341:
! 342: new_g = ((float)gdImageGreen(srcback, cpxl)) - ((float)gdImageGreen(srcback, pxl));
! 343:
! 344: if (new_g < 0.0f) {
! 345: new_g = -new_g;
! 346: }
! 347: if (new_g != 0) {
! 348: flt_g[j][i] = 1.0f/new_g;
! 349: } else {
! 350: flt_g[j][i] = 1.0f;
! 351: }
! 352:
! 353: new_b = ((float)gdImageBlue(srcback, cpxl)) - ((float)gdImageBlue(srcback, pxl));
! 354:
! 355: if (new_b < 0.0f) {
! 356: new_b = -new_b;
! 357: }
! 358: if (new_b != 0) {
! 359: flt_b[j][i] = 1.0f/new_b;
! 360: } else {
! 361: flt_b[j][i] = 1.0f;
! 362: }
! 363: }
! 364:
! 365: flt_r_sum += flt_r[j][i];
! 366: flt_g_sum += flt_g[j][i];
! 367: flt_b_sum += flt_b [j][i];
! 368: }
! 369: }
! 370:
! 371: for (j=0; j<3; j++) {
! 372: for (i=0; i<3; i++) {
! 373: if (flt_r_sum != 0.0) {
! 374: flt_r[j][i] /= flt_r_sum;
! 375: }
! 376: if (flt_g_sum != 0.0) {
! 377: flt_g[j][i] /= flt_g_sum;
! 378: }
! 379: if (flt_b_sum != 0.0) {
! 380: flt_b [j][i] /= flt_b_sum;
! 381: }
! 382: }
! 383: }
! 384:
! 385: new_r = new_g = new_b = 0.0;
! 386:
! 387: for (j=0; j<3; j++) {
! 388: for (i=0; i<3; i++) {
! 389: pxl = f(src, x-(3>>1)+i, y-(3>>1)+j);
! 390: new_r += (float)gdImageRed(srcback, pxl) * flt_r[j][i];
! 391: new_g += (float)gdImageGreen(srcback, pxl) * flt_g[j][i];
! 392: new_b += (float)gdImageBlue(srcback, pxl) * flt_b[j][i];
! 393: }
! 394: }
! 395:
! 396: new_r = (new_r > 255.0f)? 255.0f : ((new_r < 0.0f)? 0.0f:new_r);
! 397: new_g = (new_g > 255.0f)? 255.0f : ((new_g < 0.0f)? 0.0f:new_g);
! 398: new_b = (new_b > 255.0f)? 255.0f : ((new_b < 0.0f)? 0.0f:new_b);
! 399: new_pxl = gdImageColorAllocateAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a);
! 400: if (new_pxl == -1) {
! 401: new_pxl = gdImageColorClosestAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a);
! 402: }
! 403: gdImageSetPixel (src, x, y, new_pxl);
! 404: }
! 405: }
! 406: gdImageDestroy(srcback);
! 407: return 1;
! 408: }
! 409:
! 410: int gdImageEdgeDetectQuick(gdImagePtr src)
! 411: {
! 412: float filter[3][3] = {{-1.0,0.0,-1.0},
! 413: {0.0,4.0,0.0},
! 414: {-1.0,0.0,-1.0}};
! 415:
! 416: return gdImageConvolution(src, filter, 1, 127);
! 417: }
! 418:
! 419: int gdImageGaussianBlur(gdImagePtr im)
! 420: {
! 421: float filter[3][3] = {{1.0,2.0,1.0},
! 422: {2.0,4.0,2.0},
! 423: {1.0,2.0,1.0}};
! 424:
! 425: return gdImageConvolution(im, filter, 16, 0);
! 426: }
! 427:
! 428: int gdImageEmboss(gdImagePtr im)
! 429: {
! 430: /*
! 431: float filter[3][3] = {{1.0,1.0,1.0},
! 432: {0.0,0.0,0.0},
! 433: {-1.0,-1.0,-1.0}};
! 434: */
! 435: float filter[3][3] = {{ 1.5, 0.0, 0.0},
! 436: { 0.0, 0.0, 0.0},
! 437: { 0.0, 0.0,-1.5}};
! 438:
! 439: return gdImageConvolution(im, filter, 1, 127);
! 440: }
! 441:
! 442: int gdImageMeanRemoval(gdImagePtr im)
! 443: {
! 444: float filter[3][3] = {{-1.0,-1.0,-1.0},
! 445: {-1.0,9.0,-1.0},
! 446: {-1.0,-1.0,-1.0}};
! 447:
! 448: return gdImageConvolution(im, filter, 1, 0);
! 449: }
! 450:
! 451: int gdImageSmooth(gdImagePtr im, float weight)
! 452: {
! 453: float filter[3][3] = {{1.0,1.0,1.0},
! 454: {1.0,0.0,1.0},
! 455: {1.0,1.0,1.0}};
! 456:
! 457: filter[1][1] = weight;
! 458:
! 459: return gdImageConvolution(im, filter, weight+8, 0);
! 460: }
! 461: /* End filters function */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>