Home | History | Annotate | Download | only in libjasper
      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: jp2_dec.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $
     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 
     86 static jp2_dec_t *jp2_dec_create(void);
     87 static void jp2_dec_destroy(jp2_dec_t *dec);
     88 static int jp2_getcs(jp2_colr_t *colr);
     89 static int fromiccpcs(int cs);
     90 static int jp2_getct(int colorspace, int type, int assoc);
     91 
     92 /******************************************************************************\
     93 * Functions.
     94 \******************************************************************************/
     95 
     96 jas_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_alloc2(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_alloc2(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
    414 jas_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 
    425 error:
    426     if (box) {
    427         jp2_box_destroy(box);
    428     }
    429     if (dec) {
    430         jp2_dec_destroy(dec);
    431     }
    432     return 0;
    433 }
    434 
    435 int 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 
    476 static 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 
    494 static 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 
    523 static 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 
    571 static 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 
    589 static 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 }
    604