@@ -186,8 +186,24 @@ def yuv2rgb(y, u, v):
186186 output_mem_sz = align_up (surface_sz )
187187 print (f"Using size { output_mem_sz :08X} for output image" )
188188else :
189- assert False
190- # TODO
189+ image_data = b''
190+ with Image .open (args .input ) as im :
191+ im_W , im_H = im .size
192+
193+ for y in range (im_H ):
194+ for x in range (im_W ):
195+ r , g , b = im .getpixel ((x , y ))
196+ image_data += struct .pack ("BBBB" , r , g , b , 255 )
197+
198+ BYTESPP = 4
199+ surface_stride = im_W * BYTESPP
200+ surface_sz = surface_stride * im_H
201+ input_mem_sz = align_up (surface_sz )
202+
203+ output_mem_sz = input_mem_sz
204+
205+ print (f"Using size { input_mem_sz :08X} for input image" )
206+ print (f"Using size { output_mem_sz :08X} for output data" )
191207
192208# Turn on the JPEG block
193209p .pmgr_adt_clocks_enable (f'/arm-io/dart-{ args .which_jpeg } ' )
@@ -733,3 +749,159 @@ def set_default_regs(param1=0):
733749 else :
734750 assert False
735751 im .save (args .output )
752+
753+ if args .encode :
754+ iface .writemem (input_buf_phys , image_data )
755+ print ("Pixel data uploaded" )
756+
757+ jpeg .MODE = 0x17f
758+ jpeg .REG_0x38 = 0x1 # if not set nothing happens
759+ jpeg .REG_0x2c = 0x1 # if not set only header is output
760+ jpeg .REG_0x34 = 0x0 # if set output is a JPEG but weird with no footer
761+ jpeg .CODEC = 0
762+
763+ jpeg .PX_USE_PLANE1 = 0x0
764+ jpeg .PX_PLANE0_WIDTH = im_W * BYTESPP - 1
765+ jpeg .PX_PLANE0_HEIGHT = im_H - 1
766+ jpeg .PX_PLANE1_WIDTH = 0xffffffff
767+ jpeg .PX_PLANE1_HEIGHT = 0xffffffff
768+ jpeg .TIMEOUT = 266000000
769+
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
774+ jpeg .PX_PLANE0_STRIDE = surface_stride
775+ jpeg .PX_PLANE1_STRIDE = 0
776+
777+ # none of this seems to affect anything????
778+ jpeg .REG_0x94 = 0xc # c/2 for 444; 8/2 for 422; 3/1 for 411; b/2 for 400
779+ jpeg .REG_0x98 = 0x2
780+ jpeg .REG_0x20c = im_W
781+ jpeg .REG_0x210 = im_H
782+
783+ jpeg .CONVERT_COLOR_SPACE = 1
784+ jpeg .MATRIX_MULT [0 ].val = 0x4d
785+ jpeg .MATRIX_MULT [1 ].val = 0x96
786+ jpeg .MATRIX_MULT [2 ].val = 0x1d
787+ jpeg .MATRIX_MULT [3 ].val = 0xffffffd5
788+ jpeg .MATRIX_MULT [4 ].val = 0xffffffab
789+ jpeg .MATRIX_MULT [5 ].val = 0x80
790+ jpeg .MATRIX_MULT [6 ].val = 0x80
791+ jpeg .MATRIX_MULT [7 ].val = 0xffffff95
792+ jpeg .MATRIX_MULT [8 ].val = 0xffffffeb
793+ jpeg .MATRIX_MULT [9 ].val = 0x0
794+ jpeg .MATRIX_MULT [10 ].val = 0x80
795+
796+ jpeg .ENCODE_PIXEL_FORMAT = 2
797+ jpeg .ENCODE_COMPONENT0_POS = 0
798+ jpeg .ENCODE_COMPONENT1_POS = 1
799+ jpeg .ENCODE_COMPONENT2_POS = 2
800+ jpeg .ENCODE_COMPONENT3_POS = 3
801+
802+ jpeg .INPUT_START1 = input_buf_iova
803+ jpeg .INPUT_START2 = 0xdeadbeef
804+ jpeg .INPUT_END = input_buf_iova + input_mem_sz + 7 # NOTE +7
805+ jpeg .OUTPUT_START1 = output_buf_iova
806+ jpeg .OUTPUT_START2 = 0xdeadbeef
807+ jpeg .OUTPUT_END = output_buf_iova + output_mem_sz
808+
809+ jpeg .REG_0x118 = 0x1
810+ jpeg .REG_0x11c = 0x0
811+
812+ jpeg .ENABLE_RST_LOGGING = 1
813+
814+ jpeg .MODE = 0x16f
815+ jpeg .JPEG_IO_FLAGS = 0x30
816+ jpeg .JPEG_WIDTH = im_W
817+ jpeg .JPEG_HEIGHT = im_H
818+ jpeg .RST_INTERVAL = 0
819+ jpeg .JPEG_OUTPUT_FLAGS = 0
820+
821+ jpeg .QTBL [0 ].val = 0xa06e64a0
822+ jpeg .QTBL [1 ].val = 0xf0ffffff
823+ jpeg .QTBL [2 ].val = 0x78788cbe
824+ jpeg .QTBL [3 ].val = 0xffffffff
825+ jpeg .QTBL [4 ].val = 0x8c82a0f0
826+ jpeg .QTBL [5 ].val = 0xffffffff
827+ jpeg .QTBL [6 ].val = 0x8caadcff
828+ jpeg .QTBL [7 ].val = 0xffffffff
829+ jpeg .QTBL [8 ].val = 0xb4dcffff
830+ jpeg .QTBL [9 ].val = 0xffffffff
831+ jpeg .QTBL [10 ].val = 0xf0ffffff
832+ jpeg .QTBL [11 ].val = 0xffffffff
833+ jpeg .QTBL [12 ].val = 0xffffffff
834+ jpeg .QTBL [13 ].val = 0xffffffff
835+ jpeg .QTBL [14 ].val = 0xffffffff
836+ jpeg .QTBL [15 ].val = 0xffffffff
837+
838+ jpeg .QTBL [16 ].val = 0xaab4f0ff
839+ jpeg .QTBL [17 ].val = 0xffffffff
840+ jpeg .QTBL [18 ].val = 0xb4d2ffff
841+ jpeg .QTBL [19 ].val = 0xffffffff
842+ jpeg .QTBL [20 ].val = 0xf0ffffff
843+ jpeg .QTBL [21 ].val = 0xffffffff
844+ jpeg .QTBL [22 ].val = 0xffffffff
845+ jpeg .QTBL [23 ].val = 0xffffffff
846+ jpeg .QTBL [24 ].val = 0xffffffff
847+ jpeg .QTBL [25 ].val = 0xffffffff
848+ jpeg .QTBL [26 ].val = 0xffffffff
849+ jpeg .QTBL [27 ].val = 0xffffffff
850+ jpeg .QTBL [28 ].val = 0xffffffff
851+ jpeg .QTBL [29 ].val = 0xffffffff
852+ jpeg .QTBL [30 ].val = 0xffffffff
853+ jpeg .QTBL [31 ].val = 0xffffffff
854+
855+ jpeg .QTBL [32 ].val = 0x01010201
856+ jpeg .QTBL [33 ].val = 0x01020202
857+ jpeg .QTBL [34 ].val = 0x02030202
858+ jpeg .QTBL [35 ].val = 0x03030604
859+ jpeg .QTBL [36 ].val = 0x03030303
860+ jpeg .QTBL [37 ].val = 0x07050804
861+ jpeg .QTBL [38 ].val = 0x0608080a
862+ jpeg .QTBL [39 ].val = 0x0908070b
863+ jpeg .QTBL [40 ].val = 0x080a0e0d
864+ jpeg .QTBL [41 ].val = 0x0b0a0a0c
865+ jpeg .QTBL [42 ].val = 0x0a08080b
866+ jpeg .QTBL [43 ].val = 0x100c0c0d
867+ jpeg .QTBL [44 ].val = 0x0f0f0f0f
868+ jpeg .QTBL [45 ].val = 0x090b1011
869+ jpeg .QTBL [46 ].val = 0x0f0e110d
870+ jpeg .QTBL [47 ].val = 0x0e0e0e01
871+
872+ jpeg .QTBL [48 ].val = 0x04040405
873+ jpeg .QTBL [49 ].val = 0x04050905
874+ jpeg .QTBL [50 ].val = 0x05090f0a
875+ jpeg .QTBL [51 ].val = 0x080a0f1a
876+ jpeg .QTBL [52 ].val = 0x13090913
877+ jpeg .QTBL [53 ].val = 0x1a1a1a1a
878+ jpeg .QTBL [54 ].val = 0x0d1a1a1a
879+ jpeg .QTBL [55 ].val = 0x1a1a1a1a
880+ jpeg .QTBL [56 ].val = 0x1a1a1a1a
881+ jpeg .QTBL [57 ].val = 0x1a1a1a1a
882+ jpeg .QTBL [58 ].val = 0x1a1a1a1a
883+ jpeg .QTBL [59 ].val = 0x1a1a1a1a
884+ jpeg .QTBL [60 ].val = 0x1a1a1a1a
885+ jpeg .QTBL [61 ].val = 0x1a1a1a1a
886+ jpeg .QTBL [62 ].val = 0x1a1a1a1a
887+ jpeg .QTBL [63 ].val = 0x1a1a1a1a
888+
889+ jpeg .HUFFMAN_TABLE .val = 0x3c
890+ jpeg .QTBL_SEL .val = 0xff
891+ jpeg .REG_0x0 .val = 0x1
892+ jpeg .REG_0x1004 .val = 0x1
893+
894+ # FIXME: we don't actually know when it's done
895+ time .sleep (1 )
896+
897+ print (jpeg .STATUS .reg )
898+ print (jpeg .PERFCOUNTER .reg )
899+ jpeg_out_sz = jpeg .COMPRESSED_BYTES .val
900+ print (f"JPEG output is { jpeg_out_sz } bytes" )
901+
902+ output_data = iface .readmem (output_buf_phys , output_mem_sz )
903+ if args .raw_output is not None :
904+ with open (args .raw_output , 'wb' ) as f :
905+ f .write (output_data )
906+ with open (args .output , 'wb' ) as f :
907+ f .write (output_data [:jpeg_out_sz ])
0 commit comments