mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-26 18:06:18 +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