Skip to content

Commit

Permalink
Added tests and fixed a few bugs that the tests threw up.
Browse files Browse the repository at this point in the history
  • Loading branch information
al45tair committed Mar 19, 2014
1 parent 68fd58a commit ac8ebcc
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 16 deletions.
19 changes: 16 additions & 3 deletions PIL/Jpeg2KImagePlugin.py
Expand Up @@ -153,11 +153,15 @@ def _open(self):

self.reduce = 0
self.layers = 0

fd = -1

if hasattr(self.fp, "fileno"):
fd = self.fp.fileno()

try:
fd = self.fp.fileno()
except:
fd = -1

self.tile = [('jpeg2k', (0, 0) + self.size, 0,
(self.codec, self.reduce, self.layers, fd))]

Expand All @@ -167,6 +171,12 @@ def load(self):
adjust = power >> 1
self.size = ((self.size[0] + adjust) / power,
(self.size[1] + adjust) / power)

if self.tile:
# Update the reduce and layers settings
t = self.tile[0]
t3 = (t[3][0], self.reduce, self.layers, t[3][3])
self.tile = [(t[0], t[1], t[2], t3)]

ImageFile.ImageFile.load(self)

Expand Down Expand Up @@ -200,7 +210,10 @@ def _save(im, fp, filename):
fd = -1

if hasattr(fp, "fileno"):
fd = fp.fileno()
try:
fd = fp.fileno()
except:
fd = -1

im.encoderconfig = (
offset,
Expand Down
2 changes: 1 addition & 1 deletion decode.c
Expand Up @@ -827,7 +827,7 @@ PyImaging_Jpeg2KDecoderNew(PyObject* self, PyObject* args)
context->format = codec_format;
context->reduce = reduce;
context->layers = layers;

return (PyObject*) decoder;
}
#endif /* HAVE_OPENJPEG */
20 changes: 19 additions & 1 deletion encode.c
Expand Up @@ -885,7 +885,7 @@ PyImaging_Jpeg2KEncoderNew(PyObject *self, PyObject *args)
else
return NULL;

encoder = PyImaging_EncoderNew(sizeof(JPEG2KENCODESTATE));
encoder = PyImaging_EncoderNew(sizeof(JPEG2KENCODESTATE));
if (!encoder)
return NULL;

Expand All @@ -906,6 +906,24 @@ PyImaging_Jpeg2KEncoderNew(PyObject *self, PyObject *args)
&context->tile_size_x,
&context->tile_size_y);

/* Error on illegal tile offsets */
if (context->tile_size_x && context->tile_size_y) {
if (context->tile_offset_x <= context->offset_x - context->tile_size_x
|| context->tile_offset_y <= context->offset_y - context->tile_size_y) {
PyErr_SetString(PyExc_ValueError,
"JPEG 2000 tile offset too small; top left tile must "
"intersect image area");
}

if (context->tile_offset_x > context->offset_x
|| context->tile_offset_y > context->offset_y) {
PyErr_SetString(PyExc_ValueError,
"JPEG 2000 tile offset too large to cover image area");
Py_DECREF(encoder);
return NULL;
}
}

