PageRenderTime 110ms CodeModel.GetById 22ms app.highlight 80ms RepoModel.GetById 1ms app.codeStats 1ms

/src/FreeImage/Source/LibOpenJPEG/jp2.c

https://bitbucket.org/cabalistic/ogredeps/
C | 1210 lines | 811 code | 218 blank | 181 comment | 165 complexity | f2709592cd610c26b6f5915451bbee6e MD5 | raw file
   1/*
   2 * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
   3 * Copyright (c) 2002-2007, Professor Benoit Macq
   4 * Copyright (c) 2001-2003, David Janssens
   5 * Copyright (c) 2002-2003, Yannick Verschueren
   6 * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
   7 * Copyright (c) 2005, Herve Drolon, FreeImage Team
   8 * Copyright (c) 2010-2011, Kaori Hagihara
   9 * All rights reserved.
  10 *
  11 * Redistribution and use in source and binary forms, with or without
  12 * modification, are permitted provided that the following conditions
  13 * are met:
  14 * 1. Redistributions of source code must retain the above copyright
  15 *    notice, this list of conditions and the following disclaimer.
  16 * 2. Redistributions in binary form must reproduce the above copyright
  17 *    notice, this list of conditions and the following disclaimer in the
  18 *    documentation and/or other materials provided with the distribution.
  19 *
  20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
  21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  30 * POSSIBILITY OF SUCH DAMAGE.
  31 */
  32#include "opj_includes.h"
  33
  34/** @defgroup JP2 JP2 - JPEG-2000 file format reader/writer */
  35/*@{*/
  36
  37/** @name Local static functions */
  38/*@{*/
  39
  40/**
  41Read box headers
  42@param cinfo Codec context info
  43@param cio Input stream
  44@param box
  45@return Returns true if successful, returns false otherwise
  46*/
  47static opj_bool jp2_read_boxhdr(opj_common_ptr cinfo, opj_cio_t *cio, opj_jp2_box_t *box);
  48/*static void jp2_write_url(opj_cio_t *cio, char *Idx_file);*/
  49/**
  50Read the IHDR box - Image Header box
  51@param jp2 JP2 handle
  52@param cio Input buffer stream
  53@return Returns true if successful, returns false otherwise
  54*/
  55static opj_bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio);
  56static void jp2_write_ihdr(opj_jp2_t *jp2, opj_cio_t *cio);
  57static void jp2_write_bpcc(opj_jp2_t *jp2, opj_cio_t *cio);
  58static opj_bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio);
  59static void jp2_write_colr(opj_jp2_t *jp2, opj_cio_t *cio);
  60/**
  61Write the FTYP box - File type box
  62@param jp2 JP2 handle
  63@param cio Output buffer stream
  64*/
  65static void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio);
  66/**
  67Read the FTYP box - File type box
  68@param jp2 JP2 handle
  69@param cio Input buffer stream
  70@return Returns true if successful, returns false otherwise
  71*/
  72static opj_bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio);
  73static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
  74static opj_bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset);
  75static void jp2_write_jp(opj_cio_t *cio);
  76/**
  77Read the JP box - JPEG 2000 signature
  78@param jp2 JP2 handle
  79@param cio Input buffer stream
  80@return Returns true if successful, returns false otherwise
  81*/
  82static opj_bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio);
  83/**
  84Decode the structure of a JP2 file
  85@param jp2 JP2 handle
  86@param cio Input buffer stream
  87@param color Collector for profile, cdef and pclr data
  88@return Returns true if successful, returns false otherwise
  89*/
  90static opj_bool jp2_read_struct(opj_jp2_t *jp2, opj_cio_t *cio,
  91	opj_jp2_color_t *color);
  92/**
  93Apply collected palette data
  94@param color Collector for profile, cdef and pclr data
  95@param image 
  96*/
  97static void jp2_apply_pclr(opj_jp2_color_t *color, opj_image_t *image, opj_common_ptr cinfo);
  98/**
  99Collect palette data
 100@param jp2 JP2 handle
 101@param cio Input buffer stream
 102@param box
 103@param color Collector for profile, cdef and pclr data
 104@return Returns true if successful, returns false otherwise
 105*/
 106static opj_bool jp2_read_pclr(opj_jp2_t *jp2, opj_cio_t *cio,
 107    opj_jp2_box_t *box, opj_jp2_color_t *color);
 108/**
 109Collect component mapping data
 110@param jp2 JP2 handle
 111@param cio Input buffer stream
 112@param box
 113@param color Collector for profile, cdef and pclr data
 114@return Returns true if successful, returns false otherwise
 115*/
 116static opj_bool jp2_read_cmap(opj_jp2_t *jp2, opj_cio_t *cio,
 117    opj_jp2_box_t *box, opj_jp2_color_t *color);
 118/**
 119Collect colour specification data
 120@param jp2 JP2 handle
 121@param cio Input buffer stream
 122@param box
 123@param color Collector for profile, cdef and pclr data
 124@return Returns true if successful, returns false otherwise
 125*/
 126static opj_bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio,
 127    opj_jp2_box_t *box, opj_jp2_color_t *color);
 128/**
 129Write file Index (superbox)
 130@param[in] offset_jp2c offset of jp2c box
 131@param[in] length_jp2c length of jp2c box
 132@param[in] offset_idx  offset of cidx box
 133@param[in] length_idx  length of cidx box
 134@param[in] cio         file output handle
 135@return                length of fidx box
 136*/
 137static int write_fidx( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_cio_t *cio);
 138/**
 139Write index Finder box
 140@param[in] offset offset of fidx box
 141@param[in] length length of fidx box
 142@param[in] cio         file output handle
 143*/
 144static void write_iptr( int offset, int length, opj_cio_t *cio);
 145/**
 146Write proxy box
 147@param[in] offset_jp2c offset of jp2c box
 148@param[in] length_jp2c length of jp2c box
 149@param[in] offset_idx  offset of cidx box
 150@param[in] length_idx  length of cidx box
 151@param[in] cio         file output handle
 152*/
 153static void write_prxy( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_cio_t *cio);
 154/*@}*/
 155
 156/*@}*/
 157
 158/* ----------------------------------------------------------------------- */
 159
 160static opj_bool jp2_read_boxhdr(opj_common_ptr cinfo, opj_cio_t *cio, opj_jp2_box_t *box) {
 161	box->init_pos = cio_tell(cio);
 162	box->length = cio_read(cio, 4);
 163	box->type = cio_read(cio, 4);
 164	if (box->length == 1) {
 165		if (cio_read(cio, 4) != 0) {
 166			opj_event_msg(cinfo, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n");
 167			return OPJ_FALSE;
 168		}
 169		box->length = cio_read(cio, 4);
 170		if (box->length == 0) 
 171			box->length = cio_numbytesleft(cio) + 12;
 172	}
 173	else if (box->length == 0) {
 174		box->length = cio_numbytesleft(cio) + 8;
 175	}
 176	
 177	return OPJ_TRUE;
 178}
 179
 180#if 0
 181static void jp2_write_url(opj_cio_t *cio, char *Idx_file) {
 182	unsigned int i;
 183	opj_jp2_box_t box;
 184
 185	box.init_pos = cio_tell(cio);
 186	cio_skip(cio, 4);
 187	cio_write(cio, JP2_URL, 4);	/* DBTL */
 188	cio_write(cio, 0, 1);		/* VERS */
 189	cio_write(cio, 0, 3);		/* FLAG */
 190
 191	if(Idx_file) {
 192		for (i = 0; i < strlen(Idx_file); i++) {
 193			cio_write(cio, Idx_file[i], 1);
 194		}
 195	}
 196
 197	box.length = cio_tell(cio) - box.init_pos;
 198	cio_seek(cio, box.init_pos);
 199	cio_write(cio, box.length, 4);	/* L */
 200	cio_seek(cio, box.init_pos + box.length);
 201}
 202#endif
 203
 204static opj_bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) {
 205	opj_jp2_box_t box;
 206
 207	opj_common_ptr cinfo = jp2->cinfo;
 208
 209	jp2_read_boxhdr(cinfo, cio, &box);
 210	if (JP2_IHDR != box.type) {
 211		opj_event_msg(cinfo, EVT_ERROR, "Expected IHDR Marker\n");
 212		return OPJ_FALSE;
 213	}
 214
 215	jp2->h = cio_read(cio, 4);			/* HEIGHT */
 216	jp2->w = cio_read(cio, 4);			/* WIDTH */
 217	jp2->numcomps = cio_read(cio, 2);	/* NC */
 218	jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t));
 219
 220	jp2->bpc = cio_read(cio, 1);		/* BPC */
 221
 222	jp2->C = cio_read(cio, 1);			/* C */
 223	jp2->UnkC = cio_read(cio, 1);		/* UnkC */
 224	jp2->IPR = cio_read(cio, 1);		/* IPR */
 225
 226	if (cio_tell(cio) - box.init_pos != box.length) {
 227		opj_event_msg(cinfo, EVT_ERROR, "Error with IHDR Box\n");
 228		return OPJ_FALSE;
 229	}
 230
 231	return OPJ_TRUE;
 232}
 233
 234static void jp2_write_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) {
 235	opj_jp2_box_t box;
 236
 237	box.init_pos = cio_tell(cio);
 238	cio_skip(cio, 4);
 239	cio_write(cio, JP2_IHDR, 4);		/* IHDR */
 240
 241	cio_write(cio, jp2->h, 4);			/* HEIGHT */
 242	cio_write(cio, jp2->w, 4);			/* WIDTH */
 243	cio_write(cio, jp2->numcomps, 2);	/* NC */
 244
 245	cio_write(cio, jp2->bpc, 1);		/* BPC */
 246
 247	cio_write(cio, jp2->C, 1);			/* C : Always 7 */
 248	cio_write(cio, jp2->UnkC, 1);		/* UnkC, colorspace unknown */
 249	cio_write(cio, jp2->IPR, 1);		/* IPR, no intellectual property */
 250
 251	box.length = cio_tell(cio) - box.init_pos;
 252	cio_seek(cio, box.init_pos);
 253	cio_write(cio, box.length, 4);	/* L */
 254	cio_seek(cio, box.init_pos + box.length);
 255}
 256
 257static void jp2_write_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) {
 258	unsigned int i;
 259	opj_jp2_box_t box;
 260
 261	box.init_pos = cio_tell(cio);
 262	cio_skip(cio, 4);
 263	cio_write(cio, JP2_BPCC, 4);	/* BPCC */
 264
 265	for (i = 0; i < jp2->numcomps; i++) {
 266		cio_write(cio, jp2->comps[i].bpcc, 1);
 267	}
 268
 269	box.length = cio_tell(cio) - box.init_pos;
 270	cio_seek(cio, box.init_pos);
 271	cio_write(cio, box.length, 4);	/* L */
 272	cio_seek(cio, box.init_pos + box.length);
 273}
 274
 275
 276static opj_bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) {
 277	unsigned int i;
 278	opj_jp2_box_t box;
 279
 280	opj_common_ptr cinfo = jp2->cinfo;
 281
 282	jp2_read_boxhdr(cinfo, cio, &box);
 283	if (JP2_BPCC != box.type) {
 284		opj_event_msg(cinfo, EVT_ERROR, "Expected BPCC Marker\n");
 285		return OPJ_FALSE;
 286	}
 287
 288	for (i = 0; i < jp2->numcomps; i++) {
 289		jp2->comps[i].bpcc = cio_read(cio, 1);
 290	}
 291
 292	if (cio_tell(cio) - box.init_pos != box.length) {
 293		opj_event_msg(cinfo, EVT_ERROR, "Error with BPCC Box\n");
 294		return OPJ_FALSE;
 295	}
 296
 297	return OPJ_TRUE;
 298}
 299
 300static void jp2_write_colr(opj_jp2_t *jp2, opj_cio_t *cio) {
 301	opj_jp2_box_t box;
 302
 303	box.init_pos = cio_tell(cio);
 304	cio_skip(cio, 4);
 305	cio_write(cio, JP2_COLR, 4);		/* COLR */
 306
 307	cio_write(cio, jp2->meth, 1);		/* METH */
 308	cio_write(cio, jp2->precedence, 1);	/* PRECEDENCE */
 309	cio_write(cio, jp2->approx, 1);		/* APPROX */
 310
 311	if(jp2->meth == 2)
 312	 jp2->enumcs = 0;
 313
 314	cio_write(cio, jp2->enumcs, 4);	/* EnumCS */
 315
 316	box.length = cio_tell(cio) - box.init_pos;
 317	cio_seek(cio, box.init_pos);
 318	cio_write(cio, box.length, 4);	/* L */
 319	cio_seek(cio, box.init_pos + box.length);
 320}
 321
 322static void jp2_free_pclr(opj_jp2_color_t *color)
 323{
 324    opj_free(color->jp2_pclr->channel_sign);
 325    opj_free(color->jp2_pclr->channel_size);
 326    opj_free(color->jp2_pclr->entries);
 327
 328	if(color->jp2_pclr->cmap) opj_free(color->jp2_pclr->cmap);
 329
 330    opj_free(color->jp2_pclr); color->jp2_pclr = NULL;
 331}
 332
 333static void free_color_data(opj_jp2_color_t *color)
 334{
 335	if(color->jp2_pclr)
 336   {
 337	jp2_free_pclr(color);
 338   }
 339	if(color->jp2_cdef) 
 340   {
 341	if(color->jp2_cdef->info) opj_free(color->jp2_cdef->info);
 342	opj_free(color->jp2_cdef);
 343   }
 344	if(color->icc_profile_buf) opj_free(color->icc_profile_buf);
 345}
 346
 347static void jp2_apply_pclr(opj_jp2_color_t *color, opj_image_t *image, opj_common_ptr cinfo)
 348{
 349	opj_image_comp_t *old_comps, *new_comps;
 350	unsigned char *channel_size, *channel_sign;
 351	unsigned int *entries;
 352	opj_jp2_cmap_comp_t *cmap;
 353	int *src, *dst;
 354	unsigned int j, max;
 355	unsigned short i, nr_channels, cmp, pcol;
 356	int k, top_k;
 357
 358	channel_size = color->jp2_pclr->channel_size;
 359	channel_sign = color->jp2_pclr->channel_sign;
 360	entries = color->jp2_pclr->entries;
 361	cmap = color->jp2_pclr->cmap;
 362	nr_channels = color->jp2_pclr->nr_channels;
 363
 364	old_comps = image->comps;
 365	new_comps = (opj_image_comp_t*)
 366	 opj_malloc(nr_channels * sizeof(opj_image_comp_t));
 367
 368	for(i = 0; i < nr_channels; ++i)
 369   {
 370	pcol = cmap[i].pcol; cmp = cmap[i].cmp;
 371
 372  if( pcol < nr_channels )
 373    new_comps[pcol] = old_comps[cmp];
 374  else
 375    {
 376    opj_event_msg(cinfo, EVT_ERROR, "Error with pcol value %d (max: %d). skipping\n", pcol, nr_channels);
 377    continue;
 378    }
 379
 380	if(cmap[i].mtyp == 0) /* Direct use */
 381  {
 382	old_comps[cmp].data = NULL; continue;
 383  }
 384/* Palette mapping: */
 385	new_comps[pcol].data = (int*)
 386	 opj_malloc(old_comps[cmp].w * old_comps[cmp].h * sizeof(int));
 387	new_comps[pcol].prec = channel_size[i];
 388	new_comps[pcol].sgnd = channel_sign[i];
 389   }
 390	top_k = color->jp2_pclr->nr_entries - 1;
 391
 392	for(i = 0; i < nr_channels; ++i)
 393   {
 394/* Direct use: */
 395	if(cmap[i].mtyp == 0) continue;
 396
 397/* Palette mapping: */
 398	cmp = cmap[i].cmp; pcol = cmap[i].pcol;
 399	src = old_comps[cmp].data; 
 400	dst = new_comps[pcol].data;
 401	max = new_comps[pcol].w * new_comps[pcol].h;
 402
 403	for(j = 0; j < max; ++j)
 404  {
 405/* The index */
 406	if((k = src[j]) < 0) k = 0; else if(k > top_k) k = top_k;
 407/* The colour */
 408	dst[j] = entries[k * nr_channels + pcol];
 409  }
 410   }
 411	max = image->numcomps;
 412	for(i = 0; i < max; ++i)
 413   {
 414	if(old_comps[i].data) opj_free(old_comps[i].data);
 415   }
 416	opj_free(old_comps);
 417	image->comps = new_comps;
 418	image->numcomps = nr_channels;
 419
 420	jp2_free_pclr(color);
 421
 422}/* apply_pclr() */
 423
 424static opj_bool jp2_read_pclr(opj_jp2_t *jp2, opj_cio_t *cio,
 425	opj_jp2_box_t *box, opj_jp2_color_t *color)
 426{
 427	opj_jp2_pclr_t *jp2_pclr;
 428	unsigned char *channel_size, *channel_sign;
 429	unsigned int *entries;
 430	unsigned short nr_entries, nr_channels;
 431	unsigned short i, j;
 432	unsigned char uc;
 433
 434	OPJ_ARG_NOT_USED(box);
 435	OPJ_ARG_NOT_USED(jp2);
 436
 437/* Part 1, I.5.3.4: 'There shall be at most one Palette box inside
 438 * a JP2 Header box' :
 439*/
 440	if(color->jp2_pclr) return OPJ_FALSE;
 441
 442	nr_entries = (unsigned short)cio_read(cio, 2); /* NE */
 443	nr_channels = (unsigned short)cio_read(cio, 1);/* NPC */
 444
 445	entries = (unsigned int*)
 446	 opj_malloc(nr_channels * nr_entries * sizeof(unsigned int));
 447	channel_size = (unsigned char*)opj_malloc(nr_channels);
 448	channel_sign = (unsigned char*)opj_malloc(nr_channels);
 449
 450	jp2_pclr = (opj_jp2_pclr_t*)opj_malloc(sizeof(opj_jp2_pclr_t));
 451	jp2_pclr->channel_sign = channel_sign;
 452	jp2_pclr->channel_size = channel_size;
 453	jp2_pclr->entries = entries;
 454	jp2_pclr->nr_entries = nr_entries;
 455	jp2_pclr->nr_channels = nr_channels;
 456	jp2_pclr->cmap = NULL;
 457
 458	color->jp2_pclr = jp2_pclr;
 459
 460	for(i = 0; i < nr_channels; ++i)
 461   {
 462	uc = cio_read(cio, 1); /* Bi */
 463	channel_size[i] = (uc & 0x7f) + 1;
 464	channel_sign[i] = (uc & 0x80)?1:0;
 465   }
 466
 467	for(j = 0; j < nr_entries; ++j)
 468   {
 469	for(i = 0; i < nr_channels; ++i)
 470  {
 471/* Cji */
 472	*entries++ = cio_read(cio, channel_size[i]>>3);
 473  }
 474   }
 475
 476	return OPJ_TRUE;
 477}/* jp2_read_pclr() */
 478
 479static opj_bool jp2_read_cmap(opj_jp2_t *jp2, opj_cio_t *cio,
 480	opj_jp2_box_t *box, opj_jp2_color_t *color)
 481{
 482	opj_jp2_cmap_comp_t *cmap;
 483	unsigned short i, nr_channels;
 484
 485	OPJ_ARG_NOT_USED(box);
 486	OPJ_ARG_NOT_USED(jp2);
 487
 488/* Need nr_channels: */
 489	if(color->jp2_pclr == NULL) return OPJ_FALSE;
 490
 491/* Part 1, I.5.3.5: 'There shall be at most one Component Mapping box
 492 * inside a JP2 Header box' :
 493*/
 494	if(color->jp2_pclr->cmap) return OPJ_FALSE;
 495
 496	nr_channels = color->jp2_pclr->nr_channels;
 497	cmap = (opj_jp2_cmap_comp_t*)
 498	 opj_malloc(nr_channels * sizeof(opj_jp2_cmap_comp_t));
 499
 500	for(i = 0; i < nr_channels; ++i)
 501   {
 502	cmap[i].cmp = (unsigned short)cio_read(cio, 2);
 503	cmap[i].mtyp = cio_read(cio, 1);
 504	cmap[i].pcol = cio_read(cio, 1);
 505
 506   }
 507	color->jp2_pclr->cmap = cmap;
 508
 509	return OPJ_TRUE;
 510}/* jp2_read_cmap() */
 511
 512static void jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color)
 513{
 514	opj_jp2_cdef_info_t *info;
 515	int color_space;
 516	unsigned short i, n, cn, typ, asoc, acn;
 517
 518	color_space = image->color_space;
 519	info = color->jp2_cdef->info;
 520	n = color->jp2_cdef->n;
 521
 522	for(i = 0; i < n; ++i)
 523   {
 524/* WATCH: acn = asoc - 1 ! */
 525	if((asoc = info[i].asoc) == 0) continue;
 526
 527	cn = info[i].cn; typ = info[i].typ; acn = asoc - 1;
 528
 529	if(cn != acn)
 530  {
 531	opj_image_comp_t saved;
 532
 533	memcpy(&saved, &image->comps[cn], sizeof(opj_image_comp_t));
 534	memcpy(&image->comps[cn], &image->comps[acn], sizeof(opj_image_comp_t));
 535	memcpy(&image->comps[acn], &saved, sizeof(opj_image_comp_t));
 536
 537	info[i].asoc = cn + 1;
 538	info[acn].asoc = info[acn].cn + 1;
 539  }
 540   }
 541	if(color->jp2_cdef->info) opj_free(color->jp2_cdef->info);
 542
 543	opj_free(color->jp2_cdef); color->jp2_cdef = NULL;
 544
 545}/* jp2_apply_cdef() */
 546
 547static opj_bool jp2_read_cdef(opj_jp2_t *jp2, opj_cio_t *cio,
 548	opj_jp2_box_t *box, opj_jp2_color_t *color)
 549{
 550	opj_jp2_cdef_info_t *info;
 551	unsigned short i, n;
 552
 553	OPJ_ARG_NOT_USED(box);
 554	OPJ_ARG_NOT_USED(jp2);
 555
 556/* Part 1, I.5.3.6: 'The shall be at most one Channel Definition box
 557 * inside a JP2 Header box.' 
 558*/
 559	if(color->jp2_cdef) return OPJ_FALSE;
 560
 561	if((n = (unsigned short)cio_read(cio, 2)) == 0) return OPJ_FALSE; /* szukw000: FIXME */
 562
 563	info = (opj_jp2_cdef_info_t*)
 564	 opj_malloc(n * sizeof(opj_jp2_cdef_info_t));
 565
 566	color->jp2_cdef = (opj_jp2_cdef_t*)opj_malloc(sizeof(opj_jp2_cdef_t));
 567	color->jp2_cdef->info = info;
 568	color->jp2_cdef->n = n;
 569
 570	for(i = 0; i < n; ++i)
 571   {
 572	info[i].cn = (unsigned short)cio_read(cio, 2);
 573	info[i].typ = (unsigned short)cio_read(cio, 2);
 574	info[i].asoc = (unsigned short)cio_read(cio, 2);
 575
 576   }
 577	return OPJ_TRUE;
 578}/* jp2_read_cdef() */
 579
 580static opj_bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio,
 581	opj_jp2_box_t *box, opj_jp2_color_t *color) 
 582{
 583	int skip_len;
 584    opj_common_ptr cinfo;
 585
 586/* Part 1, I.5.3.3 : 'A conforming JP2 reader shall ignore all Colour
 587 * Specification boxes after the first.' 
 588*/
 589	if(color->jp2_has_colr) return OPJ_FALSE;
 590
 591	cinfo = jp2->cinfo;
 592
 593	jp2->meth = cio_read(cio, 1);		/* METH */
 594	jp2->precedence = cio_read(cio, 1);	/* PRECEDENCE */
 595	jp2->approx = cio_read(cio, 1);		/* APPROX */
 596
 597	if (jp2->meth == 1) 
 598   {
 599	jp2->enumcs = cio_read(cio, 4);	/* EnumCS */
 600   } 
 601	else
 602	if (jp2->meth == 2) 
 603   {
 604/* skip PROFILE */
 605	skip_len = box->init_pos + box->length - cio_tell(cio);
 606	if (skip_len < 0) 
 607  {
 608	opj_event_msg(cinfo, EVT_ERROR, "Error with COLR box size\n");
 609	return OPJ_FALSE;
 610  }
 611	if(skip_len > 0)
 612  {
 613	unsigned char *start;
 614
 615	start = cio_getbp(cio);
 616	color->icc_profile_buf = (unsigned char*)opj_malloc(skip_len);
 617	color->icc_profile_len = skip_len;
 618
 619	cio_skip(cio, box->init_pos + box->length - cio_tell(cio));
 620
 621	memcpy(color->icc_profile_buf, start, skip_len);
 622  }
 623   }
 624
 625	if (cio_tell(cio) - box->init_pos != box->length) 
 626   {
 627	opj_event_msg(cinfo, EVT_ERROR, "Error with COLR Box\n");
 628	return OPJ_FALSE;
 629   }
 630	color->jp2_has_colr = 1;
 631
 632	return OPJ_TRUE;
 633}/* jp2_read_colr() */
 634
 635opj_bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio, opj_jp2_color_t *color) 
 636{
 637	opj_jp2_box_t box;
 638	int jp2h_end;
 639
 640	opj_common_ptr cinfo = jp2->cinfo;
 641
 642	jp2_read_boxhdr(cinfo, cio, &box);
 643	do 
 644   {
 645	if (JP2_JP2H != box.type) 
 646  {
 647	if (box.type == JP2_JP2C) 
 648 {
 649	opj_event_msg(cinfo, EVT_ERROR, "Expected JP2H Marker\n");
 650	return OPJ_FALSE;
 651 }
 652	cio_skip(cio, box.length - 8);
 653
 654	if(cio->bp >= cio->end) return OPJ_FALSE;
 655
 656	jp2_read_boxhdr(cinfo, cio, &box);
 657  }
 658   } while(JP2_JP2H != box.type);
 659
 660	if (!jp2_read_ihdr(jp2, cio))
 661		return OPJ_FALSE;
 662	jp2h_end = box.init_pos + box.length;
 663
 664	if (jp2->bpc == 255) 
 665   {
 666	if (!jp2_read_bpcc(jp2, cio))
 667		return OPJ_FALSE;
 668   }
 669	jp2_read_boxhdr(cinfo, cio, &box);
 670
 671	while(cio_tell(cio) < jp2h_end)
 672   {
 673	if(box.type == JP2_COLR)
 674  {
 675	if( !jp2_read_colr(jp2, cio, &box, color))
 676 {
 677    cio_seek(cio, box.init_pos + 8);
 678    cio_skip(cio, box.length - 8);
 679 }
 680    jp2_read_boxhdr(cinfo, cio, &box);
 681    continue;
 682  }
 683    if(box.type == JP2_CDEF && !jp2->ignore_pclr_cmap_cdef)
 684  {
 685    if( !jp2_read_cdef(jp2, cio, &box, color))
 686 {
 687    cio_seek(cio, box.init_pos + 8);
 688    cio_skip(cio, box.length - 8);
 689 }
 690    jp2_read_boxhdr(cinfo, cio, &box);
 691    continue;
 692  }
 693    if(box.type == JP2_PCLR && !jp2->ignore_pclr_cmap_cdef)
 694  {
 695    if( !jp2_read_pclr(jp2, cio, &box, color))
 696 {
 697    cio_seek(cio, box.init_pos + 8);
 698    cio_skip(cio, box.length - 8);
 699 }
 700    jp2_read_boxhdr(cinfo, cio, &box);
 701    continue;
 702  }
 703    if(box.type == JP2_CMAP && !jp2->ignore_pclr_cmap_cdef)
 704  {
 705    if( !jp2_read_cmap(jp2, cio, &box, color))
 706 {
 707    cio_seek(cio, box.init_pos + 8);
 708    cio_skip(cio, box.length - 8);
 709 }
 710    jp2_read_boxhdr(cinfo, cio, &box);
 711    continue;
 712  }
 713	cio_seek(cio, box.init_pos + 8);
 714	cio_skip(cio, box.length - 8);
 715	jp2_read_boxhdr(cinfo, cio, &box);
 716
 717   }/* while(cio_tell(cio) < box_end) */
 718
 719	cio_seek(cio, jp2h_end);
 720
 721/* Part 1, I.5.3.3 : 'must contain at least one' */
 722	return (color->jp2_has_colr == 1);
 723
 724}/* jp2_read_jp2h() */
 725
 726opj_image_t* opj_jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, 
 727	opj_codestream_info_t *cstr_info) 
 728{
 729	opj_common_ptr cinfo;
 730	opj_image_t *image = NULL;
 731	opj_jp2_color_t color;
 732
 733	if(!jp2 || !cio) 
 734   {
 735	return NULL;
 736   }
 737	memset(&color, 0, sizeof(opj_jp2_color_t));
 738	cinfo = jp2->cinfo;
 739
 740/* JP2 decoding */
 741	if(!jp2_read_struct(jp2, cio, &color)) 
 742   {
 743	free_color_data(&color);
 744	opj_event_msg(cinfo, EVT_ERROR, "Failed to decode jp2 structure\n");
 745	return NULL;
 746   }
 747
 748/* J2K decoding */
 749	image = j2k_decode(jp2->j2k, cio, cstr_info);
 750
 751	if(!image) 
 752   {
 753	free_color_data(&color);
 754	opj_event_msg(cinfo, EVT_ERROR, "Failed to decode J2K image\n");
 755	return NULL;
 756   }
 757   
 758    if (!jp2->ignore_pclr_cmap_cdef){
 759
 760    /* Set Image Color Space */
 761	if (jp2->enumcs == 16)
 762		image->color_space = CLRSPC_SRGB;
 763	else if (jp2->enumcs == 17)
 764		image->color_space = CLRSPC_GRAY;
 765	else if (jp2->enumcs == 18)
 766		image->color_space = CLRSPC_SYCC;
 767	else
 768		image->color_space = CLRSPC_UNKNOWN;
 769
 770	if(color.jp2_cdef)
 771   {
 772	jp2_apply_cdef(image, &color);
 773   }
 774	if(color.jp2_pclr)
 775   {
 776/* Part 1, I.5.3.4: Either both or none : */
 777	if( !color.jp2_pclr->cmap) 
 778	 jp2_free_pclr(&color);
 779	else
 780	 jp2_apply_pclr(&color, image, cinfo);
 781   }
 782	if(color.icc_profile_buf)
 783   {
 784	image->icc_profile_buf = color.icc_profile_buf;
 785	color.icc_profile_buf = NULL;
 786	image->icc_profile_len = color.icc_profile_len;
 787   }
 788   }
 789   
 790	return image;
 791
 792}/* opj_jp2_decode() */
 793
 794
 795void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) {
 796	opj_jp2_box_t box;
 797
 798	box.init_pos = cio_tell(cio);
 799	cio_skip(cio, 4);
 800	cio_write(cio, JP2_JP2H, 4);	/* JP2H */
 801
 802	jp2_write_ihdr(jp2, cio);
 803
 804	if (jp2->bpc == 255) {
 805		jp2_write_bpcc(jp2, cio);
 806	}
 807	jp2_write_colr(jp2, cio);
 808
 809	box.length = cio_tell(cio) - box.init_pos;
 810	cio_seek(cio, box.init_pos);
 811	cio_write(cio, box.length, 4);	/* L */
 812	cio_seek(cio, box.init_pos + box.length);
 813}
 814
 815static void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) {
 816	unsigned int i;
 817	opj_jp2_box_t box;
 818
 819	box.init_pos = cio_tell(cio);
 820	cio_skip(cio, 4);
 821	cio_write(cio, JP2_FTYP, 4);		/* FTYP */
 822
 823	cio_write(cio, jp2->brand, 4);		/* BR */
 824	cio_write(cio, jp2->minversion, 4);	/* MinV */
 825
 826	for (i = 0; i < jp2->numcl; i++) {
 827		cio_write(cio, jp2->cl[i], 4);	/* CL */
 828	}
 829
 830	box.length = cio_tell(cio) - box.init_pos;
 831	cio_seek(cio, box.init_pos);
 832	cio_write(cio, box.length, 4);	/* L */
 833	cio_seek(cio, box.init_pos + box.length);
 834}
 835
 836static opj_bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) {
 837	int i;
 838	opj_jp2_box_t box;
 839
 840	opj_common_ptr cinfo = jp2->cinfo;
 841
 842	jp2_read_boxhdr(cinfo, cio, &box);
 843
 844	if (JP2_FTYP != box.type) {
 845		opj_event_msg(cinfo, EVT_ERROR, "Expected FTYP Marker\n");
 846		return OPJ_FALSE;
 847	}
 848
 849	jp2->brand = cio_read(cio, 4);		/* BR */
 850	jp2->minversion = cio_read(cio, 4);	/* MinV */
 851	jp2->numcl = (box.length - 16) / 4;
 852	jp2->cl = (unsigned int *) opj_malloc(jp2->numcl * sizeof(unsigned int));
 853
 854	for (i = 0; i < (int)jp2->numcl; i++) {
 855		jp2->cl[i] = cio_read(cio, 4);	/* CLi */
 856	}
 857
 858	if (cio_tell(cio) - box.init_pos != box.length) {
 859		opj_event_msg(cinfo, EVT_ERROR, "Error with FTYP Box\n");
 860		return OPJ_FALSE;
 861	}
 862
 863	return OPJ_TRUE;
 864}
 865
 866static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
 867	unsigned int j2k_codestream_offset, j2k_codestream_length;
 868	opj_jp2_box_t box;
 869
 870	opj_j2k_t *j2k = jp2->j2k;
 871
 872	box.init_pos = cio_tell(cio);
 873	cio_skip(cio, 4);
 874	cio_write(cio, JP2_JP2C, 4);	/* JP2C */
 875
 876	/* J2K encoding */
 877	j2k_codestream_offset = cio_tell(cio);
 878	if(!j2k_encode(j2k, cio, image, cstr_info)) {
 879		opj_event_msg(j2k->cinfo, EVT_ERROR, "Failed to encode image\n");
 880		return 0;
 881	}
 882	j2k_codestream_length = cio_tell(cio) - j2k_codestream_offset;
 883
 884	jp2->j2k_codestream_offset = j2k_codestream_offset;
 885	jp2->j2k_codestream_length = j2k_codestream_length;
 886
 887	box.length = 8 + jp2->j2k_codestream_length;
 888	cio_seek(cio, box.init_pos);
 889	cio_write(cio, box.length, 4);	/* L */
 890	cio_seek(cio, box.init_pos + box.length);
 891
 892	return box.length;
 893}
 894
 895static opj_bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset) {
 896	opj_jp2_box_t box;
 897
 898	opj_common_ptr cinfo = jp2->cinfo;
 899
 900	jp2_read_boxhdr(cinfo, cio, &box);
 901	do {
 902		if(JP2_JP2C != box.type) {
 903			cio_skip(cio, box.length - 8);
 904			jp2_read_boxhdr(cinfo, cio, &box);
 905		}
 906	} while(JP2_JP2C != box.type);
 907
 908	*j2k_codestream_offset = cio_tell(cio);
 909	*j2k_codestream_length = box.length - 8;
 910
 911	return OPJ_TRUE;
 912}
 913
 914static void jp2_write_jp(opj_cio_t *cio) {
 915	opj_jp2_box_t box;
 916
 917	box.init_pos = cio_tell(cio);
 918	cio_skip(cio, 4);
 919	cio_write(cio, JP2_JP, 4);		/* JP2 signature */
 920	cio_write(cio, 0x0d0a870a, 4);
 921
 922	box.length = cio_tell(cio) - box.init_pos;
 923	cio_seek(cio, box.init_pos);
 924	cio_write(cio, box.length, 4);	/* L */
 925	cio_seek(cio, box.init_pos + box.length);
 926}
 927
 928static opj_bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio) {
 929	opj_jp2_box_t box;
 930
 931	opj_common_ptr cinfo = jp2->cinfo;
 932
 933	jp2_read_boxhdr(cinfo, cio, &box);
 934	if (JP2_JP != box.type) {
 935		opj_event_msg(cinfo, EVT_ERROR, "Expected JP Marker\n");
 936		return OPJ_FALSE;
 937	}
 938	if (0x0d0a870a != cio_read(cio, 4)) {
 939		opj_event_msg(cinfo, EVT_ERROR, "Error with JP Marker\n");
 940		return OPJ_FALSE;
 941	}
 942	if (cio_tell(cio) - box.init_pos != box.length) {
 943		opj_event_msg(cinfo, EVT_ERROR, "Error with JP Box size\n");
 944		return OPJ_FALSE;
 945	}
 946
 947	return OPJ_TRUE;
 948}
 949
 950
 951static opj_bool jp2_read_struct(opj_jp2_t *jp2, opj_cio_t *cio,
 952	opj_jp2_color_t *color) {
 953	if (!jp2_read_jp(jp2, cio))
 954		return OPJ_FALSE;
 955	if (!jp2_read_ftyp(jp2, cio))
 956		return OPJ_FALSE;
 957	if (!jp2_read_jp2h(jp2, cio, color))
 958		return OPJ_FALSE;
 959	if (!jp2_read_jp2c(jp2, cio, &jp2->j2k_codestream_length, &jp2->j2k_codestream_offset))
 960		return OPJ_FALSE;
 961	
 962	return OPJ_TRUE;
 963}
 964
 965
 966static int write_fidx( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_cio_t *cio)
 967{  
 968  int len, lenp;
 969  
 970  lenp = cio_tell( cio);
 971  cio_skip( cio, 4);              /* L [at the end] */
 972  cio_write( cio, JPIP_FIDX, 4);  /* IPTR           */
 973  
 974  write_prxy( offset_jp2c, length_jp2c, offset_idx, length_idx, cio);
 975
 976  len = cio_tell( cio)-lenp;
 977  cio_seek( cio, lenp);
 978  cio_write( cio, len, 4);        /* L              */
 979  cio_seek( cio, lenp+len);  
 980
 981  return len;
 982}
 983
 984static void write_prxy( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_cio_t *cio)
 985{
 986  int len, lenp;
 987
 988  lenp = cio_tell( cio);
 989  cio_skip( cio, 4);              /* L [at the end] */
 990  cio_write( cio, JPIP_PRXY, 4);  /* IPTR           */
 991  
 992  cio_write( cio, offset_jp2c, 8); /* OOFF           */
 993  cio_write( cio, length_jp2c, 4); /* OBH part 1     */
 994  cio_write( cio, JP2_JP2C, 4);        /* OBH part 2     */
 995  
 996  cio_write( cio, 1,1);           /* NI             */
 997
 998  cio_write( cio, offset_idx, 8);  /* IOFF           */
 999  cio_write( cio, length_idx, 4);  /* IBH part 1     */
1000  cio_write( cio, JPIP_CIDX, 4);   /* IBH part 2     */
1001
1002  len = cio_tell( cio)-lenp;
1003  cio_seek( cio, lenp);
1004  cio_write( cio, len, 4);        /* L              */
1005  cio_seek( cio, lenp+len);
1006}
1007
1008static void write_iptr( int offset, int length, opj_cio_t *cio)
1009{
1010  int len, lenp;
1011  
1012  lenp = cio_tell( cio);
1013  cio_skip( cio, 4);              /* L [at the end] */
1014  cio_write( cio, JPIP_IPTR, 4);  /* IPTR           */
1015  
1016  cio_write( cio, offset, 8);
1017  cio_write( cio, length, 8);
1018
1019  len = cio_tell( cio)-lenp;
1020  cio_seek( cio, lenp);
1021  cio_write( cio, len, 4);        /* L             */
1022  cio_seek( cio, lenp+len);
1023}
1024
1025
1026/* ----------------------------------------------------------------------- */
1027/* JP2 decoder interface                                             */
1028/* ----------------------------------------------------------------------- */
1029
1030opj_jp2_t* jp2_create_decompress(opj_common_ptr cinfo) {
1031	opj_jp2_t *jp2 = (opj_jp2_t*) opj_calloc(1, sizeof(opj_jp2_t));
1032	if(jp2) {
1033		jp2->cinfo = cinfo;
1034		/* create the J2K codec */
1035		jp2->j2k = j2k_create_decompress(cinfo);
1036		if(jp2->j2k == NULL) {
1037			jp2_destroy_decompress(jp2);
1038			return NULL;
1039		}
1040	}
1041	return jp2;
1042}
1043
1044void jp2_destroy_decompress(opj_jp2_t *jp2) {
1045	if(jp2) {
1046		/* destroy the J2K codec */
1047		j2k_destroy_decompress(jp2->j2k);
1048
1049		if(jp2->comps) {
1050			opj_free(jp2->comps);
1051		}
1052		if(jp2->cl) {
1053			opj_free(jp2->cl);
1054		}
1055		opj_free(jp2);
1056	}
1057}
1058
1059void jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters) {
1060	/* setup the J2K codec */
1061	j2k_setup_decoder(jp2->j2k, parameters);
1062	/* further JP2 initializations go here */
1063	jp2->ignore_pclr_cmap_cdef = parameters->flags & OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
1064}
1065
1066/* ----------------------------------------------------------------------- */
1067/* JP2 encoder interface                                             */
1068/* ----------------------------------------------------------------------- */
1069
1070opj_jp2_t* jp2_create_compress(opj_common_ptr cinfo) {
1071	opj_jp2_t *jp2 = (opj_jp2_t*)opj_malloc(sizeof(opj_jp2_t));
1072	if(jp2) {
1073		jp2->cinfo = cinfo;
1074		/* create the J2K codec */
1075		jp2->j2k = j2k_create_compress(cinfo);
1076		if(jp2->j2k == NULL) {
1077			jp2_destroy_compress(jp2);
1078			return NULL;
1079		}
1080	}
1081	return jp2;
1082}
1083
1084void jp2_destroy_compress(opj_jp2_t *jp2) {
1085	if(jp2) {
1086		/* destroy the J2K codec */
1087		j2k_destroy_compress(jp2->j2k);
1088
1089		if(jp2->comps) {
1090			opj_free(jp2->comps);
1091		}
1092		if(jp2->cl) {
1093			opj_free(jp2->cl);
1094		}
1095		opj_free(jp2);
1096	}
1097}
1098
1099void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_t *image) {
1100	int i;
1101	int depth_0, sign;
1102
1103	if(!jp2 || !parameters || !image)
1104		return;
1105
1106	/* setup the J2K codec */
1107	/* ------------------- */
1108
1109	/* Check if number of components respects standard */
1110	if (image->numcomps < 1 || image->numcomps > 16384) {
1111		opj_event_msg(jp2->cinfo, EVT_ERROR, "Invalid number of components specified while setting up JP2 encoder\n");
1112		return;
1113	}
1114
1115	j2k_setup_encoder(jp2->j2k, parameters, image);
1116
1117	/* setup the JP2 codec */
1118	/* ------------------- */
1119	
1120	/* Profile box */
1121
1122	jp2->brand = JP2_JP2;	/* BR */
1123	jp2->minversion = 0;	/* MinV */
1124	jp2->numcl = 1;
1125	jp2->cl = (unsigned int*) opj_malloc(jp2->numcl * sizeof(unsigned int));
1126	jp2->cl[0] = JP2_JP2;	/* CL0 : JP2 */
1127
1128	/* Image Header box */
1129
1130	jp2->numcomps = image->numcomps;	/* NC */
1131	jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t));
1132	jp2->h = image->y1 - image->y0;		/* HEIGHT */
1133	jp2->w = image->x1 - image->x0;		/* WIDTH */
1134	/* BPC */
1135	depth_0 = image->comps[0].prec - 1;
1136	sign = image->comps[0].sgnd;
1137	jp2->bpc = depth_0 + (sign << 7);
1138	for (i = 1; i < image->numcomps; i++) {
1139		int depth = image->comps[i].prec - 1;
1140		sign = image->comps[i].sgnd;
1141		if (depth_0 != depth)
1142			jp2->bpc = 255;
1143	}
1144	jp2->C = 7;			/* C : Always 7 */
1145	jp2->UnkC = 0;		/* UnkC, colorspace specified in colr box */
1146	jp2->IPR = 0;		/* IPR, no intellectual property */
1147	
1148	/* BitsPerComponent box */
1149
1150	for (i = 0; i < image->numcomps; i++) {
1151		jp2->comps[i].bpcc = image->comps[i].prec - 1 + (image->comps[i].sgnd << 7);
1152	}
1153	jp2->meth = 1;
1154	if (image->color_space == 1)
1155		jp2->enumcs = 16;	/* sRGB as defined by IEC 61966-2.1 */
1156	else if (image->color_space == 2)
1157		jp2->enumcs = 17;	/* greyscale */
1158	else if (image->color_space == 3)
1159		jp2->enumcs = 18;	/* YUV */
1160	jp2->precedence = 0;	/* PRECEDENCE */
1161	jp2->approx = 0;		/* APPROX */
1162	
1163	jp2->jpip_on = parameters->jpip_on;
1164}
1165
1166opj_bool opj_jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
1167
1168	int pos_iptr, pos_cidx, pos_jp2c, len_jp2c, len_cidx, end_pos, pos_fidx, len_fidx;
1169	pos_jp2c = pos_iptr = -1; /* remove a warning */
1170
1171	/* JP2 encoding */
1172
1173	/* JPEG 2000 Signature box */
1174	jp2_write_jp(cio);
1175	/* File Type box */
1176	jp2_write_ftyp(jp2, cio);
1177	/* JP2 Header box */
1178	jp2_write_jp2h(jp2, cio);
1179
1180	if( jp2->jpip_on){
1181	  pos_iptr = cio_tell( cio);
1182	  cio_skip( cio, 24); /* IPTR further ! */
1183	  
1184	  pos_jp2c = cio_tell( cio);
1185	}
1186
1187	/* J2K encoding */
1188	if(!(len_jp2c = jp2_write_jp2c( jp2, cio, image, cstr_info))){
1189	    opj_event_msg(jp2->cinfo, EVT_ERROR, "Failed to encode image\n");
1190	    return OPJ_FALSE;
1191	}
1192
1193	if( jp2->jpip_on){
1194	  pos_cidx = cio_tell( cio);
1195	  
1196	  len_cidx = write_cidx( pos_jp2c+8, cio, image, *cstr_info, len_jp2c-8);
1197	  
1198	  pos_fidx = cio_tell( cio);
1199	  len_fidx = write_fidx( pos_jp2c, len_jp2c, pos_cidx, len_cidx, cio);
1200	  
1201	  end_pos = cio_tell( cio);
1202	  
1203	  cio_seek( cio, pos_iptr);
1204	  write_iptr( pos_fidx, len_fidx, cio);
1205	  
1206	  cio_seek( cio, end_pos);
1207	}
1208
1209	return OPJ_TRUE;
1210}