📄 jpc_dec.c
字号:
for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
++compno, ++tcomp) {
for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno < tcomp->numrlvls;
++rlvlno, ++rlvl) {
if (!rlvl->bands) {
continue;
}
for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands; ++bandno, ++band) {
if (band->prcs) {
for (prcno = 0, prc = band->prcs; prcno <
rlvl->numprcs; ++prcno, ++prc) {
if (!prc->cblks) {
continue;
}
for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks; ++cblkno, ++cblk) {
while (cblk->segs.head) {
seg = cblk->segs.head;
jpc_seglist_remove(&cblk->segs, seg);
jpc_seg_destroy(seg);
}
jas_matrix_destroy(cblk->data);
if (cblk->mqdec) {
jpc_mqdec_destroy(cblk->mqdec);
}
if (cblk->nulldec) {
jpc_bitstream_close(cblk->nulldec);
}
if (cblk->flags) {
jas_matrix_destroy(cblk->flags);
}
}
if (prc->incltagtree) {
jpc_tagtree_destroy(prc->incltagtree);
}
if (prc->numimsbstagtree) {
jpc_tagtree_destroy(prc->numimsbstagtree);
}
if (prc->cblks) {
jas_free(prc->cblks);
}
}
}
if (band->data) {
jas_matrix_destroy(band->data);
}
if (band->prcs) {
jas_free(band->prcs);
}
}
if (rlvl->bands) {
jas_free(rlvl->bands);
}
}
if (tcomp->rlvls) {
jas_free(tcomp->rlvls);
}
if (tcomp->data) {
jas_matrix_destroy(tcomp->data);
}
if (tcomp->tsfb) {
jpc_tsfb_destroy(tcomp->tsfb);
}
}
}
if (tile->cp) {
jpc_dec_cp_destroy(tile->cp);
tile->cp = 0;
}
if (tile->tcomps) {
jas_free(tile->tcomps);
tile->tcomps = 0;
}
if (tile->pi) {
jpc_pi_destroy(tile->pi);
tile->pi = 0;
}
if (tile->pkthdrstream) {
jas_stream_close(tile->pkthdrstream);
tile->pkthdrstream = 0;
}
if (tile->pptstab) {
jpc_ppxstab_destroy(tile->pptstab);
tile->pptstab = 0;
}
tile->state = JPC_TILE_DONE;
return 0;
}
static int jpc_dec_tiledecode(jpc_dec_t *dec, jpc_dec_tile_t *tile)
{
int i;
int j;
jpc_dec_tcomp_t *tcomp;
jpc_dec_rlvl_t *rlvl;
jpc_dec_band_t *band;
int compno;
int rlvlno;
int bandno;
int adjust;
int v;
jpc_dec_ccp_t *ccp;
jpc_dec_cmpt_t *cmpt;
if (jpc_dec_decodecblks(dec, tile)) {
jas_eprintf("jpc_dec_decodecblks failed\n");
return -1;
}
/* Perform dequantization. */
for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
++compno, ++tcomp) {
ccp = &tile->cp->ccps[compno];
for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno < tcomp->numrlvls;
++rlvlno, ++rlvl) {
if (!rlvl->bands) {
continue;
}
for (bandno = 0, band = rlvl->bands;
bandno < rlvl->numbands; ++bandno, ++band) {
if (!band->data) {
continue;
}
jpc_undo_roi(band->data, band->roishift, ccp->roishift -
band->roishift, band->numbps);
if (tile->realmode) {
jas_matrix_asl(band->data, JPC_FIX_FRACBITS);
jpc_dequantize(band->data, band->absstepsize);
}
}
}
}
/* Apply an inverse wavelet transform if necessary. */
for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
++compno, ++tcomp) {
ccp = &tile->cp->ccps[compno];
jpc_tsfb_synthesize(tcomp->tsfb, tcomp->data);
}
/* Apply an inverse intercomponent transform if necessary. */
switch (tile->cp->mctid) {
case JPC_MCT_RCT:
assert(dec->numcomps == 3);
jpc_irct(tile->tcomps[0].data, tile->tcomps[1].data,
tile->tcomps[2].data);
break;
case JPC_MCT_ICT:
assert(dec->numcomps == 3);
jpc_iict(tile->tcomps[0].data, tile->tcomps[1].data,
tile->tcomps[2].data);
break;
}
/* Perform rounding and convert to integer values. */
if (tile->realmode) {
for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
++compno, ++tcomp) {
for (i = 0; i < jas_matrix_numrows(tcomp->data); ++i) {
for (j = 0; j < jas_matrix_numcols(tcomp->data); ++j) {
v = jas_matrix_get(tcomp->data, i, j);
v = jpc_fix_round(v);
jas_matrix_set(tcomp->data, i, j, jpc_fixtoint(v));
}
}
}
}
/* Perform level shift. */
for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno <
dec->numcomps; ++compno, ++tcomp, ++cmpt) {
adjust = cmpt->sgnd ? 0 : (1 << (cmpt->prec - 1));
for (i = 0; i < jas_matrix_numrows(tcomp->data); ++i) {
for (j = 0; j < jas_matrix_numcols(tcomp->data); ++j) {
*jas_matrix_getref(tcomp->data, i, j) += adjust;
}
}
}
/* Perform clipping. */
for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno <
dec->numcomps; ++compno, ++tcomp, ++cmpt) {
jpc_fix_t mn;
jpc_fix_t mx;
mn = cmpt->sgnd ? (-(1 << (cmpt->prec - 1))) : (0);
mx = cmpt->sgnd ? ((1 << (cmpt->prec - 1)) - 1) : ((1 <<
cmpt->prec) - 1);
jas_matrix_clip(tcomp->data, mn, mx);
}
/* XXX need to free tsfb struct */
/* Write the data for each component of the image. */
for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno <
dec->numcomps; ++compno, ++tcomp, ++cmpt) {
if (jas_image_writecmpt(dec->image, compno, tcomp->xstart -
JPC_CEILDIV(dec->xstart, cmpt->hstep), tcomp->ystart -
JPC_CEILDIV(dec->ystart, cmpt->vstep), jas_matrix_numcols(
tcomp->data), jas_matrix_numrows(tcomp->data), tcomp->data)) {
jas_eprintf("write component failed\n");
return -4;
}
}
return 0;
}
static int jpc_dec_process_eoc(jpc_dec_t *dec, jpc_ms_t *ms)
{
int tileno;
jpc_dec_tile_t *tile;
/* Eliminate compiler warnings about unused variables. */
ms = 0;
for (tileno = 0, tile = dec->tiles; tileno < dec->numtiles; ++tileno,
++tile) {
if (tile->state == JPC_TILE_ACTIVE) {
if (jpc_dec_tiledecode(dec, tile)) {
return -1;
}
}
jpc_dec_tilefini(dec, tile);
}
/* We are done processing the code stream. */
dec->state = JPC_MT;
return 1;
}
static int jpc_dec_process_siz(jpc_dec_t *dec, jpc_ms_t *ms)
{
jpc_siz_t *siz = &ms->parms.siz;
int compno;
int tileno;
jpc_dec_tile_t *tile;
jpc_dec_tcomp_t *tcomp;
int htileno;
int vtileno;
jpc_dec_cmpt_t *cmpt;
dec->xstart = siz->xoff;
dec->ystart = siz->yoff;
dec->xend = siz->width;
dec->yend = siz->height;
dec->tilewidth = siz->tilewidth;
dec->tileheight = siz->tileheight;
dec->tilexoff = siz->tilexoff;
dec->tileyoff = siz->tileyoff;
dec->numcomps = siz->numcomps;
if (!(dec->cp = jpc_dec_cp_create(dec->numcomps))) {
return -1;
}
if (!(dec->cmpts = jas_malloc(dec->numcomps * sizeof(jpc_dec_cmpt_t)))) {
return -1;
}
for (compno = 0, cmpt = dec->cmpts; compno < dec->numcomps; ++compno,
++cmpt) {
cmpt->prec = siz->comps[compno].prec;
cmpt->sgnd = siz->comps[compno].sgnd;
cmpt->hstep = siz->comps[compno].hsamp;
cmpt->vstep = siz->comps[compno].vsamp;
cmpt->width = JPC_CEILDIV(dec->xend, cmpt->hstep) -
JPC_CEILDIV(dec->xstart, cmpt->hstep);
cmpt->height = JPC_CEILDIV(dec->yend, cmpt->vstep) -
JPC_CEILDIV(dec->ystart, cmpt->vstep);
cmpt->hsubstep = 0;
cmpt->vsubstep = 0;
}
dec->image = 0;
dec->numhtiles = JPC_CEILDIV(dec->xend - dec->tilexoff, dec->tilewidth);
dec->numvtiles = JPC_CEILDIV(dec->yend - dec->tileyoff, dec->tileheight);
dec->numtiles = dec->numhtiles * dec->numvtiles;
if (!(dec->tiles = jas_malloc(dec->numtiles * sizeof(jpc_dec_tile_t)))) {
return -1;
}
for (tileno = 0, tile = dec->tiles; tileno < dec->numtiles; ++tileno,
++tile) {
htileno = tileno % dec->numhtiles;
vtileno = tileno / dec->numhtiles;
tile->realmode = 0;
tile->state = JPC_TILE_INIT;
tile->xstart = JAS_MAX(dec->tilexoff + htileno * dec->tilewidth,
dec->xstart);
tile->ystart = JAS_MAX(dec->tileyoff + vtileno * dec->tileheight,
dec->ystart);
tile->xend = JAS_MIN(dec->tilexoff + (htileno + 1) *
dec->tilewidth, dec->xend);
tile->yend = JAS_MIN(dec->tileyoff + (vtileno + 1) *
dec->tileheight, dec->yend);
tile->numparts = 0;
tile->partno = 0;
tile->pkthdrstream = 0;
tile->pkthdrstreampos = 0;
tile->pptstab = 0;
tile->cp = 0;
if (!(tile->tcomps = jas_malloc(dec->numcomps *
sizeof(jpc_dec_tcomp_t)))) {
return -1;
}
for (compno = 0, cmpt = dec->cmpts, tcomp = tile->tcomps;
compno < dec->numcomps; ++compno, ++cmpt, ++tcomp) {
tcomp->rlvls = 0;
tcomp->data = 0;
tcomp->xstart = JPC_CEILDIV(tile->xstart, cmpt->hstep);
tcomp->ystart = JPC_CEILDIV(tile->ystart, cmpt->vstep);
tcomp->xend = JPC_CEILDIV(tile->xend, cmpt->hstep);
tcomp->yend = JPC_CEILDIV(tile->yend, cmpt->vstep);
tcomp->tsfb = 0;
}
}
dec->pkthdrstreams = 0;
/* We should expect to encounter other main header marker segments
or an SOT marker segment next. */
dec->state = JPC_MH;
return 0;
}
static int jpc_dec_process_cod(jpc_dec_t *dec, jpc_ms_t *ms)
{
jpc_cod_t *cod = &ms->parms.cod;
jpc_dec_tile_t *tile;
switch (dec->state) {
case JPC_MH:
jpc_dec_cp_setfromcod(dec->cp, cod);
break;
case JPC_TPH:
if (!(tile = dec->curtile)) {
return -1;
}
if (tile->partno != 0) {
return -1;
}
jpc_dec_cp_setfromcod(tile->cp, cod);
break;
}
return 0;
}
static int jpc_dec_process_coc(jpc_dec_t *dec, jpc_ms_t *ms)
{
jpc_coc_t *coc = &ms->parms.coc;
jpc_dec_tile_t *tile;
if (JAS_CAST(int, coc->compno) > dec->numcomps) {
jas_eprintf("invalid component number in COC marker segment\n");
return -1;
}
switch (dec->state) {
case JPC_MH:
jpc_dec_cp_setfromcoc(dec->cp, coc);
break;
case JPC_TPH:
if (!(tile = dec->curtile)) {
return -1;
}
if (tile->partno > 0) {
return -1;
}
jpc_dec_cp_setfromcoc(tile->cp, coc);
break;
}
return 0;
}
static int jpc_dec_process_rgn(jpc_dec_t *dec, jpc_ms_t *ms)
{
jpc_rgn_t *rgn = &ms->parms.rgn;
jpc_dec_tile_t *tile;
if (JAS_CAST(int, rgn->compno) > dec->numcomps) {
jas_eprintf("invalid component number in RGN marker segment\n");
return -1;
}
switch (dec->state) {
case JPC_MH:
jpc_dec_cp_setfromrgn(dec->cp, rgn);
break;
case JPC_TPH:
if (!(tile = dec->curtile)) {
return -1;
}
if (tile->partno > 0) {
return -1;
}
jpc_dec_cp_setfromrgn(tile->cp, rgn);
break;
}
return 0;
}
static int jpc_dec_process_qcd(jpc_dec_t *dec, jpc_ms_t *ms)
{
jpc_qcd_t *qcd = &ms->parms.qcd;
jpc_dec_tile_t *tile;
switch (dec->state) {
case JPC_MH:
jpc_dec_cp_setfromqcd(dec->cp, qcd);
break;
case JPC_TPH:
if (!(tile = dec->curtile)) {
return -1;
}
if (tile->partno > 0) {
return -1;
}
jpc_dec_cp_setfromqcd(tile->cp, qcd);
break;
}
return 0;
}
static int jpc_dec_process_qcc(jpc_dec_t *dec, jpc_ms_t *ms)
{
jpc_qcc_t *qcc = &ms->parms.qcc;
jpc_dec_tile_t *tile;
if (JAS_CAST(int, qcc->compno) > dec->numcomps) {
jas_eprintf("invalid component number in QCC marker segment\n");
return -1;
}
switch (dec->state) {
case JPC_MH:
jpc_dec_cp_setfromqcc(dec->cp, qcc);
break;
case JPC_TPH:
if (!(tile = dec->curtile)) {
return -1;
}
if (tile->partno > 0) {
return -1;
}
jpc_dec_cp_setfromqcc(tile->cp, qcc);
break;
}
return 0;
}
static int jpc_dec_process_poc(jpc_dec_t *dec, jpc_ms_t *ms)
{
jpc_poc_t *poc = &ms->parms.poc;
jpc_dec_tile_t *tile;
switch (dec->state) {
case JPC_MH:
if (jpc_dec_cp_setfrompoc(dec->cp, poc, 1)) {
return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -