Fixed icns decoding with jpeg2k.

This commit is contained in:
Joey Payne 2016-02-09 08:12:59 -07:00
commit e02e236ebc

View file

@ -1097,6 +1097,10 @@ class ICNSElement(Structure):
width, height, png_data, stats_dict = png_file.read_flat() width, height, png_data, stats_dict = png_file.read_flat()
im = Image.frombytes('RGBA', [width, height], bytes(png_data))
output = BytesIO()
im.save(output, format='PNG')
bpp = stats_dict['bitdepth'] * 4 bpp = stats_dict['bitdepth'] * 4
icns_info = ICNSInfo() icns_info = ICNSInfo()
@ -1107,14 +1111,14 @@ class ICNSElement(Structure):
icns_info.iconChannels = 4 if bpp == 32 else 1 icns_info.iconChannels = 4 if bpp == 32 else 1
icns_info.iconPixelDepth = int(bpp / icns_info.iconChannels) icns_info.iconPixelDepth = int(bpp / icns_info.iconChannels)
icns_info.iconRawDataSize = int(width * height * 4) icns_info.iconRawDataSize = int(width * height * 4)
icns_info.data = bytes(png_data) icns_info.data = bytes(output.getvalue())
else: else:
image = Image.open(BytesIO(data)) image = Image.open(BytesIO(data))
mode_to_bpp = {'1':1, 'L':8, 'P':8, 'RGB':24, 'RGBA':32, 'CMYK':32, 'YCbCr':24, 'I':32, 'F':32} mode_to_bpp = {'1':1, 'L':8, 'P':8, 'RGB':24, 'RGBA':32, 'CMYK':32, 'YCbCr':24, 'I':32, 'F':32}
output = BytesIO() output = BytesIO()
image.save(output, format='PNG') image.save(output, format='PNG')
bpp = mode_to_bpp[image.mode] bpp = mode_to_bpp[image.mode]
png_data = bytearray(output.getvalue()) png_data = bytes(output.getvalue())
icns_info = ICNSInfo() icns_info = ICNSInfo()
icns_info.isImage = 1 icns_info.isImage = 1
@ -1124,7 +1128,7 @@ class ICNSElement(Structure):
icns_info.iconChannels = 4 if bpp == 32 else 1 icns_info.iconChannels = 4 if bpp == 32 else 1
icns_info.iconPixelDepth = int(bpp / icns_info.iconChannels) icns_info.iconPixelDepth = int(bpp / icns_info.iconChannels)
icns_info.iconRawDataSize = int(image.size[0] * image.size[1] * 4) icns_info.iconRawDataSize = int(image.size[0] * image.size[1] * 4)
icns_info.data = bytes(png_data) icns_info.data = png_data
else: else:
icns_info = ICNSInfo.from_type(icon_type) icns_info = ICNSInfo.from_type(icon_type)
@ -1264,9 +1268,10 @@ def icns_parse_family_data(icns_data):
def get_image_with_mask(icns_data, element_type): def get_image_with_mask(icns_data, element_type):
element = ICNSElement.from_family(icns_data, element_type) element = ICNSElement.from_family(icns_data, element_type)
icns_image = element.get_image() icns_image = element.get_image()
if element_type not in [ICNS_256x256_32BIT_ARGB_DATA, if element_type in [ICNS_256x256_32BIT_ARGB_DATA,
ICNS_512x512_32BIT_ARGB_DATA, ICNS_512x512_32BIT_ARGB_DATA,
ICNS_1024x1024_32BIT_ARGB_DATA]: ICNS_1024x1024_32BIT_ARGB_DATA]:
return icns_image
mask_type = get_mask_type_for_icon_type(element_type) mask_type = get_mask_type_for_icon_type(element_type)
mask_element = ICNSElement.from_family(icns_data, mask_type) mask_element = ICNSElement.from_family(icns_data, mask_type)
mask_image = mask_element.get_mask() mask_image = mask_element.get_mask()
@ -1355,8 +1360,8 @@ def get_image_with_mask(icns_data, element_type):
color_index = 0xFF if (data_value & 0x80) else 0x00 color_index = 0xFF if (data_value & 0x80) else 0x00
data_value = data_value << 1 data_value = data_value << 1
icns_image.data[pixel_id*4+3] = color_index icns_image.data[pixel_id*4+3] = color_index
im = Image.frombytes('RGBA', [icns_image.iconSize.width,icns_image.iconSize.height], bytes(icns_image.data)) im = Image.frombytes('RGBA', [icns_image.iconSize.width,icns_image.iconSize.height], bytes(icns_image.data))
#print(icns_image.data)
output = BytesIO() output = BytesIO()
im.save(output, format='PNG') im.save(output, format='PNG')
icns_image.data = bytes(output.getvalue()) icns_image.data = bytes(output.getvalue())