Skip to content

Instantly share code, notes, and snippets.

@garcia
Created September 17, 2012 06:47
Show Gist options
  • Save garcia/3735889 to your computer and use it in GitHub Desktop.
Save garcia/3735889 to your computer and use it in GitHub Desktop.
Losslessly rotate a GIF's hue 180 degrees
#!/usr/bin/env python
import colorsys
import struct
import sys
f_in = open(sys.argv[1], 'rb')
f_out = open(sys.argv[2], 'wb')
# check header
if f_in.read(3) != 'GIF':
raise TypeError('not a GIF')
f_out.write('GIF')
# check version
version = f_in.read(3)
if version not in ('87a', '89a'):
raise TypeError('invalid GIF version')
f_out.write(version)
# discard screen width and height
f_out.write(f_in.read(4))
# get byte 10
b10 = f_in.read(1)
f_out.write(b10)
b10 = ord(b10)
# global color table bit
has_gct = b10 >> 7
if not has_gct:
raise TypeError('no global color table')
# global color table size
gctsize = b10 % 8
gctlen = 2 ** (gctsize + 1)
# discard background color index and pixel aspect ratio
f_out.write(f_in.read(2))
# get global color table
gct = f_in.read(gctlen * 3)
for i in xrange(gctlen):
# parse color to RGB
color = [ord(byte) / 256. for byte in gct[i * 3:(i + 1) * 3]]
# convert to HSV
color_hsv = list(colorsys.rgb_to_hsv(*color))
# rotate hue 180 degrees
color_hsv[0] = (color_hsv[0] + .5) % 1
# convert back to RGB
color = colorsys.hsv_to_rgb(*color_hsv)
f_out.write(''.join([chr(int(c * 256)) for c in color]))
# output remainder of file
f_out.write(f_in.read())
# close files
f_out.close()
f_in.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment