I mode support

This commit is contained in:
Alexander 2019-12-01 22:52:43 +03:00
parent a576b14056
commit d92c58fa7f
2 changed files with 87 additions and 16 deletions

View File

@ -102,12 +102,7 @@ class TestImageReduce(PillowTestCase):
last_pixel = im.resize((1, 1), Image.BOX, last_pixel_box) last_pixel = im.resize((1, 1), Image.BOX, last_pixel_box)
reference.paste(last_pixel, area_size) reference.paste(last_pixel, area_size)
try: self.assert_compare_images(reduced, reference, average_diff, max_diff)
self.assert_compare_images(reduced, reference, average_diff, max_diff)
except Exception:
reduced.save("_out.{}.{}x{}.reduced.png".format(im.mode, *factor))
reference.save("_out.{}.{}x{}.reference.png".format(im.mode, *factor))
raise
def assert_compare_images(self, a, b, max_average_diff, max_diff=255): def assert_compare_images(self, a, b, max_average_diff, max_diff=255):
self.assertEqual( self.assertEqual(
@ -177,7 +172,12 @@ class TestImageReduce(PillowTestCase):
for factor in self.remarkable_factors: for factor in self.remarkable_factors:
self.compare_reduce_with_reference(im, factor) self.compare_reduce_with_reference(im, factor)
def test_mode_I(self):
im = self.get_image("I")
for factor in self.remarkable_factors:
self.compare_reduce_with_reference(im, factor)
def test_mode_F(self): def test_mode_F(self):
im = self.get_image("F") im = self.get_image("F")
for factor in self.remarkable_factors: for factor in self.remarkable_factors:
self.compare_reduce_with_reference(im, factor) self.compare_reduce_with_reference(im, factor, 0, 0)

View File

@ -1164,15 +1164,12 @@ ImagingReduceNxN_32bpc(Imaging imOut, Imaging imIn, int xscale, int yscale)
switch(imIn->type) { switch(imIn->type) {
case IMAGING_TYPE_INT32: case IMAGING_TYPE_INT32:
break;
case IMAGING_TYPE_FLOAT32:
for (y = 0; y < imIn->ysize / yscale; y++) { for (y = 0; y < imIn->ysize / yscale; y++) {
for (x = 0; x < imIn->xsize / xscale; x++) { for (x = 0; x < imIn->xsize / xscale; x++) {
double ss = 0; double ss = 0;
for (yy = y*yscale; yy < y*yscale + yscale - 1; yy += 2) { for (yy = y*yscale; yy < y*yscale + yscale - 1; yy += 2) {
float *line0 = (float *)imIn->image[yy]; INT32 *line0 = (INT32 *)imIn->image32[yy];
float *line1 = (float *)imIn->image[yy + 1]; INT32 *line1 = (INT32 *)imIn->image32[yy + 1];
for (xi = 0; xi < xscale - 1; xi += 2) { for (xi = 0; xi < xscale - 1; xi += 2) {
xx = x*xscale + xi; xx = x*xscale + xi;
ss += line0[xx + 0] + line0[xx + 1] + ss += line0[xx + 0] + line0[xx + 1] +
@ -1184,7 +1181,40 @@ ImagingReduceNxN_32bpc(Imaging imOut, Imaging imIn, int xscale, int yscale)
} }
} }
if (yscale & 0x01) { if (yscale & 0x01) {
float *line = (float *)imIn->image[yy]; INT32 *line = (INT32 *)imIn->image32[yy];
for (xi = 0; xi < xscale - 1; xi += 2) {
xx = x*xscale + xi;
ss += line[xx + 0] + line[xx + 1];
}
if (xscale & 0x01) {
xx = x*xscale + xi;
ss += line[xx + 0];
}
}
IMAGING_PIXEL_I(imOut, x, y) = ROUND_UP(ss * multiplier);
}
}
break;
case IMAGING_TYPE_FLOAT32:
for (y = 0; y < imIn->ysize / yscale; y++) {
for (x = 0; x < imIn->xsize / xscale; x++) {
double ss = 0;
for (yy = y*yscale; yy < y*yscale + yscale - 1; yy += 2) {
FLOAT32 *line0 = (FLOAT32 *)imIn->image32[yy];
FLOAT32 *line1 = (FLOAT32 *)imIn->image32[yy + 1];
for (xi = 0; xi < xscale - 1; xi += 2) {
xx = x*xscale + xi;
ss += line0[xx + 0] + line0[xx + 1] +
line1[xx + 0] + line1[xx + 1];
}
if (xscale & 0x01) {
xx = x*xscale + xi;
ss += line0[xx + 0] + line1[xx + 0];
}
}
if (yscale & 0x01) {
FLOAT32 *line = (FLOAT32 *)imIn->image32[yy];
for (xi = 0; xi < xscale - 1; xi += 2) { for (xi = 0; xi < xscale - 1; xi += 2) {
xx = x*xscale + xi; xx = x*xscale + xi;
ss += line[xx + 0] + line[xx + 1]; ss += line[xx + 0] + line[xx + 1];
@ -1211,6 +1241,47 @@ ImagingReduceCorners_32bpc(Imaging imOut, Imaging imIn, int xscale, int yscale)
switch(imIn->type) { switch(imIn->type) {
case IMAGING_TYPE_INT32: case IMAGING_TYPE_INT32:
if (imIn->xsize % xscale) {
double multiplier = 1.0 / ((imIn->xsize % xscale) * yscale);
for (y = 0; y < imIn->ysize / yscale; y++) {
double ss = 0;
x = imIn->xsize / xscale;
for (yy = y*yscale; yy < y*yscale + yscale; yy++) {
INT32 *line = (INT32 *)imIn->image32[yy];
for (xx = x*xscale; xx < imIn->xsize; xx++) {
ss += line[xx + 0];
}
}
IMAGING_PIXEL_I(imOut, x, y) = ROUND_UP(ss * multiplier);
}
}
if (imIn->ysize % yscale) {
double multiplier = 1.0 / (xscale * (imIn->ysize % yscale));
y = imIn->ysize / yscale;
for (x = 0; x < imIn->xsize / xscale; x++) {
double ss = 0;
for (yy = y*yscale; yy < imIn->ysize; yy++) {
INT32 *line = (INT32 *)imIn->image32[yy];
for (xx = x*xscale; xx < x*xscale + xscale; xx++) {
ss += line[xx + 0];
}
}
IMAGING_PIXEL_I(imOut, x, y) = ROUND_UP(ss * multiplier);
}
}
if (imIn->xsize % xscale && imIn->ysize % yscale) {
double multiplier = 1.0 / ((imIn->xsize % xscale) * (imIn->ysize % yscale));
double ss = 0;
x = imIn->xsize / xscale;
y = imIn->ysize / yscale;
for (yy = y*yscale; yy < imIn->ysize; yy++) {
INT32 *line = (INT32 *)imIn->image32[yy];
for (xx = x*xscale; xx < imIn->xsize; xx++) {
ss += line[xx + 0];
}
}
IMAGING_PIXEL_I(imOut, x, y) = ROUND_UP(ss * multiplier);
}
break; break;
case IMAGING_TYPE_FLOAT32: case IMAGING_TYPE_FLOAT32:
@ -1220,7 +1291,7 @@ ImagingReduceCorners_32bpc(Imaging imOut, Imaging imIn, int xscale, int yscale)
double ss = 0; double ss = 0;
x = imIn->xsize / xscale; x = imIn->xsize / xscale;
for (yy = y*yscale; yy < y*yscale + yscale; yy++) { for (yy = y*yscale; yy < y*yscale + yscale; yy++) {
float *line = (float *)imIn->image[yy]; FLOAT32 *line = (FLOAT32 *)imIn->image32[yy];
for (xx = x*xscale; xx < imIn->xsize; xx++) { for (xx = x*xscale; xx < imIn->xsize; xx++) {
ss += line[xx + 0]; ss += line[xx + 0];
} }
@ -1234,7 +1305,7 @@ ImagingReduceCorners_32bpc(Imaging imOut, Imaging imIn, int xscale, int yscale)
for (x = 0; x < imIn->xsize / xscale; x++) { for (x = 0; x < imIn->xsize / xscale; x++) {
double ss = 0; double ss = 0;
for (yy = y*yscale; yy < imIn->ysize; yy++) { for (yy = y*yscale; yy < imIn->ysize; yy++) {
float *line = (float *)imIn->image[yy]; FLOAT32 *line = (FLOAT32 *)imIn->image32[yy];
for (xx = x*xscale; xx < x*xscale + xscale; xx++) { for (xx = x*xscale; xx < x*xscale + xscale; xx++) {
ss += line[xx + 0]; ss += line[xx + 0];
} }
@ -1248,7 +1319,7 @@ ImagingReduceCorners_32bpc(Imaging imOut, Imaging imIn, int xscale, int yscale)
x = imIn->xsize / xscale; x = imIn->xsize / xscale;
y = imIn->ysize / yscale; y = imIn->ysize / yscale;
for (yy = y*yscale; yy < imIn->ysize; yy++) { for (yy = y*yscale; yy < imIn->ysize; yy++) {
float *line = (float *)imIn->image[yy]; FLOAT32 *line = (FLOAT32 *)imIn->image32[yy];
for (xx = x*xscale; xx < imIn->xsize; xx++) { for (xx = x*xscale; xx < imIn->xsize; xx++) {
ss += line[xx + 0]; ss += line[xx + 0];
} }