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 
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 
jp2_decode(jas_stream_t * in,char * optstr)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 		if (!iccprof) {
295 			jas_eprintf("error: failed to parse ICC profile\n");
296 			goto error;
297 		}
298 		jas_iccprof_gethdr(iccprof, &icchdr);
299 		jas_eprintf("ICC Profile CS %08x\n", icchdr.colorspc);
300 		jas_image_setclrspc(dec->image, fromiccpcs(icchdr.colorspc));
301 		dec->image->cmprof_ = jas_cmprof_createfromiccprof(iccprof);
302 		assert(dec->image->cmprof_);
303 		jas_iccprof_destroy(iccprof);
304 		break;
305 	}
306 
307 	/* If a CMAP box is present, a PCLR box must also be present. */
308 	if (dec->cmap && !dec->pclr) {
309 		jas_eprintf("warning: missing PCLR box or superfluous CMAP box\n");
310 		jp2_box_destroy(dec->cmap);
311 		dec->cmap = 0;
312 	}
313 
314 	/* If a CMAP box is not present, a PCLR box must not be present. */
315 	if (!dec->cmap && dec->pclr) {
316 		jas_eprintf("warning: missing CMAP box or superfluous PCLR box\n");
317 		jp2_box_destroy(dec->pclr);
318 		dec->pclr = 0;
319 	}
320 
321 	/* Determine the number of channels (which is essentially the number
322 	  of components after any palette mappings have been applied). */
323 	dec->numchans = dec->cmap ? dec->cmap->data.cmap.numchans : JAS_CAST(uint, jas_image_numcmpts(dec->image));
324 
325 	/* Perform a basic sanity check on the CMAP box if present. */
326 	if (dec->cmap) {
327 		for (i = 0; i < dec->numchans; ++i) {
328 			/* Is the component number reasonable? */
329 			if (dec->cmap->data.cmap.ents[i].cmptno >= JAS_CAST(uint, jas_image_numcmpts(dec->image))) {
330 				jas_eprintf("error: invalid component number in CMAP box\n");
331 				goto error;
332 			}
333 			/* Is the LUT index reasonable? */
334 			if (dec->cmap->data.cmap.ents[i].pcol >= dec->pclr->data.pclr.numchans) {
335 				jas_eprintf("error: invalid CMAP LUT index\n");
336 				goto error;
337 			}
338 		}
339 	}
340 
341 	/* Allocate space for the channel-number to component-number LUT. */
342 	if (!(dec->chantocmptlut = jas_alloc2(dec->numchans, sizeof(uint_fast16_t)))) {
343 		jas_eprintf("error: no memory\n");
344 		goto error;
345 	}
346 
347 	if (!dec->cmap) {
348 		for (i = 0; i < dec->numchans; ++i) {
349 			dec->chantocmptlut[i] = i;
350 		}
351 	} else {
352 		cmapd = &dec->cmap->data.cmap;
353 		pclrd = &dec->pclr->data.pclr;
354 		//cdefd = &dec->cdef->data.cdef;
355 		for (channo = 0; channo < cmapd->numchans; ++channo) {
356 			cmapent = &cmapd->ents[channo];
357 			if (cmapent->map == JP2_CMAP_DIRECT) {
358 				dec->chantocmptlut[channo] = channo;
359 			} else if (cmapent->map == JP2_CMAP_PALETTE) {
360 				lutents = jas_alloc2(pclrd->numlutents, sizeof(int_fast32_t));
361 				for (i = 0; i < pclrd->numlutents; ++i) {
362 					lutents[i] = pclrd->lutdata[cmapent->pcol + i * pclrd->numchans];
363 				}
364 				newcmptno = jas_image_numcmpts(dec->image);
365 				jas_image_depalettize(dec->image, cmapent->cmptno, pclrd->numlutents, lutents, JP2_BPCTODTYPE(pclrd->bpc[cmapent->pcol]), newcmptno);
366 				dec->chantocmptlut[channo] = newcmptno;
367 				jas_free(lutents);
368 #if 0
369 				if (dec->cdef) {
370 					cdefent = jp2_cdef_lookup(cdefd, channo);
371 					if (!cdefent) {
372 						abort();
373 					}
374 				jas_image_setcmpttype(dec->image, newcmptno, jp2_getct(jas_image_clrspc(dec->image), cdefent->type, cdefent->assoc));
375 				} else {
376 				jas_image_setcmpttype(dec->image, newcmptno, jp2_getct(jas_image_clrspc(dec->image), 0, channo + 1));
377 				}
378 #endif
379 			}
380 		}
381 	}
382 
383 	/* Mark all components as being of unknown type. */
384 
385 	for (i = 0; i < JAS_CAST(uint, jas_image_numcmpts(dec->image)); ++i) {
386 		jas_image_setcmpttype(dec->image, i, JAS_IMAGE_CT_UNKNOWN);
387 	}
388 
389 	/* Determine the type of each component. */
390 	if (dec->cdef) {
391 		for (i = 0; i < dec->numchans; ++i) {
392 			/* Is the channel number reasonable? */
393 			if (dec->cdef->data.cdef.ents[i].channo >= dec->numchans) {
394 				jas_eprintf("error: invalid channel number in CDEF box\n");
395 				goto error;
396 			}
397 			jas_image_setcmpttype(dec->image,
398 			  dec->chantocmptlut[dec->cdef->data.cdef.ents[i].channo],
399 			  jp2_getct(jas_image_clrspc(dec->image),
400 			  dec->cdef->data.cdef.ents[i].type, dec->cdef->data.cdef.ents[i].assoc));
401 		}
402 	} else {
403 		for (i = 0; i < dec->numchans; ++i) {
404 			jas_image_setcmpttype(dec->image, dec->chantocmptlut[i],
405 			  jp2_getct(jas_image_clrspc(dec->image), 0, i + 1));
406 		}
407 	}
408 
409 	/* Delete any components that are not of interest. */
410 	for (i = jas_image_numcmpts(dec->image); i > 0; --i) {
411 		if (jas_image_cmpttype(dec->image, i - 1) == JAS_IMAGE_CT_UNKNOWN) {
412 			jas_image_delcmpt(dec->image, i - 1);
413 		}
414 	}
415 
416 	/* Ensure that some components survived. */
417 	if (!jas_image_numcmpts(dec->image)) {
418 		jas_eprintf("error: no components\n");
419 		goto error;
420 	}
421 #if 0
422 jas_eprintf("no of components is %d\n", jas_image_numcmpts(dec->image));
423 #endif
424 
425 	/* Prevent the image from being destroyed later. */
426 	image = dec->image;
427 	dec->image = 0;
428 
429 	jp2_dec_destroy(dec);
430 
431 	return image;
432 
433 error:
434 	if (box) {
435 		jp2_box_destroy(box);
436 	}
437 	if (dec) {
438 		jp2_dec_destroy(dec);
439 	}
440 	return 0;
441 }
442 
jp2_validate(jas_stream_t * in)443 int jp2_validate(jas_stream_t *in)
444 {
445 	char buf[JP2_VALIDATELEN];
446 	int i;
447 	int n;
448 #if 0
449 	jas_stream_t *tmpstream;
450 	jp2_box_t *box;
451 #endif
452 
453 	assert(JAS_STREAM_MAXPUTBACK >= JP2_VALIDATELEN);
454 
455 	/* Read the validation data (i.e., the data used for detecting
456 	  the format). */
457 	if ((n = jas_stream_read(in, buf, JP2_VALIDATELEN)) < 0) {
458 		return -1;
459 	}
460 
461 	/* Put the validation data back onto the stream, so that the
462 	  stream position will not be changed. */
463 	for (i = n - 1; i >= 0; --i) {
464 		if (jas_stream_ungetc(in, buf[i]) == EOF) {
465 			return -1;
466 		}
467 	}
468 
469 	/* Did we read enough data? */
470 	if (n < JP2_VALIDATELEN) {
471 		return -1;
472 	}
473 
474 	/* Is the box type correct? */
475 	if (((buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7]) !=
476 	  JP2_BOX_JP)
477 	{
478 		return -1;
479 	}
480 
481 	return 0;
482 }
483 
jp2_dec_create(void)484 static jp2_dec_t *jp2_dec_create(void)
485 {
486 	jp2_dec_t *dec;
487 
488 	if (!(dec = jas_malloc(sizeof(jp2_dec_t)))) {
489 		return 0;
490 	}
491 	dec->ihdr = 0;
492 	dec->bpcc = 0;
493 	dec->cdef = 0;
494 	dec->pclr = 0;
495 	dec->image = 0;
496 	dec->chantocmptlut = 0;
497 	dec->cmap = 0;
498 	dec->colr = 0;
499 	return dec;
500 }
501 
jp2_dec_destroy(jp2_dec_t * dec)502 static void jp2_dec_destroy(jp2_dec_t *dec)
503 {
504 	if (dec->ihdr) {
505 		jp2_box_destroy(dec->ihdr);
506 	}
507 	if (dec->bpcc) {
508 		jp2_box_destroy(dec->bpcc);
509 	}
510 	if (dec->cdef) {
511 		jp2_box_destroy(dec->cdef);
512 	}
513 	if (dec->pclr) {
514 		jp2_box_destroy(dec->pclr);
515 	}
516 	if (dec->image) {
517 		jas_image_destroy(dec->image);
518 	}
519 	if (dec->cmap) {
520 		jp2_box_destroy(dec->cmap);
521 	}
522 	if (dec->colr) {
523 		jp2_box_destroy(dec->colr);
524 	}
525 	if (dec->chantocmptlut) {
526 		jas_free(dec->chantocmptlut);
527 	}
528 	jas_free(dec);
529 }
530 
jp2_getct(int colorspace,int type,int assoc)531 static int jp2_getct(int colorspace, int type, int assoc)
532 {
533 	if (type == 1 && assoc == 0) {
534 		return JAS_IMAGE_CT_OPACITY;
535 	}
536 	if (type == 0 && assoc >= 1 && assoc <= 65534) {
537 		switch (colorspace) {
538 		case JAS_CLRSPC_FAM_RGB:
539 			switch (assoc) {
540 			case JP2_CDEF_RGB_R:
541 				return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R);
542 				break;
543 			case JP2_CDEF_RGB_G:
544 				return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G);
545 				break;
546 			case JP2_CDEF_RGB_B:
547 				return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B);
548 				break;
549 			}
550 			break;
551 		case JAS_CLRSPC_FAM_YCBCR:
552 			switch (assoc) {
553 			case JP2_CDEF_YCBCR_Y:
554 				return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_Y);
555 				break;
556 			case JP2_CDEF_YCBCR_CB:
557 				return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CB);
558 				break;
559 			case JP2_CDEF_YCBCR_CR:
560 				return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CR);
561 				break;
562 			}
563 			break;
564 		case JAS_CLRSPC_FAM_GRAY:
565 			switch (assoc) {
566 			case JP2_CDEF_GRAY_Y:
567 				return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y);
568 				break;
569 			}
570 			break;
571 		default:
572 			return JAS_IMAGE_CT_COLOR(assoc - 1);
573 			break;
574 		}
575 	}
576 	return JAS_IMAGE_CT_UNKNOWN;
577 }
578 
jp2_getcs(jp2_colr_t * colr)579 static int jp2_getcs(jp2_colr_t *colr)
580 {
581 	if (colr->method == JP2_COLR_ENUM) {
582 		switch (colr->csid) {
583 		case JP2_COLR_SRGB:
584 			return JAS_CLRSPC_SRGB;
585 			break;
586 		case JP2_COLR_SYCC:
587 			return JAS_CLRSPC_SYCBCR;
588 			break;
589 		case JP2_COLR_SGRAY:
590 			return JAS_CLRSPC_SGRAY;
591 			break;
592 		}
593 	}
594 	return JAS_CLRSPC_UNKNOWN;
595 }
596 
fromiccpcs(int cs)597 static int fromiccpcs(int cs)
598 {
599 	switch (cs) {
600 	case ICC_CS_RGB:
601 		return JAS_CLRSPC_GENRGB;
602 		break;
603 	case ICC_CS_YCBCR:
604 		return JAS_CLRSPC_GENYCBCR;
605 		break;
606 	case ICC_CS_GRAY:
607 		return JAS_CLRSPC_GENGRAY;
608 		break;
609 	}
610 	return JAS_CLRSPC_UNKNOWN;
611 }
612