Guido van Rossum | 70f1418 | 1993-12-29 16:35:41 +0000 | [diff] [blame] | 1 | # Implement 'jpeg' interface using SGI's compression library |
| 2 | |
| 3 | # XXX Options 'smooth' and 'optimize' are ignored. |
| 4 | |
| 5 | # XXX It appears that compressing grayscale images doesn't work right; |
| 6 | # XXX the resulting file causes weirdness. |
| 7 | |
Fred Drake | def0038 | 2000-08-18 14:59:33 +0000 | [diff] [blame] | 8 | class error(Exception): |
Tim Peters | 182b5ac | 2004-07-18 06:16:08 +0000 | [diff] [blame^] | 9 | pass |
Guido van Rossum | 70f1418 | 1993-12-29 16:35:41 +0000 | [diff] [blame] | 10 | |
| 11 | options = {'quality': 75, 'optimize': 0, 'smooth': 0, 'forcegray': 0} |
| 12 | |
| 13 | comp = None |
| 14 | decomp = None |
| 15 | |
| 16 | def compress(imgdata, width, height, bytesperpixel): |
Tim Peters | 182b5ac | 2004-07-18 06:16:08 +0000 | [diff] [blame^] | 17 | global comp |
| 18 | import cl |
| 19 | if comp is None: comp = cl.OpenCompressor(cl.JPEG) |
| 20 | if bytesperpixel == 1: |
| 21 | format = cl.GRAYSCALE |
| 22 | elif bytesperpixel == 4: |
| 23 | format = cl.RGBX |
| 24 | if options['forcegray']: |
| 25 | iformat = cl.GRAYSCALE |
| 26 | else: |
| 27 | iformat = cl.YUV |
| 28 | # XXX How to support 'optimize'? |
| 29 | params = [cl.IMAGE_WIDTH, width, cl.IMAGE_HEIGHT, height, \ |
| 30 | cl.ORIGINAL_FORMAT, format, \ |
| 31 | cl.ORIENTATION, cl.BOTTOM_UP, \ |
| 32 | cl.QUALITY_FACTOR, options['quality'], \ |
| 33 | cl.INTERNAL_FORMAT, iformat, \ |
| 34 | ] |
| 35 | comp.SetParams(params) |
| 36 | jpegdata = comp.Compress(1, imgdata) |
| 37 | return jpegdata |
Guido van Rossum | 70f1418 | 1993-12-29 16:35:41 +0000 | [diff] [blame] | 38 | |
| 39 | def decompress(jpegdata): |
Tim Peters | 182b5ac | 2004-07-18 06:16:08 +0000 | [diff] [blame^] | 40 | global decomp |
| 41 | import cl |
| 42 | if decomp is None: decomp = cl.OpenDecompressor(cl.JPEG) |
| 43 | headersize = decomp.ReadHeader(jpegdata) |
| 44 | params = [cl.IMAGE_WIDTH, 0, cl.IMAGE_HEIGHT, 0, cl.INTERNAL_FORMAT, 0] |
| 45 | decomp.GetParams(params) |
| 46 | width, height, format = params[1], params[3], params[5] |
| 47 | if format == cl.GRAYSCALE or options['forcegray']: |
| 48 | format = cl.GRAYSCALE |
| 49 | bytesperpixel = 1 |
| 50 | else: |
| 51 | format = cl.RGBX |
| 52 | bytesperpixel = 4 |
| 53 | # XXX How to support 'smooth'? |
| 54 | params = [cl.ORIGINAL_FORMAT, format, \ |
| 55 | cl.ORIENTATION, cl.BOTTOM_UP, \ |
| 56 | cl.FRAME_BUFFER_SIZE, width*height*bytesperpixel] |
| 57 | decomp.SetParams(params) |
| 58 | imgdata = decomp.Decompress(1, jpegdata) |
| 59 | return imgdata, width, height, bytesperpixel |
Guido van Rossum | 70f1418 | 1993-12-29 16:35:41 +0000 | [diff] [blame] | 60 | |
| 61 | def setoption(name, value): |
Tim Peters | 182b5ac | 2004-07-18 06:16:08 +0000 | [diff] [blame^] | 62 | if type(value) is not type(0): |
| 63 | raise TypeError, 'jpeg.setoption: numeric options only' |
| 64 | if name == 'forcegrey': |
| 65 | name = 'forcegray' |
| 66 | if not options.has_key(name): |
| 67 | raise KeyError, 'jpeg.setoption: unknown option name' |
| 68 | options[name] = int(value) |
Guido van Rossum | 70f1418 | 1993-12-29 16:35:41 +0000 | [diff] [blame] | 69 | |
| 70 | def test(): |
Tim Peters | 182b5ac | 2004-07-18 06:16:08 +0000 | [diff] [blame^] | 71 | import sys |
| 72 | if sys.argv[1:2] == ['-g']: |
| 73 | del sys.argv[1] |
| 74 | setoption('forcegray', 1) |
| 75 | if not sys.argv[1:]: |
| 76 | sys.argv.append('/usr/local/images/data/jpg/asterix.jpg') |
| 77 | for file in sys.argv[1:]: |
| 78 | show(file) |
Guido van Rossum | 70f1418 | 1993-12-29 16:35:41 +0000 | [diff] [blame] | 79 | |
| 80 | def show(file): |
Tim Peters | 182b5ac | 2004-07-18 06:16:08 +0000 | [diff] [blame^] | 81 | import gl, GL, DEVICE |
| 82 | jpegdata = open(file, 'r').read() |
| 83 | imgdata, width, height, bytesperpixel = decompress(jpegdata) |
| 84 | gl.foreground() |
| 85 | gl.prefsize(width, height) |
| 86 | win = gl.winopen(file) |
| 87 | if bytesperpixel == 1: |
| 88 | gl.cmode() |
| 89 | gl.pixmode(GL.PM_SIZE, 8) |
| 90 | gl.gconfig() |
| 91 | for i in range(256): |
| 92 | gl.mapcolor(i, i, i, i) |
| 93 | else: |
| 94 | gl.RGBmode() |
| 95 | gl.pixmode(GL.PM_SIZE, 32) |
| 96 | gl.gconfig() |
| 97 | gl.qdevice(DEVICE.REDRAW) |
| 98 | gl.qdevice(DEVICE.ESCKEY) |
| 99 | gl.qdevice(DEVICE.WINQUIT) |
| 100 | gl.qdevice(DEVICE.WINSHUT) |
| 101 | gl.lrectwrite(0, 0, width-1, height-1, imgdata) |
| 102 | while 1: |
| 103 | dev, val = gl.qread() |
| 104 | if dev in (DEVICE.ESCKEY, DEVICE.WINSHUT, DEVICE.WINQUIT): |
| 105 | break |
| 106 | if dev == DEVICE.REDRAW: |
| 107 | gl.lrectwrite(0, 0, width-1, height-1, imgdata) |
| 108 | gl.winclose(win) |
| 109 | # Now test the compression and write the result to a fixed filename |
| 110 | newjpegdata = compress(imgdata, width, height, bytesperpixel) |
| 111 | open('/tmp/j.jpg', 'w').write(newjpegdata) |