112 lines
3.5 KiB
Python
112 lines
3.5 KiB
Python
|
# Implement 'jpeg' interface using SGI's compression library
|
||
|
|
||
|
# XXX Options 'smooth' and 'optimize' are ignored.
|
||
|
|
||
|
# XXX It appears that compressing grayscale images doesn't work right;
|
||
|
# XXX the resulting file causes weirdness.
|
||
|
|
||
|
class error(Exception):
|
||
|
pass
|
||
|
|
||
|
options = {'quality': 75, 'optimize': 0, 'smooth': 0, 'forcegray': 0}
|
||
|
|
||
|
comp = None
|
||
|
decomp = None
|
||
|
|
||
|
def compress(imgdata, width, height, bytesperpixel):
|
||
|
global comp
|
||
|
import cl
|
||
|
if comp is None: comp = cl.OpenCompressor(cl.JPEG)
|
||
|
if bytesperpixel == 1:
|
||
|
format = cl.GRAYSCALE
|
||
|
elif bytesperpixel == 4:
|
||
|
format = cl.RGBX
|
||
|
if options['forcegray']:
|
||
|
iformat = cl.GRAYSCALE
|
||
|
else:
|
||
|
iformat = cl.YUV
|
||
|
# XXX How to support 'optimize'?
|
||
|
params = [cl.IMAGE_WIDTH, width, cl.IMAGE_HEIGHT, height,
|
||
|
cl.ORIGINAL_FORMAT, format,
|
||
|
cl.ORIENTATION, cl.BOTTOM_UP,
|
||
|
cl.QUALITY_FACTOR, options['quality'],
|
||
|
cl.INTERNAL_FORMAT, iformat,
|
||
|
]
|
||
|
comp.SetParams(params)
|
||
|
jpegdata = comp.Compress(1, imgdata)
|
||
|
return jpegdata
|
||
|
|
||
|
def decompress(jpegdata):
|
||
|
global decomp
|
||
|
import cl
|
||
|
if decomp is None: decomp = cl.OpenDecompressor(cl.JPEG)
|
||
|
headersize = decomp.ReadHeader(jpegdata)
|
||
|
params = [cl.IMAGE_WIDTH, 0, cl.IMAGE_HEIGHT, 0, cl.INTERNAL_FORMAT, 0]
|
||
|
decomp.GetParams(params)
|
||
|
width, height, format = params[1], params[3], params[5]
|
||
|
if format == cl.GRAYSCALE or options['forcegray']:
|
||
|
format = cl.GRAYSCALE
|
||
|
bytesperpixel = 1
|
||
|
else:
|
||
|
format = cl.RGBX
|
||
|
bytesperpixel = 4
|
||
|
# XXX How to support 'smooth'?
|
||
|
params = [cl.ORIGINAL_FORMAT, format,
|
||
|
cl.ORIENTATION, cl.BOTTOM_UP,
|
||
|
cl.FRAME_BUFFER_SIZE, width*height*bytesperpixel]
|
||
|
decomp.SetParams(params)
|
||
|
imgdata = decomp.Decompress(1, jpegdata)
|
||
|
return imgdata, width, height, bytesperpixel
|
||
|
|
||
|
def setoption(name, value):
|
||
|
if type(value) is not type(0):
|
||
|
raise TypeError, 'jpeg.setoption: numeric options only'
|
||
|
if name == 'forcegrey':
|
||
|
name = 'forcegray'
|
||
|
if not options.has_key(name):
|
||
|
raise KeyError, 'jpeg.setoption: unknown option name'
|
||
|
options[name] = int(value)
|
||
|
|
||
|
def test():
|
||
|
import sys
|
||
|
if sys.argv[1:2] == ['-g']:
|
||
|
del sys.argv[1]
|
||
|
setoption('forcegray', 1)
|
||
|
if not sys.argv[1:]:
|
||
|
sys.argv.append('/usr/local/images/data/jpg/asterix.jpg')
|
||
|
for file in sys.argv[1:]:
|
||
|
show(file)
|
||
|
|
||
|
def show(file):
|
||
|
import gl, GL, DEVICE
|
||
|
jpegdata = open(file, 'r').read()
|
||
|
imgdata, width, height, bytesperpixel = decompress(jpegdata)
|
||
|
gl.foreground()
|
||
|
gl.prefsize(width, height)
|
||
|
win = gl.winopen(file)
|
||
|
if bytesperpixel == 1:
|
||
|
gl.cmode()
|
||
|
gl.pixmode(GL.PM_SIZE, 8)
|
||
|
gl.gconfig()
|
||
|
for i in range(256):
|
||
|
gl.mapcolor(i, i, i, i)
|
||
|
else:
|
||
|
gl.RGBmode()
|
||
|
gl.pixmode(GL.PM_SIZE, 32)
|
||
|
gl.gconfig()
|
||
|
gl.qdevice(DEVICE.REDRAW)
|
||
|
gl.qdevice(DEVICE.ESCKEY)
|
||
|
gl.qdevice(DEVICE.WINQUIT)
|
||
|
gl.qdevice(DEVICE.WINSHUT)
|
||
|
gl.lrectwrite(0, 0, width-1, height-1, imgdata)
|
||
|
while 1:
|
||
|
dev, val = gl.qread()
|
||
|
if dev in (DEVICE.ESCKEY, DEVICE.WINSHUT, DEVICE.WINQUIT):
|
||
|
break
|
||
|
if dev == DEVICE.REDRAW:
|
||
|
gl.lrectwrite(0, 0, width-1, height-1, imgdata)
|
||
|
gl.winclose(win)
|
||
|
# Now test the compression and write the result to a fixed filename
|
||
|
newjpegdata = compress(imgdata, width, height, bytesperpixel)
|
||
|
open('/tmp/j.jpg', 'w').write(newjpegdata)
|