From 220bfee19a98a0d5b3fe5a52b51df16dd459c397 Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Fri, 29 Jun 2018 22:33:08 +0200 Subject: [PATCH 1/2] replace copy operations with memcpy() This replaces trivial instances where a copy from one pointer to the other involves no further calculations or casts. The compiler will optimize this to whatever the platform offers. --- src/libImaging/Access.c | 35 +++++++++++++---------------------- src/libImaging/Draw.c | 3 +-- src/libImaging/Filter.c | 5 ++--- src/libImaging/Geometry.c | 2 +- src/libImaging/GetBBox.c | 4 ++-- src/libImaging/Histo.c | 4 ++-- src/libImaging/Unpack.c | 4 ++-- 7 files changed, 23 insertions(+), 34 deletions(-) diff --git a/src/libImaging/Access.c b/src/libImaging/Access.c index 292968f1c..8d27a0ab3 100644 --- a/src/libImaging/Access.c +++ b/src/libImaging/Access.c @@ -94,11 +94,11 @@ static void get_pixel_16L(Imaging im, int x, int y, void* color) { UINT8* in = (UINT8*) &im->image[y][x+x]; - UINT16* out = color; #ifdef WORDS_BIGENDIAN + UINT16* out = color; out[0] = in[0] + (in[1]<<8); #else - out[0] = *(UINT16*) in; + memcpy(color, in, sizeof(UINT16)); #endif } @@ -106,10 +106,10 @@ static void get_pixel_16B(Imaging im, int x, int y, void* color) { UINT8* in = (UINT8*) &im->image[y][x+x]; - UINT16* out = color; #ifdef WORDS_BIGENDIAN - out[0] = *(UINT16*) in; + memcpy(color, in, sizeof(UINT16)); #else + UINT16* out = color; out[0] = in[1] + (in[0]<<8); #endif } @@ -117,19 +117,18 @@ get_pixel_16B(Imaging im, int x, int y, void* color) static void get_pixel_32(Imaging im, int x, int y, void* color) { - INT32* out = color; - out[0] = im->image32[y][x]; + memcpy(color, &im->image32[y][x], sizeof(INT32)); } static void get_pixel_32L(Imaging im, int x, int y, void* color) { UINT8* in = (UINT8*) &im->image[y][x*4]; - INT32* out = color; #ifdef WORDS_BIGENDIAN + INT32* out = color; out[0] = in[0] + (in[1]<<8) + (in[2]<<16) + (in[3]<<24); #else - out[0] = *(INT32*) in; + memcpy(color, in, sizeof(INT32)); #endif } @@ -137,10 +136,10 @@ static void get_pixel_32B(Imaging im, int x, int y, void* color) { UINT8* in = (UINT8*) &im->image[y][x*4]; - INT32* out = color; #ifdef WORDS_BIGENDIAN - out[0] = *(INT32*) in; + memcpy(color, in, sizeof(INT32)); #else + INT32* out = color; out[0] = in[3] + (in[2]<<8) + (in[1]<<16) + (in[0]<<24); #endif } @@ -153,7 +152,7 @@ put_pixel(Imaging im, int x, int y, const void* color) if (im->image8) im->image8[y][x] = *((UINT8*) color); else - im->image32[y][x] = *((INT32*) color); + memcpy(&im->image32[y][x], color, sizeof(INT32)); } static void @@ -165,10 +164,7 @@ put_pixel_8(Imaging im, int x, int y, const void* color) static void put_pixel_16L(Imaging im, int x, int y, const void* color) { - const char* in = color; - UINT8* out = (UINT8*) &im->image8[y][x+x]; - out[0] = in[0]; - out[1] = in[1]; + memcpy(&im->image8[y][x+x], color, 2); } static void @@ -183,12 +179,7 @@ put_pixel_16B(Imaging im, int x, int y, const void* color) static void put_pixel_32L(Imaging im, int x, int y, const void* color) { - const char* in = color; - UINT8* out = (UINT8*) &im->image8[y][x*4]; - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = in[3]; + memcpy(&im->image8[y][x*4], color, 4); } static void @@ -205,7 +196,7 @@ put_pixel_32B(Imaging im, int x, int y, const void* color) static void put_pixel_32(Imaging im, int x, int y, const void* color) { - im->image32[y][x] = *((INT32*) color); + memcpy(&im->image32[y][x], color, sizeof(INT32)); } void diff --git a/src/libImaging/Draw.c b/src/libImaging/Draw.c index 6bcd1d2b3..37e84c12e 100644 --- a/src/libImaging/Draw.c +++ b/src/libImaging/Draw.c @@ -40,7 +40,6 @@ #define FLOOR(v) ((v) >= 0.0 ? (int) (v) : (int) floor(v)) #define INK8(ink) (*(UINT8*)ink) -#define INK32(ink) (*(INT32*)ink) /* * Rounds around zero (up=away from zero, down=torwards zero) @@ -555,7 +554,7 @@ DRAW draw32rgba = { point32rgba, hline32rgba, line32rgba, polygon32rgba }; ink = INK8(ink_);\ } else {\ draw = (op) ? &draw32rgba : &draw32; \ - ink = INK32(ink_);\ + memcpy(&ink, ink_, sizeof(ink)); \ } int diff --git a/src/libImaging/Filter.c b/src/libImaging/Filter.c index 6e4a00501..64010eeef 100644 --- a/src/libImaging/Filter.c +++ b/src/libImaging/Filter.c @@ -124,7 +124,7 @@ ImagingFilter3x3(Imaging imOut, Imaging im, const float* kernel, UINT8* in1 = (UINT8*) im->image[y+1]; UINT32* out = (UINT32*) imOut->image[y]; - out[0] = ((UINT32*) in0)[0]; + memcpy(out, in0, sizeof(UINT32)); if (im->bands == 2) { for (x = 1; x < im->xsize-1; x++) { float ss0 = offset; @@ -234,8 +234,7 @@ ImagingFilter5x5(Imaging imOut, Imaging im, const float* kernel, UINT8* in2 = (UINT8*) im->image[y+2]; UINT32* out = (UINT32*) imOut->image[y]; - out[0] = ((UINT32*) in0)[0]; - out[1] = ((UINT32*) in0)[1]; + memcpy(out, in0, sizeof(UINT32) * 2); if (im->bands == 2) { for (x = 2; x < im->xsize-2; x++) { float ss0 = offset; diff --git a/src/libImaging/Geometry.c b/src/libImaging/Geometry.c index 23236a971..d78546314 100644 --- a/src/libImaging/Geometry.c +++ b/src/libImaging/Geometry.c @@ -439,7 +439,7 @@ nearest_filter32(void* out, Imaging im, double xin, double yin) int y = COORD(yin); if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) return 0; - ((INT32*)out)[0] = im->image32[y][x]; + memcpy(out, &im->image32[y][x], sizeof(INT32)); return 1; } diff --git a/src/libImaging/GetBBox.c b/src/libImaging/GetBBox.c index 3cfa42c48..5cfb795df 100644 --- a/src/libImaging/GetBBox.c +++ b/src/libImaging/GetBBox.c @@ -146,7 +146,7 @@ ImagingGetExtrema(Imaging im, void *extrema) imax = in[x]; } } - ((INT32*) extrema)[0] = imin; + memcpy(extrema, &imin, sizeof(imin)); ((INT32*) extrema)[1] = imax; break; case IMAGING_TYPE_FLOAT32: @@ -160,7 +160,7 @@ ImagingGetExtrema(Imaging im, void *extrema) fmax = in[x]; } } - ((FLOAT32*) extrema)[0] = fmin; + memcpy(extrema, &fmin, sizeof(fmin)); ((FLOAT32*) extrema)[1] = fmax; break; case IMAGING_TYPE_SPECIAL: diff --git a/src/libImaging/Histo.c b/src/libImaging/Histo.c index b7c1a9834..589277a51 100644 --- a/src/libImaging/Histo.c +++ b/src/libImaging/Histo.c @@ -130,7 +130,7 @@ ImagingGetHistogram(Imaging im, Imaging imMask, void* minmax) } if (!im->xsize || !im->ysize) break; - imin = ((INT32*) minmax)[0]; + memcpy(&imin, minmax, sizeof(imin)); imax = ((INT32*) minmax)[1]; if (imin >= imax) break; @@ -153,7 +153,7 @@ ImagingGetHistogram(Imaging im, Imaging imMask, void* minmax) } if (!im->xsize || !im->ysize) break; - fmin = ((FLOAT32*) minmax)[0]; + memcpy(&fmin, minmax, sizeof(fmin)); fmax = ((FLOAT32*) minmax)[1]; if (fmin >= fmax) break; diff --git a/src/libImaging/Unpack.c b/src/libImaging/Unpack.c index c1e8f25d0..2edf76619 100644 --- a/src/libImaging/Unpack.c +++ b/src/libImaging/Unpack.c @@ -1048,7 +1048,7 @@ unpackI12_I16(UINT8* out, const UINT8* in, int pixels){ #ifdef WORDS_BIGENDIAN out[0] = tmp[1]; out[1] = tmp[0]; #else - out16[0] = pixel; + memcpy(out, &pixel, sizeof(pixel)); #endif pixel = (((UINT16) (in[1] & 0x0F)) << 8) + in[2]; @@ -1065,7 +1065,7 @@ unpackI12_I16(UINT8* out, const UINT8* in, int pixels){ #ifdef WORDS_BIGENDIAN out[0] = tmp[1]; out[1] = tmp[0]; #else - out16[0] = pixel; + memcpy(out, &pixel, sizeof(pixel)); #endif } } From 7a4af2b7671b14163f61c7f88889fad66e50d77b Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Sun, 1 Jul 2018 12:47:59 +0200 Subject: [PATCH 2/2] fix unaligned accesses by using memcpy() --- src/_imaging.c | 31 +++-- src/libImaging/Access.c | 16 +-- src/libImaging/Bands.c | 30 +++-- src/libImaging/ColorLUT.c | 10 +- src/libImaging/Convert.c | 165 +++++++++++++---------- src/libImaging/Filter.c | 33 +++-- src/libImaging/Geometry.c | 18 ++- src/libImaging/GetBBox.c | 24 ++-- src/libImaging/Histo.c | 4 +- src/libImaging/Pack.c | 13 +- src/libImaging/Point.c | 16 ++- src/libImaging/Resample.c | 30 +++-- src/libImaging/SgiRleDecode.c | 19 +-- src/libImaging/Unpack.c | 243 +++++++++++++++------------------- 14 files changed, 353 insertions(+), 299 deletions(-) diff --git a/src/_imaging.c b/src/_imaging.c index d6cf562da..e63da27e9 100644 --- a/src/_imaging.c +++ b/src/_imaging.c @@ -382,7 +382,8 @@ getlist(PyObject* arg, Py_ssize_t* length, const char* wrong_length, int type) Py_ssize_t i, n; int itemp; double dtemp; - void* list; + FLOAT32 ftemp; + UINT8* list; PyObject* seq; PyObject* op; @@ -416,19 +417,19 @@ 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] = CLIP8(itemp); + list[i] = CLIP8(itemp); break; case TYPE_INT32: itemp = PyInt_AsLong(op); - ((INT32*)list)[i] = itemp; + memcpy(list + i * sizeof(INT32), &itemp, sizeof(itemp)); break; case TYPE_FLOAT32: - dtemp = PyFloat_AsDouble(op); - ((FLOAT32*)list)[i] = (FLOAT32) dtemp; + ftemp = (FLOAT32)PyFloat_AsDouble(op); + memcpy(list + i * sizeof(ftemp), &ftemp, sizeof(ftemp)); break; case TYPE_DOUBLE: dtemp = PyFloat_AsDouble(op); - ((double*)list)[i] = (double) dtemp; + memcpy(list + i * sizeof(dtemp), &dtemp, sizeof(dtemp)); break; } } @@ -532,6 +533,8 @@ getink(PyObject* color, Imaging im, char* ink) to return it into a 32 bit C long */ PY_LONG_LONG r = 0; + FLOAT32 ftmp; + INT32 itmp; /* fill ink buffer (four bytes) with something that can be cast to either UINT8 or INT32 */ @@ -597,14 +600,16 @@ getink(PyObject* color, Imaging im, char* ink) /* signed integer */ if (rIsInt != 1) return NULL; - *(INT32*) ink = r; + itmp = r; + memcpy(ink, &itmp, sizeof(itmp)); return ink; case IMAGING_TYPE_FLOAT32: /* floating point */ f = PyFloat_AsDouble(color); if (f == -1.0 && PyErr_Occurred()) return NULL; - *(FLOAT32*) ink = (FLOAT32) f; + ftmp = f; + memcpy(ink, &ftmp, sizeof(ftmp)); return ink; case IMAGING_TYPE_SPECIAL: if (strncmp(im->mode, "I;16", 4) == 0) { @@ -799,15 +804,19 @@ _prepare_lut_table(PyObject* table, Py_ssize_t table_size) } for (i = 0; i < table_size; i++) { + FLOAT16 htmp; + double dtmp; switch (data_type) { case TYPE_FLOAT16: - item = float16tofloat32(((FLOAT16*) table_data)[i]); + memcpy(&htmp, ((char*) table_data) + i * sizeof(htmp), sizeof(htmp)); + item = float16tofloat32(htmp); break; case TYPE_FLOAT32: - item = ((FLOAT32*) table_data)[i]; + memcpy(&item, ((char*) table_data) + i * sizeof(FLOAT32), sizeof(FLOAT32)); break; case TYPE_DOUBLE: - item = ((double*) table_data)[i]; + memcpy(&dtmp, ((char*) table_data) + i * sizeof(dtmp), sizeof(dtmp)); + item = (FLOAT32) dtmp; break; } /* Max value for INT16 */ diff --git a/src/libImaging/Access.c b/src/libImaging/Access.c index 8d27a0ab3..15ffa11fc 100644 --- a/src/libImaging/Access.c +++ b/src/libImaging/Access.c @@ -95,8 +95,8 @@ get_pixel_16L(Imaging im, int x, int y, void* color) { UINT8* in = (UINT8*) &im->image[y][x+x]; #ifdef WORDS_BIGENDIAN - UINT16* out = color; - out[0] = in[0] + (in[1]<<8); + UINT16 out = in[0] + (in[1]<<8); + memcpy(color, &out, sizeof(out)); #else memcpy(color, in, sizeof(UINT16)); #endif @@ -109,8 +109,8 @@ get_pixel_16B(Imaging im, int x, int y, void* color) #ifdef WORDS_BIGENDIAN memcpy(color, in, sizeof(UINT16)); #else - UINT16* out = color; - out[0] = in[1] + (in[0]<<8); + UINT16 out = in[1] + (in[0]<<8); + memcpy(color, &out, sizeof(out)); #endif } @@ -125,8 +125,8 @@ get_pixel_32L(Imaging im, int x, int y, void* color) { UINT8* in = (UINT8*) &im->image[y][x*4]; #ifdef WORDS_BIGENDIAN - INT32* out = color; - out[0] = in[0] + (in[1]<<8) + (in[2]<<16) + (in[3]<<24); + INT32 out = in[0] + (in[1]<<8) + (in[2]<<16) + (in[3]<<24); + memcpy(color, &out, sizeof(out)); #else memcpy(color, in, sizeof(INT32)); #endif @@ -139,8 +139,8 @@ get_pixel_32B(Imaging im, int x, int y, void* color) #ifdef WORDS_BIGENDIAN memcpy(color, in, sizeof(INT32)); #else - INT32* out = color; - out[0] = in[3] + (in[2]<<8) + (in[1]<<16) + (in[0]<<24); + INT32 out = in[3] + (in[2]<<8) + (in[1]<<16) + (in[0]<<24); + memcpy(color, &out, sizeof(out)); #endif } diff --git a/src/libImaging/Bands.c b/src/libImaging/Bands.c index e38e22819..7fff04486 100644 --- a/src/libImaging/Bands.c +++ b/src/libImaging/Bands.c @@ -50,7 +50,8 @@ ImagingGetBand(Imaging imIn, int band) UINT8* out = imOut->image8[y]; x = 0; for (; x < imIn->xsize - 3; x += 4) { - *((UINT32*) (out + x)) = MAKE_UINT32(in[0], in[4], in[8], in[12]); + UINT32 v = MAKE_UINT32(in[0], in[4], in[8], in[12]); + memcpy(out + x, &v, sizeof(v)); in += 16; } for (; x < imIn->xsize; x++) { @@ -98,8 +99,10 @@ ImagingSplit(Imaging imIn, Imaging bands[4]) UINT8* out1 = bands[1]->image8[y]; x = 0; for (; x < imIn->xsize - 3; x += 4) { - *((UINT32*) (out0 + x)) = MAKE_UINT32(in[0], in[4], in[8], in[12]); - *((UINT32*) (out1 + x)) = MAKE_UINT32(in[0+3], in[4+3], in[8+3], in[12+3]); + UINT32 v = MAKE_UINT32(in[0], in[4], in[8], in[12]); + memcpy(out0 + x, &v, sizeof(v)); + v = MAKE_UINT32(in[0+3], in[4+3], in[8+3], in[12+3]); + memcpy(out1 + x, &v, sizeof(v)); in += 16; } for (; x < imIn->xsize; x++) { @@ -116,9 +119,12 @@ ImagingSplit(Imaging imIn, Imaging bands[4]) UINT8* out2 = bands[2]->image8[y]; x = 0; for (; x < imIn->xsize - 3; x += 4) { - *((UINT32*) (out0 + x)) = MAKE_UINT32(in[0], in[4], in[8], in[12]); - *((UINT32*) (out1 + x)) = MAKE_UINT32(in[0+1], in[4+1], in[8+1], in[12+1]); - *((UINT32*) (out2 + x)) = MAKE_UINT32(in[0+2], in[4+2], in[8+2], in[12+2]); + UINT32 v = MAKE_UINT32(in[0], in[4], in[8], in[12]); + memcpy(out0 + x, &v, sizeof(v)); + v = MAKE_UINT32(in[0+1], in[4+1], in[8+1], in[12+1]); + memcpy(out1 + x, &v, sizeof(v)); + v = MAKE_UINT32(in[0+2], in[4+2], in[8+2], in[12+2]); + memcpy(out2 + x, &v, sizeof(v)); in += 16; } for (; x < imIn->xsize; x++) { @@ -137,10 +143,14 @@ ImagingSplit(Imaging imIn, Imaging bands[4]) UINT8* out3 = bands[3]->image8[y]; x = 0; for (; x < imIn->xsize - 3; x += 4) { - *((UINT32*) (out0 + x)) = MAKE_UINT32(in[0], in[4], in[8], in[12]); - *((UINT32*) (out1 + x)) = MAKE_UINT32(in[0+1], in[4+1], in[8+1], in[12+1]); - *((UINT32*) (out2 + x)) = MAKE_UINT32(in[0+2], in[4+2], in[8+2], in[12+2]); - *((UINT32*) (out3 + x)) = MAKE_UINT32(in[0+3], in[4+3], in[8+3], in[12+3]); + UINT32 v = MAKE_UINT32(in[0], in[4], in[8], in[12]); + memcpy(out0 + x, &v, sizeof(v)); + v = MAKE_UINT32(in[0+1], in[4+1], in[8+1], in[12+1]); + memcpy(out1 + x, &v, sizeof(v)); + v = MAKE_UINT32(in[0+2], in[4+2], in[8+2], in[12+2]); + memcpy(out2 + x, &v, sizeof(v)); + v = MAKE_UINT32(in[0+3], in[4+3], in[8+3], in[12+3]); + memcpy(out3 + x, &v, sizeof(v)); in += 16; } for (; x < imIn->xsize; x++) { diff --git a/src/libImaging/ColorLUT.c b/src/libImaging/ColorLUT.c index 46b00142b..f01d38993 100644 --- a/src/libImaging/ColorLUT.c +++ b/src/libImaging/ColorLUT.c @@ -105,7 +105,7 @@ ImagingColorLUT3D_linear(Imaging imOut, Imaging imIn, int table_channels, ImagingSectionEnter(&cookie); for (y = 0; y < imOut->ysize; y++) { UINT8* rowIn = (UINT8 *)imIn->image[y]; - UINT32* rowOut = (UINT32 *)imOut->image[y]; + char* rowOut = (char *)imOut->image[y]; for (x = 0; x < imOut->xsize; x++) { UINT32 index1D = rowIn[x*4 + 0] * scale1D; UINT32 index2D = rowIn[x*4 + 1] * scale2D; @@ -120,6 +120,7 @@ ImagingColorLUT3D_linear(Imaging imOut, Imaging imIn, int table_channels, INT16 leftleft[4], leftright[4], rightleft[4], rightright[4]; if (table_channels == 3) { + UINT32 v; interpolate3(leftleft, &table[idx + 0], &table[idx + 3], shift1D); interpolate3(leftright, &table[idx + size1D*3], &table[idx + size1D*3 + 3], shift1D); @@ -133,12 +134,14 @@ ImagingColorLUT3D_linear(Imaging imOut, Imaging imIn, int table_channels, interpolate3(result, left, right, shift3D); - rowOut[x] = MAKE_UINT32( + v = MAKE_UINT32( clip8(result[0]), clip8(result[1]), clip8(result[2]), rowIn[x*4 + 3]); + memcpy(rowOut + x * sizeof(v), &v, sizeof(v)); } if (table_channels == 4) { + UINT32 v; interpolate4(leftleft, &table[idx + 0], &table[idx + 4], shift1D); interpolate4(leftright, &table[idx + size1D*4], &table[idx + size1D*4 + 4], shift1D); @@ -152,9 +155,10 @@ ImagingColorLUT3D_linear(Imaging imOut, Imaging imIn, int table_channels, interpolate4(result, left, right, shift3D); - rowOut[x] = MAKE_UINT32( + v = MAKE_UINT32( clip8(result[0]), clip8(result[1]), clip8(result[2]), clip8(result[3])); + memcpy(rowOut + x * sizeof(v), &v, sizeof(v)); } } } diff --git a/src/libImaging/Convert.c b/src/libImaging/Convert.c index a6fefca32..038a83fe5 100644 --- a/src/libImaging/Convert.c +++ b/src/libImaging/Convert.c @@ -229,42 +229,46 @@ static void rgb2i(UINT8* out_, const UINT8* in, int xsize) { int x; - INT32* out = (INT32*) out_; - for (x = 0; x < xsize; x++, in += 4) - *out++ = L24(in) >> 16; + for (x = 0; x < xsize; x++, in += 4, out_ += 4) { + INT32 v = L24(in) >> 16; + memcpy(out_, &v, sizeof(v)); + } } static void rgb2f(UINT8* out_, const UINT8* in, int xsize) { int x; - FLOAT32* out = (FLOAT32*) out_; - for (x = 0; x < xsize; x++, in += 4) - *out++ = (float) L(in) / 1000.0F; + for (x = 0; x < xsize; x++, in += 4, out_ += 4) { + FLOAT32 v = (float) L(in) / 1000.0F; + memcpy(out_, &v, sizeof(v)); + } } static void rgb2bgr15(UINT8* out_, const UINT8* in, int xsize) { int x; - UINT16* out = (UINT16*) out_; - for (x = 0; x < xsize; x++, in += 4) - *out++ = + for (x = 0; x < xsize; x++, in += 4, out_ += 2) { + UINT16 v = ((((UINT16)in[0])<<7)&0x7c00) + ((((UINT16)in[1])<<2)&0x03e0) + ((((UINT16)in[2])>>3)&0x001f); + memcpy(out_, &v, sizeof(v)); + } } static void rgb2bgr16(UINT8* out_, const UINT8* in, int xsize) { int x; - UINT16* out = (UINT16*) out_; - for (x = 0; x < xsize; x++, in += 4) - *out++ = + for (x = 0; x < xsize; x++, in += 4, out_ += 2) { + UINT16 v = ((((UINT16)in[0])<<8)&0xf800) + ((((UINT16)in[1])<<3)&0x07e0) + ((((UINT16)in[2])>>3)&0x001f); + memcpy(out_, &v, sizeof(v)); + } } static void @@ -490,12 +494,13 @@ rgbT2rgba(UINT8* out, int xsize, int r, int g, int b) UINT32 repl = trns & 0x00ffffff; #endif - UINT32* tmp = (UINT32 *)out; int i; - for (i=0; i < xsize; i++ ,tmp++) { - if (tmp[0]==trns) { - tmp[0]=repl; + for (i=0; i < xsize; i++ ,out += sizeof(trns)) { + UINT32 v; + memcpy(&v, out, sizeof(v)); + if (v==trns) { + memcpy(out, &repl, sizeof(repl)); } } } @@ -565,32 +570,35 @@ static void bit2i(UINT8* out_, const UINT8* in, int xsize) { int x; - INT32* out = (INT32*) out_; - for (x = 0; x < xsize; x++) - *out++ = (*in++ != 0) ? 255 : 0; + for (x = 0; x < xsize; x++, out_ += 4) { + INT32 v = (*in++ != 0) ? 255 : 0; + memcpy(out_, &v, sizeof(v)); + } } static void l2i(UINT8* out_, const UINT8* in, int xsize) { int x; - INT32* out = (INT32*) out_; - for (x = 0; x < xsize; x++) - *out++ = (INT32) *in++; + for (x = 0; x < xsize; x++, out_ += 4) { + INT32 v = *in++; + memcpy(out_, &v, sizeof(v)); + } } static void i2l(UINT8* out, const UINT8* in_, int xsize) { int x; - INT32* in = (INT32*) in_; - for (x = 0; x < xsize; x++, in++, out++) { - if (*in <= 0) + for (x = 0; x < xsize; x++, out++, in_ += 4) { + INT32 v; + memcpy(&v, in_, sizeof(v)); + if (v <= 0) *out = 0; - else if (*in >= 255) + else if (v >= 255) *out = 255; else - *out = (UINT8) *in; + *out = (UINT8) v; } } @@ -598,10 +606,13 @@ static void i2f(UINT8* out_, const UINT8* in_, int xsize) { int x; - INT32* in = (INT32*) in_; - FLOAT32* out = (FLOAT32*) out_; - for (x = 0; x < xsize; x++) - *out++ = (FLOAT32) *in++; + for (x = 0; x < xsize; x++, in_ += 4, out_ += 4) { + INT32 i; + FLOAT32 f; + memcpy(&i, in_, sizeof(i)); + f = i; + memcpy(out_, &f, sizeof(f)); + } } static void @@ -628,32 +639,35 @@ static void bit2f(UINT8* out_, const UINT8* in, int xsize) { int x; - FLOAT32* out = (FLOAT32*) out_; - for (x = 0; x < xsize; x++) - *out++ = (*in++ != 0) ? 255.0F : 0.0F; + for (x = 0; x < xsize; x++, out_ += 4) { + FLOAT32 f = (*in++ != 0) ? 255.0F : 0.0F; + memcpy(out_, &f, sizeof(f)); + } } static void l2f(UINT8* out_, const UINT8* in, int xsize) { int x; - FLOAT32* out = (FLOAT32*) out_; - for (x = 0; x < xsize; x++) - *out++ = (FLOAT32) *in++; + for (x = 0; x < xsize; x++, out_ += 4) { + FLOAT32 f = (FLOAT32) *in++; + memcpy(out_, &f, sizeof(f)); + } } static void f2l(UINT8* out, const UINT8* in_, int xsize) { int x; - FLOAT32* in = (FLOAT32*) in_; - for (x = 0; x < xsize; x++, in++, out++) { - if (*in <= 0.0) + for (x = 0; x < xsize; x++, out++, in_ += 4) { + FLOAT32 v; + memcpy(&v, in_, sizeof(v)); + if (v <= 0.0) *out = 0; - else if (*in >= 255.0) + else if (v >= 255.0) *out = 255; else - *out = (UINT8) *in; + *out = (UINT8) v; } } @@ -661,10 +675,13 @@ static void f2i(UINT8* out_, const UINT8* in_, int xsize) { int x; - FLOAT32* in = (FLOAT32*) in_; - INT32* out = (INT32*) out_; - for (x = 0; x < xsize; x++) - *out++ = (INT32) *in++; + for (x = 0; x < xsize; x++, in_ += 4, out_ += 4) { + FLOAT32 f; + INT32 i; + memcpy(&f, in_, sizeof(f)); + i = f; + memcpy(out_, &i, sizeof(i)); + } } /* ----------------- */ @@ -723,9 +740,10 @@ static void I_I16L(UINT8* out, const UINT8* in_, int xsize) { int x, v; - INT32* in = (INT32*) in_; - for (x = 0; x < xsize; x++, in++) { - v = CLIP16(*in); + for (x = 0; x < xsize; x++, in_ += 4) { + INT32 i; + memcpy(&i, in_, sizeof(i)); + v = CLIP16(i); *out++ = (UINT8) v; *out++ = (UINT8) (v >> 8); } @@ -735,9 +753,10 @@ static void I_I16B(UINT8* out, const UINT8* in_, int xsize) { int x, v; - INT32* in = (INT32*) in_; - for (x = 0; x < xsize; x++, in++) { - v = CLIP16(*in); + for (x = 0; x < xsize; x++, in_ += 4) { + INT32 i; + memcpy(&i, in_, sizeof(i)); + v = CLIP16(i); *out++ = (UINT8) (v >> 8); *out++ = (UINT8) v; } @@ -748,9 +767,10 @@ static void I16L_I(UINT8* out_, const UINT8* in, int xsize) { int x; - INT32* out = (INT32*) out_; - for (x = 0; x < xsize; x++, in += 2) - *out++ = in[0] + ((int) in[1] << 8); + for (x = 0; x < xsize; x++, in += 2, out_ += 4) { + INT32 v = in[0] + ((int) in[1] << 8); + memcpy(out_, &v, sizeof(v)); + } } @@ -758,18 +778,20 @@ static void I16B_I(UINT8* out_, const UINT8* in, int xsize) { int x; - INT32* out = (INT32*) out_; - for (x = 0; x < xsize; x++, in += 2) - *out++ = in[1] + ((int) in[0] << 8); + for (x = 0; x < xsize; x++, in += 2, out_ += 4) { + INT32 v = in[1] + ((int) in[0] << 8); + memcpy(out_, &v, sizeof(v)); + } } static void I16L_F(UINT8* out_, const UINT8* in, int xsize) { int x; - FLOAT32* out = (FLOAT32*) out_; - for (x = 0; x < xsize; x++, in += 2) - *out++ = (FLOAT32) (in[0] + ((int) in[1] << 8)); + for (x = 0; x < xsize; x++, in += 2, out_ += 4) { + FLOAT32 v = in[0] + ((int) in[1] << 8); + memcpy(out_, &v, sizeof(v)); + } } @@ -777,9 +799,10 @@ static void I16B_F(UINT8* out_, const UINT8* in, int xsize) { int x; - FLOAT32* out = (FLOAT32*) out_; - for (x = 0; x < xsize; x++, in += 2) - *out++ = (FLOAT32) (in[1] + ((int) in[0] << 8)); + for (x = 0; x < xsize; x++, in += 2, out_ += 4) { + FLOAT32 v = in[1] + ((int) in[0] << 8); + memcpy(out_, &v, sizeof(v)); + } } static void @@ -1018,9 +1041,10 @@ static void p2i(UINT8* out_, const UINT8* in, int xsize, const UINT8* palette) { int x; - INT32* out = (INT32*) out_; - for (x = 0; x < xsize; x++) - *out++ = L(&palette[in[x]*4]) / 1000; + for (x = 0; x < xsize; x++, in += 2, out_ += 4) { + INT32 v = L(&palette[in[x]*4]) / 1000; + memcpy(out_, &v, sizeof(v)); + } } static void @@ -1036,9 +1060,10 @@ static void p2f(UINT8* out_, const UINT8* in, int xsize, const UINT8* palette) { int x; - FLOAT32* out = (FLOAT32*) out_; - for (x = 0; x < xsize; x++) - *out++ = (float) L(&palette[in[x]*4]) / 1000.0F; + for (x = 0; x < xsize; x++, in += 2, out_ += 4) { + FLOAT32 v = L(&palette[in[x]*4]) / 1000.0F; + memcpy(out_, &v, sizeof(v)); + } } static void diff --git a/src/libImaging/Filter.c b/src/libImaging/Filter.c index 64010eeef..b033abf66 100644 --- a/src/libImaging/Filter.c +++ b/src/libImaging/Filter.c @@ -122,26 +122,29 @@ ImagingFilter3x3(Imaging imOut, Imaging im, const float* kernel, UINT8* in_1 = (UINT8*) im->image[y-1]; UINT8* in0 = (UINT8*) im->image[y]; UINT8* in1 = (UINT8*) im->image[y+1]; - UINT32* out = (UINT32*) imOut->image[y]; + UINT8* out = (UINT8*) imOut->image[y]; memcpy(out, in0, sizeof(UINT32)); if (im->bands == 2) { for (x = 1; x < im->xsize-1; x++) { float ss0 = offset; float ss3 = offset; + UINT32 v; ss0 += KERNEL1x3(in1, x*4+0, &kernel[0], 4); ss3 += KERNEL1x3(in1, x*4+3, &kernel[0], 4); ss0 += KERNEL1x3(in0, x*4+0, &kernel[3], 4); ss3 += KERNEL1x3(in0, x*4+3, &kernel[3], 4); ss0 += KERNEL1x3(in_1, x*4+0, &kernel[6], 4); ss3 += KERNEL1x3(in_1, x*4+3, &kernel[6], 4); - out[x] = MAKE_UINT32(clip8(ss0), 0, 0, clip8(ss3)); + v = MAKE_UINT32(clip8(ss0), 0, 0, clip8(ss3)); + memcpy(out + x * sizeof(v), &v, sizeof(v)); } } else if (im->bands == 3) { for (x = 1; x < im->xsize-1; x++) { float ss0 = offset; float ss1 = offset; float ss2 = offset; + UINT32 v; ss0 += KERNEL1x3(in1, x*4+0, &kernel[0], 4); ss1 += KERNEL1x3(in1, x*4+1, &kernel[0], 4); ss2 += KERNEL1x3(in1, x*4+2, &kernel[0], 4); @@ -151,8 +154,9 @@ ImagingFilter3x3(Imaging imOut, Imaging im, const float* kernel, ss0 += KERNEL1x3(in_1, x*4+0, &kernel[6], 4); ss1 += KERNEL1x3(in_1, x*4+1, &kernel[6], 4); ss2 += KERNEL1x3(in_1, x*4+2, &kernel[6], 4); - out[x] = MAKE_UINT32( + v = MAKE_UINT32( clip8(ss0), clip8(ss1), clip8(ss2), 0); + memcpy(out + x * sizeof(v), &v, sizeof(v)); } } else if (im->bands == 4) { for (x = 1; x < im->xsize-1; x++) { @@ -160,6 +164,7 @@ ImagingFilter3x3(Imaging imOut, Imaging im, const float* kernel, float ss1 = offset; float ss2 = offset; float ss3 = offset; + UINT32 v; ss0 += KERNEL1x3(in1, x*4+0, &kernel[0], 4); ss1 += KERNEL1x3(in1, x*4+1, &kernel[0], 4); ss2 += KERNEL1x3(in1, x*4+2, &kernel[0], 4); @@ -172,11 +177,12 @@ ImagingFilter3x3(Imaging imOut, Imaging im, const float* kernel, ss1 += KERNEL1x3(in_1, x*4+1, &kernel[6], 4); ss2 += KERNEL1x3(in_1, x*4+2, &kernel[6], 4); ss3 += KERNEL1x3(in_1, x*4+3, &kernel[6], 4); - out[x] = MAKE_UINT32( + v = MAKE_UINT32( clip8(ss0), clip8(ss1), clip8(ss2), clip8(ss3)); + memcpy(out + x * sizeof(v), &v, sizeof(v)); } } - out[x] = ((UINT32*) in0)[x]; + memcpy(out + x * sizeof(UINT32), in0 + x * sizeof(UINT32), sizeof(UINT32)); } } memcpy(imOut->image[y], im->image[y], im->linesize); @@ -232,13 +238,14 @@ ImagingFilter5x5(Imaging imOut, Imaging im, const float* kernel, UINT8* in0 = (UINT8*) im->image[y]; UINT8* in1 = (UINT8*) im->image[y+1]; UINT8* in2 = (UINT8*) im->image[y+2]; - UINT32* out = (UINT32*) imOut->image[y]; + UINT8* out = (UINT8*) imOut->image[y]; memcpy(out, in0, sizeof(UINT32) * 2); if (im->bands == 2) { for (x = 2; x < im->xsize-2; x++) { float ss0 = offset; float ss3 = offset; + UINT32 v; ss0 += KERNEL1x5(in2, x*4+0, &kernel[0], 4); ss3 += KERNEL1x5(in2, x*4+3, &kernel[0], 4); ss0 += KERNEL1x5(in1, x*4+0, &kernel[5], 4); @@ -249,13 +256,15 @@ ImagingFilter5x5(Imaging imOut, Imaging im, const float* kernel, ss3 += KERNEL1x5(in_1, x*4+3, &kernel[15], 4); ss0 += KERNEL1x5(in_2, x*4+0, &kernel[20], 4); ss3 += KERNEL1x5(in_2, x*4+3, &kernel[20], 4); - out[x] = MAKE_UINT32(clip8(ss0), 0, 0, clip8(ss3)); + v = MAKE_UINT32(clip8(ss0), 0, 0, clip8(ss3)); + memcpy(out + x * sizeof(v), &v, sizeof(v)); } } else if (im->bands == 3) { for (x = 2; x < im->xsize-2; x++) { float ss0 = offset; float ss1 = offset; float ss2 = offset; + UINT32 v; ss0 += KERNEL1x5(in2, x*4+0, &kernel[0], 4); ss1 += KERNEL1x5(in2, x*4+1, &kernel[0], 4); ss2 += KERNEL1x5(in2, x*4+2, &kernel[0], 4); @@ -271,8 +280,9 @@ ImagingFilter5x5(Imaging imOut, Imaging im, const float* kernel, ss0 += KERNEL1x5(in_2, x*4+0, &kernel[20], 4); ss1 += KERNEL1x5(in_2, x*4+1, &kernel[20], 4); ss2 += KERNEL1x5(in_2, x*4+2, &kernel[20], 4); - out[x] = MAKE_UINT32( + v = MAKE_UINT32( clip8(ss0), clip8(ss1), clip8(ss2), 0); + memcpy(out + x * sizeof(v), &v, sizeof(v)); } } else if (im->bands == 4) { for (x = 2; x < im->xsize-2; x++) { @@ -280,6 +290,7 @@ ImagingFilter5x5(Imaging imOut, Imaging im, const float* kernel, float ss1 = offset; float ss2 = offset; float ss3 = offset; + UINT32 v; ss0 += KERNEL1x5(in2, x*4+0, &kernel[0], 4); ss1 += KERNEL1x5(in2, x*4+1, &kernel[0], 4); ss2 += KERNEL1x5(in2, x*4+2, &kernel[0], 4); @@ -300,12 +311,12 @@ ImagingFilter5x5(Imaging imOut, Imaging im, const float* kernel, ss1 += KERNEL1x5(in_2, x*4+1, &kernel[20], 4); ss2 += KERNEL1x5(in_2, x*4+2, &kernel[20], 4); ss3 += KERNEL1x5(in_2, x*4+3, &kernel[20], 4); - out[x] = MAKE_UINT32( + v = MAKE_UINT32( clip8(ss0), clip8(ss1), clip8(ss2), clip8(ss3)); + memcpy(out + x * sizeof(v), &v, sizeof(v)); } } - out[x] = ((UINT32*) in0)[x]; - out[x+1] = ((UINT32*) in0)[x+1]; + memcpy(out + x * sizeof(UINT32), in0 + x * sizeof(UINT32), sizeof(UINT32) * 2); } } memcpy(imOut->image[y], im->image[y], im->linesize); diff --git a/src/libImaging/Geometry.c b/src/libImaging/Geometry.c index d78546314..fd5e25958 100644 --- a/src/libImaging/Geometry.c +++ b/src/libImaging/Geometry.c @@ -428,7 +428,7 @@ nearest_filter16(void* out, Imaging im, double xin, double yin) int y = COORD(yin); if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) return 0; - ((INT16*)out)[0] = ((INT16*)(im->image8[y]))[x]; + memcpy(out, im->image8[y] + x * sizeof(INT16), sizeof(INT16)); return 1; } @@ -489,18 +489,22 @@ bilinear_filter8(void* out, Imaging im, double xin, double yin) static int bilinear_filter32I(void* out, Imaging im, double xin, double yin) { + INT32 k; BILINEAR_HEAD(INT32); BILINEAR_BODY(INT32, im->image32, 1, 0); - ((INT32*)out)[0] = (INT32) v1; + k = v1; + memcpy(out, &k, sizeof(k)); return 1; } static int bilinear_filter32F(void* out, Imaging im, double xin, double yin) { + FLOAT32 k; BILINEAR_HEAD(FLOAT32); BILINEAR_BODY(FLOAT32, im->image32, 1, 0); - ((FLOAT32*)out)[0] = (FLOAT32) v1; + k = v1; + memcpy(out, &k, sizeof(k)); return 1; } @@ -601,18 +605,22 @@ bicubic_filter8(void* out, Imaging im, double xin, double yin) static int bicubic_filter32I(void* out, Imaging im, double xin, double yin) { + INT32 k; BICUBIC_HEAD(INT32); BICUBIC_BODY(INT32, im->image32, 1, 0); - ((INT32*)out)[0] = (INT32) v1; + k = v1; + memcpy(out, &k, sizeof(k)); return 1; } static int bicubic_filter32F(void* out, Imaging im, double xin, double yin) { + FLOAT32 k; BICUBIC_HEAD(FLOAT32); BICUBIC_BODY(FLOAT32, im->image32, 1, 0); - ((FLOAT32*)out)[0] = (FLOAT32) v1; + k = v1; + memcpy(out, &k, sizeof(k)); return 1; } diff --git a/src/libImaging/GetBBox.c b/src/libImaging/GetBBox.c index 5cfb795df..b63888f87 100644 --- a/src/libImaging/GetBBox.c +++ b/src/libImaging/GetBBox.c @@ -147,7 +147,7 @@ ImagingGetExtrema(Imaging im, void *extrema) } } memcpy(extrema, &imin, sizeof(imin)); - ((INT32*) extrema)[1] = imax; + memcpy(((char*)extrema) + sizeof(imin), &imax, sizeof(imax)); break; case IMAGING_TYPE_FLOAT32: fmin = fmax = ((FLOAT32*) im->image32[0])[0]; @@ -161,22 +161,26 @@ ImagingGetExtrema(Imaging im, void *extrema) } } memcpy(extrema, &fmin, sizeof(fmin)); - ((FLOAT32*) extrema)[1] = fmax; + memcpy(((char*)extrema) + sizeof(fmin), &fmax, sizeof(fmax)); break; case IMAGING_TYPE_SPECIAL: if (strcmp(im->mode, "I;16") == 0) { - imin = imax = ((UINT16*) im->image8[0])[0]; + UINT16 v; + memcpy(&v, *im->image8, sizeof(v)); + imin = imax = v; for (y = 0; y < im->ysize; y++) { - UINT16* in = (UINT16 *) im->image[y]; for (x = 0; x < im->xsize; x++) { - if (imin > in[x]) - imin = in[x]; - else if (imax < in[x]) - imax = in[x]; + memcpy(&v, im->image[y] + x * sizeof(v), sizeof(v)); + if (imin > v) + imin = v; + else if (imax < v) + imax = v; } } - ((UINT16*) extrema)[0] = (UINT16) imin; - ((UINT16*) extrema)[1] = (UINT16) imax; + v = (UINT16) imin; + memcpy(extrema, &v, sizeof(v)); + v = (UINT16) imax; + memcpy(((char*)extrema) + sizeof(v), &v, sizeof(v)); break; } /* FALL THROUGH */ diff --git a/src/libImaging/Histo.c b/src/libImaging/Histo.c index 589277a51..5c2824ab0 100644 --- a/src/libImaging/Histo.c +++ b/src/libImaging/Histo.c @@ -131,7 +131,7 @@ ImagingGetHistogram(Imaging im, Imaging imMask, void* minmax) if (!im->xsize || !im->ysize) break; memcpy(&imin, minmax, sizeof(imin)); - imax = ((INT32*) minmax)[1]; + memcpy(&imax, ((char*)minmax) + sizeof(imin), sizeof(imax)); if (imin >= imax) break; ImagingSectionEnter(&cookie); @@ -154,7 +154,7 @@ ImagingGetHistogram(Imaging im, Imaging imMask, void* minmax) if (!im->xsize || !im->ysize) break; memcpy(&fmin, minmax, sizeof(fmin)); - fmax = ((FLOAT32*) minmax)[1]; + memcpy(&fmax, ((char*)minmax) + sizeof(fmin), sizeof(fmax)); if (fmin >= fmax) break; ImagingSectionEnter(&cookie); diff --git a/src/libImaging/Pack.c b/src/libImaging/Pack.c index 000ee384a..eaa276af4 100644 --- a/src/libImaging/Pack.c +++ b/src/libImaging/Pack.c @@ -261,7 +261,7 @@ ImagingPackRGB(UINT8* out, const UINT8* in, int pixels) } #else for (; i < pixels-1; i++) { - ((UINT32*)out)[0] = ((UINT32*)in)[i]; + memcpy(out, in + i * 4, 4); out += 3; } for (; i < pixels; i++) { @@ -402,18 +402,19 @@ static void packI16B(UINT8* out, const UINT8* in_, int pixels) { int i; - INT32* in = (INT32*) in_; UINT16 tmp_; UINT8* tmp = (UINT8*) &tmp_; for (i = 0; i < pixels; i++) { - if (in[0] <= 0) + INT32 in; + memcpy(&in, in_, sizeof(in)); + if (in <= 0) tmp_ = 0; - else if (in[0] > 65535) + else if (in > 65535) tmp_ = 65535; else - tmp_ = in[0]; + tmp_ = in; C16B; - out += 2; in++; + out += 2; in_ += sizeof(in); } } diff --git a/src/libImaging/Point.c b/src/libImaging/Point.c index 426c410c9..9b4bf6b75 100644 --- a/src/libImaging/Point.c +++ b/src/libImaging/Point.c @@ -99,12 +99,12 @@ im_point_8_32(Imaging imOut, Imaging imIn, im_point_context* context) { int x, y; /* 8-bit source, 32-bit destination */ - INT32* table = (INT32*) context->table; + char* table = (char*) context->table; for (y = 0; y < imIn->ysize; y++) { UINT8* in = imIn->image8[y]; INT32* out = imOut->image32[y]; for (x = 0; x < imIn->xsize; x++) - out[x] = table[in[x]]; + memcpy(out + x, table + in[x] * sizeof(INT32), sizeof(INT32)); } } @@ -242,11 +242,15 @@ ImagingPointTransform(Imaging imIn, double scale, double offset) if (strcmp(imIn->mode,"I;16") == 0) { ImagingSectionEnter(&cookie); for (y = 0; y < imIn->ysize; y++) { - UINT16* in = (UINT16 *)imIn->image[y]; - UINT16* out = (UINT16 *)imOut->image[y]; + char* in = (char*)imIn->image[y]; + char* out = (char*)imOut->image[y]; /* FIXME: add clipping? */ - for (x = 0; x < imIn->xsize; x++) - out[x] = in[x] * scale + offset; + for (x = 0; x < imIn->xsize; x++) { + UINT16 v; + memcpy(&v, in + x * sizeof(v), sizeof(v)); + v = v * scale + offset; + memcpy(out + x * sizeof(UINT16), &v, sizeof(v)); + } } ImagingSectionLeave(&cookie); break; diff --git a/src/libImaging/Resample.c b/src/libImaging/Resample.c index 90e2aa1d0..4a98e8477 100644 --- a/src/libImaging/Resample.c +++ b/src/libImaging/Resample.c @@ -304,6 +304,7 @@ ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn, int offset, if (imIn->bands == 2) { for (yy = 0; yy < imOut->ysize; yy++) { for (xx = 0; xx < imOut->xsize; xx++) { + UINT32 v; xmin = bounds[xx * 2 + 0]; xmax = bounds[xx * 2 + 1]; k = &kk[xx * ksize]; @@ -312,13 +313,14 @@ ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn, int offset, ss0 += ((UINT8) imIn->image[yy + offset][(x + xmin)*4 + 0]) * k[x]; ss3 += ((UINT8) imIn->image[yy + offset][(x + xmin)*4 + 3]) * k[x]; } - ((UINT32 *) imOut->image[yy])[xx] = MAKE_UINT32( - clip8(ss0), 0, 0, clip8(ss3)); + v = MAKE_UINT32(clip8(ss0), 0, 0, clip8(ss3)); + memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v)); } } } else if (imIn->bands == 3) { for (yy = 0; yy < imOut->ysize; yy++) { for (xx = 0; xx < imOut->xsize; xx++) { + UINT32 v; xmin = bounds[xx * 2 + 0]; xmax = bounds[xx * 2 + 1]; k = &kk[xx * ksize]; @@ -328,13 +330,14 @@ ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn, int offset, ss1 += ((UINT8) imIn->image[yy + offset][(x + xmin)*4 + 1]) * k[x]; ss2 += ((UINT8) imIn->image[yy + offset][(x + xmin)*4 + 2]) * k[x]; } - ((UINT32 *) imOut->image[yy])[xx] = MAKE_UINT32( - clip8(ss0), clip8(ss1), clip8(ss2), 0); + v = MAKE_UINT32(clip8(ss0), clip8(ss1), clip8(ss2), 0); + memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v)); } } } else { for (yy = 0; yy < imOut->ysize; yy++) { for (xx = 0; xx < imOut->xsize; xx++) { + UINT32 v; xmin = bounds[xx * 2 + 0]; xmax = bounds[xx * 2 + 1]; k = &kk[xx * ksize]; @@ -345,8 +348,8 @@ ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn, int offset, ss2 += ((UINT8) imIn->image[yy + offset][(x + xmin)*4 + 2]) * k[x]; ss3 += ((UINT8) imIn->image[yy + offset][(x + xmin)*4 + 3]) * k[x]; } - ((UINT32 *) imOut->image[yy])[xx] = MAKE_UINT32( - clip8(ss0), clip8(ss1), clip8(ss2), clip8(ss3)); + v = MAKE_UINT32(clip8(ss0), clip8(ss1), clip8(ss2), clip8(ss3)); + memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v)); } } } @@ -388,13 +391,14 @@ ImagingResampleVertical_8bpc(Imaging imOut, Imaging imIn, int offset, ymin = bounds[yy * 2 + 0]; ymax = bounds[yy * 2 + 1]; for (xx = 0; xx < imOut->xsize; xx++) { + UINT32 v; ss0 = ss3 = 1 << (PRECISION_BITS -1); for (y = 0; y < ymax; y++) { ss0 += ((UINT8) imIn->image[y + ymin][xx*4 + 0]) * k[y]; ss3 += ((UINT8) imIn->image[y + ymin][xx*4 + 3]) * k[y]; } - ((UINT32 *) imOut->image[yy])[xx] = MAKE_UINT32( - clip8(ss0), 0, 0, clip8(ss3)); + v = MAKE_UINT32(clip8(ss0), 0, 0, clip8(ss3)); + memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v)); } } } else if (imIn->bands == 3) { @@ -403,14 +407,15 @@ ImagingResampleVertical_8bpc(Imaging imOut, Imaging imIn, int offset, ymin = bounds[yy * 2 + 0]; ymax = bounds[yy * 2 + 1]; for (xx = 0; xx < imOut->xsize; xx++) { + UINT32 v; ss0 = ss1 = ss2 = 1 << (PRECISION_BITS -1); for (y = 0; y < ymax; y++) { ss0 += ((UINT8) imIn->image[y + ymin][xx*4 + 0]) * k[y]; ss1 += ((UINT8) imIn->image[y + ymin][xx*4 + 1]) * k[y]; ss2 += ((UINT8) imIn->image[y + ymin][xx*4 + 2]) * k[y]; } - ((UINT32 *) imOut->image[yy])[xx] = MAKE_UINT32( - clip8(ss0), clip8(ss1), clip8(ss2), 0); + v = MAKE_UINT32(clip8(ss0), clip8(ss1), clip8(ss2), 0); + memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v)); } } } else { @@ -419,6 +424,7 @@ ImagingResampleVertical_8bpc(Imaging imOut, Imaging imIn, int offset, ymin = bounds[yy * 2 + 0]; ymax = bounds[yy * 2 + 1]; for (xx = 0; xx < imOut->xsize; xx++) { + UINT32 v; ss0 = ss1 = ss2 = ss3 = 1 << (PRECISION_BITS -1); for (y = 0; y < ymax; y++) { ss0 += ((UINT8) imIn->image[y + ymin][xx*4 + 0]) * k[y]; @@ -426,8 +432,8 @@ ImagingResampleVertical_8bpc(Imaging imOut, Imaging imIn, int offset, ss2 += ((UINT8) imIn->image[y + ymin][xx*4 + 2]) * k[y]; ss3 += ((UINT8) imIn->image[y + ymin][xx*4 + 3]) * k[y]; } - ((UINT32 *) imOut->image[yy])[xx] = MAKE_UINT32( - clip8(ss0), clip8(ss1), clip8(ss2), clip8(ss3)); + v = MAKE_UINT32(clip8(ss0), clip8(ss1), clip8(ss2), clip8(ss3)); + memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v)); } } } diff --git a/src/libImaging/SgiRleDecode.c b/src/libImaging/SgiRleDecode.c index f87c473e3..d8341f3e5 100644 --- a/src/libImaging/SgiRleDecode.c +++ b/src/libImaging/SgiRleDecode.c @@ -56,15 +56,15 @@ static int expandrow(UINT8* dest, UINT8* src, int n, int z) return 0; } -static int expandrow2(UINT16* dest, UINT16* src, int n, int z) +static int expandrow2(UINT8* dest, const UINT8* src, int n, int z) { UINT8 pixel, count; for (;n > 0; n--) { - pixel = ((UINT8*)src)[1]; - ++src; + pixel = src[1]; + src+=2; if (n == 1 && pixel != 0) return n; count = pixel & RLE_MAX_RUN; @@ -72,16 +72,17 @@ static int expandrow2(UINT16* dest, UINT16* src, int n, int z) return count; if (pixel & RLE_COPY_FLAG) { while(count--) { - *dest = *src++; - dest += z; + memcpy(dest, src, 2); + src += 2; + dest += z * 2; } } else { while (count--) { - *dest = *src; - dest += z; + memcpy(dest, src, 2); + dest += z * 2; } - ++src; + src+=2; } } return 0; @@ -162,7 +163,7 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state, goto sgi_finish_decode; } else { - if(expandrow2((UINT16*)&state->buffer[c->channo * 2], (UINT16*)&ptr[c->rleoffset], c->rlelength, im->bands)) + if(expandrow2(&state->buffer[c->channo * 2], &ptr[c->rleoffset], c->rlelength, im->bands)) goto sgi_finish_decode; } diff --git a/src/libImaging/Unpack.c b/src/libImaging/Unpack.c index 2edf76619..ab0c8dc60 100644 --- a/src/libImaging/Unpack.c +++ b/src/libImaging/Unpack.c @@ -32,7 +32,6 @@ #include "Imaging.h" - #define R 0 #define G 1 #define B 2 @@ -327,11 +326,11 @@ static void unpackLA(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* LA, pixel interleaved */ for (i = 0; i < pixels; i++) { - out[i] = MAKE_UINT32(in[0], in[0], in[0], in[1]); - in += 2; + UINT32 iv = MAKE_UINT32(in[0], in[0], in[0], in[1]); + memcpy(_out, &iv, sizeof(iv)); + in += 2; _out += 4; } } @@ -339,10 +338,10 @@ static void unpackLAL(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* LA, line interleaved */ - for (i = 0; i < pixels; i++) { - out[i] = MAKE_UINT32(in[i], in[i], in[i], in[i+pixels]); + for (i = 0; i < pixels; i++, _out+=4) { + UINT32 iv = MAKE_UINT32(in[i], in[i], in[i], in[i+pixels]); + memcpy(_out, &iv, sizeof(iv)); } } @@ -480,38 +479,30 @@ void ImagingUnpackRGB(UINT8* _out, const UINT8* in, int pixels) { int i = 0; -#ifdef __sparc - /* SPARC CPUs cannot read integers from nonaligned addresses. */ - for (; i < pixels; i++) { - _out[R] = in[0]; - _out[G] = in[1]; - _out[B] = in[2]; - _out[A] = 255; - _out += 4; in += 3; - } -#else - UINT32* out = (UINT32*) _out; /* RGB triplets */ for (; i < pixels-1; i++) { - out[i] = MASK_UINT32_CHANNEL_3 | *(UINT32*)&in[0]; - in += 3; + UINT32 iv; + memcpy(&iv, in, sizeof(iv)); + iv |= MASK_UINT32_CHANNEL_3; + memcpy(_out, &iv, sizeof(iv)); + in += 3; _out += 4; } for (; i < pixels; i++) { - out[i] = MAKE_UINT32(in[0], in[1], in[2], 255); - in += 3; + UINT32 iv = MAKE_UINT32(in[0], in[1], in[2], 255); + memcpy(_out, &iv, sizeof(iv)); + in += 3; _out += 4; } -#endif } void unpackRGB16L(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* 16-bit RGB triplets, little-endian order */ for (i = 0; i < pixels; i++) { - out[i] = MAKE_UINT32(in[1], in[3], in[5], 255); - in += 6; + UINT32 iv = MAKE_UINT32(in[1], in[3], in[5], 255); + memcpy(_out, &iv, sizeof(iv)); + in += 6; _out += 4; } } @@ -519,11 +510,11 @@ void unpackRGB16B(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* 16-bit RGB triplets, big-endian order */ for (i = 0; i < pixels; i++) { - out[i] = MAKE_UINT32(in[0], in[2], in[4], 255); - in += 6; + UINT32 iv = MAKE_UINT32(in[0], in[2], in[4], 255); + memcpy(_out, &iv, sizeof(iv)); + in += 6; _out += 4; } } @@ -531,10 +522,10 @@ static void unpackRGBL(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* RGB, line interleaved */ - for (i = 0; i < pixels; i++) { - out[i] = MAKE_UINT32(in[i], in[i+pixels], in[i+pixels+pixels], 255); + for (i = 0; i < pixels; i++, _out+=4) { + UINT32 iv = MAKE_UINT32(in[i], in[i+pixels], in[i+pixels+pixels], 255); + memcpy(_out, &iv, sizeof(iv)); } } @@ -542,12 +533,12 @@ static void unpackRGBR(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* RGB, bit reversed */ for (i = 0; i < pixels; i++) { - out[i] = MAKE_UINT32(BITFLIP[in[0]], BITFLIP[in[1]], - BITFLIP[in[2]], 255); - in += 3; + UINT32 iv = MAKE_UINT32(BITFLIP[in[0]], BITFLIP[in[1]], + BITFLIP[in[2]], 255); + memcpy(_out, &iv, sizeof(iv)); + in += 3; _out += 4; } } @@ -555,11 +546,11 @@ void ImagingUnpackBGR(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* RGB, reversed bytes */ for (i = 0; i < pixels; i++) { - out[i] = MAKE_UINT32(in[2], in[1], in[0], 255); - in += 3; + UINT32 iv = MAKE_UINT32(in[2], in[1], in[0], 255); + memcpy(_out, &iv, sizeof(iv)); + in += 3; _out += 4; } } @@ -687,11 +678,11 @@ static void ImagingUnpackBGRX(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* RGB, reversed bytes with padding */ for (i = 0; i < pixels; i++) { - out[i] = MAKE_UINT32(in[2], in[1], in[0], 255); - in += 4; + UINT32 iv = MAKE_UINT32(in[2], in[1], in[0], 255); + memcpy(_out, &iv, sizeof(iv)); + in += 4; _out += 4; } } @@ -699,11 +690,11 @@ static void ImagingUnpackXRGB(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* RGB, leading pad */ for (i = 0; i < pixels; i++) { - out[i] = MAKE_UINT32(in[1], in[2], in[3], 255); - in += 4; + UINT32 iv = MAKE_UINT32(in[1], in[2], in[3], 255); + memcpy(_out, &iv, sizeof(iv)); + in += 4; _out += 4; } } @@ -711,11 +702,11 @@ static void ImagingUnpackXBGR(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* RGB, reversed bytes, leading pad */ for (i = 0; i < pixels; i++) { - out[i] = MAKE_UINT32(in[3], in[2], in[1], 255); - in += 4; + UINT32 iv = MAKE_UINT32(in[3], in[2], in[1], 255); + memcpy(_out, &iv, sizeof(iv)); + in += 4; _out += 4; } } @@ -725,11 +716,11 @@ static void unpackRGBALA(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* greyscale with alpha */ for (i = 0; i < pixels; i++) { - out[i] = MAKE_UINT32(in[0], in[0], in[0], in[1]); - in += 2; + UINT32 iv = MAKE_UINT32(in[0], in[0], in[0], in[1]); + memcpy(_out, &iv, sizeof(iv)); + in += 2; _out += 4; } } @@ -737,11 +728,11 @@ static void unpackRGBALA16B(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* 16-bit greyscale with alpha, big-endian */ for (i = 0; i < pixels; i++) { - out[i] = MAKE_UINT32(in[0], in[0], in[0], in[2]); - in += 4; + UINT32 iv = MAKE_UINT32(in[0], in[0], in[0], in[2]); + memcpy(_out, &iv, sizeof(iv)); + in += 4; _out += 4; } } @@ -749,20 +740,21 @@ static void unpackRGBa16L(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* premultiplied 16-bit RGBA, little-endian */ for (i = 0; i < pixels; i++) { int a = in[7]; + UINT32 iv; if ( ! a) { - out[i] = 0; + iv = 0; } else if (a == 255) { - out[i] = MAKE_UINT32(in[1], in[3], in[5], a); + iv = MAKE_UINT32(in[1], in[3], in[5], a); } else { - out[i] = MAKE_UINT32(CLIP8(in[1] * 255 / a), - CLIP8(in[3] * 255 / a), - CLIP8(in[5] * 255 / a), a); + iv = MAKE_UINT32(CLIP8(in[1] * 255 / a), + CLIP8(in[3] * 255 / a), + CLIP8(in[5] * 255 / a), a); } - in += 8; + memcpy(_out, &iv, sizeof(iv)); + in += 8; _out += 4; } } @@ -770,20 +762,21 @@ static void unpackRGBa16B(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* premultiplied 16-bit RGBA, big-endian */ for (i = 0; i < pixels; i++) { int a = in[6]; + UINT32 iv; if ( ! a) { - out[i] = 0; + iv = 0; } else if (a == 255) { - out[i] = MAKE_UINT32(in[0], in[2], in[4], a); + iv = MAKE_UINT32(in[0], in[2], in[4], a); } else { - out[i] = MAKE_UINT32(CLIP8(in[0] * 255 / a), - CLIP8(in[2] * 255 / a), - CLIP8(in[4] * 255 / a), a); + iv = MAKE_UINT32(CLIP8(in[0] * 255 / a), + CLIP8(in[2] * 255 / a), + CLIP8(in[4] * 255 / a), a); } - in += 8; + memcpy(_out, &iv, sizeof(iv)); + in += 8; _out += 4; } } @@ -791,20 +784,21 @@ static void unpackRGBa(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* premultiplied RGBA */ for (i = 0; i < pixels; i++) { int a = in[3]; + UINT32 iv; if ( ! a) { - out[i] = 0; + iv = 0; } else if (a == 255) { - out[i] = MAKE_UINT32(in[0], in[1], in[2], a); + iv = MAKE_UINT32(in[0], in[1], in[2], a); } else { - out[i] = MAKE_UINT32(CLIP8(in[0] * 255 / a), - CLIP8(in[1] * 255 / a), - CLIP8(in[2] * 255 / a), a); + iv = MAKE_UINT32(CLIP8(in[0] * 255 / a), + CLIP8(in[1] * 255 / a), + CLIP8(in[2] * 255 / a), a); } - in += 4; + memcpy(_out, &iv, sizeof(iv)); + in += 4; _out += 4; } } @@ -854,20 +848,21 @@ static void unpackBGRa(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* premultiplied BGRA */ for (i = 0; i < pixels; i++) { int a = in[3]; + UINT32 iv; if ( ! a) { - out[i] = 0; + iv = 0; } else if (a == 255) { - out[i] = MAKE_UINT32(in[2], in[1], in[0], a); + iv = MAKE_UINT32(in[2], in[1], in[0], a); } else { - out[i] = MAKE_UINT32(CLIP8(in[2] * 255 / a), - CLIP8(in[1] * 255 / a), - CLIP8(in[0] * 255 / a), a); + iv = MAKE_UINT32(CLIP8(in[2] * 255 / a), + CLIP8(in[1] * 255 / a), + CLIP8(in[0] * 255 / a), a); } - in += 4; + memcpy(_out, &iv, sizeof(iv)); + in += 4; _out += 4; } } @@ -889,11 +884,11 @@ static void unpackRGBAL(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* RGBA, line interleaved */ - for (i = 0; i < pixels; i++) { - out[i] = MAKE_UINT32(in[i], in[i+pixels], in[i+pixels+pixels], - in[i+pixels+pixels+pixels]); + for (i = 0; i < pixels; i++, _out+=4) { + UINT32 iv = MAKE_UINT32(in[i], in[i+pixels], in[i+pixels+pixels], + in[i+pixels+pixels+pixels]); + memcpy(_out, &iv, sizeof(iv)); } } @@ -901,10 +896,10 @@ void unpackRGBA16L(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* 16-bit RGBA, little-endian order */ - for (i = 0; i < pixels; i++) { - out[i] = MAKE_UINT32(in[1], in[3], in[5], in[7]); + for (i = 0; i < pixels; i++, _out+=4) { + UINT32 iv = MAKE_UINT32(in[1], in[3], in[5], in[7]); + memcpy(_out, &iv, sizeof(iv)); in += 8; } } @@ -913,10 +908,10 @@ void unpackRGBA16B(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* 16-bit RGBA, big-endian order */ - for (i = 0; i < pixels; i++) { - out[i] = MAKE_UINT32(in[0], in[2], in[4], in[6]); + for (i = 0; i < pixels; i++, _out+=4) { + UINT32 iv = MAKE_UINT32(in[0], in[2], in[4], in[6]); + memcpy(_out, &iv, sizeof(iv)); in += 8; } } @@ -925,11 +920,11 @@ static void unpackARGB(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* RGBA, leading pad */ for (i = 0; i < pixels; i++) { - out[i] = MAKE_UINT32(in[1], in[2], in[3], in[0]); - in += 4; + UINT32 iv = MAKE_UINT32(in[1], in[2], in[3], in[0]); + memcpy(_out, &iv, sizeof(iv)); + in += 4; _out += 4; } } @@ -937,11 +932,11 @@ static void unpackABGR(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* RGBA, reversed bytes */ for (i = 0; i < pixels; i++) { - out[i] = MAKE_UINT32(in[3], in[2], in[1], in[0]); - in += 4; + UINT32 iv = MAKE_UINT32(in[3], in[2], in[1], in[0]); + memcpy(_out, &iv, sizeof(iv)); + in += 4; _out += 4; } } @@ -949,11 +944,11 @@ static void unpackBGRA(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* RGBA, reversed bytes */ for (i = 0; i < pixels; i++) { - out[i] = MAKE_UINT32(in[2], in[1], in[0], in[3]); - in += 4; + UINT32 iv = MAKE_UINT32(in[2], in[1], in[0], in[3]); + memcpy(_out, &iv, sizeof(iv)); + in += 4; _out += 4; } } @@ -964,11 +959,11 @@ static void unpackCMYKI(UINT8* _out, const UINT8* in, int pixels) { int i; - UINT32* out = (UINT32*) _out; /* CMYK, inverted bytes (Photoshop 2.5) */ for (i = 0; i < pixels; i++) { - out[i] = ~MAKE_UINT32(in[0], in[1], in[2], in[3]); - in += 4; + UINT32 iv = ~MAKE_UINT32(in[0], in[1], in[2], in[3]); + memcpy(_out, &iv, sizeof(iv)); + in += 4; _out += 4; } } @@ -1042,7 +1037,6 @@ unpackI12_I16(UINT8* out, const UINT8* in, int pixels){ #ifdef WORDS_BIGENDIAN UINT8* tmp = (UINT8 *)&pixel; #endif - UINT16* out16 = (UINT16 *)out; for (i = 0; i < pixels-1; i+=2) { pixel = (((UINT16) in[0]) << 4 ) + (in[1] >>4); #ifdef WORDS_BIGENDIAN @@ -1051,14 +1045,15 @@ unpackI12_I16(UINT8* out, const UINT8* in, int pixels){ memcpy(out, &pixel, sizeof(pixel)); #endif + out+=2; pixel = (((UINT16) (in[1] & 0x0F)) << 8) + in[2]; #ifdef WORDS_BIGENDIAN - out[2] = tmp[1]; out[3] = tmp[0]; + out[0] = tmp[1]; out[1] = tmp[0]; #else - out16[1] = pixel; + memcpy(out, &pixel, sizeof(pixel)); #endif - in += 3; out16 += 2; out+=4; + in += 3; out+=2; } if (i == pixels-1) { pixel = (((UINT16) in[0]) << 4 ) + (in[1] >>4); @@ -1096,44 +1091,20 @@ static void copy4skip1(UINT8* _out, const UINT8* in, int pixels) { int i; -#ifdef __sparc - /* SPARC CPUs cannot read integers from nonaligned addresses. */ for (i = 0; i < pixels; i++) { - _out[0] = in[0]; - _out[1] = in[1]; - _out[2] = in[2]; - _out[3] = in[3]; - _out += 4; in += 5; + memcpy(_out, in, 4); + in += 5; _out += 4; } -#else - UINT32* out = (UINT32*) _out; - for (i = 0; i < pixels; i++) { - out[i] = *(UINT32*)&in[0]; - in += 5; - } -#endif } static void copy4skip2(UINT8* _out, const UINT8* in, int pixels) { int i; -#ifdef __sparc - /* SPARC CPUs cannot read integers from nonaligned addresses. */ for (i = 0; i < pixels; i++) { - _out[0] = in[0]; - _out[1] = in[1]; - _out[2] = in[2]; - _out[3] = in[3]; - _out += 4; in += 6; + memcpy(_out, in, 4); + in += 6; _out += 4; } -#else - UINT32* out = (UINT32*) _out; - for (i = 0; i < pixels; i++) { - out[i] = *(UINT32*)&in[0]; - in += 6; - } -#endif }