Merge pull request #3107 from radarhere/effects

Corrected undefined behaviour
This commit is contained in:
Hugo 2018-04-22 09:04:35 +03:00 committed by GitHub
commit ad36932ebb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 49 additions and 55 deletions

View File

@ -96,8 +96,6 @@
#undef VERBOSE
#define CLIP(x) ((x) <= 0 ? 0 : (x) < 256 ? (x) : 255)
#define B16(p, i) ((((int)p[(i)]) << 8) + p[(i)+1])
#define L16(p, i) ((((int)p[(i)+1]) << 8) + p[(i)])
#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) {
case TYPE_UINT8:
itemp = PyInt_AsLong(op);
((UINT8*)list)[i] = CLIP(itemp);
((UINT8*)list)[i] = CLIP8(itemp);
break;
case TYPE_INT32:
itemp = PyInt_AsLong(op);
@ -529,7 +527,7 @@ getink(PyObject* color, Imaging im, char* ink)
return NULL;
}
}
ink[0] = CLIP(r);
ink[0] = CLIP8(r);
ink[1] = ink[2] = ink[3] = 0;
} else {
a = 255;
@ -549,10 +547,10 @@ getink(PyObject* color, Imaging im, char* ink)
return NULL;
}
}
ink[0] = CLIP(r);
ink[1] = CLIP(g);
ink[2] = CLIP(b);
ink[3] = CLIP(a);
ink[0] = CLIP8(r);
ink[1] = CLIP8(g);
ink[2] = CLIP8(b);
ink[3] = CLIP8(a);
}
return ink;
case IMAGING_TYPE_INT32:
@ -744,7 +742,7 @@ _prepare_lut_table(PyObject* table, Py_ssize_t table_size)
prepared[i] = table_data[i] * (255 << PRECISION_BITS) + 0.5;
}
}
#undef PRECISION_BITS
free(table_data);
return prepared;
@ -803,7 +801,7 @@ _color_lut_3d(ImagingObject* self, PyObject* args)
return NULL;
}
if ( ! ImagingColorLUT3D_linear(imOut, self->image,
if ( ! ImagingColorLUT3D_linear(imOut, self->image,
table_channels, size1D, size2D, size3D,
prepared_table)) {
free(prepared_table);
@ -1284,17 +1282,17 @@ _point(ImagingObject* self, PyObject* args)
im = ImagingPoint(self->image, mode, (void*) data);
else if (mode && bands > 1) {
for (i = 0; i < 256; i++) {
lut[i*4] = CLIP(data[i]);
lut[i*4+1] = CLIP(data[i+256]);
lut[i*4+2] = CLIP(data[i+512]);
lut[i*4] = CLIP8(data[i]);
lut[i*4+1] = CLIP8(data[i+256]);
lut[i*4+2] = CLIP8(data[i+512]);
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);
} else {
/* map individual bands */
for (i = 0; i < n; i++)
lut[i] = CLIP(data[i]);
lut[i] = CLIP8(data[i]);
im = ImagingPoint(self->image, mode, (void*) lut);
}
free(data);
@ -1358,7 +1356,7 @@ _putdata(ImagingObject* self, PyObject* args)
else
/* Scaled and clipped string data */
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)
x = 0, y++;
}
@ -1372,7 +1370,7 @@ _putdata(ImagingObject* self, PyObject* args)
/* Clipped data */
for (i = x = y = 0; i < n; 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){
x = 0, y++;
}
@ -1382,7 +1380,7 @@ _putdata(ImagingObject* self, PyObject* args)
/* Scaled and clipped data */
for (i = x = y = 0; i < n; 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));
if (++x >= (int) image->xsize){
x = 0, y++;

View File

@ -19,9 +19,6 @@
#include "Imaging.h"
#define CLIP(x) ((x) <= 0 ? 0 : (x) < 256 ? (x) : 255)
Imaging
ImagingGetBand(Imaging imIn, int band)
{
@ -214,7 +211,7 @@ ImagingFillBand(Imaging imOut, int band, int color)
if (imOut->bands == 2 && band == 1)
band = 3;
color = CLIP(color);
color = CLIP8(color);
/* Insert color into image */
for (y = 0; y < imOut->ysize; y++) {

View File

@ -38,7 +38,6 @@
#define MAX(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))
/* 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) {
pixel = in[0];
} else {
pixel = CLIP((255 * in[0]) / alpha);
pixel = CLIP8((255 * in[0]) / alpha);
}
*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.
h = fmod((h/6.0 + 1.0), 1.0);
uh = (UINT8)CLIP((int)(h*255.0));
us = (UINT8)CLIP((int)(s*255.0));
uh = (UINT8)CLIP8((int)(h*255.0));
us = (UINT8)CLIP8((int)(s*255.0));
*out++ = uh;
*out++ = us;
@ -355,9 +354,9 @@ hsv2rgb(UINT8* out, const UINT8* in, int xsize)
p = round((float)v * (1.0-fs));
q = round((float)v * (1.0-fs*f));
t = round((float)v * (1.0-fs*(1.0-f)));
up = (UINT8)CLIP(p);
uq = (UINT8)CLIP(q);
ut = (UINT8)CLIP(t);
up = (UINT8)CLIP8(p);
uq = (UINT8)CLIP8(q);
ut = (UINT8)CLIP8(t);
switch (i%6) {
case 0:
@ -466,9 +465,9 @@ rgba2rgbA(UINT8* out, const UINT8* in, int xsize)
*out++ = in[1];
*out++ = in[2];
} else {
*out++ = CLIP((255 * in[0]) / alpha);
*out++ = CLIP((255 * in[1]) / alpha);
*out++ = CLIP((255 * in[2]) / alpha);
*out++ = CLIP8((255 * in[0]) / alpha);
*out++ = CLIP8((255 * in[1]) / alpha);
*out++ = CLIP8((255 * in[2]) / alpha);
}
*out++ = in[3];
}
@ -537,9 +536,9 @@ cmyk2rgb(UINT8* out, const UINT8* in, int xsize)
int x, nk, tmp;
for (x = 0; x < xsize; x++) {
nk = 255 - in[3];
out[0] = CLIP(nk - MULDIV255(in[0], nk, tmp));
out[1] = CLIP(nk - MULDIV255(in[1], nk, tmp));
out[2] = CLIP(nk - MULDIV255(in[2], nk, tmp));
out[0] = CLIP8(nk - MULDIV255(in[0], nk, tmp));
out[1] = CLIP8(nk - MULDIV255(in[1], nk, tmp));
out[2] = CLIP8(nk - MULDIV255(in[2], nk, tmp));
out[3] = 255;
out += 4;
in += 4;
@ -1132,9 +1131,9 @@ topalette(Imaging imOut, Imaging imIn, ImagingPalette inpalette, int dither)
int d2;
INT16* cache;
r = CLIP(in[0] + (r + e[3+0])/16);
g = CLIP(in[1] + (g + e[3+1])/16);
b = CLIP(in[2] + (b + e[3+2])/16);
r = CLIP8(in[0] + (r + e[3+0])/16);
g = CLIP8(in[1] + (g + e[3+1])/16);
b = CLIP8(in[2] + (b + e[3+2])/16);
/* get closest colour */
cache = &ImagingPaletteCache(palette, r, g, b);
@ -1236,7 +1235,7 @@ tobilevel(Imaging imOut, Imaging imIn, int dither)
for (x = 0; x < imIn->xsize; x++) {
/* 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;
/* propagate errors */
@ -1264,7 +1263,7 @@ tobilevel(Imaging imOut, Imaging imIn, int dither)
for (x = 0; x < imIn->xsize; x++, in += 4) {
/* 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;
/* propagate errors */

View File

@ -106,7 +106,7 @@ ImagingEffectNoise(int xsize, int ysize, float sigma)
this = factor * v1;
next = factor * v2;
}
out[x] = (unsigned char) (128 + sigma * this);
out[x] = CLIP8(128 + sigma * this);
}
}

View File

@ -30,6 +30,8 @@
(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.
GCC generates code with partial dependency which is 3 times slower.
See: http://stackoverflow.com/a/26588074/253146 */

View File

@ -45,8 +45,6 @@
#define Y 2
#define K 3
#define CLIP(x) ((x) <= 0 ? 0 : (x) < 256 ? (x) : 255)
/* byte-swapping macros */
#define C16N\
@ -749,9 +747,9 @@ unpackRGBa16L(UINT8* _out, const UINT8* in, int pixels)
} else if (a == 255) {
out[i] = MAKE_UINT32(in[1], in[3], in[5], a);
} else {
out[i] = MAKE_UINT32(CLIP(in[1] * 255 / a),
CLIP(in[3] * 255 / a),
CLIP(in[5] * 255 / a), a);
out[i] = MAKE_UINT32(CLIP8(in[1] * 255 / a),
CLIP8(in[3] * 255 / a),
CLIP8(in[5] * 255 / a), a);
}
in += 8;
}
@ -770,9 +768,9 @@ unpackRGBa16B(UINT8* _out, const UINT8* in, int pixels)
} else if (a == 255) {
out[i] = MAKE_UINT32(in[0], in[2], in[4], a);
} else {
out[i] = MAKE_UINT32(CLIP(in[0] * 255 / a),
CLIP(in[2] * 255 / a),
CLIP(in[4] * 255 / a), a);
out[i] = MAKE_UINT32(CLIP8(in[0] * 255 / a),
CLIP8(in[2] * 255 / a),
CLIP8(in[4] * 255 / a), a);
}
in += 8;
}
@ -791,9 +789,9 @@ unpackRGBa(UINT8* _out, const UINT8* in, int pixels)
} else if (a == 255) {
out[i] = MAKE_UINT32(in[0], in[1], in[2], a);
} else {
out[i] = MAKE_UINT32(CLIP(in[0] * 255 / a),
CLIP(in[1] * 255 / a),
CLIP(in[2] * 255 / a), a);
out[i] = MAKE_UINT32(CLIP8(in[0] * 255 / a),
CLIP8(in[1] * 255 / a),
CLIP8(in[2] * 255 / a), a);
}
in += 4;
}
@ -812,9 +810,9 @@ unpackBGRa(UINT8* _out, const UINT8* in, int pixels)
} else if (a == 255) {
out[i] = MAKE_UINT32(in[2], in[1], in[0], a);
} else {
out[i] = MAKE_UINT32(CLIP(in[2] * 255 / a),
CLIP(in[1] * 255 / a),
CLIP(in[0] * 255 / a), a);
out[i] = MAKE_UINT32(CLIP8(in[2] * 255 / a),
CLIP8(in[1] * 255 / a),
CLIP8(in[0] * 255 / a), a);
}
in += 4;
}