Annotation of embedaddon/php/ext/gd/libgd/gd_filter.c, revision 1.1.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>