source: jp2/trunk/src/libjasper/jp2/jp2_dec.c @ 1

Revision 1, 15.9 KB checked in by cristy, 5 years ago (diff)


Line 
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 "jasper/jas_image.h"
75#include "jasper/jas_stream.h"
76#include "jasper/jas_math.h"
77#include "jasper/jas_debug.h"
78#include "jasper/jas_malloc.h"
79#include "jasper/jas_version.h"
80
81#include "jp2_cod.h"
82#include "jp2_dec.h"
83
84#define JP2_VALIDATELEN (JAS_MIN(JP2_JP_LEN + 16, JAS_STREAM_MAXPUTBACK))
85
86static jp2_dec_t *jp2_dec_create(void);
87static void jp2_dec_destroy(jp2_dec_t *dec);
88static int jp2_getcs(jp2_colr_t *colr);
89static int fromiccpcs(int cs);
90static int jp2_getct(int colorspace, int type, int assoc);
91
92/******************************************************************************\
93* Functions.
94\******************************************************************************/
95
96jas_image_t *jp2_decode(jas_stream_t *in, char *optstr)
97{
98        jp2_box_t *box;
99        int found;
100        jas_image_t *image;
101        jp2_dec_t *dec;
102        bool samedtype;
103        int dtype;
104        unsigned int i;
105        jp2_cmap_t *cmapd;
106        jp2_pclr_t *pclrd;
107        jp2_cdef_t *cdefd;
108        unsigned int channo;
109        int newcmptno;
110        int_fast32_t *lutents;
111#if 0
112        jp2_cdefchan_t *cdefent;
113        int cmptno;
114#endif
115        jp2_cmapent_t *cmapent;
116        jas_icchdr_t icchdr;
117        jas_iccprof_t *iccprof;
118
119        dec = 0;
120        box = 0;
121        image = 0;
122
123        if (!(dec = jp2_dec_create())) {
124                goto error;
125        }
126
127        /* Get the first box.  This should be a JP box. */
128        if (!(box = jp2_box_get(in))) {
129                jas_eprintf("error: cannot get box\n");
130                goto error;
131        }
132        if (box->type != JP2_BOX_JP) {
133                jas_eprintf("error: expecting signature box\n");
134                goto error;
135        }
136        if (box->data.jp.magic != JP2_JP_MAGIC) {
137                jas_eprintf("incorrect magic number\n");
138                goto error;
139        }
140        jp2_box_destroy(box);
141        box = 0;
142
143        /* Get the second box.  This should be a FTYP box. */
144        if (!(box = jp2_box_get(in))) {
145                goto error;
146        }
147        if (box->type != JP2_BOX_FTYP) {
148                jas_eprintf("expecting file type box\n");
149                goto error;
150        }
151        jp2_box_destroy(box);
152        box = 0;
153
154        /* Get more boxes... */
155        found = 0;
156        while ((box = jp2_box_get(in))) {
157                if (jas_getdbglevel() >= 1) {
158                        jas_eprintf("box type %s\n", box->info->name);
159                }
160                switch (box->type) {
161                case JP2_BOX_JP2C:
162                        found = 1;
163                        break;
164                case JP2_BOX_IHDR:
165                        if (!dec->ihdr) {
166                                dec->ihdr = box;
167                                box = 0;
168                        }
169                        break;
170                case JP2_BOX_BPCC:
171                        if (!dec->bpcc) {
172                                dec->bpcc = box;
173                                box = 0;
174                        }
175                        break;
176                case JP2_BOX_CDEF:
177                        if (!dec->cdef) {
178                                dec->cdef = box;
179                                box = 0;
180                        }
181                        break;
182                case JP2_BOX_PCLR:
183                        if (!dec->pclr) {
184                                dec->pclr = box;
185                                box = 0;
186                        }
187                        break;
188                case JP2_BOX_CMAP:
189                        if (!dec->cmap) {
190                                dec->cmap = box;
191                                box = 0;
192                        }
193                        break;
194                case JP2_BOX_COLR:
195                        if (!dec->colr) {
196                                dec->colr = box;
197                                box = 0;
198                        }
199                        break;
200                }
201                if (box) {
202                        jp2_box_destroy(box);
203                        box = 0;
204                }
205                if (found) {
206                        break;
207                }
208        }
209
210        if (!found) {
211                jas_eprintf("error: no code stream found\n");
212                goto error;
213        }
214
215        if (!(dec->image = jpc_decode(in, optstr))) {
216                jas_eprintf("error: cannot decode code stream\n");
217                goto error;
218        }
219
220        /* An IHDR box must be present. */
221        if (!dec->ihdr) {
222                jas_eprintf("error: missing IHDR box\n");
223                goto error;
224        }
225
226        /* Does the number of components indicated in the IHDR box match
227          the value specified in the code stream? */
228        if (dec->ihdr->data.ihdr.numcmpts != JAS_CAST(uint, jas_image_numcmpts(dec->image))) {
229                jas_eprintf("warning: number of components mismatch\n");
230        }
231
232        /* At least one component must be present. */
233        if (!jas_image_numcmpts(dec->image)) {
234                jas_eprintf("error: no components\n");
235                goto error;
236        }
237
238        /* Determine if all components have the same data type. */
239        samedtype = true;
240        dtype = jas_image_cmptdtype(dec->image, 0);
241        for (i = 1; i < JAS_CAST(uint, jas_image_numcmpts(dec->image)); ++i) {
242                if (jas_image_cmptdtype(dec->image, i) != dtype) {
243                        samedtype = false;
244                        break;
245                }
246        }
247
248        /* Is the component data type indicated in the IHDR box consistent
249          with the data in the code stream? */
250        if ((samedtype && dec->ihdr->data.ihdr.bpc != JP2_DTYPETOBPC(dtype)) ||
251          (!samedtype && dec->ihdr->data.ihdr.bpc != JP2_IHDR_BPCNULL)) {
252                jas_eprintf("warning: component data type mismatch\n");
253        }
254
255        /* Is the compression type supported? */
256        if (dec->ihdr->data.ihdr.comptype != JP2_IHDR_COMPTYPE) {
257                jas_eprintf("error: unsupported compression type\n");
258                goto error;
259        }
260
261        if (dec->bpcc) {
262                /* Is the number of components indicated in the BPCC box
263                  consistent with the code stream data? */
264                if (dec->bpcc->data.bpcc.numcmpts != JAS_CAST(uint, jas_image_numcmpts(
265                  dec->image))) {
266                        jas_eprintf("warning: number of components mismatch\n");
267                }
268                /* Is the component data type information indicated in the BPCC
269                  box consistent with the code stream data? */
270                if (!samedtype) {
271                        for (i = 0; i < JAS_CAST(uint, jas_image_numcmpts(dec->image)); ++i) {
272                                if (jas_image_cmptdtype(dec->image, i) != JP2_BPCTODTYPE(dec->bpcc->data.bpcc.bpcs[i])) {
273                                        jas_eprintf("warning: component data type mismatch\n");
274                                }
275                        }
276                } else {
277                        jas_eprintf("warning: superfluous BPCC box\n");
278                }
279        }
280
281        /* A COLR box must be present. */
282        if (!dec->colr) {
283                jas_eprintf("error: no COLR box\n");
284                goto error;
285        }
286
287        switch (dec->colr->data.colr.method) {
288        case JP2_COLR_ENUM:
289                jas_image_setclrspc(dec->image, jp2_getcs(&dec->colr->data.colr));
290                break;
291        case JP2_COLR_ICC:
292                iccprof = jas_iccprof_createfrombuf(dec->colr->data.colr.iccp,
293                  dec->colr->data.colr.iccplen);
294                assert(iccprof);
295                jas_iccprof_gethdr(iccprof, &icchdr);
296                jas_eprintf("ICC Profile CS %08x\n", icchdr.colorspc);
297                jas_image_setclrspc(dec->image, fromiccpcs(icchdr.colorspc));
298                dec->image->cmprof_ = jas_cmprof_createfromiccprof(iccprof);
299                assert(dec->image->cmprof_);
300                jas_iccprof_destroy(iccprof);
301                break;
302        }
303
304        /* If a CMAP box is present, a PCLR box must also be present. */
305        if (dec->cmap && !dec->pclr) {
306                jas_eprintf("warning: missing PCLR box or superfluous CMAP box\n");
307                jp2_box_destroy(dec->cmap);
308                dec->cmap = 0;
309        }
310
311        /* If a CMAP box is not present, a PCLR box must not be present. */
312        if (!dec->cmap && dec->pclr) {
313                jas_eprintf("warning: missing CMAP box or superfluous PCLR box\n");
314                jp2_box_destroy(dec->pclr);
315                dec->pclr = 0;
316        }
317
318        /* Determine the number of channels (which is essentially the number
319          of components after any palette mappings have been applied). */
320        dec->numchans = dec->cmap ? dec->cmap->data.cmap.numchans : JAS_CAST(uint, jas_image_numcmpts(dec->image));
321
322        /* Perform a basic sanity check on the CMAP box if present. */
323        if (dec->cmap) {
324                for (i = 0; i < dec->numchans; ++i) {
325                        /* Is the component number reasonable? */
326                        if (dec->cmap->data.cmap.ents[i].cmptno >= JAS_CAST(uint, jas_image_numcmpts(dec->image))) {
327                                jas_eprintf("error: invalid component number in CMAP box\n");
328                                goto error;
329                        }
330                        /* Is the LUT index reasonable? */
331                        if (dec->cmap->data.cmap.ents[i].pcol >= dec->pclr->data.pclr.numchans) {
332                                jas_eprintf("error: invalid CMAP LUT index\n");
333                                goto error;
334                        }
335                }
336        }
337
338        /* Allocate space for the channel-number to component-number LUT. */
339        if (!(dec->chantocmptlut = jas_malloc(dec->numchans * sizeof(uint_fast16_t)))) {
340                jas_eprintf("error: no memory\n");
341                goto error;
342        }
343
344        if (!dec->cmap) {
345                for (i = 0; i < dec->numchans; ++i) {
346                        dec->chantocmptlut[i] = i;
347                }
348        } else {
349                cmapd = &dec->cmap->data.cmap;
350                pclrd = &dec->pclr->data.pclr;
351                cdefd = &dec->cdef->data.cdef;
352                for (channo = 0; channo < cmapd->numchans; ++channo) {
353                        cmapent = &cmapd->ents[channo];
354                        if (cmapent->map == JP2_CMAP_DIRECT) {
355                                dec->chantocmptlut[channo] = channo;
356                        } else if (cmapent->map == JP2_CMAP_PALETTE) {
357                                lutents = jas_malloc(pclrd->numlutents * sizeof(int_fast32_t));
358                                for (i = 0; i < pclrd->numlutents; ++i) {
359                                        lutents[i] = pclrd->lutdata[cmapent->pcol + i * pclrd->numchans];
360                                }
361                                newcmptno = jas_image_numcmpts(dec->image);
362                                jas_image_depalettize(dec->image, cmapent->cmptno, pclrd->numlutents, lutents, JP2_BPCTODTYPE(pclrd->bpc[cmapent->pcol]), newcmptno);
363                                dec->chantocmptlut[channo] = newcmptno;
364                                jas_free(lutents);
365#if 0
366                                if (dec->cdef) {
367                                        cdefent = jp2_cdef_lookup(cdefd, channo);
368                                        if (!cdefent) {
369                                                abort();
370                                        }
371                                jas_image_setcmpttype(dec->image, newcmptno, jp2_getct(jas_image_clrspc(dec->image), cdefent->type, cdefent->assoc));
372                                } else {
373                                jas_image_setcmpttype(dec->image, newcmptno, jp2_getct(jas_image_clrspc(dec->image), 0, channo + 1));
374                                }
375#endif
376                        }
377                }
378        }
379
380        /* Mark all components as being of unknown type. */
381
382        for (i = 0; i < JAS_CAST(uint, jas_image_numcmpts(dec->image)); ++i) {
383                jas_image_setcmpttype(dec->image, i, JAS_IMAGE_CT_UNKNOWN);
384        }
385
386        /* Determine the type of each component. */
387        if (dec->cdef) {
388                for (i = 0; i < dec->numchans; ++i) {
389                        jas_image_setcmpttype(dec->image,
390                          dec->chantocmptlut[dec->cdef->data.cdef.ents[i].channo],
391                          jp2_getct(jas_image_clrspc(dec->image),
392                          dec->cdef->data.cdef.ents[i].type, dec->cdef->data.cdef.ents[i].assoc));
393                }
394        } else {
395                for (i = 0; i < dec->numchans; ++i) {
396                        jas_image_setcmpttype(dec->image, dec->chantocmptlut[i],
397                          jp2_getct(jas_image_clrspc(dec->image), 0, i + 1));
398                }
399        }
400
401        /* Delete any components that are not of interest. */
402        for (i = jas_image_numcmpts(dec->image); i > 0; --i) {
403                if (jas_image_cmpttype(dec->image, i - 1) == JAS_IMAGE_CT_UNKNOWN) {
404                        jas_image_delcmpt(dec->image, i - 1);
405                }
406        }
407
408        /* Ensure that some components survived. */
409        if (!jas_image_numcmpts(dec->image)) {
410                jas_eprintf("error: no components\n");
411                goto error;
412        }
413#if 0
414jas_eprintf("no of components is %d\n", jas_image_numcmpts(dec->image));
415#endif
416
417        /* Prevent the image from being destroyed later. */
418        image = dec->image;
419        dec->image = 0;
420
421        jp2_dec_destroy(dec);
422
423        return image;
424
425error:
426        if (box) {
427                jp2_box_destroy(box);
428        }
429        if (dec) {
430                jp2_dec_destroy(dec);
431        }
432        return 0;
433}
434
435int jp2_validate(jas_stream_t *in)
436{
437        char buf[JP2_VALIDATELEN];
438        int i;
439        int n;
440#if 0
441        jas_stream_t *tmpstream;
442        jp2_box_t *box;
443#endif
444
445        assert(JAS_STREAM_MAXPUTBACK >= JP2_VALIDATELEN);
446
447        /* Read the validation data (i.e., the data used for detecting
448          the format). */
449        if ((n = jas_stream_read(in, buf, JP2_VALIDATELEN)) < 0) {
450                return -1;
451        }
452
453        /* Put the validation data back onto the stream, so that the
454          stream position will not be changed. */
455        for (i = n - 1; i >= 0; --i) {
456                if (jas_stream_ungetc(in, buf[i]) == EOF) {
457                        return -1;
458                }
459        }
460
461        /* Did we read enough data? */
462        if (n < JP2_VALIDATELEN) {
463                return -1;
464        }
465
466        /* Is the box type correct? */
467        if (((buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7]) !=
468          JP2_BOX_JP)
469        {
470                return -1;
471        }
472
473        return 0;
474}
475
476static jp2_dec_t *jp2_dec_create(void)
477{
478        jp2_dec_t *dec;
479
480        if (!(dec = jas_malloc(sizeof(jp2_dec_t)))) {
481                return 0;
482        }
483        dec->ihdr = 0;
484        dec->bpcc = 0;
485        dec->cdef = 0;
486        dec->pclr = 0;
487        dec->image = 0;
488        dec->chantocmptlut = 0;
489        dec->cmap = 0;
490        dec->colr = 0;
491        return dec;
492}
493
494static void jp2_dec_destroy(jp2_dec_t *dec)
495{
496        if (dec->ihdr) {
497                jp2_box_destroy(dec->ihdr);
498        }
499        if (dec->bpcc) {
500                jp2_box_destroy(dec->bpcc);
501        }
502        if (dec->cdef) {
503                jp2_box_destroy(dec->cdef);
504        }
505        if (dec->pclr) {
506                jp2_box_destroy(dec->pclr);
507        }
508        if (dec->image) {
509                jas_image_destroy(dec->image);
510        }
511        if (dec->cmap) {
512                jp2_box_destroy(dec->cmap);
513        }
514        if (dec->colr) {
515                jp2_box_destroy(dec->colr);
516        }
517        if (dec->chantocmptlut) {
518                jas_free(dec->chantocmptlut);
519        }
520        jas_free(dec);
521}
522
523static int jp2_getct(int colorspace, int type, int assoc)
524{
525        if (type == 1 && assoc == 0) {
526                return JAS_IMAGE_CT_OPACITY;
527        }
528        if (type == 0 && assoc >= 1 && assoc <= 65534) {
529                switch (colorspace) {
530                case JAS_CLRSPC_FAM_RGB:
531                        switch (assoc) {
532                        case JP2_CDEF_RGB_R:
533                                return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R);
534                                break;
535                        case JP2_CDEF_RGB_G:
536                                return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G);
537                                break;
538                        case JP2_CDEF_RGB_B:
539                                return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B);
540                                break;
541                        }
542                        break;
543                case JAS_CLRSPC_FAM_YCBCR:
544                        switch (assoc) {
545                        case JP2_CDEF_YCBCR_Y:
546                                return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_Y);
547                                break;
548                        case JP2_CDEF_YCBCR_CB:
549                                return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CB);
550                                break;
551                        case JP2_CDEF_YCBCR_CR:
552                                return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CR);
553                                break;
554                        }
555                        break;
556                case JAS_CLRSPC_FAM_GRAY:
557                        switch (assoc) {
558                        case JP2_CDEF_GRAY_Y:
559                                return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y);
560                                break;
561                        }
562                        break;
563                default:
564                        return JAS_IMAGE_CT_COLOR(assoc - 1);
565                        break;
566                }
567        }
568        return JAS_IMAGE_CT_UNKNOWN;
569}
570
571static int jp2_getcs(jp2_colr_t *colr)
572{
573        if (colr->method == JP2_COLR_ENUM) {
574                switch (colr->csid) {
575                case JP2_COLR_SRGB:
576                        return JAS_CLRSPC_SRGB;
577                        break;
578                case JP2_COLR_SYCC:
579                        return JAS_CLRSPC_SYCBCR;
580                        break;
581                case JP2_COLR_SGRAY:
582                        return JAS_CLRSPC_SGRAY;
583                        break;
584                }
585        }
586        return JAS_CLRSPC_UNKNOWN;
587}
588
589static int fromiccpcs(int cs)
590{
591        switch (cs) {
592        case ICC_CS_RGB:
593                return JAS_CLRSPC_GENRGB;
594                break;
595        case ICC_CS_YCBCR:
596                return JAS_CLRSPC_GENYCBCR;
597                break;
598        case ICC_CS_GRAY:
599                return JAS_CLRSPC_GENGRAY;
600                break;
601        }
602        return JAS_CLRSPC_UNKNOWN;
603}
Note: See TracBrowser for help on using the repository browser.