diff -rupN python-imaging-Pillow-72de37c/decode.c python-imaging-Pillow-72de37c-new/decode.c --- python-imaging-Pillow-72de37c/decode.c 2014-04-02 00:31:55.000000000 +0200 +++ python-imaging-Pillow-72de37c-new/decode.c 2014-05-27 14:12:58.913340062 +0200 @@ -800,8 +800,9 @@ PyImaging_Jpeg2KDecoderNew(PyObject* sel int reduce = 0; int layers = 0; int fd = -1; - if (!PyArg_ParseTuple(args, "ss|iii", &mode, &format, - &reduce, &layers, &fd)) + PY_LONG_LONG length = -1; + if (!PyArg_ParseTuple(args, "ss|iiiL", &mode, &format, + &reduce, &layers, &fd, &length)) return NULL; if (strcmp(format, "j2k") == 0) @@ -824,6 +825,7 @@ PyImaging_Jpeg2KDecoderNew(PyObject* sel context = (JPEG2KDECODESTATE *)decoder->state.context; context->fd = fd; + context->length = (off_t)length; context->format = codec_format; context->reduce = reduce; context->layers = layers; diff -rupN python-imaging-Pillow-72de37c/libImaging/Jpeg2KDecode.c python-imaging-Pillow-72de37c-new/libImaging/Jpeg2KDecode.c --- python-imaging-Pillow-72de37c/libImaging/Jpeg2KDecode.c 2014-04-02 00:31:55.000000000 +0200 +++ python-imaging-Pillow-72de37c-new/libImaging/Jpeg2KDecode.c 2014-05-27 14:14:02.756806143 +0200 @@ -517,7 +517,21 @@ j2k_decode_entry(Imaging im, ImagingCode opj_stream_set_read_function(stream, j2k_read); opj_stream_set_skip_function(stream, j2k_skip); +/* OpenJPEG 2.0 doesn't have OPJ_VERSION_MAJOR */ +#ifndef OPJ_VERSION_MAJOR opj_stream_set_user_data(stream, decoder); +#else + opj_stream_set_user_data(stream, decoder, NULL); + + /* Hack: if we don't know the length, the largest file we can + possibly support is 4GB. We can't go larger than this, because + OpenJPEG truncates this value for the final box in the file, and + the box lengths in OpenJPEG are currently 32 bit. */ + if (context->length < 0) + opj_stream_set_user_data_length(stream, 0xffffffff); + else + opj_stream_set_user_data_length(stream, context->length); +#endif /* Setup decompression context */ context->error_msg = NULL; diff -rupN python-imaging-Pillow-72de37c/libImaging/Jpeg2KEncode.c python-imaging-Pillow-72de37c-new/libImaging/Jpeg2KEncode.c --- python-imaging-Pillow-72de37c/libImaging/Jpeg2KEncode.c 2014-04-02 00:31:55.000000000 +0200 +++ python-imaging-Pillow-72de37c-new/libImaging/Jpeg2KEncode.c 2014-05-27 14:12:58.915340109 +0200 @@ -259,7 +259,11 @@ j2k_encode_entry(Imaging im, ImagingCode opj_stream_set_skip_function(stream, j2k_skip); opj_stream_set_seek_function(stream, j2k_seek); +#if OPJ_VERSION_MAJOR == 2 && OPJ_VERSION_MINOR == 0 opj_stream_set_user_data(stream, encoder); +#else + opj_stream_set_user_data(stream, encoder, NULL); +#endif /* Setup an opj_image */ if (strcmp (im->mode, "L") == 0) { diff -rupN python-imaging-Pillow-72de37c/libImaging/Jpeg2K.h python-imaging-Pillow-72de37c-new/libImaging/Jpeg2K.h --- python-imaging-Pillow-72de37c/libImaging/Jpeg2K.h 2014-04-02 00:31:55.000000000 +0200 +++ python-imaging-Pillow-72de37c-new/libImaging/Jpeg2K.h 2014-05-27 14:12:58.913340062 +0200 @@ -8,7 +8,7 @@ * Copyright (c) 2014 by Alastair Houghton */ -#include +#include /* -------------------------------------------------------------------- */ /* Decoder */ @@ -20,6 +20,9 @@ typedef struct { /* File descriptor, if available; otherwise, -1 */ int fd; + /* Length of data, if available; otherwise, -1 */ + off_t length; + /* Specify the desired format */ OPJ_CODEC_FORMAT format; diff -rupN python-imaging-Pillow-72de37c/PIL/Jpeg2KImagePlugin.py python-imaging-Pillow-72de37c-new/PIL/Jpeg2KImagePlugin.py --- python-imaging-Pillow-72de37c/PIL/Jpeg2KImagePlugin.py 2014-04-02 00:31:55.000000000 +0200 +++ python-imaging-Pillow-72de37c-new/PIL/Jpeg2KImagePlugin.py 2014-05-27 14:12:58.912340040 +0200 @@ -155,15 +155,25 @@ class Jpeg2KImageFile(ImageFile.ImageFil self.layers = 0 fd = -1 + length = -1 if hasattr(self.fp, "fileno"): try: fd = self.fp.fileno() + length = os.fstat(fd).st_size except: fd = -1 - + elif hasattr(self.fp, "seek"): + try: + pos = f.tell() + f.seek(0, 2) + length = f.tell() + f.seek(pos, 0) + except: + length = -1 + self.tile = [('jpeg2k', (0, 0) + self.size, 0, - (self.codec, self.reduce, self.layers, fd))] + (self.codec, self.reduce, self.layers, fd, length))] def load(self): if self.reduce: @@ -175,7 +185,7 @@ class Jpeg2KImageFile(ImageFile.ImageFil if self.tile: # Update the reduce and layers settings t = self.tile[0] - t3 = (t[3][0], self.reduce, self.layers, t[3][3]) + t3 = (t[3][0], self.reduce, self.layers, t[3][3], t[3][4]) self.tile = [(t[0], (0, 0) + self.size, t[2], t3)] ImageFile.ImageFile.load(self) diff -rupN python-imaging-Pillow-72de37c/setup.py python-imaging-Pillow-72de37c-new/setup.py --- python-imaging-Pillow-72de37c/setup.py 2014-04-02 00:31:55.000000000 +0200 +++ python-imaging-Pillow-72de37c-new/setup.py 2014-05-27 14:12:58.916340132 +0200 @@ -331,14 +331,23 @@ class pil_build_ext(build_ext): _add_directory(include_dirs, "/usr/include") # on Windows, look for the OpenJPEG libraries in the location that - # the official installed puts them + # the official installer puts them if sys.platform == "win32": - _add_directory(library_dirs, - os.path.join(os.environ.get("ProgramFiles", ""), - "OpenJPEG 2.0", "lib")) - _add_directory(include_dirs, - os.path.join(os.environ.get("ProgramFiles", ""), - "OpenJPEG 2.0", "include")) + program_files = os.environ.get('ProgramFiles', '') + best_version = (0, 0) + best_path = None + for name in os.listdir(program_files): + if name.startswith('OpenJPEG '): + version = tuple([int(x) for x in name[9:].strip().split('.')]) + if version > best_version: + best_version = version + best_path = os.path.join(program_files, name) + + if best_path: + _add_directory(library_dirs, + os.path.join(best_path, 'lib')) + _add_directory(include_dirs, + os.path.join(best_path, 'include')) # # insert new dirs *before* default libs, to avoid conflicts @@ -369,10 +378,28 @@ class pil_build_ext(build_ext): feature.jpeg = "libjpeg" # alternative name if feature.want('jpeg2000'): - if _find_include_file(self, "openjpeg-2.0/openjpeg.h"): - if _find_library_file(self, "openjp2"): - feature.jpeg2000 = "openjp2" - + best_version = None + best_path = None + + # Find the best version + for directory in self.compiler.include_dirs: + for name in os.listdir(directory): + if name.startswith('openjpeg-') and \ + os.path.isfile(os.path.join(directory, name, + 'openjpeg.h')): + version = tuple([int(x) for x in name[9:].split('.')]) + if best_version is None or version > best_version: + best_version = version + best_path = os.path.join(directory, name) + + if best_version and _find_library_file(self, 'openjp2'): + # Add the directory to the include path so we can include + # rather than having to cope with the versioned + # include path + _add_directory(self.compiler.include_dirs, best_path, 0) + feature.jpeg2000 = 'openjp2' + feature.openjpeg_version = '.'.join([str(x) for x in best_version]) + if feature.want('tiff'): if _find_library_file(self, "tiff"): feature.tiff = "tiff" @@ -566,7 +593,7 @@ class pil_build_ext(build_ext): options = [ (feature.tcl and feature.tk, "TKINTER"), (feature.jpeg, "JPEG"), - (feature.jpeg2000, "OPENJPEG (JPEG2000)"), + (feature.jpeg2000, "OPENJPEG (JPEG2000)", feature.openjpeg_version), (feature.zlib, "ZLIB (PNG/ZIP)"), (feature.tiff, "LIBTIFF"), (feature.freetype, "FREETYPE2"), @@ -577,7 +604,10 @@ class pil_build_ext(build_ext): all = 1 for option in options: if option[0]: - print("--- %s support available" % option[1]) + version = '' + if len(option) >= 3: + version = ' (%s)' % option[2] + print("--- %s support available%s" % (option[1], version)) else: print("*** %s support not available" % option[1]) if option[1] == "TKINTER" and _tkinter: