PageRenderTime 101ms CodeModel.GetById 25ms app.highlight 68ms RepoModel.GetById 1ms app.codeStats 0ms

/src/FreeImage/Source/LibOpenJPEG/t2.c

https://bitbucket.org/cabalistic/ogredeps/
C | 793 lines | 561 code | 99 blank | 133 comment | 190 complexity | 7fbbdb8a4f3035c45f7f53beeb3fa933 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 * All rights reserved.
  9 *
 10 * Redistribution and use in source and binary forms, with or without
 11 * modification, are permitted provided that the following conditions
 12 * are met:
 13 * 1. Redistributions of source code must retain the above copyright
 14 *    notice, this list of conditions and the following disclaimer.
 15 * 2. Redistributions in binary form must reproduce the above copyright
 16 *    notice, this list of conditions and the following disclaimer in the
 17 *    documentation and/or other materials provided with the distribution.
 18 *
 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 29 * POSSIBILITY OF SUCH DAMAGE.
 30 */
 31
 32#include "opj_includes.h"
 33
 34/** @defgroup T2 T2 - Implementation of a tier-2 coding */
 35/*@{*/
 36
 37/** @name Local static functions */
 38/*@{*/
 39
 40static void t2_putcommacode(opj_bio_t *bio, int n);
 41static int t2_getcommacode(opj_bio_t *bio);
 42/**
 43Variable length code for signalling delta Zil (truncation point)
 44@param bio Bit Input/Output component
 45@param n delta Zil
 46*/
 47static void t2_putnumpasses(opj_bio_t *bio, int n);
 48static int t2_getnumpasses(opj_bio_t *bio);
 49/**
 50Encode a packet of a tile to a destination buffer
 51@param tile Tile for which to write the packets
 52@param tcp Tile coding parameters
 53@param pi Packet identity
 54@param dest Destination buffer
 55@param len Length of the destination buffer
 56@param cstr_info Codestream information structure 
 57@param tileno Number of the tile encoded
 58@return 
 59*/
 60static int t2_encode_packet(opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi, unsigned char *dest, int len, opj_codestream_info_t *cstr_info, int tileno);
 61/**
 62@param cblk
 63@param index
 64@param cblksty
 65@param first
 66*/
 67static void t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first);
 68/**
 69Decode a packet of a tile from a source buffer
 70@param t2 T2 handle
 71@param src Source buffer
 72@param len Length of the source buffer
 73@param tile Tile for which to write the packets
 74@param tcp Tile coding parameters
 75@param pi Packet identity
 76@param pack_info Packet information
 77@return 
 78*/
 79static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, 
 80														opj_tcp_t *tcp, opj_pi_iterator_t *pi, opj_packet_info_t *pack_info);
 81
 82/*@}*/
 83
 84/*@}*/
 85
 86/* ----------------------------------------------------------------------- */
 87
 88/* #define RESTART 0x04 */
 89
 90static void t2_putcommacode(opj_bio_t *bio, int n) {
 91	while (--n >= 0) {
 92		bio_write(bio, 1, 1);
 93	}
 94	bio_write(bio, 0, 1);
 95}
 96
 97static int t2_getcommacode(opj_bio_t *bio) {
 98	int n;
 99	for (n = 0; bio_read(bio, 1); n++) {
100		;
101	}
102	return n;
103}
104
105static void t2_putnumpasses(opj_bio_t *bio, int n) {
106	if (n == 1) {
107		bio_write(bio, 0, 1);
108	} else if (n == 2) {
109		bio_write(bio, 2, 2);
110	} else if (n <= 5) {
111		bio_write(bio, 0xc | (n - 3), 4);
112	} else if (n <= 36) {
113		bio_write(bio, 0x1e0 | (n - 6), 9);
114	} else if (n <= 164) {
115		bio_write(bio, 0xff80 | (n - 37), 16);
116	}
117}
118
119static int t2_getnumpasses(opj_bio_t *bio) {
120	int n;
121	if (!bio_read(bio, 1))
122		return 1;
123	if (!bio_read(bio, 1))
124		return 2;
125	if ((n = bio_read(bio, 2)) != 3)
126		return (3 + n);
127	if ((n = bio_read(bio, 5)) != 31)
128		return (6 + n);
129	return (37 + bio_read(bio, 7));
130}
131
132static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_iterator_t *pi, unsigned char *dest, int length, opj_codestream_info_t *cstr_info, int tileno) {
133	int bandno, cblkno;
134	unsigned char *c = dest;
135
136	int compno = pi->compno;	/* component value */
137	int resno  = pi->resno;		/* resolution level value */
138	int precno = pi->precno;	/* precinct value */
139	int layno  = pi->layno;		/* quality layer value */
140
141	opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
142	opj_tcd_resolution_t *res = &tilec->resolutions[resno];
143	
144	opj_bio_t *bio = NULL;	/* BIO component */
145	
146	/* <SOP 0xff91> */
147	if (tcp->csty & J2K_CP_CSTY_SOP) {
148		c[0] = 255;
149		c[1] = 145;
150		c[2] = 0;
151		c[3] = 4;
152		c[4] = (unsigned char)((tile->packno % 65536) / 256);
153		c[5] = (unsigned char)((tile->packno % 65536) % 256);
154		c += 6;
155	}
156	/* </SOP> */
157	
158	if (!layno) {
159		for (bandno = 0; bandno < res->numbands; bandno++) {
160			opj_tcd_band_t *band = &res->bands[bandno];
161			opj_tcd_precinct_t *prc = &band->precincts[precno];
162			tgt_reset(prc->incltree);
163			tgt_reset(prc->imsbtree);
164			for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
165				opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno];
166				cblk->numpasses = 0;
167				tgt_setvalue(prc->imsbtree, cblkno, band->numbps - cblk->numbps);
168			}
169		}
170	}
171	
172	bio = bio_create();
173	bio_init_enc(bio, c, length);
174	bio_write(bio, 1, 1);		/* Empty header bit */
175	
176	/* Writing Packet header */
177	for (bandno = 0; bandno < res->numbands; bandno++) {
178		opj_tcd_band_t *band = &res->bands[bandno];
179		opj_tcd_precinct_t *prc = &band->precincts[precno];
180		for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
181			opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno];
182			opj_tcd_layer_t *layer = &cblk->layers[layno];
183			if (!cblk->numpasses && layer->numpasses) {
184				tgt_setvalue(prc->incltree, cblkno, layno);
185			}
186		}
187		for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
188			opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno];
189			opj_tcd_layer_t *layer = &cblk->layers[layno];
190			int increment = 0;
191			int nump = 0;
192			int len = 0, passno;
193			/* cblk inclusion bits */
194			if (!cblk->numpasses) {
195				tgt_encode(bio, prc->incltree, cblkno, layno + 1);
196			} else {
197				bio_write(bio, layer->numpasses != 0, 1);
198			}
199			/* if cblk not included, go to the next cblk  */
200			if (!layer->numpasses) {
201				continue;
202			}
203			/* if first instance of cblk --> zero bit-planes information */
204			if (!cblk->numpasses) {
205				cblk->numlenbits = 3;
206				tgt_encode(bio, prc->imsbtree, cblkno, 999);
207			}
208			/* number of coding passes included */
209			t2_putnumpasses(bio, layer->numpasses);
210			
211			/* computation of the increase of the length indicator and insertion in the header     */
212			for (passno = cblk->numpasses; passno < cblk->numpasses + layer->numpasses; passno++) {
213				opj_tcd_pass_t *pass = &cblk->passes[passno];
214				nump++;
215				len += pass->len;
216				if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) {
217					increment = int_max(increment, int_floorlog2(len) + 1 - (cblk->numlenbits + int_floorlog2(nump)));
218					len = 0;
219					nump = 0;
220				}
221			}
222			t2_putcommacode(bio, increment);
223
224			/* computation of the new Length indicator */
225			cblk->numlenbits += increment;
226
227			/* insertion of the codeword segment length */
228			for (passno = cblk->numpasses; passno < cblk->numpasses + layer->numpasses; passno++) {
229				opj_tcd_pass_t *pass = &cblk->passes[passno];
230				nump++;
231				len += pass->len;
232				if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) {
233					bio_write(bio, len, cblk->numlenbits + int_floorlog2(nump));
234					len = 0;
235					nump = 0;
236				}
237			}
238		}
239	}
240
241	if (bio_flush(bio)) {
242		bio_destroy(bio);
243		return -999;		/* modified to eliminate longjmp !! */
244	}
245
246	c += bio_numbytes(bio);
247	bio_destroy(bio);
248	
249	/* <EPH 0xff92> */
250	if (tcp->csty & J2K_CP_CSTY_EPH) {
251		c[0] = 255;
252		c[1] = 146;
253		c += 2;
254	}
255	/* </EPH> */
256
257	/* << INDEX */
258	/* End of packet header position. Currently only represents the distance to start of packet
259	// Will be updated later by incrementing with packet start value */
260	if(cstr_info && cstr_info->index_write) {
261		opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno];
262		info_PK->end_ph_pos = (int)(c - dest);
263	}
264	/* INDEX >> */
265	
266	/* Writing the packet body */
267	
268	for (bandno = 0; bandno < res->numbands; bandno++) {
269		opj_tcd_band_t *band = &res->bands[bandno];
270		opj_tcd_precinct_t *prc = &band->precincts[precno];
271		for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
272			opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno];
273			opj_tcd_layer_t *layer = &cblk->layers[layno];
274			if (!layer->numpasses) {
275				continue;
276			}
277			if (c + layer->len > dest + length) {
278				return -999;
279			}
280			
281			memcpy(c, layer->data, layer->len);
282			cblk->numpasses += layer->numpasses;
283			c += layer->len;
284			/* << INDEX */ 
285			if(cstr_info && cstr_info->index_write) {
286				opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno];
287				info_PK->disto += layer->disto;
288				if (cstr_info->D_max < info_PK->disto) {
289					cstr_info->D_max = info_PK->disto;
290				}
291			}
292			/* INDEX >> */
293		}
294	}
295	
296	return (c - dest);
297}
298
299static void t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first) {
300	opj_tcd_seg_t* seg;
301	cblk->segs = (opj_tcd_seg_t*) opj_realloc(cblk->segs, (index + 1) * sizeof(opj_tcd_seg_t));
302	seg = &cblk->segs[index];
303	seg->data = NULL;
304	seg->dataindex = 0;
305	seg->numpasses = 0;
306	seg->len = 0;
307	if (cblksty & J2K_CCP_CBLKSTY_TERMALL) {
308		seg->maxpasses = 1;
309	}
310	else if (cblksty & J2K_CCP_CBLKSTY_LAZY) {
311		if (first) {
312			seg->maxpasses = 10;
313		} else {
314			seg->maxpasses = (((seg - 1)->maxpasses == 1) || ((seg - 1)->maxpasses == 10)) ? 2 : 1;
315		}
316	} else {
317		seg->maxpasses = 109;
318	}
319}
320
321static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, 
322														opj_tcp_t *tcp, opj_pi_iterator_t *pi, opj_packet_info_t *pack_info) {
323	int bandno, cblkno;
324	unsigned char *c = src;
325
326	opj_cp_t *cp = t2->cp;
327
328	int compno = pi->compno;	/* component value */
329	int resno  = pi->resno;		/* resolution level value */
330	int precno = pi->precno;	/* precinct value */
331	int layno  = pi->layno;		/* quality layer value */
332
333	opj_tcd_resolution_t* res = &tile->comps[compno].resolutions[resno];
334
335	unsigned char *hd = NULL;
336	int present;
337	
338	opj_bio_t *bio = NULL;	/* BIO component */
339	
340	if (layno == 0) {
341		for (bandno = 0; bandno < res->numbands; bandno++) {
342			opj_tcd_band_t *band = &res->bands[bandno];
343			opj_tcd_precinct_t *prc = &band->precincts[precno];
344			
345			if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue;
346			
347			tgt_reset(prc->incltree);
348			tgt_reset(prc->imsbtree);
349			for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
350				opj_tcd_cblk_dec_t* cblk = &prc->cblks.dec[cblkno];
351				cblk->numsegs = 0;
352			}
353		}
354	}
355	
356	/* SOP markers */
357	
358	if (tcp->csty & J2K_CP_CSTY_SOP) {
359		if ((*c) != 0xff || (*(c + 1) != 0x91)) {
360			opj_event_msg(t2->cinfo, EVT_WARNING, "Expected SOP marker\n");
361		} else {
362			c += 6;
363		}
364		
365		/** TODO : check the Nsop value */
366	}
367	
368	/* 
369	When the marker PPT/PPM is used the packet header are store in PPT/PPM marker
370	This part deal with this caracteristic
371	step 1: Read packet header in the saved structure
372	step 2: Return to codestream for decoding 
373	*/
374
375	bio = bio_create();
376	
377	if (cp->ppm == 1) {		/* PPM */
378		hd = cp->ppm_data;
379		bio_init_dec(bio, hd, cp->ppm_len);
380	} else if (tcp->ppt == 1) {	/* PPT */
381		hd = tcp->ppt_data;
382		bio_init_dec(bio, hd, tcp->ppt_len);
383	} else {			/* Normal Case */
384		hd = c;
385		bio_init_dec(bio, hd, src+len-hd);
386	}
387	
388	present = bio_read(bio, 1);
389	
390	if (!present) {
391		bio_inalign(bio);
392		hd += bio_numbytes(bio);
393		bio_destroy(bio);
394		
395		/* EPH markers */
396		
397		if (tcp->csty & J2K_CP_CSTY_EPH) {
398			if ((*hd) != 0xff || (*(hd + 1) != 0x92)) {
399				printf("Error : expected EPH marker\n");
400			} else {
401				hd += 2;
402			}
403		}
404
405		/* << INDEX */
406		/* End of packet header position. Currently only represents the distance to start of packet
407		// Will be updated later by incrementing with packet start value*/
408		if(pack_info) {
409			pack_info->end_ph_pos = (int)(c - src);
410		}
411		/* INDEX >> */
412		
413		if (cp->ppm == 1) {		/* PPM case */
414			cp->ppm_len += cp->ppm_data-hd;
415			cp->ppm_data = hd;
416			return (c - src);
417		}
418		if (tcp->ppt == 1) {	/* PPT case */
419			tcp->ppt_len+=tcp->ppt_data-hd;
420			tcp->ppt_data = hd;
421			return (c - src);
422		}
423		
424		return (hd - src);
425	}
426	
427	for (bandno = 0; bandno < res->numbands; bandno++) {
428		opj_tcd_band_t *band = &res->bands[bandno];
429		opj_tcd_precinct_t *prc = &band->precincts[precno];
430		
431		if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue;
432		
433		for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
434			int included, increment, n, segno;
435			opj_tcd_cblk_dec_t* cblk = &prc->cblks.dec[cblkno];
436			/* if cblk not yet included before --> inclusion tagtree */
437			if (!cblk->numsegs) {
438				included = tgt_decode(bio, prc->incltree, cblkno, layno + 1);
439				/* else one bit */
440			} else {
441				included = bio_read(bio, 1);
442			}
443			/* if cblk not included */
444			if (!included) {
445				cblk->numnewpasses = 0;
446				continue;
447			}
448			/* if cblk not yet included --> zero-bitplane tagtree */
449			if (!cblk->numsegs) {
450				int i, numimsbs;
451				for (i = 0; !tgt_decode(bio, prc->imsbtree, cblkno, i); i++) {
452					;
453				}
454				numimsbs = i - 1;
455				cblk->numbps = band->numbps - numimsbs;
456				cblk->numlenbits = 3;
457			}
458			/* number of coding passes */
459			cblk->numnewpasses = t2_getnumpasses(bio);
460			increment = t2_getcommacode(bio);
461			/* length indicator increment */
462			cblk->numlenbits += increment;
463			segno = 0;
464			if (!cblk->numsegs) {
465				t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 1);
466			} else {
467				segno = cblk->numsegs - 1;
468				if (cblk->segs[segno].numpasses == cblk->segs[segno].maxpasses) {
469					++segno;
470					t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0);
471				}
472			}
473			n = cblk->numnewpasses;
474			
475			do {
476				cblk->segs[segno].numnewpasses = int_min(cblk->segs[segno].maxpasses - cblk->segs[segno].numpasses, n);
477				cblk->segs[segno].newlen = bio_read(bio, cblk->numlenbits + int_floorlog2(cblk->segs[segno].numnewpasses));
478				n -= cblk->segs[segno].numnewpasses;
479				if (n > 0) {
480					++segno;
481					t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0);
482				}
483			} while (n > 0);
484		}
485	}
486	
487	if (bio_inalign(bio)) {
488		bio_destroy(bio);
489		return -999;
490	}
491	
492	hd += bio_numbytes(bio);
493	bio_destroy(bio);
494	
495	/* EPH markers */
496	if (tcp->csty & J2K_CP_CSTY_EPH) {
497		if ((*hd) != 0xff || (*(hd + 1) != 0x92)) {
498			opj_event_msg(t2->cinfo, EVT_ERROR, "Expected EPH marker\n");
499			return -999;
500		} else {
501			hd += 2;
502		}
503	}
504
505	/* << INDEX */
506	/* End of packet header position. Currently only represents the distance to start of packet
507	// Will be updated later by incrementing with packet start value*/
508	if(pack_info) {
509		pack_info->end_ph_pos = (int)(hd - src);
510	}
511	/* INDEX >> */
512	
513	if (cp->ppm==1) {
514		cp->ppm_len+=cp->ppm_data-hd;
515		cp->ppm_data = hd;
516	} else if (tcp->ppt == 1) {
517		tcp->ppt_len+=tcp->ppt_data-hd;
518		tcp->ppt_data = hd;
519	} else {
520		c=hd;
521	}
522	
523	for (bandno = 0; bandno < res->numbands; bandno++) {
524		opj_tcd_band_t *band = &res->bands[bandno];
525		opj_tcd_precinct_t *prc = &band->precincts[precno];
526		
527		if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue;
528		
529		for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
530			opj_tcd_cblk_dec_t* cblk = &prc->cblks.dec[cblkno];
531			opj_tcd_seg_t *seg = NULL;
532			if (!cblk->numnewpasses)
533				continue;
534			if (!cblk->numsegs) {
535				seg = &cblk->segs[0];
536				cblk->numsegs++;
537				cblk->len = 0;
538			} else {
539				seg = &cblk->segs[cblk->numsegs - 1];
540				if (seg->numpasses == seg->maxpasses) {
541					seg++;
542					cblk->numsegs++;
543				}
544			}
545			
546			do {
547				if (c + seg->newlen > src + len) {
548					return -999;
549				}
550
551#ifdef USE_JPWL
552			/* we need here a j2k handle to verify if making a check to
553			the validity of cblocks parameters is selected from user (-W) */
554
555				/* let's check that we are not exceeding */
556				if ((cblk->len + seg->newlen) > 8192) {
557					opj_event_msg(t2->cinfo, EVT_WARNING,
558						"JPWL: segment too long (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
559						seg->newlen, cblkno, precno, bandno, resno, compno);
560					if (!JPWL_ASSUME) {
561						opj_event_msg(t2->cinfo, EVT_ERROR, "JPWL: giving up\n");
562						return -999;
563					}
564					seg->newlen = 8192 - cblk->len;
565					opj_event_msg(t2->cinfo, EVT_WARNING, "      - truncating segment to %d\n", seg->newlen);
566					break;
567				};
568
569#endif /* USE_JPWL */
570				
571				cblk->data = (unsigned char*) opj_realloc(cblk->data, (cblk->len + seg->newlen) * sizeof(unsigned char));
572				memcpy(cblk->data + cblk->len, c, seg->newlen);
573				if (seg->numpasses == 0) {
574					seg->data = &cblk->data;
575					seg->dataindex = cblk->len;
576				}
577				c += seg->newlen;
578				cblk->len += seg->newlen;
579				seg->len += seg->newlen;
580				seg->numpasses += seg->numnewpasses;
581				cblk->numnewpasses -= seg->numnewpasses;
582				if (cblk->numnewpasses > 0) {
583					seg++;
584					cblk->numsegs++;
585				}
586			} while (cblk->numnewpasses > 0);
587		}
588	}
589	
590	return (c - src);
591}
592
593/* ----------------------------------------------------------------------- */
594
595int t2_encode_packets(opj_t2_t* t2,int tileno, opj_tcd_tile_t *tile, int maxlayers, unsigned char *dest, int len, opj_codestream_info_t *cstr_info,int tpnum, int tppos,int pino, J2K_T2_MODE t2_mode, int cur_totnum_tp){
596	unsigned char *c = dest;
597	int e = 0;
598	int compno;
599	opj_pi_iterator_t *pi = NULL;
600	int poc;
601	opj_image_t *image = t2->image;
602	opj_cp_t *cp = t2->cp;
603	opj_tcp_t *tcp = &cp->tcps[tileno];
604	int pocno = cp->cinema == CINEMA4K_24? 2: 1;
605	int maxcomp = cp->max_comp_size > 0 ? image->numcomps : 1;
606	
607	pi = pi_initialise_encode(image, cp, tileno, t2_mode);
608	if(!pi) {
609		/* TODO: throw an error */
610		return -999;
611	}
612	
613	if(t2_mode == THRESH_CALC ){ /* Calculating threshold */
614		for(compno = 0; compno < maxcomp; compno++ ){
615			for(poc = 0; poc < pocno ; poc++){
616				int comp_len = 0;
617				int tpnum = compno;
618				if (pi_create_encode(pi, cp,tileno,poc,tpnum,tppos,t2_mode,cur_totnum_tp)) {
619					opj_event_msg(t2->cinfo, EVT_ERROR, "Error initializing Packet Iterator\n");
620					pi_destroy(pi, cp, tileno);
621					return -999;
622				}
623				while (pi_next(&pi[poc])) {
624					if (pi[poc].layno < maxlayers) {
625						e = t2_encode_packet(tile, &cp->tcps[tileno], &pi[poc], c, dest + len - c, cstr_info, tileno);
626						comp_len = comp_len + e;
627						if (e == -999) {
628							break;
629						} else {
630							c += e;
631						}
632					}
633				}
634				if (e == -999) break;
635				if (cp->max_comp_size){
636					if (comp_len > cp->max_comp_size){
637						e = -999;
638						break;
639					}
640				}
641			}
642			if (e == -999)  break;
643		}
644	}else{  /* t2_mode == FINAL_PASS  */
645		pi_create_encode(pi, cp,tileno,pino,tpnum,tppos,t2_mode,cur_totnum_tp);
646		while (pi_next(&pi[pino])) {
647			if (pi[pino].layno < maxlayers) {
648				e = t2_encode_packet(tile, &cp->tcps[tileno], &pi[pino], c, dest + len - c, cstr_info, tileno);
649				if (e == -999) {
650					break;
651				} else {
652					c += e;
653				}
654				/* INDEX >> */
655				if(cstr_info) {
656					if(cstr_info->index_write) {
657						opj_tile_info_t *info_TL = &cstr_info->tile[tileno];
658						opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->packno];
659						if (!cstr_info->packno) {
660							info_PK->start_pos = info_TL->end_header + 1;
661						} else {
662							info_PK->start_pos = ((cp->tp_on | tcp->POC)&& info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno - 1].end_pos + 1;
663						}
664						info_PK->end_pos = info_PK->start_pos + e - 1;
665						info_PK->end_ph_pos += info_PK->start_pos - 1;	/* End of packet header which now only represents the distance 
666																														// to start of packet is incremented by value of start of packet*/
667					}
668					
669					cstr_info->packno++;
670				}
671				/* << INDEX */
672				tile->packno++;
673			}
674		}
675	}
676	
677	pi_destroy(pi, cp, tileno);
678	
679	if (e == -999) {
680		return e;
681	}
682	
683  return (c - dest);
684}
685
686int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile, opj_codestream_info_t *cstr_info) {
687	unsigned char *c = src;
688	opj_pi_iterator_t *pi;
689	int pino, e = 0;
690	int n = 0, curtp = 0;
691	int tp_start_packno;
692
693	opj_image_t *image = t2->image;
694	opj_cp_t *cp = t2->cp;
695	
696	/* create a packet iterator */
697	pi = pi_create_decode(image, cp, tileno);
698	if(!pi) {
699		/* TODO: throw an error */
700		return -999;
701	}
702
703	tp_start_packno = 0;
704	
705	for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) {
706		while (pi_next(&pi[pino])) {
707			if ((cp->layer==0) || (cp->layer>=((pi[pino].layno)+1))) {
708				opj_packet_info_t *pack_info;
709				if (cstr_info)
710					pack_info = &cstr_info->tile[tileno].packet[cstr_info->packno];
711				else
712					pack_info = NULL;
713				e = t2_decode_packet(t2, c, src + len - c, tile, &cp->tcps[tileno], &pi[pino], pack_info);
714			} else {
715				e = 0;
716			}
717			if(e == -999) return -999;
718			/* progression in resolution */
719			image->comps[pi[pino].compno].resno_decoded =	
720				(e > 0) ? 
721				int_max(pi[pino].resno, image->comps[pi[pino].compno].resno_decoded) 
722				: image->comps[pi[pino].compno].resno_decoded;
723			n++;
724
725			/* INDEX >> */
726			if(cstr_info) {
727				opj_tile_info_t *info_TL = &cstr_info->tile[tileno];
728				opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->packno];
729				if (!cstr_info->packno) {
730					info_PK->start_pos = info_TL->end_header + 1;
731				} else if (info_TL->packet[cstr_info->packno-1].end_pos >= (int)cstr_info->tile[tileno].tp[curtp].tp_end_pos){ /* New tile part*/
732					info_TL->tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; /* Number of packets in previous tile-part*/
733          info_TL->tp[curtp].tp_start_pack = tp_start_packno;
734					tp_start_packno = cstr_info->packno;
735					curtp++;
736					info_PK->start_pos = cstr_info->tile[tileno].tp[curtp].tp_end_header+1;
737				} else {
738					info_PK->start_pos = (cp->tp_on && info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno - 1].end_pos + 1;
739				}
740				info_PK->end_pos = info_PK->start_pos + e - 1;
741				info_PK->end_ph_pos += info_PK->start_pos - 1;	/* End of packet header which now only represents the distance 
742																												// to start of packet is incremented by value of start of packet*/
743				cstr_info->packno++;
744			}
745			/* << INDEX */
746			
747			if (e == -999) {		/* ADD */
748				break;
749			} else {
750				c += e;
751			}			
752		}
753	}
754	/* INDEX >> */
755	if(cstr_info) {
756		cstr_info->tile[tileno].tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; /* Number of packets in last tile-part*/
757    cstr_info->tile[tileno].tp[curtp].tp_start_pack = tp_start_packno;
758	}
759	/* << INDEX */
760
761	/* don't forget to release pi */
762	pi_destroy(pi, cp, tileno);
763	
764	if (e == -999) {
765		return e;
766	}
767	
768	return (c - src);
769}
770
771/* ----------------------------------------------------------------------- */
772
773opj_t2_t* t2_create(opj_common_ptr cinfo, opj_image_t *image, opj_cp_t *cp) {
774	/* create the tcd structure */
775	opj_t2_t *t2 = (opj_t2_t*)opj_malloc(sizeof(opj_t2_t));
776	if(!t2) return NULL;
777	t2->cinfo = cinfo;
778	t2->image = image;
779	t2->cp = cp;
780
781	return t2;
782}
783
784void t2_destroy(opj_t2_t *t2) {
785	if(t2) {
786		opj_free(t2);
787	}
788}
789
790
791
792
793