/src/jasper/src/libjasper/jp2/jp2_dec.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 1999-2000 Image Power, Inc. and the University of |
3 | | * British Columbia. |
4 | | * Copyright (c) 2001-2003 Michael David Adams. |
5 | | * All rights reserved. |
6 | | */ |
7 | | |
8 | | /* __START_OF_JASPER_LICENSE__ |
9 | | * |
10 | | * JasPer License Version 2.0 |
11 | | * |
12 | | * Copyright (c) 2001-2006 Michael David Adams |
13 | | * Copyright (c) 1999-2000 Image Power, Inc. |
14 | | * Copyright (c) 1999-2000 The University of British Columbia |
15 | | * |
16 | | * All rights reserved. |
17 | | * |
18 | | * Permission is hereby granted, free of charge, to any person (the |
19 | | * "User") obtaining a copy of this software and associated documentation |
20 | | * files (the "Software"), to deal in the Software without restriction, |
21 | | * including without limitation the rights to use, copy, modify, merge, |
22 | | * publish, distribute, and/or sell copies of the Software, and to permit |
23 | | * persons to whom the Software is furnished to do so, subject to the |
24 | | * following conditions: |
25 | | * |
26 | | * 1. The above copyright notices and this permission notice (which |
27 | | * includes the disclaimer below) shall be included in all copies or |
28 | | * substantial portions of the Software. |
29 | | * |
30 | | * 2. The name of a copyright holder shall not be used to endorse or |
31 | | * promote products derived from the Software without specific prior |
32 | | * written permission. |
33 | | * |
34 | | * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS |
35 | | * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER |
36 | | * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS |
37 | | * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING |
38 | | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A |
39 | | * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO |
40 | | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL |
41 | | * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING |
42 | | * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |
43 | | * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION |
44 | | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE |
45 | | * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE |
46 | | * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. |
47 | | * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS |
48 | | * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL |
49 | | * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS |
50 | | * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE |
51 | | * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE |
52 | | * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL |
53 | | * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, |
54 | | * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL |
55 | | * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH |
56 | | * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, |
57 | | * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH |
58 | | * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY |
59 | | * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. |
60 | | * |
61 | | * __END_OF_JASPER_LICENSE__ |
62 | | */ |
63 | | |
64 | | /* |
65 | | * JP2 Library |
66 | | * |
67 | | * $Id$ |
68 | | */ |
69 | | |
70 | | /******************************************************************************\ |
71 | | * Includes. |
72 | | \******************************************************************************/ |
73 | | |
74 | | #include "jp2_dec.h" |
75 | | #include "jp2_cod.h" |
76 | | |
77 | | #include "jasper/jas_image.h" |
78 | | #include "jasper/jas_stream.h" |
79 | | #include "jasper/jas_math.h" |
80 | | #include "jasper/jas_debug.h" |
81 | | #include "jasper/jas_malloc.h" |
82 | | #include "jasper/jas_types.h" |
83 | | |
84 | | #include <assert.h> |
85 | | #include <stdio.h> |
86 | | |
87 | | /******************************************************************************\ |
88 | | * Function prototypes. |
89 | | \******************************************************************************/ |
90 | | |
91 | | static jp2_dec_t *jp2_dec_create(void); |
92 | | static void jp2_dec_destroy(jp2_dec_t *dec); |
93 | | static int jp2_getcs(jp2_colr_t *colr); |
94 | | static int fromiccpcs(int cs); |
95 | | static int jp2_getct(int colorspace, int type, int assoc); |
96 | | |
97 | | /******************************************************************************\ |
98 | | * Functions. |
99 | | \******************************************************************************/ |
100 | | |
101 | | jas_image_t *jp2_decode(jas_stream_t *in, const char *optstr) |
102 | 19.7k | { |
103 | 19.7k | jp2_box_t *box; |
104 | 19.7k | int found; |
105 | 19.7k | jas_image_t *image; |
106 | 19.7k | jp2_dec_t *dec; |
107 | 19.7k | bool samedtype; |
108 | 19.7k | int dtype; |
109 | 19.7k | unsigned int i; |
110 | 19.7k | jp2_cmap_t *cmapd; |
111 | 19.7k | jp2_pclr_t *pclrd; |
112 | | #if 0 |
113 | | /* The following code appears to no longer be needed. */ |
114 | | jp2_cdef_t *cdefd; |
115 | | #endif |
116 | 19.7k | unsigned int channo; |
117 | 19.7k | int newcmptno; |
118 | 19.7k | int_fast32_t *lutents; |
119 | | #if 0 |
120 | | jp2_cdefchan_t *cdefent; |
121 | | int cmptno; |
122 | | #endif |
123 | 19.7k | jp2_cmapent_t *cmapent; |
124 | 19.7k | jas_icchdr_t icchdr; |
125 | 19.7k | jas_iccprof_t *iccprof; |
126 | | |
127 | 19.7k | dec = 0; |
128 | 19.7k | box = 0; |
129 | 19.7k | image = 0; |
130 | | |
131 | 19.7k | JAS_LOGDEBUGF(100, "jp2_decode(%p, \"%s\")\n", in, optstr); |
132 | | |
133 | 19.7k | if (!(dec = jp2_dec_create())) { |
134 | 0 | goto error; |
135 | 0 | } |
136 | | |
137 | | /* Get the first box. This should be a JP box. */ |
138 | 19.7k | if (!(box = jp2_box_get(in))) { |
139 | 7.77k | jas_logerrorf("error: cannot get box\n"); |
140 | 7.77k | goto error; |
141 | 7.77k | } |
142 | 11.9k | if (box->type != JP2_BOX_JP) { |
143 | 0 | jas_logerrorf("error: expecting signature box\n"); |
144 | 0 | goto error; |
145 | 0 | } |
146 | 11.9k | if (box->data.jp.magic != JP2_JP_MAGIC) { |
147 | 3.32k | jas_logerrorf("incorrect magic number (0x%lx != 0x%lx)\n", |
148 | 3.32k | JAS_CAST(unsigned long, box->data.jp.magic), |
149 | 3.32k | JAS_CAST(unsigned long, JP2_JP_MAGIC)); |
150 | 3.32k | goto error; |
151 | 3.32k | } |
152 | 8.59k | jp2_box_destroy(box); |
153 | 8.59k | box = 0; |
154 | | |
155 | | /* Get the second box. This should be a FTYP box. */ |
156 | 8.59k | if (!(box = jp2_box_get(in))) { |
157 | 629 | jas_logerrorf("error: cannot get box\n"); |
158 | 629 | goto error; |
159 | 629 | } |
160 | 7.96k | if (box->type != JP2_BOX_FTYP) { |
161 | 302 | jas_logerrorf("expecting file type box\n"); |
162 | 302 | goto error; |
163 | 302 | } |
164 | 7.66k | jp2_box_destroy(box); |
165 | 7.66k | box = 0; |
166 | | |
167 | | /* Get more boxes... */ |
168 | 7.66k | found = 0; |
169 | 32.5k | while ((box = jp2_box_get(in))) { |
170 | 30.6k | if (jas_get_debug_level() >= 1) { |
171 | 0 | jas_logdebugf(1, "got box type %s\n", box->info->name); |
172 | 0 | } |
173 | 30.6k | switch (box->type) { |
174 | 5.77k | case JP2_BOX_JP2C: |
175 | 5.77k | found = 1; |
176 | 5.77k | break; |
177 | 2.61k | case JP2_BOX_IHDR: |
178 | 2.61k | if (!dec->ihdr) { |
179 | 1.54k | dec->ihdr = box; |
180 | 1.54k | box = 0; |
181 | 1.54k | } |
182 | 2.61k | break; |
183 | 1.54k | case JP2_BOX_BPCC: |
184 | 1.54k | if (!dec->bpcc) { |
185 | 100 | dec->bpcc = box; |
186 | 100 | box = 0; |
187 | 100 | } |
188 | 1.54k | break; |
189 | 944 | case JP2_BOX_CDEF: |
190 | 944 | if (!dec->cdef) { |
191 | 168 | dec->cdef = box; |
192 | 168 | box = 0; |
193 | 168 | } |
194 | 944 | break; |
195 | 1.43k | case JP2_BOX_PCLR: |
196 | 1.43k | if (!dec->pclr) { |
197 | 163 | dec->pclr = box; |
198 | 163 | box = 0; |
199 | 163 | } |
200 | 1.43k | break; |
201 | 876 | case JP2_BOX_CMAP: |
202 | 876 | if (!dec->cmap) { |
203 | 164 | dec->cmap = box; |
204 | 164 | box = 0; |
205 | 164 | } |
206 | 876 | break; |
207 | 3.57k | case JP2_BOX_COLR: |
208 | 3.57k | if (!dec->colr) { |
209 | 1.99k | dec->colr = box; |
210 | 1.99k | box = 0; |
211 | 1.99k | } |
212 | 3.57k | break; |
213 | 30.6k | } |
214 | 30.6k | if (box) { |
215 | 26.5k | jp2_box_destroy(box); |
216 | 26.5k | box = 0; |
217 | 26.5k | } |
218 | 30.6k | if (found) { |
219 | 5.77k | break; |
220 | 5.77k | } |
221 | 30.6k | } |
222 | | |
223 | 7.66k | if (!found) { |
224 | 1.89k | jas_logerrorf("error: no code stream found\n"); |
225 | 1.89k | goto error; |
226 | 1.89k | } |
227 | | |
228 | 5.77k | if (!(dec->image = jpc_decode(in, optstr))) { |
229 | 3.93k | jas_logerrorf("error: cannot decode code stream\n"); |
230 | 3.93k | goto error; |
231 | 3.93k | } |
232 | | |
233 | | /* An IHDR box must be present. */ |
234 | 1.84k | if (!dec->ihdr) { |
235 | 517 | jas_logerrorf("error: missing IHDR box\n"); |
236 | 517 | goto error; |
237 | 517 | } |
238 | | |
239 | | /* Does the number of components indicated in the IHDR box match |
240 | | the value specified in the code stream? */ |
241 | 1.32k | if (dec->ihdr->data.ihdr.numcmpts != JAS_CAST(jas_uint, |
242 | 1.32k | jas_image_numcmpts(dec->image))) { |
243 | 31 | jas_logerrorf("error: number of components mismatch (IHDR)\n"); |
244 | 31 | goto error; |
245 | 31 | } |
246 | | |
247 | | /* At least one component must be present. */ |
248 | 1.29k | if (!jas_image_numcmpts(dec->image)) { |
249 | 0 | jas_logerrorf("error: no components\n"); |
250 | 0 | goto error; |
251 | 0 | } |
252 | | |
253 | | /* Determine if all components have the same data type. */ |
254 | 1.29k | samedtype = true; |
255 | 1.29k | dtype = jas_image_cmptdtype(dec->image, 0); |
256 | 2.32k | for (i = 1; i < JAS_CAST(jas_uint, jas_image_numcmpts(dec->image)); ++i) { |
257 | 1.27k | if (jas_image_cmptdtype(dec->image, i) != dtype) { |
258 | 242 | samedtype = false; |
259 | 242 | break; |
260 | 242 | } |
261 | 1.27k | } |
262 | | |
263 | | /* Is the component data type indicated in the IHDR box consistent |
264 | | with the data in the code stream? */ |
265 | 1.29k | if ((samedtype && dec->ihdr->data.ihdr.bpc != JP2_DTYPETOBPC(dtype)) || |
266 | 1.28k | (!samedtype && dec->ihdr->data.ihdr.bpc != JP2_IHDR_BPCNULL)) { |
267 | 18 | jas_logerrorf("error: component data type mismatch (IHDR)\n"); |
268 | 18 | goto error; |
269 | 18 | } |
270 | | |
271 | | /* Is the compression type supported? */ |
272 | 1.27k | if (dec->ihdr->data.ihdr.comptype != JP2_IHDR_COMPTYPE) { |
273 | 13 | jas_logerrorf("error: unsupported compression type\n"); |
274 | 13 | goto error; |
275 | 13 | } |
276 | | |
277 | 1.26k | if (dec->bpcc) { |
278 | | /* Is the number of components indicated in the BPCC box |
279 | | consistent with the code stream data? */ |
280 | 26 | if (dec->bpcc->data.bpcc.numcmpts != |
281 | 26 | JAS_CAST(jas_uint, jas_image_numcmpts(dec->image))) { |
282 | 2 | jas_logerrorf("error: number of components mismatch (BPCC)\n"); |
283 | 2 | goto error; |
284 | 2 | } |
285 | | /* Is the component data type information indicated in the BPCC |
286 | | box consistent with the code stream data? */ |
287 | 24 | if (!samedtype) { |
288 | 92 | for (i = 0; i < JAS_CAST(jas_uint, jas_image_numcmpts(dec->image)); |
289 | 77 | ++i) { |
290 | 77 | if (jas_image_cmptdtype(dec->image, i) != |
291 | 77 | JP2_BPCTODTYPE(dec->bpcc->data.bpcc.bpcs[i])) { |
292 | 7 | jas_logerrorf("error: component data type mismatch (BPCC)\n"); |
293 | 7 | goto error; |
294 | 7 | } |
295 | 77 | } |
296 | 22 | } else { |
297 | 2 | jas_logwarnf("warning: superfluous BPCC box\n"); |
298 | 2 | } |
299 | 24 | } |
300 | | |
301 | | /* A COLR box must be present. */ |
302 | 1.25k | if (!dec->colr) { |
303 | 5 | jas_logerrorf("error: no COLR box\n"); |
304 | 5 | goto error; |
305 | 5 | } |
306 | | |
307 | 1.24k | switch (dec->colr->data.colr.method) { |
308 | 236 | case JP2_COLR_ENUM: |
309 | 236 | jas_image_setclrspc(dec->image, jp2_getcs(&dec->colr->data.colr)); |
310 | 236 | break; |
311 | 287 | case JP2_COLR_ICC: |
312 | 287 | iccprof = jas_iccprof_createfrombuf(dec->colr->data.colr.iccp, |
313 | 287 | dec->colr->data.colr.iccplen); |
314 | 287 | if (!iccprof) { |
315 | 219 | jas_logerrorf("error: failed to parse ICC profile\n"); |
316 | 219 | goto error; |
317 | 219 | } |
318 | 68 | jas_iccprof_gethdr(iccprof, &icchdr); |
319 | 68 | JAS_LOGDEBUGF(2, "ICC Profile CS %08x\n", icchdr.colorspc); |
320 | 68 | dec->image->cmprof_ = jas_cmprof_createfromiccprof(iccprof); |
321 | 68 | if (!dec->image->cmprof_) { |
322 | 68 | jas_image_setclrspc(dec->image, JAS_CLRSPC_UNKNOWN); |
323 | 68 | jas_logwarnf("warning: cannot create CM profile from ICC profile\n"); |
324 | 68 | } else { |
325 | 0 | jas_image_setclrspc(dec->image, fromiccpcs(icchdr.colorspc)); |
326 | 0 | } |
327 | 68 | jas_iccprof_destroy(iccprof); |
328 | 68 | break; |
329 | 1.24k | } |
330 | | |
331 | | /* If a CMAP box is present, a PCLR box must also be present. */ |
332 | 1.02k | if (dec->cmap && !dec->pclr) { |
333 | 1 | jas_logwarnf("warning: missing PCLR box or superfluous CMAP box\n"); |
334 | 1 | jp2_box_destroy(dec->cmap); |
335 | 1 | dec->cmap = 0; |
336 | 1 | } |
337 | | |
338 | | /* If a CMAP box is not present, a PCLR box must not be present. */ |
339 | 1.02k | if (!dec->cmap && dec->pclr) { |
340 | 3 | jas_logwarnf("warning: missing CMAP box or superfluous PCLR box\n"); |
341 | 3 | jp2_box_destroy(dec->pclr); |
342 | 3 | dec->pclr = 0; |
343 | 3 | } |
344 | | |
345 | | /* Determine the number of channels (which is essentially the number |
346 | | of components after any palette mappings have been applied). */ |
347 | 1.02k | dec->numchans = dec->cmap ? dec->cmap->data.cmap.numchans : |
348 | 1.02k | JAS_CAST(jas_uint, jas_image_numcmpts(dec->image)); |
349 | | |
350 | | /* Perform a basic sanity check on the CMAP box if present. */ |
351 | 1.02k | if (dec->cmap) { |
352 | 332 | for (i = 0; i < dec->numchans; ++i) { |
353 | | /* Is the component number reasonable? */ |
354 | 259 | if (dec->cmap->data.cmap.ents[i].cmptno >= JAS_CAST(jas_uint, |
355 | 259 | jas_image_numcmpts(dec->image))) { |
356 | 15 | jas_logerrorf("error: invalid component number in CMAP box\n"); |
357 | 15 | goto error; |
358 | 15 | } |
359 | | /* Is the LUT index reasonable? */ |
360 | 244 | if (dec->cmap->data.cmap.ents[i].pcol >= |
361 | 244 | dec->pclr->data.pclr.numchans) { |
362 | 3 | jas_logerrorf("error: invalid CMAP LUT index\n"); |
363 | 3 | goto error; |
364 | 3 | } |
365 | 244 | } |
366 | 91 | } |
367 | | |
368 | | /* Allocate space for the channel-number to component-number LUT. */ |
369 | 1.01k | if (!(dec->chantocmptlut = jas_alloc2(dec->numchans, |
370 | 1.01k | sizeof(uint_fast16_t)))) { |
371 | 0 | jas_logerrorf("error: no memory\n"); |
372 | 0 | goto error; |
373 | 0 | } |
374 | | |
375 | 1.01k | if (!dec->cmap) { |
376 | 2.81k | for (i = 0; i < dec->numchans; ++i) { |
377 | 1.88k | dec->chantocmptlut[i] = i; |
378 | 1.88k | } |
379 | 937 | } else { |
380 | | /* Check to ensure that CMAP/PCLR were initialized. */ |
381 | 73 | if (!dec->cmap || !dec->pclr) { |
382 | 0 | jas_logerrorf("missing CMAP/PCLR box\n"); |
383 | 0 | goto error; |
384 | 0 | } |
385 | | |
386 | 73 | cmapd = &dec->cmap->data.cmap; |
387 | 73 | pclrd = &dec->pclr->data.pclr; |
388 | | #if 0 |
389 | | /* The following code appears to no longer be needed. */ |
390 | | cdefd = &dec->cdef->data.cdef; |
391 | | #endif |
392 | 247 | for (channo = 0; channo < cmapd->numchans; ++channo) { |
393 | 203 | cmapent = &cmapd->ents[channo]; |
394 | 203 | if (cmapent->map == JP2_CMAP_DIRECT) { |
395 | 34 | dec->chantocmptlut[channo] = channo; |
396 | 169 | } else if (cmapent->map == JP2_CMAP_PALETTE) { |
397 | 141 | if (!pclrd->numlutents) { |
398 | 0 | jas_logerrorf("error: empty LUT\n"); |
399 | 0 | goto error; |
400 | 0 | } |
401 | 141 | if (!(lutents = jas_alloc2(pclrd->numlutents, |
402 | 141 | sizeof(int_fast32_t)))) { |
403 | 0 | jas_logerrorf("error: cannot allocate LUT\n"); |
404 | 0 | goto error; |
405 | 0 | } |
406 | 18.9k | for (i = 0; i < pclrd->numlutents; ++i) { |
407 | 18.8k | lutents[i] = pclrd->lutdata[cmapent->pcol + i * pclrd->numchans]; |
408 | 18.8k | } |
409 | 141 | newcmptno = jas_image_numcmpts(dec->image); |
410 | 141 | if (jas_image_depalettize(dec->image, cmapent->cmptno, |
411 | 141 | pclrd->numlutents, lutents, |
412 | 141 | JP2_BPCTODTYPE(pclrd->bpc[cmapent->pcol]), newcmptno)) { |
413 | 1 | jas_logerrorf("jas_image_depalettize failed\n"); |
414 | 1 | jas_free(lutents); |
415 | 1 | jas_logerrorf("error: depalettize failed\n"); |
416 | 1 | goto error; |
417 | 1 | } |
418 | 140 | dec->chantocmptlut[channo] = newcmptno; |
419 | 140 | jas_free(lutents); |
420 | | #if 0 |
421 | | /* The following code appears to no longer be needed. */ |
422 | | if (dec->cdef) { |
423 | | cdefent = jp2_cdef_lookup(cdefd, channo); |
424 | | if (!cdefent) { |
425 | | abort(); |
426 | | } |
427 | | jas_image_setcmpttype(dec->image, newcmptno, jp2_getct(jas_image_clrspc(dec->image), cdefent->type, cdefent->assoc)); |
428 | | } else { |
429 | | jas_image_setcmpttype(dec->image, newcmptno, jp2_getct(jas_image_clrspc(dec->image), 0, channo + 1)); |
430 | | } |
431 | | #endif |
432 | 140 | } else { |
433 | 28 | jas_logerrorf("error: invalid MTYP in CMAP box\n"); |
434 | 28 | goto error; |
435 | 28 | } |
436 | 203 | } |
437 | 73 | } |
438 | | |
439 | | #if 0 |
440 | | /* The following code appears to no longer be needed. */ |
441 | | /* Ensure that the number of channels being used by the decoder |
442 | | matches the number of image components. */ |
443 | | if (dec->numchans != jas_image_numcmpts(dec->image)) { |
444 | | jas_logerrorf("error: mismatch in number of components (%d != %d)\n", |
445 | | dec->numchans, jas_image_numcmpts(dec->image)); |
446 | | goto error; |
447 | | } |
448 | | #endif |
449 | | |
450 | | /* Mark all components as being of unknown type. */ |
451 | | |
452 | 3.00k | for (i = 0; i < JAS_CAST(jas_uint, jas_image_numcmpts(dec->image)); ++i) { |
453 | 2.02k | jas_image_setcmpttype(dec->image, i, JAS_IMAGE_CT_UNKNOWN); |
454 | 2.02k | } |
455 | | |
456 | | /* Determine the type of each component. */ |
457 | 981 | if (dec->cdef) { |
458 | 308 | for (i = 0; i < dec->cdef->data.cdef.numchans; ++i) { |
459 | 257 | uint_fast16_t channo = dec->cdef->data.cdef.ents[i].channo; |
460 | | /* Is the channel number reasonable? */ |
461 | 257 | if (channo >= dec->numchans) { |
462 | 24 | jas_logerrorf("error: invalid channel number in CDEF box (%d)\n", |
463 | 24 | channo); |
464 | 24 | goto error; |
465 | 24 | } |
466 | 233 | unsigned compno = dec->chantocmptlut[channo]; |
467 | 233 | if (compno >= jas_image_numcmpts(dec->image)) { |
468 | 1 | jas_logerrorf( |
469 | 1 | "error: invalid component reference in CDEF box (%d)\n", |
470 | 1 | compno); |
471 | 1 | goto error; |
472 | 1 | } |
473 | 232 | jas_image_setcmpttype(dec->image, compno, |
474 | 232 | jp2_getct(jas_image_clrspc(dec->image), |
475 | 232 | dec->cdef->data.cdef.ents[i].type, |
476 | 232 | dec->cdef->data.cdef.ents[i].assoc)); |
477 | 232 | } |
478 | 905 | } else { |
479 | 2.63k | for (i = 0; i < dec->numchans; ++i) { |
480 | 1.73k | unsigned compno = dec->chantocmptlut[i]; |
481 | 1.73k | if (compno >= jas_image_numcmpts(dec->image)) { |
482 | 2 | jas_logerrorf( |
483 | 2 | "error: invalid component reference (%d)\n", compno); |
484 | 2 | goto error; |
485 | 2 | } |
486 | 1.73k | jas_image_setcmpttype(dec->image, compno, |
487 | 1.73k | jp2_getct(jas_image_clrspc(dec->image), 0, i + 1)); |
488 | 1.73k | } |
489 | 905 | } |
490 | | |
491 | | /* Delete any components that are not of interest. */ |
492 | 2.88k | for (i = jas_image_numcmpts(dec->image); i > 0; --i) { |
493 | 1.93k | if (jas_image_cmpttype(dec->image, i - 1) == JAS_IMAGE_CT_UNKNOWN) { |
494 | 74 | jas_image_delcmpt(dec->image, i - 1); |
495 | 74 | } |
496 | 1.93k | } |
497 | | |
498 | | /* Ensure that some components survived. */ |
499 | 954 | if (!jas_image_numcmpts(dec->image)) { |
500 | 8 | jas_logerrorf("error: no components\n"); |
501 | 8 | goto error; |
502 | 8 | } |
503 | | |
504 | | /* Prevent the image from being destroyed later. */ |
505 | 946 | image = dec->image; |
506 | 946 | dec->image = 0; |
507 | | |
508 | 946 | jp2_dec_destroy(dec); |
509 | | |
510 | 946 | return image; |
511 | | |
512 | 18.7k | error: |
513 | 18.7k | if (image) { |
514 | 0 | jas_image_destroy(image); |
515 | 0 | } |
516 | 18.7k | if (box) { |
517 | 3.62k | jp2_box_destroy(box); |
518 | 3.62k | } |
519 | 18.7k | if (dec) { |
520 | 18.7k | jp2_dec_destroy(dec); |
521 | 18.7k | } |
522 | 18.7k | return 0; |
523 | 954 | } |
524 | | |
525 | | #define JP2_VALIDATE_LEN JAS_MIN(JP2_JP_LEN + 4, JAS_STREAM_MAXPUTBACK) |
526 | | int jp2_validate(jas_stream_t *in) |
527 | 0 | { |
528 | 0 | unsigned char buf[JP2_VALIDATE_LEN]; |
529 | | |
530 | | /* Read the validation data (i.e., the data used for detecting |
531 | | the format). */ |
532 | 0 | assert(sizeof(buf) <= JAS_STREAM_MAXPUTBACK); |
533 | 0 | if (jas_stream_peek(in, buf, sizeof(buf)) != sizeof(buf)) { |
534 | 0 | return -1; |
535 | 0 | } |
536 | | |
537 | | /* Is the box type correct? */ |
538 | 0 | assert(JP2_VALIDATE_LEN >= 8); |
539 | 0 | if (((JAS_CAST(uint_least32_t, buf[4]) << 24) | |
540 | 0 | (JAS_CAST(uint_least32_t, buf[5]) << 16) | |
541 | 0 | (JAS_CAST(uint_least32_t, buf[6] << 8)) | |
542 | 0 | (JAS_CAST(uint_least32_t, buf[7]))) != |
543 | 0 | JP2_BOX_JP) { |
544 | 0 | return -1; |
545 | 0 | } |
546 | | |
547 | 0 | return 0; |
548 | 0 | } |
549 | | |
550 | | static jp2_dec_t *jp2_dec_create(void) |
551 | 19.7k | { |
552 | 19.7k | jp2_dec_t *dec; |
553 | | |
554 | 19.7k | if (!(dec = jas_malloc(sizeof(jp2_dec_t)))) { |
555 | 0 | return 0; |
556 | 0 | } |
557 | 19.7k | dec->ihdr = 0; |
558 | 19.7k | dec->bpcc = 0; |
559 | 19.7k | dec->cdef = 0; |
560 | 19.7k | dec->pclr = 0; |
561 | 19.7k | dec->image = 0; |
562 | 19.7k | dec->chantocmptlut = 0; |
563 | 19.7k | dec->cmap = 0; |
564 | 19.7k | dec->colr = 0; |
565 | 19.7k | return dec; |
566 | 19.7k | } |
567 | | |
568 | | static void jp2_dec_destroy(jp2_dec_t *dec) |
569 | 19.7k | { |
570 | 19.7k | if (dec->ihdr) { |
571 | 1.54k | jp2_box_destroy(dec->ihdr); |
572 | 1.54k | } |
573 | 19.7k | if (dec->bpcc) { |
574 | 100 | jp2_box_destroy(dec->bpcc); |
575 | 100 | } |
576 | 19.7k | if (dec->cdef) { |
577 | 168 | jp2_box_destroy(dec->cdef); |
578 | 168 | } |
579 | 19.7k | if (dec->pclr) { |
580 | 160 | jp2_box_destroy(dec->pclr); |
581 | 160 | } |
582 | 19.7k | if (dec->image) { |
583 | 894 | jas_image_destroy(dec->image); |
584 | 894 | } |
585 | 19.7k | if (dec->cmap) { |
586 | 163 | jp2_box_destroy(dec->cmap); |
587 | 163 | } |
588 | 19.7k | if (dec->colr) { |
589 | 1.99k | jp2_box_destroy(dec->colr); |
590 | 1.99k | } |
591 | 19.7k | if (dec->chantocmptlut) { |
592 | 1.01k | jas_free(dec->chantocmptlut); |
593 | 1.01k | } |
594 | 19.7k | jas_free(dec); |
595 | 19.7k | } |
596 | | |
597 | | static int jp2_getct(int colorspace, int type, int assoc) |
598 | 1.96k | { |
599 | 1.96k | if (type == 1 && assoc == 0) { |
600 | 5 | return JAS_IMAGE_CT_OPACITY; |
601 | 5 | } |
602 | 1.95k | if (type == 0 && assoc >= 1 && assoc <= 65534) { |
603 | 1.87k | switch (colorspace) { |
604 | 0 | case JAS_CLRSPC_FAM_RGB: |
605 | 0 | switch (assoc) { |
606 | 0 | case JP2_CDEF_RGB_R: |
607 | 0 | return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R); |
608 | 0 | case JP2_CDEF_RGB_G: |
609 | 0 | return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G); |
610 | 0 | case JP2_CDEF_RGB_B: |
611 | 0 | return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B); |
612 | 0 | } |
613 | 0 | break; |
614 | 0 | case JAS_CLRSPC_FAM_YCBCR: |
615 | 0 | switch (assoc) { |
616 | 0 | case JP2_CDEF_YCBCR_Y: |
617 | 0 | return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_Y); |
618 | 0 | case JP2_CDEF_YCBCR_CB: |
619 | 0 | return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CB); |
620 | 0 | case JP2_CDEF_YCBCR_CR: |
621 | 0 | return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CR); |
622 | 0 | } |
623 | 0 | break; |
624 | 0 | case JAS_CLRSPC_FAM_GRAY: |
625 | 0 | switch (assoc) { |
626 | 0 | case JP2_CDEF_GRAY_Y: |
627 | 0 | return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y); |
628 | 0 | } |
629 | 0 | break; |
630 | 1.87k | default: |
631 | 1.87k | return JAS_IMAGE_CT_COLOR(assoc - 1); |
632 | 1.87k | } |
633 | 1.87k | } |
634 | 82 | return JAS_IMAGE_CT_UNKNOWN; |
635 | 1.95k | } |
636 | | |
637 | | static int jp2_getcs(jp2_colr_t *colr) |
638 | 236 | { |
639 | 236 | if (colr->method == JP2_COLR_ENUM) { |
640 | 236 | switch (colr->csid) { |
641 | 77 | case JP2_COLR_SRGB: |
642 | 77 | return JAS_CLRSPC_SRGB; |
643 | 92 | case JP2_COLR_SYCC: |
644 | 92 | return JAS_CLRSPC_SYCBCR; |
645 | 12 | case JP2_COLR_SGRAY: |
646 | 12 | return JAS_CLRSPC_SGRAY; |
647 | 236 | } |
648 | 236 | } |
649 | 55 | return JAS_CLRSPC_UNKNOWN; |
650 | 236 | } |
651 | | |
652 | | static int fromiccpcs(int cs) |
653 | 0 | { |
654 | 0 | switch (cs) { |
655 | 0 | case ICC_CS_RGB: |
656 | 0 | return JAS_CLRSPC_GENRGB; |
657 | 0 | case ICC_CS_YCBCR: |
658 | 0 | return JAS_CLRSPC_GENYCBCR; |
659 | 0 | case ICC_CS_GRAY: |
660 | 0 | return JAS_CLRSPC_GENGRAY; |
661 | 0 | } |
662 | 0 | return JAS_CLRSPC_UNKNOWN; |
663 | 0 | } |