Unified different GIF optimize conditions

This commit is contained in:
Andrew Murray 2016-11-05 13:32:02 +11:00
parent 5aeb0ed972
commit a51dc7dcaf

View File

@ -434,11 +434,9 @@ def _get_local_header(fp, im, offset, flags):
# optimize the block away if transparent color is not used
transparent_color_exists = True
if _get_optimize(im, im.encoderinfo):
used_palette_colors = _get_used_palette_colors(im)
used_palette_colors = _get_optimize(im, im.encoderinfo)
if used_palette_colors is not None:
# adjust the transparency index after optimize
if len(used_palette_colors) < 256:
for i in range(len(used_palette_colors)):
if used_palette_colors[i] == transparency:
transparency = i
@ -552,9 +550,28 @@ def _save_netpbm(im, fp, filename):
# --------------------------------------------------------------------
# GIF utilities
def _get_optimize(im, info):
return im.mode in ("P", "L") and info and info.get("optimize", 0)
# Force optimization so that we can test performance against
# cases where it took lots of memory and time previously.
_FORCE_OPTIMIZE = False
def _get_optimize(im, info):
if im.mode in ("P", "L") and info and info.get("optimize", 0):
# Potentially expensive operation.
# The palette saves 3 bytes per color not used, but palette
# lengths are restricted to 3*(2**N) bytes. Max saving would
# be 768 -> 6 bytes if we went all the way down to 2 colors.
# * If we're over 128 colors, we can't save any space.
# * If there aren't any holes, it's not worth collapsing.
# * If we have a 'large' image, the palette is in the noise.
# create the new palette if not every color is used
used_palette_colors = _get_used_palette_colors(im)
if _FORCE_OPTIMIZE or im.mode == 'L' or \
(len(used_palette_colors) <= 128 and
max(used_palette_colors) > len(used_palette_colors) and
im.width * im.height < 512 * 512):
return used_palette_colors
def _get_used_palette_colors(im):
used_palette_colors = []
@ -586,10 +603,6 @@ def _get_header_palette(palette_bytes):
palette_bytes += o8(0) * 3 * actual_target_size_diff
return palette_bytes
# Force optimization so that we can test performance against
# cases where it took lots of memory and time previously.
_FORCE_OPTIMIZE = False
def _get_palette_bytes(im, palette, info):
if im.mode == "P":
if palette and isinstance(palette, bytes):
@ -602,25 +615,10 @@ def _get_palette_bytes(im, palette, info):
else:
source_palette = bytearray([i//3 for i in range(768)])
used_palette_colors = palette_bytes = None
palette_bytes = None
if _get_optimize(im, info):
used_palette_colors = _get_used_palette_colors(im)
# Potentially expensive operation.
# The palette saves 3 bytes per color not used, but palette
# lengths are restricted to 3*(2**N) bytes. Max saving would
# be 768 -> 6 bytes if we went all the way down to 2 colors.
# * If we're over 128 colors, we can't save any space.
# * If there aren't any holes, it's not worth collapsing.
# * If we have a 'large' image, the palette is in the noise.
# create the new palette if not every color is used
if _FORCE_OPTIMIZE or im.mode == 'L' or \
(len(used_palette_colors) <= 128 and
max(used_palette_colors) > len(used_palette_colors) and
im.width * im.height < 512 * 512):
used_palette_colors = _get_optimize(im, info)
if used_palette_colors is not None:
palette_bytes = b""
new_positions = [0]*256