@@ -25,7 +25,9 @@ def divroundup(val, div):
2525g .add_argument ("-e" , "--encode" , action = 'store_true' )
2626g .add_argument ("-d" , "--decode" , action = 'store_true' )
2727ap .add_argument ("--raw-output" , type = str , required = False )
28- ap .add_argument ("--decode-scale" , type = int , required = False )
28+ ap .add_argument ("--decode-scale" , type = int , required = False , default = 1 )
29+ ap .add_argument ("--decode-pixelfmt" , type = str , required = False , default = 'RGBA' )
30+ ap .add_argument ("--decode-rgba-alpha" , type = int , required = False , default = 255 )
2931ap .add_argument ("input" , type = str )
3032ap .add_argument ("output" , type = str )
3133args = ap .parse_args ()
@@ -34,12 +36,16 @@ def divroundup(val, div):
3436
3537# Perform necessary pre-parsing
3638if args .decode :
37- if args .decode_scale is not None :
38- assert args .decode_scale in [1 , 2 , 4 , 8 ]
39- decode_scale = args .decode_scale
40- else :
41- decode_scale = 1
42- # TODO: finish implementing this
39+ assert args .decode_scale in [1 , 2 , 4 , 8 ]
40+ decode_scale = args .decode_scale
41+ # FIXME: verify behavior on non-evenly-divisible sizes
42+
43+ assert args .decode_pixelfmt in [
44+ 'RGBA' ,
45+ 'BGRA' ,
46+ 'RGB565' ,
47+ ]
48+ pixfmt = args .decode_pixelfmt
4349
4450 with open (args .input , 'rb' ) as f :
4551 jpeg_data = f .read ()
@@ -114,9 +120,14 @@ def divroundup(val, div):
114120 assert False
115121
116122 # FIXME: Exactly how much extra memory do we need to allocate?
117- surface_W = divroundup (jpeg_W , macroblock_W ) * macroblock_W
118- surface_H = divroundup (jpeg_H , macroblock_H ) * macroblock_H
119- BYTESPP = 4
123+ surface_W = divroundup (jpeg_W // decode_scale , macroblock_W ) * macroblock_W
124+ surface_H = divroundup (jpeg_H // decode_scale , macroblock_H ) * macroblock_H
125+ if pixfmt in ['RGBA' , 'BGRA' ]:
126+ BYTESPP = 4
127+ elif pixfmt == 'RGB565' :
128+ BYTESPP = 2
129+ else :
130+ assert False
120131 surface_stride = surface_W * BYTESPP
121132
122133 input_mem_sz = align_up (len (jpeg_data ))
@@ -311,11 +322,14 @@ def set_default_regs(param1=0):
311322 jpeg .CODEC .set (CODEC = E_CODEC ._411 )
312323 else :
313324 assert False
314- jpeg .DECODE_PIXEL_FORMAT .set (FORMAT = E_DECODE_PIXEL_FORMAT .RGBA8888 )
325+ if pixfmt == 'RGBA' or pixfmt == 'BGRA' :
326+ jpeg .DECODE_PIXEL_FORMAT .set (FORMAT = E_DECODE_PIXEL_FORMAT .RGBA8888 )
327+ elif pixfmt == 'RGB565' :
328+ jpeg .DECODE_PIXEL_FORMAT .set (FORMAT = E_DECODE_PIXEL_FORMAT .RGB565 )
315329
316330 jpeg .PX_USE_PLANE1 = 0
317- jpeg .PX_PLANE0_WIDTH = jpeg_W * BYTESPP - 1
318- jpeg .PX_PLANE0_HEIGHT = jpeg_H - 1
331+ jpeg .PX_PLANE0_WIDTH = jpeg_W * BYTESPP // decode_scale - 1
332+ jpeg .PX_PLANE0_HEIGHT = jpeg_H // decode_scale - 1
319333 # TODO P1
320334 jpeg .TIMEOUT = 266000000
321335
@@ -324,38 +338,64 @@ def set_default_regs(param1=0):
324338
325339 jpeg .DECODE_MACROBLOCKS_W = divroundup (jpeg_W , macroblock_W )
326340 jpeg .DECODE_MACROBLOCKS_H = divroundup (jpeg_H , macroblock_H )
327- # right_edge_px = jpeg_W - divroundup(jpeg_W, 8)*8 + 8
328- # bot_edge_px = jpeg_H - divroundup(jpeg_H, 8)*8 + 8
329- # # XXX changing this does not seem to do anything
330- # jpeg.RIGHT_EDGE_PIXELS.val = right_edge_px
331- # jpeg.BOTTOM_EDGE_PIXELS.val = bot_edge_px
332- # jpeg.RIGHT_EDGE_SAMPLES.val = right_edge_px // 2
333- # jpeg.BOTTOM_EDGE_SAMPLES.val = bot_edge_px // 2
341+ right_edge_px = \
342+ jpeg_W - divroundup (jpeg_W , macroblock_W )* macroblock_W + macroblock_W
343+ bot_edge_px = \
344+ jpeg_H - divroundup (jpeg_H , macroblock_H )* macroblock_H + macroblock_H
345+ # XXX changing this does not seem to do anything
346+ jpeg .RIGHT_EDGE_PIXELS .val = right_edge_px
347+ jpeg .BOTTOM_EDGE_PIXELS .val = bot_edge_px
348+ jpeg .RIGHT_EDGE_SAMPLES .val = right_edge_px // (macroblock_W // 8 )
349+ jpeg .BOTTOM_EDGE_SAMPLES .val = bot_edge_px // (macroblock_H // 8 )
334350
335351 jpeg .PX_TILES_H = divroundup (jpeg_H , macroblock_H )
336- jpeg .PX_TILES_W = divroundup (jpeg_W , macroblock_W )
337- if jpeg_MODE == '444' or jpeg_MODE == '400' :
338- jpeg .PX_PLANE0_TILING_H = 4
339- jpeg .PX_PLANE0_TILING_V = 8
340- jpeg .PX_PLANE1_TILING_H = 1
341- jpeg .PX_PLANE1_TILING_V = 1
342- elif jpeg_MODE == '422' :
343- jpeg .PX_PLANE0_TILING_H = 8
344- jpeg .PX_PLANE0_TILING_V = 8
345- jpeg .PX_PLANE1_TILING_H = 1
346- jpeg .PX_PLANE1_TILING_V = 1
347- elif jpeg_MODE == '420' :
348- jpeg .PX_PLANE0_TILING_H = 8
349- jpeg .PX_PLANE0_TILING_V = 16
350- jpeg .PX_PLANE1_TILING_H = 0
351- jpeg .PX_PLANE1_TILING_V = 0
352- elif jpeg_MODE == '411' :
353- jpeg .PX_PLANE0_TILING_H = 16
354- jpeg .PX_PLANE0_TILING_V = 8
355- jpeg .PX_PLANE1_TILING_H = 0
356- jpeg .PX_PLANE1_TILING_V = 0
357- else :
358- assert False
352+ jpeg .PX_TILES_W = divroundup (jpeg_W // decode_scale , macroblock_W )
353+ if pixfmt == 'RGBA' or pixfmt == 'BGRA' :
354+ if jpeg_MODE == '444' or jpeg_MODE == '400' :
355+ jpeg .PX_PLANE0_TILING_H = 4
356+ jpeg .PX_PLANE0_TILING_V = 8 // decode_scale
357+ jpeg .PX_PLANE1_TILING_H = 1
358+ jpeg .PX_PLANE1_TILING_V = 1
359+ elif jpeg_MODE == '422' :
360+ jpeg .PX_PLANE0_TILING_H = 8
361+ jpeg .PX_PLANE0_TILING_V = 8 // decode_scale
362+ jpeg .PX_PLANE1_TILING_H = 1
363+ jpeg .PX_PLANE1_TILING_V = 1
364+ elif jpeg_MODE == '420' :
365+ jpeg .PX_PLANE0_TILING_H = 8
366+ jpeg .PX_PLANE0_TILING_V = 16 // decode_scale
367+ jpeg .PX_PLANE1_TILING_H = 0
368+ jpeg .PX_PLANE1_TILING_V = 0
369+ elif jpeg_MODE == '411' :
370+ jpeg .PX_PLANE0_TILING_H = 16
371+ jpeg .PX_PLANE0_TILING_V = 8 // decode_scale
372+ jpeg .PX_PLANE1_TILING_H = 0
373+ jpeg .PX_PLANE1_TILING_V = 0
374+ else :
375+ assert False
376+ elif pixfmt == 'RGB565' :
377+ if jpeg_MODE == '444' or jpeg_MODE == '400' :
378+ jpeg .PX_PLANE0_TILING_H = 2
379+ jpeg .PX_PLANE0_TILING_V = 8 // decode_scale
380+ jpeg .PX_PLANE1_TILING_H = 1
381+ jpeg .PX_PLANE1_TILING_V = 1
382+ elif jpeg_MODE == '422' :
383+ jpeg .PX_PLANE0_TILING_H = 4
384+ jpeg .PX_PLANE0_TILING_V = 8 // decode_scale
385+ jpeg .PX_PLANE1_TILING_H = 1
386+ jpeg .PX_PLANE1_TILING_V = 1
387+ elif jpeg_MODE == '420' :
388+ jpeg .PX_PLANE0_TILING_H = 4
389+ jpeg .PX_PLANE0_TILING_V = 16 // decode_scale
390+ jpeg .PX_PLANE1_TILING_H = 0
391+ jpeg .PX_PLANE1_TILING_V = 0
392+ elif jpeg_MODE == '411' :
393+ jpeg .PX_PLANE0_TILING_H = 8
394+ jpeg .PX_PLANE0_TILING_V = 8 // decode_scale
395+ jpeg .PX_PLANE1_TILING_H = 0
396+ jpeg .PX_PLANE1_TILING_V = 0
397+ else :
398+ assert False
359399
360400 if jpeg_MODE in ['422' , '420' ]: # TODO
361401 jpeg .CHROMA_DOUBLE_H = 1
@@ -378,10 +418,19 @@ def set_default_regs(param1=0):
378418 jpeg .MATRIX_MULT [9 ].val = 0x0
379419 jpeg .MATRIX_MULT [10 ].val = 0xffffff80
380420
381- jpeg .RGBA_ALPHA = 0xff
382- jpeg .RGBA_ORDER = 1
383-
384- jpeg .SCALE_FACTOR = 0
421+ jpeg .RGBA_ALPHA = args .decode_rgba_alpha
422+ jpeg .RGBA_ORDER = pixfmt == "RGBA"
423+
424+ if decode_scale == 1 :
425+ jpeg .SCALE_FACTOR .set (SCALE = E_SCALE .DIV1 )
426+ elif decode_scale == 2 :
427+ jpeg .SCALE_FACTOR .set (SCALE = E_SCALE .DIV2 )
428+ elif decode_scale == 4 :
429+ jpeg .SCALE_FACTOR .set (SCALE = E_SCALE .DIV4 )
430+ elif decode_scale == 8 :
431+ jpeg .SCALE_FACTOR .set (SCALE = E_SCALE .DIV8 )
432+ else :
433+ assert False
385434
386435 jpeg .INPUT_START1 = input_buf_iova
387436 jpeg .INPUT_START2 = 0xdeadbeef
@@ -421,13 +470,26 @@ def set_default_regs(param1=0):
421470 with open (args .raw_output , 'wb' ) as f :
422471 f .write (output_data )
423472
424- with Image .new (mode = 'RGBA' , size = (jpeg_W , jpeg_H )) as im :
425- for y in range (jpeg_H ):
426- for x in range (jpeg_W ):
473+ with Image .new (
474+ mode = 'RGBA' ,
475+ size = (jpeg_W // decode_scale , jpeg_H // decode_scale )) as im :
476+ for y in range (jpeg_H // decode_scale ):
477+ for x in range (jpeg_W // decode_scale ):
427478 block = output_data [
428479 y * surface_stride + x * BYTESPP :
429480 y * surface_stride + (x + 1 )* BYTESPP ]
430481
431- r , g , b , a = block
482+ if pixfmt == "RGBA" :
483+ r , g , b , a = block
484+ elif pixfmt == "BGRA" :
485+ b , g , r , a = block
486+ elif pixfmt == "RGB565" :
487+ rgb = struct .unpack ("<H" , block )[0 ]
488+ b = (rgb & 0b11111 ) << 3
489+ g = ((rgb >> 5 ) & 0b111111 ) << 2
490+ r = ((rgb >> 11 ) & 0b11111 ) << 3
491+ a = 255
492+ else :
493+ assert False
432494 im .putpixel ((x , y ), (r , g , b , a ))
433495 im .save (args .output )
0 commit comments