📄 jpc_enc.c
字号:
}
if (jas_getdbglevel() >= 5) {
dump_layeringinfo(enc);
}
jas_stream_close(out);
JAS_DBGLOG(10, ("done doing rateallocation\n"));
#if 0
jas_eprintf("DONE RATE ALLOCATE\n");
#endif
return 0;
}
/******************************************************************************\
* Tile constructors and destructors.
\******************************************************************************/
jpc_enc_tile_t *jpc_enc_tile_create(jpc_enc_cp_t *cp, jas_image_t *image, int tileno)
{
jpc_enc_tile_t *tile;
uint_fast32_t htileno;
uint_fast32_t vtileno;
uint_fast16_t lyrno;
uint_fast16_t cmptno;
jpc_enc_tcmpt_t *tcmpt;
if (!(tile = jas_malloc(sizeof(jpc_enc_tile_t)))) {
goto error;
}
/* Initialize a few members used in error recovery. */
tile->tcmpts = 0;
tile->lyrsizes = 0;
tile->numtcmpts = cp->numcmpts;
tile->pi = 0;
tile->tileno = tileno;
htileno = tileno % cp->numhtiles;
vtileno = tileno / cp->numhtiles;
/* Calculate the coordinates of the top-left and bottom-right
corners of the tile. */
tile->tlx = JAS_MAX(cp->tilegrdoffx + htileno * cp->tilewidth,
cp->imgareatlx);
tile->tly = JAS_MAX(cp->tilegrdoffy + vtileno * cp->tileheight,
cp->imgareatly);
tile->brx = JAS_MIN(cp->tilegrdoffx + (htileno + 1) * cp->tilewidth,
cp->refgrdwidth);
tile->bry = JAS_MIN(cp->tilegrdoffy + (vtileno + 1) * cp->tileheight,
cp->refgrdheight);
/* Initialize some tile coding parameters. */
tile->intmode = cp->tcp.intmode;
tile->csty = cp->tcp.csty;
tile->prg = cp->tcp.prg;
tile->mctid = cp->tcp.mctid;
tile->numlyrs = cp->tcp.numlyrs;
if (!(tile->lyrsizes = jas_malloc(tile->numlyrs *
sizeof(uint_fast32_t)))) {
goto error;
}
for (lyrno = 0; lyrno < tile->numlyrs; ++lyrno) {
tile->lyrsizes[lyrno] = 0;
}
/* Allocate an array for the per-tile-component information. */
if (!(tile->tcmpts = jas_malloc(cp->numcmpts * sizeof(jpc_enc_tcmpt_t)))) {
goto error;
}
/* Initialize a few members critical for error recovery. */
for (cmptno = 0, tcmpt = tile->tcmpts; cmptno < cp->numcmpts;
++cmptno, ++tcmpt) {
tcmpt->rlvls = 0;
tcmpt->tsfb = 0;
tcmpt->data = 0;
}
/* Initialize the per-tile-component information. */
for (cmptno = 0, tcmpt = tile->tcmpts; cmptno < cp->numcmpts;
++cmptno, ++tcmpt) {
if (!tcmpt_create(tcmpt, cp, image, tile)) {
goto error;
}
}
/* Initialize the synthesis weights for the MCT. */
switch (tile->mctid) {
case JPC_MCT_RCT:
tile->tcmpts[0].synweight = jpc_dbltofix(sqrt(3.0));
tile->tcmpts[1].synweight = jpc_dbltofix(sqrt(0.6875));
tile->tcmpts[2].synweight = jpc_dbltofix(sqrt(0.6875));
break;
case JPC_MCT_ICT:
tile->tcmpts[0].synweight = jpc_dbltofix(sqrt(3.0000));
tile->tcmpts[1].synweight = jpc_dbltofix(sqrt(3.2584));
tile->tcmpts[2].synweight = jpc_dbltofix(sqrt(2.4755));
break;
default:
case JPC_MCT_NONE:
for (cmptno = 0, tcmpt = tile->tcmpts; cmptno < cp->numcmpts;
++cmptno, ++tcmpt) {
tcmpt->synweight = JPC_FIX_ONE;
}
break;
}
if (!(tile->pi = jpc_enc_pi_create(cp, tile))) {
goto error;
}
return tile;
error:
if (tile) {
jpc_enc_tile_destroy(tile);
}
return 0;
}
void jpc_enc_tile_destroy(jpc_enc_tile_t *tile)
{
jpc_enc_tcmpt_t *tcmpt;
uint_fast16_t cmptno;
if (tile->tcmpts) {
for (cmptno = 0, tcmpt = tile->tcmpts; cmptno <
tile->numtcmpts; ++cmptno, ++tcmpt) {
tcmpt_destroy(tcmpt);
}
jas_free(tile->tcmpts);
}
if (tile->lyrsizes) {
jas_free(tile->lyrsizes);
}
if (tile->pi) {
jpc_pi_destroy(tile->pi);
}
jas_free(tile);
}
static jpc_enc_tcmpt_t *tcmpt_create(jpc_enc_tcmpt_t *tcmpt, jpc_enc_cp_t *cp,
jas_image_t *image, jpc_enc_tile_t *tile)
{
uint_fast16_t cmptno;
uint_fast16_t rlvlno;
jpc_enc_rlvl_t *rlvl;
uint_fast32_t tlx;
uint_fast32_t tly;
uint_fast32_t brx;
uint_fast32_t bry;
uint_fast32_t cmpttlx;
uint_fast32_t cmpttly;
jpc_enc_ccp_t *ccp;
jpc_tsfb_band_t bandinfos[JPC_MAXBANDS];
tcmpt->tile = tile;
tcmpt->tsfb = 0;
tcmpt->data = 0;
tcmpt->rlvls = 0;
/* Deduce the component number. */
cmptno = tcmpt - tile->tcmpts;
ccp = &cp->ccps[cmptno];
/* Compute the coordinates of the top-left and bottom-right
corners of this tile-component. */
tlx = JPC_CEILDIV(tile->tlx, ccp->sampgrdstepx);
tly = JPC_CEILDIV(tile->tly, ccp->sampgrdstepy);
brx = JPC_CEILDIV(tile->brx, ccp->sampgrdstepx);
bry = JPC_CEILDIV(tile->bry, ccp->sampgrdstepy);
/* Create a sequence to hold the tile-component sample data. */
if (!(tcmpt->data = jas_seq2d_create(tlx, tly, brx, bry))) {
goto error;
}
/* Get the image data associated with this tile-component. */
cmpttlx = JPC_CEILDIV(cp->imgareatlx, ccp->sampgrdstepx);
cmpttly = JPC_CEILDIV(cp->imgareatly, ccp->sampgrdstepy);
if (jas_image_readcmpt(image, cmptno, tlx - cmpttlx, tly - cmpttly,
brx - tlx, bry - tly, tcmpt->data)) {
goto error;
}
tcmpt->synweight = 0;
tcmpt->qmfbid = cp->tccp.qmfbid;
tcmpt->numrlvls = cp->tccp.maxrlvls;
tcmpt->numbands = 3 * tcmpt->numrlvls - 2;
if (!(tcmpt->tsfb = jpc_cod_gettsfb(tcmpt->qmfbid, tcmpt->numrlvls - 1))) {
goto error;
}
for (rlvlno = 0; rlvlno < tcmpt->numrlvls; ++rlvlno) {
tcmpt->prcwidthexpns[rlvlno] = cp->tccp.prcwidthexpns[rlvlno];
tcmpt->prcheightexpns[rlvlno] = cp->tccp.prcheightexpns[rlvlno];
}
tcmpt->cblkwidthexpn = cp->tccp.cblkwidthexpn;
tcmpt->cblkheightexpn = cp->tccp.cblkheightexpn;
tcmpt->cblksty = cp->tccp.cblksty;
tcmpt->csty = cp->tccp.csty;
tcmpt->numstepsizes = tcmpt->numbands;
assert(tcmpt->numstepsizes <= JPC_MAXBANDS);
memset(tcmpt->stepsizes, 0, sizeof(tcmpt->numstepsizes *
sizeof(uint_fast16_t)));
/* Retrieve information about the various bands. */
jpc_tsfb_getbands(tcmpt->tsfb, jas_seq2d_xstart(tcmpt->data),
jas_seq2d_ystart(tcmpt->data), jas_seq2d_xend(tcmpt->data),
jas_seq2d_yend(tcmpt->data), bandinfos);
if (!(tcmpt->rlvls = jas_malloc(tcmpt->numrlvls * sizeof(jpc_enc_rlvl_t)))) {
goto error;
}
for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls;
++rlvlno, ++rlvl) {
rlvl->bands = 0;
rlvl->tcmpt = tcmpt;
}
for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls;
++rlvlno, ++rlvl) {
if (!rlvl_create(rlvl, cp, tcmpt, bandinfos)) {
goto error;
}
}
return tcmpt;
error:
tcmpt_destroy(tcmpt);
return 0;
}
static void tcmpt_destroy(jpc_enc_tcmpt_t *tcmpt)
{
jpc_enc_rlvl_t *rlvl;
uint_fast16_t rlvlno;
if (tcmpt->rlvls) {
for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls;
++rlvlno, ++rlvl) {
rlvl_destroy(rlvl);
}
jas_free(tcmpt->rlvls);
}
if (tcmpt->data) {
jas_seq2d_destroy(tcmpt->data);
}
if (tcmpt->tsfb) {
jpc_tsfb_destroy(tcmpt->tsfb);
}
}
static jpc_enc_rlvl_t *rlvl_create(jpc_enc_rlvl_t *rlvl, jpc_enc_cp_t *cp,
jpc_enc_tcmpt_t *tcmpt, jpc_tsfb_band_t *bandinfos)
{
uint_fast16_t rlvlno;
uint_fast32_t tlprctlx;
uint_fast32_t tlprctly;
uint_fast32_t brprcbrx;
uint_fast32_t brprcbry;
uint_fast16_t bandno;
jpc_enc_band_t *band;
/* Deduce the resolution level. */
rlvlno = rlvl - tcmpt->rlvls;
/* Initialize members required for error recovery. */
rlvl->bands = 0;
rlvl->tcmpt = tcmpt;
/* Compute the coordinates of the top-left and bottom-right
corners of the tile-component at this resolution. */
rlvl->tlx = JPC_CEILDIVPOW2(jas_seq2d_xstart(tcmpt->data), tcmpt->numrlvls -
1 - rlvlno);
rlvl->tly = JPC_CEILDIVPOW2(jas_seq2d_ystart(tcmpt->data), tcmpt->numrlvls -
1 - rlvlno);
rlvl->brx = JPC_CEILDIVPOW2(jas_seq2d_xend(tcmpt->data), tcmpt->numrlvls -
1 - rlvlno);
rlvl->bry = JPC_CEILDIVPOW2(jas_seq2d_yend(tcmpt->data), tcmpt->numrlvls -
1 - rlvlno);
if (rlvl->tlx >= rlvl->brx || rlvl->tly >= rlvl->bry) {
rlvl->numhprcs = 0;
rlvl->numvprcs = 0;
rlvl->numprcs = 0;
return rlvl;
}
rlvl->numbands = (!rlvlno) ? 1 : 3;
rlvl->prcwidthexpn = cp->tccp.prcwidthexpns[rlvlno];
rlvl->prcheightexpn = cp->tccp.prcheightexpns[rlvlno];
if (!rlvlno) {
rlvl->cbgwidthexpn = rlvl->prcwidthexpn;
rlvl->cbgheightexpn = rlvl->prcheightexpn;
} else {
rlvl->cbgwidthexpn = rlvl->prcwidthexpn - 1;
rlvl->cbgheightexpn = rlvl->prcheightexpn - 1;
}
rlvl->cblkwidthexpn = JAS_MIN(cp->tccp.cblkwidthexpn, rlvl->cbgwidthexpn);
rlvl->cblkheightexpn = JAS_MIN(cp->tccp.cblkheightexpn, rlvl->cbgheightexpn);
/* Compute the number of precincts. */
tlprctlx = JPC_FLOORTOMULTPOW2(rlvl->tlx, rlvl->prcwidthexpn);
tlprctly = JPC_FLOORTOMULTPOW2(rlvl->tly, rlvl->prcheightexpn);
brprcbrx = JPC_CEILTOMULTPOW2(rlvl->brx, rlvl->prcwidthexpn);
brprcbry = JPC_CEILTOMULTPOW2(rlvl->bry, rlvl->prcheightexpn);
rlvl->numhprcs = JPC_FLOORDIVPOW2(brprcbrx - tlprctlx, rlvl->prcwidthexpn);
rlvl->numvprcs = JPC_FLOORDIVPOW2(brprcbry - tlprctly, rlvl->prcheightexpn);
rlvl->numprcs = rlvl->numhprcs * rlvl->numvprcs;
if (!(rlvl->bands = jas_malloc(rlvl->numbands * sizeof(jpc_enc_band_t)))) {
goto error;
}
for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands;
++bandno, ++band) {
band->prcs = 0;
band->data = 0;
band->rlvl = rlvl;
}
for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands;
++bandno, ++band) {
if (!band_create(band, cp, rlvl, bandinfos)) {
goto error;
}
}
return rlvl;
error:
rlvl_destroy(rlvl);
return 0;
}
static void rlvl_destroy(jpc_enc_rlvl_t *rlvl)
{
jpc_enc_band_t *band;
uint_fast16_t bandno;
if (rlvl->bands) {
for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands;
++bandno, ++band) {
band_destroy(band);
}
jas_free(rlvl->bands);
}
}
static jpc_enc_band_t *band_create(jpc_enc_band_t *band, jpc_enc_cp_t *cp,
jpc_enc_rlvl_t *rlvl, jpc_tsfb_band_t *bandinfos)
{
uint_fast16_t bandno;
uint_fast16_t gblbandno;
uint_fast16_t rlvlno;
jpc_tsfb_band_t *bandinfo;
jpc_enc_tcmpt_t *tcmpt;
uint_fast32_t prcno;
jpc_enc_prc_t *prc;
tcmpt = rlvl->tcmpt;
band->data = 0;
band->prcs = 0;
band->rlvl = rlvl;
/* Deduce the resolution level and band number. */
rlvlno = rlvl - rlvl->tcmpt->rlvls;
bandno = band - rlvl->bands;
gblbandno = (!rlvlno) ? 0 : (3 * (rlvlno - 1) + bandno + 1);
bandinfo = &bandinfos[gblbandno];
if (bandinfo->xstart != bandinfo->xend && bandinfo->ystart != bandinfo->yend) {
if (!(band->data = jas_seq2d_create(0, 0, 0, 0))) {
goto error;
}
jas_seq2d_bindsub(band->data, tcmpt->data, bandinfo->locxstart,
bandinfo->locystart, bandinfo->locxend, bandinfo->locyend);
jas_seq2d_setshift(band->data, bandinfo->xstart, bandinfo->ystart);
}
band->orient = bandinfo->orient;
band->analgain = JPC_NOMINALGAIN(cp->tccp.qmfbid, tcmpt->numrlvls, rlvlno,
band->orient);
band->numbps = 0;
band->absstepsize = 0;
band->stepsize = 0;
band->synweight = bandinfo->synenergywt;
if (band->data) {
if (!(band->prcs = jas_malloc(rlvl->numprcs * sizeof(jpc_enc_prc_t)))) {
goto error;
}
for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs; ++prcno,
++prc) {
prc->cblks = 0;
prc->incltree = 0;
prc->nlibtree = 0;
prc->savincltree = 0;
prc->savnlibtree = 0;
prc->band = band;
}
for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs; ++prcno,
++prc) {
if (!prc_create(prc, cp, band)) {
goto error;
}
}
}
return band;
error:
band_destroy(band);
return 0;
}
static void band_destroy(jpc_enc_band_t *band)
{
jpc_enc_prc_t *prc;
jpc_enc_rlvl_t *rlvl;
uint_fast32_t prcno;
if (band->prcs) {
rlvl = band->rlvl;
for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs;
++prcno, ++prc) {
prc_destroy(prc);
}
jas_free(band->prcs);
}
if (band->data) {
jas_seq2d_destroy(band->data);
}
}
static jpc_enc_prc_t *prc_create(jpc_enc_prc_t *prc, jpc_enc_cp_t *cp, jpc_enc_band_t *band)
{
uint_fast32_t prcno;
uint_fast32_t prcxind;
uint_fast32_t prcyind;
uint_fast32_t cbgtlx;
uint_fast32_t cbgtly;
uint_fast32_t tlprctlx;
uint_fast32_t tlprctly;
uint_fast32_t tlcbgtlx;
uint_fast32_t tlcbgtly;
uint_fast16_t rlvlno;
jpc_enc_rlvl_t *rlvl;
uint_fast32_t tlcblktlx;
uint_fast32_t tlcblktly;
uint_fast32_t brcblkbrx;
uint_fast32_t brcblkbry;
uint_fast32_t cblkno;
jpc_enc_cblk_t *cblk;
jpc_enc_tcmpt_t *tcmpt;
prc->cblks = 0;
prc->incltree = 0;
prc->savincltree = 0;
prc->nlibtree = 0;
prc->savnlibtree = 0;
rlvl = ba
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -