1/*
2 * The copyright in this software is being made available under the 2-clauses
3 * BSD License, included below. This software may be subject to other third
4 * party and contributor rights, including patent rights, and no such rights
5 * are granted under this license.
6 *
7 * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
8 * Copyright (c) 2002-2014, Professor Benoit Macq
9 * Copyright (c) 2001-2003, David Janssens
10 * Copyright (c) 2002-2003, Yannick Verschueren
11 * Copyright (c) 2003-2007, Francois-Olivier Devaux
12 * Copyright (c) 2003-2014, Antonin Descampe
13 * Copyright (c) 2005, Herve Drolon, FreeImage Team
14 * Copyright (c) 2010-2011, Kaori Hagihara
15 * Copyright (c) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR
16 * Copyright (c) 2012, CS Systemes d'Information, France
17 * All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 * 1. Redistributions of source code must retain the above copyright
23 *    notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 *    notice, this list of conditions and the following disclaimer in the
26 *    documentation and/or other materials provided with the distribution.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
32 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 */
40#include "opj_includes.h"
41
42/** @defgroup JP2 JP2 - JPEG-2000 file format reader/writer */
43/*@{*/
44
45#define OPJ_BOX_SIZE	1024
46
47/** @name Local static functions */
48/*@{*/
49
50/*static void jp2_write_url(opj_cio_t *cio, char *Idx_file);*/
51
52/**
53 * Reads a IHDR box - Image Header box
54 *
55 * @param	p_image_header_data			pointer to actual data (already read from file)
56 * @param	jp2							the jpeg2000 file codec.
57 * @param	p_image_header_size			the size of the image header
58 * @param	p_manager					the user event manager.
59 *
60 * @return	true if the image header is valid, false else.
61 */
62static OPJ_BOOL opj_jp2_read_ihdr(  opj_jp2_t *jp2,
63                                    OPJ_BYTE *p_image_header_data,
64                                    OPJ_UINT32 p_image_header_size,
65                                    opj_event_mgr_t * p_manager );
66
67/**
68 * Writes the Image Header box - Image Header box.
69 *
70 * @param jp2					jpeg2000 file codec.
71 * @param p_nb_bytes_written	pointer to store the nb of bytes written by the function.
72 *
73 * @return	the data being copied.
74*/
75static OPJ_BYTE * opj_jp2_write_ihdr(opj_jp2_t *jp2,
76                                     OPJ_UINT32 * p_nb_bytes_written );
77
78/**
79 * Writes the Bit per Component box.
80 *
81 * @param	jp2						jpeg2000 file codec.
82 * @param	p_nb_bytes_written		pointer to store the nb of bytes written by the function.
83 *
84 * @return	the data being copied.
85*/
86static OPJ_BYTE * opj_jp2_write_bpcc(	opj_jp2_t *jp2,
87								        OPJ_UINT32 * p_nb_bytes_written );
88
89/**
90 * Reads a Bit per Component box.
91 *
92 * @param	p_bpc_header_data			pointer to actual data (already read from file)
93 * @param	jp2							the jpeg2000 file codec.
94 * @param	p_bpc_header_size			the size of the bpc header
95 * @param	p_manager					the user event manager.
96 *
97 * @return	true if the bpc header is valid, fale else.
98 */
99static OPJ_BOOL opj_jp2_read_bpcc(  opj_jp2_t *jp2,
100                                    OPJ_BYTE * p_bpc_header_data,
101                                    OPJ_UINT32 p_bpc_header_size,
102                                    opj_event_mgr_t * p_manager );
103
104static OPJ_BOOL opj_jp2_read_cdef(	opj_jp2_t * jp2,
105                                    OPJ_BYTE * p_cdef_header_data,
106									OPJ_UINT32 p_cdef_header_size,
107									opj_event_mgr_t * p_manager );
108
109static void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color);
110
111/**
112 * Writes the Colour Specification box.
113 *
114 * @param jp2					jpeg2000 file codec.
115 * @param p_nb_bytes_written	pointer to store the nb of bytes written by the function.
116 *
117 * @return	the data being copied.
118*/
119static OPJ_BYTE * opj_jp2_write_colr(   opj_jp2_t *jp2,
120									    OPJ_UINT32 * p_nb_bytes_written );
121
122/**
123 * Writes a FTYP box - File type box
124 *
125 * @param	cio			the stream to write data to.
126 * @param	jp2			the jpeg2000 file codec.
127 * @param	p_manager	the user event manager.
128 *
129 * @return	true if writing was successful.
130 */
131static OPJ_BOOL opj_jp2_write_ftyp(	opj_jp2_t *jp2,
132									opj_stream_private_t *cio,
133									opj_event_mgr_t * p_manager );
134
135/**
136 * Reads a a FTYP box - File type box
137 *
138 * @param	p_header_data	the data contained in the FTYP box.
139 * @param	jp2				the jpeg2000 file codec.
140 * @param	p_header_size	the size of the data contained in the FTYP box.
141 * @param	p_manager		the user event manager.
142 *
143 * @return true if the FTYP box is valid.
144 */
145static OPJ_BOOL opj_jp2_read_ftyp(	opj_jp2_t *jp2,
146									OPJ_BYTE * p_header_data,
147									OPJ_UINT32 p_header_size,
148									opj_event_mgr_t * p_manager );
149
150OPJ_BOOL opj_jp2_skip_jp2c(	opj_jp2_t *jp2,
151						    opj_stream_private_t *cio,
152						    opj_event_mgr_t * p_manager );
153
154/**
155 * Reads the Jpeg2000 file Header box - JP2 Header box (warning, this is a super box).
156 *
157 * @param	p_header_data	the data contained in the file header box.
158 * @param	jp2				the jpeg2000 file codec.
159 * @param	p_header_size	the size of the data contained in the file header box.
160 * @param	p_manager		the user event manager.
161 *
162 * @return true if the JP2 Header box was successfully reconized.
163*/
164static OPJ_BOOL opj_jp2_read_jp2h(  opj_jp2_t *jp2,
165                                    OPJ_BYTE *p_header_data,
166                                    OPJ_UINT32 p_header_size,
167                                    opj_event_mgr_t * p_manager );
168
169/**
170 * Writes the Jpeg2000 codestream Header box - JP2C Header box. This function must be called AFTER the coding has been done.
171 *
172 * @param	cio			the stream to write data to.
173 * @param	jp2			the jpeg2000 file codec.
174 * @param	p_manager	user event manager.
175 *
176 * @return true if writing was successful.
177*/
178static OPJ_BOOL opj_jp2_write_jp2c(	opj_jp2_t *jp2,
179								    opj_stream_private_t *cio,
180								    opj_event_mgr_t * p_manager );
181
182#ifdef USE_JPIP
183/**
184 * Write index Finder box
185 * @param cio     the stream to write to.
186 * @param	jp2			the jpeg2000 file codec.
187 * @param	p_manager	user event manager.
188*/
189static OPJ_BOOL opj_jpip_write_iptr(	opj_jp2_t *jp2,
190								    opj_stream_private_t *cio,
191								    opj_event_mgr_t * p_manager );
192
193/**
194 * Write index Finder box
195 * @param cio     the stream to write to.
196 * @param	jp2			the jpeg2000 file codec.
197 * @param	p_manager	user event manager.
198 */
199static OPJ_BOOL opj_jpip_write_cidx(opj_jp2_t *jp2,
200  opj_stream_private_t *cio,
201  opj_event_mgr_t * p_manager );
202
203/**
204 * Write file Index (superbox)
205 * @param cio     the stream to write to.
206 * @param	jp2			the jpeg2000 file codec.
207 * @param	p_manager	user event manager.
208 */
209static OPJ_BOOL opj_jpip_write_fidx(opj_jp2_t *jp2,
210  opj_stream_private_t *cio,
211  opj_event_mgr_t * p_manager );
212#endif /* USE_JPIP */
213
214/**
215 * Reads a jpeg2000 file signature box.
216 *
217 * @param	p_header_data	the data contained in the signature box.
218 * @param	jp2				the jpeg2000 file codec.
219 * @param	p_header_size	the size of the data contained in the signature box.
220 * @param	p_manager		the user event manager.
221 *
222 * @return true if the file signature box is valid.
223 */
224static OPJ_BOOL opj_jp2_read_jp(opj_jp2_t *jp2,
225                                OPJ_BYTE * p_header_data,
226                                OPJ_UINT32 p_header_size,
227                                opj_event_mgr_t * p_manager);
228
229/**
230 * Writes a jpeg2000 file signature box.
231 *
232 * @param cio the stream to write data to.
233 * @param	jp2			the jpeg2000 file codec.
234 * @param p_manager the user event manager.
235 *
236 * @return true if writing was successful.
237 */
238static OPJ_BOOL opj_jp2_write_jp(	opj_jp2_t *jp2,
239			    	        	    opj_stream_private_t *cio,
240				            		opj_event_mgr_t * p_manager );
241
242/**
243Apply collected palette data
244@param color Collector for profile, cdef and pclr data
245@param image
246*/
247static void opj_jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color);
248
249static void opj_jp2_free_pclr(opj_jp2_color_t *color);
250
251/**
252 * Collect palette data
253 *
254 * @param jp2 JP2 handle
255 * @param p_pclr_header_data    FIXME DOC
256 * @param p_pclr_header_size    FIXME DOC
257 * @param p_manager
258 *
259 * @return Returns true if successful, returns false otherwise
260*/
261static OPJ_BOOL opj_jp2_read_pclr(	opj_jp2_t *jp2,
262                                    OPJ_BYTE * p_pclr_header_data,
263                                    OPJ_UINT32 p_pclr_header_size,
264                                    opj_event_mgr_t * p_manager );
265
266/**
267 * Collect component mapping data
268 *
269 * @param jp2                 JP2 handle
270 * @param p_cmap_header_data  FIXME DOC
271 * @param p_cmap_header_size  FIXME DOC
272 * @param p_manager           FIXME DOC
273 *
274 * @return Returns true if successful, returns false otherwise
275*/
276
277static OPJ_BOOL opj_jp2_read_cmap(	opj_jp2_t * jp2,
278                                    OPJ_BYTE * p_cmap_header_data,
279                                    OPJ_UINT32 p_cmap_header_size,
280                                    opj_event_mgr_t * p_manager );
281
282/**
283 * Reads the Color Specification box.
284 *
285 * @param	p_colr_header_data			pointer to actual data (already read from file)
286 * @param	jp2							the jpeg2000 file codec.
287 * @param	p_colr_header_size			the size of the color header
288 * @param	p_manager					the user event manager.
289 *
290 * @return	true if the bpc header is valid, fale else.
291*/
292static OPJ_BOOL opj_jp2_read_colr(  opj_jp2_t *jp2,
293                                    OPJ_BYTE * p_colr_header_data,
294                                    OPJ_UINT32 p_colr_header_size,
295                                    opj_event_mgr_t * p_manager );
296
297/*@}*/
298
299/*@}*/
300
301/**
302 * Sets up the procedures to do on writing header after the codestream.
303 * Developpers wanting to extend the library can add their own writing procedures.
304 */
305static void opj_jp2_setup_end_header_writing (opj_jp2_t *jp2);
306
307/**
308 * Sets up the procedures to do on reading header after the codestream.
309 * Developpers wanting to extend the library can add their own writing procedures.
310 */
311static void opj_jp2_setup_end_header_reading (opj_jp2_t *jp2);
312
313/**
314 * Reads a jpeg2000 file header structure.
315 *
316 * @param jp2 the jpeg2000 file header structure.
317 * @param stream the stream to read data from.
318 * @param p_manager the user event manager.
319 *
320 * @return true if the box is valid.
321 */
322static OPJ_BOOL opj_jp2_read_header_procedure(  opj_jp2_t *jp2,
323                                                opj_stream_private_t *stream,
324                                                opj_event_mgr_t * p_manager );
325
326/**
327 * Excutes the given procedures on the given codec.
328 *
329 * @param	p_procedure_list	the list of procedures to execute
330 * @param	jp2					the jpeg2000 file codec to execute the procedures on.
331 * @param	stream					the stream to execute the procedures on.
332 * @param	p_manager			the user manager.
333 *
334 * @return	true				if all the procedures were successfully executed.
335 */
336static OPJ_BOOL opj_jp2_exec (  opj_jp2_t * jp2,
337                                opj_procedure_list_t * p_procedure_list,
338                                opj_stream_private_t *stream,
339                                opj_event_mgr_t * p_manager );
340
341/**
342 * Reads a box header. The box is the way data is packed inside a jpeg2000 file structure.
343 *
344 * @param	cio						the input stream to read data from.
345 * @param	box						the box structure to fill.
346 * @param	p_number_bytes_read		pointer to an int that will store the number of bytes read from the stream (shoul usually be 2).
347 * @param	p_manager				user event manager.
348 *
349 * @return	true if the box is reconized, false otherwise
350*/
351static OPJ_BOOL opj_jp2_read_boxhdr(opj_jp2_box_t *box,
352                                    OPJ_UINT32 * p_number_bytes_read,
353                                    opj_stream_private_t *cio,
354                                    opj_event_mgr_t * p_manager);
355
356/**
357 * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
358 * are valid. Developpers wanting to extend the library can add their own validation procedures.
359 */
360static void opj_jp2_setup_encoding_validation (opj_jp2_t *jp2);
361
362/**
363 * Sets up the procedures to do on writing header. Developpers wanting to extend the library can add their own writing procedures.
364 */
365static void opj_jp2_setup_header_writing (opj_jp2_t *jp2);
366
367OPJ_BOOL opj_jp2_default_validation (	opj_jp2_t * jp2,
368                                        opj_stream_private_t *cio,
369                                        opj_event_mgr_t * p_manager );
370
371/**
372 * Finds the image execution function related to the given box id.
373 *
374 * @param	p_id	the id of the handler to fetch.
375 *
376 * @return	the given handler or NULL if it could not be found.
377 */
378static const opj_jp2_header_handler_t * opj_jp2_img_find_handler (OPJ_UINT32 p_id);
379
380/**
381 * Finds the execution function related to the given box id.
382 *
383 * @param	p_id	the id of the handler to fetch.
384 *
385 * @return	the given handler or NULL if it could not be found.
386 */
387static const opj_jp2_header_handler_t * opj_jp2_find_handler (OPJ_UINT32 p_id );
388
389const opj_jp2_header_handler_t jp2_header [] =
390{
391	{JP2_JP,opj_jp2_read_jp},
392	{JP2_FTYP,opj_jp2_read_ftyp},
393	{JP2_JP2H,opj_jp2_read_jp2h}
394};
395
396const opj_jp2_header_handler_t jp2_img_header [] =
397{
398	{JP2_IHDR,opj_jp2_read_ihdr},
399	{JP2_COLR,opj_jp2_read_colr},
400	{JP2_BPCC,opj_jp2_read_bpcc},
401	{JP2_PCLR,opj_jp2_read_pclr},
402	{JP2_CMAP,opj_jp2_read_cmap},
403	{JP2_CDEF,opj_jp2_read_cdef}
404
405};
406
407/**
408 * Reads a box header. The box is the way data is packed inside a jpeg2000 file structure. Data is read from a character string
409 *
410 * @param	box						the box structure to fill.
411 * @param	p_data					the character string to read data from.
412 * @param	p_number_bytes_read		pointer to an int that will store the number of bytes read from the stream (shoul usually be 2).
413 * @param	p_box_max_size			the maximum number of bytes in the box.
414 * @param	p_manager         FIXME DOC
415 *
416 * @return	true if the box is reconized, false otherwise
417*/
418static OPJ_BOOL opj_jp2_read_boxhdr_char(   opj_jp2_box_t *box,
419                                            OPJ_BYTE * p_data,
420                                            OPJ_UINT32 * p_number_bytes_read,
421                                            OPJ_UINT32 p_box_max_size,
422                                            opj_event_mgr_t * p_manager );
423
424/**
425 * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
426 * are valid. Developpers wanting to extend the library can add their own validation procedures.
427 */
428static void opj_jp2_setup_decoding_validation (opj_jp2_t *jp2);
429
430/**
431 * Sets up the procedures to do on reading header.
432 * Developpers wanting to extend the library can add their own writing procedures.
433 */
434static void opj_jp2_setup_header_reading (opj_jp2_t *jp2);
435
436/* ----------------------------------------------------------------------- */
437 OPJ_BOOL opj_jp2_read_boxhdr(opj_jp2_box_t *box,
438                              OPJ_UINT32 * p_number_bytes_read,
439                              opj_stream_private_t *cio,
440                              opj_event_mgr_t * p_manager )
441{
442	/* read header from file */
443	OPJ_BYTE l_data_header [8];
444
445	/* preconditions */
446	assert(cio != 00);
447	assert(box != 00);
448	assert(p_number_bytes_read != 00);
449	assert(p_manager != 00);
450
451	*p_number_bytes_read = (OPJ_UINT32)opj_stream_read_data(cio,l_data_header,8,p_manager);
452	if (*p_number_bytes_read != 8) {
453		return OPJ_FALSE;
454	}
455
456	/* process read data */
457	opj_read_bytes(l_data_header,&(box->length), 4);
458	opj_read_bytes(l_data_header+4,&(box->type), 4);
459
460  if(box->length == 0)/* last box */
461    {
462    const OPJ_OFF_T bleft = opj_stream_get_number_byte_left(cio);
463    box->length = (OPJ_UINT32)bleft;
464    assert( (OPJ_OFF_T)box->length == bleft );
465    return OPJ_TRUE;
466    }
467
468	/* do we have a "special very large box ?" */
469	/* read then the XLBox */
470	if (box->length == 1) {
471		OPJ_UINT32 l_xl_part_size;
472
473		OPJ_UINT32 l_nb_bytes_read = (OPJ_UINT32)opj_stream_read_data(cio,l_data_header,8,p_manager);
474		if (l_nb_bytes_read != 8) {
475			if (l_nb_bytes_read > 0) {
476				*p_number_bytes_read += l_nb_bytes_read;
477			}
478
479			return OPJ_FALSE;
480		}
481
482        *p_number_bytes_read = 16;
483		opj_read_bytes(l_data_header,&l_xl_part_size, 4);
484		if (l_xl_part_size != 0) {
485			opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n");
486			return OPJ_FALSE;
487		}
488		opj_read_bytes(l_data_header+4,&(box->length), 4);
489	}
490    return OPJ_TRUE;
491}
492
493#if 0
494static void jp2_write_url(opj_cio_t *cio, char *Idx_file) {
495	OPJ_UINT32 i;
496	opj_jp2_box_t box;
497
498	box.init_pos = cio_tell(cio);
499	cio_skip(cio, 4);
500	cio_write(cio, JP2_URL, 4);	/* DBTL */
501	cio_write(cio, 0, 1);		/* VERS */
502	cio_write(cio, 0, 3);		/* FLAG */
503
504	if(Idx_file) {
505		for (i = 0; i < strlen(Idx_file); i++) {
506			cio_write(cio, Idx_file[i], 1);
507		}
508	}
509
510	box.length = cio_tell(cio) - box.init_pos;
511	cio_seek(cio, box.init_pos);
512	cio_write(cio, box.length, 4);	/* L */
513	cio_seek(cio, box.init_pos + box.length);
514}
515#endif
516
517OPJ_BOOL opj_jp2_read_ihdr( opj_jp2_t *jp2,
518                            OPJ_BYTE *p_image_header_data,
519                            OPJ_UINT32 p_image_header_size,
520                            opj_event_mgr_t * p_manager )
521{
522	/* preconditions */
523	assert(p_image_header_data != 00);
524	assert(jp2 != 00);
525	assert(p_manager != 00);
526
527	if (p_image_header_size != 14) {
528		opj_event_msg(p_manager, EVT_ERROR, "Bad image header box (bad size)\n");
529		return OPJ_FALSE;
530	}
531
532	opj_read_bytes(p_image_header_data,&(jp2->h),4);			/* HEIGHT */
533	p_image_header_data += 4;
534	opj_read_bytes(p_image_header_data,&(jp2->w),4);			/* WIDTH */
535	p_image_header_data += 4;
536	opj_read_bytes(p_image_header_data,&(jp2->numcomps),2);		/* NC */
537	p_image_header_data += 2;
538
539	/* allocate memory for components */
540	jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t));
541	if (jp2->comps == 0) {
542		opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle image header (ihdr)\n");
543		return OPJ_FALSE;
544	}
545	memset(jp2->comps,0,jp2->numcomps * sizeof(opj_jp2_comps_t));
546
547	opj_read_bytes(p_image_header_data,&(jp2->bpc),1);			/* BPC */
548	++ p_image_header_data;
549
550	opj_read_bytes(p_image_header_data,&(jp2->C),1);			/* C */
551	++ p_image_header_data;
552
553	/* Should be equal to 7 cf. chapter about image header box of the norm */
554	if (jp2->C != 7){
555		opj_event_msg(p_manager, EVT_INFO, "JP2 IHDR box: compression type indicate that the file is not a conforming JP2 file (%d) \n", jp2->C);
556	}
557
558	opj_read_bytes(p_image_header_data,&(jp2->UnkC),1);			/* UnkC */
559	++ p_image_header_data;
560	opj_read_bytes(p_image_header_data,&(jp2->IPR),1);			/* IPR */
561	++ p_image_header_data;
562
563	return OPJ_TRUE;
564}
565
566OPJ_BYTE * opj_jp2_write_ihdr(opj_jp2_t *jp2,
567                              OPJ_UINT32 * p_nb_bytes_written
568                              )
569{
570	OPJ_BYTE * l_ihdr_data,* l_current_ihdr_ptr;
571
572	/* preconditions */
573	assert(jp2 != 00);
574	assert(p_nb_bytes_written != 00);
575
576	/* default image header is 22 bytes wide */
577	l_ihdr_data = (OPJ_BYTE *) opj_malloc(22);
578	if (l_ihdr_data == 00) {
579		return 00;
580	}
581	memset(l_ihdr_data,0,22);
582
583	l_current_ihdr_ptr = l_ihdr_data;
584
585	opj_write_bytes(l_current_ihdr_ptr,22,4);				/* write box size */
586	l_current_ihdr_ptr+=4;
587
588	opj_write_bytes(l_current_ihdr_ptr,JP2_IHDR, 4);		/* IHDR */
589	l_current_ihdr_ptr+=4;
590
591	opj_write_bytes(l_current_ihdr_ptr,jp2->h, 4);		/* HEIGHT */
592	l_current_ihdr_ptr+=4;
593
594	opj_write_bytes(l_current_ihdr_ptr, jp2->w, 4);		/* WIDTH */
595	l_current_ihdr_ptr+=4;
596
597	opj_write_bytes(l_current_ihdr_ptr, jp2->numcomps, 2);		/* NC */
598	l_current_ihdr_ptr+=2;
599
600	opj_write_bytes(l_current_ihdr_ptr, jp2->bpc, 1);		/* BPC */
601	++l_current_ihdr_ptr;
602
603	opj_write_bytes(l_current_ihdr_ptr, jp2->C, 1);		/* C : Always 7 */
604	++l_current_ihdr_ptr;
605
606	opj_write_bytes(l_current_ihdr_ptr, jp2->UnkC, 1);		/* UnkC, colorspace unknown */
607	++l_current_ihdr_ptr;
608
609	opj_write_bytes(l_current_ihdr_ptr, jp2->IPR, 1);		/* IPR, no intellectual property */
610	++l_current_ihdr_ptr;
611
612	*p_nb_bytes_written = 22;
613
614	return l_ihdr_data;
615}
616
617OPJ_BYTE * opj_jp2_write_bpcc(	opj_jp2_t *jp2,
618						        OPJ_UINT32 * p_nb_bytes_written
619                                )
620{
621	OPJ_UINT32 i;
622	/* room for 8 bytes for box and 1 byte for each component */
623	OPJ_UINT32 l_bpcc_size = 8 + jp2->numcomps;
624	OPJ_BYTE * l_bpcc_data,* l_current_bpcc_ptr;
625
626	/* preconditions */
627	assert(jp2 != 00);
628	assert(p_nb_bytes_written != 00);
629
630	l_bpcc_data = (OPJ_BYTE *) opj_malloc(l_bpcc_size);
631	if (l_bpcc_data == 00) {
632		return 00;
633	}
634	memset(l_bpcc_data,0,l_bpcc_size);
635
636	l_current_bpcc_ptr = l_bpcc_data;
637
638	opj_write_bytes(l_current_bpcc_ptr,l_bpcc_size,4);				/* write box size */
639	l_current_bpcc_ptr += 4;
640
641	opj_write_bytes(l_current_bpcc_ptr,JP2_BPCC,4);					/* BPCC */
642	l_current_bpcc_ptr += 4;
643
644	for (i = 0; i < jp2->numcomps; ++i)  {
645		opj_write_bytes(l_current_bpcc_ptr, jp2->comps[i].bpcc, 1); /* write each component information */
646		++l_current_bpcc_ptr;
647	}
648
649	*p_nb_bytes_written = l_bpcc_size;
650
651	return l_bpcc_data;
652}
653
654OPJ_BOOL opj_jp2_read_bpcc( opj_jp2_t *jp2,
655                            OPJ_BYTE * p_bpc_header_data,
656                            OPJ_UINT32 p_bpc_header_size,
657                            opj_event_mgr_t * p_manager
658                            )
659{
660	OPJ_UINT32 i;
661
662	/* preconditions */
663	assert(p_bpc_header_data != 00);
664	assert(jp2 != 00);
665	assert(p_manager != 00);
666
667
668	if (jp2->bpc != 255 ){
669		opj_event_msg(p_manager, EVT_WARNING, "A BPCC header box is available although BPC given by the IHDR box (%d) indicate components bit depth is constant\n",jp2->bpc);
670	}
671
672	/* and length is relevant */
673	if (p_bpc_header_size != jp2->numcomps) {
674		opj_event_msg(p_manager, EVT_ERROR, "Bad BPCC header box (bad size)\n");
675		return OPJ_FALSE;
676	}
677
678	/* read info for each component */
679	for (i = 0; i < jp2->numcomps; ++i) {
680		opj_read_bytes(p_bpc_header_data,&jp2->comps[i].bpcc ,1);	/* read each BPCC component */
681		++p_bpc_header_data;
682	}
683
684	return OPJ_TRUE;
685}
686
687OPJ_BYTE * opj_jp2_write_colr(  opj_jp2_t *jp2,
688							    OPJ_UINT32 * p_nb_bytes_written
689                                )
690{
691	/* room for 8 bytes for box 3 for common data and variable upon profile*/
692	OPJ_UINT32 l_colr_size = 11;
693	OPJ_BYTE * l_colr_data,* l_current_colr_ptr;
694
695	/* preconditions */
696	assert(jp2 != 00);
697	assert(p_nb_bytes_written != 00);
698    assert(jp2->meth == 1 || jp2->meth == 2);
699
700	switch (jp2->meth) {
701		case 1 :
702			l_colr_size += 4; /* EnumCS */
703			break;
704		case 2 :
705            assert(jp2->color.icc_profile_len);	/* ICC profile */
706            l_colr_size += jp2->color.icc_profile_len;
707			break;
708		default :
709			return 00;
710	}
711
712	l_colr_data = (OPJ_BYTE *) opj_malloc(l_colr_size);
713	if (l_colr_data == 00) {
714		return 00;
715	}
716	memset(l_colr_data,0,l_colr_size);
717
718	l_current_colr_ptr = l_colr_data;
719
720	opj_write_bytes(l_current_colr_ptr,l_colr_size,4);				/* write box size */
721	l_current_colr_ptr += 4;
722
723	opj_write_bytes(l_current_colr_ptr,JP2_COLR,4);					/* BPCC */
724	l_current_colr_ptr += 4;
725
726	opj_write_bytes(l_current_colr_ptr, jp2->meth,1);				/* METH */
727	++l_current_colr_ptr;
728
729	opj_write_bytes(l_current_colr_ptr, jp2->precedence,1);			/* PRECEDENCE */
730	++l_current_colr_ptr;
731
732	opj_write_bytes(l_current_colr_ptr, jp2->approx,1);				/* APPROX */
733	++l_current_colr_ptr;
734
735	if (jp2->meth == 1) { /* Meth value is restricted to 1 or 2 (Table I.9 of part 1) */
736        opj_write_bytes(l_current_colr_ptr, jp2->enumcs,4); }       /* EnumCS */
737    else {
738        if (jp2->meth == 2) {                                      /* ICC profile */
739            OPJ_UINT32 i;
740            for(i = 0; i < jp2->color.icc_profile_len; ++i) {
741                opj_write_bytes(l_current_colr_ptr, jp2->color.icc_profile_buf[i], 1);
742                ++l_current_colr_ptr;
743            }
744        }
745	}
746
747	*p_nb_bytes_written = l_colr_size;
748
749	return l_colr_data;
750}
751
752void opj_jp2_free_pclr(opj_jp2_color_t *color)
753{
754    opj_free(color->jp2_pclr->channel_sign);
755    opj_free(color->jp2_pclr->channel_size);
756    opj_free(color->jp2_pclr->entries);
757
758	if(color->jp2_pclr->cmap) opj_free(color->jp2_pclr->cmap);
759
760    opj_free(color->jp2_pclr); color->jp2_pclr = NULL;
761}
762
763static OPJ_BOOL opj_jp2_check_color(opj_image_t *image, opj_jp2_color_t *color, opj_event_mgr_t *p_manager)
764{
765	OPJ_UINT16 i;
766
767	/* testcase 4149.pdf.SIGSEGV.cf7.3501 */
768	if (color->jp2_cdef) {
769		opj_jp2_cdef_info_t *info = color->jp2_cdef->info;
770		OPJ_UINT16 n = color->jp2_cdef->n;
771
772		for (i = 0; i < n; i++) {
773			if (info[i].cn >= image->numcomps) {
774				opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].cn, image->numcomps);
775				return OPJ_FALSE;
776			}
777			if (info[i].asoc > 0 && (OPJ_UINT32)(info[i].asoc - 1) >= image->numcomps) {
778				opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].asoc - 1, image->numcomps);
779				return OPJ_FALSE;
780			}
781		}
782	}
783
784	/* testcases 451.pdf.SIGSEGV.f4c.3723, 451.pdf.SIGSEGV.5b5.3723 and
785	   66ea31acbb0f23a2bbc91f64d69a03f5_signal_sigsegv_13937c0_7030_5725.pdf */
786	if (color->jp2_pclr && color->jp2_pclr->cmap) {
787		OPJ_UINT16 nr_channels = color->jp2_pclr->nr_channels;
788		opj_jp2_cmap_comp_t *cmap = color->jp2_pclr->cmap;
789		OPJ_BOOL *pcol_usage, is_sane = OPJ_TRUE;
790
791		/* verify that all original components match an existing one */
792		for (i = 0; i < nr_channels; i++) {
793			if (cmap[i].cmp >= image->numcomps) {
794				opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", cmap[i].cmp, image->numcomps);
795				is_sane = OPJ_FALSE;
796			}
797		}
798
799		pcol_usage = opj_calloc(nr_channels, sizeof(OPJ_BOOL));
800		if (!pcol_usage) {
801			opj_event_msg(p_manager, EVT_ERROR, "Unexpected OOM.\n");
802			return OPJ_FALSE;
803		}
804		/* verify that no component is targeted more than once */
805		for (i = 0; i < nr_channels; i++) {
806      OPJ_UINT16 pcol = cmap[i].pcol;
807      assert(cmap[i].mtyp == 0 || cmap[i].mtyp == 1);
808			if (pcol >= nr_channels) {
809				opj_event_msg(p_manager, EVT_ERROR, "Invalid component/palette index for direct mapping %d.\n", pcol);
810				is_sane = OPJ_FALSE;
811			}
812			else if (pcol_usage[pcol] && cmap[i].mtyp == 1) {
813				opj_event_msg(p_manager, EVT_ERROR, "Component %d is mapped twice.\n", pcol);
814				is_sane = OPJ_FALSE;
815			}
816      else if (cmap[i].mtyp == 0 && cmap[i].pcol != 0) {
817        /* I.5.3.5 PCOL: If the value of the MTYP field for this channel is 0, then
818         * the value of this field shall be 0. */
819				opj_event_msg(p_manager, EVT_ERROR, "Direct use at #%d however pcol=%d.\n", i, pcol);
820				is_sane = OPJ_FALSE;
821      }
822			else
823				pcol_usage[pcol] = OPJ_TRUE;
824		}
825		/* verify that all components are targeted at least once */
826		for (i = 0; i < nr_channels; i++) {
827			if (!pcol_usage[i] && cmap[i].mtyp != 0) {
828				opj_event_msg(p_manager, EVT_ERROR, "Component %d doesn't have a mapping.\n", i);
829				is_sane = OPJ_FALSE;
830			}
831		}
832		opj_free(pcol_usage);
833		if (!is_sane) {
834			return OPJ_FALSE;
835		}
836	}
837
838	return OPJ_TRUE;
839}
840
841/* file9.jp2 */
842void opj_jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color)
843{
844	opj_image_comp_t *old_comps, *new_comps;
845	OPJ_BYTE *channel_size, *channel_sign;
846	OPJ_UINT32 *entries;
847	opj_jp2_cmap_comp_t *cmap;
848	OPJ_INT32 *src, *dst;
849	OPJ_UINT32 j, max;
850	OPJ_UINT16 i, nr_channels, cmp, pcol;
851	OPJ_INT32 k, top_k;
852
853	channel_size = color->jp2_pclr->channel_size;
854	channel_sign = color->jp2_pclr->channel_sign;
855	entries = color->jp2_pclr->entries;
856	cmap = color->jp2_pclr->cmap;
857	nr_channels = color->jp2_pclr->nr_channels;
858
859	old_comps = image->comps;
860	new_comps = (opj_image_comp_t*)
861			opj_malloc(nr_channels * sizeof(opj_image_comp_t));
862
863	for(i = 0; i < nr_channels; ++i) {
864		pcol = cmap[i].pcol; cmp = cmap[i].cmp;
865
866		/* Direct use */
867    if(cmap[i].mtyp == 0){
868      assert( pcol == 0 );
869      new_comps[i] = old_comps[cmp];
870    } else {
871      assert( i == pcol );
872      new_comps[pcol] = old_comps[cmp];
873    }
874
875		/* Palette mapping: */
876		new_comps[i].data = (OPJ_INT32*)
877				opj_malloc(old_comps[cmp].w * old_comps[cmp].h * sizeof(OPJ_INT32));
878		new_comps[i].prec = channel_size[i];
879		new_comps[i].sgnd = channel_sign[i];
880	}
881
882	top_k = color->jp2_pclr->nr_entries - 1;
883
884	for(i = 0; i < nr_channels; ++i) {
885		/* Palette mapping: */
886		cmp = cmap[i].cmp; pcol = cmap[i].pcol;
887		src = old_comps[cmp].data;
888    assert( src );
889		max = new_comps[pcol].w * new_comps[pcol].h;
890
891		/* Direct use: */
892    if(cmap[i].mtyp == 0) {
893      assert( cmp == 0 );
894      dst = new_comps[i].data;
895      assert( dst );
896      for(j = 0; j < max; ++j) {
897        dst[j] = src[j];
898      }
899    }
900    else {
901      assert( i == pcol );
902      dst = new_comps[pcol].data;
903      assert( dst );
904      for(j = 0; j < max; ++j) {
905        /* The index */
906        if((k = src[j]) < 0) k = 0; else if(k > top_k) k = top_k;
907
908        /* The colour */
909        dst[j] = (OPJ_INT32)entries[k * nr_channels + pcol];
910        }
911    }
912	}
913
914	max = image->numcomps;
915	for(i = 0; i < max; ++i) {
916		if(old_comps[i].data) opj_free(old_comps[i].data);
917	}
918
919	opj_free(old_comps);
920	image->comps = new_comps;
921	image->numcomps = nr_channels;
922
923	opj_jp2_free_pclr(color);
924
925}/* apply_pclr() */
926
927OPJ_BOOL opj_jp2_read_pclr(	opj_jp2_t *jp2,
928                            OPJ_BYTE * p_pclr_header_data,
929                            OPJ_UINT32 p_pclr_header_size,
930                            opj_event_mgr_t * p_manager
931                            )
932{
933	opj_jp2_pclr_t *jp2_pclr;
934	OPJ_BYTE *channel_size, *channel_sign;
935	OPJ_UINT32 *entries;
936	OPJ_UINT16 nr_entries,nr_channels;
937	OPJ_UINT16 i, j;
938	OPJ_UINT32 l_value;
939	OPJ_BYTE *orig_header_data = p_pclr_header_data;
940
941	/* preconditions */
942	assert(p_pclr_header_data != 00);
943	assert(jp2 != 00);
944	assert(p_manager != 00);
945    (void)p_pclr_header_size;
946
947	if(jp2->color.jp2_pclr)
948		return OPJ_FALSE;
949
950	if (p_pclr_header_size < 3)
951		return OPJ_FALSE;
952
953	opj_read_bytes(p_pclr_header_data, &l_value , 2);	/* NE */
954	p_pclr_header_data += 2;
955	nr_entries = (OPJ_UINT16) l_value;
956
957	opj_read_bytes(p_pclr_header_data, &l_value , 1);	/* NPC */
958	++p_pclr_header_data;
959	nr_channels = (OPJ_UINT16) l_value;
960
961	if (p_pclr_header_size < 3 + (OPJ_UINT32)nr_channels || nr_channels == 0 || nr_entries >= (OPJ_UINT32)-1 / nr_channels)
962		return OPJ_FALSE;
963
964	entries = (OPJ_UINT32*) opj_malloc((size_t)nr_channels * nr_entries * sizeof(OPJ_UINT32));
965    if (!entries)
966        return OPJ_FALSE;
967	channel_size = (OPJ_BYTE*) opj_malloc(nr_channels);
968    if (!channel_size)
969    {
970        opj_free(entries);
971        return OPJ_FALSE;
972    }
973	channel_sign = (OPJ_BYTE*) opj_malloc(nr_channels);
974	if (!channel_sign)
975	{
976        opj_free(entries);
977        opj_free(channel_size);
978        return OPJ_FALSE;
979	}
980
981	jp2_pclr = (opj_jp2_pclr_t*)opj_malloc(sizeof(opj_jp2_pclr_t));
982    if (!jp2_pclr)
983    {
984        opj_free(entries);
985        opj_free(channel_size);
986        opj_free(channel_sign);
987        return OPJ_FALSE;
988    }
989
990	jp2_pclr->channel_sign = channel_sign;
991	jp2_pclr->channel_size = channel_size;
992	jp2_pclr->entries = entries;
993	jp2_pclr->nr_entries = nr_entries;
994	jp2_pclr->nr_channels = (OPJ_BYTE) l_value;
995	jp2_pclr->cmap = NULL;
996
997	jp2->color.jp2_pclr = jp2_pclr;
998
999	for(i = 0; i < nr_channels; ++i) {
1000		opj_read_bytes(p_pclr_header_data, &l_value , 1);	/* Bi */
1001		++p_pclr_header_data;
1002
1003		channel_size[i] = (OPJ_BYTE)((l_value & 0x7f) + 1);
1004		channel_sign[i] = (l_value & 0x80) ? 1 : 0;
1005	}
1006
1007	for(j = 0; j < nr_entries; ++j) {
1008		for(i = 0; i < nr_channels; ++i) {
1009			OPJ_UINT32 bytes_to_read = (OPJ_UINT32)((channel_size[i]+7)>>3);
1010
1011			if (bytes_to_read > sizeof(OPJ_UINT32))
1012				bytes_to_read = sizeof(OPJ_UINT32);
1013			if ((ptrdiff_t)p_pclr_header_size < p_pclr_header_data - orig_header_data + (ptrdiff_t)bytes_to_read)
1014				return OPJ_FALSE;
1015
1016			opj_read_bytes(p_pclr_header_data, &l_value , bytes_to_read);	/* Cji */
1017			p_pclr_header_data += bytes_to_read;
1018			*entries = (OPJ_UINT32) l_value;
1019			entries++;
1020		}
1021	}
1022
1023	return OPJ_TRUE;
1024}
1025
1026OPJ_BOOL opj_jp2_read_cmap(	opj_jp2_t * jp2,
1027                            OPJ_BYTE * p_cmap_header_data,
1028                            OPJ_UINT32 p_cmap_header_size,
1029                            opj_event_mgr_t * p_manager
1030                            )
1031{
1032	opj_jp2_cmap_comp_t *cmap;
1033	OPJ_BYTE i, nr_channels;
1034	OPJ_UINT32 l_value;
1035
1036	/* preconditions */
1037	assert(jp2 != 00);
1038	assert(p_cmap_header_data != 00);
1039	assert(p_manager != 00);
1040    (void)p_cmap_header_size;
1041
1042	/* Need nr_channels: */
1043	if(jp2->color.jp2_pclr == NULL) {
1044		opj_event_msg(p_manager, EVT_ERROR, "Need to read a PCLR box before the CMAP box.\n");
1045		return OPJ_FALSE;
1046	}
1047
1048	/* Part 1, I.5.3.5: 'There shall be at most one Component Mapping box
1049	 * inside a JP2 Header box' :
1050	*/
1051	if(jp2->color.jp2_pclr->cmap) {
1052		opj_event_msg(p_manager, EVT_ERROR, "Only one CMAP box is allowed.\n");
1053		return OPJ_FALSE;
1054	}
1055
1056	nr_channels = jp2->color.jp2_pclr->nr_channels;
1057	if (p_cmap_header_size < (OPJ_UINT32)nr_channels * 4) {
1058		opj_event_msg(p_manager, EVT_ERROR, "Insufficient data for CMAP box.\n");
1059		return OPJ_FALSE;
1060	}
1061
1062	cmap = (opj_jp2_cmap_comp_t*) opj_malloc(nr_channels * sizeof(opj_jp2_cmap_comp_t));
1063    if (!cmap)
1064        return OPJ_FALSE;
1065
1066
1067	for(i = 0; i < nr_channels; ++i) {
1068		opj_read_bytes(p_cmap_header_data, &l_value, 2);			/* CMP^i */
1069		p_cmap_header_data +=2;
1070		cmap[i].cmp = (OPJ_UINT16) l_value;
1071
1072		opj_read_bytes(p_cmap_header_data, &l_value, 1);			/* MTYP^i */
1073		++p_cmap_header_data;
1074		cmap[i].mtyp = (OPJ_BYTE) l_value;
1075
1076		opj_read_bytes(p_cmap_header_data, &l_value, 1);			/* PCOL^i */
1077		++p_cmap_header_data;
1078		cmap[i].pcol = (OPJ_BYTE) l_value;
1079	}
1080
1081	jp2->color.jp2_pclr->cmap = cmap;
1082
1083	return OPJ_TRUE;
1084}
1085
1086void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color)
1087{
1088	opj_jp2_cdef_info_t *info;
1089	OPJ_UINT16 i, n, cn, asoc, acn;
1090
1091	info = color->jp2_cdef->info;
1092	n = color->jp2_cdef->n;
1093
1094  for(i = 0; i < n; ++i)
1095    {
1096    /* WATCH: acn = asoc - 1 ! */
1097    asoc = info[i].asoc;
1098    if(asoc == 0 || asoc == 65535)
1099      {
1100      if (i < image->numcomps)
1101        image->comps[i].alpha = info[i].typ;
1102      continue;
1103      }
1104
1105    cn = info[i].cn;
1106    acn = (OPJ_UINT16)(asoc - 1);
1107    if( cn >= image->numcomps || acn >= image->numcomps )
1108      {
1109      fprintf(stderr, "cn=%d, acn=%d, numcomps=%d\n", cn, acn, image->numcomps);
1110      continue;
1111      }
1112
1113		if(cn != acn)
1114		{
1115			opj_image_comp_t saved;
1116
1117			memcpy(&saved, &image->comps[cn], sizeof(opj_image_comp_t));
1118			memcpy(&image->comps[cn], &image->comps[acn], sizeof(opj_image_comp_t));
1119			memcpy(&image->comps[acn], &saved, sizeof(opj_image_comp_t));
1120
1121			info[i].asoc = (OPJ_UINT16)(cn + 1);
1122			info[acn].asoc = (OPJ_UINT16)(info[acn].cn + 1);
1123		}
1124
1125		image->comps[cn].alpha = info[i].typ;
1126	}
1127
1128	if(color->jp2_cdef->info) opj_free(color->jp2_cdef->info);
1129
1130	opj_free(color->jp2_cdef); color->jp2_cdef = NULL;
1131
1132}/* jp2_apply_cdef() */
1133
1134OPJ_BOOL opj_jp2_read_cdef(	opj_jp2_t * jp2,
1135                            OPJ_BYTE * p_cdef_header_data,
1136							OPJ_UINT32 p_cdef_header_size,
1137							opj_event_mgr_t * p_manager
1138                            )
1139{
1140	opj_jp2_cdef_info_t *cdef_info;
1141	OPJ_UINT16 i;
1142	OPJ_UINT32 l_value;
1143
1144	/* preconditions */
1145	assert(jp2 != 00);
1146	assert(p_cdef_header_data != 00);
1147	assert(p_manager != 00);
1148    (void)p_cdef_header_size;
1149
1150	/* Part 1, I.5.3.6: 'The shall be at most one Channel Definition box
1151	 * inside a JP2 Header box.'*/
1152	if(jp2->color.jp2_cdef) return OPJ_FALSE;
1153
1154	if (p_cdef_header_size < 2) {
1155		opj_event_msg(p_manager, EVT_ERROR, "Insufficient data for CDEF box.\n");
1156		return OPJ_FALSE;
1157	}
1158
1159	opj_read_bytes(p_cdef_header_data,&l_value ,2);			/* N */
1160	p_cdef_header_data+= 2;
1161
1162	if ( (OPJ_UINT16)l_value == 0){ /* szukw000: FIXME */
1163		opj_event_msg(p_manager, EVT_ERROR, "Number of channel description is equal to zero in CDEF box.\n");
1164		return OPJ_FALSE;
1165	}
1166
1167	if (p_cdef_header_size < 2 + (OPJ_UINT32)(OPJ_UINT16)l_value * 6) {
1168		opj_event_msg(p_manager, EVT_ERROR, "Insufficient data for CDEF box.\n");
1169		return OPJ_FALSE;
1170	}
1171
1172	cdef_info = (opj_jp2_cdef_info_t*) opj_malloc(l_value * sizeof(opj_jp2_cdef_info_t));
1173    if (!cdef_info)
1174        return OPJ_FALSE;
1175
1176	jp2->color.jp2_cdef = (opj_jp2_cdef_t*)opj_malloc(sizeof(opj_jp2_cdef_t));
1177    if(!jp2->color.jp2_cdef)
1178    {
1179        opj_free(cdef_info);
1180        return OPJ_FALSE;
1181    }
1182	jp2->color.jp2_cdef->info = cdef_info;
1183	jp2->color.jp2_cdef->n = (OPJ_UINT16) l_value;
1184
1185	for(i = 0; i < jp2->color.jp2_cdef->n; ++i) {
1186		opj_read_bytes(p_cdef_header_data, &l_value, 2);			/* Cn^i */
1187		p_cdef_header_data +=2;
1188		cdef_info[i].cn = (OPJ_UINT16) l_value;
1189
1190		opj_read_bytes(p_cdef_header_data, &l_value, 2);			/* Typ^i */
1191		p_cdef_header_data +=2;
1192		cdef_info[i].typ = (OPJ_UINT16) l_value;
1193
1194		opj_read_bytes(p_cdef_header_data, &l_value, 2);			/* Asoc^i */
1195		p_cdef_header_data +=2;
1196		cdef_info[i].asoc = (OPJ_UINT16) l_value;
1197   }
1198
1199	return OPJ_TRUE;
1200}
1201
1202OPJ_BOOL opj_jp2_read_colr( opj_jp2_t *jp2,
1203                            OPJ_BYTE * p_colr_header_data,
1204                            OPJ_UINT32 p_colr_header_size,
1205                            opj_event_mgr_t * p_manager
1206                            )
1207{
1208	OPJ_UINT32 l_value;
1209
1210	/* preconditions */
1211	assert(jp2 != 00);
1212	assert(p_colr_header_data != 00);
1213	assert(p_manager != 00);
1214
1215	if (p_colr_header_size < 3) {
1216		opj_event_msg(p_manager, EVT_ERROR, "Bad COLR header box (bad size)\n");
1217		return OPJ_FALSE;
1218	}
1219
1220	/* Part 1, I.5.3.3 : 'A conforming JP2 reader shall ignore all Colour
1221	 * Specification boxes after the first.'
1222	*/
1223	if(jp2->color.jp2_has_colr) {
1224		opj_event_msg(p_manager, EVT_INFO, "A conforming JP2 reader shall ignore all Colour Specification boxes after the first, so we ignore this one.\n");
1225		p_colr_header_data += p_colr_header_size;
1226		return OPJ_TRUE;
1227	}
1228
1229	opj_read_bytes(p_colr_header_data,&jp2->meth ,1);			/* METH */
1230	++p_colr_header_data;
1231
1232	opj_read_bytes(p_colr_header_data,&jp2->precedence ,1);		/* PRECEDENCE */
1233	++p_colr_header_data;
1234
1235	opj_read_bytes(p_colr_header_data,&jp2->approx ,1);			/* APPROX */
1236	++p_colr_header_data;
1237
1238	if (jp2->meth == 1) {
1239		if (p_colr_header_size > 7) {
1240			/* testcase Altona_Technical_v20_x4.pdf */
1241			opj_event_msg(p_manager, EVT_WARNING, "Bad COLR header box (bad size: %d)\n", p_colr_header_size);
1242		}
1243
1244		opj_read_bytes(p_colr_header_data,&jp2->enumcs ,4);			/* EnumCS */
1245
1246		p_colr_header_data += 4;
1247
1248		if(jp2->enumcs == 14)/* CIELab */
1249		{
1250			OPJ_UINT32 *cielab;
1251			OPJ_UINT32 rl, ol, ra, oa, rb, ob, il;
1252
1253			cielab = (OPJ_UINT32*)opj_malloc(9 * sizeof(OPJ_UINT32));
1254			cielab[0] = 14; /* enumcs */
1255
1256			if(p_colr_header_size == 7)/* default values */
1257			{
1258				rl = ra = rb = ol = oa = ob = 0;
1259				il = 0x00443530; /* D50 */
1260				cielab[1] = 0x44454600;/* DEF */
1261			}
1262			else if(p_colr_header_size == 35)
1263			{
1264				opj_read_bytes(p_colr_header_data, &rl, 4);
1265				p_colr_header_data += 4;
1266				opj_read_bytes(p_colr_header_data, &ol, 4);
1267				p_colr_header_data += 4;
1268				opj_read_bytes(p_colr_header_data, &ra, 4);
1269				p_colr_header_data += 4;
1270				opj_read_bytes(p_colr_header_data, &oa, 4);
1271				p_colr_header_data += 4;
1272				opj_read_bytes(p_colr_header_data, &rb, 4);
1273				p_colr_header_data += 4;
1274				opj_read_bytes(p_colr_header_data, &ob, 4);
1275				p_colr_header_data += 4;
1276				opj_read_bytes(p_colr_header_data, &il, 4);
1277				p_colr_header_data += 4;
1278				cielab[1] = 0;
1279			}
1280			cielab[2] = rl; cielab[4] = ra; cielab[6] = rb;
1281			cielab[3] = ol; cielab[5] = oa; cielab[7] = ob;
1282			cielab[8] = il;
1283
1284			jp2->color.icc_profile_buf = (unsigned char*)cielab;
1285			jp2->color.icc_profile_len = 0;
1286		}
1287
1288        jp2->color.jp2_has_colr = 1;
1289	}
1290	else if (jp2->meth == 2) {
1291		/* ICC profile */
1292		OPJ_INT32 it_icc_value = 0;
1293		OPJ_INT32 icc_len = (OPJ_INT32)p_colr_header_size - 3;
1294
1295		jp2->color.icc_profile_len = (OPJ_UINT32)icc_len;
1296		jp2->color.icc_profile_buf = (OPJ_BYTE*) opj_malloc((size_t)icc_len);
1297        if (!jp2->color.icc_profile_buf)
1298        {
1299            jp2->color.icc_profile_len = 0;
1300            return OPJ_FALSE;
1301        }
1302		memset(jp2->color.icc_profile_buf, 0, (size_t)icc_len * sizeof(OPJ_BYTE));
1303
1304		for (it_icc_value = 0; it_icc_value < icc_len; ++it_icc_value)
1305		{
1306			opj_read_bytes(p_colr_header_data,&l_value,1);		/* icc values */
1307			++p_colr_header_data;
1308			jp2->color.icc_profile_buf[it_icc_value] = (OPJ_BYTE) l_value;
1309		}
1310
1311        jp2->color.jp2_has_colr = 1;
1312	}
1313	else if (jp2->meth > 2)
1314    {
1315        /*	ISO/IEC 15444-1:2004 (E), Table I.9 ?Legal METH values:
1316        conforming JP2 reader shall ignore the entire Colour Specification box.*/
1317        opj_event_msg(p_manager, EVT_INFO, "COLR BOX meth value is not a regular value (%d), "
1318            "so we will ignore the entire Colour Specification box. \n", jp2->meth);
1319    }
1320    return OPJ_TRUE;
1321}
1322
1323OPJ_BOOL opj_jp2_decode(opj_jp2_t *jp2,
1324                        opj_stream_private_t *p_stream,
1325                        opj_image_t* p_image,
1326                        opj_event_mgr_t * p_manager)
1327{
1328	if (!p_image)
1329		return OPJ_FALSE;
1330
1331	/* J2K decoding */
1332	if( ! opj_j2k_decode(jp2->j2k, p_stream, p_image, p_manager) ) {
1333		opj_event_msg(p_manager, EVT_ERROR, "Failed to decode the codestream in the JP2 file\n");
1334		return OPJ_FALSE;
1335	}
1336
1337    if (!jp2->ignore_pclr_cmap_cdef){
1338	    if (!opj_jp2_check_color(p_image, &(jp2->color), p_manager)) {
1339		    return OPJ_FALSE;
1340	    }
1341
1342	    /* Set Image Color Space */
1343	    if (jp2->enumcs == 16)
1344		    p_image->color_space = OPJ_CLRSPC_SRGB;
1345	    else if (jp2->enumcs == 17)
1346		    p_image->color_space = OPJ_CLRSPC_GRAY;
1347	    else if (jp2->enumcs == 18)
1348		    p_image->color_space = OPJ_CLRSPC_SYCC;
1349            else if (jp2->enumcs == 24)
1350                    p_image->color_space = OPJ_CLRSPC_EYCC;
1351	    else
1352		    p_image->color_space = OPJ_CLRSPC_UNKNOWN;
1353
1354	    /* Apply the color space if needed */
1355	    if(jp2->color.jp2_cdef) {
1356		    opj_jp2_apply_cdef(p_image, &(jp2->color));
1357	    }
1358
1359	    if(jp2->color.jp2_pclr) {
1360		    /* Part 1, I.5.3.4: Either both or none : */
1361		    if( !jp2->color.jp2_pclr->cmap)
1362			    opj_jp2_free_pclr(&(jp2->color));
1363		    else
1364				if(!p_image->useColorSpace)
1365			    opj_jp2_apply_pclr(p_image, &(jp2->color));
1366	    }
1367
1368	    if(jp2->color.icc_profile_buf) {
1369		    p_image->icc_profile_buf = jp2->color.icc_profile_buf;
1370		    p_image->icc_profile_len = jp2->color.icc_profile_len;
1371		    jp2->color.icc_profile_buf = NULL;
1372	    }
1373    }
1374
1375	return OPJ_TRUE;
1376}
1377
1378OPJ_BOOL opj_jp2_write_jp2h(opj_jp2_t *jp2,
1379                            opj_stream_private_t *stream,
1380                            opj_event_mgr_t * p_manager
1381                            )
1382{
1383	opj_jp2_img_header_writer_handler_t l_writers [3];
1384	opj_jp2_img_header_writer_handler_t * l_current_writer;
1385
1386	OPJ_INT32 i, l_nb_pass;
1387	/* size of data for super box*/
1388	OPJ_UINT32 l_jp2h_size = 8;
1389	OPJ_BOOL l_result = OPJ_TRUE;
1390
1391	/* to store the data of the super box */
1392	OPJ_BYTE l_jp2h_data [8];
1393
1394	/* preconditions */
1395	assert(stream != 00);
1396	assert(jp2 != 00);
1397	assert(p_manager != 00);
1398
1399	memset(l_writers,0,sizeof(l_writers));
1400
1401	if (jp2->bpc == 255) {
1402		l_nb_pass = 3;
1403		l_writers[0].handler = opj_jp2_write_ihdr;
1404		l_writers[1].handler = opj_jp2_write_bpcc;
1405		l_writers[2].handler = opj_jp2_write_colr;
1406	}
1407	else {
1408		l_nb_pass = 2;
1409		l_writers[0].handler = opj_jp2_write_ihdr;
1410		l_writers[1].handler = opj_jp2_write_colr;
1411	}
1412
1413	/* write box header */
1414	/* write JP2H type */
1415	opj_write_bytes(l_jp2h_data+4,JP2_JP2H,4);
1416
1417	l_current_writer = l_writers;
1418	for (i=0;i<l_nb_pass;++i) {
1419		l_current_writer->m_data = l_current_writer->handler(jp2,&(l_current_writer->m_size));
1420		if (l_current_writer->m_data == 00) {
1421			opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to hold JP2 Header data\n");
1422			l_result = OPJ_FALSE;
1423			break;
1424		}
1425
1426		l_jp2h_size += l_current_writer->m_size;
1427		++l_current_writer;
1428	}
1429
1430	if (! l_result) {
1431		l_current_writer = l_writers;
1432		for (i=0;i<l_nb_pass;++i) {
1433			if (l_current_writer->m_data != 00) {
1434				opj_free(l_current_writer->m_data );
1435			}
1436			++l_current_writer;
1437		}
1438
1439		return OPJ_FALSE;
1440	}
1441
1442	/* write super box size */
1443	opj_write_bytes(l_jp2h_data,l_jp2h_size,4);
1444
1445	/* write super box data on stream */
1446	if (opj_stream_write_data(stream,l_jp2h_data,8,p_manager) != 8) {
1447		opj_event_msg(p_manager, EVT_ERROR, "Stream error while writing JP2 Header box\n");
1448		l_result = OPJ_FALSE;
1449	}
1450
1451	if (l_result) {
1452		l_current_writer = l_writers;
1453		for (i=0;i<l_nb_pass;++i) {
1454			if (opj_stream_write_data(stream,l_current_writer->m_data,l_current_writer->m_size,p_manager) != l_current_writer->m_size) {
1455				opj_event_msg(p_manager, EVT_ERROR, "Stream error while writing JP2 Header box\n");
1456				l_result = OPJ_FALSE;
1457				break;
1458			}
1459			++l_current_writer;
1460		}
1461	}
1462
1463	l_current_writer = l_writers;
1464
1465	/* cleanup */
1466	for (i=0;i<l_nb_pass;++i) {
1467		if (l_current_writer->m_data != 00) {
1468			opj_free(l_current_writer->m_data );
1469		}
1470		++l_current_writer;
1471	}
1472
1473	return l_result;
1474}
1475
1476OPJ_BOOL opj_jp2_write_ftyp(opj_jp2_t *jp2,
1477							opj_stream_private_t *cio,
1478							opj_event_mgr_t * p_manager )
1479{
1480	OPJ_UINT32 i;
1481	OPJ_UINT32 l_ftyp_size = 16 + 4 * jp2->numcl;
1482	OPJ_BYTE * l_ftyp_data, * l_current_data_ptr;
1483	OPJ_BOOL l_result;
1484
1485	/* preconditions */
1486	assert(cio != 00);
1487	assert(jp2 != 00);
1488	assert(p_manager != 00);
1489
1490	l_ftyp_data = (OPJ_BYTE *) opj_malloc(l_ftyp_size);
1491
1492	if (l_ftyp_data == 00) {
1493		opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle ftyp data\n");
1494		return OPJ_FALSE;
1495	}
1496
1497	memset(l_ftyp_data,0,l_ftyp_size);
1498
1499	l_current_data_ptr = l_ftyp_data;
1500
1501	opj_write_bytes(l_current_data_ptr, l_ftyp_size,4); /* box size */
1502	l_current_data_ptr += 4;
1503
1504	opj_write_bytes(l_current_data_ptr, JP2_FTYP,4); /* FTYP */
1505	l_current_data_ptr += 4;
1506
1507	opj_write_bytes(l_current_data_ptr, jp2->brand,4); /* BR */
1508	l_current_data_ptr += 4;
1509
1510	opj_write_bytes(l_current_data_ptr, jp2->minversion,4); /* MinV */
1511	l_current_data_ptr += 4;
1512
1513	for (i = 0; i < jp2->numcl; i++)  {
1514		opj_write_bytes(l_current_data_ptr, jp2->cl[i],4);	/* CL */
1515	}
1516
1517	l_result = (opj_stream_write_data(cio,l_ftyp_data,l_ftyp_size,p_manager) == l_ftyp_size);
1518	if (! l_result)
1519	{
1520		opj_event_msg(p_manager, EVT_ERROR, "Error while writing ftyp data to stream\n");
1521	}
1522
1523	opj_free(l_ftyp_data);
1524
1525	return l_result;
1526}
1527
1528OPJ_BOOL opj_jp2_write_jp2c(opj_jp2_t *jp2,
1529							opj_stream_private_t *cio,
1530							opj_event_mgr_t * p_manager )
1531{
1532	OPJ_OFF_T j2k_codestream_exit;
1533	OPJ_BYTE l_data_header [8];
1534
1535	/* preconditions */
1536	assert(jp2 != 00);
1537	assert(cio != 00);
1538	assert(p_manager != 00);
1539	assert(opj_stream_has_seek(cio));
1540
1541	j2k_codestream_exit = opj_stream_tell(cio);
1542	opj_write_bytes(l_data_header,
1543                    (OPJ_UINT32) (j2k_codestream_exit - jp2->j2k_codestream_offset),
1544                    4); /* size of codestream */
1545	opj_write_bytes(l_data_header + 4,JP2_JP2C,4);									   /* JP2C */
1546
1547	if (! opj_stream_seek(cio,jp2->j2k_codestream_offset,p_manager)) {
1548		opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
1549		return OPJ_FALSE;
1550	}
1551
1552	if (opj_stream_write_data(cio,l_data_header,8,p_manager) != 8) {
1553		opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
1554		return OPJ_FALSE;
1555	}
1556
1557	if (! opj_stream_seek(cio,j2k_codestream_exit,p_manager)) {
1558		opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
1559		return OPJ_FALSE;
1560	}
1561
1562	return OPJ_TRUE;
1563}
1564
1565OPJ_BOOL opj_jp2_write_jp(	opj_jp2_t *jp2,
1566			    		    opj_stream_private_t *cio,
1567				    		opj_event_mgr_t * p_manager )
1568{
1569	/* 12 bytes will be read */
1570	OPJ_BYTE l_signature_data [12];
1571
1572	/* preconditions */
1573	assert(cio != 00);
1574	assert(jp2 != 00);
1575	assert(p_manager != 00);
1576
1577	/* write box length */
1578	opj_write_bytes(l_signature_data,12,4);
1579	/* writes box type */
1580	opj_write_bytes(l_signature_data+4,JP2_JP,4);
1581	/* writes magic number*/
1582	opj_write_bytes(l_signature_data+8,0x0d0a870a,4);
1583
1584	if (opj_stream_write_data(cio,l_signature_data,12,p_manager) != 12) {
1585		return OPJ_FALSE;
1586	}
1587
1588	return OPJ_TRUE;
1589}
1590
1591/* ----------------------------------------------------------------------- */
1592/* JP2 decoder interface                                             */
1593/* ----------------------------------------------------------------------- */
1594
1595void opj_jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters)
1596{
1597	/* setup the J2K codec */
1598	opj_j2k_setup_decoder(jp2->j2k, parameters);
1599
1600	/* further JP2 initializations go here */
1601	jp2->color.jp2_has_colr = 0;
1602    jp2->ignore_pclr_cmap_cdef = parameters->flags & OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
1603}
1604
1605/* ----------------------------------------------------------------------- */
1606/* JP2 encoder interface                                             */
1607/* ----------------------------------------------------------------------- */
1608
1609void opj_jp2_setup_encoder(	opj_jp2_t *jp2,
1610                            opj_cparameters_t *parameters,
1611                            opj_image_t *image,
1612                            opj_event_mgr_t * p_manager)
1613{
1614    OPJ_UINT32 i;
1615	OPJ_UINT32 depth_0;
1616  OPJ_UINT32 sign;
1617
1618	if(!jp2 || !parameters || !image)
1619		return;
1620
1621	/* setup the J2K codec */
1622	/* ------------------- */
1623
1624	/* Check if number of components respects standard */
1625	if (image->numcomps < 1 || image->numcomps > 16384) {
1626		opj_event_msg(p_manager, EVT_ERROR, "Invalid number of components specified while setting up JP2 encoder\n");
1627		return;
1628	}
1629
1630	opj_j2k_setup_encoder(jp2->j2k, parameters, image, p_manager );
1631
1632	/* setup the JP2 codec */
1633	/* ------------------- */
1634
1635	/* Profile box */
1636
1637	jp2->brand = JP2_JP2;	/* BR */
1638	jp2->minversion = 0;	/* MinV */
1639	jp2->numcl = 1;
1640	jp2->cl = (OPJ_UINT32*) opj_malloc(jp2->numcl * sizeof(OPJ_UINT32));
1641    if (!jp2->cl){
1642        jp2->cl = NULL;
1643        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory when setup the JP2 encoder\n");
1644        return;
1645    }
1646	jp2->cl[0] = JP2_JP2;	/* CL0 : JP2 */
1647
1648	/* Image Header box */
1649
1650	jp2->numcomps = image->numcomps;	/* NC */
1651	jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t));
1652    if (!jp2->comps) {
1653        jp2->comps = NULL;
1654        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory when setup the JP2 encoder\n");
1655        return;
1656    }
1657
1658	jp2->h = image->y1 - image->y0;		/* HEIGHT */
1659	jp2->w = image->x1 - image->x0;		/* WIDTH */
1660	/* BPC */
1661	depth_0 = image->comps[0].prec - 1;
1662	sign = image->comps[0].sgnd;
1663	jp2->bpc = depth_0 + (sign << 7);
1664	for (i = 1; i < image->numcomps; i++) {
1665		OPJ_UINT32 depth = image->comps[i].prec - 1;
1666		sign = image->comps[i].sgnd;
1667		if (depth_0 != depth)
1668			jp2->bpc = 255;
1669	}
1670	jp2->C = 7;			/* C : Always 7 */
1671	jp2->UnkC = 0;		/* UnkC, colorspace specified in colr box */
1672	jp2->IPR = 0;		/* IPR, no intellectual property */
1673
1674	/* BitsPerComponent box */
1675	for (i = 0; i < image->numcomps; i++) {
1676		jp2->comps[i].bpcc = image->comps[i].prec - 1 + (image->comps[i].sgnd << 7);
1677	}
1678
1679	/* Colour Specification box */
1680    if(image->icc_profile_len) {
1681        jp2->meth = 2;
1682        jp2->enumcs = 0;
1683    }
1684    else {
1685        jp2->meth = 1;
1686        if (image->color_space == 1)
1687            jp2->enumcs = 16;	/* sRGB as defined by IEC 61966-2-1 */
1688        else if (image->color_space == 2)
1689            jp2->enumcs = 17;	/* greyscale */
1690        else if (image->color_space == 3)
1691            jp2->enumcs = 18;	/* YUV */
1692    }
1693
1694
1695	jp2->precedence = 0;	/* PRECEDENCE */
1696	jp2->approx = 0;		/* APPROX */
1697
1698	jp2->jpip_on = parameters->jpip_on;
1699}
1700
1701OPJ_BOOL opj_jp2_encode(opj_jp2_t *jp2,
1702						opj_stream_private_t *stream,
1703						opj_event_mgr_t * p_manager)
1704{
1705	return opj_j2k_encode(jp2->j2k, stream, p_manager);
1706}
1707
1708OPJ_BOOL opj_jp2_end_decompress(opj_jp2_t *jp2,
1709                                opj_stream_private_t *cio,
1710                                opj_event_mgr_t * p_manager
1711                                )
1712{
1713	/* preconditions */
1714	assert(jp2 != 00);
1715	assert(cio != 00);
1716	assert(p_manager != 00);
1717
1718	/* customization of the end encoding */
1719	opj_jp2_setup_end_header_reading(jp2);
1720
1721	/* write header */
1722	if (! opj_jp2_exec (jp2,jp2->m_procedure_list,cio,p_manager)) {
1723		return OPJ_FALSE;
1724	}
1725
1726	return opj_j2k_end_decompress(jp2->j2k, cio, p_manager);
1727}
1728
1729OPJ_BOOL opj_jp2_end_compress(	opj_jp2_t *jp2,
1730							    opj_stream_private_t *cio,
1731							    opj_event_mgr_t * p_manager
1732                                )
1733{
1734	/* preconditions */
1735	assert(jp2 != 00);
1736	assert(cio != 00);
1737	assert(p_manager != 00);
1738
1739	/* customization of the end encoding */
1740	opj_jp2_setup_end_header_writing(jp2);
1741
1742	if (! opj_j2k_end_compress(jp2->j2k,cio,p_manager)) {
1743		return OPJ_FALSE;
1744	}
1745
1746	/* write header */
1747	return opj_jp2_exec(jp2,jp2->m_procedure_list,cio,p_manager);
1748}
1749
1750void opj_jp2_setup_end_header_writing (opj_jp2_t *jp2)
1751{
1752	/* preconditions */
1753	assert(jp2 != 00);
1754
1755#ifdef USE_JPIP
1756  if( jp2->jpip_on )
1757    opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_write_iptr );
1758#endif
1759	opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_jp2c );
1760	/* DEVELOPER CORNER, add your custom procedures */
1761#ifdef USE_JPIP
1762  if( jp2->jpip_on )
1763    {
1764    opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_write_cidx );
1765    opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_write_fidx );
1766    }
1767#endif
1768}
1769
1770void opj_jp2_setup_end_header_reading (opj_jp2_t *jp2)
1771{
1772	/* preconditions */
1773	assert(jp2 != 00);
1774	opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_read_header_procedure );
1775	/* DEVELOPER CORNER, add your custom procedures */
1776}
1777
1778OPJ_BOOL opj_jp2_default_validation (	opj_jp2_t * jp2,
1779                                        opj_stream_private_t *cio,
1780                                        opj_event_mgr_t * p_manager
1781                                        )
1782{
1783	OPJ_BOOL l_is_valid = OPJ_TRUE;
1784	OPJ_UINT32 i;
1785
1786	/* preconditions */
1787	assert(jp2 != 00);
1788	assert(cio != 00);
1789	assert(p_manager != 00);
1790
1791	/* JPEG2000 codec validation */
1792
1793	/* STATE checking */
1794	/* make sure the state is at 0 */
1795	l_is_valid &= (jp2->jp2_state == JP2_STATE_NONE);
1796
1797	/* make sure not reading a jp2h ???? WEIRD */
1798	l_is_valid &= (jp2->jp2_img_state == JP2_IMG_STATE_NONE);
1799
1800	/* POINTER validation */
1801	/* make sure a j2k codec is present */
1802	l_is_valid &= (jp2->j2k != 00);
1803
1804	/* make sure a procedure list is present */
1805	l_is_valid &= (jp2->m_procedure_list != 00);
1806
1807	/* make sure a validation list is present */
1808	l_is_valid &= (jp2->m_validation_list != 00);
1809
1810	/* PARAMETER VALIDATION */
1811	/* number of components */
1812	l_is_valid &= (jp2->numcl > 0);
1813	/* width */
1814	l_is_valid &= (jp2->h > 0);
1815	/* height */
1816	l_is_valid &= (jp2->w > 0);
1817	/* precision */
1818	for (i = 0; i < jp2->numcomps; ++i)	{
1819		l_is_valid &= (jp2->comps[i].bpcc > 0);
1820	}
1821
1822	/* METH */
1823	l_is_valid &= ((jp2->meth > 0) && (jp2->meth < 3));
1824
1825	/* stream validation */
1826	/* back and forth is needed */
1827	l_is_valid &= opj_stream_has_seek(cio);
1828
1829	return l_is_valid;
1830}
1831
1832OPJ_BOOL opj_jp2_read_header_procedure(  opj_jp2_t *jp2,
1833                                                opj_stream_private_t *stream,
1834                                                opj_event_mgr_t * p_manager
1835                                                )
1836{
1837	opj_jp2_box_t box;
1838	OPJ_UINT32 l_nb_bytes_read;
1839	const opj_jp2_header_handler_t * l_current_handler;
1840	OPJ_UINT32 l_last_data_size = OPJ_BOX_SIZE;
1841	OPJ_UINT32 l_current_data_size;
1842	OPJ_BYTE * l_current_data = 00;
1843
1844	/* preconditions */
1845	assert(stream != 00);
1846	assert(jp2 != 00);
1847	assert(p_manager != 00);
1848
1849	l_current_data = (OPJ_BYTE*)opj_malloc(l_last_data_size);
1850
1851	if (l_current_data == 00) {
1852		opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle jpeg2000 file header\n");
1853		return OPJ_FALSE;
1854	}
1855	memset(l_current_data, 0 , l_last_data_size);
1856
1857	while (opj_jp2_read_boxhdr(&box,&l_nb_bytes_read,stream,p_manager)) {
1858		/* is it the codestream box ? */
1859		if (box.type == JP2_JP2C) {
1860			if (jp2->jp2_state & JP2_STATE_HEADER) {
1861				jp2->jp2_state |= JP2_STATE_CODESTREAM;
1862                                opj_free(l_current_data);
1863				return OPJ_TRUE;
1864			}
1865			else {
1866				opj_event_msg(p_manager, EVT_ERROR, "bad placed jpeg codestream\n");
1867				opj_free(l_current_data);
1868				return OPJ_FALSE;
1869			}
1870		}
1871		else if	(box.length == 0) {
1872			opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of undefined sizes\n");
1873			opj_free(l_current_data);
1874			return OPJ_FALSE;
1875		}
1876		/* testcase 1851.pdf.SIGSEGV.ce9.948 */
1877		/* testcase K-5787457125613568 */
1878		else if	(box.length < l_nb_bytes_read || box.length > opj_stream_get_number_byte_left(stream)) {
1879			opj_event_msg(p_manager, EVT_ERROR, "invalid box size %d (%x)\n", box.length, box.type);
1880			opj_free(l_current_data);
1881			return OPJ_FALSE;
1882		}
1883
1884		l_current_handler = opj_jp2_find_handler(box.type);
1885		l_current_data_size = box.length - l_nb_bytes_read;
1886
1887		if (l_current_handler != 00) {
1888			if (l_current_data_size > l_last_data_size) {
1889				OPJ_BYTE* new_current_data = (OPJ_BYTE*)opj_realloc(l_current_data,l_current_data_size);
1890				if (!new_current_data) {
1891					opj_free(l_current_data);
1892                    opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle jpeg2000 box\n");
1893					return OPJ_FALSE;
1894				}
1895                l_current_data = new_current_data;
1896				l_last_data_size = l_current_data_size;
1897			}
1898
1899			l_nb_bytes_read = (OPJ_UINT32)opj_stream_read_data(stream,l_current_data,l_current_data_size,p_manager);
1900			if (l_nb_bytes_read != l_current_data_size) {
1901				opj_event_msg(p_manager, EVT_ERROR, "Problem with reading JPEG2000 box, stream error\n");
1902                opj_free(l_current_data);
1903				return OPJ_FALSE;
1904			}
1905
1906			if (! l_current_handler->handler(jp2,l_current_data,l_current_data_size,p_manager)) {
1907				opj_free(l_current_data);
1908				return OPJ_FALSE;
1909			}
1910		}
1911		else {
1912			jp2->jp2_state |= JP2_STATE_UNKNOWN;
1913			if (opj_stream_skip(stream,l_current_data_size,p_manager) != l_current_data_size) {
1914				opj_event_msg(p_manager, EVT_ERROR, "Problem with skipping JPEG2000 box, stream error\n");
1915				opj_free(l_current_data);
1916				return OPJ_FALSE;
1917			}
1918		}
1919	}
1920
1921	opj_free(l_current_data);
1922
1923	return OPJ_TRUE;
1924}
1925
1926/**
1927 * Excutes the given procedures on the given codec.
1928 *
1929 * @param	p_procedure_list	the list of procedures to execute
1930 * @param	jp2					the jpeg2000 file codec to execute the procedures on.
1931 * @param	stream					the stream to execute the procedures on.
1932 * @param	p_manager			the user manager.
1933 *
1934 * @return	true				if all the procedures were successfully executed.
1935 */
1936static OPJ_BOOL opj_jp2_exec (  opj_jp2_t * jp2,
1937                                opj_procedure_list_t * p_procedure_list,
1938                                opj_stream_private_t *stream,
1939                                opj_event_mgr_t * p_manager
1940                                )
1941
1942{
1943	OPJ_BOOL (** l_procedure) (opj_jp2_t * jp2, opj_stream_private_t *, opj_event_mgr_t *) = 00;
1944	OPJ_BOOL l_result = OPJ_TRUE;
1945	OPJ_UINT32 l_nb_proc, i;
1946
1947	/* preconditions */
1948	assert(p_procedure_list != 00);
1949	assert(jp2 != 00);
1950	assert(stream != 00);
1951	assert(p_manager != 00);
1952
1953	l_nb_proc = opj_procedure_list_get_nb_procedures(p_procedure_list);
1954	l_procedure = (OPJ_BOOL (**) (opj_jp2_t * jp2, opj_stream_private_t *, opj_event_mgr_t *)) opj_procedure_list_get_first_procedure(p_procedure_list);
1955
1956	for	(i=0;i<l_nb_proc;++i) {
1957		l_result = l_result && (*l_procedure) (jp2,stream,p_manager);
1958		++l_procedure;
1959	}
1960
1961	/* and clear the procedure list at the end. */
1962	opj_procedure_list_clear(p_procedure_list);
1963	return l_result;
1964}
1965
1966OPJ_BOOL opj_jp2_start_compress(opj_jp2_t *jp2,
1967                                opj_stream_private_t *stream,
1968                                opj_image_t * p_image,
1969                                opj_event_mgr_t * p_manager
1970                                )
1971{
1972	/* preconditions */
1973	assert(jp2 != 00);
1974	assert(stream != 00);
1975	assert(p_manager != 00);
1976
1977	/* customization of the validation */
1978	opj_jp2_setup_encoding_validation (jp2);
1979
1980	/* validation of the parameters codec */
1981	if (! opj_jp2_exec(jp2,jp2->m_validation_list,stream,p_manager)) {
1982		return OPJ_FALSE;
1983	}
1984
1985	/* customization of the encoding */
1986	opj_jp2_setup_header_writing(jp2);
1987
1988	/* write header */
1989	if (! opj_jp2_exec (jp2,jp2->m_procedure_list,stream,p_manager)) {
1990		return OPJ_FALSE;
1991	}
1992
1993	return opj_j2k_start_compress(jp2->j2k,stream,p_image,p_manager);
1994}
1995
1996const opj_jp2_header_handler_t * opj_jp2_find_handler (OPJ_UINT32 p_id)
1997{
1998	OPJ_UINT32 i, l_handler_size = sizeof(jp2_header) / sizeof(opj_jp2_header_handler_t);
1999
2000	for (i=0;i<l_handler_size;++i) {
2001		if (jp2_header[i].id == p_id) {
2002			return &jp2_header[i];
2003		}
2004	}
2005	return NULL;
2006}
2007
2008/**
2009 * Finds the image execution function related to the given box id.
2010 *
2011 * @param	p_id	the id of the handler to fetch.
2012 *
2013 * @return	the given handler or 00 if it could not be found.
2014 */
2015static const opj_jp2_header_handler_t * opj_jp2_img_find_handler (OPJ_UINT32 p_id)
2016{
2017	OPJ_UINT32 i, l_handler_size = sizeof(jp2_img_header) / sizeof(opj_jp2_header_handler_t);
2018	for (i=0;i<l_handler_size;++i)
2019	{
2020		if (jp2_img_header[i].id == p_id) {
2021			return &jp2_img_header[i];
2022		}
2023	}
2024
2025	return NULL;
2026}
2027
2028/**
2029 * Reads a jpeg2000 file signature box.
2030 *
2031 * @param	p_header_data	the data contained in the signature box.
2032 * @param	jp2				the jpeg2000 file codec.
2033 * @param	p_header_size	the size of the data contained in the signature box.
2034 * @param	p_manager		the user event manager.
2035 *
2036 * @return true if the file signature box is valid.
2037 */
2038static OPJ_BOOL opj_jp2_read_jp(opj_jp2_t *jp2,
2039                                OPJ_BYTE * p_header_data,
2040                                OPJ_UINT32 p_header_size,
2041                                opj_event_mgr_t * p_manager
2042                                )
2043
2044{
2045	OPJ_UINT32 l_magic_number;
2046
2047	/* preconditions */
2048	assert(p_header_data != 00);
2049	assert(jp2 != 00);
2050	assert(p_manager != 00);
2051
2052	if (jp2->jp2_state != JP2_STATE_NONE) {
2053		opj_event_msg(p_manager, EVT_ERROR, "The signature box must be the first box in the file.\n");
2054		return OPJ_FALSE;
2055	}
2056
2057	/* assure length of data is correct (4 -> magic number) */
2058	if (p_header_size != 4) {
2059		opj_event_msg(p_manager, EVT_ERROR, "Error with JP signature Box size\n");
2060		return OPJ_FALSE;
2061	}
2062
2063	/* rearrange data */
2064	opj_read_bytes(p_header_data,&l_magic_number,4);
2065	if (l_magic_number != 0x0d0a870a ) {
2066		opj_event_msg(p_manager, EVT_ERROR, "Error with JP Signature : bad magic number\n");
2067		return OPJ_FALSE;
2068	}
2069
2070	jp2->jp2_state |= JP2_STATE_SIGNATURE;
2071
2072	return OPJ_TRUE;
2073}
2074
2075/**
2076 * Reads a a FTYP box - File type box
2077 *
2078 * @param	p_header_data	the data contained in the FTYP box.
2079 * @param	jp2				the jpeg2000 file codec.
2080 * @param	p_header_size	the size of the data contained in the FTYP box.
2081 * @param	p_manager		the user event manager.
2082 *
2083 * @return true if the FTYP box is valid.
2084 */
2085static OPJ_BOOL opj_jp2_read_ftyp(	opj_jp2_t *jp2,
2086									OPJ_BYTE * p_header_data,
2087									OPJ_UINT32 p_header_size,
2088									opj_event_mgr_t * p_manager
2089                                    )
2090{
2091	OPJ_UINT32 i, l_remaining_bytes;
2092
2093	/* preconditions */
2094	assert(p_header_data != 00);
2095	assert(jp2 != 00);
2096	assert(p_manager != 00);
2097
2098	if (jp2->jp2_state != JP2_STATE_SIGNATURE) {
2099		opj_event_msg(p_manager, EVT_ERROR, "The ftyp box must be the second box in the file.\n");
2100		return OPJ_FALSE;
2101	}
2102
2103	/* assure length of data is correct */
2104	if (p_header_size < 8) {
2105		opj_event_msg(p_manager, EVT_ERROR, "Error with FTYP signature Box size\n");
2106		return OPJ_FALSE;
2107	}
2108
2109	opj_read_bytes(p_header_data,&jp2->brand,4);		/* BR */
2110	p_header_data += 4;
2111
2112	opj_read_bytes(p_header_data,&jp2->minversion,4);		/* MinV */
2113	p_header_data += 4;
2114
2115	l_remaining_bytes = p_header_size - 8;
2116
2117	/* the number of remaining bytes should be a multiple of 4 */
2118	if ((l_remaining_bytes & 0x3) != 0) {
2119		opj_event_msg(p_manager, EVT_ERROR, "Error with FTYP signature Box size\n");
2120		return OPJ_FALSE;
2121	}
2122
2123	/* div by 4 */
2124	jp2->numcl = l_remaining_bytes >> 2;
2125	if (jp2->numcl) {
2126		jp2->cl = (OPJ_UINT32 *) opj_malloc(jp2->numcl * sizeof(OPJ_UINT32));
2127		if (jp2->cl == 00) {
2128			opj_event_msg(p_manager, EVT_ERROR, "Not enough memory with FTYP Box\n");
2129			return OPJ_FALSE;
2130		}
2131		memset(jp2->cl,0,jp2->numcl * sizeof(OPJ_UINT32));
2132	}
2133
2134	for (i = 0; i < jp2->numcl; ++i)
2135	{
2136		opj_read_bytes(p_header_data,&jp2->cl[i],4);		/* CLi */
2137		p_header_data += 4;
2138	}
2139
2140	jp2->jp2_state |= JP2_STATE_FILE_TYPE;
2141
2142	return OPJ_TRUE;
2143}
2144
2145OPJ_BOOL opj_jp2_skip_jp2c(	opj_jp2_t *jp2,
2146					    	opj_stream_private_t *stream,
2147					    	opj_event_mgr_t * p_manager )
2148{
2149	/* preconditions */
2150	assert(jp2 != 00);
2151	assert(stream != 00);
2152	assert(p_manager != 00);
2153
2154	jp2->j2k_codestream_offset = opj_stream_tell(stream);
2155
2156	if (opj_stream_skip(stream,8,p_manager) != 8) {
2157		return OPJ_FALSE;
2158	}
2159
2160	return OPJ_TRUE;
2161}
2162
2163static OPJ_BOOL opj_jpip_skip_iptr(	opj_jp2_t *jp2,
2164  opj_stream_private_t *stream,
2165  opj_event_mgr_t * p_manager )
2166{
2167  /* preconditions */
2168  assert(jp2 != 00);
2169  assert(stream != 00);
2170  assert(p_manager != 00);
2171
2172  jp2->jpip_iptr_offset = opj_stream_tell(stream);
2173
2174  if (opj_stream_skip(stream,24,p_manager) != 24) {
2175    return OPJ_FALSE;
2176  }
2177
2178  return OPJ_TRUE;
2179}
2180
2181/**
2182 * Reads the Jpeg2000 file Header box - JP2 Header box (warning, this is a super box).
2183 *
2184 * @param	p_header_data	the data contained in the file header box.
2185 * @param	jp2				the jpeg2000 file codec.
2186 * @param	p_header_size	the size of the data contained in the file header box.
2187 * @param	p_manager		the user event manager.
2188 *
2189 * @return true if the JP2 Header box was successfully reconized.
2190*/
2191static OPJ_BOOL opj_jp2_read_jp2h(  opj_jp2_t *jp2,
2192                                    OPJ_BYTE *p_header_data,
2193                                    OPJ_UINT32 p_header_size,
2194                                    opj_event_mgr_t * p_manager
2195                                    )
2196{
2197	OPJ_UINT32 l_box_size=0, l_current_data_size = 0;
2198	opj_jp2_box_t box;
2199	const opj_jp2_header_handler_t * l_current_handler;
2200
2201	/* preconditions */
2202	assert(p_header_data != 00);
2203	assert(jp2 != 00);
2204	assert(p_manager != 00);
2205
2206	/* make sure the box is well placed */
2207	if ((jp2->jp2_state & JP2_STATE_FILE_TYPE) != JP2_STATE_FILE_TYPE ) {
2208		opj_event_msg(p_manager, EVT_ERROR, "The  box must be the first box in the file.\n");
2209		return OPJ_FALSE;
2210	}
2211
2212	jp2->jp2_img_state = JP2_IMG_STATE_NONE;
2213
2214	/* iterate while remaining data */
2215	while (p_header_size > 0) {
2216
2217		if (! opj_jp2_read_boxhdr_char(&box,p_header_data,&l_box_size,p_header_size, p_manager)) {
2218			opj_event_msg(p_manager, EVT_ERROR, "Stream error while reading JP2 Header box\n");
2219			return OPJ_FALSE;
2220		}
2221
2222		if (box.length > p_header_size) {
2223			opj_event_msg(p_manager, EVT_ERROR, "Stream error while reading JP2 Header box: box length is inconsistent.\n");
2224			return OPJ_FALSE;
2225		}
2226
2227		l_current_handler = opj_jp2_img_find_handler(box.type);
2228		//BUGID:0055999
2229		//test file: fuzz-signal_sigsegv_6b88de_1123_2509.pdf
2230		if (box.length < l_box_size) return OPJ_FALSE;
2231		l_current_data_size = box.length - l_box_size;
2232		p_header_data += l_box_size;
2233
2234		if (l_current_handler != 00) {
2235			if (! l_current_handler->handler(jp2,p_header_data,l_current_data_size,p_manager)) {
2236				return OPJ_FALSE;
2237			}
2238		}
2239		else {
2240			jp2->jp2_img_state |= JP2_IMG_STATE_UNKNOWN;
2241		}
2242
2243		p_header_data += l_current_data_size;
2244		p_header_size -= box.length;
2245	}
2246
2247	jp2->jp2_state |= JP2_STATE_HEADER;
2248
2249	return OPJ_TRUE;
2250}
2251
2252OPJ_BOOL opj_jp2_read_boxhdr_char(   opj_jp2_box_t *box,
2253                                     OPJ_BYTE * p_data,
2254                                     OPJ_UINT32 * p_number_bytes_read,
2255                                     OPJ_UINT32 p_box_max_size,
2256                                     opj_event_mgr_t * p_manager
2257                                     )
2258{
2259	OPJ_UINT32 l_value;
2260
2261	/* preconditions */
2262	assert(p_data != 00);
2263	assert(box != 00);
2264	assert(p_number_bytes_read != 00);
2265	assert(p_manager != 00);
2266
2267	if (p_box_max_size < 8) {
2268		opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of less than 8 bytes\n");
2269		return OPJ_FALSE;
2270	}
2271
2272	/* process read data */
2273	opj_read_bytes(p_data, &l_value, 4);
2274	p_data += 4;
2275	box->length = (OPJ_UINT32)(l_value);
2276
2277	opj_read_bytes(p_data, &l_value, 4);
2278	p_data += 4;
2279	box->type = (OPJ_UINT32)(l_value);
2280
2281	*p_number_bytes_read = 8;
2282
2283	/* do we have a "special very large box ?" */
2284	/* read then the XLBox */
2285	if (box->length == 1) {
2286		OPJ_UINT32 l_xl_part_size;
2287
2288		if (p_box_max_size < 16) {
2289			opj_event_msg(p_manager, EVT_ERROR, "Cannot handle XL box of less than 16 bytes\n");
2290			return OPJ_FALSE;
2291		}
2292
2293		opj_read_bytes(p_data,&l_xl_part_size, 4);
2294		p_data += 4;
2295		*p_number_bytes_read += 4;
2296
2297		if (l_xl_part_size != 0) {
2298			opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n");
2299			return OPJ_FALSE;
2300		}
2301
2302		opj_read_bytes(p_data, &l_value, 4);
2303		*p_number_bytes_read += 4;
2304		box->length = (OPJ_UINT32)(l_value);
2305
2306		if (box->length == 0) {
2307			opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of undefined sizes\n");
2308			return OPJ_FALSE;
2309		}
2310	}
2311	else if (box->length == 0) {
2312		opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of undefined sizes\n");
2313		return OPJ_FALSE;
2314	}
2315
2316	return OPJ_TRUE;
2317}
2318
2319OPJ_BOOL opj_jp2_read_header(	opj_stream_private_t *p_stream,
2320                                opj_jp2_t *jp2,
2321                                opj_image_t ** p_image,
2322                                opj_event_mgr_t * p_manager
2323                                )
2324{
2325	/* preconditions */
2326	assert(jp2 != 00);
2327	assert(p_stream != 00);
2328	assert(p_manager != 00);
2329
2330	/* customization of the validation */
2331	opj_jp2_setup_decoding_validation (jp2);
2332
2333	/* customization of the encoding */
2334	opj_jp2_setup_header_reading(jp2);
2335
2336	/* validation of the parameters codec */
2337	if (! opj_jp2_exec(jp2,jp2->m_validation_list,p_stream,p_manager)) {
2338		return OPJ_FALSE;
2339	}
2340
2341	/* read header */
2342	if (! opj_jp2_exec (jp2,jp2->m_procedure_list,p_stream,p_manager)) {
2343		return OPJ_FALSE;
2344	}
2345
2346	return opj_j2k_read_header(	p_stream,
2347							jp2->j2k,
2348							p_image,
2349							p_manager);
2350}
2351
2352void opj_jp2_setup_encoding_validation (opj_jp2_t *jp2)
2353{
2354	/* preconditions */
2355	assert(jp2 != 00);
2356
2357	opj_procedure_list_add_procedure(jp2->m_validation_list, (opj_procedure)opj_jp2_default_validation);
2358	/* DEVELOPER CORNER, add your custom validation procedure */
2359}
2360
2361void opj_jp2_setup_decoding_validation (opj_jp2_t *jp2)
2362{
2363	/* preconditions */
2364	assert(jp2 != 00);
2365	/* DEVELOPER CORNER, add your custom validation procedure */
2366}
2367
2368void opj_jp2_setup_header_writing (opj_jp2_t *jp2)
2369{
2370	/* preconditions */
2371	assert(jp2 != 00);
2372
2373	opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_jp );
2374	opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_ftyp );
2375	opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_jp2h );
2376  if( jp2->jpip_on )
2377    opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_skip_iptr );
2378	opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_skip_jp2c );
2379
2380	/* DEVELOPER CORNER, insert your custom procedures */
2381
2382}
2383
2384void opj_jp2_setup_header_reading (opj_jp2_t *jp2)
2385{
2386	/* preconditions */
2387	assert(jp2 != 00);
2388
2389	opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_read_header_procedure );
2390	/* DEVELOPER CORNER, add your custom procedures */
2391}
2392
2393OPJ_BOOL opj_jp2_read_tile_header ( opj_jp2_t * p_jp2,
2394                                    OPJ_UINT32 * p_tile_index,
2395                                    OPJ_UINT32 * p_data_size,
2396                                    OPJ_INT32 * p_tile_x0,
2397                                    OPJ_INT32 * p_tile_y0,
2398                                    OPJ_INT32 * p_tile_x1,
2399                                    OPJ_INT32 * p_tile_y1,
2400                                    OPJ_UINT32 * p_nb_comps,
2401                                    OPJ_BOOL * p_go_on,
2402                                    opj_stream_private_t *p_stream,
2403                                    opj_event_mgr_t * p_manager
2404                                    )
2405{
2406	return opj_j2k_read_tile_header(p_jp2->j2k,
2407								p_tile_index,
2408								p_data_size,
2409								p_tile_x0, p_tile_y0,
2410								p_tile_x1, p_tile_y1,
2411								p_nb_comps,
2412								p_go_on,
2413								p_stream,
2414								p_manager);
2415}
2416
2417OPJ_BOOL opj_jp2_write_tile (	opj_jp2_t *p_jp2,
2418					 	 	    OPJ_UINT32 p_tile_index,
2419					 	 	    OPJ_BYTE * p_data,
2420					 	 	    OPJ_UINT32 p_data_size,
2421					 	 	    opj_stream_private_t *p_stream,
2422					 	 	    opj_event_mgr_t * p_manager
2423                                )
2424
2425{
2426	return opj_j2k_write_tile (p_jp2->j2k,p_tile_index,p_data,p_data_size,p_stream,p_manager);
2427}
2428
2429OPJ_BOOL opj_jp2_decode_tile (  opj_jp2_t * p_jp2,
2430                                OPJ_UINT32 p_tile_index,
2431                                OPJ_BYTE * p_data,
2432                                OPJ_UINT32 p_data_size,
2433                                opj_stream_private_t *p_stream,
2434                                opj_event_mgr_t * p_manager
2435                                )
2436{
2437	return opj_j2k_decode_tile (p_jp2->j2k,p_tile_index,p_data,p_data_size,p_stream,p_manager);
2438}
2439
2440void opj_jp2_destroy(opj_jp2_t *jp2)
2441{
2442	if (jp2) {
2443		/* destroy the J2K codec */
2444		opj_j2k_destroy(jp2->j2k);
2445		jp2->j2k = 00;
2446
2447		if (jp2->comps) {
2448			opj_free(jp2->comps);
2449			jp2->comps = 00;
2450		}
2451
2452		if (jp2->cl) {
2453			opj_free(jp2->cl);
2454			jp2->cl = 00;
2455		}
2456
2457		if (jp2->color.icc_profile_buf) {
2458			opj_free(jp2->color.icc_profile_buf);
2459			jp2->color.icc_profile_buf = 00;
2460		}
2461
2462		if (jp2->color.jp2_cdef) {
2463			if (jp2->color.jp2_cdef->info) {
2464				opj_free(jp2->color.jp2_cdef->info);
2465				jp2->color.jp2_cdef->info = NULL;
2466			}
2467
2468			opj_free(jp2->color.jp2_cdef);
2469			jp2->color.jp2_cdef = 00;
2470		}
2471
2472		if (jp2->color.jp2_pclr) {
2473			if (jp2->color.jp2_pclr->cmap) {
2474				opj_free(jp2->color.jp2_pclr->cmap);
2475				jp2->color.jp2_pclr->cmap = NULL;
2476			}
2477			if (jp2->color.jp2_pclr->channel_sign) {
2478				opj_free(jp2->color.jp2_pclr->channel_sign);
2479				jp2->color.jp2_pclr->channel_sign = NULL;
2480			}
2481			if (jp2->color.jp2_pclr->channel_size) {
2482				opj_free(jp2->color.jp2_pclr->channel_size);
2483				jp2->color.jp2_pclr->channel_size = NULL;
2484			}
2485			if (jp2->color.jp2_pclr->entries) {
2486				opj_free(jp2->color.jp2_pclr->entries);
2487				jp2->color.jp2_pclr->entries = NULL;
2488			}
2489
2490			opj_free(jp2->color.jp2_pclr);
2491			jp2->color.jp2_pclr = 00;
2492		}
2493
2494		if (jp2->m_validation_list) {
2495			opj_procedure_list_destroy(jp2->m_validation_list);
2496			jp2->m_validation_list = 00;
2497		}
2498
2499		if (jp2->m_procedure_list) {
2500			opj_procedure_list_destroy(jp2->m_procedure_list);
2501			jp2->m_procedure_list = 00;
2502		}
2503
2504		opj_free(jp2);
2505	}
2506}
2507
2508OPJ_BOOL opj_jp2_set_decode_area(	opj_jp2_t *p_jp2,
2509								    opj_image_t* p_image,
2510								    OPJ_INT32 p_start_x, OPJ_INT32 p_start_y,
2511								    OPJ_INT32 p_end_x, OPJ_INT32 p_end_y,
2512								    opj_event_mgr_t * p_manager
2513                                    )
2514{
2515	return opj_j2k_set_decode_area(p_jp2->j2k, p_image, p_start_x, p_start_y, p_end_x, p_end_y, p_manager);
2516}
2517
2518OPJ_BOOL opj_jp2_get_tile(	opj_jp2_t *p_jp2,
2519                            opj_stream_private_t *p_stream,
2520                            opj_image_t* p_image,
2521                            opj_event_mgr_t * p_manager,
2522                            OPJ_UINT32 tile_index
2523                            )
2524{
2525	if (!p_image)
2526		return OPJ_FALSE;
2527
2528	opj_event_msg(p_manager, EVT_WARNING, "JP2 box which are after the codestream will not be read by this function.\n");
2529
2530	if (! opj_j2k_get_tile(p_jp2->j2k, p_stream, p_image, p_manager, tile_index) ){
2531		opj_event_msg(p_manager, EVT_ERROR, "Failed to decode the codestream in the JP2 file\n");
2532		return OPJ_FALSE;
2533	}
2534
2535	if (!opj_jp2_check_color(p_image, &(p_jp2->color), p_manager)) {
2536		return OPJ_FALSE;
2537	}
2538
2539	/* Set Image Color Space */
2540	if (p_jp2->enumcs == 16)
2541		p_image->color_space = OPJ_CLRSPC_SRGB;
2542	else if (p_jp2->enumcs == 17)
2543		p_image->color_space = OPJ_CLRSPC_GRAY;
2544	else if (p_jp2->enumcs == 18)
2545		p_image->color_space = OPJ_CLRSPC_SYCC;
2546	else
2547		p_image->color_space = OPJ_CLRSPC_UNKNOWN;
2548
2549	/* Apply the color space if needed */
2550	if(p_jp2->color.jp2_cdef) {
2551		opj_jp2_apply_cdef(p_image, &(p_jp2->color));
2552	}
2553
2554	if(p_jp2->color.jp2_pclr) {
2555		/* Part 1, I.5.3.4: Either both or none : */
2556		if( !p_jp2->color.jp2_pclr->cmap)
2557			opj_jp2_free_pclr(&(p_jp2->color));
2558		else
2559			opj_jp2_apply_pclr(p_image, &(p_jp2->color));
2560	}
2561
2562	if(p_jp2->color.icc_profile_buf) {
2563		p_image->icc_profile_buf = p_jp2->color.icc_profile_buf;
2564		p_image->icc_profile_len = p_jp2->color.icc_profile_len;
2565		p_jp2->color.icc_profile_buf = NULL;
2566	}
2567
2568	return OPJ_TRUE;
2569}
2570
2571/* ----------------------------------------------------------------------- */
2572/* JP2 encoder interface                                             */
2573/* ----------------------------------------------------------------------- */
2574
2575opj_jp2_t* opj_jp2_create(OPJ_BOOL p_is_decoder)
2576{
2577	opj_jp2_t *jp2 = (opj_jp2_t*)opj_malloc(sizeof(opj_jp2_t));
2578	if (jp2) {
2579		memset(jp2,0,sizeof(opj_jp2_t));
2580
2581		/* create the J2K codec */
2582		if (! p_is_decoder) {
2583			jp2->j2k = opj_j2k_create_compress();
2584		}
2585		else {
2586			jp2->j2k = opj_j2k_create_decompress();
2587		}
2588
2589		if (jp2->j2k == 00) {
2590			opj_jp2_destroy(jp2);
2591			return 00;
2592		}
2593
2594		/* Color structure */
2595		jp2->color.icc_profile_buf = NULL;
2596		jp2->color.icc_profile_len = 0;
2597		jp2->color.jp2_cdef = NULL;
2598		jp2->color.jp2_pclr = NULL;
2599		jp2->color.jp2_has_colr = 0;
2600
2601		/* validation list creation */
2602		jp2->m_validation_list = opj_procedure_list_create();
2603		if (! jp2->m_validation_list) {
2604			opj_jp2_destroy(jp2);
2605			return 00;
2606		}
2607
2608		/* execution list creation */
2609		jp2->m_procedure_list = opj_procedure_list_create();
2610		if (! jp2->m_procedure_list) {
2611			opj_jp2_destroy(jp2);
2612			return 00;
2613		}
2614	}
2615
2616	return jp2;
2617}
2618
2619void jp2_dump(opj_jp2_t* p_jp2, OPJ_INT32 flag, FILE* out_stream)
2620{
2621	/* preconditions */
2622	assert(p_jp2 != 00);
2623
2624	j2k_dump(p_jp2->j2k,
2625					flag,
2626					out_stream);
2627}
2628
2629opj_codestream_index_t* jp2_get_cstr_index(opj_jp2_t* p_jp2)
2630{
2631	return j2k_get_cstr_index(p_jp2->j2k);
2632}
2633
2634opj_codestream_info_v2_t* jp2_get_cstr_info(opj_jp2_t* p_jp2)
2635{
2636	return j2k_get_cstr_info(p_jp2->j2k);
2637}
2638
2639OPJ_BOOL opj_jp2_set_decoded_resolution_factor(opj_jp2_t *p_jp2,
2640                                               OPJ_UINT32 res_factor,
2641                                               opj_event_mgr_t * p_manager)
2642{
2643	return opj_j2k_set_decoded_resolution_factor(p_jp2->j2k, res_factor, p_manager);
2644}
2645
2646/* JPIP specific */
2647
2648#ifdef USE_JPIP
2649static OPJ_BOOL opj_jpip_write_iptr(opj_jp2_t *jp2,
2650  opj_stream_private_t *cio,
2651  opj_event_mgr_t * p_manager )
2652{
2653  OPJ_OFF_T j2k_codestream_exit;
2654  OPJ_BYTE l_data_header [24];
2655
2656  /* preconditions */
2657  assert(jp2 != 00);
2658  assert(cio != 00);
2659  assert(p_manager != 00);
2660  assert(opj_stream_has_seek(cio));
2661
2662  j2k_codestream_exit = opj_stream_tell(cio);
2663  opj_write_bytes(l_data_header, 24, 4); /* size of iptr */
2664  opj_write_bytes(l_data_header + 4,JPIP_IPTR,4);									   /* IPTR */
2665#if 0
2666  opj_write_bytes(l_data_header + 4 + 4, 0, 8); /* offset */
2667  opj_write_bytes(l_data_header + 8 + 8, 0, 8); /* length */
2668#else
2669  opj_write_double(l_data_header + 4 + 4, 0); /* offset */
2670  opj_write_double(l_data_header + 8 + 8, 0); /* length */
2671#endif
2672
2673  if (! opj_stream_seek(cio,jp2->jpip_iptr_offset,p_manager)) {
2674    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
2675    return OPJ_FALSE;
2676  }
2677
2678  if (opj_stream_write_data(cio,l_data_header,24,p_manager) != 24) {
2679    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
2680    return OPJ_FALSE;
2681  }
2682
2683  if (! opj_stream_seek(cio,j2k_codestream_exit,p_manager)) {
2684    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
2685    return OPJ_FALSE;
2686  }
2687
2688  return OPJ_TRUE;
2689}
2690
2691static OPJ_BOOL opj_jpip_write_fidx(opj_jp2_t *jp2,
2692  opj_stream_private_t *cio,
2693  opj_event_mgr_t * p_manager )
2694{
2695  OPJ_OFF_T j2k_codestream_exit;
2696  OPJ_BYTE l_data_header [24];
2697
2698  /* preconditions */
2699  assert(jp2 != 00);
2700  assert(cio != 00);
2701  assert(p_manager != 00);
2702  assert(opj_stream_has_seek(cio));
2703
2704  opj_write_bytes(l_data_header, 24, 4); /* size of iptr */
2705  opj_write_bytes(l_data_header + 4,JPIP_FIDX,4);									   /* IPTR */
2706  opj_write_double(l_data_header + 4 + 4, 0); /* offset */
2707  opj_write_double(l_data_header + 8 + 8, 0); /* length */
2708
2709  if (opj_stream_write_data(cio,l_data_header,24,p_manager) != 24) {
2710    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
2711    return OPJ_FALSE;
2712  }
2713
2714  j2k_codestream_exit = opj_stream_tell(cio);
2715  if (! opj_stream_seek(cio,j2k_codestream_exit,p_manager)) {
2716    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
2717    return OPJ_FALSE;
2718  }
2719
2720  return OPJ_TRUE;
2721}
2722
2723static OPJ_BOOL opj_jpip_write_cidx(opj_jp2_t *jp2,
2724  opj_stream_private_t *cio,
2725  opj_event_mgr_t * p_manager )
2726{
2727  OPJ_OFF_T j2k_codestream_exit;
2728  OPJ_BYTE l_data_header [24];
2729
2730  /* preconditions */
2731  assert(jp2 != 00);
2732  assert(cio != 00);
2733  assert(p_manager != 00);
2734  assert(opj_stream_has_seek(cio));
2735
2736  j2k_codestream_exit = opj_stream_tell(cio);
2737  opj_write_bytes(l_data_header, 24, 4); /* size of iptr */
2738  opj_write_bytes(l_data_header + 4,JPIP_CIDX,4);									   /* IPTR */
2739#if 0
2740  opj_write_bytes(l_data_header + 4 + 4, 0, 8); /* offset */
2741  opj_write_bytes(l_data_header + 8 + 8, 0, 8); /* length */
2742#else
2743  opj_write_double(l_data_header + 4 + 4, 0); /* offset */
2744  opj_write_double(l_data_header + 8 + 8, 0); /* length */
2745#endif
2746
2747  if (! opj_stream_seek(cio,j2k_codestream_exit,p_manager)) {
2748    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
2749    return OPJ_FALSE;
2750  }
2751
2752  if (opj_stream_write_data(cio,l_data_header,24,p_manager) != 24) {
2753    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
2754    return OPJ_FALSE;
2755  }
2756
2757  j2k_codestream_exit = opj_stream_tell(cio);
2758  if (! opj_stream_seek(cio,j2k_codestream_exit,p_manager)) {
2759    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
2760    return OPJ_FALSE;
2761  }
2762
2763  return OPJ_TRUE;
2764}
2765
2766#if 0
2767static void write_prxy( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_stream_private_t *cio,
2768  opj_event_mgr_t * p_manager )
2769{
2770  OPJ_BYTE l_data_header [8];
2771  OPJ_OFF_T len, lenp;
2772
2773  lenp = opj_stream_tell(cio);
2774  opj_stream_skip(cio, 4, p_manager);         /* L [at the end] */
2775  opj_write_bytes(l_data_header,JPIP_PRXY,4); /* IPTR           */
2776  opj_stream_write_data(cio,l_data_header,4,p_manager);
2777
2778  opj_write_bytes( l_data_header, offset_jp2c, 8); /* OOFF           */
2779  opj_stream_write_data(cio,l_data_header,8,p_manager);
2780  opj_write_bytes( l_data_header, length_jp2c, 4); /* OBH part 1     */
2781  opj_write_bytes( l_data_header+4, JP2_JP2C, 4);  /* OBH part 2     */
2782  opj_stream_write_data(cio,l_data_header,8,p_manager);
2783
2784  opj_write_bytes( l_data_header, 1, 1);/* NI             */
2785  opj_stream_write_data(cio,l_data_header,1,p_manager);
2786
2787  opj_write_bytes( l_data_header, offset_idx, 8);  /* IOFF           */
2788  opj_stream_write_data(cio,l_data_header,8,p_manager);
2789  opj_write_bytes( l_data_header, length_idx, 4);  /* IBH part 1     */
2790  opj_write_bytes( l_data_header+4, JPIP_CIDX, 4);   /* IBH part 2     */
2791  opj_stream_write_data(cio,l_data_header,8,p_manager);
2792
2793  len = opj_stream_tell(cio)-lenp;
2794  opj_stream_skip(cio, lenp, p_manager);
2795  opj_write_bytes(l_data_header,len,4);/* L              */
2796  opj_stream_write_data(cio,l_data_header,4,p_manager);
2797  opj_stream_seek(cio, lenp+len,p_manager);
2798}
2799#endif
2800
2801
2802#if 0
2803static int write_fidx( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_stream_private_t *cio,
2804  opj_event_mgr_t * p_manager )
2805{
2806  OPJ_BYTE l_data_header [4];
2807  OPJ_OFF_T len, lenp;
2808
2809  lenp = opj_stream_tell(cio);
2810  opj_stream_skip(cio, 4, p_manager);
2811  opj_write_bytes(l_data_header,JPIP_FIDX,4); /* FIDX */
2812  opj_stream_write_data(cio,l_data_header,4,p_manager);
2813
2814  write_prxy( offset_jp2c, length_jp2c, offset_idx, length_idx, cio,p_manager);
2815
2816  len = opj_stream_tell(cio)-lenp;
2817  opj_stream_skip(cio, lenp, p_manager);
2818  opj_write_bytes(l_data_header,len,4);/* L              */
2819  opj_stream_write_data(cio,l_data_header,4,p_manager);
2820  opj_stream_seek(cio, lenp+len,p_manager);
2821
2822  return len;
2823}
2824#endif
2825#endif /* USE_JPIP */
2826