int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile) { unsigned char *c = src; opj_pi_iterator_t *pi; int pino, e = 0; int n = 0; opj_image_t *image = t2->image; opj_cp_t *cp = t2->cp; /* create a packet iterator */ pi = pi_create(image, cp, tileno); if(!pi) { /* TODO: throw an error */ return -999; } for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) { while (pi_next(&pi[pino])) { if ((cp->layer==0) || (cp->layer>=((pi[pino].layno)+1))) { e = t2_decode_packet(t2, c, src + len - c, tile, &cp->tcps[tileno], &pi[pino]); } else { e = 0; } /* progression in resolution */ image->comps[pi[pino].compno].resno_decoded = (e > 0) ? int_max(pi[pino].resno, image->comps[pi[pino].compno].resno_decoded) : image->comps[pi[pino].compno].resno_decoded; n++; if (e == -999) { /* ADD */ break; } else { c += e; } } } /* don't forget to release pi */ pi_destroy(pi, cp, tileno); if (e == -999) { return e; } return (c - src); }
int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile) { unsigned char *c = src; opj_pi_iterator_t *pi; int pino, e = 0; int n = 0,i; opj_volume_t *volume = t2->volume; opj_cp_t *cp = t2->cp; /* create a packet iterator */ pi = pi_create(volume, cp, tileno); if(!pi) { /* TODO: throw an error */ return -999; } for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) { while (pi_next(&pi[pino])) { if ((cp->layer==0) || (cp->layer>=((pi[pino].layno)+1))) { e = t2_decode_packet(t2, c, src + len - c, tile, &cp->tcps[tileno], &pi[pino]); } else { e = 0; } /* progression in resolution */ for (i = 0; i < 3; i++){ volume->comps[pi[pino].compno].resno_decoded[i] = (e > 0) ? int_max(pi[pino].resno, volume->comps[pi[pino].compno].resno_decoded[i]) : volume->comps[pi[pino].compno].resno_decoded[i]; } n++; if (e == -999) { /* ADD */ break; } else { opj_event_msg(t2->cinfo, EVT_INFO, " t2_decode_packet: %d bytes decoded\n",e); c += e; } } } /* don't forget to release pi */ pi_destroy(pi, cp, tileno); if (e == -999) { return e; } return (c - src); }
int 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) { unsigned char *c = src; opj_pi_iterator_t *pi; int pino, e = 0; int n = 0, curtp = 0; int tp_start_packno; opj_image_t *image = t2->image; opj_cp_t *cp = t2->cp; /* create a packet iterator */ pi = pi_create_decode(image, cp, tileno); if(!pi) { /* TODO: throw an error */ return -999; } tp_start_packno = 0; for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) { while (pi_next(&pi[pino])) { if ((cp->layer==0) || (cp->layer>=((pi[pino].layno)+1))) { opj_packet_info_t *pack_info; if (cstr_info) pack_info = &cstr_info->tile[tileno].packet[cstr_info->packno]; else pack_info = NULL; e = t2_decode_packet(t2, c, src + len - c, tile, &cp->tcps[tileno], &pi[pino], pack_info); } else { e = 0; } if(e == -999) return -999; /* progression in resolution */ image->comps[pi[pino].compno].resno_decoded = (e > 0) ? int_max(pi[pino].resno, image->comps[pi[pino].compno].resno_decoded) : image->comps[pi[pino].compno].resno_decoded; n++; /* INDEX >> */ if(cstr_info) { opj_tile_info_t *info_TL = &cstr_info->tile[tileno]; opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->packno]; if (!cstr_info->packno) { info_PK->start_pos = info_TL->end_header + 1; } else if (info_TL->packet[cstr_info->packno-1].end_pos >= (int)cstr_info->tile[tileno].tp[curtp].tp_end_pos){ /* New tile part*/ info_TL->tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; /* Number of packets in previous tile-part*/ info_TL->tp[curtp].tp_start_pack = tp_start_packno; tp_start_packno = cstr_info->packno; curtp++; info_PK->start_pos = cstr_info->tile[tileno].tp[curtp].tp_end_header+1; } else { 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; } info_PK->end_pos = info_PK->start_pos + e - 1; info_PK->end_ph_pos += info_PK->start_pos - 1; /* End of packet header which now only represents the distance // to start of packet is incremented by value of start of packet*/ cstr_info->packno++; } /* << INDEX */ if (e == -999) { /* ADD */ break; } else { c += e; } } } /* INDEX >> */ if(cstr_info) { cstr_info->tile[tileno].tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; /* Number of packets in last tile-part*/ cstr_info->tile[tileno].tp[curtp].tp_start_pack = tp_start_packno; } /* << INDEX */ /* don't forget to release pi */ pi_destroy(pi, cp, tileno); if (e == -999) { return e; } return (c - src); }
int 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){ unsigned char *c = dest; int e = 0; int compno; opj_pi_iterator_t *pi = NULL; int poc; opj_image_t *image = t2->image; opj_cp_t *cp = t2->cp; opj_tcp_t *tcp = &cp->tcps[tileno]; int pocno = cp->cinema == CINEMA4K_24? 2: 1; int maxcomp = cp->max_comp_size > 0 ? image->numcomps : 1; pi = pi_initialise_encode(image, cp, tileno, t2_mode); if(!pi) { /* TODO: throw an error */ return -999; } if(t2_mode == THRESH_CALC ){ /* Calculating threshold */ for(compno = 0; compno < maxcomp; compno++ ){ for(poc = 0; poc < pocno ; poc++){ int comp_len = 0; int tpnum = compno; if (pi_create_encode(pi, cp,tileno,poc,tpnum,tppos,t2_mode,cur_totnum_tp)) { opj_event_msg(t2->cinfo, EVT_ERROR, "Error initializing Packet Iterator\n"); pi_destroy(pi, cp, tileno); return -999; } while (pi_next(&pi[poc])) { if (pi[poc].layno < maxlayers) { e = t2_encode_packet(tile, &cp->tcps[tileno], &pi[poc], c, dest + len - c, cstr_info, tileno); comp_len = comp_len + e; if (e == -999) { break; } else { c += e; } } } if (e == -999) break; if (cp->max_comp_size){ if (comp_len > cp->max_comp_size){ e = -999; break; } } } if (e == -999) break; } }else{ /* t2_mode == FINAL_PASS */ pi_create_encode(pi, cp,tileno,pino,tpnum,tppos,t2_mode,cur_totnum_tp); while (pi_next(&pi[pino])) { if (pi[pino].layno < maxlayers) { e = t2_encode_packet(tile, &cp->tcps[tileno], &pi[pino], c, dest + len - c, cstr_info, tileno); if (e == -999) { break; } else { c += e; } /* INDEX >> */ if(cstr_info) { if(cstr_info->index_write) { opj_tile_info_t *info_TL = &cstr_info->tile[tileno]; opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->packno]; if (!cstr_info->packno) { info_PK->start_pos = info_TL->end_header + 1; } else { 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; } info_PK->end_pos = info_PK->start_pos + e - 1; info_PK->end_ph_pos += info_PK->start_pos - 1; /* End of packet header which now only represents the distance // to start of packet is incremented by value of start of packet*/ } cstr_info->packno++; } /* << INDEX */ tile->packno++; } } } pi_destroy(pi, cp, tileno); if (e == -999) { return e; } return (c - dest); }
bool t2_decode_packets( opj_t2_t *p_t2, OPJ_UINT32 p_tile_no, struct opj_tcd_tile *p_tile, OPJ_BYTE *p_src, OPJ_UINT32 * p_data_read, OPJ_UINT32 p_max_len, struct opj_codestream_info *p_cstr_info) { OPJ_BYTE *l_current_data = p_src; opj_pi_iterator_t *l_pi = 00; OPJ_UINT32 pino; opj_image_t *l_image = p_t2->image; opj_cp_t *l_cp = p_t2->cp; opj_cp_t *cp = p_t2->cp; opj_tcp_t *l_tcp = &(p_t2->cp->tcps[p_tile_no]); OPJ_UINT32 l_nb_bytes_read; OPJ_UINT32 l_nb_pocs = l_tcp->numpocs + 1; opj_pi_iterator_t *l_current_pi = 00; OPJ_UINT32 curtp = 0; OPJ_UINT32 tp_start_packno; opj_packet_info_t *l_pack_info = 00; opj_image_comp_t* l_img_comp = 00; if (p_cstr_info) { l_pack_info = p_cstr_info->tile[p_tile_no].packet; } /* create a packet iterator */ l_pi = pi_create_decode(l_image, l_cp, p_tile_no); if (!l_pi) { return false; } tp_start_packno = 0; l_current_pi = l_pi; for (pino = 0; pino <= l_tcp->numpocs; ++pino) { while (pi_next(l_current_pi)) { if (l_tcp->num_layers_to_decode > l_current_pi->layno && l_current_pi->resno < p_tile->comps[l_current_pi->compno].minimum_num_resolutions) { l_nb_bytes_read = 0; if (! t2_decode_packet(p_t2,p_tile,l_tcp,l_current_pi,l_current_data,&l_nb_bytes_read,p_max_len,l_pack_info)) { pi_destroy(l_pi,l_nb_pocs); return false; } l_img_comp = &(l_image->comps[l_current_pi->compno]); l_img_comp->resno_decoded = uint_max(l_current_pi->resno, l_img_comp->resno_decoded); } else { l_nb_bytes_read = 0; if (! t2_skip_packet(p_t2,p_tile,l_tcp,l_current_pi,l_current_data,&l_nb_bytes_read,p_max_len,l_pack_info)) { pi_destroy(l_pi,l_nb_pocs); return false; } } l_current_data += l_nb_bytes_read; p_max_len -= l_nb_bytes_read; /* INDEX >> */ if(p_cstr_info) { opj_tile_info_t *info_TL = &p_cstr_info->tile[p_tile_no]; opj_packet_info_t *info_PK = &info_TL->packet[p_cstr_info->packno]; if (!p_cstr_info->packno) { info_PK->start_pos = info_TL->end_header + 1; } else if (info_TL->packet[p_cstr_info->packno-1].end_pos >= (OPJ_INT32)p_cstr_info->tile[p_tile_no].tp[curtp].tp_end_pos){ // New tile part info_TL->tp[curtp].tp_numpacks = p_cstr_info->packno - tp_start_packno; // Number of packets in previous tile-part tp_start_packno = p_cstr_info->packno; curtp++; info_PK->start_pos = p_cstr_info->tile[p_tile_no].tp[curtp].tp_end_header+1; } else { info_PK->start_pos = (cp->m_specific_param.m_enc.m_tp_on && info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[p_cstr_info->packno - 1].end_pos + 1; } info_PK->end_pos = info_PK->start_pos + l_nb_bytes_read - 1; info_PK->end_ph_pos += info_PK->start_pos - 1; // End of packet header which now only represents the distance ++p_cstr_info->packno; } /* << INDEX */ } ++l_current_pi; } /* INDEX >> */ if (p_cstr_info) { p_cstr_info->tile[p_tile_no].tp[curtp].tp_numpacks = p_cstr_info->packno - tp_start_packno; // Number of packets in last tile-part } /* << INDEX */ /* don't forget to release pi */ pi_destroy(l_pi,l_nb_pocs); *p_data_read = l_current_data - p_src; return true; }
bool t2_encode_packets( opj_t2_t* p_t2, OPJ_UINT32 p_tile_no, opj_tcd_tile_t *p_tile, OPJ_UINT32 p_maxlayers, OPJ_BYTE *p_dest, OPJ_UINT32 * p_data_written, OPJ_UINT32 p_max_len, opj_codestream_info_t *cstr_info, OPJ_UINT32 p_tp_num, OPJ_INT32 p_tp_pos, OPJ_UINT32 p_pino, J2K_T2_MODE p_t2_mode) { OPJ_BYTE *l_current_data = p_dest; OPJ_UINT32 l_nb_bytes = 0; OPJ_UINT32 compno; OPJ_UINT32 poc; opj_pi_iterator_t *l_pi = 00; opj_pi_iterator_t *l_current_pi = 00; opj_image_t *l_image = p_t2->image; opj_cp_t *l_cp = p_t2->cp; opj_tcp_t *l_tcp = &l_cp->tcps[p_tile_no]; OPJ_UINT32 pocno = l_cp->m_specific_param.m_enc.m_cinema == CINEMA4K_24? 2: 1; OPJ_UINT32 l_max_comp = l_cp->m_specific_param.m_enc.m_max_comp_size > 0 ? l_image->numcomps : 1; OPJ_UINT32 l_nb_pocs = l_tcp->numpocs + 1; l_pi = pi_initialise_encode(l_image, l_cp, p_tile_no, p_t2_mode); if (!l_pi) { return false; } * p_data_written = 0; if (p_t2_mode == THRESH_CALC ) { /* Calculating threshold */ l_current_pi = l_pi; for (compno = 0; compno < l_max_comp; ++compno) { OPJ_UINT32 l_comp_len = 0; l_current_pi = l_pi; for (poc = 0; poc < pocno ; ++poc) { OPJ_UINT32 l_tp_num = compno; pi_create_encode(l_pi, l_cp,p_tile_no,poc,l_tp_num,p_tp_pos,p_t2_mode); while (pi_next(l_current_pi)) { if (l_current_pi->layno < p_maxlayers) { l_nb_bytes = 0; if (! t2_encode_packet(p_tile_no,p_tile, l_tcp, l_current_pi, l_current_data, &l_nb_bytes, p_max_len, cstr_info)) { pi_destroy(l_pi, l_nb_pocs); return false; } l_comp_len += l_nb_bytes; l_current_data += l_nb_bytes; p_max_len -= l_nb_bytes; * p_data_written += l_nb_bytes; } } if (l_cp->m_specific_param.m_enc.m_max_comp_size) { if (l_comp_len > l_cp->m_specific_param.m_enc.m_max_comp_size) { pi_destroy(l_pi, l_nb_pocs); return false; } } ++l_current_pi; } } } else { /* t2_mode == FINAL_PASS */ pi_create_encode(l_pi, l_cp,p_tile_no,p_pino,p_tp_num,p_tp_pos,p_t2_mode); l_current_pi = &l_pi[p_pino]; while (pi_next(l_current_pi)) { if (l_current_pi->layno < p_maxlayers) { l_nb_bytes=0; if (! t2_encode_packet(p_tile_no,p_tile, l_tcp, l_current_pi, l_current_data, &l_nb_bytes, p_max_len, cstr_info)) { pi_destroy(l_pi, l_nb_pocs); return false; } l_current_data += l_nb_bytes; p_max_len -= l_nb_bytes; * p_data_written += l_nb_bytes; /* INDEX >> */ if(cstr_info) { if(cstr_info->index_write) { opj_tile_info_t *info_TL = &cstr_info->tile[p_tile_no]; opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->packno]; if (!cstr_info->packno) { info_PK->start_pos = info_TL->end_header + 1; } else { info_PK->start_pos = ((l_cp->m_specific_param.m_enc.m_tp_on | l_tcp->POC)&& info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno - 1].end_pos + 1; } info_PK->end_pos = info_PK->start_pos + l_nb_bytes - 1; info_PK->end_ph_pos += info_PK->start_pos - 1; // End of packet header which now only represents the distance // to start of packet is incremented by value of start of packet } cstr_info->packno++; } /* << INDEX */ ++p_tile->packno; } } } pi_destroy(l_pi, l_nb_pocs); return true; }
opj_pi_iterator_t *pi_initialise_encode(opj_image_t *image, opj_cp_t *cp, int tileno, J2K_T2_MODE t2_mode){ int p, q, pino; int compno, resno; int maxres = 0; int maxprec = 0; opj_pi_iterator_t *pi = NULL; opj_tcp_t *tcp = NULL; opj_tccp_t *tccp = NULL; size_t array_size; tcp = &cp->tcps[tileno]; array_size = (tcp->numpocs + 1) * sizeof(opj_pi_iterator_t); pi = (opj_pi_iterator_t *) opj_malloc(array_size); if(!pi) { return NULL;} pi->tp_on = cp->tp_on; for(pino = 0;pino < tcp->numpocs+1 ; pino ++){ p = tileno % cp->tw; q = tileno / cp->tw; pi[pino].tx0 = int_max(cp->tx0 + p * cp->tdx, image->x0); pi[pino].ty0 = int_max(cp->ty0 + q * cp->tdy, image->y0); pi[pino].tx1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1); pi[pino].ty1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1); pi[pino].numcomps = image->numcomps; array_size = image->numcomps * sizeof(opj_pi_comp_t); pi[pino].comps = (opj_pi_comp_t *) opj_malloc(array_size); if(!pi[pino].comps) { pi_destroy(pi, cp, tileno); return NULL; } memset(pi[pino].comps, 0, array_size); for (compno = 0; compno < pi[pino].numcomps; compno++) { int tcx0, tcy0, tcx1, tcy1; opj_pi_comp_t *comp = &pi[pino].comps[compno]; tccp = &tcp->tccps[compno]; comp->dx = image->comps[compno].dx; comp->dy = image->comps[compno].dy; comp->numresolutions = tccp->numresolutions; array_size = comp->numresolutions * sizeof(opj_pi_resolution_t); comp->resolutions = (opj_pi_resolution_t *) opj_malloc(array_size); if(!comp->resolutions) { pi_destroy(pi, cp, tileno); return NULL; } tcx0 = int_ceildiv(pi[pino].tx0, comp->dx); tcy0 = int_ceildiv(pi[pino].ty0, comp->dy); tcx1 = int_ceildiv(pi[pino].tx1, comp->dx); tcy1 = int_ceildiv(pi[pino].ty1, comp->dy); if (comp->numresolutions > maxres) { maxres = comp->numresolutions; } for (resno = 0; resno < comp->numresolutions; resno++) { int levelno; int rx0, ry0, rx1, ry1; int px0, py0, px1, py1; opj_pi_resolution_t *res = &comp->resolutions[resno]; if (tccp->csty & J2K_CCP_CSTY_PRT) { res->pdx = tccp->prcw[resno]; res->pdy = tccp->prch[resno]; } else { res->pdx = 15; res->pdy = 15; } levelno = comp->numresolutions - 1 - resno; rx0 = int_ceildivpow2(tcx0, levelno); ry0 = int_ceildivpow2(tcy0, levelno); rx1 = int_ceildivpow2(tcx1, levelno); ry1 = int_ceildivpow2(tcy1, levelno); px0 = int_floordivpow2(rx0, res->pdx) << res->pdx; py0 = int_floordivpow2(ry0, res->pdy) << res->pdy; px1 = int_ceildivpow2(rx1, res->pdx) << res->pdx; py1 = int_ceildivpow2(ry1, res->pdy) << res->pdy; res->pw = (rx0==rx1)?0:((px1 - px0) >> res->pdx); res->ph = (ry0==ry1)?0:((py1 - py0) >> res->pdy); if (res->pw*res->ph > maxprec) { maxprec = res->pw * res->ph; } } } tccp = &tcp->tccps[0]; pi[pino].step_p = 1; pi[pino].step_c = maxprec * pi[pino].step_p; pi[pino].step_r = image->numcomps * pi[pino].step_c; pi[pino].step_l = maxres * pi[pino].step_r; for (compno = 0; compno < pi->numcomps; compno++) { opj_pi_comp_t *comp = &pi->comps[compno]; for (resno = 0; resno < comp->numresolutions; resno++) { int dx, dy; opj_pi_resolution_t *res = &comp->resolutions[resno]; dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno)); dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno)); pi[pino].dx = !pi->dx ? dx : int_min(pi->dx, dx); pi[pino].dy = !pi->dy ? dy : int_min(pi->dy, dy); } } if (pino == 0) { array_size = tcp->numlayers * pi[pino].step_l * sizeof(short int); pi[pino].include = (short int *) opj_malloc(array_size); if(!pi[pino].include) { pi_destroy(pi, cp, tileno); return NULL; } } else { pi[pino].include = pi[pino - 1].include; } /* Generation of boundaries for each prog flag*/ if(tcp->POC & (t2_mode == FINAL_PASS)){ tcp->pocs[pino].compS= tcp->pocs[pino].compno0; tcp->pocs[pino].compE= tcp->pocs[pino].compno1; tcp->pocs[pino].resS = tcp->pocs[pino].resno0; tcp->pocs[pino].resE = tcp->pocs[pino].resno1; tcp->pocs[pino].layE = tcp->pocs[pino].layno1; tcp->pocs[pino].prg = tcp->pocs[pino].prg1; if (pino > 0) tcp->pocs[pino].layS = (tcp->pocs[pino].layE > tcp->pocs[pino - 1].layE) ? tcp->pocs[pino - 1].layE : 0; }else { tcp->pocs[pino].compS= 0; tcp->pocs[pino].compE= image->numcomps; tcp->pocs[pino].resS = 0; tcp->pocs[pino].resE = maxres; tcp->pocs[pino].layS = 0; tcp->pocs[pino].layE = tcp->numlayers; tcp->pocs[pino].prg = tcp->prg; } tcp->pocs[pino].prcS = 0; tcp->pocs[pino].prcE = maxprec;; tcp->pocs[pino].txS = pi[pino].tx0; tcp->pocs[pino].txE = pi[pino].tx1; tcp->pocs[pino].tyS = pi[pino].ty0; tcp->pocs[pino].tyE = pi[pino].ty1; tcp->pocs[pino].dx = pi[pino].dx; tcp->pocs[pino].dy = pi[pino].dy; } return pi; }
opj_pi_iterator_t *pi_create_decode(opj_image_t *image, opj_cp_t *cp, int tileno) { int p, q; int compno, resno, pino; opj_pi_iterator_t *pi = NULL; opj_tcp_t *tcp = NULL; opj_tccp_t *tccp = NULL; size_t array_size; tcp = &cp->tcps[tileno]; array_size = (tcp->numpocs + 1) * sizeof(opj_pi_iterator_t); pi = (opj_pi_iterator_t *) opj_malloc(array_size); if(!pi) { /* TODO: throw an error */ return NULL; } for (pino = 0; pino < tcp->numpocs + 1; pino++) { /* change */ int maxres = 0; int maxprec = 0; p = tileno % cp->tw; q = tileno / cp->tw; pi[pino].tx0 = int_max(cp->tx0 + p * cp->tdx, image->x0); pi[pino].ty0 = int_max(cp->ty0 + q * cp->tdy, image->y0); pi[pino].tx1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1); pi[pino].ty1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1); pi[pino].numcomps = image->numcomps; array_size = image->numcomps * sizeof(opj_pi_comp_t); pi[pino].comps = (opj_pi_comp_t *) opj_malloc(array_size); if(!pi[pino].comps) { /* TODO: throw an error */ pi_destroy(pi, cp, tileno); return NULL; } memset(pi[pino].comps, 0, array_size); for (compno = 0; compno < pi->numcomps; compno++) { int tcx0, tcy0, tcx1, tcy1; opj_pi_comp_t *comp = &pi[pino].comps[compno]; tccp = &tcp->tccps[compno]; comp->dx = image->comps[compno].dx; comp->dy = image->comps[compno].dy; comp->numresolutions = tccp->numresolutions; array_size = comp->numresolutions * sizeof(opj_pi_resolution_t); comp->resolutions = (opj_pi_resolution_t *) opj_malloc(array_size); if(!comp->resolutions) { /* TODO: throw an error */ pi_destroy(pi, cp, tileno); return NULL; } tcx0 = int_ceildiv(pi->tx0, comp->dx); tcy0 = int_ceildiv(pi->ty0, comp->dy); tcx1 = int_ceildiv(pi->tx1, comp->dx); tcy1 = int_ceildiv(pi->ty1, comp->dy); if (comp->numresolutions > maxres) { maxres = comp->numresolutions; } for (resno = 0; resno < comp->numresolutions; resno++) { int levelno; int rx0, ry0, rx1, ry1; int px0, py0, px1, py1; opj_pi_resolution_t *res = &comp->resolutions[resno]; if (tccp->csty & J2K_CCP_CSTY_PRT) { res->pdx = tccp->prcw[resno]; res->pdy = tccp->prch[resno]; } else { res->pdx = 15; res->pdy = 15; } levelno = comp->numresolutions - 1 - resno; rx0 = int_ceildivpow2(tcx0, levelno); ry0 = int_ceildivpow2(tcy0, levelno); rx1 = int_ceildivpow2(tcx1, levelno); ry1 = int_ceildivpow2(tcy1, levelno); px0 = int_floordivpow2(rx0, res->pdx) << res->pdx; py0 = int_floordivpow2(ry0, res->pdy) << res->pdy; px1 = int_ceildivpow2(rx1, res->pdx) << res->pdx; py1 = int_ceildivpow2(ry1, res->pdy) << res->pdy; res->pw = (rx0==rx1)?0:((px1 - px0) >> res->pdx); res->ph = (ry0==ry1)?0:((py1 - py0) >> res->pdy); if (res->pw*res->ph > maxprec) { maxprec = res->pw*res->ph; } } } tccp = &tcp->tccps[0]; pi[pino].step_p = 1; pi[pino].step_c = maxprec * pi[pino].step_p; pi[pino].step_r = image->numcomps * pi[pino].step_c; pi[pino].step_l = maxres * pi[pino].step_r; if (pino == 0) { array_size = image->numcomps * maxres * tcp->numlayers * maxprec * sizeof(short int); pi[pino].include = (short int *) opj_malloc(array_size); if(!pi[pino].include) { /* TODO: throw an error */ pi_destroy(pi, cp, tileno); return NULL; } } else { pi[pino].include = pi[pino - 1].include; } if (tcp->POC == 0) { pi[pino].first = 1; pi[pino].poc.resno0 = 0; pi[pino].poc.compno0 = 0; pi[pino].poc.layno1 = tcp->numlayers; pi[pino].poc.resno1 = maxres; pi[pino].poc.compno1 = image->numcomps; pi[pino].poc.prg = tcp->prg; } else { pi[pino].first = 1; pi[pino].poc.resno0 = tcp->pocs[pino].resno0; pi[pino].poc.compno0 = tcp->pocs[pino].compno0; pi[pino].poc.layno1 = tcp->pocs[pino].layno1; pi[pino].poc.resno1 = tcp->pocs[pino].resno1; pi[pino].poc.compno1 = tcp->pocs[pino].compno1; pi[pino].poc.prg = tcp->pocs[pino].prg; } pi[pino].poc.layno0 = 0; pi[pino].poc.precno0 = 0; pi[pino].poc.precno1 = maxprec; } return pi; }
opj_pi_iterator_t *pi_create(opj_volume_t *volume, opj_cp_t *cp, int tileno) { int p, q, r; int compno, resno, pino; opj_pi_iterator_t *pi = NULL; opj_tcp_t *tcp = NULL; opj_tccp_t *tccp = NULL; size_t array_size; tcp = &cp->tcps[tileno]; array_size = (tcp->numpocs + 1) * sizeof(opj_pi_iterator_t); pi = (opj_pi_iterator_t *) opj_malloc(array_size); if(!pi) { fprintf(stdout,"[ERROR] Malloc of opj_pi_iterator failed \n"); return NULL; } for (pino = 0; pino < tcp->numpocs + 1; pino++) { /* change */ int maxres = 0; int maxprec = 0; p = tileno % cp->tw; q = tileno / cp->tw; r = tileno / (cp->tw * cp->th); pi[pino].tx0 = int_max(cp->tx0 + p * cp->tdx, volume->x0); pi[pino].ty0 = int_max(cp->ty0 + q * cp->tdy, volume->y0); pi[pino].tz0 = int_max(cp->tz0 + r * cp->tdz, volume->z0); pi[pino].tx1 = int_min(cp->tx0 + (p + 1) * cp->tdx, volume->x1); pi[pino].ty1 = int_min(cp->ty0 + (q + 1) * cp->tdy, volume->y1); pi[pino].tz1 = int_min(cp->tz0 + (r + 1) * cp->tdz, volume->z1); pi[pino].numcomps = volume->numcomps; array_size = volume->numcomps * sizeof(opj_pi_comp_t); pi[pino].comps = (opj_pi_comp_t *) opj_malloc(array_size); if(!pi[pino].comps) { fprintf(stdout,"[ERROR] Malloc of opj_pi_comp failed \n"); pi_destroy(pi, cp, tileno); return NULL; } memset(pi[pino].comps, 0, array_size); for (compno = 0; compno < pi->numcomps; compno++) { int tcx0, tcx1, tcy0, tcy1, tcz0, tcz1; int i; opj_pi_comp_t *comp = &pi[pino].comps[compno]; tccp = &tcp->tccps[compno]; comp->dx = volume->comps[compno].dx; comp->dy = volume->comps[compno].dy; comp->dz = volume->comps[compno].dz; for (i = 0; i < 3; i++) { comp->numresolution[i] = tccp->numresolution[i]; if (comp->numresolution[i] > maxres) { maxres = comp->numresolution[i]; } } array_size = comp->numresolution[0] * sizeof(opj_pi_resolution_t); comp->resolutions = (opj_pi_resolution_t *) opj_malloc(array_size); if(!comp->resolutions) { fprintf(stdout,"[ERROR] Malloc of opj_pi_resolution failed \n"); pi_destroy(pi, cp, tileno); return NULL; } tcx0 = int_ceildiv(pi->tx0, comp->dx); tcy0 = int_ceildiv(pi->ty0, comp->dy); tcz0 = int_ceildiv(pi->tz0, comp->dz); tcx1 = int_ceildiv(pi->tx1, comp->dx); tcy1 = int_ceildiv(pi->ty1, comp->dy); tcz1 = int_ceildiv(pi->tz1, comp->dz); for (resno = 0; resno < comp->numresolution[0]; resno++) { int levelnox, levelnoy, levelnoz, diff; int rx0, ry0, rz0, rx1, ry1, rz1; int px0, py0, pz0, px1, py1, pz1; opj_pi_resolution_t *res = &comp->resolutions[resno]; if (tccp->csty & J3D_CCP_CSTY_PRT) { res->pdx = tccp->prctsiz[0][resno]; res->pdy = tccp->prctsiz[1][resno]; res->pdz = tccp->prctsiz[2][resno]; } else { res->pdx = 15; res->pdy = 15; res->pdz = 15; } levelnox = comp->numresolution[0] - 1 - resno; levelnoy = comp->numresolution[1] - 1 - resno; levelnoz = comp->numresolution[2] - 1 - resno; if (levelnoz < 0) levelnoz = 0; diff = comp->numresolution[0] - comp->numresolution[2]; rx0 = int_ceildivpow2(tcx0, levelnox); ry0 = int_ceildivpow2(tcy0, levelnoy); rz0 = int_ceildivpow2(tcz0, levelnoz); rx1 = int_ceildivpow2(tcx1, levelnox); ry1 = int_ceildivpow2(tcy1, levelnoy); rz1 = int_ceildivpow2(tcz1, levelnoz); px0 = int_floordivpow2(rx0, res->pdx) << res->pdx; py0 = int_floordivpow2(ry0, res->pdy) << res->pdy; pz0 = int_floordivpow2(rz0, res->pdz) << res->pdz; px1 = int_ceildivpow2(rx1, res->pdx) << res->pdx; py1 = int_ceildivpow2(ry1, res->pdy) << res->pdy; pz1 = int_ceildivpow2(rz1, res->pdz) << res->pdz; res->prctno[0] = (rx0==rx1)? 0 : ((px1 - px0) >> res->pdx); res->prctno[1] = (ry0==ry1)? 0 : ((py1 - py0) >> res->pdy); res->prctno[2] = (rz0==rz1)? 0 : ((pz1 - pz0) >> res->pdz); if (res->prctno[0]*res->prctno[1]*res->prctno[2] > maxprec) { maxprec = res->prctno[0]*res->prctno[1]*res->prctno[2]; } } } tccp = &tcp->tccps[0]; pi[pino].step_p = 1; pi[pino].step_c = maxprec * pi[pino].step_p; pi[pino].step_r = volume->numcomps * pi[pino].step_c; pi[pino].step_l = maxres * pi[pino].step_r; if (pino == 0) { array_size = volume->numcomps * maxres * tcp->numlayers * maxprec * sizeof(short int); pi[pino].include = (short int *) opj_malloc(array_size); if(!pi[pino].include) { fprintf(stdout,"[ERROR] Malloc of pi[pino].include failed \n"); pi_destroy(pi, cp, tileno); return NULL; } } else { pi[pino].include = pi[pino - 1].include; } if (tcp->POC == 0) { pi[pino].first = 1; pi[pino].poc.resno0 = 0; pi[pino].poc.compno0 = 0; pi[pino].poc.layno1 = tcp->numlayers; pi[pino].poc.resno1 = maxres; pi[pino].poc.compno1 = volume->numcomps; pi[pino].poc.prg = tcp->prg; } else { pi[pino].first = 1; pi[pino].poc.resno0 = tcp->pocs[pino].resno0; pi[pino].poc.compno0 = tcp->pocs[pino].compno0; pi[pino].poc.layno1 = tcp->pocs[pino].layno1; pi[pino].poc.resno1 = tcp->pocs[pino].resno1; pi[pino].poc.compno1 = tcp->pocs[pino].compno1; pi[pino].poc.prg = tcp->pocs[pino].prg; } } return pi; }