@@ -70,6 +70,57 @@ def parse_j2k(buffer):
7070
7171 return param
7272
73+ def parse_codestream_markers (buffer ):
74+ offset = 0
75+ markers = []
76+ while offset < len (buffer ):
77+ symbol_code_bytes = buffer [offset : offset + 2 ]
78+ marker = unpack (">H" , symbol_code_bytes )[0 ]
79+ offset += 2
80+ if marker == 0xFF4F :
81+ markers .append ("SOC" )
82+ elif marker == 0xFF51 :
83+ markers .append ("SIZ" )
84+ length_bytes = buffer [offset : offset + 2 ]
85+ length = unpack (">H" , length_bytes )[0 ]
86+ offset += length
87+ elif marker == 0xFF52 :
88+ markers .append ("COD" )
89+ length_bytes = buffer [offset : offset + 2 ]
90+ length = unpack (">H" , length_bytes )[0 ]
91+ offset += length
92+ elif marker == 0xFF55 :
93+ markers .append ("TLM" )
94+ length_bytes = buffer [offset : offset + 2 ]
95+ length = unpack (">H" , length_bytes )[0 ]
96+ offset += length
97+ elif marker == 0xFF58 :
98+ markers .append ("PLT" )
99+ length_bytes = buffer [offset : offset + 2 ]
100+ length = unpack (">H" , length_bytes )[0 ]
101+ offset += length
102+ elif marker == 0xFF5C :
103+ markers .append ("QCD" )
104+ length_bytes = buffer [offset : offset + 2 ]
105+ length = unpack (">H" , length_bytes )[0 ]
106+ offset += length
107+ elif marker == 0xFF64 :
108+ markers .append ("COM" )
109+ length_bytes = buffer [offset : offset + 2 ]
110+ length = unpack (">H" , length_bytes )[0 ]
111+ offset += length
112+ elif marker == 0xFF90 :
113+ markers .append ("SOT" )
114+ length_bytes = buffer [offset : offset + 2 ]
115+ length = unpack (">H" , length_bytes )[0 ]
116+ offset += length
117+ elif marker == 0xFF93 :
118+ markers .append ("SOD" )
119+ # If we get to here, we have the marker info we need
120+ break
121+ else :
122+ raise Exception (f"unexpected marker: 0x{ marker :04X} " )
123+ return markers
73124
74125class TestEncode :
75126 """Tests for encode_array()"""
@@ -701,6 +752,82 @@ def test_jp2(self):
701752 buffer = encode_array (arr , codec_format = 1 )
702753 assert buffer .startswith (b"\x00 \x00 \x00 \x0c \x6a \x50 \x20 \x20 \x0d \x0a \x87 \x0a " )
703754
755+ def test_no_tlm_or_plt_explicit (self ):
756+ """Test encoding with no TLM or PLT, explicitly disabled"""
757+ rows = 123
758+ cols = 234
759+ bit_depth = 8
760+ maximum = 2 ** bit_depth - 1
761+ dtype = f"u{ math .ceil (bit_depth / 8 )} "
762+ arr = np .random .randint (0 , high = maximum + 1 , size = (rows , cols ), dtype = dtype )
763+ buffer = encode_array (arr , compression_ratios = [4 , 2 , 1 ], add_tlm = False , add_plt = False )
764+ out = decode (buffer )
765+ markers = parse_codestream_markers (buffer )
766+ assert "TLM" not in markers
767+ assert "PLT" not in markers
768+ assert np .allclose (arr , out , atol = 5 )
769+
770+ def test_no_tlm_or_plt_default (self ):
771+ """Test encoding with no TLM or PLT, default options"""
772+ rows = 123
773+ cols = 234
774+ bit_depth = 8
775+ maximum = 2 ** bit_depth - 1
776+ dtype = f"u{ math .ceil (bit_depth / 8 )} "
777+ arr = np .random .randint (0 , high = maximum + 1 , size = (rows , cols ), dtype = dtype )
778+ buffer = encode_array (arr , compression_ratios = [4 , 2 , 1 ])
779+ out = decode (buffer )
780+ markers = parse_codestream_markers (buffer )
781+ assert "TLM" not in markers
782+ assert "PLT" not in markers
783+ assert np .allclose (arr , out , atol = 5 )
784+
785+ def test_tlm (self ):
786+ """Test encoding with TLM"""
787+ rows = 123
788+ cols = 234
789+ bit_depth = 8
790+ maximum = 2 ** bit_depth - 1
791+ dtype = f"u{ math .ceil (bit_depth / 8 )} "
792+ arr = np .random .randint (0 , high = maximum + 1 , size = (rows , cols ), dtype = dtype )
793+ buffer = encode_array (arr , compression_ratios = [4 , 2 , 1 ], add_tlm = True )
794+ out = decode (buffer )
795+ markers = parse_codestream_markers (buffer )
796+ assert "TLM" in markers
797+ assert "PLT" not in markers
798+ assert np .allclose (arr , out , atol = 5 )
799+
800+ def test_plt (self ):
801+ """Test encoding with PLT"""
802+ rows = 123
803+ cols = 234
804+ bit_depth = 8
805+ maximum = 2 ** bit_depth - 1
806+ dtype = f"u{ math .ceil (bit_depth / 8 )} "
807+ arr = np .random .randint (0 , high = maximum + 1 , size = (rows , cols ), dtype = dtype )
808+ buffer = encode_array (arr , compression_ratios = [4 , 2 , 1 ], add_plt = True )
809+ out = decode (buffer )
810+ markers = parse_codestream_markers (buffer )
811+ assert "TLM" not in markers
812+ assert "PLT" in markers
813+ assert np .allclose (arr , out , atol = 5 )
814+
815+ def test_tlm_and_plt (self ):
816+ """Test encoding with both TLM and PLT"""
817+ rows = 123
818+ cols = 234
819+ bit_depth = 8
820+ maximum = 2 ** bit_depth - 1
821+ dtype = f"u{ math .ceil (bit_depth / 8 )} "
822+ arr = np .random .randint (0 , high = maximum + 1 , size = (rows , cols ), dtype = dtype )
823+ buffer = encode_array (arr , compression_ratios = [4 , 2 , 1 ], add_plt = True , add_tlm = True )
824+ out = decode (buffer )
825+ param = parse_j2k (buffer )
826+ assert param ["precision" ] == bit_depth
827+ markers = parse_codestream_markers (buffer )
828+ assert "TLM" in markers
829+ assert "PLT" in markers
830+ assert np .allclose (arr , out , atol = 5 )
704831
705832class TestEncodeBuffer :
706833 """Tests for _openjpeg.encode_buffer"""
@@ -2034,6 +2161,80 @@ def test_unused_bits_u1(self):
20342161 assert out .dtype .kind == "u"
20352162 assert np .array_equal (arr , out )
20362163
2164+ def test_no_tlm_or_plt_explicit (self ):
2165+ """Test encoding with no TLM and PLT, explicitly disabled"""
2166+ rows = 123
2167+ cols = 234
2168+ bit_depth = 8
2169+ arr = np .random .randint (0 , high = 256 , size = (rows , cols ), dtype = "u1" )
2170+ buffer = encode_buffer (arr .tobytes (), cols , rows , samples_per_pixel = 1 , bits_stored = bit_depth , is_signed = False , add_plt = False , add_tlm = False )
2171+ out = decode (buffer )
2172+ param = parse_j2k (buffer )
2173+ assert param ["precision" ] == bit_depth
2174+ markers = parse_codestream_markers (buffer )
2175+ assert "TLM" not in markers
2176+ assert "PLT" not in markers
2177+ assert np .allclose (arr , out , atol = 5 )
2178+
2179+ def test_no_tlm_or_plt_default (self ):
2180+ """Test encoding with no TLM and PLT, default options"""
2181+ rows = 123
2182+ cols = 234
2183+ bit_depth = 8
2184+ arr = np .random .randint (0 , high = 256 , size = (rows , cols ), dtype = "u1" )
2185+ buffer = encode_buffer (arr .tobytes (), cols , rows , samples_per_pixel = 1 , bits_stored = bit_depth , is_signed = False )
2186+ out = decode (buffer )
2187+ param = parse_j2k (buffer )
2188+ assert param ["precision" ] == bit_depth
2189+ markers = parse_codestream_markers (buffer )
2190+ assert "TLM" not in markers
2191+ assert "PLT" not in markers
2192+ assert np .allclose (arr , out , atol = 5 )
2193+
2194+ def test_tlm (self ):
2195+ """Test encoding with TLM"""
2196+ rows = 123
2197+ cols = 234
2198+ bit_depth = 8
2199+ arr = np .random .randint (0 , high = 256 , size = (rows , cols ), dtype = "u1" )
2200+ buffer = encode_buffer (arr .tobytes (), cols , rows , samples_per_pixel = 1 , bits_stored = bit_depth , is_signed = False , add_tlm = True )
2201+ out = decode (buffer )
2202+ param = parse_j2k (buffer )
2203+ assert param ["precision" ] == bit_depth
2204+ markers = parse_codestream_markers (buffer )
2205+ assert "TLM" in markers
2206+ assert "PLT" not in markers
2207+ assert np .allclose (arr , out , atol = 5 )
2208+
2209+ def test_plt (self ):
2210+ """Test encoding with PLT"""
2211+ rows = 123
2212+ cols = 234
2213+ bit_depth = 8
2214+ arr = np .random .randint (0 , high = 256 , size = (rows , cols ), dtype = "u1" )
2215+ buffer = encode_buffer (arr .tobytes (), cols , rows , samples_per_pixel = 1 , bits_stored = bit_depth , is_signed = False , add_plt = True )
2216+ out = decode (buffer )
2217+ param = parse_j2k (buffer )
2218+ assert param ["precision" ] == bit_depth
2219+ markers = parse_codestream_markers (buffer )
2220+ assert "TLM" not in markers
2221+ assert "PLT" in markers
2222+ assert np .allclose (arr , out , atol = 5 )
2223+
2224+ def test_tlm_and_plt (self ):
2225+ """Test encoding with both TLM and PLT"""
2226+ rows = 123
2227+ cols = 234
2228+ bit_depth = 8
2229+ arr = np .random .randint (0 , high = 256 , size = (rows , cols ), dtype = "u1" )
2230+ buffer = encode_buffer (arr .tobytes (), cols , rows , samples_per_pixel = 1 , bits_stored = bit_depth , is_signed = False , add_plt = True , add_tlm = True )
2231+ out = decode (buffer )
2232+ param = parse_j2k (buffer )
2233+ assert param ["precision" ] == bit_depth
2234+ markers = parse_codestream_markers (buffer )
2235+ assert "TLM" in markers
2236+ assert "PLT" in markers
2237+ assert np .allclose (arr , out , atol = 5 )
20372238
20382239class TestEncodePixelData :
20392240 """Tests for encode_pixel_data()"""
0 commit comments