mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-31 07:57:27 +03:00 
			
		
		
		
	Merge pull request #3107 from radarhere/effects
Corrected undefined behaviour
This commit is contained in:
		
						commit
						ad36932ebb
					
				|  | @ -96,8 +96,6 @@ | ||||||
| 
 | 
 | ||||||
| #undef    VERBOSE | #undef    VERBOSE | ||||||
| 
 | 
 | ||||||
| #define CLIP(x) ((x) <= 0 ? 0 : (x) < 256 ? (x) : 255) |  | ||||||
| 
 |  | ||||||
| #define B16(p, i) ((((int)p[(i)]) << 8) + p[(i)+1]) | #define B16(p, i) ((((int)p[(i)]) << 8) + p[(i)+1]) | ||||||
| #define L16(p, i) ((((int)p[(i)+1]) << 8) + p[(i)]) | #define L16(p, i) ((((int)p[(i)+1]) << 8) + p[(i)]) | ||||||
| #define S16(v) ((v) < 32768 ? (v) : ((v) - 65536)) | #define S16(v) ((v) < 32768 ? (v) : ((v) - 65536)) | ||||||
|  | @ -409,7 +407,7 @@ getlist(PyObject* arg, Py_ssize_t* length, const char* wrong_length, int type) | ||||||
|         switch (type) { |         switch (type) { | ||||||
|         case TYPE_UINT8: |         case TYPE_UINT8: | ||||||
|             itemp = PyInt_AsLong(op); |             itemp = PyInt_AsLong(op); | ||||||
|             ((UINT8*)list)[i] = CLIP(itemp); |             ((UINT8*)list)[i] = CLIP8(itemp); | ||||||
|             break; |             break; | ||||||
|         case TYPE_INT32: |         case TYPE_INT32: | ||||||
|             itemp = PyInt_AsLong(op); |             itemp = PyInt_AsLong(op); | ||||||
|  | @ -529,7 +527,7 @@ getink(PyObject* color, Imaging im, char* ink) | ||||||
|                     return NULL; |                     return NULL; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             ink[0] = CLIP(r); |             ink[0] = CLIP8(r); | ||||||
|             ink[1] = ink[2] = ink[3] = 0; |             ink[1] = ink[2] = ink[3] = 0; | ||||||
|         } else { |         } else { | ||||||
|             a = 255; |             a = 255; | ||||||
|  | @ -549,10 +547,10 @@ getink(PyObject* color, Imaging im, char* ink) | ||||||
|                         return NULL; |                         return NULL; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             ink[0] = CLIP(r); |             ink[0] = CLIP8(r); | ||||||
|             ink[1] = CLIP(g); |             ink[1] = CLIP8(g); | ||||||
|             ink[2] = CLIP(b); |             ink[2] = CLIP8(b); | ||||||
|             ink[3] = CLIP(a); |             ink[3] = CLIP8(a); | ||||||
|         } |         } | ||||||
|         return ink; |         return ink; | ||||||
|     case IMAGING_TYPE_INT32: |     case IMAGING_TYPE_INT32: | ||||||
|  | @ -1284,17 +1282,17 @@ _point(ImagingObject* self, PyObject* args) | ||||||
|             im = ImagingPoint(self->image, mode, (void*) data); |             im = ImagingPoint(self->image, mode, (void*) data); | ||||||
|         else if (mode && bands > 1) { |         else if (mode && bands > 1) { | ||||||
|             for (i = 0; i < 256; i++) { |             for (i = 0; i < 256; i++) { | ||||||
|                 lut[i*4] = CLIP(data[i]); |                 lut[i*4] = CLIP8(data[i]); | ||||||
|                 lut[i*4+1] = CLIP(data[i+256]); |                 lut[i*4+1] = CLIP8(data[i+256]); | ||||||
|                 lut[i*4+2] = CLIP(data[i+512]); |                 lut[i*4+2] = CLIP8(data[i+512]); | ||||||
|                 if (n > 768) |                 if (n > 768) | ||||||
|                     lut[i*4+3] = CLIP(data[i+768]); |                     lut[i*4+3] = CLIP8(data[i+768]); | ||||||
|             } |             } | ||||||
|             im = ImagingPoint(self->image, mode, (void*) lut); |             im = ImagingPoint(self->image, mode, (void*) lut); | ||||||
|         } else { |         } else { | ||||||
|             /* map individual bands */ |             /* map individual bands */ | ||||||
|             for (i = 0; i < n; i++) |             for (i = 0; i < n; i++) | ||||||
|                 lut[i] = CLIP(data[i]); |                 lut[i] = CLIP8(data[i]); | ||||||
|             im = ImagingPoint(self->image, mode, (void*) lut); |             im = ImagingPoint(self->image, mode, (void*) lut); | ||||||
|         } |         } | ||||||
|         free(data); |         free(data); | ||||||
|  | @ -1358,7 +1356,7 @@ _putdata(ImagingObject* self, PyObject* args) | ||||||
|             else |             else | ||||||
|                 /* Scaled and clipped string data */ |                 /* Scaled and clipped string data */ | ||||||
|                 for (i = x = y = 0; i < n; i++) { |                 for (i = x = y = 0; i < n; i++) { | ||||||
|                     image->image8[y][x] = CLIP((int) (p[i] * scale + offset)); |                     image->image8[y][x] = CLIP8((int) (p[i] * scale + offset)); | ||||||
|                     if (++x >= (int) image->xsize) |                     if (++x >= (int) image->xsize) | ||||||
|                         x = 0, y++; |                         x = 0, y++; | ||||||
|                 } |                 } | ||||||
|  | @ -1372,7 +1370,7 @@ _putdata(ImagingObject* self, PyObject* args) | ||||||
|                /* Clipped data */ |                /* Clipped data */ | ||||||
|                for (i = x = y = 0; i < n; i++) { |                for (i = x = y = 0; i < n; i++) { | ||||||
|                    op = PySequence_Fast_GET_ITEM(seq, i); |                    op = PySequence_Fast_GET_ITEM(seq, i); | ||||||
|                    image->image8[y][x] = (UINT8) CLIP(PyInt_AsLong(op)); |                    image->image8[y][x] = (UINT8) CLIP8(PyInt_AsLong(op)); | ||||||
|                    if (++x >= (int) image->xsize){ |                    if (++x >= (int) image->xsize){ | ||||||
|                        x = 0, y++; |                        x = 0, y++; | ||||||
|                    } |                    } | ||||||
|  | @ -1382,7 +1380,7 @@ _putdata(ImagingObject* self, PyObject* args) | ||||||
|                /* Scaled and clipped data */ |                /* Scaled and clipped data */ | ||||||
|                for (i = x = y = 0; i < n; i++) { |                for (i = x = y = 0; i < n; i++) { | ||||||
|                    PyObject *op = PySequence_Fast_GET_ITEM(seq, i); |                    PyObject *op = PySequence_Fast_GET_ITEM(seq, i); | ||||||
|                    image->image8[y][x] = CLIP( |                    image->image8[y][x] = CLIP8( | ||||||
|                        (int) (PyFloat_AsDouble(op) * scale + offset)); |                        (int) (PyFloat_AsDouble(op) * scale + offset)); | ||||||
|                    if (++x >= (int) image->xsize){ |                    if (++x >= (int) image->xsize){ | ||||||
|                        x = 0, y++; |                        x = 0, y++; | ||||||
|  |  | ||||||
|  | @ -19,9 +19,6 @@ | ||||||
| #include "Imaging.h" | #include "Imaging.h" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #define CLIP(x) ((x) <= 0 ? 0 : (x) < 256 ? (x) : 255) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| Imaging | Imaging | ||||||
| ImagingGetBand(Imaging imIn, int band) | ImagingGetBand(Imaging imIn, int band) | ||||||
| { | { | ||||||
|  | @ -214,7 +211,7 @@ ImagingFillBand(Imaging imOut, int band, int color) | ||||||
|     if (imOut->bands == 2 && band == 1) |     if (imOut->bands == 2 && band == 1) | ||||||
|         band = 3; |         band = 3; | ||||||
| 
 | 
 | ||||||
|     color = CLIP(color); |     color = CLIP8(color); | ||||||
| 
 | 
 | ||||||
|     /* Insert color into image */ |     /* Insert color into image */ | ||||||
|     for (y = 0; y < imOut->ysize; y++) { |     for (y = 0; y < imOut->ysize; y++) { | ||||||
|  |  | ||||||
|  | @ -38,7 +38,6 @@ | ||||||
| #define MAX(a, b) (a)>(b) ? (a) : (b) | #define MAX(a, b) (a)>(b) ? (a) : (b) | ||||||
| #define MIN(a, b) (a)<(b) ? (a) : (b) | #define MIN(a, b) (a)<(b) ? (a) : (b) | ||||||
| 
 | 
 | ||||||
| #define CLIP(v) ((v) <= 0 ? 0 : (v) >= 255 ? 255 : (v)) |  | ||||||
| #define CLIP16(v) ((v) <= -32768 ? -32768 : (v) >= 32767 ? 32767 : (v)) | #define CLIP16(v) ((v) <= -32768 ? -32768 : (v) >= 32767 ? 32767 : (v)) | ||||||
| 
 | 
 | ||||||
| /* ITU-R Recommendation 601-2 (assuming nonlinear RGB) */ | /* ITU-R Recommendation 601-2 (assuming nonlinear RGB) */ | ||||||
|  | @ -141,7 +140,7 @@ la2lA(UINT8* out, const UINT8* in, int xsize) | ||||||
|         if (alpha == 255 || alpha == 0) { |         if (alpha == 255 || alpha == 0) { | ||||||
|             pixel = in[0]; |             pixel = in[0]; | ||||||
|         } else { |         } else { | ||||||
|             pixel = CLIP((255 * in[0]) / alpha); |             pixel = CLIP8((255 * in[0]) / alpha); | ||||||
|         } |         } | ||||||
|         *out++ = (UINT8) pixel; |         *out++ = (UINT8) pixel; | ||||||
|         *out++ = (UINT8) pixel; |         *out++ = (UINT8) pixel; | ||||||
|  | @ -316,8 +315,8 @@ rgb2hsv(UINT8* out, const UINT8* in, int xsize) | ||||||
|             // incorrect hue happens if h/6 is negative.
 |             // incorrect hue happens if h/6 is negative.
 | ||||||
|             h = fmod((h/6.0 + 1.0), 1.0); |             h = fmod((h/6.0 + 1.0), 1.0); | ||||||
| 
 | 
 | ||||||
|             uh = (UINT8)CLIP((int)(h*255.0)); |             uh = (UINT8)CLIP8((int)(h*255.0)); | ||||||
|             us = (UINT8)CLIP((int)(s*255.0)); |             us = (UINT8)CLIP8((int)(s*255.0)); | ||||||
| 
 | 
 | ||||||
|             *out++ = uh; |             *out++ = uh; | ||||||
|             *out++ = us; |             *out++ = us; | ||||||
|  | @ -355,9 +354,9 @@ hsv2rgb(UINT8* out, const UINT8* in, int xsize) | ||||||
|             p = round((float)v * (1.0-fs)); |             p = round((float)v * (1.0-fs)); | ||||||
|             q = round((float)v * (1.0-fs*f)); |             q = round((float)v * (1.0-fs*f)); | ||||||
|             t = round((float)v * (1.0-fs*(1.0-f))); |             t = round((float)v * (1.0-fs*(1.0-f))); | ||||||
|             up = (UINT8)CLIP(p); |             up = (UINT8)CLIP8(p); | ||||||
|             uq = (UINT8)CLIP(q); |             uq = (UINT8)CLIP8(q); | ||||||
|             ut = (UINT8)CLIP(t); |             ut = (UINT8)CLIP8(t); | ||||||
| 
 | 
 | ||||||
|             switch (i%6) { |             switch (i%6) { | ||||||
|             case 0: |             case 0: | ||||||
|  | @ -466,9 +465,9 @@ rgba2rgbA(UINT8* out, const UINT8* in, int xsize) | ||||||
|             *out++ = in[1]; |             *out++ = in[1]; | ||||||
|             *out++ = in[2]; |             *out++ = in[2]; | ||||||
|         } else { |         } else { | ||||||
|             *out++ = CLIP((255 * in[0]) / alpha); |             *out++ = CLIP8((255 * in[0]) / alpha); | ||||||
|             *out++ = CLIP((255 * in[1]) / alpha); |             *out++ = CLIP8((255 * in[1]) / alpha); | ||||||
|             *out++ = CLIP((255 * in[2]) / alpha); |             *out++ = CLIP8((255 * in[2]) / alpha); | ||||||
|         } |         } | ||||||
|         *out++ = in[3]; |         *out++ = in[3]; | ||||||
|     } |     } | ||||||
|  | @ -537,9 +536,9 @@ cmyk2rgb(UINT8* out, const UINT8* in, int xsize) | ||||||
|     int x, nk, tmp; |     int x, nk, tmp; | ||||||
|     for (x = 0; x < xsize; x++) { |     for (x = 0; x < xsize; x++) { | ||||||
|         nk = 255 - in[3]; |         nk = 255 - in[3]; | ||||||
|         out[0] = CLIP(nk - MULDIV255(in[0], nk, tmp)); |         out[0] = CLIP8(nk - MULDIV255(in[0], nk, tmp)); | ||||||
|         out[1] = CLIP(nk - MULDIV255(in[1], nk, tmp)); |         out[1] = CLIP8(nk - MULDIV255(in[1], nk, tmp)); | ||||||
|         out[2] = CLIP(nk - MULDIV255(in[2], nk, tmp)); |         out[2] = CLIP8(nk - MULDIV255(in[2], nk, tmp)); | ||||||
|         out[3] = 255; |         out[3] = 255; | ||||||
|         out += 4; |         out += 4; | ||||||
|         in += 4; |         in += 4; | ||||||
|  | @ -1132,9 +1131,9 @@ topalette(Imaging imOut, Imaging imIn, ImagingPalette inpalette, int dither) | ||||||
|                     int d2; |                     int d2; | ||||||
|                     INT16* cache; |                     INT16* cache; | ||||||
| 
 | 
 | ||||||
|                     r = CLIP(in[0] + (r + e[3+0])/16); |                     r = CLIP8(in[0] + (r + e[3+0])/16); | ||||||
|                     g = CLIP(in[1] + (g + e[3+1])/16); |                     g = CLIP8(in[1] + (g + e[3+1])/16); | ||||||
|                     b = CLIP(in[2] + (b + e[3+2])/16); |                     b = CLIP8(in[2] + (b + e[3+2])/16); | ||||||
| 
 | 
 | ||||||
|                     /* get closest colour */ |                     /* get closest colour */ | ||||||
|                     cache = &ImagingPaletteCache(palette, r, g, b); |                     cache = &ImagingPaletteCache(palette, r, g, b); | ||||||
|  | @ -1236,7 +1235,7 @@ tobilevel(Imaging imOut, Imaging imIn, int dither) | ||||||
|             for (x = 0; x < imIn->xsize; x++) { |             for (x = 0; x < imIn->xsize; x++) { | ||||||
| 
 | 
 | ||||||
|                 /* pick closest colour */ |                 /* pick closest colour */ | ||||||
|                 l = CLIP(in[x] + (l + errors[x+1])/16); |                 l = CLIP8(in[x] + (l + errors[x+1])/16); | ||||||
|                 out[x] = (l > 128) ? 255 : 0; |                 out[x] = (l > 128) ? 255 : 0; | ||||||
| 
 | 
 | ||||||
|                 /* propagate errors */ |                 /* propagate errors */ | ||||||
|  | @ -1264,7 +1263,7 @@ tobilevel(Imaging imOut, Imaging imIn, int dither) | ||||||
|             for (x = 0; x < imIn->xsize; x++, in += 4) { |             for (x = 0; x < imIn->xsize; x++, in += 4) { | ||||||
| 
 | 
 | ||||||
|                 /* pick closest colour */ |                 /* pick closest colour */ | ||||||
|                 l = CLIP(L(in)/1000 + (l + errors[x+1])/16); |                 l = CLIP8(L(in)/1000 + (l + errors[x+1])/16); | ||||||
|                 out[x] = (l > 128) ? 255 : 0; |                 out[x] = (l > 128) ? 255 : 0; | ||||||
| 
 | 
 | ||||||
|                 /* propagate errors */ |                 /* propagate errors */ | ||||||
|  |  | ||||||
|  | @ -106,7 +106,7 @@ ImagingEffectNoise(int xsize, int ysize, float sigma) | ||||||
|                 this = factor * v1; |                 this = factor * v1; | ||||||
|                 next = factor * v2; |                 next = factor * v2; | ||||||
|             } |             } | ||||||
|             out[x] = (unsigned char) (128 + sigma * this); |             out[x] = CLIP8(128 + sigma * this); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -30,6 +30,8 @@ | ||||||
|     (MULDIV255(in1, (255 - mask), tmp1) + in2) |     (MULDIV255(in1, (255 - mask), tmp1) + in2) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | #define CLIP8(v) ((v) <= 0 ? 0 : (v) < 256 ? (v) : 255) | ||||||
|  | 
 | ||||||
| /* This is to work around a bug in GCC prior 4.9 in 64 bit mode.
 | /* This is to work around a bug in GCC prior 4.9 in 64 bit mode.
 | ||||||
|    GCC generates code with partial dependency which is 3 times slower. |    GCC generates code with partial dependency which is 3 times slower. | ||||||
|    See: http://stackoverflow.com/a/26588074/253146 */
 |    See: http://stackoverflow.com/a/26588074/253146 */
 | ||||||
|  |  | ||||||
|  | @ -45,8 +45,6 @@ | ||||||
| #define Y 2 | #define Y 2 | ||||||
| #define K 3 | #define K 3 | ||||||
| 
 | 
 | ||||||
| #define CLIP(x) ((x) <= 0 ? 0 : (x) < 256 ? (x) : 255) |  | ||||||
| 
 |  | ||||||
| /* byte-swapping macros */ | /* byte-swapping macros */ | ||||||
| 
 | 
 | ||||||
| #define C16N\ | #define C16N\ | ||||||
|  | @ -749,9 +747,9 @@ unpackRGBa16L(UINT8* _out, const UINT8* in, int pixels) | ||||||
|         } else if (a == 255) { |         } else if (a == 255) { | ||||||
|             out[i] = MAKE_UINT32(in[1], in[3], in[5], a); |             out[i] = MAKE_UINT32(in[1], in[3], in[5], a); | ||||||
|         } else { |         } else { | ||||||
|             out[i] = MAKE_UINT32(CLIP(in[1] * 255 / a), |             out[i] = MAKE_UINT32(CLIP8(in[1] * 255 / a), | ||||||
|                                  CLIP(in[3] * 255 / a), |                                  CLIP8(in[3] * 255 / a), | ||||||
|                                  CLIP(in[5] * 255 / a), a); |                                  CLIP8(in[5] * 255 / a), a); | ||||||
|         } |         } | ||||||
|         in += 8; |         in += 8; | ||||||
|     } |     } | ||||||
|  | @ -770,9 +768,9 @@ unpackRGBa16B(UINT8* _out, const UINT8* in, int pixels) | ||||||
|         } else if (a == 255) { |         } else if (a == 255) { | ||||||
|             out[i] = MAKE_UINT32(in[0], in[2], in[4], a); |             out[i] = MAKE_UINT32(in[0], in[2], in[4], a); | ||||||
|         } else { |         } else { | ||||||
|             out[i] = MAKE_UINT32(CLIP(in[0] * 255 / a), |             out[i] = MAKE_UINT32(CLIP8(in[0] * 255 / a), | ||||||
|                                  CLIP(in[2] * 255 / a), |                                  CLIP8(in[2] * 255 / a), | ||||||
|                                  CLIP(in[4] * 255 / a), a); |                                  CLIP8(in[4] * 255 / a), a); | ||||||
|         } |         } | ||||||
|         in += 8; |         in += 8; | ||||||
|     } |     } | ||||||
|  | @ -791,9 +789,9 @@ unpackRGBa(UINT8* _out, const UINT8* in, int pixels) | ||||||
|         } else if (a == 255) { |         } else if (a == 255) { | ||||||
|             out[i] = MAKE_UINT32(in[0], in[1], in[2], a); |             out[i] = MAKE_UINT32(in[0], in[1], in[2], a); | ||||||
|         } else { |         } else { | ||||||
|             out[i] = MAKE_UINT32(CLIP(in[0] * 255 / a), |             out[i] = MAKE_UINT32(CLIP8(in[0] * 255 / a), | ||||||
|                                  CLIP(in[1] * 255 / a), |                                  CLIP8(in[1] * 255 / a), | ||||||
|                                  CLIP(in[2] * 255 / a), a); |                                  CLIP8(in[2] * 255 / a), a); | ||||||
|         } |         } | ||||||
|         in += 4; |         in += 4; | ||||||
|     } |     } | ||||||
|  | @ -812,9 +810,9 @@ unpackBGRa(UINT8* _out, const UINT8* in, int pixels) | ||||||
|         } else if (a == 255) { |         } else if (a == 255) { | ||||||
|             out[i] = MAKE_UINT32(in[2], in[1], in[0], a); |             out[i] = MAKE_UINT32(in[2], in[1], in[0], a); | ||||||
|         } else { |         } else { | ||||||
|             out[i] = MAKE_UINT32(CLIP(in[2] * 255 / a), |             out[i] = MAKE_UINT32(CLIP8(in[2] * 255 / a), | ||||||
|                                  CLIP(in[1] * 255 / a), |                                  CLIP8(in[1] * 255 / a), | ||||||
|                                  CLIP(in[0] * 255 / a), a); |                                  CLIP8(in[0] * 255 / a), a); | ||||||
|         } |         } | ||||||
|         in += 4; |         in += 4; | ||||||
|     } |     } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user