Skip to content

Commit 254a39e

Browse files
committed
Fixed icns decoding with jpeg2k.
1 parent 09013d6 commit 254a39e

File tree

1 file changed

+89
-84
lines changed

1 file changed

+89
-84
lines changed

icns_info.py

Lines changed: 89 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,10 @@ def get_image(self):
10971097

10981098
width, height, png_data, stats_dict = png_file.read_flat()
10991099

1100+
im = Image.frombytes('RGBA', [width, height], bytes(png_data))
1101+
output = BytesIO()
1102+
im.save(output, format='PNG')
1103+
11001104
bpp = stats_dict['bitdepth'] * 4
11011105

11021106
icns_info = ICNSInfo()
@@ -1107,14 +1111,14 @@ def get_image(self):
11071111
icns_info.iconChannels = 4 if bpp == 32 else 1
11081112
icns_info.iconPixelDepth = int(bpp / icns_info.iconChannels)
11091113
icns_info.iconRawDataSize = int(width * height * 4)
1110-
icns_info.data = bytes(png_data)
1114+
icns_info.data = bytes(output.getvalue())
11111115
else:
11121116
image = Image.open(BytesIO(data))
11131117
mode_to_bpp = {'1':1, 'L':8, 'P':8, 'RGB':24, 'RGBA':32, 'CMYK':32, 'YCbCr':24, 'I':32, 'F':32}
11141118
output = BytesIO()
11151119
image.save(output, format='PNG')
11161120
bpp = mode_to_bpp[image.mode]
1117-
png_data = bytearray(output.getvalue())
1121+
png_data = bytes(output.getvalue())
11181122

11191123
icns_info = ICNSInfo()
11201124
icns_info.isImage = 1
@@ -1124,7 +1128,7 @@ def get_image(self):
11241128
icns_info.iconChannels = 4 if bpp == 32 else 1
11251129
icns_info.iconPixelDepth = int(bpp / icns_info.iconChannels)
11261130
icns_info.iconRawDataSize = int(image.size[0] * image.size[1] * 4)
1127-
icns_info.data = bytes(png_data)
1131+
icns_info.data = png_data
11281132

11291133
else:
11301134
icns_info = ICNSInfo.from_type(icon_type)
@@ -1264,99 +1268,100 @@ def icns_parse_family_data(icns_data):
12641268
def get_image_with_mask(icns_data, element_type):
12651269
element = ICNSElement.from_family(icns_data, element_type)
12661270
icns_image = element.get_image()
1267-
if element_type not in [ICNS_256x256_32BIT_ARGB_DATA,
1268-
ICNS_512x512_32BIT_ARGB_DATA,
1269-
ICNS_1024x1024_32BIT_ARGB_DATA]:
1270-
mask_type = get_mask_type_for_icon_type(element_type)
1271-
mask_element = ICNSElement.from_family(icns_data, mask_type)
1272-
mask_image = mask_element.get_mask()
1273-
1271+
if element_type in [ICNS_256x256_32BIT_ARGB_DATA,
1272+
ICNS_512x512_32BIT_ARGB_DATA,
1273+
ICNS_1024x1024_32BIT_ARGB_DATA]:
1274+
return icns_image
1275+
mask_type = get_mask_type_for_icon_type(element_type)
1276+
mask_element = ICNSElement.from_family(icns_data, mask_type)
1277+
mask_image = mask_element.get_mask()
1278+
1279+
old_bit_depth = icns_image.iconPixelDepth * icns_image.iconChannels
1280+
if old_bit_depth < 32:
12741281
old_bit_depth = icns_image.iconPixelDepth * icns_image.iconChannels
1275-
if old_bit_depth < 32:
1276-
old_bit_depth = icns_image.iconPixelDepth * icns_image.iconChannels
1277-
pixel_count = icns_image.iconSize.width * icns_image.iconSize.height
1278-
new_block_size = icns_image.iconSize.width * 32
1279-
new_data_size = new_block_size * icns_image.iconSize.height
1282+
pixel_count = icns_image.iconSize.width * icns_image.iconSize.height
1283+
new_block_size = icns_image.iconSize.width * 32
1284+
new_data_size = new_block_size * icns_image.iconSize.height
12801285

1281-
old_data = icns_image.data
1282-
new_data = bytearray(int(new_data_size))
1286+
old_data = icns_image.data
1287+
new_data = bytearray(int(new_data_size))
12831288

1284-
data_count = 0
1285-
1286-
if element_type in [ICNS_48x48_8BIT_DATA,
1287-
ICNS_32x32_8BIT_DATA,
1288-
ICNS_16x16_8BIT_DATA,
1289-
ICNS_16x12_8BIT_DATA]:
1290-
for pixel_id in range(pixel_count):
1291-
color_index = old_data[data_count]
1292-
color_rgb = icns_colormap_8[color_index]
1293-
new_data[pixel_id*4+0] = color_rgb[0]
1294-
new_data[pixel_id*4+1] = color_rgb[1]
1295-
new_data[pixel_id*4+2] = color_rgb[2]
1296-
new_data[pixel_id*4+3] = 0xFF
1297-
data_count += 1
1298-
elif element_type in [ICNS_48x48_4BIT_DATA,
1299-
ICNS_32x32_4BIT_DATA,
1300-
ICNS_16x16_4BIT_DATA,
1301-
ICNS_16x12_4BIT_DATA]:
1302-
data_value = 0
1303-
for pixel_id in range(pixel_count):
1304-
if (pixel_id % 2) == 0:
1305-
data_value = old_data[data_count]
1306-
data_count += 1
1307-
color_index = (data_value & 0xF0) >> 4
1308-
color_rgb = icns_colormap_4[color_index]
1309-
new_data[pixel_id*4+0] = color_rgb[0]
1310-
new_data[pixel_id*4+1] = color_rgb[1]
1311-
new_data[pixel_id*4+2] = color_rgb[2]
1312-
new_data[pixel_id*4+3] = 0xFF
1313-
elif element_type in [ICNS_48x48_1BIT_DATA,
1314-
ICNS_32x32_1BIT_DATA,
1315-
ICNS_16x16_1BIT_DATA,
1316-
ICNS_16x12_1BIT_DATA]:
1317-
data_value = 0
1318-
for pixel_id in range(pixel_count):
1319-
if (pixel_id % 8) == 0:
1320-
data_value = old_data[data_count]
1321-
data_count += 1
1322-
color_index = 0x00 if (data_value & 0x80) else 0xFF
1323-
data_value = data_value << 1
1324-
new_data[pixel_id*4+0] = color_index
1325-
new_data[pixel_id*4+1] = color_index
1326-
new_data[pixel_id*4+2] = color_index
1327-
new_data[pixel_id*4+3] = 0xFF
1328-
1329-
icns_image.iconPixelDepth = 8
1330-
icns_image.iconChannels = 4
1331-
icns_image.iconRawDataSize = int(new_data_size)
1332-
icns_image.data = new_data
1289+
data_count = 0
13331290

