fix: jp2 image size bytes header
This commit is contained in:
@@ -29,6 +29,32 @@ def determine_file_ext(data: bytes) -> Optional[str]:
|
||||
return None
|
||||
|
||||
|
||||
def _determine_jp2_size(data: bytes) -> Optional[Tuple[int, int]]:
|
||||
''' Read raw bytes and extract JPEG2000 image size. '''
|
||||
if data[:4] == b'\xFF\x4F\xFF\x51':
|
||||
w, h = struct.unpack('>II', data[8:16])
|
||||
return w, h
|
||||
|
||||
# fixed "jP" file header 0000000C 6A502020 0D0A870A
|
||||
off = 12
|
||||
filesize = len(data)
|
||||
|
||||
while off < filesize:
|
||||
box_size, box_type = struct.unpack('>I4s', data[off:off+8])
|
||||
# find JP2 Header box
|
||||
if box_type == b'jp2h':
|
||||
child = off + 8 # skip parent header
|
||||
while child < (off + box_size):
|
||||
# find Image Header box
|
||||
if data[child+4:child+8] == b'ihdr':
|
||||
h, w = struct.unpack('>II', data[child+8:child+16])
|
||||
return w, h
|
||||
|
||||
child += struct.unpack('>I', data[child:child+4])[0]
|
||||
off += box_size
|
||||
return None
|
||||
|
||||
|
||||
def determine_image_size(data: bytes, ext: Optional[str] = None) \
|
||||
-> Optional[Tuple[int, int]]:
|
||||
''' Supports PNG, ARGB, and Jpeg 2000 image data. '''
|
||||
@@ -45,14 +71,7 @@ def determine_image_size(data: bytes, ext: Optional[str] = None) \
|
||||
data = data[4:] # without it32 header
|
||||
return IcnsType.match_maxsize(PackBytes.get_size(data), 'rgb').size
|
||||
elif ext == 'jp2':
|
||||
if data[:4] == b'\xFF\x4F\xFF\x51':
|
||||
w, h = struct.unpack('>II', data[8:16])
|
||||
return w, h
|
||||
len_ftype = struct.unpack('>I', data[12:16])[0]
|
||||
# file header + type box + header box (super box) + image header box
|
||||
offset = 12 + len_ftype + 8 + 8
|
||||
h, w = struct.unpack('>II', data[offset:offset + 8])
|
||||
return w, h
|
||||
return _determine_jp2_size(data)
|
||||
return None # icns does not support other image types except binary
|
||||
|
||||
|
||||
|
||||
BIN
tests/fixtures/32x32.jpf
vendored
Normal file
BIN
tests/fixtures/32x32.jpf
vendored
Normal file
Binary file not shown.
@@ -146,6 +146,7 @@ class TestCLI_compose(unittest.TestCase):
|
||||
def test_jp2(self):
|
||||
self.assert_conv_file('256x256.jp2', 'ic08')
|
||||
self.assert_conv_file('18x18.j2k', 'icsb', arg=['-f'])
|
||||
self.assert_conv_file('32x32.jpf', 'icp5', arg=['-f'])
|
||||
|
||||
def test_argb(self):
|
||||
self.assert_conv_file('rgb.icns.argb', 'ic04')
|
||||
|
||||
@@ -444,6 +444,7 @@ class TestRawData(unittest.TestCase):
|
||||
self.assertEqual(fn('rgb.icns.argb'), (16, 16))
|
||||
self.assertEqual(fn('256x256.jp2'), (256, 256))
|
||||
self.assertEqual(fn('18x18.j2k'), (18, 18))
|
||||
self.assertEqual(fn('32x32.jpf'), (32, 32))
|
||||
|
||||
def test_ext(self):
|
||||
for data, ext in (
|
||||
|
||||
Reference in New Issue
Block a user