diff --git a/PIL/Image.py b/PIL/Image.py index a6447d45f..664380e82 100644 --- a/PIL/Image.py +++ b/PIL/Image.py @@ -150,6 +150,7 @@ ROTATE_90 = 2 ROTATE_180 = 3 ROTATE_270 = 4 TRANSPOSE = 5 +TRANSPOSE_ROTATE_180 = 6 # transforms AFFINE = 0 diff --git a/_imaging.c b/_imaging.c index 60a97aa19..90fa61e59 100644 --- a/_imaging.c +++ b/_imaging.c @@ -1674,6 +1674,7 @@ _transpose(ImagingObject* self, PyObject* args) case 2: /* rotate 90 */ case 4: /* rotate 270 */ case 5: /* transpose */ + case 6: /* transpose and rotate 180 */ imOut = ImagingNewDirty(imIn->mode, imIn->ysize, imIn->xsize); break; default: @@ -1701,6 +1702,9 @@ _transpose(ImagingObject* self, PyObject* args) case 5: (void) ImagingTranspose(imOut, imIn); break; + case 6: + (void) ImagingTransposeRotate180(imOut, imIn); + break; } return PyImagingNew(imOut); diff --git a/libImaging/Geometry.c b/libImaging/Geometry.c index c1b7029db..6d9af669d 100644 --- a/libImaging/Geometry.c +++ b/libImaging/Geometry.c @@ -160,6 +160,50 @@ ImagingTranspose(Imaging imOut, Imaging imIn) } +Imaging +ImagingTransposeRotate180(Imaging imOut, Imaging imIn) +{ + ImagingSectionCookie cookie; + int x, y, xx, yy, xxsize, yysize; + int xr, yr; + + if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) + return (Imaging) ImagingError_ModeError(); + if (imIn->xsize != imOut->ysize || imIn->ysize != imOut->xsize) + return (Imaging) ImagingError_Mismatch(); + + ImagingCopyInfo(imOut, imIn); + +#define TRANSPOSE(image) \ + for (y = 0; y < imIn->ysize; y += ROTATE_CHUNK) { \ + for (x = 0; x < imIn->xsize; x += ROTATE_CHUNK) { \ + yysize = y + ROTATE_CHUNK < imIn->ysize ? y + ROTATE_CHUNK : imIn->ysize; \ + xxsize = x + ROTATE_CHUNK < imIn->xsize ? x + ROTATE_CHUNK : imIn->xsize; \ + for (yy = y; yy < yysize; yy++) { \ + yr = imIn->ysize - 1 - yy; \ + xr = imIn->xsize - 1 - x; \ + for (xx = x; xx < xxsize; xx++, xr--) { \ + imOut->image[xr][yr] = imIn->image[yy][xx]; \ + } \ + } \ + } \ + } + + ImagingSectionEnter(&cookie); + + if (imIn->image8) + TRANSPOSE(image8) + else + TRANSPOSE(image32) + + ImagingSectionLeave(&cookie); + +#undef TRANSPOSE + + return imOut; +} + + Imaging ImagingRotate180(Imaging imOut, Imaging imIn) { diff --git a/libImaging/Imaging.h b/libImaging/Imaging.h index fa7ed368d..dbb9823a0 100644 --- a/libImaging/Imaging.h +++ b/libImaging/Imaging.h @@ -291,8 +291,9 @@ extern Imaging ImagingRankFilter(Imaging im, int size, int rank); extern Imaging ImagingRotate90(Imaging imOut, Imaging imIn); extern Imaging ImagingRotate180(Imaging imOut, Imaging imIn); extern Imaging ImagingRotate270(Imaging imOut, Imaging imIn); -extern Imaging ImagingResample(Imaging imIn, int xsize, int ysize, int filter, float box[4]); extern Imaging ImagingTranspose(Imaging imOut, Imaging imIn); +extern Imaging ImagingTransposeRotate180(Imaging imOut, Imaging imIn); +extern Imaging ImagingResample(Imaging imIn, int xsize, int ysize, int filter, float box[4]); extern Imaging ImagingTransform( Imaging imOut, Imaging imIn, int method, int x0, int y0, int x1, int y1, double *a, int filter, int fill);