mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-27 10:26:19 +03:00
L mode support
This commit is contained in:
parent
a241f1ed8e
commit
008c1c88e2
|
@ -79,12 +79,17 @@ class TestImageReduce(PillowTestCase):
|
||||||
last_row = im.resize((area_size[0], 1), Image.BOX, last_row_box)
|
last_row = im.resize((area_size[0], 1), Image.BOX, last_row_box)
|
||||||
reference.paste(last_row, (0, area_size[1]))
|
reference.paste(last_row, (0, area_size[1]))
|
||||||
|
|
||||||
if area_size[0] < reduced.size[0]:
|
if area_size[0] < reduced.size[0] and area_size[1] < reduced.size[1]:
|
||||||
last_pixel_box = (area_box[2], area_box[3], im.size[0], im.size[1])
|
last_pixel_box = (area_box[2], area_box[3], im.size[0], im.size[1])
|
||||||
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(
|
||||||
|
@ -114,6 +119,11 @@ class TestImageReduce(PillowTestCase):
|
||||||
.format(last_diff, max_diff, band),
|
.format(last_diff, max_diff, band),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_mode_L(self):
|
||||||
|
im = self.get_image("L")
|
||||||
|
for factor in self.remarkable_factors:
|
||||||
|
self.compare_reduce_with_reference(im, factor)
|
||||||
|
|
||||||
def test_mode_LA(self):
|
def test_mode_LA(self):
|
||||||
im = self.get_image("LA")
|
im = self.get_image("LA")
|
||||||
for factor in self.remarkable_factors:
|
for factor in self.remarkable_factors:
|
||||||
|
@ -124,6 +134,11 @@ 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_La(self):
|
||||||
|
im = self.get_image("La")
|
||||||
|
for factor in self.remarkable_factors:
|
||||||
|
self.compare_reduce_with_reference(im, factor)
|
||||||
|
|
||||||
def test_mode_RGB(self):
|
def test_mode_RGB(self):
|
||||||
im = self.get_image("RGB")
|
im = self.get_image("RGB")
|
||||||
for factor in self.remarkable_factors:
|
for factor in self.remarkable_factors:
|
||||||
|
@ -139,6 +154,11 @@ 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_RGBa(self):
|
||||||
|
im = self.get_image("RGBa")
|
||||||
|
for factor in self.remarkable_factors:
|
||||||
|
self.compare_reduce_with_reference(im, factor)
|
||||||
|
|
||||||
def test_mode_CMYK(self):
|
def test_mode_CMYK(self):
|
||||||
im = self.get_image("CMYK")
|
im = self.get_image("CMYK")
|
||||||
for factor in self.remarkable_factors:
|
for factor in self.remarkable_factors:
|
||||||
|
|
|
@ -24,7 +24,36 @@ ImagingReduceNxN(Imaging imOut, Imaging imIn, int xscale, int yscale)
|
||||||
UINT32 amend = yscale * xscale / 2;
|
UINT32 amend = yscale * xscale / 2;
|
||||||
|
|
||||||
if (imIn->image8) {
|
if (imIn->image8) {
|
||||||
|
for (y = 0; y < imIn->ysize / yscale; y++) {
|
||||||
|
for (x = 0; x < imIn->xsize / xscale; x++) {
|
||||||
|
UINT32 ss = amend;
|
||||||
|
for (yy = y*yscale; yy < y*yscale + yscale - 1; yy += 2) {
|
||||||
|
UINT8 *line0 = (UINT8 *)imIn->image8[yy];
|
||||||
|
UINT8 *line1 = (UINT8 *)imIn->image8[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) {
|
||||||
|
UINT8 *line = (UINT8 *)imIn->image8[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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
imOut->image8[y][x] = (ss * multiplier) >> 24;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
switch(imIn->type) {
|
switch(imIn->type) {
|
||||||
case IMAGING_TYPE_UINT8:
|
case IMAGING_TYPE_UINT8:
|
||||||
|
@ -183,7 +212,21 @@ ImagingReduce1xN(Imaging imOut, Imaging imIn, int yscale)
|
||||||
UINT32 amend = yscale * xscale / 2;
|
UINT32 amend = yscale * xscale / 2;
|
||||||
|
|
||||||
if (imIn->image8) {
|
if (imIn->image8) {
|
||||||
|
for (y = 0; y < imIn->ysize / yscale; y++) {
|
||||||
|
for (x = 0; x < imIn->xsize / xscale; x++) {
|
||||||
|
UINT32 ss = amend;
|
||||||
|
for (yy = y*yscale; yy < y*yscale + yscale - 1; yy += 2) {
|
||||||
|
UINT8 *line0 = (UINT8 *)imIn->image8[yy];
|
||||||
|
UINT8 *line1 = (UINT8 *)imIn->image8[yy + 1];
|
||||||
|
ss += line0[x + 0] + line1[x + 0];
|
||||||
|
}
|
||||||
|
if (yscale & 0x01) {
|
||||||
|
UINT8 *line = (UINT8 *)imIn->image8[yy];
|
||||||
|
ss += line[x + 0];
|
||||||
|
}
|
||||||
|
imOut->image8[y][x] = (ss * multiplier) >> 24;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
switch(imIn->type) {
|
switch(imIn->type) {
|
||||||
case IMAGING_TYPE_UINT8:
|
case IMAGING_TYPE_UINT8:
|
||||||
|
@ -279,7 +322,21 @@ ImagingReduceNx1(Imaging imOut, Imaging imIn, int xscale)
|
||||||
UINT32 amend = yscale * xscale / 2;
|
UINT32 amend = yscale * xscale / 2;
|
||||||
|
|
||||||
if (imIn->image8) {
|
if (imIn->image8) {
|
||||||
|
for (y = 0; y < imIn->ysize / yscale; y++) {
|
||||||
|
for (x = 0; x < imIn->xsize / xscale; x++) {
|
||||||
|
UINT32 ss = amend;
|
||||||
|
UINT8 *line = (UINT8 *)imIn->image8[y];
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
imOut->image8[y][x] = (ss * multiplier) >> 24;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
switch(imIn->type) {
|
switch(imIn->type) {
|
||||||
case IMAGING_TYPE_UINT8:
|
case IMAGING_TYPE_UINT8:
|
||||||
|
@ -373,7 +430,16 @@ ImagingReduce2x2(Imaging imOut, Imaging imIn)
|
||||||
UINT32 amend = yscale * xscale / 2;
|
UINT32 amend = yscale * xscale / 2;
|
||||||
|
|
||||||
if (imIn->image8) {
|
if (imIn->image8) {
|
||||||
|
for (y = 0; y < imIn->ysize / yscale; y++) {
|
||||||
|
UINT8 *line0 = (UINT8 *)imIn->image8[y*yscale + 0];
|
||||||
|
UINT8 *line1 = (UINT8 *)imIn->image8[y*yscale + 1];
|
||||||
|
for (x = 0; x < imIn->xsize / xscale; x++) {
|
||||||
|
UINT32 ss;
|
||||||
|
ss = line0[x*xscale + 0] + line0[x*xscale + 1] +
|
||||||
|
line1[x*xscale + 0] + line1[x*xscale + 1];
|
||||||
|
imOut->image8[y][x] = (ss + amend) >> 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
switch(imIn->type) {
|
switch(imIn->type) {
|
||||||
case IMAGING_TYPE_UINT8:
|
case IMAGING_TYPE_UINT8:
|
||||||
|
@ -444,7 +510,18 @@ ImagingReduce3x3(Imaging imOut, Imaging imIn)
|
||||||
UINT32 amend = yscale * xscale / 2;
|
UINT32 amend = yscale * xscale / 2;
|
||||||
|
|
||||||
if (imIn->image8) {
|
if (imIn->image8) {
|
||||||
|
for (y = 0; y < imIn->ysize / yscale; y++) {
|
||||||
|
UINT8 *line0 = (UINT8 *)imIn->image8[y*yscale + 0];
|
||||||
|
UINT8 *line1 = (UINT8 *)imIn->image8[y*yscale + 1];
|
||||||
|
UINT8 *line2 = (UINT8 *)imIn->image8[y*yscale + 2];
|
||||||
|
for (x = 0; x < imIn->xsize / xscale; x++) {
|
||||||
|
UINT32 ss;
|
||||||
|
ss = line0[x*xscale + 0] + line0[x*xscale + 1] + line0[x*xscale + 2] +
|
||||||
|
line1[x*xscale + 0] + line1[x*xscale + 1] + line1[x*xscale + 2] +
|
||||||
|
line2[x*xscale + 0] + line2[x*xscale + 1] + line2[x*xscale + 2];
|
||||||
|
imOut->image8[y][x] = ((ss + amend) * multiplier) >> 24;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
switch(imIn->type) {
|
switch(imIn->type) {
|
||||||
case IMAGING_TYPE_UINT8:
|
case IMAGING_TYPE_UINT8:
|
||||||
|
@ -527,7 +604,20 @@ ImagingReduce4x4(Imaging imOut, Imaging imIn)
|
||||||
UINT32 amend = yscale * xscale / 2;
|
UINT32 amend = yscale * xscale / 2;
|
||||||
|
|
||||||
if (imIn->image8) {
|
if (imIn->image8) {
|
||||||
|
for (y = 0; y < imIn->ysize / yscale; y++) {
|
||||||
|
UINT8 *line0 = (UINT8 *)imIn->image8[y*yscale + 0];
|
||||||
|
UINT8 *line1 = (UINT8 *)imIn->image8[y*yscale + 1];
|
||||||
|
UINT8 *line2 = (UINT8 *)imIn->image8[y*yscale + 2];
|
||||||
|
UINT8 *line3 = (UINT8 *)imIn->image8[y*yscale + 3];
|
||||||
|
for (x = 0; x < imIn->xsize / xscale; x++) {
|
||||||
|
UINT32 ss;
|
||||||
|
ss = line0[x*xscale + 0] + line0[x*xscale + 1] + line0[x*xscale + 2] + line0[x*xscale + 3] +
|
||||||
|
line1[x*xscale + 0] + line1[x*xscale + 1] + line1[x*xscale + 2] + line1[x*xscale + 3] +
|
||||||
|
line2[x*xscale + 0] + line2[x*xscale + 1] + line2[x*xscale + 2] + line2[x*xscale + 3] +
|
||||||
|
line3[x*xscale + 0] + line3[x*xscale + 1] + line3[x*xscale + 2] + line3[x*xscale + 3];
|
||||||
|
imOut->image8[y][x] = (ss + amend) >> 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
switch(imIn->type) {
|
switch(imIn->type) {
|
||||||
case IMAGING_TYPE_UINT8:
|
case IMAGING_TYPE_UINT8:
|
||||||
|
@ -619,7 +709,22 @@ ImagingReduce5x5(Imaging imOut, Imaging imIn)
|
||||||
UINT32 amend = yscale * xscale / 2;
|
UINT32 amend = yscale * xscale / 2;
|
||||||
|
|
||||||
if (imIn->image8) {
|
if (imIn->image8) {
|
||||||
|
for (y = 0; y < imIn->ysize / yscale; y++) {
|
||||||
|
UINT8 *line0 = (UINT8 *)imIn->image8[y*yscale + 0];
|
||||||
|
UINT8 *line1 = (UINT8 *)imIn->image8[y*yscale + 1];
|
||||||
|
UINT8 *line2 = (UINT8 *)imIn->image8[y*yscale + 2];
|
||||||
|
UINT8 *line3 = (UINT8 *)imIn->image8[y*yscale + 3];
|
||||||
|
UINT8 *line4 = (UINT8 *)imIn->image8[y*yscale + 4];
|
||||||
|
for (x = 0; x < imIn->xsize / xscale; x++) {
|
||||||
|
UINT32 ss;
|
||||||
|
ss = line0[x*xscale + 0] + line0[x*xscale + 1] + line0[x*xscale + 2] + line0[x*xscale + 3] + line0[x*xscale + 4] +
|
||||||
|
line1[x*xscale + 0] + line1[x*xscale + 1] + line1[x*xscale + 2] + line1[x*xscale + 3] + line1[x*xscale + 4] +
|
||||||
|
line2[x*xscale + 0] + line2[x*xscale + 1] + line2[x*xscale + 2] + line2[x*xscale + 3] + line2[x*xscale + 4] +
|
||||||
|
line3[x*xscale + 0] + line3[x*xscale + 1] + line3[x*xscale + 2] + line3[x*xscale + 3] + line3[x*xscale + 4] +
|
||||||
|
line4[x*xscale + 0] + line4[x*xscale + 1] + line4[x*xscale + 2] + line4[x*xscale + 3] + line4[x*xscale + 4];
|
||||||
|
imOut->image8[y][x] = ((ss + amend) * multiplier) >> 24;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
switch(imIn->type) {
|
switch(imIn->type) {
|
||||||
case IMAGING_TYPE_UINT8:
|
case IMAGING_TYPE_UINT8:
|
||||||
|
@ -720,7 +825,54 @@ ImagingReduceCorners(Imaging imOut, Imaging imIn, int xscale, int yscale)
|
||||||
int x, y, xx, yy;
|
int x, y, xx, yy;
|
||||||
|
|
||||||
if (imIn->image8) {
|
if (imIn->image8) {
|
||||||
|
if (imIn->xsize % xscale) {
|
||||||
|
int scale = (imIn->xsize % xscale) * yscale;
|
||||||
|
UINT32 multiplier = division_UINT32(scale, 8);
|
||||||
|
UINT32 amend = scale / 2;
|
||||||
|
for (y = 0; y < imIn->ysize / yscale; y++) {
|
||||||
|
UINT32 ss = amend;
|
||||||
|
x = imIn->xsize / xscale;
|
||||||
|
|
||||||
|
for (yy = y*yscale; yy < y*yscale + yscale; yy++) {
|
||||||
|
UINT8 *line = (UINT8 *)imIn->image8[yy];
|
||||||
|
for (xx = x*xscale; xx < imIn->xsize; xx++) {
|
||||||
|
ss += line[xx + 0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
imOut->image8[y][x] = (ss * multiplier) >> 24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (imIn->ysize % yscale) {
|
||||||
|
int scale = xscale * (imIn->ysize % yscale);
|
||||||
|
UINT32 multiplier = division_UINT32(scale, 8);
|
||||||
|
UINT32 amend = scale / 2;
|
||||||
|
y = imIn->ysize / yscale;
|
||||||
|
for (x = 0; x < imIn->xsize / xscale; x++) {
|
||||||
|
UINT32 ss = amend;
|
||||||
|
for (yy = y*yscale; yy < imIn->ysize; yy++) {
|
||||||
|
UINT8 *line = (UINT8 *)imIn->image8[yy];
|
||||||
|
for (xx = x*xscale; xx < x*xscale + xscale; xx++) {
|
||||||
|
ss += line[xx + 0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
imOut->image8[y][x] = (ss * multiplier) >> 24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (imIn->xsize % xscale && imIn->ysize % yscale) {
|
||||||
|
int scale = (imIn->xsize % xscale) * (imIn->ysize % yscale);
|
||||||
|
UINT32 multiplier = division_UINT32(scale, 8);
|
||||||
|
UINT32 amend = scale / 2;
|
||||||
|
UINT32 ss = amend;
|
||||||
|
x = imIn->xsize / xscale;
|
||||||
|
y = imIn->ysize / yscale;
|
||||||
|
for (yy = y*yscale; yy < imIn->ysize; yy++) {
|
||||||
|
UINT8 *line = (UINT8 *)imIn->image8[yy];
|
||||||
|
for (xx = x*xscale; xx < imIn->xsize; xx++) {
|
||||||
|
ss += line[xx + 0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
imOut->image8[y][x] = (ss * multiplier) >> 24;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
switch(imIn->type) {
|
switch(imIn->type) {
|
||||||
case IMAGING_TYPE_UINT8:
|
case IMAGING_TYPE_UINT8:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user