1334-
if mask_type in [ICNS_128x128_8BIT_MASK,
1335-
ICNS_48x48_8BIT_MASK,
1336-
ICNS_32x32_8BIT_MASK,
1337-
ICNS_16x16_8BIT_MASK]:
1338-
pixel_count = mask_image.iconSize.width * mask_image.iconSize.height
1339-
data_count = 0
1291+
if element_type in [ICNS_48x48_8BIT_DATA,
1292+
ICNS_32x32_8BIT_DATA,
1293+
ICNS_16x16_8BIT_DATA,
1294+
ICNS_16x12_8BIT_DATA]:
13401295
for pixel_id in range(pixel_count):
1341-
icns_image.data[pixel_id*4+3] = mask_image.data[data_count]
1296+
color_index = old_data[data_count]
1297+
color_rgb = icns_colormap_8[color_index]
1298+
new_data[pixel_id*4+0] = color_rgb[0]
1299+
new_data[pixel_id*4+1] = color_rgb[1]
1300+
new_data[pixel_id*4+2] = color_rgb[2]
1301+
new_data[pixel_id*4+3] = 0xFF
13421302
data_count += 1
1343-
1344-
elif mask_type in [ICNS_48x48_1BIT_MASK,
1345-
ICNS_32x32_1BIT_MASK,
1346-
ICNS_16x16_1BIT_MASK,
1347-
ICNS_16x12_1BIT_MASK]:
1348-
pixel_count = mask_image.iconSize.width * mask_image.iconSize.height
1349-
data_count = 0
1303+
elif element_type in [ICNS_48x48_4BIT_DATA,
1304+
ICNS_32x32_4BIT_DATA,
1305+
ICNS_16x16_4BIT_DATA,
1306+
ICNS_16x12_4BIT_DATA]:
1307+
data_value = 0
1308+
for pixel_id in range(pixel_count):
1309+
if (pixel_id % 2) == 0:
1310+
data_value = old_data[data_count]
1311+
data_count += 1
1312+
color_index = (data_value & 0xF0) >> 4
1313+
color_rgb = icns_colormap_4[color_index]
1314+
new_data[pixel_id*4+0] = color_rgb[0]
1315+
new_data[pixel_id*4+1] = color_rgb[1]
1316+
new_data[pixel_id*4+2] = color_rgb[2]
1317+
new_data[pixel_id*4+3] = 0xFF
1318+
elif element_type in [ICNS_48x48_1BIT_DATA,
1319+
ICNS_32x32_1BIT_DATA,
1320+
ICNS_16x16_1BIT_DATA,
1321+
ICNS_16x12_1BIT_DATA]:
13501322
data_value = 0
13511323
for pixel_id in range(pixel_count):
13521324
if (pixel_id % 8) == 0:
1353-
data_value = mask_image.data[data_count]
1325+
data_value = old_data[data_count]
13541326
data_count += 1
1355-
color_index = 0xFF if (data_value & 0x80) else 0x00
1327+
color_index = 0x00 if (data_value & 0x80) else 0xFF
13561328
data_value = data_value << 1
1357-
icns_image.data[pixel_id*4+3] = color_index
1358-
1329+
new_data[pixel_id*4+0] = color_index
1330+
new_data[pixel_id*4+1] = color_index
1331+
new_data[pixel_id*4+2] = color_index
1332+
new_data[pixel_id*4+3] = 0xFF
1333+
1334+
icns_image.iconPixelDepth = 8
1335+
icns_image.iconChannels = 4
1336+
icns_image.iconRawDataSize = int(new_data_size)
1337+
icns_image.data = new_data
1338+
1339+
if mask_type in [ICNS_128x128_8BIT_MASK,
1340+
ICNS_48x48_8BIT_MASK,
1341+
ICNS_32x32_8BIT_MASK,
1342+
ICNS_16x16_8BIT_MASK]:
1343+
pixel_count = mask_image.iconSize.width * mask_image.iconSize.height
1344+
data_count = 0
1345+
for pixel_id in range(pixel_count):
1346+
icns_image.data[pixel_id*4+3] = mask_image.data[data_count]
1347+
data_count += 1
1348+
1349+
elif mask_type in [ICNS_48x48_1BIT_MASK,
1350+
ICNS_32x32_1BIT_MASK,
1351+
ICNS_16x16_1BIT_MASK,
1352+
ICNS_16x12_1BIT_MASK]:
1353+
pixel_count = mask_image.iconSize.width * mask_image.iconSize.height
1354+
data_count = 0
1355+
data_value = 0
1356+
for pixel_id in range(pixel_count):
1357+
if (pixel_id % 8) == 0:
1358+
data_value = mask_image.data[data_count]
1359+
data_count += 1
1360+
color_index = 0xFF if (data_value & 0x80) else 0x00
1361+
data_value = data_value << 1
1362+
icns_image.data[pixel_id*4+3] = color_index
13591363
im = Image.frombytes('RGBA', [icns_image.iconSize.width,icns_image.iconSize.height], bytes(icns_image.data))
1364+
#print(icns_image.data)
13601365
output = BytesIO()
13611366
im.save(output, format='PNG')
13621367
icns_image.data = bytes(output.getvalue())

0 commit comments

Comments
 (0)