diff --git a/libImaging/Jpeg2KEncode.c b/libImaging/Jpeg2KEncode.c index c1e16e97f..4aaefd60a 100644 --- a/libImaging/Jpeg2KEncode.c +++ b/libImaging/Jpeg2KEncode.c @@ -88,6 +88,38 @@ 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[1]; + *ptr++ = data[0]; + data += 2; + } + } +} + +static void +j2k_pack_i16b(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[0]; + *ptr++ = data[1]; + data += 2; + } + } +} + static void j2k_pack_la(Imaging im, UINT8 *buf, unsigned x0, unsigned y0, unsigned w, unsigned h) @@ -247,6 +279,9 @@ j2k_encode_entry(Imaging im, ImagingCodecState state, j2k_pack_tile_t pack; int ret = -1; + unsigned prec = 8; + unsigned bpp = 8; + stream = opj_stream_default_create(OPJ_FALSE); if (!stream) { @@ -266,6 +301,18 @@ j2k_encode_entry(Imaging im, ImagingCodecState state, components = 1; color_space = OPJ_CLRSPC_GRAY; pack = j2k_pack_l; + } else if (strcmp (im->mode, "I;16") == 0) { + components = 1; + color_space = OPJ_CLRSPC_GRAY; + pack = j2k_pack_i16; + prec = 16; + bpp = 16; + } else if (strcmp (im->mode, "I;16B") == 0) { + components = 1; + color_space = OPJ_CLRSPC_GRAY; + pack = j2k_pack_i16b; + prec = 16; + bpp = 16; } else if (strcmp (im->mode, "LA") == 0) { components = 2; color_space = OPJ_CLRSPC_GRAY; @@ -293,8 +340,8 @@ j2k_encode_entry(Imaging im, ImagingCodecState state, image_params[n].w = im->xsize; image_params[n].h = im->ysize; image_params[n].x0 = image_params[n].y0 = 0; - image_params[n].prec = 8; - image_params[n].bpp = 8; + image_params[n].prec = prec; + image_params[n].bpp = bpp; image_params[n].sgnd = 0; } @@ -437,7 +484,7 @@ j2k_encode_entry(Imaging im, ImagingCodecState state, 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; for (y = 0; y < tiles_y; ++y) { @@ -469,7 +516,7 @@ j2k_encode_entry(Imaging im, ImagingCodecState state, 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, data_size, stream)) {