Skip to content

Commit 970b278

Browse files
ArcaneNibblemarcan
authored andcommitted
jpeg: Implement encoding subsampling modes
Signed-off-by: R <[email protected]>
1 parent 45876d0 commit 970b278

1 file changed

Lines changed: 61 additions & 6 deletions

File tree

proxyclient/experiments/jpeg.py

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def yuv2rgb(y, u, v):
4848
ap.add_argument("--decode-scale", type=int, required=False, default=1)
4949
ap.add_argument("--decode-pixelfmt", type=str, required=False, default='RGBA')
5050
ap.add_argument("--decode-rgba-alpha", type=int, required=False, default=255)
51+
ap.add_argument("--encode-subsampling", type=str, required=False, default='444')
5152
ap.add_argument("input", type=str)
5253
ap.add_argument("output", type=str)
5354
args = 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")
188189
else:
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

Comments
 (0)