Fixed some bugs.

This commit is contained in:
Alastair Houghton 2014-03-13 12:29:03 +00:00
parent 7dba77364a
commit 5b22b715ce
3 changed files with 97 additions and 48 deletions

View File

@ -138,12 +138,10 @@ class Jpeg2KImageFile(ImageFile.ImageFile):
sig = self.fp.read(4) sig = self.fp.read(4)
if sig == b'\xff\x4f\xff\x51': if sig == b'\xff\x4f\xff\x51':
self.codec = "j2k" self.codec = "j2k"
print 'Reading size/mode'
try: try:
self.size, self.mode = _parse_codestream(self.fp) self.size, self.mode = _parse_codestream(self.fp)
except Exception as e: except Exception as e:
print e print e
print '%r, %r' % (self.size, self.mode)
else: else:
sig = sig + self.fp.read(8) sig = sig + self.fp.read(8)

View File

@ -42,6 +42,14 @@
#include <pthread.h> #include <pthread.h>
#endif #endif
#define DEBUG_INCREMENTAL 0
#if DEBUG_INCREMENTAL
#define DEBUG(...) printf(__VA_ARGS__)
#else
#define DEBUG(...)
#endif
struct ImagingIncrementalStreamStruct { struct ImagingIncrementalStreamStruct {
UINT8 *buffer; UINT8 *buffer;
UINT8 *ptr; UINT8 *ptr;
@ -206,6 +214,8 @@ ImagingIncrementalDecoderCreate(ImagingIncrementalDecoderEntry decoder_entry,
void void
ImagingIncrementalDecoderDestroy(ImagingIncrementalDecoder decoder) ImagingIncrementalDecoderDestroy(ImagingIncrementalDecoder decoder)
{ {
DEBUG("destroying\n");
if (!decoder->started) { if (!decoder->started) {
#ifdef _WIN32 #ifdef _WIN32
ResumeThread(decoder->hThread); ResumeThread(decoder->hThread);
@ -252,6 +262,8 @@ ImagingIncrementalDecodeData(ImagingIncrementalDecoder decoder,
UINT8 *buf, int bytes) UINT8 *buf, int bytes)
{ {
if (!decoder->started) { if (!decoder->started) {
DEBUG("starting\n");
#ifdef _WIN32 #ifdef _WIN32
ResumeThread(decoder->hThread); ResumeThread(decoder->hThread);
#else #else
@ -260,6 +272,8 @@ ImagingIncrementalDecodeData(ImagingIncrementalDecoder decoder,
decoder->started = 1; decoder->started = 1;
} }
DEBUG("providing %p, %d\n", buf, bytes);
#ifndef _WIN32 #ifndef _WIN32
pthread_mutex_lock(&decoder->data_mutex); pthread_mutex_lock(&decoder->data_mutex);
#endif #endif
@ -279,6 +293,8 @@ ImagingIncrementalDecodeData(ImagingIncrementalDecoder decoder,
pthread_mutex_unlock(&decoder->decode_mutex); pthread_mutex_unlock(&decoder->decode_mutex);
#endif #endif
DEBUG("got result %d\n", decoder->result);
return decoder->result; return decoder->result;
} }
@ -289,12 +305,74 @@ ImagingIncrementalDecoderRead(ImagingIncrementalDecoder decoder,
UINT8 *ptr = (UINT8 *)buffer; UINT8 *ptr = (UINT8 *)buffer;
size_t done = 0; size_t done = 0;
DEBUG("reading (want %llu bytes)\n", (unsigned long long)bytes);
#ifndef _WIN32
pthread_mutex_lock(&decoder->data_mutex); pthread_mutex_lock(&decoder->data_mutex);
#endif
while (bytes) { while (bytes) {
size_t todo = bytes; size_t todo = bytes;
size_t remaining = decoder->stream.end - decoder->stream.ptr; size_t remaining = decoder->stream.end - decoder->stream.ptr;
if (!remaining) { 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 #ifndef _WIN32
pthread_mutex_lock(&decoder->decode_mutex); pthread_mutex_lock(&decoder->decode_mutex);
#endif #endif
@ -316,50 +394,15 @@ ImagingIncrementalDecoderRead(ImagingIncrementalDecoder decoder,
if (!todo) if (!todo)
break; break;
memcpy (ptr, decoder->stream.ptr, todo);
decoder->stream.ptr += todo; decoder->stream.ptr += todo;
bytes -= todo; bytes -= todo;
done += todo; done += todo;
ptr += todo;
} }
#ifndef _WIN32
pthread_mutex_unlock(&decoder->data_mutex); 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 #endif
remaining = decoder->stream.end - decoder->stream.ptr; DEBUG("skipped total %llu bytes\n", (unsigned long long)done);
}
if (todo > remaining)
todo = remaining;
if (!todo)
break;
decoder->stream.ptr += todo;
bytes -= todo;
done += todo;
}
return done; return done;
} }

View File

@ -17,7 +17,7 @@
#ifdef HAVE_OPENJPEG #ifdef HAVE_OPENJPEG
#include <unistd.h> #include <stdlib.h>
#include "Jpeg2K.h" #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; 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 static OPJ_SIZE_T
j2k_write(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) 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 static OPJ_OFF_T
j2k_skip(OPJ_OFF_T p_nb_bytes, void *p_user_data) j2k_skip(OPJ_OFF_T p_nb_bytes, void *p_user_data)
{ {
ImagingIncrementalDecoder decoder = (ImagingIncrementalDecoder)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 static OPJ_BOOL
j2k_seek(OPJ_OFF_T p_nb_bytes, void *p_user_data) 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; return OPJ_FALSE;
} }
@ -281,12 +289,12 @@ j2k_decode_entry(Imaging im, ImagingCodecState state,
ImagingIncrementalDecoder decoder) ImagingIncrementalDecoder decoder)
{ {
JPEG2KSTATE *context = (JPEG2KSTATE *) state->context; JPEG2KSTATE *context = (JPEG2KSTATE *) state->context;
opj_stream_t *stream; opj_stream_t *stream = NULL;
opj_image_t *image; opj_image_t *image = NULL;
opj_codec_t *codec; opj_codec_t *codec = NULL;
opj_dparameters_t params; opj_dparameters_t params;
OPJ_COLOR_SPACE color_space; OPJ_COLOR_SPACE color_space;
j2k_unpacker_t unpack; j2k_unpacker_t unpack = NULL;
unsigned n; unsigned n;
stream = opj_stream_default_create(OPJ_TRUE); stream = opj_stream_default_create(OPJ_TRUE);