PyTurboJPEG 2.3.0__tar.gz → 2.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyturbojpeg-2.3.0 → pyturbojpeg-2.4.0}/PKG-INFO +8 -1
- {pyturbojpeg-2.3.0 → pyturbojpeg-2.4.0}/PyTurboJPEG.egg-info/PKG-INFO +8 -1
- {pyturbojpeg-2.3.0 → pyturbojpeg-2.4.0}/README.md +7 -0
- {pyturbojpeg-2.3.0 → pyturbojpeg-2.4.0}/setup.py +1 -1
- {pyturbojpeg-2.3.0 → pyturbojpeg-2.4.0}/tests/test_turbojpeg.py +11 -0
- {pyturbojpeg-2.3.0 → pyturbojpeg-2.4.0}/turbojpeg.py +39 -1
- {pyturbojpeg-2.3.0 → pyturbojpeg-2.4.0}/LICENSE +0 -0
- {pyturbojpeg-2.3.0 → pyturbojpeg-2.4.0}/PyTurboJPEG.egg-info/SOURCES.txt +0 -0
- {pyturbojpeg-2.3.0 → pyturbojpeg-2.4.0}/PyTurboJPEG.egg-info/dependency_links.txt +0 -0
- {pyturbojpeg-2.3.0 → pyturbojpeg-2.4.0}/PyTurboJPEG.egg-info/requires.txt +0 -0
- {pyturbojpeg-2.3.0 → pyturbojpeg-2.4.0}/PyTurboJPEG.egg-info/top_level.txt +0 -0
- {pyturbojpeg-2.3.0 → pyturbojpeg-2.4.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyTurboJPEG
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.0
|
|
4
4
|
Summary: A Python wrapper of libjpeg-turbo for decoding and encoding JPEG image.
|
|
5
5
|
Home-page: https://github.com/lilohuang/PyTurboJPEG
|
|
6
6
|
Author: Lilo Huang
|
|
@@ -179,6 +179,13 @@ with open('input.jpg', 'rb') as f:
|
|
|
179
179
|
cropped_data = jpeg.crop(f.read(), 8, 8, 320, 240)
|
|
180
180
|
with open('cropped_output.jpg', 'wb') as f:
|
|
181
181
|
f.write(cropped_data)
|
|
182
|
+
|
|
183
|
+
# Lossless Huffman table optimization (re-encodes with optimal tables,
|
|
184
|
+
# identical pixels; typically smaller unless already optimized)
|
|
185
|
+
with open('input.jpg', 'rb') as f:
|
|
186
|
+
optimized_data = jpeg.optimize(f.read())
|
|
187
|
+
with open('optimized_output.jpg', 'wb') as f:
|
|
188
|
+
f.write(optimized_data)
|
|
182
189
|
```
|
|
183
190
|
|
|
184
191
|
### In-Place Operations
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyTurboJPEG
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.0
|
|
4
4
|
Summary: A Python wrapper of libjpeg-turbo for decoding and encoding JPEG image.
|
|
5
5
|
Home-page: https://github.com/lilohuang/PyTurboJPEG
|
|
6
6
|
Author: Lilo Huang
|
|
@@ -179,6 +179,13 @@ with open('input.jpg', 'rb') as f:
|
|
|
179
179
|
cropped_data = jpeg.crop(f.read(), 8, 8, 320, 240)
|
|
180
180
|
with open('cropped_output.jpg', 'wb') as f:
|
|
181
181
|
f.write(cropped_data)
|
|
182
|
+
|
|
183
|
+
# Lossless Huffman table optimization (re-encodes with optimal tables,
|
|
184
|
+
# identical pixels; typically smaller unless already optimized)
|
|
185
|
+
with open('input.jpg', 'rb') as f:
|
|
186
|
+
optimized_data = jpeg.optimize(f.read())
|
|
187
|
+
with open('optimized_output.jpg', 'wb') as f:
|
|
188
|
+
f.write(optimized_data)
|
|
182
189
|
```
|
|
183
190
|
|
|
184
191
|
### In-Place Operations
|
|
@@ -155,6 +155,13 @@ with open('input.jpg', 'rb') as f:
|
|
|
155
155
|
cropped_data = jpeg.crop(f.read(), 8, 8, 320, 240)
|
|
156
156
|
with open('cropped_output.jpg', 'wb') as f:
|
|
157
157
|
f.write(cropped_data)
|
|
158
|
+
|
|
159
|
+
# Lossless Huffman table optimization (re-encodes with optimal tables,
|
|
160
|
+
# identical pixels; typically smaller unless already optimized)
|
|
161
|
+
with open('input.jpg', 'rb') as f:
|
|
162
|
+
optimized_data = jpeg.optimize(f.read())
|
|
163
|
+
with open('optimized_output.jpg', 'wb') as f:
|
|
164
|
+
f.write(optimized_data)
|
|
158
165
|
```
|
|
159
166
|
|
|
160
167
|
### In-Place Operations
|
|
@@ -2,7 +2,7 @@ import io
|
|
|
2
2
|
from setuptools import setup, find_packages
|
|
3
3
|
setup(
|
|
4
4
|
name='PyTurboJPEG',
|
|
5
|
-
version='2.
|
|
5
|
+
version='2.4.0',
|
|
6
6
|
description='A Python wrapper of libjpeg-turbo for decoding and encoding JPEG image.',
|
|
7
7
|
author='Lilo Huang',
|
|
8
8
|
author_email='kuso.cc@gmail.com',
|
|
@@ -513,6 +513,17 @@ class TestCropMultiple:
|
|
|
513
513
|
assert subsample == TJSAMP_GRAY
|
|
514
514
|
|
|
515
515
|
|
|
516
|
+
class TestOptimize:
|
|
517
|
+
"""Test optimize function."""
|
|
518
|
+
|
|
519
|
+
def test_optimize_is_lossless(self, jpeg_instance, encoded_sample_jpeg):
|
|
520
|
+
"""Test optimization returns a valid JPEG with unchanged pixels."""
|
|
521
|
+
optimized = jpeg_instance.optimize(encoded_sample_jpeg)
|
|
522
|
+
original_pixels = jpeg_instance.decode(encoded_sample_jpeg)
|
|
523
|
+
optimized_pixels = jpeg_instance.decode(optimized)
|
|
524
|
+
assert np.array_equal(original_pixels, optimized_pixels)
|
|
525
|
+
|
|
526
|
+
|
|
516
527
|
class TestBufferSize:
|
|
517
528
|
"""Test buffer_size function."""
|
|
518
529
|
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
# SOFTWARE.
|
|
24
24
|
|
|
25
25
|
__author__ = 'Lilo Huang <kuso.cc@gmail.com>'
|
|
26
|
-
__version__ = '2.
|
|
26
|
+
__version__ = '2.4.0'
|
|
27
27
|
|
|
28
28
|
from ctypes import *
|
|
29
29
|
from ctypes.util import find_library
|
|
@@ -125,6 +125,7 @@ TJXOPT_GRAY = 8
|
|
|
125
125
|
TJXOPT_NOOUTPUT = 16
|
|
126
126
|
TJXOPT_PROGRESSIVE = 32
|
|
127
127
|
TJXOPT_COPYNONE = 64
|
|
128
|
+
TJXOPT_OPTIMIZE = 256 # Huffman table optimization
|
|
128
129
|
|
|
129
130
|
# pixel size
|
|
130
131
|
# see details in https://github.com/libjpeg-turbo/libjpeg-turbo/blob/main/src/turbojpeg.h
|
|
@@ -1351,6 +1352,43 @@ class TurboJPEG(object):
|
|
|
1351
1352
|
finally:
|
|
1352
1353
|
self.__destroy(handle)
|
|
1353
1354
|
|
|
1355
|
+
def optimize(self, jpeg_buf, copynone=False):
|
|
1356
|
+
"""Losslessly optimize the Huffman tables of a jpeg image.
|
|
1357
|
+
|
|
1358
|
+
Re-encodes the entropy-coded data with optimal Huffman tables
|
|
1359
|
+
(equivalent to ``jpegtran -optimize``) without any loss in image
|
|
1360
|
+
quality. Typically reduces file size, unless the input is already
|
|
1361
|
+
optimized.
|
|
1362
|
+
|
|
1363
|
+
Parameters
|
|
1364
|
+
----------
|
|
1365
|
+
jpeg_buf: bytes
|
|
1366
|
+
Input jpeg image.
|
|
1367
|
+
copynone: bool
|
|
1368
|
+
True = do not copy EXIF data (False by default)
|
|
1369
|
+
|
|
1370
|
+
Returns
|
|
1371
|
+
----------
|
|
1372
|
+
bytes
|
|
1373
|
+
Huffman-optimized jpeg image.
|
|
1374
|
+
"""
|
|
1375
|
+
handle = self.__init(TJINIT_TRANSFORM)
|
|
1376
|
+
try:
|
|
1377
|
+
jpeg_array = np.frombuffer(jpeg_buf, dtype=np.uint8)
|
|
1378
|
+
src_addr = self.__getaddr(jpeg_array)
|
|
1379
|
+
status = self.__decompress_header(handle, src_addr, jpeg_array.size)
|
|
1380
|
+
if status != 0:
|
|
1381
|
+
self.__report_error(handle)
|
|
1382
|
+
# Without TJXOPT_CROP the cropping region is ignored and the whole
|
|
1383
|
+
# image is transformed, so the (zeroed) region needs no setup.
|
|
1384
|
+
transforms = (TransformStruct * 1)()
|
|
1385
|
+
transforms[0].op = TJXOP_NONE
|
|
1386
|
+
transforms[0].options = TJXOPT_OPTIMIZE | (copynone and TJXOPT_COPYNONE)
|
|
1387
|
+
return self.__do_transform(handle, src_addr, jpeg_array.size, 1, transforms)[0]
|
|
1388
|
+
|
|
1389
|
+
finally:
|
|
1390
|
+
self.__destroy(handle)
|
|
1391
|
+
|
|
1354
1392
|
def buffer_size(self, img_array, jpeg_subsample=TJSAMP_422):
|
|
1355
1393
|
"""Get maximum number of bytes of compressed jpeg data"""
|
|
1356
1394
|
height, width = img_array.shape[:2]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|