1 /*
2  * Copyright (c) 1999-2000 Image Power, Inc. and the University of
3  *   British Columbia.
4  * Copyright (c) 2001-2002 Michael David Adams.
5  * All rights reserved.
6  */
7 
8 /* __START_OF_JASPER_LICENSE__
9  *
10  * JasPer Software License
11  *
12  * IMAGE POWER JPEG-2000 PUBLIC LICENSE
13  * ************************************
14  *
15  * GRANT:
16  *
17  * Permission is hereby granted, free of charge, to any person (the "User")
18  * obtaining a copy of this software and associated documentation, to deal
19  * in the JasPer Software without restriction, including without limitation
20  * the right to use, copy, modify, merge, publish, distribute, sublicense,
21  * and/or sell copies of the JasPer Software (in source and binary forms),
22  * and to permit persons to whom the JasPer Software is furnished to do so,
23  * provided further that the License Conditions below are met.
24  *
25  * License Conditions
26  * ******************
27  *
28  * A.  Redistributions of source code must retain the above copyright notice,
29  * and this list of conditions, and the following disclaimer.
30  *
31  * B.  Redistributions in binary form must reproduce the above copyright
32  * notice, and this list of conditions, and the following disclaimer in
33  * the documentation and/or other materials provided with the distribution.
34  *
35  * C.  Neither the name of Image Power, Inc. nor any other contributor
36  * (including, but not limited to, the University of British Columbia and
37  * Michael David Adams) may be used to endorse or promote products derived
38  * from this software without specific prior written permission.
39  *
40  * D.  User agrees that it shall not commence any action against Image Power,
41  * Inc., the University of British Columbia, Michael David Adams, or any
42  * other contributors (collectively "Licensors") for infringement of any
43  * intellectual property rights ("IPR") held by the User in respect of any
44  * technology that User owns or has a right to license or sublicense and
45  * which is an element required in order to claim compliance with ISO/IEC
46  * 15444-1 (i.e., JPEG-2000 Part 1).  "IPR" means all intellectual property
47  * rights worldwide arising under statutory or common law, and whether
48  * or not perfected, including, without limitation, all (i) patents and
49  * patent applications owned or licensable by User; (ii) rights associated
50  * with works of authorship including copyrights, copyright applications,
51  * copyright registrations, mask work rights, mask work applications,
52  * mask work registrations; (iii) rights relating to the protection of
53  * trade secrets and confidential information; (iv) any right analogous
54  * to those set forth in subsections (i), (ii), or (iii) and any other
55  * proprietary rights relating to intangible property (other than trademark,
56  * trade dress, or service mark rights); and (v) divisions, continuations,
57  * renewals, reissues and extensions of the foregoing (as and to the extent
58  * applicable) now existing, hereafter filed, issued or acquired.
59  *
60  * E.  If User commences an infringement action against any Licensor(s) then
61  * such Licensor(s) shall have the right to terminate User's license and
62  * all sublicenses that have been granted hereunder by User to other parties.
63  *
64  * F.  This software is for use only in hardware or software products that
65  * are compliant with ISO/IEC 15444-1 (i.e., JPEG-2000 Part 1).  No license
66  * or right to this Software is granted for products that do not comply
67  * with ISO/IEC 15444-1.  The JPEG-2000 Part 1 standard can be purchased
68  * from the ISO.
69  *
70  * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE.
71  * NO USE OF THE JASPER SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
72  * THIS DISCLAIMER.  THE JASPER SOFTWARE IS PROVIDED BY THE LICENSORS AND
73  * CONTRIBUTORS UNDER THIS LICENSE ON AN ``AS-IS'' BASIS, WITHOUT WARRANTY
74  * OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION,
75  * WARRANTIES THAT THE JASPER SOFTWARE IS FREE OF DEFECTS, IS MERCHANTABLE,
76  * IS FIT FOR A PARTICULAR PURPOSE OR IS NON-INFRINGING.  THOSE INTENDING
77  * TO USE THE JASPER SOFTWARE OR MODIFICATIONS THEREOF FOR USE IN HARDWARE
78  * OR SOFTWARE PRODUCTS ARE ADVISED THAT THEIR USE MAY INFRINGE EXISTING
79  * PATENTS, COPYRIGHTS, TRADEMARKS, OR OTHER INTELLECTUAL PROPERTY RIGHTS.
80  * THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE JASPER SOFTWARE
81  * IS WITH THE USER.  SHOULD ANY PART OF THE JASPER SOFTWARE PROVE DEFECTIVE
82  * IN ANY RESPECT, THE USER (AND NOT THE INITIAL DEVELOPERS, THE UNIVERSITY
83  * OF BRITISH COLUMBIA, IMAGE POWER, INC., MICHAEL DAVID ADAMS, OR ANY
84  * OTHER CONTRIBUTOR) SHALL ASSUME THE COST OF ANY NECESSARY SERVICING,
85  * REPAIR OR CORRECTION.  UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY,
86  * WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL THE
87  * INITIAL DEVELOPER, THE UNIVERSITY OF BRITISH COLUMBIA, IMAGE POWER, INC.,
88  * MICHAEL DAVID ADAMS, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF THE
89  * JASPER SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO
90  * THE USER OR ANY OTHER PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR
91  * CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION,
92  * DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR
93  * MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF
94  * SUCH PARTY HAD BEEN INFORMED, OR OUGHT TO HAVE KNOWN, OF THE POSSIBILITY
95  * OF SUCH DAMAGES.  THE JASPER SOFTWARE AND UNDERLYING TECHNOLOGY ARE NOT
96  * FAULT-TOLERANT AND ARE NOT DESIGNED, MANUFACTURED OR INTENDED FOR USE OR
97  * RESALE AS ON-LINE CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING
98  * FAIL-SAFE PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES,
99  * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT
100  * LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
101  * JASPER SOFTWARE OR UNDERLYING TECHNOLOGY OR PRODUCT COULD LEAD DIRECTLY
102  * TO DEATH, PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE
103  * ("HIGH RISK ACTIVITIES").  LICENSOR SPECIFICALLY DISCLAIMS ANY EXPRESS
104  * OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.  USER WILL NOT
105  * KNOWINGLY USE, DISTRIBUTE OR RESELL THE JASPER SOFTWARE OR UNDERLYING
106  * TECHNOLOGY OR PRODUCTS FOR HIGH RISK ACTIVITIES AND WILL ENSURE THAT ITS
107  * CUSTOMERS AND END-USERS OF ITS PRODUCTS ARE PROVIDED WITH A COPY OF THE
108  * NOTICE SPECIFIED IN THIS SECTION.
109  *
110  * __END_OF_JASPER_LICENSE__
111  */
112 
113 /*
114  * JP2 Library
115  *
116  * $Id$
117  */
118 
119 /******************************************************************************\
120 * Includes.
121 \******************************************************************************/
122 
123 #include <assert.h>
124 #include <stdlib.h>
125 
126 #include "netpbm/pm_c_util.h"
127 
128 #include "jasper/jas_stream.h"
129 #include "jasper/jas_malloc.h"
130 #include "jasper/jas_debug.h"
131 
132 #include "jp2_cod.h"
133 
134 /******************************************************************************\
135 * Function prototypes.
136 \******************************************************************************/
137 
138 #define ONES(n) ((1 << (n)) - 1)
139 
140 jp2_boxinfo_t *jp2_boxinfolookup(int type);
141 
142 static int jp2_getuint8(jas_stream_t *in, uint_fast8_t *val);
143 static int jp2_getuint16(jas_stream_t *in, uint_fast16_t *val);
144 static int jp2_getuint32(jas_stream_t *in, uint_fast32_t *val);
145 static int jp2_getuint64(jas_stream_t *in, uint_fast64_t *val);
146 static int jp2_putuint8(jas_stream_t *out, uint_fast8_t val);
147 static int jp2_putuint16(jas_stream_t *out, uint_fast16_t val);
148 static int jp2_putuint32(jas_stream_t *out, uint_fast32_t val);
149 
150 static int jp2_getint(jas_stream_t *in, int s, int n, int_fast32_t *val);
151 
152 jp2_box_t *jp2_box_get(jas_stream_t *in);
153 void jp2_box_dump(jp2_box_t *box, FILE *out);
154 
155 static int jp2_jp_getdata(jp2_box_t *box, jas_stream_t *in);
156 static int jp2_jp_putdata(jp2_box_t *box, jas_stream_t *out);
157 static int jp2_ftyp_getdata(jp2_box_t *box, jas_stream_t *in);
158 static int jp2_ftyp_putdata(jp2_box_t *box, jas_stream_t *out);
159 static int jp2_ihdr_getdata(jp2_box_t *box, jas_stream_t *in);
160 static int jp2_ihdr_putdata(jp2_box_t *box, jas_stream_t *out);
161 static void jp2_bpcc_destroy(jp2_box_t *box);
162 static int jp2_bpcc_getdata(jp2_box_t *box, jas_stream_t *in);
163 static int jp2_bpcc_putdata(jp2_box_t *box, jas_stream_t *out);
164 static int jp2_colr_getdata(jp2_box_t *box, jas_stream_t *in);
165 static int jp2_colr_putdata(jp2_box_t *box, jas_stream_t *out);
166 static void jp2_colr_dumpdata(jp2_box_t *box, FILE *out);
167 static void jp2_colr_destroy(jp2_box_t *box);
168 static void jp2_cdef_destroy(jp2_box_t *box);
169 static int jp2_cdef_getdata(jp2_box_t *box, jas_stream_t *in);
170 static int jp2_cdef_putdata(jp2_box_t *box, jas_stream_t *out);
171 static void jp2_cdef_dumpdata(jp2_box_t *box, FILE *out);
172 static void jp2_cmap_destroy(jp2_box_t *box);
173 static int jp2_cmap_getdata(jp2_box_t *box, jas_stream_t *in);
174 static int jp2_cmap_putdata(jp2_box_t *box, jas_stream_t *out);
175 static void jp2_cmap_dumpdata(jp2_box_t *box, FILE *out);
176 static void jp2_pclr_destroy(jp2_box_t *box);
177 static int jp2_pclr_getdata(jp2_box_t *box, jas_stream_t *in);
178 static int jp2_pclr_putdata(jp2_box_t *box, jas_stream_t *out);
179 static void jp2_pclr_dumpdata(jp2_box_t *box, FILE *out);
180 
181 /******************************************************************************\
182 * Local data.
183 \******************************************************************************/
184 
185 jp2_boxinfo_t jp2_boxinfos[] = {
186     {JP2_BOX_JP, "JP", 0,
187       {0, 0, jp2_jp_getdata, jp2_jp_putdata, 0}},
188     {JP2_BOX_FTYP, "FTYP", 0,
189       {0, 0, jp2_ftyp_getdata, jp2_ftyp_putdata, 0}},
190     {JP2_BOX_JP2H, "JP2H", JP2_BOX_SUPER,
191       {0, 0, 0, 0, 0}},
192     {JP2_BOX_IHDR, "IHDR", 0,
193       {0, 0, jp2_ihdr_getdata, jp2_ihdr_putdata, 0}},
194     {JP2_BOX_BPCC, "BPCC", 0,
195       {0, jp2_bpcc_destroy, jp2_bpcc_getdata, jp2_bpcc_putdata, 0}},
196     {JP2_BOX_COLR, "COLR", 0,
197       {0, jp2_colr_destroy, jp2_colr_getdata, jp2_colr_putdata, jp2_colr_dumpdata}},
198     {JP2_BOX_PCLR, "PCLR", 0,
199       {0, jp2_pclr_destroy, jp2_pclr_getdata, jp2_pclr_putdata, jp2_pclr_dumpdata}},
200     {JP2_BOX_CMAP, "CMAP", 0,
201       {0, jp2_cmap_destroy, jp2_cmap_getdata, jp2_cmap_putdata, jp2_cmap_dumpdata}},
202     {JP2_BOX_CDEF, "CDEF", 0,
203       {0, jp2_cdef_destroy, jp2_cdef_getdata, jp2_cdef_putdata, jp2_cdef_dumpdata}},
204     {JP2_BOX_RES, "RES", JP2_BOX_SUPER,
205       {0, 0, 0, 0, 0}},
206     {JP2_BOX_RESC, "RESC", 0,
207       {0, 0, 0, 0, 0}},
208     {JP2_BOX_RESD, "RESD", 0,
209       {0, 0, 0, 0, 0}},
210     {JP2_BOX_JP2C, "JP2C", JP2_BOX_NODATA,
211       {0, 0, 0, 0, 0}},
212     {JP2_BOX_JP2I, "JP2I", 0,
213       {0, 0, 0, 0, 0}},
214     {JP2_BOX_XML, "XML", 0,
215       {0, 0, 0, 0, 0}},
216     {JP2_BOX_UUID, "UUID", 0,
217       {0, 0, 0, 0, 0}},
218     {JP2_BOX_UINF, "UINF", JP2_BOX_SUPER,
219       {0, 0, 0, 0, 0}},
220     {JP2_BOX_ULST, "ULST", 0,
221       {0, 0, 0, 0, 0}},
222     {JP2_BOX_URL, "URL", 0,
223       {0, 0, 0, 0, 0}},
224     {0, 0, 0, {0, 0, 0, 0, 0}},
225 };
226 
227 jp2_boxinfo_t jp2_boxinfo_unk = {
228     0, "Unknown", 0, {0, 0, 0, 0}
229 };
230 
231 /******************************************************************************\
232 * Box constructor.
233 \******************************************************************************/
234 
jp2_box_create(int type)235 jp2_box_t *jp2_box_create(int type)
236 {
237     jp2_box_t *box;
238     jp2_boxinfo_t *boxinfo;
239 
240     if (!(box = jas_malloc(sizeof(jp2_box_t)))) {
241         return 0;
242     }
243     memset(box, 0, sizeof(jp2_box_t));
244     box->type = type;
245     box->len = 0;
246     if (!(boxinfo = jp2_boxinfolookup(type))) {
247         return 0;
248     }
249     box->info = boxinfo;
250     box->ops = &boxinfo->ops;
251     return box;
252 }
253 
254 /******************************************************************************\
255 * Box destructor.
256 \******************************************************************************/
257 
jp2_box_destroy(jp2_box_t * box)258 void jp2_box_destroy(jp2_box_t *box)
259 {
260     if (box->ops->destroy) {
261         (*box->ops->destroy)(box);
262     }
263     jas_free(box);
264 }
265 
jp2_bpcc_destroy(jp2_box_t * box)266 static void jp2_bpcc_destroy(jp2_box_t *box)
267 {
268     jp2_bpcc_t *bpcc = &box->data.bpcc;
269     if (bpcc->bpcs) {
270         jas_free(bpcc->bpcs);
271         bpcc->bpcs = 0;
272     }
273 }
274 
jp2_cdef_destroy(jp2_box_t * box)275 static void jp2_cdef_destroy(jp2_box_t *box)
276 {
277     jp2_cdef_t *cdef = &box->data.cdef;
278     if (cdef->ents) {
279         jas_free(cdef->ents);
280         cdef->ents = 0;
281     }
282 }
283 
284 /******************************************************************************\
285 * Box input.
286 \******************************************************************************/
287 
jp2_box_get(jas_stream_t * in)288 jp2_box_t *jp2_box_get(jas_stream_t *in)
289 {
290     jp2_box_t *box;
291     jp2_boxinfo_t *boxinfo;
292     jas_stream_t *tmpstream;
293     uint_fast32_t len;
294     uint_fast64_t extlen;
295     bool dataflag;
296 
297     box = 0;
298     tmpstream = 0;
299 
300     if (!(box = jas_malloc(sizeof(jp2_box_t)))) {
301         goto error;
302     }
303     box->ops = &jp2_boxinfo_unk.ops;
304     if (jp2_getuint32(in, &len) || jp2_getuint32(in, &box->type)) {
305         goto error;
306     }
307     boxinfo = jp2_boxinfolookup(box->type);
308     box->info = boxinfo;
309     box->ops = &boxinfo->ops;
310     box->len = len;
311     if (box->len == 1) {
312         if (jp2_getuint64(in, &extlen)) {
313             goto error;
314         }
315         box->len = extlen;
316     }
317     if (box->len != 0 && box->len < 8) {
318         goto error;
319     }
320 
321     dataflag = !(box->info->flags & (JP2_BOX_SUPER | JP2_BOX_NODATA));
322 
323     if (dataflag) {
324         if (!(tmpstream = jas_stream_memopen(0, 0))) {
325             goto error;
326         }
327         if (jas_stream_copy(tmpstream, in, box->len - JP2_BOX_HDRLEN)) {
328             goto error;
329         }
330         jas_stream_rewind(tmpstream);
331 
332         if (box->ops->getdata) {
333             if ((*box->ops->getdata)(box, tmpstream)) {
334                 goto error;
335             }
336         }
337         jas_stream_close(tmpstream);
338     }
339 
340     if (jas_getdbglevel() > 0) {
341         jp2_box_dump(box, stderr);
342     }
343     return box;
344     abort();
345 
346 error:
347     if (box) {
348         jp2_box_destroy(box);
349     }
350     if (tmpstream) {
351         jas_stream_close(tmpstream);
352     }
353     return 0;
354 }
355 
jp2_box_dump(jp2_box_t * box,FILE * out)356 void jp2_box_dump(jp2_box_t *box, FILE *out)
357 {
358     jp2_boxinfo_t *boxinfo;
359     boxinfo = jp2_boxinfolookup(box->type);
360     assert(boxinfo);
361 
362     fprintf(out, "JP2 box: ");
363     fprintf(out, "type=%c%s%c (0x%08x); length=%d\n", '"', boxinfo->name,
364             '"', (unsigned int) box->type, (int)box->len);
365     if (box->ops->dumpdata) {
366         (*box->ops->dumpdata)(box, out);
367     }
368 }
369 
jp2_jp_getdata(jp2_box_t * box,jas_stream_t * in)370 static int jp2_jp_getdata(jp2_box_t *box, jas_stream_t *in)
371 {
372     jp2_jp_t *jp = &box->data.jp;
373     if (jp2_getuint32(in, &jp->magic)) {
374         return -1;
375     }
376     return 0;
377 }
378 
jp2_ftyp_getdata(jp2_box_t * box,jas_stream_t * in)379 static int jp2_ftyp_getdata(jp2_box_t *box, jas_stream_t *in)
380 {
381     jp2_ftyp_t *ftyp = &box->data.ftyp;
382     int i;
383     if (jp2_getuint32(in, &ftyp->majver) || jp2_getuint32(in, &ftyp->minver)) {
384         return -1;
385     }
386     ftyp->numcompatcodes = ((box->len - JP2_BOX_HDRLEN) - 8) / 4;
387     if (ftyp->numcompatcodes > JP2_FTYP_MAXCOMPATCODES) {
388         return -1;
389     }
390     for (i = 0; i < ftyp->numcompatcodes; ++i) {
391         if (jp2_getuint32(in, &ftyp->compatcodes[i])) {
392             return -1;
393         }
394     }
395     return 0;
396 }
397 
jp2_ihdr_getdata(jp2_box_t * box,jas_stream_t * in)398 static int jp2_ihdr_getdata(jp2_box_t *box, jas_stream_t *in)
399 {
400     jp2_ihdr_t *ihdr = &box->data.ihdr;
401     if (jp2_getuint32(in, &ihdr->height) || jp2_getuint32(in, &ihdr->width) ||
402       jp2_getuint16(in, &ihdr->numcmpts) || jp2_getuint8(in, &ihdr->bpc) ||
403       jp2_getuint8(in, &ihdr->comptype) || jp2_getuint8(in, &ihdr->csunk) ||
404       jp2_getuint8(in, &ihdr->ipr)) {
405         return -1;
406     }
407     return 0;
408 }
409 
jp2_bpcc_getdata(jp2_box_t * box,jas_stream_t * in)410 static int jp2_bpcc_getdata(jp2_box_t *box, jas_stream_t *in)
411 {
412     jp2_bpcc_t *bpcc = &box->data.bpcc;
413     int i;
414     bpcc->numcmpts = box->len - JP2_BOX_HDRLEN;
415     if (!(bpcc->bpcs = jas_malloc(bpcc->numcmpts * sizeof(uint_fast8_t)))) {
416         return -1;
417     }
418     for (i = 0; i < bpcc->numcmpts; ++i) {
419         if (jp2_getuint8(in, &bpcc->bpcs[i])) {
420             return -1;
421         }
422     }
423     return 0;
424 }
425 
jp2_colr_dumpdata(jp2_box_t * box,FILE * out)426 static void jp2_colr_dumpdata(jp2_box_t *box, FILE *out)
427 {
428     jp2_colr_t *colr = &box->data.colr;
429     fprintf(out, "method=%d; pri=%d; approx=%d\n", (int)colr->method, (int)colr->pri, (int)colr->approx);
430     switch (colr->method) {
431     case JP2_COLR_ENUM:
432         fprintf(out, "csid=%d\n", (int)colr->csid);
433         break;
434     case JP2_COLR_ICC:
435         jas_memdump(out, colr->iccp, colr->iccplen);
436         break;
437     }
438 }
439 
jp2_colr_getdata(jp2_box_t * box,jas_stream_t * in)440 static int jp2_colr_getdata(jp2_box_t *box, jas_stream_t *in)
441 {
442     jp2_colr_t *colr = &box->data.colr;
443     colr->csid = 0;
444     colr->iccp = 0;
445     colr->iccplen = 0;
446 
447     if (jp2_getuint8(in, &colr->method) || jp2_getuint8(in, &colr->pri) ||
448       jp2_getuint8(in, &colr->approx)) {
449         return -1;
450     }
451     switch (colr->method) {
452     case JP2_COLR_ENUM:
453         if (jp2_getuint32(in, &colr->csid)) {
454             return -1;
455         }
456         break;
457     case JP2_COLR_ICC:
458         colr->iccplen = box->len - JP2_BOX_HDRLEN - 3;
459         if (!(colr->iccp = jas_malloc(colr->iccplen * sizeof(uint_fast8_t)))) {
460             return -1;
461         }
462         if (jas_stream_read(in, colr->iccp, colr->iccplen) != colr->iccplen) {
463             return -1;
464         }
465         break;
466     }
467     return 0;
468 }
469 
jp2_cdef_dumpdata(jp2_box_t * box,FILE * out)470 static void jp2_cdef_dumpdata(jp2_box_t *box, FILE *out)
471 {
472     jp2_cdef_t *cdef = &box->data.cdef;
473     int i;
474     for (i = 0; i < cdef->numchans; ++i) {
475         fprintf(out, "channo=%d; type=%d; assoc=%d\n",
476                 (int)cdef->ents[i].channo, (int)cdef->ents[i].type,
477                 (int)cdef->ents[i].assoc);
478     }
479 }
480 
jp2_colr_destroy(jp2_box_t * box)481 static void jp2_colr_destroy(jp2_box_t *box)
482 {
483     jp2_colr_t *colr = &box->data.colr;
484     if (colr->iccp) {
485         free(colr->iccp);
486     }
487 }
488 
jp2_cdef_getdata(jp2_box_t * box,jas_stream_t * in)489 static int jp2_cdef_getdata(jp2_box_t *box, jas_stream_t *in)
490 {
491     jp2_cdef_t *cdef = &box->data.cdef;
492     jp2_cdefchan_t *chan;
493     int channo;
494     if (jp2_getuint16(in, &cdef->numchans)) {
495         return -1;
496     }
497     if (!(cdef->ents = jas_malloc(cdef->numchans * sizeof(jp2_cdefchan_t)))) {
498         return -1;
499     }
500     for (channo = 0; channo < cdef->numchans; ++channo) {
501         chan = &cdef->ents[channo];
502         if (jp2_getuint16(in, &chan->channo) || jp2_getuint16(in, &chan->type) ||
503           jp2_getuint16(in, &chan->assoc)) {
504             return -1;
505         }
506     }
507     return 0;
508 }
509 
510 /******************************************************************************\
511 * Box output.
512 \******************************************************************************/
513 
jp2_box_put(jp2_box_t * box,jas_stream_t * out)514 int jp2_box_put(jp2_box_t *box, jas_stream_t *out)
515 {
516     jas_stream_t *tmpstream;
517     bool dataflag;
518 
519     tmpstream = 0;
520 
521     dataflag = !(box->info->flags & (JP2_BOX_SUPER | JP2_BOX_NODATA));
522 
523     if (dataflag) {
524         tmpstream = jas_stream_memopen(0, 0);
525         if (box->ops->putdata) {
526             if ((*box->ops->putdata)(box, tmpstream)) {
527                 goto error;
528             }
529         }
530         box->len = jas_stream_tell(tmpstream) + JP2_BOX_HDRLEN;
531         jas_stream_rewind(tmpstream);
532     }
533     /* There was code here in official Jasper to handle 64 bit lengths,
534        but it was based on determining whether box->len fits in 32 bits.
535        But box->len is a 32 bit data type, so it fits in 32 bits by
536        definition.  Either this encoder is incapable of making boxes with
537        lengths that don't fit in 32 bits, or it passes invalid values of
538        box->len to us.  We assume the former because it's easier.
539     */
540     if (jp2_putuint32(out, box->len)) {
541         goto error;
542     }
543     if (jp2_putuint32(out, box->type)) {
544         goto error;
545     }
546 
547     if (dataflag) {
548         if (jas_stream_copy(out, tmpstream, box->len - JP2_BOX_HDRLEN)) {
549             goto error;
550         }
551         jas_stream_close(tmpstream);
552     }
553 
554     return 0;
555     abort();
556 
557 error:
558 
559     if (tmpstream) {
560         jas_stream_close(tmpstream);
561     }
562     return -1;
563 }
564 
jp2_jp_putdata(jp2_box_t * box,jas_stream_t * out)565 static int jp2_jp_putdata(jp2_box_t *box, jas_stream_t *out)
566 {
567     jp2_jp_t *jp = &box->data.jp;
568     if (jp2_putuint32(out, jp->magic)) {
569         return -1;
570     }
571     return 0;
572 }
573 
jp2_ftyp_putdata(jp2_box_t * box,jas_stream_t * out)574 static int jp2_ftyp_putdata(jp2_box_t *box, jas_stream_t *out)
575 {
576     jp2_ftyp_t *ftyp = &box->data.ftyp;
577     int i;
578     if (jp2_putuint32(out, ftyp->majver) || jp2_putuint32(out, ftyp->minver)) {
579         return -1;
580     }
581     for (i = 0; i < ftyp->numcompatcodes; ++i) {
582         if (jp2_putuint32(out, ftyp->compatcodes[i])) {
583             return -1;
584         }
585     }
586     return 0;
587 }
588 
jp2_ihdr_putdata(jp2_box_t * box,jas_stream_t * out)589 static int jp2_ihdr_putdata(jp2_box_t *box, jas_stream_t *out)
590 {
591     jp2_ihdr_t *ihdr = &box->data.ihdr;
592     if (jp2_putuint32(out, ihdr->height) || jp2_putuint32(out, ihdr->width) ||
593       jp2_putuint16(out, ihdr->numcmpts) || jp2_putuint8(out, ihdr->bpc) ||
594       jp2_putuint8(out, ihdr->comptype) || jp2_putuint8(out, ihdr->csunk) ||
595       jp2_putuint8(out, ihdr->ipr)) {
596         return -1;
597     }
598     return 0;
599 }
600 
jp2_bpcc_putdata(jp2_box_t * box,jas_stream_t * out)601 static int jp2_bpcc_putdata(jp2_box_t *box, jas_stream_t *out)
602 {
603     jp2_bpcc_t *bpcc = &box->data.bpcc;
604     int i;
605     for (i = 0; i < bpcc->numcmpts; ++i) {
606         if (jp2_putuint8(out, bpcc->bpcs[i])) {
607             return -1;
608         }
609     }
610     return 0;
611 }
612 
jp2_colr_putdata(jp2_box_t * box,jas_stream_t * out)613 static int jp2_colr_putdata(jp2_box_t *box, jas_stream_t *out)
614 {
615     jp2_colr_t *colr = &box->data.colr;
616     if (jp2_putuint8(out, colr->method) || jp2_putuint8(out, colr->pri) ||
617       jp2_putuint8(out, colr->approx)) {
618         return -1;
619     }
620     switch (colr->method) {
621     case JP2_COLR_ENUM:
622         if (jp2_putuint32(out, colr->csid)) {
623             return -1;
624         }
625         break;
626     case JP2_COLR_ICC:
627         /* XXX - not implemented */
628         abort();
629         break;
630     }
631     return 0;
632 }
633 
jp2_cdef_putdata(jp2_box_t * box,jas_stream_t * out)634 static int jp2_cdef_putdata(jp2_box_t *box, jas_stream_t *out)
635 {
636     jp2_cdef_t *cdef = &box->data.cdef;
637     int i;
638     jp2_cdefchan_t *ent;
639 
640     if (jp2_putuint16(out, cdef->numchans)) {
641         return -1;
642     }
643 
644     for (i = 0; i < cdef->numchans; ++i) {
645         ent = &cdef->ents[i];
646         if (jp2_putuint16(out, ent->channo) ||
647           jp2_putuint16(out, ent->type) ||
648           jp2_putuint16(out, ent->assoc)) {
649             return -1;
650         }
651     }
652     return 0;
653 }
654 
655 /******************************************************************************\
656 * Input operations for primitive types.
657 \******************************************************************************/
658 
jp2_getuint8(jas_stream_t * in,uint_fast8_t * val)659 static int jp2_getuint8(jas_stream_t *in, uint_fast8_t *val)
660 {
661     int c;
662     if ((c = jas_stream_getc(in)) == EOF) {
663         return -1;
664     }
665     if (val) {
666         *val = c;
667     }
668     return 0;
669 }
670 
jp2_getuint16(jas_stream_t * in,uint_fast16_t * val)671 static int jp2_getuint16(jas_stream_t *in, uint_fast16_t *val)
672 {
673     uint_fast16_t v;
674     int c;
675     if ((c = jas_stream_getc(in)) == EOF) {
676         return -1;
677     }
678     v = c;
679     if ((c = jas_stream_getc(in)) == EOF) {
680         return -1;
681     }
682     v = (v << 8) | c;
683     if (val) {
684         *val = v;
685     }
686     return 0;
687 }
688 
jp2_getuint32(jas_stream_t * in,uint_fast32_t * val)689 static int jp2_getuint32(jas_stream_t *in, uint_fast32_t *val)
690 {
691     uint_fast32_t v;
692     int c;
693     if ((c = jas_stream_getc(in)) == EOF) {
694         return -1;
695     }
696     v = c;
697     if ((c = jas_stream_getc(in)) == EOF) {
698         return -1;
699     }
700     v = (v << 8) | c;
701     if ((c = jas_stream_getc(in)) == EOF) {
702         return -1;
703     }
704     v = (v << 8) | c;
705     if ((c = jas_stream_getc(in)) == EOF) {
706         return -1;
707     }
708     v = (v << 8) | c;
709     if (val) {
710         *val = v;
711     }
712     return 0;
713 }
714 
jp2_getuint64(jas_stream_t * in,uint_fast64_t * val)715 static int jp2_getuint64(jas_stream_t *in, uint_fast64_t *val)
716 {
717     abort();
718 }
719 
720 /******************************************************************************\
721 * Output operations for primitive types.
722 \******************************************************************************/
723 
jp2_putuint8(jas_stream_t * out,uint_fast8_t val)724 static int jp2_putuint8(jas_stream_t *out, uint_fast8_t val)
725 {
726     if (jas_stream_putc(out, val & 0xff) == EOF) {
727         return -1;
728     }
729     return 0;
730 }
731 
jp2_putuint16(jas_stream_t * out,uint_fast16_t val)732 static int jp2_putuint16(jas_stream_t *out, uint_fast16_t val)
733 {
734     if (jas_stream_putc(out, (val >> 8) & 0xff) == EOF ||
735       jas_stream_putc(out, val & 0xff) == EOF) {
736         return -1;
737     }
738     return 0;
739 }
740 
jp2_putuint32(jas_stream_t * out,uint_fast32_t val)741 static int jp2_putuint32(jas_stream_t *out, uint_fast32_t val)
742 {
743     if (jas_stream_putc(out, (val >> 24) & 0xff) == EOF ||
744       jas_stream_putc(out, (val >> 16) & 0xff) == EOF ||
745       jas_stream_putc(out, (val >> 8) & 0xff) == EOF ||
746       jas_stream_putc(out, val & 0xff) == EOF) {
747         return -1;
748     }
749     return 0;
750 }
751 
752 /******************************************************************************\
753 * Miscellaneous code.
754 \******************************************************************************/
755 
jp2_boxinfolookup(int type)756 jp2_boxinfo_t *jp2_boxinfolookup(int type)
757 {
758     jp2_boxinfo_t *boxinfo;
759     for (boxinfo = jp2_boxinfos; boxinfo->name; ++boxinfo) {
760         if (boxinfo->type == type) {
761             return boxinfo;
762         }
763     }
764     return &jp2_boxinfo_unk;
765 }
766 
767 
768 
769 
770 
jp2_cmap_destroy(jp2_box_t * box)771 static void jp2_cmap_destroy(jp2_box_t *box)
772 {
773     jp2_cmap_t *cmap = &box->data.cmap;
774     if (cmap->ents) {
775         jas_free(cmap->ents);
776     }
777 }
778 
jp2_cmap_getdata(jp2_box_t * box,jas_stream_t * in)779 static int jp2_cmap_getdata(jp2_box_t *box, jas_stream_t *in)
780 {
781     jp2_cmap_t *cmap = &box->data.cmap;
782     jp2_cmapent_t *ent;
783     int i;
784 
785     cmap->numchans = (box->len - JP2_BOX_HDRLEN) / 4;
786     if (!(cmap->ents = jas_malloc(cmap->numchans * sizeof(jp2_cmapent_t)))) {
787         return -1;
788     }
789     for (i = 0; i < cmap->numchans; ++i) {
790         ent = &cmap->ents[i];
791         if (jp2_getuint16(in, &ent->cmptno) ||
792           jp2_getuint8(in, &ent->map) ||
793           jp2_getuint8(in, &ent->pcol)) {
794             return -1;
795         }
796     }
797 
798     return 0;
799 }
800 
jp2_cmap_putdata(jp2_box_t * box,jas_stream_t * out)801 static int jp2_cmap_putdata(jp2_box_t *box, jas_stream_t *out)
802 {
803     return -1;
804 }
805 
jp2_cmap_dumpdata(jp2_box_t * box,FILE * out)806 static void jp2_cmap_dumpdata(jp2_box_t *box, FILE *out)
807 {
808     jp2_cmap_t *cmap = &box->data.cmap;
809     int i;
810     jp2_cmapent_t *ent;
811     fprintf(stderr, "numchans = %d\n", (int) cmap->numchans);
812     for (i = 0; i < cmap->numchans; ++i) {
813         ent = &cmap->ents[i];
814         fprintf(stderr, "cmptno=%d; map=%d; pcol=%d\n",
815           (int) ent->cmptno, (int) ent->map, (int) ent->pcol);
816     }
817 }
818 
jp2_pclr_destroy(jp2_box_t * box)819 static void jp2_pclr_destroy(jp2_box_t *box)
820 {
821     jp2_pclr_t *pclr = &box->data.pclr;
822     if (pclr->lutdata) {
823         jas_free(pclr->lutdata);
824     }
825 }
826 
jp2_pclr_getdata(jp2_box_t * box,jas_stream_t * in)827 static int jp2_pclr_getdata(jp2_box_t *box, jas_stream_t *in)
828 {
829     jp2_pclr_t *pclr = &box->data.pclr;
830     int lutsize;
831     int i;
832     int j;
833     int_fast32_t x;
834 
835     pclr->lutdata = 0;
836 
837     if (jp2_getuint16(in, &pclr->numlutents) ||
838       jp2_getuint8(in, &pclr->numchans)) {
839         return -1;
840     }
841     lutsize = pclr->numlutents * pclr->numchans;
842     if (!(pclr->lutdata = jas_malloc(lutsize * sizeof(int_fast32_t)))) {
843         return -1;
844     }
845     if (!(pclr->bpc = jas_malloc(pclr->numchans * sizeof(uint_fast8_t)))) {
846         return -1;
847     }
848     for (i = 0; i < pclr->numchans; ++i) {
849         if (jp2_getuint8(in, &pclr->bpc[i])) {
850             return -1;
851         }
852     }
853     for (i = 0; i < pclr->numlutents; ++i) {
854         for (j = 0; j < pclr->numchans; ++j) {
855             if (jp2_getint(in, (pclr->bpc[j] & 0x80) != 0,
856               (pclr->bpc[j] & 0x7f) + 1, &x)) {
857                 return -1;
858             }
859             pclr->lutdata[i * pclr->numchans + j] = x;
860         }
861     }
862     return 0;
863 }
864 
jp2_pclr_putdata(jp2_box_t * box,jas_stream_t * out)865 static int jp2_pclr_putdata(jp2_box_t *box, jas_stream_t *out)
866 {
867     /* This code from official Jasper must be part of unfinished work.
868        It generates an unused variable warning.
869     jp2_pclr_t *pclr = &box->data.pclr;
870     */
871     return -1;
872 }
873 
jp2_pclr_dumpdata(jp2_box_t * box,FILE * out)874 static void jp2_pclr_dumpdata(jp2_box_t *box, FILE *out)
875 {
876     jp2_pclr_t *pclr = &box->data.pclr;
877     int i;
878     int j;
879     fprintf(out, "numents=%d; numchans=%d\n", (int) pclr->numlutents,
880       (int) pclr->numchans);
881     for (i = 0; i < pclr->numlutents; ++i) {
882         for (j = 0; j < pclr->numchans; ++j) {
883             fprintf(out, "LUT[%d][%d]=%d\n", i, j,
884                     (int)pclr->lutdata[i * pclr->numchans + j]);
885         }
886     }
887 }
888 
jp2_getint(jas_stream_t * in,int s,int n,int_fast32_t * val)889 static int jp2_getint(jas_stream_t *in, int s, int n, int_fast32_t *val)
890 {
891     int c;
892     int i;
893     uint_fast32_t v;
894     int m;
895 
896     m = (n + 7) / 8;
897 
898     v = 0;
899     for (i = 0; i < m; ++i) {
900         if ((c = jas_stream_getc(in)) == EOF) {
901             return -1;
902         }
903         v = (v << 8) | c;
904     }
905     v &= ONES(n);
906     if (s) {
907         int sb;
908         sb = v & (1 << (8 * m - 1));
909         *val = ((~v) + 1) & ONES(8 * m);
910         if (sb) {
911             *val = -*val;
912         }
913     } else {
914         *val = v;
915     }
916 
917     return 0;
918 }
919 
jp2_cdef_lookup(jp2_cdef_t * cdef,int channo)920 jp2_cdefchan_t *jp2_cdef_lookup(jp2_cdef_t *cdef, int channo)
921 {
922     int i;
923     jp2_cdefchan_t *cdefent;
924     for (i = 0; i < cdef->numchans; ++i) {
925         cdefent = &cdef->ents[i];
926         if (cdefent->channo == channo) {
927             return cdefent;
928         }
929     }
930     return 0;
931 }
932