# 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.

error = 'jpeg.error' # Exception

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) <> 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)
