static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi, opj_packet_info_t *pack_info) { int bandno, cblkno; unsigned char *c = src; opj_cp_t *cp = t2->cp; int compno = pi->compno; /* component value */ int resno = pi->resno; /* resolution level value */ int precno = pi->precno; /* precinct value */ int layno = pi->layno; /* quality layer value */ opj_tcd_resolution_t* res = &tile->comps[compno].resolutions[resno]; unsigned char *hd = NULL; int present; opj_bio_t *bio = NULL; /* BIO component */ if (layno == 0) { for (bandno = 0; bandno < res->numbands; bandno++) { opj_tcd_band_t *band = &res->bands[bandno]; opj_tcd_precinct_t *prc = &band->precincts[precno]; if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue; tgt_reset(prc->incltree); tgt_reset(prc->imsbtree); for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { opj_tcd_cblk_dec_t* cblk = &prc->cblks.dec[cblkno]; cblk->numsegs = 0; } } } /* SOP markers */ if (tcp->csty & J2K_CP_CSTY_SOP) { if ((*c) != 0xff || (*(c + 1) != 0x91)) { opj_event_msg(t2->cinfo, EVT_WARNING, "Expected SOP marker\n"); } else { c += 6; } /** TODO : check the Nsop value */ } /* When the marker PPT/PPM is used the packet header are store in PPT/PPM marker This part deal with this caracteristic step 1: Read packet header in the saved structure step 2: Return to codestream for decoding */ bio = bio_create(); if (cp->ppm == 1) { /* PPM */ hd = cp->ppm_data; bio_init_dec(bio, hd, cp->ppm_len); } else if (tcp->ppt == 1) { /* PPT */ hd = tcp->ppt_data; bio_init_dec(bio, hd, tcp->ppt_len); } else { /* Normal Case */ hd = c; bio_init_dec(bio, hd, src+len-hd); } present = bio_read(bio, 1); if (!present) { bio_inalign(bio); hd += bio_numbytes(bio); bio_destroy(bio); /* EPH markers */ if (tcp->csty & J2K_CP_CSTY_EPH) { if ((*hd) != 0xff || (*(hd + 1) != 0x92)) { printf("Error : expected EPH marker\n"); } else { hd += 2; } } /* << INDEX */ /* End of packet header position. Currently only represents the distance to start of packet // Will be updated later by incrementing with packet start value*/ if(pack_info) { pack_info->end_ph_pos = (int)(c - src); } /* INDEX >> */ if (cp->ppm == 1) { /* PPM case */ cp->ppm_len += cp->ppm_data-hd; cp->ppm_data = hd; return (c - src); } if (tcp->ppt == 1) { /* PPT case */ tcp->ppt_len+=tcp->ppt_data-hd; tcp->ppt_data = hd; return (c - src); } return (hd - src); } for (bandno = 0; bandno < res->numbands; bandno++) { opj_tcd_band_t *band = &res->bands[bandno]; opj_tcd_precinct_t *prc = &band->precincts[precno]; if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue; for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { int included, increment, n, segno; opj_tcd_cblk_dec_t* cblk = &prc->cblks.dec[cblkno]; /* if cblk not yet included before --> inclusion tagtree */ if (!cblk->numsegs) { included = tgt_decode(bio, prc->incltree, cblkno, layno + 1); /* else one bit */ } else { included = bio_read(bio, 1); } /* if cblk not included */ if (!included) { cblk->numnewpasses = 0; continue; } /* if cblk not yet included --> zero-bitplane tagtree */ if (!cblk->numsegs) { int i, numimsbs; for (i = 0; !tgt_decode(bio, prc->imsbtree, cblkno, i); i++) { ; } numimsbs = i - 1; cblk->numbps = band->numbps - numimsbs; cblk->numlenbits = 3; } /* number of coding passes */ cblk->numnewpasses = t2_getnumpasses(bio); increment = t2_getcommacode(bio); /* length indicator increment */ cblk->numlenbits += increment; segno = 0; if (!cblk->numsegs) { t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 1); } else { segno = cblk->numsegs - 1; if (cblk->segs[segno].numpasses == cblk->segs[segno].maxpasses) { ++segno; t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0); } } n = cblk->numnewpasses; do { cblk->segs[segno].numnewpasses = int_min(cblk->segs[segno].maxpasses - cblk->segs[segno].numpasses, n); cblk->segs[segno].newlen = bio_read(bio, cblk->numlenbits + int_floorlog2(cblk->segs[segno].numnewpasses)); n -= cblk->segs[segno].numnewpasses; if (n > 0) { ++segno; t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0); } } while (n > 0); } } if (bio_inalign(bio)) { bio_destroy(bio); return -999; } hd += bio_numbytes(bio); bio_destroy(bio); /* EPH markers */ if (tcp->csty & J2K_CP_CSTY_EPH) { if ((*hd) != 0xff || (*(hd + 1) != 0x92)) { opj_event_msg(t2->cinfo, EVT_ERROR, "Expected EPH marker\n"); return -999; } else { hd += 2; } } /* << INDEX */ /* End of packet header position. Currently only represents the distance to start of packet // Will be updated later by incrementing with packet start value*/ if(pack_info) { pack_info->end_ph_pos = (int)(hd - src); } /* INDEX >> */ if (cp->ppm==1) { cp->ppm_len+=cp->ppm_data-hd; cp->ppm_data = hd; } else if (tcp->ppt == 1) { tcp->ppt_len+=tcp->ppt_data-hd; tcp->ppt_data = hd; } else { c=hd; } for (bandno = 0; bandno < res->numbands; bandno++) { opj_tcd_band_t *band = &res->bands[bandno]; opj_tcd_precinct_t *prc = &band->precincts[precno]; if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue; for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { opj_tcd_cblk_dec_t* cblk = &prc->cblks.dec[cblkno]; opj_tcd_seg_t *seg = NULL; if (!cblk->numnewpasses) continue; if (!cblk->numsegs) { seg = &cblk->segs[0]; cblk->numsegs++; cblk->len = 0; } else { seg = &cblk->segs[cblk->numsegs - 1]; if (seg->numpasses == seg->maxpasses) { seg++; cblk->numsegs++; } } do { if (c + seg->newlen > src + len) { return -999; } #ifdef USE_JPWL /* we need here a j2k handle to verify if making a check to the validity of cblocks parameters is selected from user (-W) */ /* let's check that we are not exceeding */ if ((cblk->len + seg->newlen) > 8192) { opj_event_msg(t2->cinfo, EVT_WARNING, "JPWL: segment too long (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n", seg->newlen, cblkno, precno, bandno, resno, compno); if (!JPWL_ASSUME) { opj_event_msg(t2->cinfo, EVT_ERROR, "JPWL: giving up\n"); return -999; } seg->newlen = 8192 - cblk->len; opj_event_msg(t2->cinfo, EVT_WARNING, " - truncating segment to %d\n", seg->newlen); break; }; #endif /* USE_JPWL */ cblk->data = (unsigned char*) opj_realloc(cblk->data, (cblk->len + seg->newlen) * sizeof(unsigned char)); memcpy(cblk->data + cblk->len, c, seg->newlen); if (seg->numpasses == 0) { seg->data = &cblk->data; seg->dataindex = cblk->len; } c += seg->newlen; cblk->len += seg->newlen; seg->len += seg->newlen; seg->numpasses += seg->numnewpasses; cblk->numnewpasses -= seg->numnewpasses; if (cblk->numnewpasses > 0) { seg++; cblk->numsegs++; } } while (cblk->numnewpasses > 0); } } return (c - src); }
int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi) { int bandno, cblkno; unsigned char *c = src; opj_cp_t *cp = t2->cp; int compno = pi->compno; /* component value */ int resno = pi->resno; /* resolution level value */ int precno = pi->precno; /* precinct value */ int layno = pi->layno; /* quality layer value */ opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; opj_tcd_resolution_t *res = &tilec->resolutions[resno]; unsigned char *hd = NULL; int present; opj_bio_t *bio = NULL; /* BIO component */ if (layno == 0) { for (bandno = 0; bandno < res->numbands; bandno++) { opj_tcd_band_t *band = &res->bands[bandno]; opj_tcd_precinct_t *prc = &band->precincts[precno]; if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)||(band->z1-band->z0 == 0)) continue; tgt_reset(prc->incltree); tgt_reset(prc->imsbtree); for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; cblk->numsegs = 0; } } } /* SOP markers */ if (tcp->csty & J3D_CP_CSTY_SOP) { if ((*c) != 0xff || (*(c + 1) != 0x91)) { opj_event_msg(t2->cinfo, EVT_WARNING, "Expected SOP marker\n"); } else { c += 6; } /** TODO : check the Nsop value */ } /* When the marker PPT/PPM is used the packet header are store in PPT/PPM marker This part deal with this caracteristic step 1: Read packet header in the saved structure step 2: Return to codestream for decoding */ bio = bio_create(); if (cp->ppm == 1) { /* PPM */ hd = cp->ppm_data; bio_init_dec(bio, hd, cp->ppm_len); } else if (tcp->ppt == 1) { /* PPT */ hd = tcp->ppt_data; bio_init_dec(bio, hd, tcp->ppt_len); } else { /* Normal Case */ hd = c; bio_init_dec(bio, hd, src+len-hd); } present = bio_read(bio, 1); if (!present) { bio_inalign(bio); hd += bio_numbytes(bio); bio_destroy(bio); /* EPH markers */ if (tcp->csty & J3D_CP_CSTY_EPH) { if ((*hd) != 0xff || (*(hd + 1) != 0x92)) { printf("Error : expected EPH marker\n"); } else { hd += 2; } } if (cp->ppm == 1) { /* PPM case */ cp->ppm_len += cp->ppm_data-hd; cp->ppm_data = hd; return (c - src); } if (tcp->ppt == 1) { /* PPT case */ tcp->ppt_len+=tcp->ppt_data-hd; tcp->ppt_data = hd; return (c - src); } return (hd - src); } for (bandno = 0; bandno < res->numbands; bandno++) { opj_tcd_band_t *band = &res->bands[bandno]; opj_tcd_precinct_t *prc = &band->precincts[precno]; if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)||(band->z1-band->z0 == 0)) continue; for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { int included, increment, n; opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; opj_tcd_seg_t *seg = NULL; /* if cblk not yet included before --> inclusion tagtree */ if (!cblk->numsegs) { included = tgt_decode(bio, prc->incltree, cblkno, layno + 1); /* else one bit */ } else { included = bio_read(bio, 1); } /* if cblk not included */ if (!included) { cblk->numnewpasses = 0; continue; } /* if cblk not yet included --> zero-bitplane tagtree */ if (!cblk->numsegs) { int i, numimsbs; for (i = 0; !tgt_decode(bio, prc->imsbtree, cblkno, i); i++); numimsbs = i - 1; cblk->numbps = band->numbps - numimsbs; cblk->numlenbits = 3; } /* number of coding passes */ cblk->numnewpasses = t2_getnumpasses(bio); increment = t2_getcommacode(bio); /* length indicator increment */ cblk->numlenbits += increment; if (!cblk->numsegs) { seg = &cblk->segs[0]; t2_init_seg(seg, tcp->tccps[compno].cblksty, 1); } else { seg = &cblk->segs[cblk->numsegs - 1]; if (seg->numpasses == seg->maxpasses) { t2_init_seg(++seg, tcp->tccps[compno].cblksty, 0); } } n = cblk->numnewpasses; do { seg->numnewpasses = int_min(seg->maxpasses - seg->numpasses, n); seg->newlen = bio_read(bio, cblk->numlenbits + int_floorlog2(seg->numnewpasses)); n -= seg->numnewpasses; if (n > 0) { t2_init_seg(++seg, tcp->tccps[compno].cblksty, 0); } } while (n > 0); } } if (bio_inalign(bio)) { bio_destroy(bio); return -999; } hd += bio_numbytes(bio); bio_destroy(bio); /* EPH markers */ if (tcp->csty & J3D_CP_CSTY_EPH) { if ((*hd) != 0xff || (*(hd + 1) != 0x92)) { opj_event_msg(t2->cinfo, EVT_ERROR, "Expected EPH marker\n"); return -999; } else { hd += 2; } } if (cp->ppm==1) { cp->ppm_len+=cp->ppm_data-hd; cp->ppm_data = hd; } else if (tcp->ppt == 1) { tcp->ppt_len+=tcp->ppt_data-hd; tcp->ppt_data = hd; } else { c=hd; } for (bandno = 0; bandno < res->numbands; bandno++) { opj_tcd_band_t *band = &res->bands[bandno]; opj_tcd_precinct_t *prc = &band->precincts[precno]; if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)||(band->z1-band->z0 == 0)) continue; for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; opj_tcd_seg_t *seg = NULL; if (!cblk->numnewpasses) continue; if (!cblk->numsegs) { seg = &cblk->segs[0]; cblk->numsegs++; cblk->len = 0; } else { seg = &cblk->segs[cblk->numsegs - 1]; if (seg->numpasses == seg->maxpasses) { seg++; cblk->numsegs++; } } do { if (c + seg->newlen > src + len) { return -999; } memcpy(cblk->data + cblk->len, c, seg->newlen); if (seg->numpasses == 0) { seg->data = cblk->data + cblk->len; } c += seg->newlen; cblk->len += seg->newlen; seg->len += seg->newlen; seg->numpasses += seg->numnewpasses; cblk->numnewpasses -= seg->numnewpasses; if (cblk->numnewpasses > 0) { seg++; cblk->numsegs++; } } while (cblk->numnewpasses > 0); } } return (c - src); }
static bool t2_read_packet_header( opj_t2_t* p_t2, opj_tcd_tile_t *p_tile, opj_tcp_t *p_tcp, opj_pi_iterator_t *p_pi, bool * p_is_data_present, OPJ_BYTE *p_src_data, OPJ_UINT32 * p_data_read, OPJ_UINT32 p_max_length, opj_packet_info_t *p_pack_info) { /* loop */ OPJ_UINT32 bandno, cblkno; OPJ_UINT32 l_nb_code_blocks; OPJ_UINT32 l_remaining_length; OPJ_UINT32 l_header_length; OPJ_UINT32 * l_modified_length_ptr = 00; OPJ_BYTE *l_current_data = p_src_data; opj_cp_t *l_cp = p_t2->cp; opj_bio_t *l_bio = 00; /* BIO component */ opj_tcd_band_t *l_band = 00; opj_tcd_cblk_dec_t* l_cblk = 00; opj_tcd_resolution_t* l_res = &p_tile->comps[p_pi->compno].resolutions[p_pi->resno]; OPJ_BYTE *l_header_data = 00; OPJ_BYTE **l_header_data_start = 00; OPJ_UINT32 l_present; if (p_pi->layno == 0) { l_band = l_res->bands; /* reset tagtrees */ for (bandno = 0; bandno < l_res->numbands; ++bandno) { opj_tcd_precinct_t *l_prc = &l_band->precincts[p_pi->precno]; if ( ! ((l_band->x1-l_band->x0 == 0)||(l_band->y1-l_band->y0 == 0))) { tgt_reset(l_prc->incltree); tgt_reset(l_prc->imsbtree); l_cblk = l_prc->cblks.dec; l_nb_code_blocks = l_prc->cw * l_prc->ch; for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) { l_cblk->numsegs = 0; l_cblk->real_num_segs = 0; ++l_cblk; } } ++l_band; } } /* SOP markers */ if (p_tcp->csty & J2K_CP_CSTY_SOP) { if ((*l_current_data) != 0xff || (*(l_current_data + 1) != 0x91)) { // TODO opj_event_msg(t2->cinfo->event_mgr, EVT_WARNING, "Expected SOP marker\n"); } else { l_current_data += 6; } /** TODO : check the Nsop value */ } /* When the marker PPT/PPM is used the packet header are store in PPT/PPM marker This part deal with this caracteristic step 1: Read packet header in the saved structure step 2: Return to codestream for decoding */ l_bio = bio_create(); if (! l_bio) { return false; } if (l_cp->ppm == 1) { /* PPM */ l_header_data_start = &l_cp->ppm_data; l_header_data = *l_header_data_start; l_modified_length_ptr = &(l_cp->ppm_len); } else if (p_tcp->ppt == 1) { /* PPT */ l_header_data_start = &(p_tcp->ppt_data); l_header_data = *l_header_data_start; l_modified_length_ptr = &(p_tcp->ppt_len); } else { /* Normal Case */ l_header_data_start = &(l_current_data); l_header_data = *l_header_data_start; l_remaining_length = p_src_data+p_max_length-l_header_data; l_modified_length_ptr = &(l_remaining_length); } bio_init_dec(l_bio, l_header_data,*l_modified_length_ptr); l_present = bio_read(l_bio, 1); if (!l_present) { bio_inalign(l_bio); l_header_data += bio_numbytes(l_bio); bio_destroy(l_bio); /* EPH markers */ if (p_tcp->csty & J2K_CP_CSTY_EPH) { if ((*l_header_data) != 0xff || (*(l_header_data + 1) != 0x92)) { printf("Error : expected EPH marker\n"); } else { l_header_data += 2; } } l_header_length = (l_header_data - *l_header_data_start); *l_modified_length_ptr -= l_header_length; *l_header_data_start += l_header_length; /* << INDEX */ // End of packet header position. Currently only represents the distance to start of packet // Will be updated later by incrementing with packet start value if (p_pack_info) { p_pack_info->end_ph_pos = (OPJ_INT32)(l_current_data - p_src_data); } /* INDEX >> */ * p_is_data_present = false; *p_data_read = l_current_data - p_src_data; return true; } l_band = l_res->bands; for (bandno = 0; bandno < l_res->numbands; ++bandno) { opj_tcd_precinct_t *l_prc = &(l_band->precincts[p_pi->precno]); if ((l_band->x1-l_band->x0 == 0)||(l_band->y1-l_band->y0 == 0)) { ++l_band; continue; } l_nb_code_blocks = l_prc->cw * l_prc->ch; l_cblk = l_prc->cblks.dec; for (cblkno = 0; cblkno < l_nb_code_blocks; cblkno++) { OPJ_UINT32 l_included,l_increment, l_segno; OPJ_INT32 n; /* if cblk not yet included before --> inclusion tagtree */ if (!l_cblk->numsegs) { l_included = tgt_decode(l_bio, l_prc->incltree, cblkno, p_pi->layno + 1); /* else one bit */ } else { l_included = bio_read(l_bio, 1); } /* if cblk not included */ if (!l_included) { l_cblk->numnewpasses = 0; ++l_cblk; continue; } /* if cblk not yet included --> zero-bitplane tagtree */ if (!l_cblk->numsegs) { OPJ_UINT32 i = 0; while (!tgt_decode(l_bio, l_prc->imsbtree, cblkno, i)) { ++i; } l_cblk->numbps = l_band->numbps + 1 - i; l_cblk->numlenbits = 3; } /* number of coding passes */ l_cblk->numnewpasses = t2_getnumpasses(l_bio); l_increment = t2_getcommacode(l_bio); /* length indicator increment */ l_cblk->numlenbits += l_increment; l_segno = 0; if (!l_cblk->numsegs) { if (! t2_init_seg(l_cblk, l_segno, p_tcp->tccps[p_pi->compno].cblksty, 1)) { bio_destroy(l_bio); return false; } } else { l_segno = l_cblk->numsegs - 1; if (l_cblk->segs[l_segno].numpasses == l_cblk->segs[l_segno].maxpasses) { ++l_segno; if (! t2_init_seg(l_cblk, l_segno, p_tcp->tccps[p_pi->compno].cblksty, 0)) { bio_destroy(l_bio); return false; } } } n = l_cblk->numnewpasses; do { l_cblk->segs[l_segno].numnewpasses = int_min(l_cblk->segs[l_segno].maxpasses - l_cblk->segs[l_segno].numpasses, n); l_cblk->segs[l_segno].newlen = bio_read(l_bio, l_cblk->numlenbits + uint_floorlog2(l_cblk->segs[l_segno].numnewpasses)); n -= l_cblk->segs[l_segno].numnewpasses; if (n > 0) { ++l_segno; if (! t2_init_seg(l_cblk, l_segno, p_tcp->tccps[p_pi->compno].cblksty, 0)) { bio_destroy(l_bio); return false; } } } while (n > 0); ++l_cblk; } ++l_band; } if (bio_inalign(l_bio)) { bio_destroy(l_bio); return false; } l_header_data += bio_numbytes(l_bio); bio_destroy(l_bio); /* EPH markers */ if (p_tcp->csty & J2K_CP_CSTY_EPH) { if ((*l_header_data) != 0xff || (*(l_header_data + 1) != 0x92)) { // TODO opj_event_msg(t2->cinfo->event_mgr, EVT_ERROR, "Expected EPH marker\n"); } else { l_header_data += 2; } } l_header_length = (l_header_data - *l_header_data_start); *l_modified_length_ptr -= l_header_length; *l_header_data_start += l_header_length; /* << INDEX */ // End of packet header position. Currently only represents the distance to start of packet // Will be updated later by incrementing with packet start value if (p_pack_info) { p_pack_info->end_ph_pos = (OPJ_INT32)(l_current_data - p_src_data); } /* INDEX >> */ * p_is_data_present = true; *p_data_read = l_current_data - p_src_data; return true; }
int t2_decode_packet(unsigned char *src, int len, tcd_tile_t *tile, j2k_tcp_t *tcp, int compno, int resno, int precno, int layno) { int bandno, cblkno; tcd_tilecomp_t *tilec=&tile->comps[compno]; tcd_resolution_t *res=&tilec->resolutions[resno]; unsigned char *c=src; int present; if (layno==0) { for (bandno=0; bandno<res->numbands; bandno++) { tcd_band_t *band=&res->bands[bandno]; tcd_precinct_t *prc=&band->precincts[precno]; tgt_reset(prc->incltree); tgt_reset(prc->imsbtree); for (cblkno=0; cblkno<prc->cw*prc->ch; cblkno++) { tcd_cblk_t *cblk=&prc->cblks[cblkno]; cblk->numsegs=0; } } } if (tcp->csty&J2K_CP_CSTY_SOP) { c+=6; } bio_init_dec(c, src+len-c); present=bio_read(1); if (!present) { bio_inalign(); c+=bio_numbytes(); return c-src; } for (bandno=0; bandno<res->numbands; bandno++) { tcd_band_t *band=&res->bands[bandno]; tcd_precinct_t *prc=&band->precincts[precno]; for (cblkno=0; cblkno<prc->cw*prc->ch; cblkno++) { int included, increment, n; tcd_cblk_t *cblk=&prc->cblks[cblkno]; tcd_seg_t *seg; if (!cblk->numsegs) { included=tgt_decode(prc->incltree, cblkno, layno+1); } else { included=bio_read(1); } if (!included) { cblk->numnewpasses=0; continue; } if (!cblk->numsegs) { int i, numimsbs; for (i=0; !tgt_decode(prc->imsbtree, cblkno, i); i++) {} numimsbs=i-1; cblk->numbps=band->numbps-numimsbs; cblk->numlenbits=3; } cblk->numnewpasses=t2_getnumpasses(); increment=t2_getcommacode(); cblk->numlenbits+=increment; if (!cblk->numsegs) { seg=&cblk->segs[0]; t2_init_seg(seg, tcp->tccps[compno].cblksty); } else { seg=&cblk->segs[cblk->numsegs-1]; if (seg->numpasses==seg->maxpasses) { t2_init_seg(++seg, tcp->tccps[compno].cblksty); } } n=cblk->numnewpasses; do { seg->numnewpasses=int_min(seg->maxpasses-seg->numpasses, n); seg->newlen=bio_read(cblk->numlenbits+int_floorlog2(seg->numnewpasses)); n-=seg->numnewpasses; if (n>0) { t2_init_seg(++seg, tcp->tccps[compno].cblksty); } } while (n>0); } } bio_inalign(); c+=bio_numbytes(); if (tcp->csty&J2K_CP_CSTY_EPH) { c+=2; } for (bandno=0; bandno<res->numbands; bandno++) { tcd_band_t *band=&res->bands[bandno]; tcd_precinct_t *prc=&band->precincts[precno]; for (cblkno=0; cblkno<prc->cw*prc->ch; cblkno++) { tcd_cblk_t *cblk=&prc->cblks[cblkno]; tcd_seg_t *seg; if (!cblk->numnewpasses) continue; if (!cblk->numsegs) { seg=&cblk->segs[cblk->numsegs++]; cblk->len=0; } else { seg=&cblk->segs[cblk->numsegs-1]; if (seg->numpasses==seg->maxpasses) { seg++; cblk->numsegs++; } } do { if (c+seg->newlen>src+len) longjmp(j2k_error, 1); memcpy(cblk->data+cblk->len, c, seg->newlen); if (seg->numpasses==0) { seg->data=cblk->data+cblk->len; } c+=seg->newlen; cblk->len+=seg->newlen; seg->len+=seg->newlen; seg->numpasses+=seg->numnewpasses; cblk->numnewpasses-=seg->numnewpasses; if (cblk->numnewpasses>0) { seg++; cblk->numsegs++; } } while (cblk->numnewpasses>0); } } return c-src; }