mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-06-29 17:33:08 +03:00
Clean commit of 16-bit monochrome JPEK2000 support
This commit is contained in:
parent
9f0b688952
commit
433ec1c219
|
@ -40,7 +40,10 @@ def _parse_codestream(fp):
|
||||||
|
|
||||||
size = (xsiz - xosiz, ysiz - yosiz)
|
size = (xsiz - xosiz, ysiz - yosiz)
|
||||||
if csiz == 1:
|
if csiz == 1:
|
||||||
mode = 'L'
|
if len(yrsiz) > 0 and yrsiz[0] > 8:
|
||||||
|
mode = 'I'
|
||||||
|
else:
|
||||||
|
mode = 'L'
|
||||||
elif csiz == 2:
|
elif csiz == 2:
|
||||||
mode = 'LA'
|
mode = 'LA'
|
||||||
elif csiz == 3:
|
elif csiz == 3:
|
||||||
|
@ -78,6 +81,7 @@ def _parse_jp2_header(fp):
|
||||||
|
|
||||||
size = None
|
size = None
|
||||||
mode = None
|
mode = None
|
||||||
|
bpc = None
|
||||||
|
|
||||||
hio = io.BytesIO(header)
|
hio = io.BytesIO(header)
|
||||||
while True:
|
while True:
|
||||||
|
@ -95,7 +99,9 @@ def _parse_jp2_header(fp):
|
||||||
= struct.unpack('>IIHBBBB', content)
|
= struct.unpack('>IIHBBBB', content)
|
||||||
size = (width, height)
|
size = (width, height)
|
||||||
if unkc:
|
if unkc:
|
||||||
if nc == 1:
|
if nc == 1 and bpc > 8:
|
||||||
|
mode = 'I'
|
||||||
|
elif nc == 1:
|
||||||
mode = 'L'
|
mode = 'L'
|
||||||
elif nc == 2:
|
elif nc == 2:
|
||||||
mode = 'LA'
|
mode = 'LA'
|
||||||
|
@ -109,13 +115,19 @@ def _parse_jp2_header(fp):
|
||||||
if meth == 1:
|
if meth == 1:
|
||||||
cs = struct.unpack('>I', content[3:7])[0]
|
cs = struct.unpack('>I', content[3:7])[0]
|
||||||
if cs == 16: # sRGB
|
if cs == 16: # sRGB
|
||||||
if nc == 3:
|
if nc == 1 and bpc > 8:
|
||||||
|
mode = 'I'
|
||||||
|
elif nc == 1:
|
||||||
|
mode = 'L'
|
||||||
|
elif nc == 3:
|
||||||
mode = 'RGB'
|
mode = 'RGB'
|
||||||
elif nc == 4:
|
elif nc == 4:
|
||||||
mode = 'RGBA'
|
mode = 'RGBA'
|
||||||
break
|
break
|
||||||
elif cs == 17: # grayscale
|
elif cs == 17: # grayscale
|
||||||
if nc == 1:
|
if nc == 1 and bpc > 8:
|
||||||
|
mode = 'I'
|
||||||
|
elif nc == 1:
|
||||||
mode = 'L'
|
mode = 'L'
|
||||||
elif nc == 2:
|
elif nc == 2:
|
||||||
mode = 'LA'
|
mode = 'LA'
|
||||||
|
@ -129,10 +141,10 @@ def _parse_jp2_header(fp):
|
||||||
|
|
||||||
return (size, mode)
|
return (size, mode)
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Image plugin for JPEG2000 images.
|
# Image plugin for JPEG2000 images.
|
||||||
|
|
||||||
|
|
||||||
class Jpeg2KImageFile(ImageFile.ImageFile):
|
class Jpeg2KImageFile(ImageFile.ImageFile):
|
||||||
format = "JPEG2000"
|
format = "JPEG2000"
|
||||||
format_description = "JPEG 2000 (ISO 15444)"
|
format_description = "JPEG 2000 (ISO 15444)"
|
||||||
|
|
|
@ -135,6 +135,56 @@ j2ku_gray_l(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
j2ku_gray_i(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
||||||
|
const UINT8 *tiledata, Imaging im)
|
||||||
|
{
|
||||||
|
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
|
||||||
|
unsigned w = tileinfo->x1 - tileinfo->x0;
|
||||||
|
unsigned h = tileinfo->y1 - tileinfo->y0;
|
||||||
|
|
||||||
|
int shift = 16 - in->comps[0].prec;
|
||||||
|
int offset = in->comps[0].sgnd ? 1 << (in->comps[0].prec - 1) : 0;
|
||||||
|
int csiz = (in->comps[0].prec + 7) >> 3;
|
||||||
|
|
||||||
|
unsigned x, y;
|
||||||
|
|
||||||
|
if (csiz == 3)
|
||||||
|
csiz = 4;
|
||||||
|
|
||||||
|
if (shift < 0)
|
||||||
|
offset += 1 << (-shift - 1);
|
||||||
|
|
||||||
|
switch (csiz) {
|
||||||
|
case 1:
|
||||||
|
for (y = 0; y < h; ++y) {
|
||||||
|
const UINT8 *data = &tiledata[y * w];
|
||||||
|
UINT32 *row = (UINT32 *)im->image[y0 + y] + x0;
|
||||||
|
for (x = 0; x < w; ++x)
|
||||||
|
*row++ = j2ku_shift(offset + *data++, shift);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
for (y = 0; y < h; ++y) {
|
||||||
|
const UINT16 *data = (const UINT16 *)&tiledata[2 * y * w];
|
||||||
|
UINT32 *row = (UINT32 *)im->image[y0 + y] + x0;
|
||||||
|
for (x = 0; x < w; ++x)
|
||||||
|
*row++ = j2ku_shift(offset + *data++, shift);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
for (y = 0; y < h; ++y) {
|
||||||
|
const UINT32 *data = (const UINT32 *)&tiledata[4 * y * w];
|
||||||
|
UINT32 *row = (UINT32 *)im->image[y0 + y] + x0;
|
||||||
|
for (x = 0; x < w; ++x)
|
||||||
|
*row++ = j2ku_shift(offset + *data++, shift);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
j2ku_gray_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
j2ku_gray_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
||||||
const UINT8 *tiledata, Imaging im)
|
const UINT8 *tiledata, Imaging im)
|
||||||
|
@ -466,6 +516,7 @@ j2ku_sycca_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
||||||
|
|
||||||
static const struct j2k_decode_unpacker j2k_unpackers[] = {
|
static const struct j2k_decode_unpacker j2k_unpackers[] = {
|
||||||
{ "L", OPJ_CLRSPC_GRAY, 1, j2ku_gray_l },
|
{ "L", OPJ_CLRSPC_GRAY, 1, j2ku_gray_l },
|
||||||
|
{ "I", OPJ_CLRSPC_GRAY, 1, j2ku_gray_i },
|
||||||
{ "LA", OPJ_CLRSPC_GRAY, 2, j2ku_graya_la },
|
{ "LA", OPJ_CLRSPC_GRAY, 2, j2ku_graya_la },
|
||||||
{ "RGB", OPJ_CLRSPC_GRAY, 1, j2ku_gray_rgb },
|
{ "RGB", OPJ_CLRSPC_GRAY, 1, j2ku_gray_rgb },
|
||||||
{ "RGB", OPJ_CLRSPC_GRAY, 2, j2ku_gray_rgb },
|
{ "RGB", OPJ_CLRSPC_GRAY, 2, j2ku_gray_rgb },
|
||||||
|
|
|
@ -88,6 +88,22 @@ j2k_pack_l(Imaging im, UINT8 *buf,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
j2k_pack_i16(Imaging im, UINT8 *buf,
|
||||||
|
unsigned x0, unsigned y0, unsigned w, unsigned h)
|
||||||
|
{
|
||||||
|
UINT8 *ptr = buf;
|
||||||
|
unsigned x,y;
|
||||||
|
for (y = 0; y < h; ++y) {
|
||||||
|
UINT8 *data = (UINT8 *)(im->image[y + y0] + x0);
|
||||||
|
for (x = 0; x < w; ++x) {
|
||||||
|
*ptr++ = *data++;
|
||||||
|
*ptr++ = *data++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
j2k_pack_la(Imaging im, UINT8 *buf,
|
j2k_pack_la(Imaging im, UINT8 *buf,
|
||||||
unsigned x0, unsigned y0, unsigned w, unsigned h)
|
unsigned x0, unsigned y0, unsigned w, unsigned h)
|
||||||
|
@ -247,6 +263,9 @@ j2k_encode_entry(Imaging im, ImagingCodecState state,
|
||||||
j2k_pack_tile_t pack;
|
j2k_pack_tile_t pack;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
|
unsigned prec = 8;
|
||||||
|
unsigned bpp = 8;
|
||||||
|
|
||||||
stream = opj_stream_default_create(OPJ_FALSE);
|
stream = opj_stream_default_create(OPJ_FALSE);
|
||||||
|
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
|
@ -271,6 +290,12 @@ 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")){
|
||||||
|
components = 1;
|
||||||
|
color_space = OPJ_CLRSPC_GRAY;
|
||||||
|
pack = j2k_pack_i16;
|
||||||
|
prec = 16;
|
||||||
|
bpp = 12;
|
||||||
} else if (strcmp (im->mode, "LA") == 0) {
|
} else if (strcmp (im->mode, "LA") == 0) {
|
||||||
components = 2;
|
components = 2;
|
||||||
color_space = OPJ_CLRSPC_GRAY;
|
color_space = OPJ_CLRSPC_GRAY;
|
||||||
|
@ -298,8 +323,8 @@ j2k_encode_entry(Imaging im, ImagingCodecState state,
|
||||||
image_params[n].w = im->xsize;
|
image_params[n].w = im->xsize;
|
||||||
image_params[n].h = im->ysize;
|
image_params[n].h = im->ysize;
|
||||||
image_params[n].x0 = image_params[n].y0 = 0;
|
image_params[n].x0 = image_params[n].y0 = 0;
|
||||||
image_params[n].prec = 8;
|
image_params[n].prec = prec;
|
||||||
image_params[n].bpp = 8;
|
image_params[n].bpp = bpp;
|
||||||
image_params[n].sgnd = 0;
|
image_params[n].sgnd = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,7 +467,7 @@ j2k_encode_entry(Imaging im, ImagingCodecState state,
|
||||||
|
|
||||||
num_tiles = tiles_x * tiles_y;
|
num_tiles = tiles_x * tiles_y;
|
||||||
|
|
||||||
state->buffer = malloc (tile_width * tile_height * components);
|
state->buffer = malloc (tile_width * tile_height * components * prec / 8);
|
||||||
|
|
||||||
tile_ndx = 0;
|
tile_ndx = 0;
|
||||||
for (y = 0; y < tiles_y; ++y) {
|
for (y = 0; y < tiles_y; ++y) {
|
||||||
|
@ -474,7 +499,7 @@ j2k_encode_entry(Imaging im, ImagingCodecState state,
|
||||||
|
|
||||||
pack(im, state->buffer, pixx, pixy, pixw, pixh);
|
pack(im, state->buffer, pixx, pixy, pixw, pixh);
|
||||||
|
|
||||||
data_size = pixw * pixh * components;
|
data_size = pixw * pixh * components * prec / 8;
|
||||||
|
|
||||||
if (!opj_write_tile(codec, tile_ndx++, state->buffer,
|
if (!opj_write_tile(codec, tile_ndx++, state->buffer,
|
||||||
data_size, stream)) {
|
data_size, stream)) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user