mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-13 02:36:17 +03:00
fix errors with pixel center coordinates
This commit is contained in:
parent
5ece454d1f
commit
5232361718
|
@ -240,7 +240,7 @@ ImagingRotate270(Imaging imOut, Imaging imIn)
|
||||||
/* transform primitives (ImagingTransformMap) */
|
/* transform primitives (ImagingTransformMap) */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
affine_transform(double* xin, double* yin, int x, int y, void* data)
|
affine_transform(double* xout, double* yout, int x, int y, void* data)
|
||||||
{
|
{
|
||||||
/* full moon tonight. your compiler will generate bogus code
|
/* full moon tonight. your compiler will generate bogus code
|
||||||
for simple expressions, unless you reorganize the code, or
|
for simple expressions, unless you reorganize the code, or
|
||||||
|
@ -250,28 +250,34 @@ affine_transform(double* xin, double* yin, int x, int y, void* data)
|
||||||
double a0 = a[0]; double a1 = a[1]; double a2 = a[2];
|
double a0 = a[0]; double a1 = a[1]; double a2 = a[2];
|
||||||
double a3 = a[3]; double a4 = a[4]; double a5 = a[5];
|
double a3 = a[3]; double a4 = a[4]; double a5 = a[5];
|
||||||
|
|
||||||
xin[0] = a0*x + a1*y + a2;
|
double xin = x + 0.5;
|
||||||
yin[0] = a3*x + a4*y + a5;
|
double yin = y + 0.5;
|
||||||
|
|
||||||
|
xout[0] = a0*xin + a1*yin + a2;
|
||||||
|
yout[0] = a3*xin + a4*yin + a5;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
perspective_transform(double* xin, double* yin, int x, int y, void* data)
|
perspective_transform(double* xout, double* yout, int x, int y, void* data)
|
||||||
{
|
{
|
||||||
double* a = (double*) data;
|
double* a = (double*) data;
|
||||||
double a0 = a[0]; double a1 = a[1]; double a2 = a[2];
|
double a0 = a[0]; double a1 = a[1]; double a2 = a[2];
|
||||||
double a3 = a[3]; double a4 = a[4]; double a5 = a[5];
|
double a3 = a[3]; double a4 = a[4]; double a5 = a[5];
|
||||||
double a6 = a[6]; double a7 = a[7];
|
double a6 = a[6]; double a7 = a[7];
|
||||||
|
|
||||||
xin[0] = (a0*x + a1*y + a2) / (a6*x + a7*y + 1);
|
double xin = x + 0.5;
|
||||||
yin[0] = (a3*x + a4*y + a5) / (a6*x + a7*y + 1);
|
double yin = y + 0.5;
|
||||||
|
|
||||||
|
xout[0] = (a0*xin + a1*yin + a2) / (a6*xin + a7*yin + 1);
|
||||||
|
yout[0] = (a3*xin + a4*yin + a5) / (a6*xin + a7*yin + 1);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
quad_transform(double* xin, double* yin, int x, int y, void* data)
|
quad_transform(double* xout, double* yout, int x, int y, void* data)
|
||||||
{
|
{
|
||||||
/* quad warp: map quadrilateral to rectangle */
|
/* quad warp: map quadrilateral to rectangle */
|
||||||
|
|
||||||
|
@ -279,8 +285,11 @@ quad_transform(double* xin, double* yin, int x, int y, void* data)
|
||||||
double a0 = a[0]; double a1 = a[1]; double a2 = a[2]; double a3 = a[3];
|
double a0 = a[0]; double a1 = a[1]; double a2 = a[2]; double a3 = a[3];
|
||||||
double a4 = a[4]; double a5 = a[5]; double a6 = a[6]; double a7 = a[7];
|
double a4 = a[4]; double a5 = a[5]; double a6 = a[6]; double a7 = a[7];
|
||||||
|
|
||||||
xin[0] = a0 + a1*x + a2*y + a3*x*y;
|
double xin = x + 0.5;
|
||||||
yin[0] = a4 + a5*x + a6*y + a7*x*y;
|
double yin = y + 0.5;
|
||||||
|
|
||||||
|
xout[0] = a0 + a1*xin + a2*yin + a3*xin*yin;
|
||||||
|
yout[0] = a4 + a5*xin + a6*yin + a7*xin*yin;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -290,8 +299,8 @@ quad_transform(double* xin, double* yin, int x, int y, void* data)
|
||||||
static int
|
static int
|
||||||
nearest_filter8(void* out, Imaging im, double xin, double yin)
|
nearest_filter8(void* out, Imaging im, double xin, double yin)
|
||||||
{
|
{
|
||||||
int x = COORD(xin);
|
int x = COORD(xin + 0.5);
|
||||||
int y = COORD(yin);
|
int y = COORD(yin + 0.5);
|
||||||
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
|
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
|
||||||
return 0;
|
return 0;
|
||||||
((UINT8*)out)[0] = im->image8[y][x];
|
((UINT8*)out)[0] = im->image8[y][x];
|
||||||
|
@ -301,8 +310,8 @@ nearest_filter8(void* out, Imaging im, double xin, double yin)
|
||||||
static int
|
static int
|
||||||
nearest_filter16(void* out, Imaging im, double xin, double yin)
|
nearest_filter16(void* out, Imaging im, double xin, double yin)
|
||||||
{
|
{
|
||||||
int x = COORD(xin);
|
int x = COORD(xin + 0.5);
|
||||||
int y = COORD(yin);
|
int y = COORD(yin + 0.5);
|
||||||
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
|
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
|
||||||
return 0;
|
return 0;
|
||||||
((INT16*)out)[0] = ((INT16*)(im->image8[y]))[x];
|
((INT16*)out)[0] = ((INT16*)(im->image8[y]))[x];
|
||||||
|
@ -312,8 +321,8 @@ nearest_filter16(void* out, Imaging im, double xin, double yin)
|
||||||
static int
|
static int
|
||||||
nearest_filter32(void* out, Imaging im, double xin, double yin)
|
nearest_filter32(void* out, Imaging im, double xin, double yin)
|
||||||
{
|
{
|
||||||
int x = COORD(xin);
|
int x = COORD(xin + 0.5);
|
||||||
int y = COORD(yin);
|
int y = COORD(yin + 0.5);
|
||||||
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
|
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
|
||||||
return 0;
|
return 0;
|
||||||
((INT32*)out)[0] = im->image32[y][x];
|
((INT32*)out)[0] = im->image32[y][x];
|
||||||
|
@ -691,8 +700,8 @@ ImagingScaleAffine(Imaging imOut, Imaging imIn,
|
||||||
return (Imaging) ImagingError_MemoryError();
|
return (Imaging) ImagingError_MemoryError();
|
||||||
}
|
}
|
||||||
|
|
||||||
xo = a[2];
|
xo = a[2] + a[0] * 0.5;
|
||||||
yo = a[5];
|
yo = a[5] + a[4] * 0.5;
|
||||||
|
|
||||||
xmin = x1;
|
xmin = x1;
|
||||||
xmax = x0;
|
xmax = x0;
|
||||||
|
@ -771,8 +780,10 @@ affine_fixed(Imaging imOut, Imaging imIn,
|
||||||
/* use 16.16 fixed point arithmetics */
|
/* use 16.16 fixed point arithmetics */
|
||||||
#define FIX(v) FLOOR((v)*65536.0 + 0.5)
|
#define FIX(v) FLOOR((v)*65536.0 + 0.5)
|
||||||
|
|
||||||
a0 = FIX(a[0]); a1 = FIX(a[1]); a2 = FIX(a[2]);
|
a0 = FIX(a[0]); a1 = FIX(a[1]);
|
||||||
a3 = FIX(a[3]); a4 = FIX(a[4]); a5 = FIX(a[5]);
|
a3 = FIX(a[3]); a4 = FIX(a[4]);
|
||||||
|
a2 = FIX(a[2] + a[0] * 0.5 + a[1] * 0.5);
|
||||||
|
a5 = FIX(a[5] + a[3] * 0.5 + a[4] * 0.5);
|
||||||
|
|
||||||
#undef FIX
|
#undef FIX
|
||||||
|
|
||||||
|
@ -835,9 +846,10 @@ ImagingTransformAffine(Imaging imOut, Imaging imIn,
|
||||||
filterid, fill);
|
filterid, fill);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a[1] == 0 && a[3] == 0)
|
if (a[1] == 0 && a[3] == 0) {
|
||||||
/* Scaling */
|
/* Scaling */
|
||||||
return ImagingScaleAffine(imOut, imIn, x0, y0, x1, y1, a, fill);
|
return ImagingScaleAffine(imOut, imIn, x0, y0, x1, y1, a, fill);
|
||||||
|
}
|
||||||
|
|
||||||
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();
|
||||||
|
@ -867,8 +879,8 @@ ImagingTransformAffine(Imaging imOut, Imaging imIn,
|
||||||
xsize = (int) imIn->xsize;
|
xsize = (int) imIn->xsize;
|
||||||
ysize = (int) imIn->ysize;
|
ysize = (int) imIn->ysize;
|
||||||
|
|
||||||
xo = a[2];
|
xo = a[2] + a[1] * 0.5 + a[0] * 0.5;
|
||||||
yo = a[5];
|
yo = a[5] + a[4] * 0.5 + a[3] * 0.5;
|
||||||
|
|
||||||
#define AFFINE_TRANSFORM(pixel, image)\
|
#define AFFINE_TRANSFORM(pixel, image)\
|
||||||
for (y = y0; y < y1; y++) {\
|
for (y = y0; y < y1; y++) {\
|
||||||
|
|
Loading…
Reference in New Issue
Block a user