Fixed JPEG2000 I;16 images on big endian

This commit is contained in:
Andrew Murray 2021-12-22 10:32:53 +11:00
parent 16167e82e6
commit 4b7b07de70
3 changed files with 14 additions and 14 deletions

View File

@ -10,7 +10,6 @@ from .helper import (
assert_image_equal, assert_image_equal,
assert_image_similar, assert_image_similar,
assert_image_similar_tofile, assert_image_similar_tofile,
is_big_endian,
skip_unless_feature, skip_unless_feature,
) )
@ -234,13 +233,11 @@ def test_16bit_monochrome_has_correct_mode():
assert jp2.mode == "I;16" assert jp2.mode == "I;16"
@pytest.mark.xfail(is_big_endian(), reason="Fails on big-endian")
def test_16bit_monochrome_jp2_like_tiff(): def test_16bit_monochrome_jp2_like_tiff():
with Image.open("Tests/images/16bit.cropped.tif") as tiff_16bit: with Image.open("Tests/images/16bit.cropped.tif") as tiff_16bit:
assert_image_similar_tofile(tiff_16bit, "Tests/images/16bit.cropped.jp2", 1e-3) assert_image_similar_tofile(tiff_16bit, "Tests/images/16bit.cropped.jp2", 1e-3)
@pytest.mark.xfail(is_big_endian(), reason="Fails on big-endian")
def test_16bit_monochrome_j2k_like_tiff(): def test_16bit_monochrome_j2k_like_tiff():
with Image.open("Tests/images/16bit.cropped.tif") as tiff_16bit: with Image.open("Tests/images/16bit.cropped.tif") as tiff_16bit:
assert_image_similar_tofile(tiff_16bit, "Tests/images/16bit.cropped.j2k", 1e-3) assert_image_similar_tofile(tiff_16bit, "Tests/images/16bit.cropped.j2k", 1e-3)

View File

@ -180,9 +180,11 @@ j2ku_gray_i(
case 2: case 2:
for (y = 0; y < h; ++y) { for (y = 0; y < h; ++y) {
const UINT16 *data = (const UINT16 *)&tiledata[2 * y * w]; const UINT16 *data = (const UINT16 *)&tiledata[2 * y * w];
UINT16 *row = (UINT16 *)im->image[y0 + y] + x0; UINT8 *row = (UINT8 *)im->image[y0 + y] + x0;
for (x = 0; x < w; ++x) { for (x = 0; x < w; ++x) {
*row++ = j2ku_shift(offset + *data++, shift); UINT16 pixel = j2ku_shift(offset + *data++, shift);
*row++ = pixel;
*row++ = pixel >> 8;
} }
} }
break; break;

View File

@ -110,8 +110,15 @@ j2k_pack_i16(Imaging im, UINT8 *buf, unsigned x0, unsigned y0, unsigned w, unsig
for (y = 0; y < h; ++y) { for (y = 0; y < h; ++y) {
UINT8 *data = (UINT8 *)(im->image[y + y0] + x0); UINT8 *data = (UINT8 *)(im->image[y + y0] + x0);
for (x = 0; x < w; ++x) { for (x = 0; x < w; ++x) {
*ptr++ = *data++; #ifdef WORDS_BIGENDIAN
*ptr++ = *data++; ptr[0] = data[1];
ptr[1] = data[0];
#else
ptr[0] = data[0];
ptr[1] = data[1];
#endif
ptr += 2;
data += 2;
} }
} }
} }
@ -301,13 +308,7 @@ j2k_encode_entry(Imaging im, ImagingCodecState state) {
components = 1; components = 1;
color_space = OPJ_CLRSPC_GRAY; color_space = OPJ_CLRSPC_GRAY;
pack = j2k_pack_l; pack = j2k_pack_l;
} else if (strcmp(im->mode, "I;16") == 0) { } else if (strcmp(im->mode, "I;16") == 0 || strcmp(im->mode, "I;16B") == 0) {
components = 1;
color_space = OPJ_CLRSPC_GRAY;
pack = j2k_pack_i16;
prec = 16;
bpp = 12;
} else if (strcmp(im->mode, "I;16B") == 0) {
components = 1; components = 1;
color_space = OPJ_CLRSPC_GRAY; color_space = OPJ_CLRSPC_GRAY;
pack = j2k_pack_i16; pack = j2k_pack_i16;