@@ -48,6 +48,7 @@ def yuv2rgb(y, u, v):
4848ap .add_argument ("--decode-scale" , type = int , required = False , default = 1 )
4949ap .add_argument ("--decode-pixelfmt" , type = str , required = False , default = 'RGBA' )
5050ap .add_argument ("--decode-rgba-alpha" , type = int , required = False , default = 255 )
51+ ap .add_argument ("--encode-subsampling" , type = str , required = False , default = '444' )
5152ap .add_argument ("input" , type = str )
5253ap .add_argument ("output" , type = str )
5354args = ap .parse_args ()
@@ -186,6 +187,16 @@ def yuv2rgb(y, u, v):
186187 output_mem_sz = align_up (surface_sz )
187188 print (f"Using size { output_mem_sz :08X} for output image" )
188189else :
190+ assert args .encode_subsampling in ['444' , '422' , '420' , '400' ]
191+ if args .encode_subsampling == '444' or args .encode_subsampling == '400' :
192+ macroblock_W , macroblock_H = 8 , 8
193+ elif args .encode_subsampling == '422' :
194+ macroblock_W , macroblock_H = 16 , 8
195+ elif args .encode_subsampling == '420' :
196+ macroblock_W , macroblock_H = 16 , 16
197+ else :
198+ assert False
199+
189200 image_data = b''
190201 with Image .open (args .input ) as im :
191202 im_W , im_H = im .size
@@ -758,7 +769,17 @@ def set_default_regs(param1=0):
758769 jpeg .REG_0x38 = 0x1 # if not set nothing happens
759770 jpeg .REG_0x2c = 0x1 # if not set only header is output
760771 jpeg .REG_0x34 = 0x0 # if set output is a JPEG but weird with no footer
761- jpeg .CODEC = 0
772+
773+ if args .encode_subsampling == '444' :
774+ jpeg .CODEC .set (CODEC = E_CODEC ._444 )
775+ elif args .encode_subsampling == '422' :
776+ jpeg .CODEC .set (CODEC = E_CODEC ._422 )
777+ elif args .encode_subsampling == '420' :
778+ jpeg .CODEC .set (CODEC = E_CODEC ._420 )
779+ elif args .encode_subsampling == '400' :
780+ jpeg .CODEC .set (CODEC = E_CODEC ._400 )
781+ else :
782+ assert False
762783
763784 jpeg .PX_USE_PLANE1 = 0x0
764785 jpeg .PX_PLANE0_WIDTH = im_W * BYTESPP - 1
@@ -767,13 +788,33 @@ def set_default_regs(param1=0):
767788 jpeg .PX_PLANE1_HEIGHT = 0xffffffff
768789 jpeg .TIMEOUT = 266000000
769790
770- jpeg .PX_TILES_W = divroundup (im_W , 8 )
771- jpeg .PX_TILES_H = divroundup (im_H , 8 )
772- jpeg .PX_PLANE0_TILING_H = 0x4
773- jpeg .PX_PLANE0_TILING_V = 0x8
791+ jpeg .PX_TILES_W = divroundup (im_W , macroblock_W )
792+ jpeg .PX_TILES_H = divroundup (im_H , macroblock_H )
793+ if args .encode_subsampling == '444' or args .encode_subsampling == '400' :
794+ jpeg .PX_PLANE0_TILING_H = 4
795+ jpeg .PX_PLANE0_TILING_V = 8
796+ jpeg .PX_PLANE1_TILING_H = 1
797+ jpeg .PX_PLANE1_TILING_V = 1
798+ elif args .encode_subsampling == '422' :
799+ jpeg .PX_PLANE0_TILING_H = 8
800+ jpeg .PX_PLANE0_TILING_V = 8
801+ jpeg .PX_PLANE1_TILING_H = 1
802+ jpeg .PX_PLANE1_TILING_V = 1
803+ elif args .encode_subsampling == '420' :
804+ jpeg .PX_PLANE0_TILING_H = 8
805+ jpeg .PX_PLANE0_TILING_V = 16
806+ jpeg .PX_PLANE1_TILING_H = 0
807+ jpeg .PX_PLANE1_TILING_V = 0
808+ else :
809+ assert False
774810 jpeg .PX_PLANE0_STRIDE = surface_stride
775811 jpeg .PX_PLANE1_STRIDE = 0
776812
813+ if args .encode_subsampling in ['422' , '420' ]:
814+ jpeg .CHROMA_HALVE_H_TYPE1 = 1
815+ if args .encode_subsampling == '420' :
816+ jpeg .CHROMA_HALVE_V_TYPE1 = 1
817+
777818 # none of this seems to affect anything????
778819 jpeg .REG_0x94 = 0xc # c/2 for 444; 8/2 for 422; 3/1 for 411; b/2 for 400
779820 jpeg .REG_0x98 = 0x2
@@ -812,7 +853,21 @@ def set_default_regs(param1=0):
812853 jpeg .ENABLE_RST_LOGGING = 1
813854
814855 jpeg .MODE = 0x16f
815- jpeg .JPEG_IO_FLAGS = 0x30
856+ if args .encode_subsampling == '444' :
857+ jpeg_subsampling = E_JPEG_IO_FLAGS_SUBSAMPLING ._444
858+ elif args .encode_subsampling == '422' :
859+ jpeg_subsampling = E_JPEG_IO_FLAGS_SUBSAMPLING ._422
860+ elif args .encode_subsampling == '420' :
861+ jpeg_subsampling = E_JPEG_IO_FLAGS_SUBSAMPLING ._420
862+ elif args .encode_subsampling == '400' :
863+ jpeg_subsampling = E_JPEG_IO_FLAGS_SUBSAMPLING ._400
864+ else :
865+ assert False
866+ jpeg .JPEG_IO_FLAGS .set (
867+ OUTPUT_8BYTE_CHUNKS_CORRECTLY = 1 ,
868+ OUTPUT_MACROBLOCKS_UNFLIPPED_H = 1 ,
869+ SUBSAMPLING_MODE = jpeg_subsampling
870+ )
816871 jpeg .JPEG_WIDTH = im_W
817872 jpeg .JPEG_HEIGHT = im_H
818873 jpeg .RST_INTERVAL = 0
0 commit comments