/src/serenity/Userland/Libraries/LibGfx/ImageFormats/JPEG2000Loader.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2024, Nico Weber <thakis@chromium.org> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #include <AK/BitStream.h> |
8 | | #include <AK/Debug.h> |
9 | | #include <AK/Enumerate.h> |
10 | | #include <AK/MemoryStream.h> |
11 | | #include <LibGfx/ICC/Profile.h> |
12 | | #include <LibGfx/ImageFormats/ISOBMFF/JPEG2000Boxes.h> |
13 | | #include <LibGfx/ImageFormats/ISOBMFF/Reader.h> |
14 | | #include <LibGfx/ImageFormats/JPEG2000BitplaneDecoding.h> |
15 | | #include <LibGfx/ImageFormats/JPEG2000InverseDiscreteWaveletTransform.h> |
16 | | #include <LibGfx/ImageFormats/JPEG2000Loader.h> |
17 | | #include <LibGfx/ImageFormats/JPEG2000ProgressionIterators.h> |
18 | | #include <LibGfx/ImageFormats/JPEG2000TagTree.h> |
19 | | #include <LibTextCodec/Decoder.h> |
20 | | |
21 | | // Core coding system spec (.jp2 format): T-REC-T.800-201511-S!!PDF-E.pdf available here: |
22 | | // https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-T.800-201511-S!!PDF-E&type=items |
23 | | |
24 | | // There is a useful example bitstream in the spec in: |
25 | | // J.10 An example of decoding showing intermediate |
26 | | |
27 | | // Extensions (.jpx format): T-REC-T.801-202106-S!!PDF-E.pdf available here: |
28 | | // https://handle.itu.int/11.1002/1000/14666-en?locatt=format:pdf&auth |
29 | | |
30 | | // rfc3745 lists the MIME type. It only mentions the jp2_id_string as magic number. |
31 | | |
32 | | // A short overview of the JPEG2000 format: |
33 | | // |
34 | | // Image Decomposition |
35 | | // ------------------- |
36 | | // |
37 | | // 1. An image is first divided into independent tiles |
38 | | // 2. Each tile is split into tile components (one each for R, G, B, A) |
39 | | // 3. Each tile component undergoes Discrete Wavelet Transform (DWT) |
40 | | // |
41 | | // Resolution Levels and Subbands |
42 | | // ------------------------------ |
43 | | // |
44 | | // The DWT produces hierarchical resolution levels with these subbands: |
45 | | // - Level 0: Single LL (Lowpass-Lowpass) subband |
46 | | // - Level 1+: HL (Highpass-Lowpass), LH (Lowpass-Highpass), and HH (Highpass-Highpass) subbands |
47 | | // |
48 | | // Subband Layout: |
49 | | // +-----+-----+----------+ |
50 | | // | LL0 | HL1 | | |
51 | | // +-----+-----+ HL2 | |
52 | | // | LH1 | HH1 | | |
53 | | // +-----+-----+----------+ |
54 | | // | | | |
55 | | // | LH2 | HH2 | |
56 | | // | | | |
57 | | // +-----------+----------+ |
58 | | // |
59 | | // Precinct Structure |
60 | | // ------------------ |
61 | | // - Precincts are rectangular regions that span all subbands within a resolution level |
62 | | // - Typical size: 512k × 512k pixels |
63 | | // - Most images contain only a single precinct due to this large size |
64 | | // - "Precinct limited to a subband": portion of precinct covering one subband |
65 | | // |
66 | | // Layer System |
67 | | // ----------- |
68 | | // - Coefficients' bitplanes can be stored separately |
69 | | // - Groups of bitplanes form "layers" |
70 | | // - For example, for an 8bpp image, layer 0 might contain the first two bitplanes, layer 1 the next two, etc. |
71 | | // - Enables progressive refinement of image color resolution |
72 | | // |
73 | | // Codeblock Organization |
74 | | // ---------------------- |
75 | | // - Each precinct is divided into codeblocks |
76 | | // - A codeblock is the smallest coded unit in JPEG2000 |
77 | | // - Typical codeblock size: 64×64 pixels |
78 | | // - Codeblocks store coefficient bitplanes from wavelet transformation |
79 | | // - Independent arithmetic decoder contexts enable parallel decoding |
80 | | // - A codeblock can be split into segments. A segment is a group of bytes |
81 | | // that are fed into the arithmetic decoder as one unit. Most files use one segment, |
82 | | // but the code block styles "termination on each coding pass" and |
83 | | // "selective arithmetic coding bypass" use multiple segments. |
84 | | // |
85 | | // Packets |
86 | | // ------- |
87 | | // "All compressed image data representing a specific tile, layer, component, resolution level and precinct appears in the |
88 | | // codestream in a contiguous segment called a packet." |
89 | | // A packet contains a packet header, and information about all codeblocks in the packet. |
90 | | |
91 | | namespace Gfx { |
92 | | |
93 | | // A JPEG2000 image can be stored in a codestream with markers, similar to a JPEG image, |
94 | | // or in a JP2 file, which is a container format based on boxes similar to ISOBMFF. |
95 | | |
96 | | // This is the marker for the codestream version. |
97 | | // T.800 Annex A, Codestream syntax, A.2 Information in the marker segments and A.3 Construction of the codestream |
98 | | static constexpr u8 marker_id_string[] = { 0xFF, 0x4F, 0xFF, 0x51 }; |
99 | | |
100 | | // This is the marker for the box version. |
101 | | // T.800 Annex I, JP2 file format syntax, I.5.1 JPEG 2000 Signature box |
102 | | static constexpr u8 jp2_id_string[] = { 0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A }; |
103 | | |
104 | | // Table A.2 – List of markers and marker segments |
105 | | // "Delimiting markers and marker segments" |
106 | 145k | #define J2K_SOC 0xFF4F // "Start of codestream" |
107 | 5.12k | #define J2K_SOT 0xFF90 // "Start of tile-part" |
108 | 147k | #define J2K_SOD 0xFF93 // "Start of data" |
109 | 75.9k | #define J2K_EOC 0xFFD9 // "End of codestream" |
110 | | // "Fixed information marker segments" |
111 | 1.13k | #define J2K_SIZ 0xFF51 // "Image and tile size" |
112 | | // "Functional marker segments" |
113 | 66.6k | #define J2K_COD 0xFF52 // "Coding style default" |
114 | 68.4k | #define J2K_COC 0xFF53 // "Coding style component" |
115 | 47.8k | #define J2K_RGN 0xFF5E // "Region-of-interest" |
116 | 66.7k | #define J2K_QCD 0xFF5C // "Quantization default" |
117 | 108k | #define J2K_QCC 0xFF5D // "Quantization component" |
118 | 47.8k | #define J2K_POC 0xFF5F // "Progression order change" |
119 | | // "Pointer marker segments" |
120 | 12.2k | #define J2K_TLM 0xFF55 // "Tile-part lengths" |
121 | 12.1k | #define J2K_PLM 0xFF57 // "Packet length, main header" |
122 | 36.8k | #define J2K_PLT 0xFF58 // "Packet length, tile-part header" |
123 | 12.0k | #define J2K_PPM 0xFF60 // "Packed packet headers, main header" |
124 | 35.7k | #define J2K_PPT 0xFF61 // "Packed packet headers, tile-part header" |
125 | | // "In-bit-stream markers and marker segments" |
126 | 108 | #define J2K_SOP 0xFF91 // "Start of packet" |
127 | 18 | #define J2K_EPH 0xFF92 // "End of packet header" |
128 | | // "Informational marker segments" |
129 | 12.1k | #define J2K_CRG 0xFF63 // "Component registration" |
130 | 83.5k | #define J2K_COM 0xFF64 // "Comment" |
131 | | |
132 | | // A.4.2 Start of tile-part (SOT) |
133 | | struct StartOfTilePart { |
134 | | // "Tile index. This number refers to the tiles in raster order starting at the number 0." |
135 | | u16 tile_index { 0 }; // "Isot" in spec. |
136 | | |
137 | | // "Length, in bytes, from the beginning of the first byte of this SOT marker segment of the tile-part to |
138 | | // the end of the data of that tile-part. Figure A.16 shows this alignment. Only the last tile-part in the |
139 | | // codestream may contain a 0 for Psot. If the Psot is 0, this tile-part is assumed to contain all data until |
140 | | // the EOC marker." |
141 | | u32 tile_part_length { 0 }; // "Psot" in spec. |
142 | | |
143 | | // "Tile-part index. There is a specific order required for decoding tile-parts; this index denotes the order |
144 | | // from 0. If there is only one tile-part for a tile, then this value is zero. The tile-parts of this tile shall |
145 | | // appear in the codestream in this order, although not necessarily consecutively." |
146 | | u8 tile_part_index { 0 }; // "TPsot" in spec. |
147 | | |
148 | | // "Number of tile-parts of a tile in the codestream. Two values are allowed: the correct number of tile- |
149 | | // parts for that tile and zero. A zero value indicates that the number of tile-parts of this tile is not |
150 | | // specified in this tile-part. |
151 | | u8 number_of_tile_parts { 0 }; // "TNsot" in spec. |
152 | | }; |
153 | | |
154 | | static ErrorOr<StartOfTilePart> read_start_of_tile_part(ReadonlyBytes data) |
155 | 4.21k | { |
156 | 4.21k | FixedMemoryStream stream { data }; |
157 | | |
158 | 4.21k | StartOfTilePart sot; |
159 | 4.21k | sot.tile_index = TRY(stream.read_value<BigEndian<u16>>()); |
160 | 4.21k | sot.tile_part_length = TRY(stream.read_value<BigEndian<u32>>()); |
161 | 4.21k | sot.tile_part_index = TRY(stream.read_value<u8>()); |
162 | 4.21k | sot.number_of_tile_parts = TRY(stream.read_value<u8>()); |
163 | | |
164 | 4.21k | dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: SOT marker segment: tile_index={}, tile_part_length={}, tile_part_index={}, number_of_tile_parts={}", sot.tile_index, sot.tile_part_length, sot.tile_part_index, sot.number_of_tile_parts); |
165 | | |
166 | 4.21k | return sot; |
167 | 4.21k | } |
168 | | |
169 | | // A.5.1 Image and tile size (SIZ) |
170 | | struct ImageAndTileSize { |
171 | | // "Denotes capabilities that a decoder needs to properly decode the codestream." |
172 | | u16 needed_decoder_capabilities { 0 }; // "Rsiz" in spec. |
173 | | |
174 | | // "Width of the reference grid." |
175 | | u32 width { 0 }; // "Xsiz" in spec. |
176 | | |
177 | | // "Height of the reference grid." |
178 | | u32 height { 0 }; // "Ysiz" in spec. |
179 | | |
180 | | // "Horizontal offset from the origin of the reference grid to the left side of the image area." |
181 | | u32 x_offset { 0 }; // "XOsiz" in spec. |
182 | | |
183 | | // "Vertical offset from the origin of the reference grid to the top side of the image area." |
184 | | u32 y_offset { 0 }; // "YOsiz" in spec. |
185 | | |
186 | | // "Width of one reference tile with respect to the reference grid." |
187 | | u32 tile_width { 0 }; // "XTsiz" in spec. |
188 | | |
189 | | // "Height of one reference tile with respect to the reference grid." |
190 | | u32 tile_height { 0 }; // "YTsiz" in spec. |
191 | | |
192 | | // "Horizontal offset from the origin of the reference grid to the left side of the first tile." |
193 | | u32 tile_x_offset { 0 }; // "XTOsiz" in spec. |
194 | | |
195 | | // "Vertical offset from the origin of the reference grid to the top side of the first tile." |
196 | | u32 tile_y_offset { 0 }; // "YTOsiz" in spec. |
197 | | |
198 | | // "Csiz" isn't stored in this struct. It corresponds to `components.size()`. |
199 | | |
200 | | struct ComponentInformation { |
201 | | // "Precision (depth) in bits and sign of the ith component samples." |
202 | | u8 depth_and_sign { 0 }; // "Ssiz" in spec. |
203 | | |
204 | | // Table A.11 – Component Ssiz parameter |
205 | 31.3M | u8 bit_depth() const { return (depth_and_sign & 0x7F) + 1; } |
206 | 1.87k | bool is_signed() const { return depth_and_sign & 0x80; } |
207 | | |
208 | | // "Horizontal separation of a sample of the ith component with respect to the reference grid." |
209 | | u8 horizontal_separation { 0 }; // "XRsiz" in spec. |
210 | | |
211 | | // "Vertical separation of a sample of the ith component with respect to the reference grid." |
212 | | u8 vertical_separation { 0 }; // "YRsiz" in spec. |
213 | | }; |
214 | | Vector<ComponentInformation> components; |
215 | | |
216 | | // (B-5) |
217 | 1.14M | u32 number_of_x_tiles() const { return ceil_div(width - x_offset, tile_width); } |
218 | 0 | u32 number_of_y_tiles() const { return ceil_div(height - y_offset, tile_height); } |
219 | | |
220 | | IntPoint tile_2d_index_from_1d_index(u32 tile_index) const |
221 | 572k | { |
222 | | // (B-6) |
223 | 572k | return { tile_index % number_of_x_tiles(), tile_index / number_of_x_tiles() }; |
224 | 572k | } |
225 | | |
226 | | IntRect reference_grid_coordinates_for_tile(IntPoint tile_2d_index) const |
227 | 572k | { |
228 | 572k | int p = tile_2d_index.x(); |
229 | 572k | int q = tile_2d_index.y(); |
230 | 572k | int tx0 = max(tile_x_offset + p * tile_width, x_offset); // (B-7) |
231 | 572k | int ty0 = max(tile_y_offset + q * tile_height, y_offset); // (B-8) |
232 | 572k | int tx1 = min(tile_x_offset + (p + 1) * tile_width, width); // (B-9) |
233 | 572k | int ty1 = min(tile_y_offset + (q + 1) * tile_height, height); // (B-10) |
234 | 572k | return { tx0, ty0, tx1 - tx0, ty1 - ty0 }; // (B-11) |
235 | 572k | } |
236 | | |
237 | | IntRect reference_grid_coordinates_for_tile_component(IntRect tile_rect, int component_index) const |
238 | 1.76M | { |
239 | | // (B-12) |
240 | 1.76M | int tcx0 = ceil_div(tile_rect.left(), static_cast<int>(components[component_index].horizontal_separation)); |
241 | 1.76M | int tcx1 = ceil_div(tile_rect.right(), static_cast<int>(components[component_index].horizontal_separation)); |
242 | 1.76M | int tcy0 = ceil_div(tile_rect.top(), static_cast<int>(components[component_index].vertical_separation)); |
243 | 1.76M | int tcy1 = ceil_div(tile_rect.bottom(), static_cast<int>(components[component_index].vertical_separation)); |
244 | 1.76M | return { tcx0, tcy0, tcx1 - tcx0, tcy1 - tcy0 }; // (B-13) |
245 | 1.76M | } |
246 | | |
247 | | IntRect reference_grid_coordinates_for_tile_component(IntPoint tile_2d_index, int component_index) const |
248 | 0 | { |
249 | 0 | auto tile_rect = reference_grid_coordinates_for_tile(tile_2d_index); |
250 | 0 | return reference_grid_coordinates_for_tile_component(tile_rect, component_index); |
251 | 0 | } |
252 | | |
253 | | IntRect reference_grid_coordinates_for_ll_band(IntRect tile_rect, int component_index, int r, int N_L) const |
254 | 599k | { |
255 | | // B.5 |
256 | | // (B-14) |
257 | 599k | auto component_rect = reference_grid_coordinates_for_tile_component(tile_rect, component_index); |
258 | 599k | int denominator = 1 << (N_L - r); |
259 | 599k | int trx0 = ceil_div(component_rect.left(), denominator); |
260 | 599k | int try0 = ceil_div(component_rect.top(), denominator); |
261 | 599k | int trx1 = ceil_div(component_rect.right(), denominator); |
262 | 599k | int try1 = ceil_div(component_rect.bottom(), denominator); |
263 | | |
264 | 599k | return { trx0, try0, trx1 - trx0, try1 - try0 }; |
265 | 599k | } |
266 | | |
267 | | IntRect reference_grid_coordinates_for_sub_band(IntRect tile_rect, int component_index, int n_b, JPEG2000::SubBand sub_band) const |
268 | 594k | { |
269 | | // B.5 |
270 | | // Table B.1 – Quantities (xob, yob) for sub-band b |
271 | 594k | int xob = 0; |
272 | 594k | int yob = 0; |
273 | 594k | if (sub_band == JPEG2000::SubBand::HorizontalHighpassVerticalLowpass || sub_band == JPEG2000::SubBand::HorizontalHighpassVerticalHighpass) |
274 | 14.0k | xob = 1; |
275 | 594k | if (sub_band == JPEG2000::SubBand::HorizontalLowpassVerticalHighpass || sub_band == JPEG2000::SubBand::HorizontalHighpassVerticalHighpass) |
276 | 14.0k | yob = 1; |
277 | 594k | VERIFY(n_b >= 1 || (n_b == 0 && sub_band == JPEG2000::SubBand::HorizontalLowpassVerticalLowpass)); |
278 | | |
279 | | // If n_b is 0, `1 << (n_b - 1)` is undefined, but n_b is only 0 for the LL band, where xob and yob are 0 anyways. |
280 | | // So the value of o_scale doesn't matter in that case. |
281 | 594k | int o_scale = 0; |
282 | 594k | if (n_b > 0) |
283 | 22.5k | o_scale = 1 << (n_b - 1); |
284 | | |
285 | | // (B-15) |
286 | 594k | auto component_rect = reference_grid_coordinates_for_tile_component(tile_rect, component_index); |
287 | 594k | int denominator = 1 << n_b; |
288 | 594k | int tbx0 = ceil_div(component_rect.left() - o_scale * xob, denominator); |
289 | 594k | int tby0 = ceil_div(component_rect.top() - o_scale * yob, denominator); |
290 | 594k | int tbx1 = ceil_div(component_rect.right() - o_scale * xob, denominator); |
291 | 594k | int tby1 = ceil_div(component_rect.bottom() - o_scale * yob, denominator); |
292 | | |
293 | 594k | return { tbx0, tby0, tbx1 - tbx0, tby1 - tby0 }; |
294 | 594k | } |
295 | | |
296 | | IntRect reference_grid_coordinates_for_sub_band(IntPoint tile_2d_index, int component_index, int n_b, JPEG2000::SubBand sub_band) const |
297 | 0 | { |
298 | 0 | auto tile_rect = reference_grid_coordinates_for_tile(tile_2d_index); |
299 | 0 | return reference_grid_coordinates_for_sub_band(tile_rect, component_index, n_b, sub_band); |
300 | 0 | } |
301 | | }; |
302 | | |
303 | | static ErrorOr<ImageAndTileSize> read_image_and_tile_size(ReadonlyBytes data) |
304 | 1.13k | { |
305 | 1.13k | FixedMemoryStream stream { data }; |
306 | | |
307 | 1.13k | ImageAndTileSize siz; |
308 | 1.13k | siz.needed_decoder_capabilities = TRY(stream.read_value<BigEndian<u16>>()); |
309 | 1.13k | siz.width = TRY(stream.read_value<BigEndian<u32>>()); |
310 | 1.13k | siz.height = TRY(stream.read_value<BigEndian<u32>>()); |
311 | 1.13k | siz.x_offset = TRY(stream.read_value<BigEndian<u32>>()); |
312 | 1.13k | siz.y_offset = TRY(stream.read_value<BigEndian<u32>>()); |
313 | 1.13k | siz.tile_width = TRY(stream.read_value<BigEndian<u32>>()); |
314 | 1.13k | siz.tile_height = TRY(stream.read_value<BigEndian<u32>>()); |
315 | 1.13k | siz.tile_x_offset = TRY(stream.read_value<BigEndian<u32>>()); |
316 | 1.13k | siz.tile_y_offset = TRY(stream.read_value<BigEndian<u32>>()); |
317 | 1.13k | u16 component_count = TRY(stream.read_value<BigEndian<u16>>()); // "Csiz" in spec. |
318 | | |
319 | | // Table A.9 – Image and tile size parameter values |
320 | | // Xsiz, Ysiz, XTsiz, YTsiz: 1 to 2^32-1. |
321 | 1.13k | if (siz.width == 0 || siz.height == 0 || siz.tile_width == 0 || siz.tile_height == 0) |
322 | 2 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Invalid image or tile size"); |
323 | | |
324 | | // Ad-hoc: Limit image size to < 4 GiB. |
325 | 1.13k | if (static_cast<u64>(siz.width) * siz.height > INT32_MAX) |
326 | 13 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Image is suspiciously large, not decoding"); |
327 | | |
328 | | // CSiz: 1 to 16384. |
329 | 1.11k | if (component_count < 1 || component_count > 16384) |
330 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Invalid number of components"); |
331 | | |
332 | 15.1k | for (size_t i = 0; i < component_count; ++i) { |
333 | 14.0k | ImageAndTileSize::ComponentInformation component; |
334 | 14.0k | component.depth_and_sign = TRY(stream.read_value<u8>()); |
335 | 14.0k | if (component.bit_depth() > 38) |
336 | 9 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Invalid component depth"); |
337 | 14.0k | component.horizontal_separation = TRY(stream.read_value<u8>()); |
338 | 14.0k | component.vertical_separation = TRY(stream.read_value<u8>()); |
339 | 0 | siz.components.append(component); |
340 | 14.0k | } |
341 | | |
342 | 1.10k | dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: SIZ marker segment: needed_decoder_capabilities={}, width={}, height={}, x_offset={}, y_offset={}, tile_width={}, tile_height={}, tile_x_offset={}, tile_y_offset={}", siz.needed_decoder_capabilities, siz.width, siz.height, siz.x_offset, siz.y_offset, siz.tile_width, siz.tile_height, siz.tile_x_offset, siz.tile_y_offset); |
343 | 1.10k | dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: SIZ marker segment: {} components:", component_count); |
344 | 1.10k | for (auto [i, component] : enumerate(siz.components)) |
345 | 6.63k | dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: SIZ marker segment: component[{}]: is_signed={}, bit_depth={}, horizontal_separation={}, vertical_separation={}", i, component.is_signed(), component.bit_depth(), component.horizontal_separation, component.vertical_separation); |
346 | | |
347 | 1.10k | return siz; |
348 | 1.11k | } |
349 | | |
350 | | // Data shared by COD and COC marker segments |
351 | | struct CodingStyleParameters { |
352 | | // Table A.15 – Coding style parameter values of the SPcod and SPcoc parameters |
353 | | // "Number of decomposition levels, NL, Zero implies no transformation." |
354 | | u8 number_of_decomposition_levels { 0 }; |
355 | | u8 code_block_width_exponent { 0 }; // "xcb" in spec; 2 already added. |
356 | | u8 code_block_height_exponent { 0 }; // "ycb" in spec; 2 already added. |
357 | | u8 code_block_style { 0 }; |
358 | | JPEG2000::Transformation transformation { JPEG2000::Transformation::Irreversible_9_7_Filter }; |
359 | | |
360 | | // Table A.19 – Code-block style for the SPcod and SPcoc parameters |
361 | 53.5k | bool uses_selective_arithmetic_coding_bypass() const { return code_block_style & 1; } |
362 | 15.4k | bool reset_context_probabilities() const { return code_block_style & 2; } |
363 | 54.6k | bool uses_termination_on_each_coding_pass() const { return code_block_style & 4; } |
364 | 15.4k | bool uses_vertically_causal_context() const { return code_block_style & 8; } |
365 | 0 | bool uses_predictable_termination() const { return code_block_style & 0x10; } |
366 | 15.4k | bool uses_segmentation_symbols() const { return code_block_style & 0x20; } |
367 | | |
368 | | // If has_explicit_precinct_size is false, this contains the default { 15, 15 } number_of_decomposition_levels + 1 times. |
369 | | // If has_explicit_precinct_size is true, this contains number_of_decomposition_levels + 1 explicit values stored in the COD marker segment. |
370 | | struct PrecinctSize { |
371 | | u8 PPx { 0 }; |
372 | | u8 PPy { 0 }; |
373 | | }; |
374 | | Vector<PrecinctSize> precinct_sizes; |
375 | | }; |
376 | | |
377 | | static ErrorOr<CodingStyleParameters> read_coding_style_parameters(ReadonlyBytes data, StringView name, bool has_explicit_precinct_size) |
378 | 3.78k | { |
379 | 3.78k | FixedMemoryStream stream { data }; |
380 | | |
381 | 3.78k | CodingStyleParameters parameters; |
382 | | |
383 | 3.78k | parameters.number_of_decomposition_levels = TRY(stream.read_value<u8>()); |
384 | 3.78k | if (parameters.number_of_decomposition_levels > 32) |
385 | 5 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Invalid number of decomposition levels"); |
386 | | |
387 | | // Table A.18 – Width or height exponent of the code-blocks for the SPcod and SPcoc parameters |
388 | 3.77k | u8 xcb = (TRY(stream.read_value<u8>()) & 0xF) + 2; |
389 | 3.77k | u8 ycb = (TRY(stream.read_value<u8>()) & 0xF) + 2; |
390 | 3.77k | if (xcb > 10 || ycb > 10 || xcb + ycb > 12) |
391 | 2 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Invalid code block size"); |
392 | 3.77k | parameters.code_block_width_exponent = xcb; |
393 | 3.77k | parameters.code_block_height_exponent = ycb; |
394 | | |
395 | 3.77k | parameters.code_block_style = TRY(stream.read_value<u8>()); |
396 | 3.77k | if (parameters.code_block_style & 0xC0) |
397 | 3 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Reserved code block style bits set"); |
398 | | |
399 | | // Table A.20 – Transformation for the SPcod and SPcoc parameters |
400 | 3.77k | u8 transformation = TRY(stream.read_value<u8>()); |
401 | 3.77k | if (transformation > 1) |
402 | 9 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Invalid transformation"); |
403 | 3.76k | parameters.transformation = transformation == 0 ? JPEG2000::Transformation::Irreversible_9_7_Filter : JPEG2000::Transformation::Reversible_5_3_Filter; |
404 | | |
405 | 3.76k | if (has_explicit_precinct_size) { |
406 | 4.35k | for (size_t i = 0; i < parameters.number_of_decomposition_levels + 1u; ++i) { |
407 | 2.35k | u8 b = TRY(stream.read_value<u8>()); |
408 | | |
409 | | // Table A.21 – Precinct width and height for the SPcod and SPcoc parameters |
410 | 0 | CodingStyleParameters::PrecinctSize precinct_size; |
411 | 2.35k | precinct_size.PPx = b & 0xF; |
412 | 2.35k | precinct_size.PPy = b >> 4; |
413 | 2.35k | if ((precinct_size.PPx == 0 || precinct_size.PPy == 0) && i > 0) |
414 | 1 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Invalid precinct size"); |
415 | 2.35k | parameters.precinct_sizes.append(precinct_size); |
416 | 2.35k | } |
417 | 2.00k | } else { |
418 | 31.4k | for (size_t i = 0; i < parameters.number_of_decomposition_levels + 1u; ++i) |
419 | 29.7k | parameters.precinct_sizes.append({ 15, 15 }); |
420 | 1.76k | } |
421 | | |
422 | 3.76k | dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: {} marker segment: number_of_decomposition_levels={}, code_block_width_exponent={}, code_block_height_exponent={}", name, parameters.number_of_decomposition_levels, parameters.code_block_width_exponent, parameters.code_block_height_exponent); |
423 | 3.76k | dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: {} marker segment: code_block_style={}, transformation={}", name, parameters.code_block_style, (int)parameters.transformation); |
424 | 3.76k | if (has_explicit_precinct_size) { |
425 | 2.00k | dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: {} marker segment: {} explicit precinct sizes:", name, parameters.precinct_sizes.size()); |
426 | 2.00k | for (auto [i, precinct_size] : enumerate(parameters.precinct_sizes)) |
427 | 2.34k | dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: {} marker segment: precinct_size[{}]: PPx={}, PPy={}", name, i, precinct_size.PPx, precinct_size.PPy); |
428 | 2.00k | } |
429 | | |
430 | 3.76k | return parameters; |
431 | 3.76k | } |
432 | | |
433 | | // A.6.1 Coding style default (COD) |
434 | | struct CodingStyleDefault { |
435 | | // Table A.13 – Coding style parameter values for the Scod parameter |
436 | | bool has_explicit_precinct_size { false }; |
437 | | bool may_use_SOP_marker { false }; |
438 | | bool shall_use_EPH_marker { false }; |
439 | | |
440 | | // Table A.16 – Progression order for the SGcod, SPcoc, and Ppoc parameters |
441 | | // B.12 Progression order |
442 | | enum ProgressionOrder { |
443 | | LayerResolutionComponentPosition = 0, |
444 | | ResolutionLayerComponentPosition = 1, |
445 | | ResolutionPositionComponentLayer = 2, |
446 | | PositionComponentResolutionLayer = 3, |
447 | | ComponentPositionResolutionLayer = 4, |
448 | | }; |
449 | | |
450 | | // Table A.17 – Multiple component transformation for the SGcod parameters |
451 | | enum MultipleComponentTransformationType { |
452 | | None = 0, |
453 | | MultipleComponentTransformationUsed = 1, // See Annex G |
454 | | }; |
455 | | |
456 | | // Table A.14 – Coding style parameter values of the SGcod parameter |
457 | | ProgressionOrder progression_order { LayerResolutionComponentPosition }; |
458 | | u16 number_of_layers { 0 }; |
459 | | MultipleComponentTransformationType multiple_component_transformation_type { None }; |
460 | | |
461 | | CodingStyleParameters parameters; |
462 | | }; |
463 | | |
464 | | static ErrorOr<CodingStyleDefault> read_coding_style_default(ReadonlyBytes data) |
465 | 1.02k | { |
466 | 1.02k | FixedMemoryStream stream { data }; |
467 | | |
468 | 1.02k | CodingStyleDefault cod; |
469 | | |
470 | 1.02k | u8 Scod = TRY(stream.read_value<u8>()); |
471 | 0 | cod.has_explicit_precinct_size = Scod & 1; |
472 | 1.02k | cod.may_use_SOP_marker = Scod & 2; |
473 | 1.02k | cod.shall_use_EPH_marker = Scod & 4; |
474 | | |
475 | 1.02k | u32 SGcod = TRY(stream.read_value<BigEndian<u32>>()); |
476 | 0 | u8 progression_order = SGcod >> 24; |
477 | 1.02k | if (progression_order > 4) |
478 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Invalid progression order"); |
479 | 1.02k | cod.progression_order = static_cast<CodingStyleDefault::ProgressionOrder>(progression_order); |
480 | | |
481 | 1.02k | cod.number_of_layers = (SGcod >> 8) & 0xFFFF; |
482 | 1.02k | if (cod.number_of_layers == 0) |
483 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Invalid number of layers"); |
484 | | |
485 | 1.02k | u8 multiple_component_transformation_type = SGcod & 0xFF; |
486 | 1.02k | if (multiple_component_transformation_type > 1) |
487 | 2 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Invalid multiple component transformation type"); |
488 | 1.02k | cod.multiple_component_transformation_type = static_cast<CodingStyleDefault::MultipleComponentTransformationType>(multiple_component_transformation_type); |
489 | | |
490 | 1.02k | dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: COD marker segment: has_explicit_precinct_size={}, may_use_SOP_marker={}, shall_use_EPH_marker={}", cod.has_explicit_precinct_size, cod.may_use_SOP_marker, cod.shall_use_EPH_marker); |
491 | 1.02k | dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: COD marker segment: progression_order={}, number_of_layers={}, multiple_component_transformation_type={}", (int)cod.progression_order, cod.number_of_layers, (int)cod.multiple_component_transformation_type); |
492 | | |
493 | 1.02k | cod.parameters = TRY(read_coding_style_parameters(data.slice(stream.offset()), "COD"sv, cod.has_explicit_precinct_size)); |
494 | | |
495 | 0 | return cod; |
496 | 1.02k | } |
497 | | |
498 | | // A.6.2 Coding style component (COC) |
499 | | struct CodingStyleComponent { |
500 | | u16 component_index { 0 }; // "Ccoc" in spec. |
501 | | |
502 | | // Table A.23 – Coding style parameter values for the Scoc parameter |
503 | | bool has_explicit_precinct_size { false }; // "Scoc" in spec. |
504 | | |
505 | | CodingStyleParameters parameters; |
506 | | }; |
507 | | |
508 | | static ErrorOr<CodingStyleComponent> read_coding_style_component(ReadonlyBytes data, size_t number_of_components) |
509 | 2.76k | { |
510 | 2.76k | FixedMemoryStream stream { data }; |
511 | | |
512 | | // Table A.22 – Coding style component parameter values |
513 | 2.76k | CodingStyleComponent coc; |
514 | 2.76k | if (number_of_components < 257) |
515 | 2.70k | coc.component_index = TRY(stream.read_value<u8>()); |
516 | 59 | else |
517 | 59 | coc.component_index = TRY(stream.read_value<BigEndian<u16>>()); |
518 | | |
519 | 2.76k | u8 Scoc = TRY(stream.read_value<u8>()); |
520 | 0 | coc.has_explicit_precinct_size = Scoc & 1; |
521 | | |
522 | 2.76k | dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: COC marker segment: component_index={}", coc.component_index); |
523 | 2.76k | coc.parameters = TRY(read_coding_style_parameters(data.slice(TRY(stream.tell())), "COC"sv, coc.has_explicit_precinct_size)); |
524 | | |
525 | 0 | return coc; |
526 | 2.76k | } |
527 | | |
528 | | // A.6.4 Quantization default (QCD) |
529 | | struct QuantizationDefault { |
530 | | enum QuantizationStyle { |
531 | | NoQuantization = 0, |
532 | | ScalarDerived = 1, |
533 | | ScalarExpounded = 2, |
534 | | }; |
535 | | QuantizationStyle quantization_style { NoQuantization }; |
536 | | u8 number_of_guard_bits { 0 }; |
537 | | |
538 | | struct ReversibleStepSize { |
539 | | u8 exponent { 0 }; |
540 | | }; |
541 | | struct IrreversibleStepSize { |
542 | | u16 mantissa { 0 }; |
543 | | u8 exponent { 0 }; |
544 | | }; |
545 | | |
546 | | // Stores a Vector<ReversibleStepSize> if quantization_style is NoQuantization, and a Vector<IrreversibleStepSize> otherwise. |
547 | | // The size of the vector is >= 3*number_of_decomposition_levels + 1 if quantization_style is not ScalarDerived, and 1 otherwise. |
548 | | using StepSizeType = Variant<Empty, Vector<ReversibleStepSize>, Vector<IrreversibleStepSize>>; |
549 | | StepSizeType step_sizes; |
550 | | }; |
551 | | |
552 | | static ErrorOr<QuantizationDefault> read_quantization_default(ReadonlyBytes data, StringView marker_name = "QCD"sv) |
553 | 44.0k | { |
554 | 44.0k | FixedMemoryStream stream { data }; |
555 | | |
556 | 44.0k | QuantizationDefault qcd; |
557 | | |
558 | 44.0k | u8 sqcd = TRY(stream.read_value<u8>()); |
559 | 0 | u8 quantization_style = sqcd & 0x1F; |
560 | 43.9k | if (quantization_style > 2) |
561 | 14 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Invalid quantization style"); |
562 | 43.9k | qcd.quantization_style = static_cast<QuantizationDefault::QuantizationStyle>(quantization_style); |
563 | 43.9k | qcd.number_of_guard_bits = sqcd >> 5; |
564 | | |
565 | 43.9k | qcd.step_sizes = TRY([&]() -> ErrorOr<QuantizationDefault::StepSizeType> { |
566 | 43.9k | if (quantization_style == QuantizationDefault::NoQuantization) { |
567 | | // Table A.29 – Reversible step size values for the SPqcd and SPqcc parameters (reversible transform only) |
568 | 43.9k | if (data.size() < 2) |
569 | 43.9k | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Not enough data for QCD marker segment"); |
570 | 43.9k | u8 number_of_decomposition_levels = (data.size() - 2) / 3; |
571 | | |
572 | 43.9k | Vector<QuantizationDefault::ReversibleStepSize> reversible_step_sizes; |
573 | 43.9k | for (size_t i = 0; i < 1u + 3u * number_of_decomposition_levels; ++i) |
574 | 43.9k | reversible_step_sizes.append({ static_cast<u8>(TRY(stream.read_value<u8>()) >> 3) }); |
575 | 43.9k | return reversible_step_sizes; |
576 | 43.9k | } |
577 | | |
578 | | // Table A.30 – Quantization values for the SPqcd and SPqcc parameters (irreversible transformation only) |
579 | 43.9k | if (data.size() < 3) |
580 | 43.9k | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Not enough data for QCD marker segment"); |
581 | 43.9k | u8 number_of_decomposition_levels = 0; |
582 | 43.9k | if (quantization_style == QuantizationDefault::ScalarExpounded) |
583 | 43.9k | number_of_decomposition_levels = (data.size() - 3) / 6; |
584 | | |
585 | 43.9k | Vector<QuantizationDefault::IrreversibleStepSize> irreversible_step_sizes; |
586 | 43.9k | for (size_t i = 0; i < 1u + 3u * number_of_decomposition_levels; ++i) { |
587 | 43.9k | u16 value = TRY(stream.read_value<BigEndian<u16>>()); |
588 | 43.9k | QuantizationDefault::IrreversibleStepSize step_size; |
589 | 43.9k | step_size.mantissa = value & 0x7FF; |
590 | 43.9k | step_size.exponent = value >> 11; |
591 | 43.9k | irreversible_step_sizes.append(step_size); |
592 | 43.9k | } |
593 | 43.9k | return irreversible_step_sizes; |
594 | 43.9k | }()); |
595 | | |
596 | 43.9k | dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: {} marker segment: quantization_style={}, number_of_guard_bits={}", marker_name, (int)qcd.quantization_style, qcd.number_of_guard_bits); |
597 | 43.9k | qcd.step_sizes.visit( |
598 | 43.9k | [](Empty) { VERIFY_NOT_REACHED(); }, |
599 | 43.9k | [&](Vector<QuantizationDefault::ReversibleStepSize> const& step_sizes) { |
600 | 18.6k | dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: {} marker segment: {} step sizes:", marker_name, step_sizes.size()); |
601 | 404k | for (auto [i, step_size] : enumerate(step_sizes)) { |
602 | 404k | dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: {} marker segment: step_size[{}]: exponent={}", marker_name, i, step_size.exponent); |
603 | 404k | } |
604 | 18.6k | }, |
605 | 43.9k | [&](Vector<QuantizationDefault::IrreversibleStepSize> const& step_sizes) { |
606 | 25.3k | dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: {} marker segment: {} step sizes:", marker_name, step_sizes.size()); |
607 | 108k | for (auto [i, step_size] : enumerate(step_sizes)) { |
608 | 108k | dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: {} marker segment: step_size[{}]: mantissa={}, exponent={}", marker_name, i, step_size.mantissa, step_size.exponent); |
609 | 108k | } |
610 | 25.3k | }); |
611 | | |
612 | 43.9k | return qcd; |
613 | 43.9k | } |
614 | | |
615 | | // A.6.5 Quantization component (QCC) |
616 | | struct QuantizationComponent { |
617 | | u16 component_index { 0 }; // "Cqcc" in spec. |
618 | | QuantizationDefault qcd; |
619 | | }; |
620 | | |
621 | | static ErrorOr<QuantizationComponent> read_quantization_component(ReadonlyBytes data, size_t number_of_components) |
622 | 42.8k | { |
623 | 42.8k | FixedMemoryStream stream { data }; |
624 | | |
625 | 42.8k | QuantizationComponent qcc; |
626 | 42.8k | if (number_of_components < 257) |
627 | 42.8k | qcc.component_index = TRY(stream.read_value<u8>()); |
628 | 7 | else |
629 | 7 | qcc.component_index = TRY(stream.read_value<BigEndian<u16>>()); |
630 | | |
631 | 42.8k | dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: QCC marker segment: component_index={}", qcc.component_index); |
632 | 42.8k | qcc.qcd = TRY(read_quantization_default(data.slice(TRY(stream.tell())), "QCC"sv)); |
633 | | |
634 | 0 | return qcc; |
635 | 42.8k | } |
636 | | |
637 | | // A.9.2 Comment (COM) |
638 | | struct Comment { |
639 | | enum CommentType { |
640 | | Binary = 0, |
641 | | ISO_IEC_8859_15 = 1, |
642 | | }; |
643 | | CommentType type { Binary }; // "Rcom" in spec. |
644 | | ReadonlyBytes data; |
645 | | }; |
646 | | |
647 | | static ErrorOr<Comment> read_comment(ReadonlyBytes data) |
648 | 17.2k | { |
649 | 17.2k | FixedMemoryStream stream { data }; |
650 | | |
651 | 17.2k | Comment com; |
652 | 17.2k | u16 comment_type = TRY(stream.read_value<BigEndian<u16>>()); |
653 | 17.2k | if (comment_type > 1) |
654 | 8 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Invalid comment type"); |
655 | 17.1k | com.type = static_cast<Comment::CommentType>(comment_type); |
656 | 17.1k | com.data = data.slice(TRY(stream.tell())); |
657 | | |
658 | 17.1k | dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: COM marker segment: comment_type={}, size()={}", (int)com.type, com.data.size()); |
659 | 17.1k | if (com.type == Comment::ISO_IEC_8859_15) |
660 | 16.6k | dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: COM marker segment, ISO/IEC 8859-15 text: '{}'", TRY(TextCodec::decoder_for("ISO-8859-15"sv)->to_utf8(StringView { com.data }))); |
661 | | |
662 | 17.1k | return com; |
663 | 17.1k | } |
664 | | |
665 | | struct TilePartData { |
666 | | StartOfTilePart sot; |
667 | | Vector<Comment> coms; |
668 | | ReadonlyBytes data; |
669 | | }; |
670 | | |
671 | | struct DecodedCodeBlock { |
672 | | IntRect rect; // Confined to sub-band rect. |
673 | | |
674 | | // Transient state used to read packet headers. |
675 | | |
676 | | // B.10.4 Code-block inclusion |
677 | | bool is_included { false }; |
678 | | |
679 | | // B.10.7.1 Single codeword segment |
680 | | // "Lblock is a code-block state variable. [...] The value of Lblock is initially set to three." |
681 | | u32 Lblock { 3 }; |
682 | | |
683 | | // Becomes true when the first packet including this codeblock is read. |
684 | | bool has_been_included_in_previous_packet { false }; |
685 | | |
686 | | // Data read from packet headers. |
687 | | |
688 | | // B.10.5 Zero bit-plane information |
689 | | // "the number of missing most significant bit-planes, P, may vary from code-block to code-block; |
690 | | // these missing bit-planes are all taken to be zero." |
691 | | u32 p { 0 }; |
692 | | |
693 | | struct Layer { |
694 | | struct Segment { |
695 | | ReadonlyBytes data; |
696 | | u32 index { 0 }; |
697 | | int number_of_passes { 0 }; |
698 | | }; |
699 | | Vector<Segment, 1> segments; |
700 | | }; |
701 | | Vector<Layer, 1> layers; |
702 | | |
703 | | u32 number_of_coding_passes() const |
704 | 43.4k | { |
705 | 43.4k | u32 total = 0; |
706 | 43.4k | for (auto const& layer : layers) |
707 | 32.1k | for (auto const& segment : layer.segments) |
708 | 20.5k | total += segment.number_of_passes; |
709 | 43.4k | return total; |
710 | 43.4k | } |
711 | | |
712 | | u32 number_of_coding_passes_in_segment(u32 segment_index) const |
713 | 0 | { |
714 | 0 | u32 total = 0; |
715 | 0 | for (auto const& layer : layers) { |
716 | 0 | for (auto const& segment : layer.segments) { |
717 | 0 | if (segment.index == segment_index) |
718 | 0 | total += segment.number_of_passes; |
719 | 0 | } |
720 | 0 | } |
721 | 0 | return total; |
722 | 0 | } |
723 | | |
724 | | Optional<u32> highest_segment_index() const |
725 | 24.3k | { |
726 | 24.3k | Optional<u32> highest_index; |
727 | 25.2k | for (auto const& layer : layers) { |
728 | 25.2k | for (auto const& segment : layer.segments) |
729 | 16.5k | highest_index = max(highest_index.value_or(segment.index), segment.index); |
730 | 25.2k | } |
731 | 24.3k | return highest_index; |
732 | 24.3k | } |
733 | | |
734 | | ErrorOr<Vector<ReadonlyBytes, 1>> segments_for_all_layers(ByteBuffer& maybe_storage) const |
735 | 24.3k | { |
736 | 24.3k | Vector<Vector<ReadonlyBytes, 1>, 1> all_segment_parts_for_segment; |
737 | 24.3k | all_segment_parts_for_segment.resize(highest_segment_index().value_or(0) + 1); |
738 | | |
739 | 24.3k | for (auto const& layer : layers) |
740 | 25.2k | for (auto const& segment : layer.segments) |
741 | 16.5k | TRY(all_segment_parts_for_segment[segment.index].try_append(segment.data)); |
742 | | |
743 | | // Copy segments with multiple parts into consecutive storage. |
744 | 24.3k | size_t total_scratch_size = 0; |
745 | 24.9k | for (auto const& segment_parts : all_segment_parts_for_segment) { |
746 | 24.9k | if (segment_parts.size() > 1) { |
747 | 70 | for (auto const& segment_part : segment_parts) |
748 | 748 | total_scratch_size += segment_part.size(); |
749 | 70 | } |
750 | 24.9k | } |
751 | | |
752 | 24.3k | if (total_scratch_size > 0) |
753 | 70 | maybe_storage = TRY(ByteBuffer::create_uninitialized(total_scratch_size)); |
754 | | |
755 | 24.3k | Vector<ReadonlyBytes, 1> all_segments; |
756 | 24.3k | size_t scratch_offset = 0; |
757 | 24.9k | for (auto& segment_parts : all_segment_parts_for_segment) { |
758 | 24.9k | if (segment_parts.size() == 1) { |
759 | 15.8k | TRY(all_segments.try_append(segment_parts[0])); |
760 | 0 | continue; |
761 | 15.8k | } |
762 | | |
763 | 9.08k | auto start = scratch_offset; |
764 | 9.08k | for (auto const& segment_part : segment_parts) { |
765 | 748 | memcpy(maybe_storage.offset_pointer(scratch_offset), segment_part.data(), segment_part.size()); |
766 | 748 | scratch_offset += segment_part.size(); |
767 | 748 | } |
768 | 9.08k | TRY(all_segments.try_append(maybe_storage.bytes().slice(start, scratch_offset - start))); |
769 | 9.08k | } |
770 | 24.3k | return all_segments; |
771 | 24.3k | } |
772 | | }; |
773 | | |
774 | | struct DecodedPrecinct { |
775 | | IntRect rect; // NOT confined to sub-band rect. |
776 | | |
777 | | int num_code_blocks_wide { 0 }; |
778 | | int num_code_blocks_high { 0 }; |
779 | | Vector<DecodedCodeBlock> code_blocks; |
780 | | |
781 | | // Transient state used to read packet headers. |
782 | | Optional<JPEG2000::TagTree> code_block_inclusion_tree; |
783 | | Optional<JPEG2000::TagTree> p_tree; |
784 | | }; |
785 | | |
786 | | struct DecodedSubBand { |
787 | | IntRect rect; |
788 | | |
789 | | // These are the same for all three sub-bands at a given resolution level. |
790 | | int num_precincts_wide { 0 }; |
791 | | int num_precincts_high { 0 }; |
792 | | |
793 | | Vector<DecodedPrecinct> precincts; |
794 | | |
795 | | // Valid after bitplane decoding. rect.width() * rect.height() == coefficients.size(). |
796 | | Vector<float> coefficients; |
797 | | }; |
798 | | |
799 | | struct DecodedTileComponent { |
800 | | IntRect rect; |
801 | | DecodedSubBand nLL; // N_L LL in the spec, corresponds to resolution level 0. |
802 | | |
803 | | using DecodedSubBands = Array<DecodedSubBand, 3>; // Ordered HL, LH, HH. |
804 | | Vector<DecodedSubBands> decompositions; |
805 | | static constexpr Array SubBandOrder { JPEG2000::SubBand::HorizontalHighpassVerticalLowpass, JPEG2000::SubBand::HorizontalLowpassVerticalHighpass, JPEG2000::SubBand::HorizontalHighpassVerticalHighpass }; |
806 | | |
807 | | // Valid after IDWT. |
808 | | Vector<float> samples; |
809 | | }; |
810 | | |
811 | | struct TileData { |
812 | | // Data from codestream markers. |
813 | | Optional<CodingStyleDefault> cod; |
814 | | Vector<CodingStyleComponent> cocs; |
815 | | Optional<QuantizationDefault> qcd; |
816 | | Vector<QuantizationComponent> qccs; |
817 | | Vector<TilePartData> tile_parts; |
818 | | |
819 | | // Data used during decoding. |
820 | | IntRect rect; |
821 | | Vector<DecodedTileComponent> components; |
822 | | Vector<Vector<float>> channels; |
823 | | Vector<ImageAndTileSize::ComponentInformation> channel_information; |
824 | | |
825 | | // FIXME: This will have to move and be reorganized come POC support. |
826 | | OwnPtr<JPEG2000::ProgressionIterator> progression_iterator; |
827 | | }; |
828 | | |
829 | | enum class ColorSpace { |
830 | | sRGB, |
831 | | Gray, |
832 | | CMYK, |
833 | | Unsupported, |
834 | | }; |
835 | | |
836 | | struct JPEG2000LoadingContext { |
837 | | enum class State { |
838 | | NotDecoded = 0, |
839 | | DecodedImage, |
840 | | Error, |
841 | | }; |
842 | | State state { State::NotDecoded }; |
843 | | ReadonlyBytes codestream_data; |
844 | | size_t codestream_cursor { 0 }; |
845 | | JPEG2000DecoderOptions options; |
846 | | |
847 | | Optional<ISOBMFF::JPEG2000ColorSpecificationBox const&> color_box; // This is always set for box-based files. |
848 | | |
849 | | Optional<ISOBMFF::JPEG2000PaletteBox const&> palette_box; |
850 | | Optional<ISOBMFF::JPEG2000ComponentMappingBox const&> component_mapping_box; |
851 | | Optional<ISOBMFF::JPEG2000ChannelDefinitionBox const&> channel_definition_box; |
852 | | |
853 | | IntSize size; |
854 | | |
855 | | ISOBMFF::BoxList boxes; |
856 | | |
857 | | // Data from marker segments: |
858 | | ImageAndTileSize siz; |
859 | | CodingStyleDefault cod; |
860 | | Vector<CodingStyleComponent> cocs; |
861 | | QuantizationDefault qcd; |
862 | | Vector<QuantizationComponent> qccs; |
863 | | Vector<Comment> coms; |
864 | | Vector<TileData> tiles; |
865 | | |
866 | | // Valid after headers have been decoded. |
867 | | // The awkward `color_space_error` is so that determine_color_space() can always succeed and |
868 | | // e.g. `file` can return data for JPEG2000s even if we can't decode the image data due to not |
869 | | // yet supporting its colorspace. |
870 | | ColorSpace color_space { ColorSpace::Unsupported }; |
871 | | Optional<Error> color_space_error; |
872 | | |
873 | | // Valid once `state` is StateDecodedImage. |
874 | | RefPtr<Bitmap> bitmap; |
875 | | RefPtr<CMYKBitmap> cmyk_bitmap; |
876 | | |
877 | | CodingStyleParameters const& coding_style_parameters_for_component(TileData const& tile, size_t component_index) const |
878 | 1.77M | { |
879 | | // Tile-part COC > Tile-part COD > Main COC > Main COD |
880 | 1.77M | for (auto const& coc : tile.cocs) { |
881 | 1.07k | if (coc.component_index == component_index) |
882 | 428 | return coc.parameters; |
883 | 1.07k | } |
884 | 1.77M | if (tile.cod.has_value()) |
885 | 0 | return tile.cod->parameters; |
886 | | |
887 | 1.77M | for (auto const& coc : cocs) { |
888 | 0 | if (coc.component_index == component_index) |
889 | 0 | return coc.parameters; |
890 | 0 | } |
891 | 1.77M | return cod.parameters; |
892 | 1.77M | } |
893 | | |
894 | | QuantizationDefault const& quantization_parameters_for_component(TileData const& tile, size_t component_index) |
895 | 30.7k | { |
896 | | // Tile-part QCC > Tile-part QCD > Main QCC > Main QCD |
897 | 30.7k | for (auto const& qcc : tile.qccs) { |
898 | 320 | if (qcc.component_index == component_index) |
899 | 128 | return qcc.qcd; |
900 | 320 | } |
901 | 30.6k | if (tile.qcd.has_value()) |
902 | 0 | return tile.qcd.value(); |
903 | | |
904 | 30.6k | for (auto const& qcc : qccs) { |
905 | 160 | if (qcc.component_index == component_index) |
906 | 64 | return qcc.qcd; |
907 | 160 | } |
908 | 30.5k | return qcd; |
909 | 30.6k | } |
910 | | |
911 | | ErrorOr<JPEG2000::ProgressionData> next_progression_data(TileData& tile) const |
912 | 8.00k | { |
913 | 8.00k | JPEG2000::ProgressionData progression_data; |
914 | | |
915 | 8.00k | auto progression_data_has_packet = [&](JPEG2000::ProgressionData const& progression_data) { |
916 | 7.96k | if (progression_data.resolution_level > coding_style_parameters_for_component(tile, progression_data.component).number_of_decomposition_levels) |
917 | 0 | return false; |
918 | | |
919 | | // "It can happen that numprecincts is 0 for a particular tile-component and resolution level. When this happens, there are no |
920 | | // packets for this tile-component and resolution level." |
921 | | // `num_precincts_wide` and `num_precincts_high` are the same for all sub-bands at a given resolution level, so it's |
922 | | // enough to only check the first. |
923 | 7.96k | auto& component = tile.components[progression_data.component]; |
924 | 7.96k | auto& sub_band_data = progression_data.resolution_level == 0 ? component.nLL : component.decompositions[progression_data.resolution_level - 1][0]; |
925 | 7.96k | if (sub_band_data.num_precincts_wide == 0 || sub_band_data.num_precincts_high == 0) |
926 | 35 | return false; |
927 | | |
928 | 7.92k | return true; |
929 | 7.96k | }; |
930 | | |
931 | 8.03k | do { |
932 | 8.03k | if (!tile.progression_iterator->has_next()) |
933 | 77 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: No more progression orders but packets left"); |
934 | 7.96k | progression_data = tile.progression_iterator->next(); |
935 | 7.96k | } while (!progression_data_has_packet(progression_data)); |
936 | | |
937 | 7.92k | return progression_data; |
938 | 8.00k | } |
939 | | }; |
940 | | |
941 | | struct MarkerSegment { |
942 | | u16 marker; |
943 | | |
944 | | // OptionalNone for markers that don't have data. |
945 | | // For markers that do have data, this does not include the marker length data. (`data.size() + 2` is the value of the marker length field.) |
946 | | Optional<ReadonlyBytes> data; |
947 | | }; |
948 | | |
949 | | static ErrorOr<u16> peek_marker(ReadonlyBytes data) |
950 | 148k | { |
951 | 148k | if (2 > data.size()) |
952 | 45 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Not enough data for marker"); |
953 | 148k | return *reinterpret_cast<BigEndian<u16> const*>(data.data()); |
954 | 148k | } |
955 | | |
956 | | static ErrorOr<u16> peek_marker(JPEG2000LoadingContext& context) |
957 | 147k | { |
958 | 147k | return peek_marker(context.codestream_data.slice(context.codestream_cursor)); |
959 | 147k | } |
960 | | |
961 | | static ErrorOr<MarkerSegment> read_marker_at_cursor(JPEG2000LoadingContext& context) |
962 | 72.2k | { |
963 | 72.2k | u16 marker = TRY(peek_marker(context)); |
964 | | // "All markers with the marker code between 0xFF30 and 0xFF3F have no marker segment parameters. They shall be skipped by the decoder." |
965 | | // "The SOC, SOD and EOC are delimiting markers not marker segments, and have no explicit length information or other parameters." |
966 | 72.2k | bool is_marker_segment = !(marker >= 0xFF30 && marker <= 0xFF3F) && marker != J2K_SOC && marker != J2K_SOD && marker != J2K_EOC; |
967 | | |
968 | 72.2k | MarkerSegment marker_segment; |
969 | 72.2k | marker_segment.marker = marker; |
970 | | |
971 | 72.2k | if (is_marker_segment) { |
972 | 71.1k | if (context.codestream_cursor + 4 > context.codestream_data.size()) |
973 | 52 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Not enough data for marker segment length"); |
974 | 71.0k | u16 marker_length = *reinterpret_cast<BigEndian<u16> const*>(context.codestream_data.data() + context.codestream_cursor + 2); |
975 | 71.0k | if (marker_length < 2) |
976 | 8 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Marker segment length too small"); |
977 | 71.0k | if (context.codestream_cursor + 2 + marker_length > context.codestream_data.size()) |
978 | 92 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Not enough data for marker segment data"); |
979 | 70.9k | marker_segment.data = ReadonlyBytes { context.codestream_data.data() + context.codestream_cursor + 4, marker_length - 2u }; |
980 | 70.9k | } |
981 | | |
982 | 72.1k | context.codestream_cursor += 2; |
983 | 72.1k | if (is_marker_segment) |
984 | 70.9k | context.codestream_cursor += 2 + marker_segment.data->size(); |
985 | | |
986 | 72.1k | return marker_segment; |
987 | 72.2k | } |
988 | | |
989 | | static ErrorOr<void> parse_codestream_main_header(JPEG2000LoadingContext& context) |
990 | 1.14k | { |
991 | | // Figure A.3 – Construction of the main header |
992 | | // "Required as the first marker" |
993 | 1.14k | auto marker = TRY(read_marker_at_cursor(context)); |
994 | 1.14k | if (marker.marker != J2K_SOC) |
995 | 2 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Expected SOC marker"); |
996 | | |
997 | | // "Required as the second marker segment" |
998 | 1.13k | marker = TRY(read_marker_at_cursor(context)); |
999 | 1.13k | if (marker.marker != J2K_SIZ) |
1000 | 5 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Expected SIZ marker"); |
1001 | 1.13k | context.siz = TRY(read_image_and_tile_size(marker.data.value())); |
1002 | | |
1003 | 0 | bool saw_COD_marker = false; |
1004 | 1.10k | bool saw_QCD_marker = false; |
1005 | 17.0k | while (true) { |
1006 | 17.0k | u16 marker = TRY(peek_marker(context)); |
1007 | 0 | switch (marker) { |
1008 | 1.01k | case J2K_COD: |
1009 | 2.12k | case J2K_COC: |
1010 | 3.11k | case J2K_QCD: |
1011 | 12.0k | case J2K_QCC: |
1012 | 12.0k | case J2K_RGN: |
1013 | 12.0k | case J2K_POC: |
1014 | 12.0k | case J2K_PPM: |
1015 | 12.1k | case J2K_TLM: |
1016 | 12.1k | case J2K_PLM: |
1017 | 12.1k | case J2K_CRG: |
1018 | 16.0k | case J2K_COM: { |
1019 | 16.0k | auto marker = TRY(read_marker_at_cursor(context)); |
1020 | 16.0k | if (marker.marker == J2K_COD) { |
1021 | 1.01k | if (saw_COD_marker) |
1022 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Multiple COD markers in main header"); |
1023 | 1.01k | context.cod = TRY(read_coding_style_default(marker.data.value())); |
1024 | 0 | saw_COD_marker = true; |
1025 | 15.0k | } else if (marker.marker == J2K_COC) { |
1026 | 1.09k | context.cocs.append(TRY(read_coding_style_component(marker.data.value(), context.siz.components.size()))); |
1027 | 13.9k | } else if (marker.marker == J2K_QCD) { |
1028 | 982 | if (saw_QCD_marker) |
1029 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Multiple QCD markers in main header"); |
1030 | 982 | context.qcd = TRY(read_quantization_default(marker.data.value())); |
1031 | 0 | saw_QCD_marker = true; |
1032 | 12.9k | } else if (marker.marker == J2K_QCC) { |
1033 | 8.94k | context.qccs.append(TRY(read_quantization_component(marker.data.value(), context.siz.components.size()))); |
1034 | 8.93k | } else if (marker.marker == J2K_COM) { |
1035 | 3.91k | context.coms.append(TRY(read_comment(marker.data.value()))); |
1036 | 3.91k | } else if (marker.marker == J2K_TLM) { |
1037 | | // TLM describes tile-part lengths, for random access. They can be ignored for now. |
1038 | 64 | } else if (marker.marker == J2K_PLM) { |
1039 | | // PLM describes packet lengths, for random access. They can be ignored for now. |
1040 | 4 | } else { |
1041 | | // FIXME: These are valid main header markers. Parse contents. |
1042 | 1 | dbgln("JPEG2000ImageDecoderPlugin: marker {:#04x} not yet implemented", marker.marker); |
1043 | 1 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: marker not yet implemented"); |
1044 | 1 | } |
1045 | 15.9k | break; |
1046 | 16.0k | } |
1047 | 15.9k | case J2K_SOT: { |
1048 | | // SOT terminates the main header. |
1049 | | // A.4.2: "There shall be at least one SOT in a codestream." |
1050 | 888 | if (!saw_COD_marker) |
1051 | 2 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Required COD marker not present in main header"); |
1052 | 886 | if (!saw_QCD_marker) |
1053 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Required QCD marker not present in main header"); |
1054 | | |
1055 | | // A.6.4: "there is not necessarily a correspondence with the number of sub-bands present because the sub-bands |
1056 | | // can be truncated with no requirement to correct [the QCD] marker segment." |
1057 | 886 | size_t step_sizes_count = context.qcd.step_sizes.visit( |
1058 | 886 | [](Empty) -> size_t { VERIFY_NOT_REACHED(); }, |
1059 | 886 | [](Vector<QuantizationDefault::ReversibleStepSize> const& step_sizes) { return step_sizes.size(); }, |
1060 | 886 | [](Vector<QuantizationDefault::IrreversibleStepSize> const& step_sizes) { return step_sizes.size(); }); |
1061 | | // FIXME: What if number_of_decomposition_levels is in context.cocs and varies by component? |
1062 | 886 | if (context.qcd.quantization_style != QuantizationDefault::ScalarDerived && step_sizes_count < context.cod.parameters.number_of_decomposition_levels * 3u + 1u) |
1063 | 1 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Not enough step sizes for number of decomposition levels"); |
1064 | | |
1065 | 885 | return {}; |
1066 | 886 | } |
1067 | 101 | default: |
1068 | 101 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Unexpected marker in main header"); |
1069 | 17.0k | } |
1070 | 17.0k | } |
1071 | 1.10k | } |
1072 | | |
1073 | | static ErrorOr<void> parse_codestream_tile_header(JPEG2000LoadingContext& context) |
1074 | 4.30k | { |
1075 | | // Figure A.4 – Construction of the first tile-part header of a given tile |
1076 | | // Figure A.5 – Construction of a non-first tile-part header |
1077 | | |
1078 | | // "Required as the first marker segment of every tile-part header" |
1079 | 4.30k | auto tile_start = context.codestream_cursor; |
1080 | 4.30k | auto marker = TRY(read_marker_at_cursor(context)); |
1081 | 4.23k | if (marker.marker != J2K_SOT) |
1082 | 22 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Expected SOT marker"); |
1083 | 4.21k | auto start_of_tile = TRY(read_start_of_tile_part(marker.data.value())); |
1084 | | // FIXME: Store start_of_tile on context somewhere. |
1085 | | |
1086 | 0 | context.tiles.resize(max(context.tiles.size(), (size_t)start_of_tile.tile_index + 1)); |
1087 | 4.21k | auto& tile = context.tiles[start_of_tile.tile_index]; |
1088 | | |
1089 | 4.21k | if (tile.tile_parts.size() != start_of_tile.tile_part_index) |
1090 | 17 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Tile part index out of order"); |
1091 | 4.19k | tile.tile_parts.append({}); |
1092 | 4.19k | auto& tile_part = tile.tile_parts.last(); |
1093 | 4.19k | tile_part.sot = start_of_tile; |
1094 | | |
1095 | 4.19k | bool found_start_of_data = false; |
1096 | 57.7k | while (!found_start_of_data) { |
1097 | 53.7k | u16 marker = TRY(peek_marker(context)); |
1098 | 0 | switch (marker) { |
1099 | 4.02k | case J2K_SOD: |
1100 | | // "Required as the last marker segment of every tile-part header" |
1101 | 4.02k | context.codestream_cursor += 2; |
1102 | 4.02k | found_start_of_data = true; |
1103 | 4.02k | break; |
1104 | 9 | case J2K_COD: |
1105 | 1.69k | case J2K_COC: |
1106 | 1.82k | case J2K_QCD: |
1107 | 35.7k | case J2K_QCC: |
1108 | 35.7k | case J2K_RGN: |
1109 | 35.7k | if (start_of_tile.tile_part_index != 0) |
1110 | 1 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: COD, COC, QCD, QCC, RGN markers are only valid in the first tile-part header"); |
1111 | 35.7k | [[fallthrough]]; |
1112 | 35.7k | case J2K_POC: |
1113 | 35.7k | case J2K_PPT: |
1114 | 36.3k | case J2K_PLT: |
1115 | 49.6k | case J2K_COM: { |
1116 | 49.6k | auto marker = TRY(read_marker_at_cursor(context)); |
1117 | 49.5k | if (marker.marker == J2K_COD) { |
1118 | 8 | if (tile.cod.has_value()) |
1119 | 1 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Multiple COD markers in tile header"); |
1120 | 7 | tile.cod = TRY(read_coding_style_default(marker.data.value())); |
1121 | 49.5k | } else if (marker.marker == J2K_COC) { |
1122 | 1.67k | tile.cocs.append(TRY(read_coding_style_component(marker.data.value(), context.siz.components.size()))); |
1123 | 47.9k | } else if (marker.marker == J2K_QCD) { |
1124 | 137 | if (tile.qcd.has_value()) |
1125 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Multiple QCD markers in tile header"); |
1126 | 137 | tile.qcd = TRY(read_quantization_default(marker.data.value())); |
1127 | 47.7k | } else if (marker.marker == J2K_QCC) { |
1128 | 33.9k | tile.qccs.append(TRY(read_quantization_component(marker.data.value(), context.siz.components.size()))); |
1129 | 33.9k | } else if (marker.marker == J2K_COM) { |
1130 | 13.2k | tile_part.coms.append(TRY(read_comment(marker.data.value()))); |
1131 | 13.2k | } else if (marker.marker == J2K_PLT) { |
1132 | | // PLT describes packet lengths, for random access. They can be ignored for now. |
1133 | 547 | } else { |
1134 | | // FIXME: These are valid main header markers. Parse contents. |
1135 | 2 | dbgln("JPEG2000ImageDecoderPlugin: marker {:#04x} not yet implemented in tile header", marker.marker); |
1136 | 2 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: marker not yet implemented in tile header"); |
1137 | 2 | } |
1138 | 49.5k | break; |
1139 | 49.5k | } |
1140 | 49.5k | default: |
1141 | 98 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Unexpected marker in tile header"); |
1142 | 53.7k | } |
1143 | 53.7k | } |
1144 | | |
1145 | 4.02k | u32 tile_bitstream_length; |
1146 | 4.02k | if (start_of_tile.tile_part_length == 0) { |
1147 | | // Leave room for EOC marker. |
1148 | 73 | if (context.codestream_data.size() - context.codestream_cursor < 2) |
1149 | 1 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Not enough data for EOC marker"); |
1150 | 72 | tile_bitstream_length = context.codestream_data.size() - context.codestream_cursor - 2; |
1151 | 3.95k | } else { |
1152 | 3.95k | u32 tile_header_length = context.codestream_cursor - tile_start; |
1153 | 3.95k | if (start_of_tile.tile_part_length < tile_header_length) |
1154 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Invalid tile part length"); |
1155 | 3.95k | tile_bitstream_length = start_of_tile.tile_part_length - tile_header_length; |
1156 | 3.95k | } |
1157 | | |
1158 | 4.02k | if (context.codestream_cursor + tile_bitstream_length > context.codestream_data.size()) |
1159 | 62 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Not enough data for tile bitstream"); |
1160 | 3.96k | tile_part.data = context.codestream_data.slice(context.codestream_cursor, tile_bitstream_length); |
1161 | | |
1162 | 3.96k | context.codestream_cursor += tile_bitstream_length; |
1163 | 3.96k | dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: Tile bitstream length: {}", tile_bitstream_length); |
1164 | | |
1165 | 3.96k | return {}; |
1166 | 4.02k | } |
1167 | | |
1168 | | static ErrorOr<void> parse_codestream_tile_headers(JPEG2000LoadingContext& context) |
1169 | 882 | { |
1170 | 4.84k | while (true) { |
1171 | 4.84k | auto marker = TRY(peek_marker(context)); |
1172 | 4.84k | if (marker == J2K_EOC) { |
1173 | 542 | context.codestream_cursor += 2; |
1174 | 542 | break; |
1175 | 542 | } |
1176 | 8.26k | TRY(parse_codestream_tile_header(context)); |
1177 | 8.26k | } |
1178 | | |
1179 | 542 | if (context.codestream_cursor < context.codestream_data.size()) |
1180 | 13 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Unexpected data after EOC marker"); |
1181 | 529 | return {}; |
1182 | 542 | } |
1183 | | |
1184 | | static ErrorOr<void> decode_jpeg2000_header(JPEG2000LoadingContext& context, ReadonlyBytes data) |
1185 | 2.05k | { |
1186 | 2.05k | if (!JPEG2000ImageDecoderPlugin::sniff(data)) |
1187 | 3 | return Error::from_string_literal("JPEG2000LoadingContext: Invalid JPEG2000 header"); |
1188 | | |
1189 | 2.05k | if (data.starts_with(marker_id_string)) { |
1190 | 1.00k | context.codestream_data = data; |
1191 | 1.00k | TRY(parse_codestream_main_header(context)); |
1192 | 0 | context.size = { context.siz.width, context.siz.height }; |
1193 | 759 | return {}; |
1194 | 1.00k | } |
1195 | | |
1196 | 2.10k | auto reader = TRY(Gfx::ISOBMFF::Reader::create(TRY(try_make<FixedMemoryStream>(data)))); |
1197 | 1.05k | context.boxes = TRY(reader.read_entire_file()); |
1198 | | |
1199 | 550 | dbgln_if(JPEG2000_DEBUG, "Embedded ISOBMFF boxes:"); |
1200 | | if constexpr (JPEG2000_DEBUG) { |
1201 | | for (auto& box : context.boxes) |
1202 | | box->dump(); |
1203 | | } |
1204 | | |
1205 | | // I.2.2 File organization |
1206 | | // "A particular order of those boxes in the file is not generally implied. However, the JPEG 2000 Signature box |
1207 | | // shall be the first box in a JP2 file, the File Type box shall immediately follow the JPEG 2000 Signature box |
1208 | | // and the JP2 Header box shall fall before the Contiguous Codestream box." |
1209 | 550 | if (context.boxes.size() < 4) |
1210 | 193 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Expected at least four boxes"); |
1211 | | |
1212 | | // Required toplevel boxes: signature box, file type box, jp2 header box, contiguous codestream box. |
1213 | | |
1214 | 357 | if (context.boxes[0]->box_type() != ISOBMFF::BoxType::JPEG2000SignatureBox) |
1215 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Expected JPEG2000SignatureBox as first box"); |
1216 | 357 | if (context.boxes[1]->box_type() != ISOBMFF::BoxType::FileTypeBox) |
1217 | 80 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Expected FileTypeBox as second box"); |
1218 | | |
1219 | 277 | Optional<size_t> jp2_header_box_index; |
1220 | 277 | Optional<size_t> contiguous_codestream_box_index; |
1221 | 326k | for (size_t i = 2; i < context.boxes.size(); ++i) { |
1222 | 326k | if (context.boxes[i]->box_type() == ISOBMFF::BoxType::JPEG2000HeaderBox) { |
1223 | | // "Within a JP2 file, there shall be one and only one JP2 Header box." |
1224 | 255 | if (jp2_header_box_index.has_value()) |
1225 | 8 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Multiple JP2 Header boxes"); |
1226 | 247 | jp2_header_box_index = i; |
1227 | 247 | } |
1228 | 326k | if (context.boxes[i]->box_type() == ISOBMFF::BoxType::JPEG2000ContiguousCodestreamBox && !contiguous_codestream_box_index.has_value()) { |
1229 | | // "a conforming reader shall ignore all codestreams after the first codestream found in the file. |
1230 | | // Contiguous Codestream boxes may be found anywhere in the file except before the JP2 Header box." |
1231 | 244 | contiguous_codestream_box_index = i; |
1232 | 244 | if (!jp2_header_box_index.has_value() || contiguous_codestream_box_index.value() < jp2_header_box_index.value()) |
1233 | 3 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: JP2 Header box must come before Contiguous Codestream box"); |
1234 | 244 | } |
1235 | 326k | } |
1236 | | |
1237 | 266 | if (!jp2_header_box_index.has_value()) |
1238 | 27 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Expected JP2 Header box"); |
1239 | 239 | if (!contiguous_codestream_box_index.has_value()) |
1240 | 3 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Expected Contiguous Codestream box"); |
1241 | | |
1242 | | // FIXME: JPEG2000ContiguousCodestreamBox makes a copy of the codestream data. That's too heavy for header scanning. |
1243 | | // Add a mode to ISOBMFF::Reader where it only stores offsets for the codestream data and the ICC profile. |
1244 | 236 | auto const& codestream_box = static_cast<ISOBMFF::JPEG2000ContiguousCodestreamBox const&>(*context.boxes[contiguous_codestream_box_index.value()]); |
1245 | 236 | context.codestream_data = codestream_box.codestream.bytes(); |
1246 | | |
1247 | | // Required child boxes of the jp2 header box: image header box, color box. |
1248 | | |
1249 | 236 | Optional<size_t> image_header_box_index; |
1250 | 236 | Optional<size_t> color_header_box_index; |
1251 | 236 | Optional<size_t> palette_box_index; |
1252 | 236 | Optional<size_t> component_mapping_box_index; |
1253 | 236 | Optional<size_t> channel_definition_box_index; |
1254 | 236 | auto const& header_box = static_cast<ISOBMFF::JPEG2000HeaderBox const&>(*context.boxes[jp2_header_box_index.value()]); |
1255 | 2.34k | for (size_t i = 0; i < header_box.child_boxes().size(); ++i) { |
1256 | 2.11k | auto const& subbox = header_box.child_boxes()[i]; |
1257 | 2.11k | if (subbox->box_type() == ISOBMFF::BoxType::JPEG2000ImageHeaderBox) { |
1258 | 147 | if (image_header_box_index.has_value()) |
1259 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Multiple Image Header boxes"); |
1260 | 147 | image_header_box_index = i; |
1261 | 147 | } |
1262 | 2.11k | if (subbox->box_type() == ISOBMFF::BoxType::JPEG2000ColorSpecificationBox) { |
1263 | | // T.800 says there should be just one 'colr' box, but T.801 allows several and says to pick the one with highest precedence. |
1264 | 674 | bool use_this_color_box; |
1265 | 674 | if (!color_header_box_index.has_value()) { |
1266 | 176 | use_this_color_box = true; |
1267 | 498 | } else { |
1268 | 498 | auto const& new_header_box = static_cast<ISOBMFF::JPEG2000ColorSpecificationBox const&>(*header_box.child_boxes()[i]); |
1269 | 498 | auto const& current_color_box = static_cast<ISOBMFF::JPEG2000ColorSpecificationBox const&>(*header_box.child_boxes()[color_header_box_index.value()]); |
1270 | 498 | use_this_color_box = new_header_box.precedence > current_color_box.precedence; |
1271 | 498 | } |
1272 | | |
1273 | 674 | if (use_this_color_box) |
1274 | 218 | color_header_box_index = i; |
1275 | 674 | } |
1276 | 2.11k | if (subbox->box_type() == ISOBMFF::BoxType::JPEG2000PaletteBox) { |
1277 | | // T.800, I.5.3.4 Palette box |
1278 | | // "There shall be at most one Palette box inside a JP2 Header box." |
1279 | 67 | if (palette_box_index.has_value()) |
1280 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Multiple Palette boxes"); |
1281 | 67 | palette_box_index = i; |
1282 | 67 | } |
1283 | 2.11k | if (subbox->box_type() == ISOBMFF::BoxType::JPEG2000ComponentMappingBox) { |
1284 | | // T.800, I.5.3.5 Component Mapping box |
1285 | | // "There shall be at most one Component Mapping box inside a JP2 Header box." |
1286 | 72 | if (component_mapping_box_index.has_value()) |
1287 | 1 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Multiple Component Mapping boxes"); |
1288 | 71 | component_mapping_box_index = i; |
1289 | 71 | } |
1290 | 2.11k | if (subbox->box_type() == ISOBMFF::BoxType::JPEG2000ChannelDefinitionBox) { |
1291 | | // T.800, I.5.3.6 Channel Definition box |
1292 | | // "There shall be at most one Channel Definition box inside a JP2 Header box." |
1293 | 51 | if (channel_definition_box_index.has_value()) |
1294 | 1 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Multiple Channel Definition boxes"); |
1295 | 50 | channel_definition_box_index = i; |
1296 | 50 | } |
1297 | 2.11k | } |
1298 | | |
1299 | 234 | if (!image_header_box_index.has_value()) |
1300 | 87 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Expected Image Header box"); |
1301 | 147 | if (!color_header_box_index.has_value()) |
1302 | 2 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Expected Color Specification box"); |
1303 | | |
1304 | 145 | auto const& image_header_box = static_cast<ISOBMFF::JPEG2000ImageHeaderBox const&>(*header_box.child_boxes()[image_header_box_index.value()]); |
1305 | 145 | context.size = { image_header_box.width, image_header_box.height }; |
1306 | | |
1307 | 145 | if (image_header_box.compression_type != ISOBMFF::JPEG2000ImageHeaderBox::CompressionType::Default) |
1308 | 4 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Decoding of non-jpeg2000 data embedded in jpeg2000 files is not implemented"); |
1309 | | |
1310 | 141 | context.color_box = static_cast<ISOBMFF::JPEG2000ColorSpecificationBox const&>(*header_box.child_boxes()[color_header_box_index.value()]); |
1311 | | |
1312 | | // "If the JP2 Header box contains a Palette box, then it shall also contain a Component Mapping box. |
1313 | | // If the JP2 Header box does not contain a Palette box, then it shall not contain a Component Mapping box." |
1314 | | // This is violated in practice though; some files have a Palette box without a Component Mapping box. |
1315 | | // So check for something weaker. |
1316 | 141 | if (!palette_box_index.has_value() && component_mapping_box_index.has_value()) |
1317 | 2 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Component Mapping should not be present without Palette box"); |
1318 | | |
1319 | 139 | if (palette_box_index.has_value()) |
1320 | 65 | context.palette_box = static_cast<ISOBMFF::JPEG2000PaletteBox const&>(*header_box.child_boxes()[palette_box_index.value()]); |
1321 | 139 | if (component_mapping_box_index.has_value()) |
1322 | 64 | context.component_mapping_box = static_cast<ISOBMFF::JPEG2000ComponentMappingBox const&>(*header_box.child_boxes()[component_mapping_box_index.value()]); |
1323 | 139 | if (channel_definition_box_index.has_value()) |
1324 | 47 | context.channel_definition_box = static_cast<ISOBMFF::JPEG2000ChannelDefinitionBox const&>(*header_box.child_boxes()[channel_definition_box_index.value()]); |
1325 | | |
1326 | 139 | TRY(parse_codestream_main_header(context)); |
1327 | | |
1328 | 0 | auto size_from_siz = IntSize { context.siz.width, context.siz.height }; |
1329 | 126 | if (size_from_siz != context.size) { |
1330 | | // FIXME: If this is common, warn and use size from SIZ marker. |
1331 | 3 | dbgln("JPEG2000ImageDecoderPlugin: Image size from SIZ marker ({}) does not match image size from JP2 header ({})", size_from_siz, context.size); |
1332 | 3 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Image size from SIZ marker does not match image size from JP2 header"); |
1333 | 3 | } |
1334 | | |
1335 | 123 | return {}; |
1336 | 126 | } |
1337 | | |
1338 | | static IntRect aligned_enclosing_rect(IntRect outer_rect, IntRect inner_rect, int width_increment, int height_increment) |
1339 | 30.9k | { |
1340 | 30.9k | int new_x = (inner_rect.x() / width_increment) * width_increment; |
1341 | 30.9k | int new_y = (inner_rect.y() / height_increment) * height_increment; |
1342 | 30.9k | int new_right = inner_rect.width() == 0 ? new_x : ceil_div(inner_rect.right(), width_increment) * width_increment; |
1343 | 30.9k | int new_bottom = inner_rect.height() == 0 ? new_y : ceil_div(inner_rect.bottom(), height_increment) * height_increment; |
1344 | 30.9k | return IntRect::intersection(outer_rect, IntRect::from_two_points({ new_x, new_y }, { new_right, new_bottom })); |
1345 | 30.9k | } |
1346 | | |
1347 | | static ErrorOr<void> compute_decoding_metadata(JPEG2000LoadingContext& context) |
1348 | 529 | { |
1349 | 30.9k | auto make_precinct = [&](DecodedSubBand const& sub_band, IntRect precinct_rect, int xcb_prime, int ycb_prime) -> ErrorOr<DecodedPrecinct> { |
1350 | 30.9k | auto rect_covered_by_codeblocks = aligned_enclosing_rect(precinct_rect, sub_band.rect, 1 << xcb_prime, 1 << ycb_prime); |
1351 | 30.9k | auto num_code_blocks_wide = rect_covered_by_codeblocks.width() / (1 << xcb_prime); |
1352 | 30.9k | auto num_code_blocks_high = rect_covered_by_codeblocks.height() / (1 << ycb_prime); |
1353 | | |
1354 | 30.9k | DecodedPrecinct precinct; |
1355 | 30.9k | precinct.rect = precinct_rect; |
1356 | 30.9k | precinct.num_code_blocks_wide = num_code_blocks_wide; |
1357 | 30.9k | precinct.num_code_blocks_high = num_code_blocks_high; |
1358 | 30.9k | precinct.code_blocks.resize(num_code_blocks_wide * num_code_blocks_high); |
1359 | | |
1360 | 30.9k | dbgln_if(JPEG2000_DEBUG, "Precinct rect: {}, num_code_blocks_wide: {}, num_code_blocks_high: {}", precinct.rect, num_code_blocks_wide, num_code_blocks_high); |
1361 | | |
1362 | 129k | for (auto [code_block_index, current_block] : enumerate(precinct.code_blocks)) { |
1363 | 129k | size_t code_block_x = code_block_index % num_code_blocks_wide; |
1364 | 129k | size_t code_block_y = code_block_index / num_code_blocks_wide; |
1365 | | |
1366 | 129k | auto code_block_rect = IntRect { { code_block_x * (1 << xcb_prime), code_block_y * (1 << ycb_prime) }, { 1 << xcb_prime, 1 << ycb_prime } }; |
1367 | 129k | code_block_rect.set_location(code_block_rect.location() + rect_covered_by_codeblocks.location()); |
1368 | | |
1369 | | // B.7 Division of the sub-bands into code-blocks |
1370 | | // "NOTE – Code-blocks in the partition may extend beyond the boundaries of the sub-band coefficients. When this happens, only the |
1371 | | // coefficients lying within the sub-band are coded using the method described in Annex D. The first stripe coded using this method |
1372 | | // corresponds to the first four rows of sub-band coefficients in the code-block or to as many such rows as are present." |
1373 | 129k | current_block.rect = code_block_rect.intersected(sub_band.rect); |
1374 | 129k | } |
1375 | | |
1376 | 30.9k | if (!precinct.code_blocks.is_empty()) { |
1377 | 30.2k | precinct.code_block_inclusion_tree = TRY(JPEG2000::TagTree::create(num_code_blocks_wide, num_code_blocks_high)); |
1378 | 30.2k | precinct.p_tree = TRY(JPEG2000::TagTree::create(num_code_blocks_wide, num_code_blocks_high)); |
1379 | 30.2k | } |
1380 | | |
1381 | 30.9k | return precinct; |
1382 | 30.9k | }; |
1383 | | |
1384 | 594k | auto make_sub_band = [&](TileData const& tile, int component_index, DecodedSubBand& sub_band, JPEG2000::SubBand sub_band_type, int r) -> ErrorOr<void> { |
1385 | 594k | auto const& coding_parameters = context.coding_style_parameters_for_component(tile, component_index); |
1386 | 594k | auto N_L = coding_parameters.number_of_decomposition_levels; |
1387 | | |
1388 | | // Table F.1 – Decomposition level nb for sub-band b |
1389 | | // Note: The spec suggests that this ends with n_b = 1, but if N_L is 0, we have 0LL and nothing else. |
1390 | 594k | auto n_b = [N_L](int r) { return r == 0 ? N_L : (N_L + 1 - r); }; |
1391 | | |
1392 | 594k | sub_band.rect = context.siz.reference_grid_coordinates_for_sub_band(tile.rect, component_index, n_b(r), sub_band_type); |
1393 | | |
1394 | | // Compute tile size at resolution level r. |
1395 | 594k | auto ll_rect = context.siz.reference_grid_coordinates_for_ll_band(tile.rect, component_index, r, N_L); |
1396 | | |
1397 | 594k | dbgln_if(JPEG2000_DEBUG, "Sub-band rect: {}, ll rect {}", sub_band.rect, ll_rect); |
1398 | | |
1399 | | // B.6 |
1400 | | // (B-16) |
1401 | 594k | int num_precincts_wide = 0; |
1402 | 594k | int num_precincts_high = 0; |
1403 | 594k | int PPx = coding_parameters.precinct_sizes[r].PPx; |
1404 | 594k | int PPy = coding_parameters.precinct_sizes[r].PPy; |
1405 | | |
1406 | 594k | if (ll_rect.width() != 0) |
1407 | 594k | num_precincts_wide = ceil_div(ll_rect.right(), 1 << PPx) - (ll_rect.left() / (1 << PPx)); |
1408 | 594k | if (ll_rect.height() != 0) |
1409 | 594k | num_precincts_high = ceil_div(ll_rect.bottom(), 1 << PPy) - (ll_rect.top() / (1 << PPy)); |
1410 | | |
1411 | 594k | sub_band.num_precincts_wide = num_precincts_wide; |
1412 | 594k | sub_band.num_precincts_high = num_precincts_high; |
1413 | | |
1414 | 594k | auto precinct_origin = IntPoint { ll_rect.x() & ~((1 << PPx) - 1), ll_rect.y() & ~((1 << PPy) - 1) }; |
1415 | | |
1416 | 594k | if (r > 0) { |
1417 | 21.0k | PPx--; |
1418 | 21.0k | PPy--; |
1419 | 21.0k | precinct_origin /= 2; |
1420 | 21.0k | } |
1421 | | |
1422 | | // B.7 |
1423 | | // (B-17) |
1424 | | // (The r > 0 check was done right above already.) |
1425 | 594k | int xcb_prime = min(coding_parameters.code_block_width_exponent, PPx); |
1426 | | |
1427 | | // (B-18) |
1428 | | // (The r > 0 check was done right above already.) |
1429 | 594k | int ycb_prime = min(coding_parameters.code_block_height_exponent, PPy); |
1430 | | |
1431 | 617k | for (int precinct_y_index = 0; precinct_y_index < num_precincts_high; ++precinct_y_index) { |
1432 | 53.9k | for (int precinct_x_index = 0; precinct_x_index < num_precincts_wide; ++precinct_x_index) { |
1433 | 30.9k | auto precinct_rect = IntRect({ precinct_x_index * (1 << PPx), precinct_y_index * (1 << PPy), 1 << PPx, 1 << PPy }); |
1434 | 30.9k | precinct_rect.set_location(precinct_rect.location() + precinct_origin); |
1435 | | |
1436 | 30.9k | sub_band.precincts.append(TRY(make_precinct(sub_band, precinct_rect, xcb_prime, ycb_prime))); |
1437 | 30.9k | } |
1438 | 22.9k | } |
1439 | | |
1440 | 594k | return {}; |
1441 | 594k | }; |
1442 | | |
1443 | 573k | auto make_component = [&](TileData const& tile, int component_index) -> ErrorOr<DecodedTileComponent> { |
1444 | 573k | DecodedTileComponent component; |
1445 | 573k | component.rect = context.siz.reference_grid_coordinates_for_tile_component(tile.rect, component_index); |
1446 | | |
1447 | 573k | dbgln_if(JPEG2000_DEBUG, "making nLL for component {}", component_index); |
1448 | 573k | TRY(make_sub_band(tile, component_index, component.nLL, JPEG2000::SubBand::HorizontalLowpassVerticalLowpass, 0)); |
1449 | | |
1450 | 0 | auto N_L = context.coding_style_parameters_for_component(tile, component_index).number_of_decomposition_levels; |
1451 | 580k | for (int resolution_level = 1; resolution_level <= N_L; ++resolution_level) { |
1452 | 7.03k | DecodedTileComponent::DecodedSubBands sub_bands; |
1453 | 21.0k | for (auto [sub_band_index, sub_band] : enumerate(DecodedTileComponent::SubBandOrder)) { |
1454 | 21.0k | dbgln_if(JPEG2000_DEBUG, "r {} making sub-band {} for component {}", resolution_level, (int)sub_band, component_index); |
1455 | 21.0k | TRY(make_sub_band(tile, component_index, sub_bands[sub_band_index], sub_band, resolution_level)); |
1456 | 21.0k | } |
1457 | 7.03k | component.decompositions.append(move(sub_bands)); |
1458 | 7.03k | } |
1459 | | |
1460 | 573k | return component; |
1461 | 573k | }; |
1462 | | |
1463 | 572k | auto make_tile = [&](size_t tile_index, TileData& tile) -> ErrorOr<void> { |
1464 | 572k | auto const& cod = tile.cod.value_or(context.cod); |
1465 | 572k | auto pq = context.siz.tile_2d_index_from_1d_index(tile_index); |
1466 | 572k | tile.rect = context.siz.reference_grid_coordinates_for_tile(pq); |
1467 | | |
1468 | 572k | dbgln_if(JPEG2000_DEBUG, "tile {} rect {}", tile_index, tile.rect); |
1469 | | |
1470 | 573k | for (auto [component_index, component] : enumerate(context.siz.components)) { |
1471 | 573k | VERIFY(component.bit_depth() >= 1); |
1472 | 573k | VERIFY(component.bit_depth() <= 38); |
1473 | 573k | if (component.horizontal_separation != 1) |
1474 | 17 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Horizontal separation not yet implemented"); |
1475 | 573k | if (component.vertical_separation != 1) |
1476 | 9 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Vertical separation not yet implemented"); |
1477 | 573k | tile.components.append(TRY(make_component(tile, component_index))); |
1478 | 573k | } |
1479 | | |
1480 | 572k | return {}; |
1481 | 572k | }; |
1482 | | |
1483 | 572k | auto make_progression_iterator = [&](JPEG2000LoadingContext const& context, TileData const& tile) -> ErrorOr<OwnPtr<JPEG2000::ProgressionIterator>> { |
1484 | 572k | auto number_of_layers = tile.cod.value_or(context.cod).number_of_layers; |
1485 | | |
1486 | 572k | int max_number_of_decomposition_levels = 0; |
1487 | 1.14M | for (size_t component_index = 0; component_index < context.siz.components.size(); ++component_index) |
1488 | 573k | max_number_of_decomposition_levels = max(max_number_of_decomposition_levels, context.coding_style_parameters_for_component(tile, component_index).number_of_decomposition_levels); |
1489 | | |
1490 | 580k | auto number_of_precincts_from_resolution_level_and_component = [&](int r, int component_index) { |
1491 | 580k | auto const& sub_band = r == 0 ? tile.components[component_index].nLL : tile.components[component_index].decompositions[r - 1][0]; |
1492 | 580k | return sub_band.num_precincts_wide * sub_band.num_precincts_high; |
1493 | 580k | }; |
1494 | | |
1495 | 572k | switch (tile.cod.value_or(context.cod).progression_order) { |
1496 | 741 | case CodingStyleDefault::ProgressionOrder::LayerResolutionComponentPosition: |
1497 | 741 | return make<JPEG2000::LayerResolutionLevelComponentPositionProgressionIterator>(number_of_layers, max_number_of_decomposition_levels, context.siz.components.size(), move(number_of_precincts_from_resolution_level_and_component)); |
1498 | 571k | case CodingStyleDefault::ResolutionLayerComponentPosition: |
1499 | 571k | return make<JPEG2000::ResolutionLevelLayerComponentPositionProgressionIterator>(number_of_layers, max_number_of_decomposition_levels, context.siz.components.size(), move(number_of_precincts_from_resolution_level_and_component)); |
1500 | 0 | case CodingStyleDefault::ResolutionPositionComponentLayer: |
1501 | 0 | return Error::from_string_literal("JPEG2000Loader: ResolutionPositionComponentLayer progression order not yet supported"); |
1502 | 0 | case CodingStyleDefault::PositionComponentResolutionLayer: |
1503 | 0 | return Error::from_string_literal("JPEG2000Loader: PositionComponentResolutionLayer progression order not yet supported"); |
1504 | 0 | case CodingStyleDefault::ComponentPositionResolutionLayer: |
1505 | 0 | return Error::from_string_literal("JPEG2000Loader: ComponentPositionResolutionLayer progression order not yet supported"); |
1506 | 572k | } |
1507 | 0 | VERIFY_NOT_REACHED(); |
1508 | 0 | }; |
1509 | | |
1510 | 572k | for (auto const& [tile_index, tile] : enumerate(context.tiles)) { |
1511 | 572k | TRY(make_tile(tile_index, tile)); |
1512 | 572k | tile.progression_iterator = TRY(make_progression_iterator(context, tile)); |
1513 | 572k | } |
1514 | | |
1515 | 503 | return {}; |
1516 | 529 | } |
1517 | | |
1518 | | static ErrorOr<u32> read_one_packet_header(JPEG2000LoadingContext& context, TileData& tile, ReadonlyBytes data) |
1519 | 8.00k | { |
1520 | 8.00k | auto progression_data = TRY(context.next_progression_data(tile)); |
1521 | | |
1522 | 0 | FixedMemoryStream stream { data }; |
1523 | | |
1524 | 7.92k | if (tile.cod.value_or(context.cod).may_use_SOP_marker && data.size() >= 2 && TRY(peek_marker(data)) == J2K_SOP) { |
1525 | | // A.8.1 Start of packet (SOP) |
1526 | | // "It may be used in the bit stream in front of every packet. It shall not be used unless indicated that it is |
1527 | | // allowed in the proper COD marker segment (see A.6.1). If PPM or PPT marker segments are used, then the SOP marker |
1528 | | // segment may appear immediately before the packet data in the bit stream. |
1529 | | // If SOP marker segments are allowed (by signalling in the COD marker segment, see A.6.1), each packet in any given tile- |
1530 | | // part may or may not be appended with an SOP marker segment." |
1531 | | // Just skip this data if it's there. |
1532 | | // FIMXE: Tweak once we add support for PPM and PPT. |
1533 | 51 | u16 marker = TRY(stream.read_value<BigEndian<u16>>()); |
1534 | 51 | u16 marker_length = TRY(stream.read_value<BigEndian<u16>>()); |
1535 | 51 | u16 packet_sequence_number = TRY(stream.read_value<BigEndian<u16>>()); |
1536 | 51 | VERIFY(marker == J2K_SOP); // Due to the peek_marker check above. |
1537 | 51 | if (marker_length != 4) |
1538 | 3 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Invalid SOP marker length"); |
1539 | 48 | (void)packet_sequence_number; // FIXME: Do something with this? |
1540 | 48 | } |
1541 | | |
1542 | 7.92k | BigEndianInputBitStream bitstream { MaybeOwned { stream } }; |
1543 | | |
1544 | | // B.9 Packets |
1545 | | // "All compressed image data representing a specific tile, layer, component, resolution level and precinct appears in the |
1546 | | // codestream in a contiguous segment called a packet. Packet data is aligned at 8-bit (one byte) boundaries." |
1547 | 7.92k | auto const& coding_parameters = context.coding_style_parameters_for_component(tile, progression_data.component); |
1548 | 7.92k | auto const r = progression_data.resolution_level; |
1549 | 7.92k | u32 const current_layer_index = progression_data.layer; |
1550 | | |
1551 | | // B.10 Packet header information coding |
1552 | | // "The packets have headers with the following information: |
1553 | | // - zero length packet; |
1554 | | // - code-block inclusion; |
1555 | | // - zero bit-plane information; |
1556 | | // - number of coding passes; |
1557 | | // - length of the code-block compressed image data from a given code-block." |
1558 | | |
1559 | | // B.10.1 Bit-stuffing routine |
1560 | | // "If the value of the byte is 0xFF, the next byte includes an extra zero bit stuffed into the MSB. Once all bits of the |
1561 | | // packet header have been assembled, the last byte is packed to the byte boundary and emitted." |
1562 | 7.92k | u8 last_full_byte { 0 }; |
1563 | 451k | Function<ErrorOr<bool>()> read_bit = [&bitstream, &last_full_byte]() -> ErrorOr<bool> { |
1564 | 451k | if (bitstream.is_aligned_to_byte_boundary()) { |
1565 | 60.4k | if (last_full_byte == 0xFF) { |
1566 | 283 | bool stuff_bit = TRY(bitstream.read_bit()); |
1567 | 283 | if (stuff_bit) |
1568 | 14 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Invalid bit-stuffing"); |
1569 | 283 | } |
1570 | 60.4k | last_full_byte = 0; |
1571 | 60.4k | } |
1572 | 451k | bool bit = TRY(bitstream.read_bit()); |
1573 | 0 | last_full_byte = (last_full_byte << 1) | bit; |
1574 | 451k | return bit; |
1575 | 451k | }; |
1576 | | |
1577 | | // The most useful section to understand the overall flow is B.10.8 Order of information within packet header, |
1578 | | // which has an example packet header bitstream, and the data layout: |
1579 | | // "bit for zero or non-zero length packet |
1580 | | // for each sub-band (LL or HL, LH and HH) |
1581 | | // for all code-blocks in this sub-band confined to the relevant precinct, in raster order |
1582 | | // code-block inclusion bits (if not previously included then tag tree, else one bit) |
1583 | | // if code-block included |
1584 | | // if first instance of code-block |
1585 | | // zero bit-planes information |
1586 | | // number of coding passes included |
1587 | | // increase of code-block length indicator (Lblock) |
1588 | | // for each codeword segment |
1589 | | // length of codeword segment" |
1590 | | // The below implements these steps. |
1591 | | |
1592 | | // "bit for zero or non-zero length packet" |
1593 | | // B.10.3 Zero length packet |
1594 | | // "The first bit in the packet header denotes whether the packet has a length of zero (empty packet). The value 0 indicates a |
1595 | | // zero length; no code-blocks are included in this case. The value 1 indicates a non-zero length; this case is considered |
1596 | | // exclusively hereinafter." |
1597 | 7.92k | bool is_non_zero = TRY(read_bit()); |
1598 | 0 | bool is_empty = !is_non_zero; |
1599 | 7.92k | if (is_empty) { |
1600 | 712 | VERIFY(last_full_byte != 0xFF); // Can't possibly have a stuffed bit here. |
1601 | 712 | return stream.offset(); |
1602 | 712 | } |
1603 | | |
1604 | | // " for each sub-band (LL or HL, LH and HH)" |
1605 | 7.21k | struct TemporaryCodeBlockData { |
1606 | 7.21k | struct Segment { |
1607 | 7.21k | u32 length { 0 }; |
1608 | 7.21k | u32 index { 0 }; |
1609 | 7.21k | int number_of_passes { 0 }; |
1610 | 7.21k | }; |
1611 | 7.21k | Vector<Segment, 1> codeword_segments; |
1612 | 7.21k | }; |
1613 | 7.21k | struct TemporarySubBandData { |
1614 | 7.21k | DecodedPrecinct* precinct { nullptr }; |
1615 | 7.21k | Vector<TemporaryCodeBlockData> temporary_code_block_data; |
1616 | 7.21k | }; |
1617 | 7.21k | Array<TemporarySubBandData, 3> temporary_sub_band_data {}; |
1618 | | |
1619 | 7.21k | static constexpr Array level_0_sub_bands { JPEG2000::SubBand::HorizontalLowpassVerticalLowpass }; |
1620 | 7.21k | auto sub_bands = r == 0 ? level_0_sub_bands.span() : DecodedTileComponent::SubBandOrder.span(); |
1621 | 19.0k | for (auto [sub_band_index, sub_band] : enumerate(sub_bands)) { |
1622 | 19.0k | auto& component = tile.components[progression_data.component]; |
1623 | 19.0k | auto& sub_band_data = r == 0 ? component.nLL : component.decompositions[r - 1][sub_band_index]; |
1624 | 19.0k | auto& precinct = sub_band_data.precincts[progression_data.precinct]; |
1625 | | |
1626 | | // B.9: "Only those code-blocks that contain samples from the relevant sub-band, confined to the precinct, have any representation in the packet." |
1627 | 19.0k | if (precinct.num_code_blocks_wide == 0 || precinct.num_code_blocks_high == 0) |
1628 | 148 | continue; |
1629 | | |
1630 | 18.8k | temporary_sub_band_data[sub_band_index].precinct = &precinct; |
1631 | 18.8k | TRY(temporary_sub_band_data[sub_band_index].temporary_code_block_data.try_resize(precinct.code_blocks.size())); |
1632 | | |
1633 | 44.0k | for (auto const& [code_block_index, current_block] : enumerate(precinct.code_blocks)) { |
1634 | 44.0k | size_t code_block_x = code_block_index % precinct.num_code_blocks_wide; |
1635 | 44.0k | size_t code_block_y = code_block_index / precinct.num_code_blocks_wide; |
1636 | | |
1637 | | // B.10.4 Code-block inclusion |
1638 | 44.0k | bool is_included; |
1639 | 44.0k | if (current_block.has_been_included_in_previous_packet) { |
1640 | | // "For code-blocks that have been included in a previous packet, a single bit is used to represent the information, where |
1641 | | // a 1 means that the code-block is included in this layer and a 0 means that it is not." |
1642 | 812 | is_included = TRY(read_bit()); |
1643 | 43.2k | } else { |
1644 | | // "For code-blocks that have not been previously included in any packet, this information is signalled with a separate tag |
1645 | | // tree code for each precinct as confined to a sub-band. The values in this tag tree are the number of the layer in which the |
1646 | | // current code-block is first included." |
1647 | 43.2k | is_included = TRY(precinct.code_block_inclusion_tree->read_value(code_block_x, code_block_y, read_bit, current_layer_index + 1)) <= current_layer_index; |
1648 | 43.2k | } |
1649 | 44.0k | dbgln_if(JPEG2000_DEBUG, "code-block inclusion: {}", is_included); |
1650 | 44.0k | current_block.is_included = is_included; |
1651 | | |
1652 | 44.0k | if (!is_included) |
1653 | 24.9k | continue; |
1654 | | |
1655 | | // B.10.5 Zero bit-plane information |
1656 | | // "If a code-block is included for the first time, |
1657 | | // [...] the number of actual bit-planes for which coding passes are generated is Mb – P |
1658 | | // [...] these missing bit-planes are all taken to be zero |
1659 | | // [...] The value of P is coded in the packet header with a separate tag tree for every precinct" |
1660 | | // And Annex E, E.1 Inverse quantization procedure: |
1661 | | // "Mb = G + exp_b - 1 (E-2) |
1662 | | // where the number of guard bits G and the exponent exp_b are specified in the QCD or QCC marker segments (see A.6.4 and A.6.5)." |
1663 | 19.1k | bool is_included_for_the_first_time = is_included && !current_block.has_been_included_in_previous_packet; |
1664 | 19.1k | if (is_included_for_the_first_time) { |
1665 | 18.4k | u32 p = TRY(precinct.p_tree->read_value(code_block_x, code_block_y, read_bit)); |
1666 | 18.4k | dbgln_if(JPEG2000_DEBUG, "zero bit-plane information: {}", p); |
1667 | 18.4k | current_block.p = p; |
1668 | 18.4k | current_block.has_been_included_in_previous_packet = true; |
1669 | 18.4k | } |
1670 | | |
1671 | | // B.10.6 Number of coding passes |
1672 | | // Table B.4 – Codewords for the number of coding passes for each code-block |
1673 | 19.1k | u8 number_of_coding_passes = TRY([&]() -> ErrorOr<u8> { |
1674 | 19.1k | if (!TRY(read_bit())) |
1675 | 19.1k | return 1; |
1676 | 19.1k | if (!TRY(read_bit())) |
1677 | 19.1k | return 2; |
1678 | | |
1679 | 19.1k | u8 bits = TRY(read_bit()); |
1680 | 19.1k | bits = (bits << 1) | TRY(read_bit()); |
1681 | 19.1k | if (bits != 3) |
1682 | 19.1k | return 3 + bits; |
1683 | | |
1684 | 19.1k | bits = TRY(read_bit()); |
1685 | 19.1k | bits = (bits << 1) | TRY(read_bit()); |
1686 | 19.1k | bits = (bits << 1) | TRY(read_bit()); |
1687 | 19.1k | bits = (bits << 1) | TRY(read_bit()); |
1688 | 19.1k | bits = (bits << 1) | TRY(read_bit()); |
1689 | 19.1k | if (bits != 31) |
1690 | 19.1k | return 6 + bits; |
1691 | | |
1692 | 19.1k | bits = TRY(read_bit()); |
1693 | 19.1k | bits = (bits << 1) | TRY(read_bit()); |
1694 | 19.1k | bits = (bits << 1) | TRY(read_bit()); |
1695 | 19.1k | bits = (bits << 1) | TRY(read_bit()); |
1696 | 19.1k | bits = (bits << 1) | TRY(read_bit()); |
1697 | 19.1k | bits = (bits << 1) | TRY(read_bit()); |
1698 | 19.1k | bits = (bits << 1) | TRY(read_bit()); |
1699 | 19.1k | return 37 + bits; |
1700 | 19.1k | }()); |
1701 | 19.1k | dbgln_if(JPEG2000_DEBUG, "number of coding passes: {}", number_of_coding_passes); |
1702 | | |
1703 | | // B.10.7 Length of the compressed image data from a given code-block |
1704 | | // "Multiple codeword segments arise when a termination occurs between coding passes which are included in the packet" |
1705 | | |
1706 | 19.1k | u32 passes_from_previous_layers = precinct.code_blocks[code_block_index].number_of_coding_passes(); |
1707 | | |
1708 | 19.1k | JPEG2000::BitplaneDecodingOptions options; |
1709 | 19.1k | options.uses_termination_on_each_coding_pass = coding_parameters.uses_termination_on_each_coding_pass(); |
1710 | 19.1k | options.uses_selective_arithmetic_coding_bypass = coding_parameters.uses_selective_arithmetic_coding_bypass(); |
1711 | 19.1k | int number_of_segments = [&]() { |
1712 | 19.1k | auto old_segment_index = passes_from_previous_layers == 0 ? 0 : JPEG2000::segment_index_from_pass_index(options, passes_from_previous_layers - 1); |
1713 | 19.1k | auto new_segment_index = JPEG2000::segment_index_from_pass_index(options, passes_from_previous_layers + number_of_coding_passes - 1); |
1714 | 19.1k | auto number_of_segments = new_segment_index - old_segment_index; |
1715 | | |
1716 | | // If the old layer does not end on a segment boundary, the new layer has to add one segment for continuing the previous segment |
1717 | | // in addition to counting the segments it contains and starts. |
1718 | 19.1k | if (old_segment_index == JPEG2000::segment_index_from_pass_index(options, passes_from_previous_layers)) |
1719 | 19.1k | number_of_segments++; |
1720 | 19.1k | return number_of_segments; |
1721 | 19.1k | }(); |
1722 | | |
1723 | | // B.10.7.1 Single codeword segment |
1724 | | // "A codeword segment is the number of bytes contributed to a packet by a code-block. |
1725 | | // The length of a codeword segment is represented by a binary number of length: |
1726 | | // bits = Lblock + ⌊log2(number_of_coding_passes)⌋ |
1727 | | // where Lblock is a code-block state variable. A separate Lblock is used for each code-block in the precinct. |
1728 | | // The value of Lblock is initially set to three. The number of bytes contributed by each code-block is preceded by signalling |
1729 | | // bits that increase the value of Lblock, as needed. A signalling bit of zero indicates the current value of Lblock is sufficient. |
1730 | | // If there are k ones followed by a zero, the value of Lblock is incremented by k." |
1731 | | // B.10.7.2 Multiple codeword segments |
1732 | | // "Let T be the set of indices of terminated coding passes included for the code-block in the packet as indicated in Tables D.8 |
1733 | | // and D.9. If the index final coding pass included in the packet is not a member of T, then it is added to T. Let n_1 < ... < n_K |
1734 | | // be the indices in T. K lengths are signalled consecutively with each length using the mechanism described in B.10.7.1." |
1735 | | // "using the mechanism" means adjusting Lblock just once, and then reading one code word segment length with the |
1736 | | // number of passes per segment, apparently. |
1737 | | // We combine both cases: the single segment case is a special case of the multiple segment case. |
1738 | | // For the B.10.7.1 case, we'll have number_of_segments = 1 and number_of_passes_in_segment = number_of_coding_passes. |
1739 | | |
1740 | 19.1k | u32 k = 0; |
1741 | 32.4k | while (TRY(read_bit())) |
1742 | 13.3k | k++; |
1743 | 0 | current_block.Lblock += k; |
1744 | | |
1745 | 20.1k | auto read_one_codeword_segment_length = [&](int number_of_passes) -> ErrorOr<u32> { |
1746 | 20.1k | u32 bits = current_block.Lblock + (u32)floor(log2(number_of_passes)); |
1747 | 20.1k | if (bits > 32) |
1748 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Too many bits for length of codeword segment"); |
1749 | | |
1750 | 20.1k | u32 length = 0; |
1751 | 152k | for (u32 i = 0; i < bits; ++i) { |
1752 | 132k | bool bit = TRY(read_bit()); |
1753 | 0 | length = (length << 1) | bit; |
1754 | 132k | } |
1755 | 20.1k | return length; |
1756 | 20.1k | }; |
1757 | | |
1758 | 19.1k | VERIFY(temporary_sub_band_data[sub_band_index].temporary_code_block_data[code_block_index].codeword_segments.is_empty()); |
1759 | | |
1760 | 19.1k | int number_of_passes_used = 0; |
1761 | 39.2k | for (int i = 0; i < number_of_segments; ++i) { |
1762 | 20.1k | int number_of_passes_in_segment = number_of_coding_passes; |
1763 | 20.1k | u32 segment_index = JPEG2000::segment_index_from_pass_index(options, passes_from_previous_layers) + i; |
1764 | | |
1765 | 20.1k | if (coding_parameters.uses_termination_on_each_coding_pass()) { |
1766 | 1.13k | number_of_passes_in_segment = 1; |
1767 | 19.0k | } else if (coding_parameters.uses_selective_arithmetic_coding_bypass()) { |
1768 | 0 | number_of_passes_in_segment = JPEG2000::number_of_passes_from_segment_index_in_bypass_mode(segment_index); |
1769 | | |
1770 | | // Correction at start: Did the previous layer end in an incomplete segment that's continued in this layer? |
1771 | 0 | Optional<u32> previous_segment_id = precinct.code_blocks[code_block_index].highest_segment_index(); |
1772 | 0 | if (previous_segment_id.has_value() && segment_index == previous_segment_id.value()) |
1773 | 0 | number_of_passes_in_segment -= precinct.code_blocks[code_block_index].number_of_coding_passes_in_segment(segment_index); |
1774 | | |
1775 | | // Correction at end: Does this layer end in an incomplete segment that's continued in the next layer? |
1776 | 0 | if (i == number_of_segments - 1) |
1777 | 0 | number_of_passes_in_segment = min(number_of_coding_passes - number_of_passes_used, number_of_passes_in_segment); |
1778 | 0 | } |
1779 | 20.1k | u32 length = TRY(read_one_codeword_segment_length(number_of_passes_in_segment)); |
1780 | 20.1k | dbgln_if(JPEG2000_DEBUG, "length({}) {}", i, length); |
1781 | 20.1k | temporary_sub_band_data[sub_band_index].temporary_code_block_data[code_block_index].codeword_segments.append({ length, segment_index, number_of_passes_in_segment }); |
1782 | 20.1k | number_of_passes_used += number_of_passes_in_segment; |
1783 | 20.1k | VERIFY(number_of_passes_used <= number_of_coding_passes); |
1784 | 20.1k | } |
1785 | 19.1k | VERIFY(number_of_passes_used == number_of_coding_passes); |
1786 | 19.1k | } |
1787 | 18.8k | } |
1788 | | |
1789 | 7.19k | if (last_full_byte == 0xFF) { |
1790 | 0 | bool final_stuff_bit = TRY(read_bit()); |
1791 | 0 | if (final_stuff_bit) |
1792 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Invalid bit-stuffing"); |
1793 | 0 | } |
1794 | | |
1795 | 7.19k | if (tile.cod.value_or(context.cod).shall_use_EPH_marker) { |
1796 | | // A.8.2 End of packet header (EPH) |
1797 | | // "If EPH markers are required (by signalling in the COD marker segment, see A.6.1), each packet header in any given tile- |
1798 | | // part shall be postpended with an EPH marker segment. If the packet headers are moved to a PPM or PPT marker segments |
1799 | | // (see A.7.4 and A.7.5), then the EPH markers shall appear after the packet headers in the PPM or PPT marker segments." |
1800 | | // Just skip this data if it's there. |
1801 | | // FIMXE: Tweak once we add support for PPM and PPT. |
1802 | 18 | u16 marker = TRY(stream.read_value<BigEndian<u16>>()); |
1803 | 18 | if (marker != J2K_EPH) |
1804 | 3 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Expected EPH marker"); |
1805 | 18 | } |
1806 | | |
1807 | | // Done reading packet header. Set `data` on each codeblock on the packet. |
1808 | 7.19k | u32 offset = stream.offset(); |
1809 | 21.5k | for (auto const& temporary_sub_band : temporary_sub_band_data) { |
1810 | 44.0k | for (auto const& [code_block_index, temporary_code_block] : enumerate(temporary_sub_band.temporary_code_block_data)) { |
1811 | 44.0k | DecodedCodeBlock::Layer layer; |
1812 | 44.0k | for (auto [length, index, number_of_passes] : temporary_code_block.codeword_segments) { |
1813 | 20.1k | auto segment_data = data.slice(offset, length); |
1814 | 20.1k | offset += length; |
1815 | 20.1k | layer.segments.append({ segment_data, index, number_of_passes }); |
1816 | 20.1k | } |
1817 | 44.0k | TRY(temporary_sub_band.precinct->code_blocks[code_block_index].layers.try_append(layer)); |
1818 | 44.0k | } |
1819 | 21.5k | } |
1820 | | |
1821 | 7.19k | return offset; |
1822 | 7.19k | } |
1823 | | |
1824 | | static ErrorOr<void> read_tile_part_packet_headers(JPEG2000LoadingContext& context, TileData& tile, TilePartData& tile_part) |
1825 | 1.77k | { |
1826 | 1.77k | auto data = tile_part.data; |
1827 | 9.68k | while (!data.is_empty()) { |
1828 | 8.00k | auto length = TRY(read_one_packet_header(context, tile, data)); |
1829 | 0 | data = data.slice(length); |
1830 | 7.90k | } |
1831 | | |
1832 | 1.68k | return {}; |
1833 | 1.77k | } |
1834 | | |
1835 | | static ErrorOr<void> read_tile_packet_headers(JPEG2000LoadingContext& context, TileData& tile) |
1836 | 572k | { |
1837 | 572k | for (auto& tile_part : tile.tile_parts) |
1838 | 1.77k | TRY(read_tile_part_packet_headers(context, tile, tile_part)); |
1839 | 572k | return {}; |
1840 | 572k | } |
1841 | | |
1842 | | static ErrorOr<void> read_packet_headers(JPEG2000LoadingContext& context) |
1843 | 503 | { |
1844 | 503 | for (auto& tile : context.tiles) |
1845 | 572k | TRY(read_tile_packet_headers(context, tile)); |
1846 | 406 | return {}; |
1847 | 503 | } |
1848 | | |
1849 | | static u8 get_exponent(QuantizationDefault const& quantization_parameters, JPEG2000::SubBand sub_band, int resolution_level) |
1850 | 6.08M | { |
1851 | 6.08M | switch (quantization_parameters.quantization_style) { |
1852 | 8.87k | case QuantizationDefault::QuantizationStyle::NoQuantization: { |
1853 | 8.87k | auto const& steps = quantization_parameters.step_sizes.get<Vector<QuantizationDefault::ReversibleStepSize>>(); |
1854 | 8.87k | if (sub_band == JPEG2000::SubBand::HorizontalLowpassVerticalLowpass) { |
1855 | 589 | VERIFY(resolution_level == 0); |
1856 | 589 | return steps[0].exponent; |
1857 | 589 | } |
1858 | 8.28k | VERIFY(resolution_level > 0); |
1859 | 8.28k | return steps[1 + (resolution_level - 1) * 3 + (int)sub_band - 1].exponent; |
1860 | 8.28k | } |
1861 | 0 | case QuantizationDefault::QuantizationStyle::ScalarDerived: |
1862 | 6.07M | case QuantizationDefault::QuantizationStyle::ScalarExpounded: { |
1863 | 6.07M | auto const& steps = quantization_parameters.step_sizes.get<Vector<QuantizationDefault::IrreversibleStepSize>>(); |
1864 | | |
1865 | 6.07M | if (quantization_parameters.quantization_style == QuantizationDefault::QuantizationStyle::ScalarDerived) { |
1866 | | // Callers must use (E-5). |
1867 | 0 | return steps[0].exponent; |
1868 | 0 | } |
1869 | | |
1870 | 6.07M | if (sub_band == JPEG2000::SubBand::HorizontalLowpassVerticalLowpass) { |
1871 | 7.76k | VERIFY(resolution_level == 0); |
1872 | 7.76k | return steps[0].exponent; |
1873 | 7.76k | } |
1874 | 6.06M | VERIFY(resolution_level > 0); |
1875 | 6.06M | return steps[1 + (resolution_level - 1) * 3 + (int)sub_band - 1].exponent; |
1876 | 6.06M | } |
1877 | 6.08M | } |
1878 | 0 | VERIFY_NOT_REACHED(); |
1879 | 0 | } |
1880 | | |
1881 | | static int compute_M_b(JPEG2000LoadingContext& context, TileData& tile, int component_index, JPEG2000::SubBand sub_band_type, int r, int N_L) |
1882 | 15.4k | { |
1883 | | // Annex E, E.1 Inverse quantization procedure: |
1884 | | // "Mb = G + exp_b - 1 (E-2) |
1885 | | // where the number of guard bits G and the exponent exp_b are specified in the QCD or QCC marker segments (see A.6.4 and A.6.5)." |
1886 | 15.4k | auto quantization_parameters = context.quantization_parameters_for_component(tile, component_index); |
1887 | 15.4k | auto exponent = get_exponent(quantization_parameters, sub_band_type, r); |
1888 | 15.4k | if (quantization_parameters.quantization_style == QuantizationDefault::QuantizationStyle::ScalarDerived) { |
1889 | | // Table F.1 – Decomposition level nb for sub-band b |
1890 | | // Note: The spec suggests that this ends with n_b = 1, but if N_L is 0, we have 0LL and nothing else. |
1891 | 0 | int n_b = r == 0 ? N_L : (N_L + 1 - r); |
1892 | | // (E-5) |
1893 | 0 | exponent = exponent - N_L + n_b; |
1894 | | // This is the same as `if (r != 0) exponent = exponent - (r - 1);` |
1895 | 0 | } |
1896 | 15.4k | return quantization_parameters.number_of_guard_bits + exponent - 1; |
1897 | 15.4k | } |
1898 | | |
1899 | | static ErrorOr<void> decode_bitplanes_to_coefficients(JPEG2000LoadingContext& context) |
1900 | 406 | { |
1901 | 15.3k | auto copy_and_dequantize_if_needed = [&](JPEG2000::Span2D<float> output, ReadonlySpan<float> input, QuantizationDefault const& quantization_parameters, JPEG2000::SubBand sub_band_type, int component_index, int r) { |
1902 | 15.3k | int w = output.size.width(); |
1903 | 15.3k | int h = output.size.height(); |
1904 | 15.3k | VERIFY(w * h == static_cast<int>(input.size())); |
1905 | | |
1906 | 253k | for (int y = 0; y < h; ++y) { |
1907 | 23.5M | for (int x = 0; x < w; ++x) { |
1908 | 23.3M | float value = input[y * w + x]; |
1909 | | |
1910 | | // E.1 Inverse quantization procedure |
1911 | | // The coefficients store qbar_b. |
1912 | 23.3M | if (quantization_parameters.quantization_style != QuantizationDefault::QuantizationStyle::NoQuantization) { |
1913 | | // E.1.1 Irreversible transformation |
1914 | 6.06M | auto R_I = context.siz.components[component_index].bit_depth(); |
1915 | | |
1916 | | // Table E.1 – Sub-band gains |
1917 | 6.06M | auto log_2_gain_b = sub_band_type == JPEG2000::SubBand::HorizontalLowpassVerticalLowpass ? 0 : (sub_band_type == JPEG2000::SubBand::HorizontalHighpassVerticalLowpass || sub_band_type == JPEG2000::SubBand::HorizontalLowpassVerticalHighpass ? 1 : 2); |
1918 | 6.06M | auto R_b = R_I + log_2_gain_b; // (E-4) |
1919 | | |
1920 | 6.06M | u16 mantissa; |
1921 | 6.06M | if (quantization_parameters.quantization_style == QuantizationDefault::QuantizationStyle::ScalarDerived) { |
1922 | | // (E-5) |
1923 | 0 | mantissa = quantization_parameters.step_sizes.get<Vector<QuantizationDefault::IrreversibleStepSize>>()[0].mantissa; |
1924 | 6.06M | } else { |
1925 | 6.06M | if (r == 0) |
1926 | 7.36k | mantissa = quantization_parameters.step_sizes.get<Vector<QuantizationDefault::IrreversibleStepSize>>()[0].mantissa; |
1927 | 6.06M | else |
1928 | 6.06M | mantissa = quantization_parameters.step_sizes.get<Vector<QuantizationDefault::IrreversibleStepSize>>()[3 * (r - 1) + (int)sub_band_type].mantissa; |
1929 | 6.06M | } |
1930 | | |
1931 | | // (E-3) |
1932 | 6.06M | auto exponent = get_exponent(quantization_parameters, sub_band_type, r); |
1933 | 6.06M | float step_size = powf(2.0f, R_b - exponent) * (1.0f + mantissa / powf(2.0f, 11.0f)); |
1934 | | |
1935 | | // (E-6), with r chosen as 0 (see NOTE below (E-6)). |
1936 | 6.06M | value *= step_size; |
1937 | 6.06M | } |
1938 | | |
1939 | 23.3M | output.data[y * output.pitch + x] = value; |
1940 | 23.3M | } |
1941 | 237k | } |
1942 | 15.3k | }; |
1943 | | |
1944 | 15.4k | auto decode_bitplanes = [&](TileData& tile, JPEG2000::SubBand sub_band_type, DecodedSubBand& sub_band, int component_index, int r, int N_L) -> ErrorOr<void> { |
1945 | 15.4k | TRY(sub_band.coefficients.try_resize(sub_band.rect.width() * sub_band.rect.height())); |
1946 | | |
1947 | 0 | auto const& coding_style = context.coding_style_parameters_for_component(tile, component_index); |
1948 | 15.4k | JPEG2000::BitplaneDecodingOptions bitplane_decoding_options; |
1949 | 15.4k | bitplane_decoding_options.uses_selective_arithmetic_coding_bypass = coding_style.uses_selective_arithmetic_coding_bypass(); |
1950 | 15.4k | bitplane_decoding_options.reset_context_probabilities_each_pass = coding_style.reset_context_probabilities(); |
1951 | 15.4k | bitplane_decoding_options.uses_termination_on_each_coding_pass = coding_style.uses_termination_on_each_coding_pass(); |
1952 | 15.4k | bitplane_decoding_options.uses_vertically_causal_context = coding_style.uses_vertically_causal_context(); |
1953 | 15.4k | bitplane_decoding_options.uses_segmentation_symbols = coding_style.uses_segmentation_symbols(); |
1954 | | |
1955 | 15.4k | int M_b = compute_M_b(context, tile, component_index, sub_band_type, r, N_L); |
1956 | | |
1957 | | // FIXME: Codeblocks all use independent arithmetic coders, so this could run in parallel. |
1958 | 15.4k | for (auto& precinct : sub_band.precincts) { |
1959 | | |
1960 | 15.3k | Vector<float> precinct_coefficients; |
1961 | 15.3k | auto clipped_precinct_rect = precinct.rect.intersected(sub_band.rect); |
1962 | 15.3k | precinct_coefficients.resize(clipped_precinct_rect.width() * clipped_precinct_rect.height()); |
1963 | | |
1964 | 24.3k | for (auto& code_block : precinct.code_blocks) { |
1965 | 24.3k | int total_number_of_coding_passes = code_block.number_of_coding_passes(); |
1966 | 24.3k | ByteBuffer storage; |
1967 | 24.3k | Vector<ReadonlyBytes, 1> combined_segments = TRY(code_block.segments_for_all_layers(storage)); |
1968 | | |
1969 | 0 | JPEG2000::Span2D<float> output; |
1970 | 24.3k | output.size = code_block.rect.size(); |
1971 | 24.3k | output.pitch = clipped_precinct_rect.width(); |
1972 | 24.3k | output.data = precinct_coefficients.span().slice((code_block.rect.y() - clipped_precinct_rect.y()) * output.pitch + (code_block.rect.x() - clipped_precinct_rect.x())); |
1973 | 24.3k | TRY(JPEG2000::decode_code_block(output, sub_band_type, total_number_of_coding_passes, combined_segments, M_b, code_block.p, bitplane_decoding_options)); |
1974 | 24.2k | } |
1975 | | |
1976 | 15.3k | JPEG2000::Span2D<float> output; |
1977 | 15.3k | output.size = clipped_precinct_rect.size(); |
1978 | 15.3k | output.pitch = sub_band.rect.width(); |
1979 | 15.3k | output.data = sub_band.coefficients.span().slice((clipped_precinct_rect.y() - sub_band.rect.y()) * output.pitch + (clipped_precinct_rect.x() - sub_band.rect.x())); |
1980 | 15.3k | copy_and_dequantize_if_needed(output, precinct_coefficients, context.quantization_parameters_for_component(tile, component_index), sub_band_type, component_index, r); |
1981 | 15.3k | } |
1982 | | |
1983 | 15.3k | return {}; |
1984 | 15.4k | }; |
1985 | | |
1986 | 498 | for (auto& tile : context.tiles) { |
1987 | 1.00k | for (auto [component_index, component] : enumerate(tile.components)) { |
1988 | 1.00k | int N_L = component.decompositions.size(); |
1989 | 1.00k | TRY(decode_bitplanes(tile, JPEG2000::SubBand::HorizontalLowpassVerticalLowpass, component.nLL, component_index, 0, N_L)); |
1990 | 4.80k | for (auto const& [decomposition_index, decomposition] : enumerate(component.decompositions)) { |
1991 | 4.80k | int r = decomposition_index + 1; |
1992 | 14.4k | for (auto [sub_band_index, sub_band] : enumerate(DecodedTileComponent::SubBandOrder)) { |
1993 | 14.4k | TRY(decode_bitplanes(tile, sub_band, decomposition[sub_band_index], component_index, r, N_L)); |
1994 | 14.4k | } |
1995 | 4.80k | } |
1996 | 984 | } |
1997 | 498 | } |
1998 | | |
1999 | 384 | return {}; |
2000 | 406 | } |
2001 | | |
2002 | | static ErrorOr<void> run_inverse_discrete_wavelet_transform(JPEG2000LoadingContext& context) |
2003 | 384 | { |
2004 | | // FIXME: Could run these in parallel. |
2005 | 476 | for (auto& tile : context.tiles) { |
2006 | 984 | for (auto [component_index, component] : enumerate(tile.components)) { |
2007 | 984 | int N_L = component.decompositions.size(); |
2008 | | |
2009 | 984 | Gfx::JPEG2000::IDWTInput input; |
2010 | 984 | input.transformation = context.coding_style_parameters_for_component(tile, component_index).transformation; |
2011 | 984 | input.LL.rect = component.nLL.rect; |
2012 | 984 | input.LL.data = { component.nLL.coefficients, component.nLL.rect.size(), component.nLL.rect.width() }; |
2013 | | |
2014 | 4.80k | for (auto const& [decomposition_index, decomposition] : enumerate(component.decompositions)) { |
2015 | 4.80k | int r = decomposition_index + 1; |
2016 | | |
2017 | 4.80k | JPEG2000::IDWTDecomposition idwt_decomposition; |
2018 | 4.80k | idwt_decomposition.ll_rect = context.siz.reference_grid_coordinates_for_ll_band(tile.rect, component_index, r, N_L); |
2019 | | |
2020 | 4.80k | VERIFY(DecodedTileComponent::SubBandOrder[0] == JPEG2000::SubBand::HorizontalHighpassVerticalLowpass); |
2021 | 4.80k | auto hl_rect = decomposition[0].rect; |
2022 | 4.80k | idwt_decomposition.hl = { hl_rect, { decomposition[0].coefficients, hl_rect.size(), hl_rect.width() } }; |
2023 | | |
2024 | 4.80k | VERIFY(DecodedTileComponent::SubBandOrder[1] == JPEG2000::SubBand::HorizontalLowpassVerticalHighpass); |
2025 | 4.80k | auto lh_rect = decomposition[1].rect; |
2026 | 4.80k | idwt_decomposition.lh = { lh_rect, { decomposition[1].coefficients, lh_rect.size(), lh_rect.width() } }; |
2027 | | |
2028 | 4.80k | VERIFY(DecodedTileComponent::SubBandOrder[2] == JPEG2000::SubBand::HorizontalHighpassVerticalHighpass); |
2029 | 4.80k | auto hh_rect = decomposition[2].rect; |
2030 | 4.80k | idwt_decomposition.hh = { hh_rect, { decomposition[2].coefficients, hh_rect.size(), hh_rect.width() } }; |
2031 | | |
2032 | 4.80k | input.decompositions.append(idwt_decomposition); |
2033 | 4.80k | } |
2034 | | |
2035 | 984 | auto output = TRY(JPEG2000::IDWT(input)); |
2036 | 984 | VERIFY(component.rect == output.rect); |
2037 | 984 | component.samples = move(output.data); |
2038 | | |
2039 | | // FIXME: Could release coefficient data here, to reduce peak memory use. |
2040 | 984 | } |
2041 | 476 | } |
2042 | | |
2043 | 384 | return {}; |
2044 | 384 | } |
2045 | | |
2046 | | static ErrorOr<void> postprocess_samples(JPEG2000LoadingContext& context) |
2047 | 384 | { |
2048 | 384 | auto undo_multiple_component_transformation = [&](TileData& tile) -> ErrorOr<void> { |
2049 | 227 | VERIFY(context.siz.components.size() == tile.components.size()); |
2050 | 227 | if (tile.components.size() < 3) |
2051 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Multiple component transformation type but fewer than 3 components"); |
2052 | | |
2053 | | // T.800, I.5.3.6 Channel Definition box |
2054 | | // "If a multiple component transform is specified within the codestream, the image must be in an RGB colourspace and the |
2055 | | // red, green and blue colours as channels 0, 1 and 2 in the codestream, respectively." |
2056 | | // FIXME: Check this. |
2057 | | |
2058 | 227 | auto transformation0 = context.coding_style_parameters_for_component(tile, 0).transformation; |
2059 | 227 | auto transformation1 = context.coding_style_parameters_for_component(tile, 1).transformation; |
2060 | 227 | auto transformation2 = context.coding_style_parameters_for_component(tile, 2).transformation; |
2061 | 227 | if (transformation0 != transformation1 || transformation1 != transformation2) |
2062 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Multiple component transformation type but components disagree on lossiness"); |
2063 | | |
2064 | | // "The three components [...] shall have the same separation on the reference grid and the same bit-depth." |
2065 | 227 | if (context.siz.components[0].horizontal_separation != context.siz.components[1].horizontal_separation |
2066 | 227 | || context.siz.components[1].horizontal_separation != context.siz.components[2].horizontal_separation) { |
2067 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Multiple component transformation type but components disagree on horizontal separation"); |
2068 | 0 | } |
2069 | | |
2070 | 227 | if (context.siz.components[0].vertical_separation != context.siz.components[1].vertical_separation |
2071 | 227 | || context.siz.components[1].vertical_separation != context.siz.components[2].vertical_separation) { |
2072 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Multiple component transformation type but components disagree on vertical separation"); |
2073 | 0 | } |
2074 | | |
2075 | | // Note: Spec says "bit-depth" but we check bit depth and sign. That must be what the spec means? |
2076 | 227 | if (context.siz.components[0].depth_and_sign != context.siz.components[1].depth_and_sign |
2077 | 227 | || context.siz.components[1].depth_and_sign != context.siz.components[2].depth_and_sign) { |
2078 | 1 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Multiple component transformation type but components disagree on bit depth"); |
2079 | 1 | } |
2080 | | |
2081 | 226 | if (tile.components[0].rect.size() != tile.components[1].rect.size() |
2082 | 226 | || tile.components[0].rect.size() != tile.components[1].rect.size()) { |
2083 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Multiple component transformation type but components disagree on dimensions"); |
2084 | 0 | } |
2085 | | |
2086 | 226 | auto& c0 = tile.components[0].samples; |
2087 | 226 | auto& c1 = tile.components[1].samples; |
2088 | 226 | auto& c2 = tile.components[2].samples; |
2089 | 226 | int w = tile.components[0].rect.width(); |
2090 | | |
2091 | 226 | if (transformation0 == JPEG2000::Transformation::Reversible_5_3_Filter) { |
2092 | | // G.2 Reversible multiple component transformation (RCT) |
2093 | | // "The three components input into the RCT shall have the same separation on the reference grid and the same bit-depth." |
2094 | | // Same for RCT and ICT; checked above this branch. |
2095 | 8.59k | for (int y = 0; y < tile.components[0].rect.height(); ++y) { |
2096 | 4.70M | for (int x = 0; x < w; ++x) { |
2097 | 4.69M | float Y = c0[y * w + x]; |
2098 | 4.69M | float Cb = c1[y * w + x]; |
2099 | 4.69M | float Cr = c2[y * w + x]; |
2100 | | |
2101 | 4.69M | float G = Y - floorf((Cb + Cr) / 4); // (G-6) |
2102 | 4.69M | float R = Cr + G; // (G-7) |
2103 | 4.69M | float B = Cb + G; // (G-8) |
2104 | | |
2105 | 4.69M | c0[y * w + x] = R; |
2106 | 4.69M | c1[y * w + x] = G; |
2107 | 4.69M | c2[y * w + x] = B; |
2108 | 4.69M | } |
2109 | 8.46k | } |
2110 | 128 | } else { |
2111 | 98 | VERIFY(transformation0 == JPEG2000::Transformation::Irreversible_9_7_Filter); |
2112 | | |
2113 | | // G.3 Irreversible multiple component transformation (ICT) |
2114 | | // "The three components input into the ICT shall have the same separation on the reference grid and the same bit-depth." |
2115 | | // Same for RCT and ICT; checked above this branch. |
2116 | 10.9k | for (int y = 0; y < tile.components[0].rect.height(); ++y) { |
2117 | 1.64M | for (int x = 0; x < w; ++x) { |
2118 | 1.63M | float Y = c0[y * w + x]; |
2119 | 1.63M | float Cb = c1[y * w + x]; |
2120 | 1.63M | float Cr = c2[y * w + x]; |
2121 | | |
2122 | 1.63M | float R = Y + 1.402f * Cr; // (G-12) |
2123 | 1.63M | float G = Y - 0.34413f * Cb - 0.7141f * Cr; // (G-13) |
2124 | 1.63M | float B = Y + 1.772f * Cb; // (G-14) |
2125 | | |
2126 | 1.63M | c0[y * w + x] = R; |
2127 | 1.63M | c1[y * w + x] = G; |
2128 | 1.63M | c2[y * w + x] = B; |
2129 | 1.63M | } |
2130 | 10.8k | } |
2131 | 98 | } |
2132 | | |
2133 | 226 | return {}; |
2134 | 226 | }; |
2135 | | |
2136 | 475 | auto undo_dc_level_shift = [&](TileData& tile) -> ErrorOr<void> { |
2137 | 475 | VERIFY(context.siz.components.size() == tile.components.size()); |
2138 | | |
2139 | | // DC level shift |
2140 | | // G.1.2 Inverse DC level shifting of tile-components |
2141 | 981 | for (auto [component_index, component] : enumerate(tile.components)) { |
2142 | 981 | if (!context.siz.components[component_index].is_signed()) { |
2143 | 980 | for (auto& coefficient : component.samples) |
2144 | 23.0M | coefficient += 1u << (context.siz.components[component_index].bit_depth() - 1); // (G-2) |
2145 | 980 | } |
2146 | 981 | } |
2147 | | |
2148 | 475 | return {}; |
2149 | 475 | }; |
2150 | | |
2151 | 476 | for (auto& tile : context.tiles) { |
2152 | | // Figure G.1 – Placement of the DC level shifting with component transformation |
2153 | 476 | if (tile.cod.value_or(context.cod).multiple_component_transformation_type == CodingStyleDefault::MultipleComponentTransformationType::MultipleComponentTransformationUsed) |
2154 | 227 | TRY(undo_multiple_component_transformation(tile)); |
2155 | | |
2156 | 950 | TRY(undo_dc_level_shift(tile)); |
2157 | 950 | } |
2158 | | |
2159 | 383 | return {}; |
2160 | 384 | } |
2161 | | |
2162 | | static ErrorOr<void> convert_to_bitmap(JPEG2000LoadingContext& context) |
2163 | 383 | { |
2164 | | // determine_color_space() defers returning an error until here, so that JPEG2000ImageDecoderPlugin::create() |
2165 | | // can succeed even with unsupported color spaces. |
2166 | 383 | if (context.color_space == ColorSpace::Unsupported) |
2167 | 22 | return move(context.color_space_error.value()); |
2168 | | |
2169 | | // Map components to channels. |
2170 | 361 | if (context.palette_box.has_value() && context.options.palette_handling != JPEG2000DecoderOptions::PaletteHandling::PaletteIndicesAsGrayscale) { |
2171 | 47 | ISOBMFF::JPEG2000ComponentMappingBox cmap; |
2172 | 47 | if (context.component_mapping_box.has_value()) { |
2173 | 47 | cmap = context.component_mapping_box.value(); |
2174 | 47 | } else { |
2175 | | // The spec requires that cmap is present if pclr is, but in practice some (very few) files have pclr without cmap. |
2176 | | // Assume that everything maps through directly in this case. |
2177 | 0 | for (size_t i = 0; i < context.palette_box->bit_depths.size(); ++i) { |
2178 | 0 | ISOBMFF::JPEG2000ComponentMappingBox::Mapping mapping; |
2179 | 0 | mapping.component_index = 0; |
2180 | 0 | mapping.palette_component_index = i; |
2181 | 0 | mapping.mapping_type = ISOBMFF::JPEG2000ComponentMappingBox::Mapping::Type::Palette; |
2182 | 0 | cmap.component_mappings.append(mapping); |
2183 | 0 | } |
2184 | 0 | } |
2185 | | |
2186 | | // I.5.3.4 Palette box |
2187 | | // "This value shall be in the range 1 to 1024" |
2188 | 47 | if (context.palette_box->palette_entries.size() > 1024) |
2189 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Only up to 1024 palette entries allowed"); |
2190 | | |
2191 | 47 | for (auto& palette_entry : context.palette_box->palette_entries) |
2192 | 3.06k | VERIFY(palette_entry.size() == context.palette_box->bit_depths.size()); // Enforced in JPEG2000PaletteBox::read_from_stream(). |
2193 | 47 | auto palette_channel_count = context.palette_box->bit_depths.size(); |
2194 | | |
2195 | 47 | for (auto& tile : context.tiles) { |
2196 | 47 | TRY(tile.channels.try_resize(cmap.component_mappings.size())); |
2197 | | |
2198 | 49 | for (auto const& [i, mapping] : enumerate(cmap.component_mappings)) { |
2199 | 49 | if (mapping.component_index >= tile.components.size()) |
2200 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Component mapping index out of range"); |
2201 | | |
2202 | 49 | if (mapping.mapping_type == ISOBMFF::JPEG2000ComponentMappingBox::Mapping::Type::Direct) { |
2203 | 0 | tile.channels[mapping.component_index] = move(tile.components[mapping.component_index].samples); |
2204 | 0 | TRY(tile.channel_information.try_append(context.siz.components[mapping.component_index])); |
2205 | 0 | continue; |
2206 | 0 | } |
2207 | | |
2208 | 49 | if (mapping.mapping_type != ISOBMFF::JPEG2000ComponentMappingBox::Mapping::Type::Palette) |
2209 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Unknown mapping type"); |
2210 | | |
2211 | 49 | if (context.siz.components[mapping.component_index].is_signed()) |
2212 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Don't know how to handle signed palette components"); |
2213 | | |
2214 | 49 | if (mapping.palette_component_index >= palette_channel_count) |
2215 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Palette component index out of range"); |
2216 | | |
2217 | 49 | ImageAndTileSize::ComponentInformation component_information; |
2218 | 49 | component_information.depth_and_sign = context.palette_box->bit_depths[mapping.palette_component_index].depth - 1; |
2219 | 49 | if (context.palette_box->bit_depths[mapping.palette_component_index].is_signed) |
2220 | 0 | component_information.depth_and_sign |= 0x80; |
2221 | 49 | component_information.horizontal_separation = context.siz.components[mapping.component_index].horizontal_separation; |
2222 | 49 | component_information.vertical_separation = context.siz.components[mapping.component_index].vertical_separation; |
2223 | 49 | TRY(tile.channel_information.try_append(component_information)); |
2224 | | |
2225 | 0 | auto const& component = tile.components[mapping.component_index]; |
2226 | 49 | TRY(tile.channels[i].try_ensure_capacity(component.samples.size())); |
2227 | 1.18M | for (auto sample : component.samples) { |
2228 | 1.18M | int index = static_cast<int>(sample); |
2229 | 1.18M | if (index < 0 || static_cast<size_t>(index) >= context.palette_box->palette_entries.size()) |
2230 | 46 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Palette index out of range"); |
2231 | 1.18M | tile.channels[i].append(context.palette_box->palette_entries[index][mapping.palette_component_index]); |
2232 | 1.18M | } |
2233 | 49 | } |
2234 | | |
2235 | 1 | for (auto& component : tile.components) |
2236 | 1 | component.samples.clear(); |
2237 | 1 | } |
2238 | 314 | } else { |
2239 | 406 | for (auto& tile : context.tiles) { |
2240 | 1.25k | for (size_t i = 0; i < tile.components.size(); ++i) { |
2241 | 849 | TRY(tile.channels.try_append(move(tile.components[i].samples))); |
2242 | 849 | TRY(tile.channel_information.try_append(context.siz.components[i])); |
2243 | 849 | } |
2244 | 406 | } |
2245 | 314 | } |
2246 | 315 | auto const channel_count = context.tiles[0].channels.size(); |
2247 | | |
2248 | 315 | bool has_alpha = false; |
2249 | 315 | if (context.palette_box.has_value() && context.options.palette_handling == JPEG2000DecoderOptions::PaletteHandling::PaletteIndicesAsGrayscale) { |
2250 | 0 | for (auto& tile : context.tiles) { |
2251 | 0 | if (tile.channels.size() != 1) |
2252 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Palette indices as grayscale require single component"); |
2253 | 0 | for (auto sample : tile.channels[0]) { |
2254 | | // The JPEG2000 spec allows palette indices up to 1023, but the PDF spec says that JPEG2000 images |
2255 | | // embedded in PDFs must have indices that fit in a one byte. |
2256 | 0 | if (sample < 0 || sample >= 256) |
2257 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Palette indices out of range"); |
2258 | 0 | } |
2259 | 0 | } |
2260 | 315 | } else { |
2261 | 315 | if (context.channel_definition_box.has_value()) { |
2262 | 7 | if (context.channel_definition_box->channels.size() != channel_count) |
2263 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Channel definition box channel count doesn't match channel count"); |
2264 | | |
2265 | 7 | Vector<bool, 4> channel_used; |
2266 | 7 | channel_used.resize(context.channel_definition_box->channels.size()); |
2267 | | |
2268 | | // If you make this more flexible in the future and implement channel swapping, |
2269 | | // check if that should happen for JPEG2000 files in PDFs as well. |
2270 | 24 | for (auto channel : context.channel_definition_box->channels) { |
2271 | 24 | if (channel.channel_index >= channel_count) |
2272 | 1 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Channel definition box channel index out of range"); |
2273 | 23 | if (channel_used[channel.channel_index]) |
2274 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Channel definition box channel index used multiple times"); |
2275 | 23 | channel_used[channel.channel_index] = true; |
2276 | | |
2277 | 23 | if (channel.channel_type != ISOBMFF::JPEG2000ChannelDefinitionBox::Channel::Type::Color |
2278 | 23 | && channel.channel_type != ISOBMFF::JPEG2000ChannelDefinitionBox::Channel::Type::Opacity) { |
2279 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Only color and opacity channels supported yet"); |
2280 | 0 | } |
2281 | 23 | if (channel.channel_type == ISOBMFF::JPEG2000ChannelDefinitionBox::Channel::Type::Color) { |
2282 | 18 | if (channel.channel_index + 1 != channel.channel_association) |
2283 | 1 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Only unshuffled color channel indices supported yet"); |
2284 | 18 | } else { |
2285 | 5 | VERIFY(channel.channel_type == ISOBMFF::JPEG2000ChannelDefinitionBox::Channel::Type::Opacity); |
2286 | 5 | if (channel.channel_index != channel_count - 1) |
2287 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Only opacity channel as last channel supported yet"); |
2288 | 5 | if (channel.channel_association != 0) |
2289 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Only full opacity channel supported yet"); |
2290 | 5 | has_alpha = true; |
2291 | 5 | } |
2292 | 23 | } |
2293 | 308 | } else if (!context.color_box.has_value()) { |
2294 | | // Raw codestream. Go by number of channels. |
2295 | 298 | has_alpha = channel_count == 2 || channel_count == 4; |
2296 | 298 | } |
2297 | | |
2298 | 313 | unsigned expected_channel_count = [](ColorSpace color_space) { |
2299 | 313 | switch (color_space) { |
2300 | 127 | case ColorSpace::Gray: |
2301 | 127 | return 1; |
2302 | 184 | case ColorSpace::sRGB: |
2303 | 184 | return 3; |
2304 | 2 | case ColorSpace::CMYK: |
2305 | 2 | return 4; |
2306 | 0 | case ColorSpace::Unsupported: // Rejected above. |
2307 | 0 | VERIFY_NOT_REACHED(); |
2308 | 313 | }; |
2309 | 0 | VERIFY_NOT_REACHED(); |
2310 | 0 | }(context.color_space); |
2311 | 313 | if (has_alpha) |
2312 | 5 | expected_channel_count++; |
2313 | 313 | if (channel_count < expected_channel_count) |
2314 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Not enough channels for expected channel count"); |
2315 | | |
2316 | 313 | if (channel_count > expected_channel_count) |
2317 | 5 | dbgln("JPEG2000ImageDecoderPlugin: More channels ({}) than expected channel count ({}), ignoring superfluous channels", context.siz.components.size(), expected_channel_count); |
2318 | | |
2319 | | // Convert to 8bpp. |
2320 | 405 | for (auto& tile : context.tiles) { |
2321 | 846 | for (auto const& [channel_index, channel] : enumerate(tile.channels)) { |
2322 | 846 | if (tile.channel_information[channel_index].is_signed()) |
2323 | 1 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Only unsigned components supported yet"); |
2324 | | |
2325 | 845 | if (tile.channel_information[channel_index].bit_depth() == 8) |
2326 | 806 | continue; |
2327 | | |
2328 | | // > 16bpp currently overflow the u16s internal to decode_code_block(). |
2329 | 39 | if (tile.channel_information[channel_index].bit_depth() > 16) |
2330 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: More than 16 bits per component not supported yet"); |
2331 | | |
2332 | 39 | for (float& sample : channel) |
2333 | 1.03M | sample = (sample * 255.0f) / ((1 << tile.channel_information[channel_index].bit_depth()) - 1); |
2334 | 39 | } |
2335 | 405 | } |
2336 | 313 | } |
2337 | | |
2338 | 312 | if (context.color_space == ColorSpace::CMYK) { |
2339 | 2 | if (has_alpha) |
2340 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: CMYK with alpha not yet supported"); |
2341 | | |
2342 | 2 | auto bitmap = TRY(Gfx::CMYKBitmap::create_with_size({ context.siz.width, context.siz.height })); |
2343 | | |
2344 | 21 | for (auto& tile : context.tiles) { |
2345 | | // compute_decoding_metadata currently rejects images with horizontal_separation or vertical_separation != 1. |
2346 | 84 | for (auto& component : tile.components) { |
2347 | 84 | if (component.rect.size() != tile.components[0].rect.size()) |
2348 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Components with differing sizes not yet supported"); |
2349 | 84 | } |
2350 | 21 | int w = tile.components[0].rect.width(); |
2351 | 21 | int h = tile.components[0].rect.height(); |
2352 | | |
2353 | 5.41k | for (int y = 0; y < h; ++y) { |
2354 | 1.16M | for (int x = 0; x < w; ++x) { |
2355 | 1.15M | float C = round_to<u8>(clamp(tile.channels[0][y * w + x], 0.0f, 255.0f)); |
2356 | 1.15M | float M = round_to<u8>(clamp(tile.channels[1][y * w + x], 0.0f, 255.0f)); |
2357 | 1.15M | float Y = round_to<u8>(clamp(tile.channels[2][y * w + x], 0.0f, 255.0f)); |
2358 | 1.15M | float K = round_to<u8>(clamp(tile.channels[3][y * w + x], 0.0f, 255.0f)); |
2359 | 1.15M | bitmap->scanline(y + tile.components[0].rect.top())[x + tile.components[0].rect.left()] = { (u8)C, (u8)M, (u8)Y, (u8)K }; |
2360 | 1.15M | } |
2361 | 5.38k | } |
2362 | 21 | } |
2363 | | |
2364 | 2 | context.cmyk_bitmap = move(bitmap); |
2365 | 2 | return {}; |
2366 | 2 | } |
2367 | | |
2368 | 310 | auto bitmap = TRY(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, { context.siz.width, context.siz.height })); |
2369 | | |
2370 | 376 | for (auto& tile : context.tiles) { |
2371 | | // compute_decoding_metadata currently rejects images with horizontal_separation or vertical_separation != 1. |
2372 | 742 | for (auto& component : tile.components) { |
2373 | 742 | if (component.rect.size() != tile.components[0].rect.size()) |
2374 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Components with differing sizes not yet supported"); |
2375 | 742 | } |
2376 | | |
2377 | 376 | int w = tile.components[0].rect.width(); |
2378 | 376 | int h = tile.components[0].rect.height(); |
2379 | | |
2380 | 24.2k | for (int y = 0; y < h; ++y) { |
2381 | 6.92M | for (int x = 0; x < w; ++x) { |
2382 | 6.89M | float value = tile.channels[0][y * w + x]; |
2383 | | |
2384 | 6.89M | u8 byte_value = round_to<u8>(clamp(value, 0.0f, 255.0f)); |
2385 | 6.89M | u8 r = byte_value; |
2386 | 6.89M | u8 g = byte_value; |
2387 | 6.89M | u8 b = byte_value; |
2388 | 6.89M | u8 a = 255; |
2389 | | |
2390 | 6.89M | if (tile.channels.size() == 2) { |
2391 | 0 | a = round_to<u8>(clamp(tile.channels[1][y * w + x], 0.0f, 255.0f)); |
2392 | 6.89M | } else if (tile.channels.size() == 3) { |
2393 | 5.50M | g = round_to<u8>(clamp(tile.channels[1][y * w + x], 0.0f, 255.0f)); |
2394 | 5.50M | b = round_to<u8>(clamp(tile.channels[2][y * w + x], 0.0f, 255.0f)); |
2395 | 5.50M | } else if (tile.channels.size() == 4) { |
2396 | 10.2k | g = round_to<u8>(clamp(tile.channels[1][y * w + x], 0.0f, 255.0f)); |
2397 | 10.2k | b = round_to<u8>(clamp(tile.channels[2][y * w + x], 0.0f, 255.0f)); |
2398 | 10.2k | a = round_to<u8>(clamp(tile.channels[3][y * w + x], 0.0f, 255.0f)); |
2399 | 10.2k | } |
2400 | | |
2401 | 6.89M | Color pixel; |
2402 | 6.89M | pixel.set_red(r); |
2403 | 6.89M | pixel.set_green(g); |
2404 | 6.89M | pixel.set_blue(b); |
2405 | 6.89M | pixel.set_alpha(a); |
2406 | 6.89M | bitmap->set_pixel(x + tile.components[0].rect.left(), y + tile.components[0].rect.top(), pixel); |
2407 | 6.89M | } |
2408 | 23.8k | } |
2409 | 376 | } |
2410 | | |
2411 | | // FIXME: Could release sample data here, to reduce peak memory use. |
2412 | | |
2413 | 303 | context.bitmap = move(bitmap); |
2414 | | |
2415 | 303 | return {}; |
2416 | 303 | } |
2417 | | |
2418 | | static ErrorOr<void> decode_image(JPEG2000LoadingContext& context) |
2419 | 882 | { |
2420 | 882 | TRY(parse_codestream_tile_headers(context)); |
2421 | 529 | TRY(compute_decoding_metadata(context)); |
2422 | 503 | TRY(read_packet_headers(context)); |
2423 | 406 | TRY(decode_bitplanes_to_coefficients(context)); |
2424 | 384 | TRY(run_inverse_discrete_wavelet_transform(context)); |
2425 | 384 | TRY(postprocess_samples(context)); |
2426 | 383 | TRY(convert_to_bitmap(context)); |
2427 | | |
2428 | 0 | return {}; |
2429 | 383 | } |
2430 | | |
2431 | | bool JPEG2000ImageDecoderPlugin::sniff(ReadonlyBytes data) |
2432 | 2.05k | { |
2433 | 2.05k | return data.starts_with(jp2_id_string) || data.starts_with(marker_id_string); |
2434 | 2.05k | } |
2435 | | |
2436 | | JPEG2000ImageDecoderPlugin::JPEG2000ImageDecoderPlugin(JPEG2000DecoderOptions options) |
2437 | 2.05k | { |
2438 | 2.05k | m_context = make<JPEG2000LoadingContext>(); |
2439 | 2.05k | m_context->options = options; |
2440 | 2.05k | } |
2441 | | |
2442 | 2.05k | JPEG2000ImageDecoderPlugin::~JPEG2000ImageDecoderPlugin() = default; |
2443 | | |
2444 | | IntSize JPEG2000ImageDecoderPlugin::size() |
2445 | 0 | { |
2446 | 0 | return m_context->size; |
2447 | 0 | } |
2448 | | |
2449 | | static void determine_color_space(JPEG2000LoadingContext& context) |
2450 | 882 | { |
2451 | 882 | if (context.palette_box.has_value() && context.options.palette_handling == JPEG2000DecoderOptions::PaletteHandling::PaletteIndicesAsGrayscale) { |
2452 | | // context.color_box has the color space after palette expansion. But in this mode, we don't expand the palette. |
2453 | 0 | context.color_space = ColorSpace::Gray; |
2454 | 0 | return; |
2455 | 0 | } |
2456 | | |
2457 | 882 | if (context.color_box.has_value()) { |
2458 | 123 | if (context.color_box->method == ISOBMFF::JPEG2000ColorSpecificationBox::Method::Enumerated) { |
2459 | 108 | if (context.color_box->enumerated_color_space == ISOBMFF::JPEG2000ColorSpecificationBox::EnumCS::sRGB) { |
2460 | 62 | context.color_space = ColorSpace::sRGB; |
2461 | 62 | } else if (context.color_box->enumerated_color_space == ISOBMFF::JPEG2000ColorSpecificationBox::EnumCS::Greyscale) { |
2462 | 13 | context.color_space = ColorSpace::Gray; |
2463 | 33 | } else if (context.color_box->enumerated_color_space == ISOBMFF::JPEG2000ColorSpecificationBox::EnumCS::CMYK) { |
2464 | 2 | context.color_space = ColorSpace::CMYK; |
2465 | 31 | } else { |
2466 | 31 | context.color_space = ColorSpace::Unsupported; |
2467 | 31 | context.color_space_error = Error::from_string_literal("JPEG2000ImageDecoderPlugin: Only sRGB and grayscale enumerated color space supported yet"); |
2468 | 31 | } |
2469 | 108 | } else if (context.color_box->method == ISOBMFF::JPEG2000ColorSpecificationBox::Method::ICC_Restricted |
2470 | 15 | || context.color_box->method == ISOBMFF::JPEG2000ColorSpecificationBox::Method::ICC_Any) { |
2471 | 13 | auto icc_header_or_error = ICC::Profile::read_header(context.color_box->icc_data.bytes()); |
2472 | 13 | if (icc_header_or_error.is_error()) { |
2473 | 7 | context.color_space = ColorSpace::Unsupported; |
2474 | 7 | context.color_space_error = icc_header_or_error.release_error(); |
2475 | 7 | return; |
2476 | 7 | } |
2477 | | |
2478 | 6 | auto icc_header = icc_header_or_error.release_value(); |
2479 | 6 | if (icc_header.data_color_space == ICC::ColorSpace::RGB) { |
2480 | 6 | context.color_space = ColorSpace::sRGB; |
2481 | 6 | } else if (icc_header.data_color_space == ICC::ColorSpace::Gray) { |
2482 | 0 | context.color_space = ColorSpace::Gray; |
2483 | 0 | } else if (icc_header.data_color_space == ICC::ColorSpace::CMYK) { |
2484 | 0 | context.color_space = ColorSpace::CMYK; |
2485 | 0 | } else { |
2486 | 0 | context.color_space = ColorSpace::Unsupported; |
2487 | 0 | context.color_space_error = Error::from_string_literal("JPEG2000ImageDecoderPlugin: Only sRGB and grayscale ICC color space supported yet"); |
2488 | 0 | } |
2489 | 6 | } else { |
2490 | 2 | context.color_space = ColorSpace::Unsupported; |
2491 | 2 | context.color_space_error = Error::from_string_literal("JPEG2000ImageDecoderPlugin: Can only handle enumerated and ICC color specification methods yet"); |
2492 | 2 | } |
2493 | 759 | } else { |
2494 | | // Raw codestream. Go by number of components. |
2495 | 759 | context.color_space = context.siz.components.size() < 3 ? ColorSpace::Gray : ColorSpace::sRGB; |
2496 | 759 | } |
2497 | 882 | } |
2498 | | |
2499 | | ErrorOr<NonnullOwnPtr<ImageDecoderPlugin>> JPEG2000ImageDecoderPlugin::create(ReadonlyBytes data) |
2500 | 2.05k | { |
2501 | 2.05k | return create_with_options(data, {}); |
2502 | 2.05k | } |
2503 | | |
2504 | | ErrorOr<NonnullOwnPtr<ImageDecoderPlugin>> JPEG2000ImageDecoderPlugin::create_with_options(ReadonlyBytes data, JPEG2000DecoderOptions options) |
2505 | 2.05k | { |
2506 | 2.05k | auto plugin = TRY(adopt_nonnull_own_or_enomem(new (nothrow) JPEG2000ImageDecoderPlugin(options))); |
2507 | 2.05k | TRY(decode_jpeg2000_header(*plugin->m_context, data)); |
2508 | 0 | determine_color_space(*plugin->m_context); |
2509 | 882 | return plugin; |
2510 | 2.05k | } |
2511 | | |
2512 | | ErrorOr<ImageFrameDescriptor> JPEG2000ImageDecoderPlugin::frame(size_t index, Optional<IntSize>) |
2513 | 882 | { |
2514 | 882 | if (index != 0) |
2515 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Invalid frame index"); |
2516 | | |
2517 | 882 | if (m_context->state == JPEG2000LoadingContext::State::Error) |
2518 | 0 | return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Decoding failed"); |
2519 | | |
2520 | 882 | if (m_context->state < JPEG2000LoadingContext::State::DecodedImage) { |
2521 | 882 | TRY(decode_image(*m_context)); |
2522 | 0 | m_context->state = JPEG2000LoadingContext::State::DecodedImage; |
2523 | 305 | } |
2524 | | |
2525 | 305 | if (m_context->cmyk_bitmap && !m_context->bitmap) |
2526 | 2 | return ImageFrameDescriptor { TRY(m_context->cmyk_bitmap->to_low_quality_rgb()), 0 }; |
2527 | | |
2528 | 303 | return ImageFrameDescriptor { m_context->bitmap, 0 }; |
2529 | 305 | } |
2530 | | |
2531 | | ErrorOr<Optional<ReadonlyBytes>> JPEG2000ImageDecoderPlugin::icc_data() |
2532 | 0 | { |
2533 | 0 | if (m_context->color_box.has_value() |
2534 | 0 | && (m_context->color_box->method == ISOBMFF::JPEG2000ColorSpecificationBox::Method::ICC_Restricted |
2535 | 0 | || m_context->color_box->method == ISOBMFF::JPEG2000ColorSpecificationBox::Method::ICC_Any)) { |
2536 | 0 | return m_context->color_box->icc_data.bytes(); |
2537 | 0 | } |
2538 | | |
2539 | 0 | return OptionalNone {}; |
2540 | 0 | } |
2541 | | |
2542 | | NaturalFrameFormat JPEG2000ImageDecoderPlugin::natural_frame_format() const |
2543 | 0 | { |
2544 | 0 | if (m_context->state == JPEG2000LoadingContext::State::Error) |
2545 | 0 | return NaturalFrameFormat::RGB; |
2546 | | |
2547 | 0 | switch (m_context->color_space) { |
2548 | 0 | case ColorSpace::sRGB: |
2549 | 0 | return NaturalFrameFormat::RGB; |
2550 | 0 | case ColorSpace::Gray: |
2551 | 0 | return NaturalFrameFormat::Grayscale; |
2552 | 0 | case ColorSpace::CMYK: |
2553 | 0 | return NaturalFrameFormat::CMYK; |
2554 | 0 | case ColorSpace::Unsupported: |
2555 | 0 | return NaturalFrameFormat::RGB; |
2556 | 0 | } |
2557 | | |
2558 | 0 | VERIFY_NOT_REACHED(); |
2559 | 0 | } |
2560 | | |
2561 | | ErrorOr<NonnullRefPtr<CMYKBitmap>> JPEG2000ImageDecoderPlugin::cmyk_frame() |
2562 | 0 | { |
2563 | 0 | VERIFY(natural_frame_format() == NaturalFrameFormat::CMYK); |
2564 | | |
2565 | 0 | if (m_context->state < JPEG2000LoadingContext::State::DecodedImage) { |
2566 | 0 | if (auto result = decode_image(*m_context); result.is_error()) { |
2567 | 0 | m_context->state = JPEG2000LoadingContext::State::Error; |
2568 | 0 | return result.release_error(); |
2569 | 0 | } |
2570 | 0 | m_context->state = JPEG2000LoadingContext::State::DecodedImage; |
2571 | 0 | } |
2572 | | |
2573 | 0 | return *m_context->cmyk_bitmap; |
2574 | 0 | } |
2575 | | |
2576 | | } |