diff --git a/PIL/Jpeg2KImagePlugin.py b/PIL/Jpeg2KImagePlugin.py index 95d206a99..62aced03e 100644 --- a/PIL/Jpeg2KImagePlugin.py +++ b/PIL/Jpeg2KImagePlugin.py @@ -138,12 +138,10 @@ class Jpeg2KImageFile(ImageFile.ImageFile): sig = self.fp.read(4) if sig == b'\xff\x4f\xff\x51': self.codec = "j2k" - print 'Reading size/mode' try: self.size, self.mode = _parse_codestream(self.fp) except Exception as e: print e - print '%r, %r' % (self.size, self.mode) else: sig = sig + self.fp.read(8) diff --git a/libImaging/Incremental.c b/libImaging/Incremental.c index 0e81af7e8..bb51d91c7 100644 --- a/libImaging/Incremental.c +++ b/libImaging/Incremental.c @@ -42,6 +42,14 @@ #include #endif +#define DEBUG_INCREMENTAL 0 + +#if DEBUG_INCREMENTAL +#define DEBUG(...) printf(__VA_ARGS__) +#else +#define DEBUG(...) +#endif + struct ImagingIncrementalStreamStruct { UINT8 *buffer; UINT8 *ptr; @@ -206,6 +214,8 @@ ImagingIncrementalDecoderCreate(ImagingIncrementalDecoderEntry decoder_entry, void ImagingIncrementalDecoderDestroy(ImagingIncrementalDecoder decoder) { + DEBUG("destroying\n"); + if (!decoder->started) { #ifdef _WIN32 ResumeThread(decoder->hThread); @@ -252,6 +262,8 @@ ImagingIncrementalDecodeData(ImagingIncrementalDecoder decoder, UINT8 *buf, int bytes) { if (!decoder->started) { + DEBUG("starting\n"); + #ifdef _WIN32 ResumeThread(decoder->hThread); #else @@ -260,6 +272,8 @@ ImagingIncrementalDecodeData(ImagingIncrementalDecoder decoder, decoder->started = 1; } + DEBUG("providing %p, %d\n", buf, bytes); + #ifndef _WIN32 pthread_mutex_lock(&decoder->data_mutex); #endif @@ -279,6 +293,8 @@ ImagingIncrementalDecodeData(ImagingIncrementalDecoder decoder, pthread_mutex_unlock(&decoder->decode_mutex); #endif + DEBUG("got result %d\n", decoder->result); + return decoder->result; } @@ -289,12 +305,74 @@ ImagingIncrementalDecoderRead(ImagingIncrementalDecoder decoder, UINT8 *ptr = (UINT8 *)buffer; size_t done = 0; + DEBUG("reading (want %llu bytes)\n", (unsigned long long)bytes); + +#ifndef _WIN32 pthread_mutex_lock(&decoder->data_mutex); +#endif while (bytes) { size_t todo = bytes; size_t remaining = decoder->stream.end - decoder->stream.ptr; if (!remaining) { + DEBUG("waiting for data\n"); + +#ifndef _WIN32 + pthread_mutex_lock(&decoder->decode_mutex); +#endif + decoder->result = (int)(decoder->stream.ptr - decoder->stream.buffer); +#if _WIN32 + SetEvent(decoder->hDecodeEvent); + WaitForSingleObject(decoder->hDataEvent); +#else + pthread_cond_signal(&decoder->decode_cond); + pthread_mutex_unlock(&decoder->decode_mutex); + pthread_cond_wait(&decoder->data_cond, &decoder->data_mutex); +#endif + + remaining = decoder->stream.end - decoder->stream.ptr; + + DEBUG("got %llu bytes\n", (unsigned long long)remaining); + } + if (todo > remaining) + todo = remaining; + + if (!todo) + break; + + memcpy (ptr, decoder->stream.ptr, todo); + decoder->stream.ptr += todo; + bytes -= todo; + done += todo; + ptr += todo; + } +#ifndef _WIN32 + pthread_mutex_unlock(&decoder->data_mutex); +#endif + + DEBUG("read total %llu bytes\n", (unsigned long long)done); + + return done; +} + +off_t +ImagingIncrementalDecoderSkip(ImagingIncrementalDecoder decoder, + off_t bytes) +{ + off_t done = 0; + + DEBUG("skipping (want %llu bytes)\n", (unsigned long long)bytes); + +#ifndef _WIN32 + pthread_mutex_lock(&decoder->data_mutex); +#endif + while (bytes) { + off_t todo = bytes; + off_t remaining = decoder->stream.end - decoder->stream.ptr; + + if (!remaining) { + DEBUG("waiting for data\n"); + #ifndef _WIN32 pthread_mutex_lock(&decoder->decode_mutex); #endif @@ -316,50 +394,15 @@ ImagingIncrementalDecoderRead(ImagingIncrementalDecoder decoder, if (!todo) break; - memcpy (ptr, decoder->stream.ptr, todo); decoder->stream.ptr += todo; bytes -= todo; done += todo; - ptr += todo; } +#ifndef _WIN32 pthread_mutex_unlock(&decoder->data_mutex); - - return done; -} - -off_t -ImagingIncrementalDecoderSkip(ImagingIncrementalDecoder decoder, - off_t bytes) -{ - off_t done = 0; - - while (bytes) { - off_t todo = bytes; - off_t remaining = decoder->stream.end - decoder->stream.ptr; - - if (!remaining) { - decoder->result = (int)(decoder->stream.ptr - decoder->stream.buffer); -#if _WIN32 - SetEvent(decoder->hDecodeEvent); - WaitForSingleObject(decoder->hDataEvent); -#else - pthread_cond_signal(&decoder->decode_cond); - pthread_mutex_lock(&decoder->data_mutex); - pthread_cond_wait(&decoder->data_cond, &decoder->data_mutex); #endif - remaining = decoder->stream.end - decoder->stream.ptr; - } - if (todo > remaining) - todo = remaining; - - if (!todo) - break; - - decoder->stream.ptr += todo; - bytes -= todo; - done += todo; - } + DEBUG("skipped total %llu bytes\n", (unsigned long long)done); return done; } diff --git a/libImaging/Jpeg2KDecode.c b/libImaging/Jpeg2KDecode.c index e050c5216..5c1d4cd42 100644 --- a/libImaging/Jpeg2KDecode.c +++ b/libImaging/Jpeg2KDecode.c @@ -17,7 +17,7 @@ #ifdef HAVE_OPENJPEG -#include +#include #include "Jpeg2K.h" /* -------------------------------------------------------------------- */ @@ -41,27 +41,35 @@ j2k_read(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) { ImagingIncrementalDecoder decoder = (ImagingIncrementalDecoder)p_user_data; - return ImagingIncrementalDecoderRead(decoder, p_buffer, p_nb_bytes); + size_t len = ImagingIncrementalDecoderRead(decoder, p_buffer, p_nb_bytes); + + return len ? len : (OPJ_SIZE_T)-1; } static OPJ_SIZE_T j2k_write(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) { - return OPJ_FALSE; + /* This should never happen */ + fprintf(stderr, "OpenJPEG has written to our read stream(!)"); + abort(); + return (OPJ_SIZE_T)-1; } static OPJ_OFF_T j2k_skip(OPJ_OFF_T p_nb_bytes, void *p_user_data) { ImagingIncrementalDecoder decoder = (ImagingIncrementalDecoder)p_user_data; + off_t pos = ImagingIncrementalDecoderSkip(decoder, p_nb_bytes); - return ImagingIncrementalDecoderSkip(decoder, p_nb_bytes); + return pos ? pos : (OPJ_OFF_T)-1; } static OPJ_BOOL j2k_seek(OPJ_OFF_T p_nb_bytes, void *p_user_data) { - // We *deliberately* don't implement this + /* This should never happen */ + fprintf(stderr, "OpenJPEG tried to seek our read stream(!)"); + abort(); return OPJ_FALSE; } @@ -281,12 +289,12 @@ j2k_decode_entry(Imaging im, ImagingCodecState state, ImagingIncrementalDecoder decoder) { JPEG2KSTATE *context = (JPEG2KSTATE *) state->context; - opj_stream_t *stream; - opj_image_t *image; - opj_codec_t *codec; + opj_stream_t *stream = NULL; + opj_image_t *image = NULL; + opj_codec_t *codec = NULL; opj_dparameters_t params; OPJ_COLOR_SPACE color_space; - j2k_unpacker_t unpack; + j2k_unpacker_t unpack = NULL; unsigned n; stream = opj_stream_default_create(OPJ_TRUE);