From ae3da712f82bf5cd682d6efa1ba765085469ef69 Mon Sep 17 00:00:00 2001 From: Lilo Huang Date: Sat, 8 Jan 2022 19:30:54 +0800 Subject: [PATCH] Improved encode() error handling on wrong array shape 1. Improved encode() error handling on wrong array shape (silent crash on wrong array shape #57) 2. Added an extra turbojpeg default path for Mac OS --- setup.py | 2 +- turbojpeg.py | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index c42c259..970b8d2 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name='PyTurboJPEG', - version='1.6.4', + version='1.6.5', description='A Python wrapper of libjpeg-turbo for decoding and encoding JPEG image.', author='Lilo Huang', author_email='kuso.cc@gmail.com', diff --git a/turbojpeg.py b/turbojpeg.py index 3b97058..d350c18 100644 --- a/turbojpeg.py +++ b/turbojpeg.py @@ -23,7 +23,7 @@ # SOFTWARE. __author__ = 'Lilo Huang ' -__version__ = '1.6.4' +__version__ = '1.6.5' from ctypes import * from ctypes.util import find_library @@ -36,7 +36,10 @@ # default libTurboJPEG library path DEFAULT_LIB_PATHS = { - 'Darwin': ['/usr/local/opt/jpeg-turbo/lib/libturbojpeg.dylib'], + 'Darwin': [ + '/usr/local/opt/jpeg-turbo/lib/libturbojpeg.dylib', + '/opt/libjpeg-turbo/lib64/libturbojpeg.dylib' + ], 'Linux': [ '/usr/lib/x86_64-linux-gnu/libturbojpeg.so.0', '/usr/lib64/libturbojpeg.so.0', @@ -111,6 +114,10 @@ TJXOPT_PROGRESSIVE = 32 TJXOPT_COPYNONE = 64 +# pixel size +# see details in https://github.com/libjpeg-turbo/libjpeg-turbo/blob/master/turbojpeg.h +tjPixelSize = [3, 3, 4, 4, 4, 4, 1, 4, 4, 4, 4, 4] + # MCU block width (in pixels) for a given level of chrominance subsampling. # MCU block sizes: # - 8x8 for no subsampling or grayscale @@ -395,13 +402,12 @@ def decode(self, jpeg_buf, pixel_format=TJPF_BGR, scaling_factor=None, flags=0): """decodes JPEG memory buffer to numpy array.""" handle = self.__init_decompress() try: - pixel_size = [3, 3, 4, 4, 4, 4, 1, 4, 4, 4, 4, 4] jpeg_array = np.frombuffer(jpeg_buf, dtype=np.uint8) src_addr = self.__getaddr(jpeg_array) scaled_width, scaled_height, _, _ = \ self.__get_header_and_dimensions(handle, jpeg_array.size, src_addr, scaling_factor) img_array = np.empty( - [scaled_height, scaled_width, pixel_size[pixel_format]], + [scaled_height, scaled_width, tjPixelSize[pixel_format]], dtype=np.uint8) dest_addr = self.__getaddr(img_array) status = self.__decompress( @@ -477,6 +483,9 @@ def encode(self, img_array, quality=85, pixel_format=TJPF_BGR, jpeg_subsample=TJ jpeg_buf = c_void_p() jpeg_size = c_ulong() height, width = img_array.shape[:2] + channel = tjPixelSize[pixel_format] + if channel > 1 and (len(img_array.shape) < 3 or img_array.shape[2] != channel): + raise ValueError('Invalid shape for image data') src_addr = self.__getaddr(img_array) status = self.__compress( handle, src_addr, width, img_array.strides[0], height, pixel_format,