mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-04-28 13:03:43 +03:00
Merge pull request #2730 from uploadcare/fast-geometry
Faster Transposition
This commit is contained in:
commit
7541755aa5
|
@ -150,6 +150,7 @@ ROTATE_90 = 2
|
||||||
ROTATE_180 = 3
|
ROTATE_180 = 3
|
||||||
ROTATE_270 = 4
|
ROTATE_270 = 4
|
||||||
TRANSPOSE = 5
|
TRANSPOSE = 5
|
||||||
|
TRANSVERSE = 6
|
||||||
|
|
||||||
# transforms
|
# transforms
|
||||||
AFFINE = 0
|
AFFINE = 0
|
||||||
|
@ -2173,8 +2174,8 @@ class Image(object):
|
||||||
|
|
||||||
:param method: One of :py:attr:`PIL.Image.FLIP_LEFT_RIGHT`,
|
:param method: One of :py:attr:`PIL.Image.FLIP_LEFT_RIGHT`,
|
||||||
:py:attr:`PIL.Image.FLIP_TOP_BOTTOM`, :py:attr:`PIL.Image.ROTATE_90`,
|
:py:attr:`PIL.Image.FLIP_TOP_BOTTOM`, :py:attr:`PIL.Image.ROTATE_90`,
|
||||||
:py:attr:`PIL.Image.ROTATE_180`, :py:attr:`PIL.Image.ROTATE_270` or
|
:py:attr:`PIL.Image.ROTATE_180`, :py:attr:`PIL.Image.ROTATE_270`,
|
||||||
:py:attr:`PIL.Image.TRANSPOSE`.
|
:py:attr:`PIL.Image.TRANSPOSE` or :py:attr:`PIL.Image.TRANSVERSE`.
|
||||||
:returns: Returns a flipped or rotated copy of this image.
|
:returns: Returns a flipped or rotated copy of this image.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import helper
|
||||||
from helper import unittest, PillowTestCase
|
from helper import unittest, PillowTestCase
|
||||||
|
|
||||||
from PIL.Image import (FLIP_LEFT_RIGHT, FLIP_TOP_BOTTOM, ROTATE_90, ROTATE_180,
|
from PIL.Image import (FLIP_LEFT_RIGHT, FLIP_TOP_BOTTOM, ROTATE_90, ROTATE_180,
|
||||||
ROTATE_270, TRANSPOSE)
|
ROTATE_270, TRANSPOSE, TRANSVERSE)
|
||||||
|
|
||||||
|
|
||||||
class TestImageTranspose(PillowTestCase):
|
class TestImageTranspose(PillowTestCase):
|
||||||
|
@ -108,6 +108,22 @@ class TestImageTranspose(PillowTestCase):
|
||||||
for mode in ("L", "RGB"):
|
for mode in ("L", "RGB"):
|
||||||
transpose(mode)
|
transpose(mode)
|
||||||
|
|
||||||
|
def test_tranverse(self):
|
||||||
|
def transpose(mode):
|
||||||
|
im = self.hopper[mode]
|
||||||
|
out = im.transpose(TRANSVERSE)
|
||||||
|
self.assertEqual(out.mode, mode)
|
||||||
|
self.assertEqual(out.size, im.size[::-1])
|
||||||
|
|
||||||
|
x, y = im.size
|
||||||
|
self.assertEqual(im.getpixel((1, 1)), out.getpixel((y-2, x-2)))
|
||||||
|
self.assertEqual(im.getpixel((x-2, 1)), out.getpixel((y-2, 1)))
|
||||||
|
self.assertEqual(im.getpixel((1, y-2)), out.getpixel((1, x-2)))
|
||||||
|
self.assertEqual(im.getpixel((x-2, y-2)), out.getpixel((1, 1)))
|
||||||
|
|
||||||
|
for mode in ("L", "RGB"):
|
||||||
|
transpose(mode)
|
||||||
|
|
||||||
def test_roundtrip(self):
|
def test_roundtrip(self):
|
||||||
im = self.hopper['L']
|
im = self.hopper['L']
|
||||||
|
|
||||||
|
@ -124,6 +140,12 @@ class TestImageTranspose(PillowTestCase):
|
||||||
im.transpose(TRANSPOSE), transpose(ROTATE_90, FLIP_TOP_BOTTOM))
|
im.transpose(TRANSPOSE), transpose(ROTATE_90, FLIP_TOP_BOTTOM))
|
||||||
self.assert_image_equal(
|
self.assert_image_equal(
|
||||||
im.transpose(TRANSPOSE), transpose(ROTATE_270, FLIP_LEFT_RIGHT))
|
im.transpose(TRANSPOSE), transpose(ROTATE_270, FLIP_LEFT_RIGHT))
|
||||||
|
self.assert_image_equal(
|
||||||
|
im.transpose(TRANSVERSE), transpose(ROTATE_90, FLIP_LEFT_RIGHT))
|
||||||
|
self.assert_image_equal(
|
||||||
|
im.transpose(TRANSVERSE), transpose(ROTATE_270, FLIP_TOP_BOTTOM))
|
||||||
|
self.assert_image_equal(
|
||||||
|
im.transpose(TRANSVERSE), transpose(ROTATE_180, TRANSPOSE))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -1678,6 +1678,7 @@ _transpose(ImagingObject* self, PyObject* args)
|
||||||
case 2: /* rotate 90 */
|
case 2: /* rotate 90 */
|
||||||
case 4: /* rotate 270 */
|
case 4: /* rotate 270 */
|
||||||
case 5: /* transpose */
|
case 5: /* transpose */
|
||||||
|
case 6: /* transverse */
|
||||||
imOut = ImagingNewDirty(imIn->mode, imIn->ysize, imIn->xsize);
|
imOut = ImagingNewDirty(imIn->mode, imIn->ysize, imIn->xsize);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1705,6 +1706,9 @@ _transpose(ImagingObject* self, PyObject* args)
|
||||||
case 5:
|
case 5:
|
||||||
(void) ImagingTranspose(imOut, imIn);
|
(void) ImagingTranspose(imOut, imIn);
|
||||||
break;
|
break;
|
||||||
|
case 6:
|
||||||
|
(void) ImagingTransverse(imOut, imIn);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PyImagingNew(imOut);
|
return PyImagingNew(imOut);
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
Rotating in chunks that fit in the cache can speed up rotation
|
Rotating in chunks that fit in the cache can speed up rotation
|
||||||
8x on a modern CPU. A chunk size of 128 requires only 65k and is large enough
|
8x on a modern CPU. A chunk size of 128 requires only 65k and is large enough
|
||||||
that the overhead from the extra loops are not apparent. */
|
that the overhead from the extra loops are not apparent. */
|
||||||
#define ROTATE_CHUNK 128
|
#define ROTATE_CHUNK 512
|
||||||
|
#define ROTATE_SMALL_CHUNK 8
|
||||||
|
|
||||||
#define COORD(v) ((v) < 0.0 ? -1 : ((int)(v)))
|
#define COORD(v) ((v) < 0.0 ? -1 : ((int)(v)))
|
||||||
#define FLOOR(v) ((v) < 0.0 ? ((int)floor(v)) : ((int)(v)))
|
#define FLOOR(v) ((v) < 0.0 ? ((int)floor(v)) : ((int)(v)))
|
||||||
|
@ -26,30 +27,27 @@ ImagingFlipLeftRight(Imaging imOut, Imaging imIn)
|
||||||
|
|
||||||
ImagingCopyInfo(imOut, imIn);
|
ImagingCopyInfo(imOut, imIn);
|
||||||
|
|
||||||
|
#define FLIP_LEFT_RIGHT(INT, image) \
|
||||||
|
for (y = 0; y < imIn->ysize; y++) { \
|
||||||
|
INT* in = imIn->image[y]; \
|
||||||
|
INT* out = imOut->image[y]; \
|
||||||
|
xr = imIn->xsize-1; \
|
||||||
|
for (x = 0; x < imIn->xsize; x++, xr--) \
|
||||||
|
out[xr] = in[x]; \
|
||||||
|
}
|
||||||
|
|
||||||
ImagingSectionEnter(&cookie);
|
ImagingSectionEnter(&cookie);
|
||||||
|
|
||||||
if (imIn->image8) {
|
if (imIn->image8) {
|
||||||
for (y = 0; y < imIn->ysize; y++) {
|
FLIP_LEFT_RIGHT(UINT8, image8)
|
||||||
UINT8* in = (UINT8*) imIn->image8[y];
|
|
||||||
UINT8* out = (UINT8*) imOut->image8[y];
|
|
||||||
x = 0;
|
|
||||||
xr = imIn->xsize-1;
|
|
||||||
for (; x < imIn->xsize; x++, xr--)
|
|
||||||
out[xr] = in[x];
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
for (y = 0; y < imIn->ysize; y++) {
|
FLIP_LEFT_RIGHT(INT32, image32)
|
||||||
UINT32* in = (UINT32*) imIn->image32[y];
|
|
||||||
UINT32* out = (UINT32*) imOut->image32[y];
|
|
||||||
x = 0;
|
|
||||||
xr = imIn->xsize-1;
|
|
||||||
for (; x < imIn->xsize; x++, xr--)
|
|
||||||
out[xr] = in[x];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
|
|
||||||
|
#undef FLIP_LEFT_RIGHT
|
||||||
|
|
||||||
return imOut;
|
return imOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +82,7 @@ ImagingRotate90(Imaging imOut, Imaging imIn)
|
||||||
{
|
{
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
int x, y, xx, yy, xr, xxsize, yysize;
|
int x, y, xx, yy, xr, xxsize, yysize;
|
||||||
|
int xxx, yyy, xxxsize, yyysize;
|
||||||
|
|
||||||
if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0)
|
if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0)
|
||||||
return (Imaging) ImagingError_ModeError();
|
return (Imaging) ImagingError_ModeError();
|
||||||
|
@ -92,15 +91,22 @@ ImagingRotate90(Imaging imOut, Imaging imIn)
|
||||||
|
|
||||||
ImagingCopyInfo(imOut, imIn);
|
ImagingCopyInfo(imOut, imIn);
|
||||||
|
|
||||||
#define ROTATE_90(image) \
|
#define ROTATE_90(INT, image) \
|
||||||
for (y = 0; y < imIn->ysize; y += ROTATE_CHUNK) { \
|
for (y = 0; y < imIn->ysize; y += ROTATE_CHUNK) { \
|
||||||
for (x = 0; x < imIn->xsize; x += ROTATE_CHUNK) { \
|
for (x = 0; x < imIn->xsize; x += ROTATE_CHUNK) { \
|
||||||
yysize = y + ROTATE_CHUNK < imIn->ysize ? y + ROTATE_CHUNK : imIn->ysize; \
|
yysize = y + ROTATE_CHUNK < imIn->ysize ? y + ROTATE_CHUNK : imIn->ysize; \
|
||||||
xxsize = x + ROTATE_CHUNK < imIn->xsize ? x + ROTATE_CHUNK : imIn->xsize; \
|
xxsize = x + ROTATE_CHUNK < imIn->xsize ? x + ROTATE_CHUNK : imIn->xsize; \
|
||||||
for (yy = y; yy < yysize; yy++) { \
|
for (yy = y; yy < yysize; yy += ROTATE_SMALL_CHUNK) { \
|
||||||
xr = imIn->xsize - 1 - x; \
|
for (xx = x; xx < xxsize; xx += ROTATE_SMALL_CHUNK) { \
|
||||||
for (xx = x; xx < xxsize; xx++, xr--) { \
|
yyysize = yy + ROTATE_SMALL_CHUNK < imIn->ysize ? yy + ROTATE_SMALL_CHUNK : imIn->ysize; \
|
||||||
imOut->image[xr][yy] = imIn->image[yy][xx]; \
|
xxxsize = xx + ROTATE_SMALL_CHUNK < imIn->xsize ? xx + ROTATE_SMALL_CHUNK : imIn->xsize; \
|
||||||
|
for (yyy = yy; yyy < yyysize; yyy++) { \
|
||||||
|
INT* in = imIn->image[yyy]; \
|
||||||
|
xr = imIn->xsize - 1 - xx; \
|
||||||
|
for (xxx = xx; xxx < xxxsize; xxx++, xr--) { \
|
||||||
|
imOut->image[xr][yyy] = in[xxx]; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
@ -109,9 +115,9 @@ ImagingRotate90(Imaging imOut, Imaging imIn)
|
||||||
ImagingSectionEnter(&cookie);
|
ImagingSectionEnter(&cookie);
|
||||||
|
|
||||||
if (imIn->image8)
|
if (imIn->image8)
|
||||||
ROTATE_90(image8)
|
ROTATE_90(UINT8, image8)
|
||||||
else
|
else
|
||||||
ROTATE_90(image32)
|
ROTATE_90(INT32, image32)
|
||||||
|
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
|
|
||||||
|
@ -126,6 +132,7 @@ ImagingTranspose(Imaging imOut, Imaging imIn)
|
||||||
{
|
{
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
int x, y, xx, yy, xxsize, yysize;
|
int x, y, xx, yy, xxsize, yysize;
|
||||||
|
int xxx, yyy, xxxsize, yyysize;
|
||||||
|
|
||||||
if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0)
|
if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0)
|
||||||
return (Imaging) ImagingError_ModeError();
|
return (Imaging) ImagingError_ModeError();
|
||||||
|
@ -134,14 +141,21 @@ ImagingTranspose(Imaging imOut, Imaging imIn)
|
||||||
|
|
||||||
ImagingCopyInfo(imOut, imIn);
|
ImagingCopyInfo(imOut, imIn);
|
||||||
|
|
||||||
#define TRANSPOSE(image) \
|
#define TRANSPOSE(INT, image) \
|
||||||
for (y = 0; y < imIn->ysize; y += ROTATE_CHUNK) { \
|
for (y = 0; y < imIn->ysize; y += ROTATE_CHUNK) { \
|
||||||
for (x = 0; x < imIn->xsize; x += ROTATE_CHUNK) { \
|
for (x = 0; x < imIn->xsize; x += ROTATE_CHUNK) { \
|
||||||
yysize = y + ROTATE_CHUNK < imIn->ysize ? y + ROTATE_CHUNK : imIn->ysize; \
|
yysize = y + ROTATE_CHUNK < imIn->ysize ? y + ROTATE_CHUNK : imIn->ysize; \
|
||||||
xxsize = x + ROTATE_CHUNK < imIn->xsize ? x + ROTATE_CHUNK : imIn->xsize; \
|
xxsize = x + ROTATE_CHUNK < imIn->xsize ? x + ROTATE_CHUNK : imIn->xsize; \
|
||||||
for (yy = y; yy < yysize; yy++) { \
|
for (yy = y; yy < yysize; yy += ROTATE_SMALL_CHUNK) { \
|
||||||
for (xx = x; xx < xxsize; xx++) { \
|
for (xx = x; xx < xxsize; xx += ROTATE_SMALL_CHUNK) { \
|
||||||
imOut->image[xx][yy] = imIn->image[yy][xx]; \
|
yyysize = yy + ROTATE_SMALL_CHUNK < imIn->ysize ? yy + ROTATE_SMALL_CHUNK : imIn->ysize; \
|
||||||
|
xxxsize = xx + ROTATE_SMALL_CHUNK < imIn->xsize ? xx + ROTATE_SMALL_CHUNK : imIn->xsize; \
|
||||||
|
for (yyy = yy; yyy < yyysize; yyy++) { \
|
||||||
|
INT* in = imIn->image[yyy]; \
|
||||||
|
for (xxx = xx; xxx < xxxsize; xxx++) { \
|
||||||
|
imOut->image[xxx][yyy] = in[xxx]; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
@ -150,9 +164,9 @@ ImagingTranspose(Imaging imOut, Imaging imIn)
|
||||||
ImagingSectionEnter(&cookie);
|
ImagingSectionEnter(&cookie);
|
||||||
|
|
||||||
if (imIn->image8)
|
if (imIn->image8)
|
||||||
TRANSPOSE(image8)
|
TRANSPOSE(UINT8, image8)
|
||||||
else
|
else
|
||||||
TRANSPOSE(image32)
|
TRANSPOSE(INT32, image32)
|
||||||
|
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
|
|
||||||
|
@ -162,6 +176,57 @@ ImagingTranspose(Imaging imOut, Imaging imIn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Imaging
|
||||||
|
ImagingTransverse(Imaging imOut, Imaging imIn)
|
||||||
|
{
|
||||||
|
ImagingSectionCookie cookie;
|
||||||
|
int x, y, xr, yr, xx, yy, xxsize, yysize;
|
||||||
|
int xxx, yyy, xxxsize, yyysize;
|
||||||
|
|
||||||
|
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 TRANSVERSE(INT, 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 += ROTATE_SMALL_CHUNK) { \
|
||||||
|
for (xx = x; xx < xxsize; xx += ROTATE_SMALL_CHUNK) { \
|
||||||
|
yyysize = yy + ROTATE_SMALL_CHUNK < imIn->ysize ? yy + ROTATE_SMALL_CHUNK : imIn->ysize; \
|
||||||
|
xxxsize = xx + ROTATE_SMALL_CHUNK < imIn->xsize ? xx + ROTATE_SMALL_CHUNK : imIn->xsize; \
|
||||||
|
yr = imIn->ysize - 1 - yy; \
|
||||||
|
for (yyy = yy; yyy < yyysize; yyy++, yr--) { \
|
||||||
|
INT* in = imIn->image[yyy]; \
|
||||||
|
xr = imIn->xsize - 1 - xx; \
|
||||||
|
for (xxx = xx; xxx < xxxsize; xxx++, xr--) { \
|
||||||
|
imOut->image[xr][yr] = in[xxx]; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
ImagingSectionEnter(&cookie);
|
||||||
|
|
||||||
|
if (imIn->image8)
|
||||||
|
TRANSVERSE(UINT8, image8)
|
||||||
|
else
|
||||||
|
TRANSVERSE(INT32, image32)
|
||||||
|
|
||||||
|
ImagingSectionLeave(&cookie);
|
||||||
|
|
||||||
|
#undef TRANSVERSE
|
||||||
|
|
||||||
|
return imOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingRotate180(Imaging imOut, Imaging imIn)
|
ImagingRotate180(Imaging imOut, Imaging imIn)
|
||||||
{
|
{
|
||||||
|
@ -175,20 +240,23 @@ ImagingRotate180(Imaging imOut, Imaging imIn)
|
||||||
|
|
||||||
ImagingCopyInfo(imOut, imIn);
|
ImagingCopyInfo(imOut, imIn);
|
||||||
|
|
||||||
#define ROTATE_180(image)\
|
#define ROTATE_180(INT, image) \
|
||||||
for (y = 0; y < imIn->ysize; y++, yr--) { \
|
for (y = 0; y < imIn->ysize; y++, yr--) { \
|
||||||
|
INT* in = imIn->image[y]; \
|
||||||
|
INT* out = imOut->image[yr]; \
|
||||||
xr = imIn->xsize-1; \
|
xr = imIn->xsize-1; \
|
||||||
for (x = 0; x < imIn->xsize; x++, xr--) \
|
for (x = 0; x < imIn->xsize; x++, xr--) \
|
||||||
imOut->image[y][x] = imIn->image[yr][xr];\
|
out[xr] = in[x]; \
|
||||||
}
|
}
|
||||||
|
|
||||||
ImagingSectionEnter(&cookie);
|
ImagingSectionEnter(&cookie);
|
||||||
|
|
||||||
yr = imIn->ysize-1;
|
yr = imIn->ysize-1;
|
||||||
if (imIn->image8)
|
if (imIn->image8) {
|
||||||
ROTATE_180(image8)
|
ROTATE_180(UINT8, image8)
|
||||||
else
|
} else {
|
||||||
ROTATE_180(image32)
|
ROTATE_180(INT32, image32)
|
||||||
|
}
|
||||||
|
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
|
|
||||||
|
@ -203,6 +271,7 @@ ImagingRotate270(Imaging imOut, Imaging imIn)
|
||||||
{
|
{
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
int x, y, xx, yy, yr, xxsize, yysize;
|
int x, y, xx, yy, yr, xxsize, yysize;
|
||||||
|
int xxx, yyy, xxxsize, yyysize;
|
||||||
|
|
||||||
if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0)
|
if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0)
|
||||||
return (Imaging) ImagingError_ModeError();
|
return (Imaging) ImagingError_ModeError();
|
||||||
|
@ -211,15 +280,22 @@ ImagingRotate270(Imaging imOut, Imaging imIn)
|
||||||
|
|
||||||
ImagingCopyInfo(imOut, imIn);
|
ImagingCopyInfo(imOut, imIn);
|
||||||
|
|
||||||
#define ROTATE_270(image) \
|
#define ROTATE_270(INT, image) \
|
||||||
for (y = 0; y < imIn->ysize; y += ROTATE_CHUNK) { \
|
for (y = 0; y < imIn->ysize; y += ROTATE_CHUNK) { \
|
||||||
for (x = 0; x < imIn->xsize; x += ROTATE_CHUNK) { \
|
for (x = 0; x < imIn->xsize; x += ROTATE_CHUNK) { \
|
||||||
yysize = y + ROTATE_CHUNK < imIn->ysize ? y + ROTATE_CHUNK : imIn->ysize; \
|
yysize = y + ROTATE_CHUNK < imIn->ysize ? y + ROTATE_CHUNK : imIn->ysize; \
|
||||||
xxsize = x + ROTATE_CHUNK < imIn->xsize ? x + ROTATE_CHUNK : imIn->xsize; \
|
xxsize = x + ROTATE_CHUNK < imIn->xsize ? x + ROTATE_CHUNK : imIn->xsize; \
|
||||||
yr = imIn->ysize - 1 - y; \
|
for (yy = y; yy < yysize; yy += ROTATE_SMALL_CHUNK) { \
|
||||||
for (yy = y; yy < yysize; yy++, yr--) { \
|
for (xx = x; xx < xxsize; xx += ROTATE_SMALL_CHUNK) { \
|
||||||
for (xx = x; xx < xxsize; xx++) { \
|
yyysize = yy + ROTATE_SMALL_CHUNK < imIn->ysize ? yy + ROTATE_SMALL_CHUNK : imIn->ysize; \
|
||||||
imOut->image[xx][yr] = imIn->image[yy][xx]; \
|
xxxsize = xx + ROTATE_SMALL_CHUNK < imIn->xsize ? xx + ROTATE_SMALL_CHUNK : imIn->xsize; \
|
||||||
|
yr = imIn->ysize - 1 - yy; \
|
||||||
|
for (yyy = yy; yyy < yyysize; yyy++, yr--) { \
|
||||||
|
INT* in = imIn->image[yyy]; \
|
||||||
|
for (xxx = xx; xxx < xxxsize; xxx++) { \
|
||||||
|
imOut->image[xxx][yr] = in[xxx]; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
@ -228,9 +304,9 @@ ImagingRotate270(Imaging imOut, Imaging imIn)
|
||||||
ImagingSectionEnter(&cookie);
|
ImagingSectionEnter(&cookie);
|
||||||
|
|
||||||
if (imIn->image8)
|
if (imIn->image8)
|
||||||
ROTATE_270(image8)
|
ROTATE_270(UINT8, image8)
|
||||||
else
|
else
|
||||||
ROTATE_270(image32)
|
ROTATE_270(INT32, image32)
|
||||||
|
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
|
|
||||||
|
|
|
@ -289,8 +289,9 @@ extern Imaging ImagingRankFilter(Imaging im, int size, int rank);
|
||||||
extern Imaging ImagingRotate90(Imaging imOut, Imaging imIn);
|
extern Imaging ImagingRotate90(Imaging imOut, Imaging imIn);
|
||||||
extern Imaging ImagingRotate180(Imaging imOut, Imaging imIn);
|
extern Imaging ImagingRotate180(Imaging imOut, Imaging imIn);
|
||||||
extern Imaging ImagingRotate270(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 ImagingTranspose(Imaging imOut, Imaging imIn);
|
||||||
|
extern Imaging ImagingTransverse(Imaging imOut, Imaging imIn);
|
||||||
|
extern Imaging ImagingResample(Imaging imIn, int xsize, int ysize, int filter, float box[4]);
|
||||||
extern Imaging ImagingTransform(
|
extern Imaging ImagingTransform(
|
||||||
Imaging imOut, Imaging imIn, int method, int x0, int y0, int x1, int y1,
|
Imaging imOut, Imaging imIn, int method, int x0, int y0, int x1, int y1,
|
||||||
double *a, int filter, int fill);
|
double *a, int filter, int fill);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user