if (quality_layers && PySequence_Check(quality_layers)) {
context->quality_is_in_db = strcmp (quality_mode, "dB") == 0;
context->quality_layers = quality_layers;
Expand Down
13 changes: 13 additions & 0 deletions libImaging/Incremental.c
Expand Up @@ -93,8 +93,12 @@ codec_thread(void *ptr)
{
ImagingIncrementalCodec codec = (ImagingIncrementalCodec)ptr;

DEBUG("Entering thread\n");

codec->result = codec->entry(codec->im, codec->state, codec);

DEBUG("Leaving thread (%d)\n", codec->result);

flush_stream(codec);

SetEvent(codec->hCodecEvent);
Expand All @@ -107,8 +111,12 @@ codec_thread(void *ptr)
{
ImagingIncrementalCodec codec = (ImagingIncrementalCodec)ptr;

DEBUG("Entering thread\n");

codec->result = codec->entry(codec->im, codec->state, codec);

DEBUG("Leaving thread (%d)\n", codec->result);

flush_stream(codec);

pthread_mutex_lock(&codec->codec_mutex);
Expand Down Expand Up @@ -335,6 +343,11 @@ ImagingIncrementalCodecPushBuffer(ImagingIncrementalCodec codec,
pthread_cond_wait(&codec->codec_cond, &codec->codec_mutex);
pthread_mutex_unlock(&codec->codec_mutex);
#endif
if (codec->result < 0) {
DEBUG("got result %d\n", codec->result);

return codec->result;
}
}

/* Codecs using an fd don't need data, so when we get here, we're done */
Expand Down
30 changes: 22 additions & 8 deletions libImaging/Jpeg2KDecode.c
Expand Up @@ -91,7 +91,7 @@ static void
j2ku_gray_l(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
const UINT8 *tiledata, Imaging im)
{
unsigned x0 = tileinfo->x0, y0 = tileinfo->y0;
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
unsigned w = tileinfo->x1 - tileinfo->x0;
unsigned h = tileinfo->y1 - tileinfo->y0;

Expand Down Expand Up @@ -139,7 +139,7 @@ static void
j2ku_gray_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
const UINT8 *tiledata, Imaging im)
{
unsigned x0 = tileinfo->x0, y0 = tileinfo->y0;
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
unsigned w = tileinfo->x1 - tileinfo->x0;
unsigned h = tileinfo->y1 - tileinfo->y0;

Expand Down Expand Up @@ -199,7 +199,7 @@ static void
j2ku_graya_la(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
const UINT8 *tiledata, Imaging im)
{
unsigned x0 = tileinfo->x0, y0 = tileinfo->y0;
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
unsigned w = tileinfo->x1 - tileinfo->x0;
unsigned h = tileinfo->y1 - tileinfo->y0;

Expand Down Expand Up @@ -256,7 +256,7 @@ static void
j2ku_srgb_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
const UINT8 *tiledata, Imaging im)
{
unsigned x0 = tileinfo->x0, y0 = tileinfo->y0;
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
unsigned w = tileinfo->x1 - tileinfo->x0;
unsigned h = tileinfo->y1 - tileinfo->y0;

Expand Down Expand Up @@ -308,7 +308,7 @@ static void
j2ku_sycc_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
const UINT8 *tiledata, Imaging im)
{
unsigned x0 = tileinfo->x0, y0 = tileinfo->y0;
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
unsigned w = tileinfo->x1 - tileinfo->x0;
unsigned h = tileinfo->y1 - tileinfo->y0;

Expand Down Expand Up @@ -363,7 +363,7 @@ static void
j2ku_srgba_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
const UINT8 *tiledata, Imaging im)
{
unsigned x0 = tileinfo->x0, y0 = tileinfo->y0;
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
unsigned w = tileinfo->x1 - tileinfo->x0;
unsigned h = tileinfo->y1 - tileinfo->y0;

Expand Down Expand Up @@ -414,7 +414,7 @@ static void
j2ku_sycca_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
const UINT8 *tiledata, Imaging im)
{
unsigned x0 = tileinfo->x0, y0 = tileinfo->y0;
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
unsigned w = tileinfo->x1 - tileinfo->x0;
unsigned h = tileinfo->y1 - tileinfo->y0;

Expand Down Expand Up @@ -517,7 +517,7 @@ j2k_decode_entry(Imaging im, ImagingCodecState state,
opj_stream_set_read_function(stream, j2k_read);
opj_stream_set_skip_function(stream, j2k_skip);

opj_stream_set_user_data(stream, context->decoder);
opj_stream_set_user_data(stream, decoder);

/* Setup decompression context */
context->error_msg = NULL;
Expand Down Expand Up @@ -650,6 +650,20 @@ j2k_decode_entry(Imaging im, ImagingCodecState state,
goto quick_exit;
}

/* Check the tile bounds; if the tile is outside the image area,
or if it has a negative width or height (i.e. the coordinates are
swapped), bail. */
if (tile_info.x0 >= tile_info.x1
|| tile_info.y0 >= tile_info.y1
|| tile_info.x0 < image->x0
|| tile_info.y0 < image->y0
|| tile_info.x1 - image->x0 > im->xsize
|| tile_info.y1 - image->y0 > im->ysize) {
state->errcode = IMAGING_CODEC_BROKEN;
state->state = J2K_STATE_FAILED;
goto quick_exit;
}

unpack(image, &tile_info, state->buffer, im);
}

Expand Down
9 changes: 6 additions & 3 deletions libImaging/Jpeg2KEncode.c
Expand Up @@ -254,7 +254,7 @@ j2k_encode_entry(Imaging im, ImagingCodecState state,
opj_stream_set_skip_function(stream, j2k_skip);
opj_stream_set_seek_function(stream, j2k_seek);

opj_stream_set_user_data(stream, context->encoder);
opj_stream_set_user_data(stream, encoder);

/* Setup an opj_image */
if (strcmp (im->mode, "L") == 0) {
Expand Down Expand Up @@ -425,8 +425,11 @@ j2k_encode_entry(Imaging im, ImagingCodecState state,
}

/* Write each tile */
tiles_x = (im->xsize + tile_width - 1) / tile_width;
tiles_y = (im->ysize + tile_height - 1) / tile_height;
tiles_x = (im->xsize + (params.image_offset_x0 - params.cp_tx0)
+ tile_width - 1) / tile_width;
tiles_y = (im->ysize + (params.image_offset_y0 - params.cp_ty0)
+ tile_height - 1) / tile_height;

num_tiles = tiles_x * tiles_y;

state->buffer = malloc (tile_width * tile_height * components);
Expand Down
1 change: 1 addition & 0 deletions selftest.py
Expand Up @@ -192,6 +192,7 @@ def check_codec(feature, codec):
check_module("PIL CORE", "PIL._imaging")
check_module("TKINTER", "PIL._imagingtk")
check_codec("JPEG", "jpeg")
check_codec("JPEG 2000", "jpeg2k")
check_codec("ZLIB (PNG/ZIP)", "zip")
check_codec("LIBTIFF", "libtiff")
check_module("FREETYPE2", "PIL._imagingft")
Expand Down

0 comments on commit ac8ebcc

Please sign in to comment.