📄 jpc_enc.c
字号:
} /* Write a SOD marker to indicate the end of the tile header. */ if (!(enc->mrk = jpc_ms_create(JPC_MS_SOD))) { return -1; } if (jpc_putms(enc->tmpstream, enc->cstate, enc->mrk)) { fprintf(stderr, "cannot write SOD marker\n"); return -1; } jpc_ms_destroy(enc->mrk); enc->mrk = 0;tilehdrlen = jas_stream_getrwcount(enc->tmpstream);/************************************************************************//************************************************************************//************************************************************************/if (jpc_enc_enccblks(enc)) { abort(); return -1;} cp = enc->cp; rho = (double) (tile->brx - tile->tlx) * (tile->bry - tile->tly) / ((cp->refgrdwidth - cp->imgareatlx) * (cp->refgrdheight - cp->imgareatly)); tile->rawsize = cp->rawsize * rho; for (lyrno = 0; lyrno < tile->numlyrs - 1; ++lyrno) { tile->lyrsizes[lyrno] = tile->rawsize * jpc_fixtodbl( cp->tcp.ilyrrates[lyrno]); } tile->lyrsizes[tile->numlyrs - 1] = (cp->totalsize != UINT_FAST32_MAX) ? (rho * enc->mainbodysize) : UINT_FAST32_MAX; for (lyrno = 0; lyrno < tile->numlyrs; ++lyrno) { if (tile->lyrsizes[lyrno] != UINT_FAST32_MAX) { if (tilehdrlen <= JAS_CAST(long, tile->lyrsizes[lyrno])) { tile->lyrsizes[lyrno] -= tilehdrlen; } else { tile->lyrsizes[lyrno] = 0; } } } if (rateallocate(enc, tile->numlyrs, tile->lyrsizes)) { return -1; }#if 0fprintf(stderr, "ENCODE TILE DATA\n");#endif if (jpc_enc_encodetiledata(enc)) { fprintf(stderr, "dotile failed\n"); return -1; }/************************************************************************//************************************************************************//************************************************************************//************************************************************************//************************************************************************//************************************************************************/ tilelen = jas_stream_tell(enc->tmpstream); if (jas_stream_seek(enc->tmpstream, 6, SEEK_SET) < 0) { return -1; } jpc_putuint32(enc->tmpstream, tilelen); if (jas_stream_seek(enc->tmpstream, 0, SEEK_SET) < 0) { return -1; } if (jpc_putdata(enc->out, enc->tmpstream, -1)) { return -1; } enc->len += tilelen; jas_stream_close(enc->tmpstream); enc->tmpstream = 0; jpc_enc_tile_destroy(enc->curtile); enc->curtile = 0; } return 0;}int jpc_enc_encodetiledata(jpc_enc_t *enc){assert(enc->tmpstream); if (jpc_enc_encpkts(enc, enc->tmpstream)) { return -1; } return 0;}int dump_passes(jpc_enc_pass_t *passes, int numpasses, jpc_enc_cblk_t *cblk){ jpc_enc_pass_t *pass; int i; jas_stream_memobj_t *smo; smo = cblk->stream->obj_; pass = passes; for (i = 0; i < numpasses; ++i) { fprintf(stderr, "start=%d end=%d type=%d term=%d lyrno=%d firstchar=%02x size=%ld pos=%ld\n", (int)pass->start, (int)pass->end, (int)pass->type, (int)pass->term, (int)pass->lyrno, smo->buf_[pass->start], (long)smo->len_, (long)smo->pos_);#if 0 jas_memdump(stderr, &smo->buf_[pass->start], pass->end - pass->start);#endif ++pass; } return 0;}void quantize(jas_matrix_t *data, jpc_fix_t stepsize){ int i; int j; jpc_fix_t t; if (stepsize == jpc_inttofix(1)) { return; } for (i = 0; i < jas_matrix_numrows(data); ++i) { for (j = 0; j < jas_matrix_numcols(data); ++j) { t = jas_matrix_get(data, i, j);{ if (t < 0) { t = jpc_fix_neg(jpc_fix_div(jpc_fix_neg(t), stepsize)); } else { t = jpc_fix_div(t, stepsize); }} jas_matrix_set(data, i, j, t); } }}void calcrdslopes(jpc_enc_cblk_t *cblk){ jpc_enc_pass_t *endpasses; jpc_enc_pass_t *pass0; jpc_enc_pass_t *pass1; jpc_enc_pass_t *pass2; jpc_flt_t slope0; jpc_flt_t slope; jpc_flt_t dd; long dr; endpasses = &cblk->passes[cblk->numpasses]; pass2 = cblk->passes; slope0 = 0; while (pass2 != endpasses) { pass0 = 0; for (pass1 = cblk->passes; pass1 != endpasses; ++pass1) { dd = pass1->cumwmsedec; dr = pass1->end; if (pass0) { dd -= pass0->cumwmsedec; dr -= pass0->end; } if (dd <= 0) { pass1->rdslope = JPC_BADRDSLOPE; if (pass1 >= pass2) { pass2 = &pass1[1]; } continue; } if (pass1 < pass2 && pass1->rdslope <= 0) { continue; } if (!dr) { assert(pass0); pass0->rdslope = 0; break; } slope = dd / dr; if (pass0 && slope >= slope0) { pass0->rdslope = 0; break; } pass1->rdslope = slope; if (pass1 >= pass2) { pass2 = &pass1[1]; } pass0 = pass1; slope0 = slope; } }#if 0 for (pass0 = cblk->passes; pass0 != endpasses; ++pass0) {if (pass0->rdslope > 0.0) { fprintf(stderr, "pass %02d nmsedec=%lf dec=%lf end=%d %lf\n", pass0 - cblk->passes, fixtodbl(pass0->nmsedec), pass0->wmsedec, pass0->end, pass0->rdslope);} }#endif}void dump_layeringinfo(jpc_enc_t *enc){ jpc_enc_tcmpt_t *tcmpt; int tcmptno; jpc_enc_rlvl_t *rlvl; int rlvlno; jpc_enc_band_t *band; int bandno; jpc_enc_prc_t *prc; int prcno; jpc_enc_cblk_t *cblk; int cblkno; jpc_enc_pass_t *pass; int passno; int lyrno; jpc_enc_tile_t *tile; tile = enc->curtile; for (lyrno = 0; lyrno < tile->numlyrs; ++lyrno) { fprintf(stderr, "lyrno = %02d\n", lyrno); for (tcmptno = 0, tcmpt = tile->tcmpts; tcmptno < tile->numtcmpts; ++tcmptno, ++tcmpt) { for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls; ++rlvlno, ++rlvl) { if (!rlvl->bands) { continue; } for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands; ++bandno, ++band) { if (!band->data) { continue; } 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) { for (passno = 0, pass = cblk->passes; passno < cblk->numpasses && pass->lyrno == lyrno; ++passno, ++pass) { fprintf(stderr, "lyrno=%02d cmptno=%02d rlvlno=%02d bandno=%02d prcno=%02d cblkno=%03d passno=%03d\n", lyrno, tcmptno, rlvlno, bandno, prcno, cblkno, passno); } } } } } } }}int rateallocate(jpc_enc_t *enc, int numlyrs, uint_fast32_t *cumlens){ jpc_flt_t lo; jpc_flt_t hi; jas_stream_t *out; long cumlen; int lyrno; jpc_flt_t thresh; jpc_flt_t goodthresh; int success; long pos; long oldpos; int numiters; jpc_enc_tcmpt_t *comp; jpc_enc_tcmpt_t *endcomps; jpc_enc_rlvl_t *lvl; jpc_enc_rlvl_t *endlvls; jpc_enc_band_t *band; jpc_enc_band_t *endbands; jpc_enc_cblk_t *cblk; jpc_enc_cblk_t *endcblks; jpc_enc_pass_t *pass; jpc_enc_pass_t *endpasses; jpc_enc_pass_t *pass1; jpc_flt_t mxrdslope; jpc_flt_t mnrdslope; jpc_enc_tile_t *tile; jpc_enc_prc_t *prc; int prcno; tile = enc->curtile; for (lyrno = 1; lyrno < numlyrs - 1; ++lyrno) { if (cumlens[lyrno - 1] > cumlens[lyrno]) { abort(); } } if (!(out = jas_stream_memopen(0, 0))) { return -1; } /* Find minimum and maximum R-D slope values. */ mnrdslope = DBL_MAX; mxrdslope = 0; endcomps = &tile->tcmpts[tile->numtcmpts]; for (comp = tile->tcmpts; comp != endcomps; ++comp) { endlvls = &comp->rlvls[comp->numrlvls]; for (lvl = comp->rlvls; lvl != endlvls; ++lvl) { if (!lvl->bands) { continue; } endbands = &lvl->bands[lvl->numbands]; for (band = lvl->bands; band != endbands; ++band) { if (!band->data) { continue; } for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs; ++prcno, ++prc) { if (!prc->cblks) { continue; } endcblks = &prc->cblks[prc->numcblks]; for (cblk = prc->cblks; cblk != endcblks; ++cblk) { calcrdslopes(cblk); endpasses = &cblk->passes[cblk->numpasses]; for (pass = cblk->passes; pass != endpasses; ++pass) { if (pass->rdslope > 0) { if (pass->rdslope < mnrdslope) { mnrdslope = pass->rdslope; } if (pass->rdslope > mxrdslope) { mxrdslope = pass->rdslope; } } } } } } } }if (jas_getdbglevel()) { fprintf(stderr, "min rdslope = %f max rdslope = %f\n", mnrdslope, mxrdslope);} jpc_init_t2state(enc, 1); for (lyrno = 0; lyrno < numlyrs; ++lyrno) { lo = mnrdslope; hi = mxrdslope; success = 0; goodthresh = 0; numiters = 0; do { cumlen = cumlens[lyrno]; if (cumlen == UINT_FAST32_MAX) { /* Only the last layer can be free of a rate constraint (e.g., for lossless coding). */ assert(lyrno == numlyrs - 1); goodthresh = -1; success = 1; break; } thresh = (lo + hi) / 2; /* Save the tier 2 coding state. */ jpc_save_t2state(enc); oldpos = jas_stream_tell(out); assert(oldpos >= 0); /* Assign all passes with R-D slopes greater than or equal to the current threshold to this layer. */ endcomps = &tile->tcmpts[tile->numtcmpts]; for (comp = tile->tcmpts; comp != endcomps; ++comp) { endlvls = &comp->rlvls[comp->numrlvls]; for (lvl = comp->rlvls; lvl != endlvls; ++lvl) { if (!lvl->bands) { continue; } endbands = &lvl->bands[lvl->numbands]; for (band = lvl->bands; band != endbands; ++band) { if (!band->data) { continue; } for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs; ++prcno, ++prc) { if (!prc->cblks) { continue; } endcblks = &prc->cblks[prc->numcblks]; for (cblk = prc->cblks; cblk != endcblks; ++cblk) { if (cblk->curpass) { endpasses = &cblk->passes[cblk->numpasses]; pass1 = cblk->curpass; for (pass = cblk->curpass; pass != endpasses; ++pass) { if (pass->rdslope >= thresh) { pass1 = &pass[1]; } } for (pass = cblk->curpass; pass != pass1; ++pass) { pass->lyrno = lyrno; } for (; pass != endpasses; ++pass) { pass->lyrno = -1; } } } } } } } /* Perform tier 2 coding. */ endcomps = &tile->tcmpts[tile->numtcmpts]; for (comp = tile->tcmpts; comp != endcomps; ++comp) { endlvls = &comp->rlvls[comp->numrlvls]; for (lvl = comp->rlvls; lvl != endlvls; ++lvl) { if (!lvl->bands) { continue; } for (prcno = 0; prcno < lvl->numprcs; ++prcno) { if (jpc_enc_encpkt(enc, out, comp - tile->tcmpts, lvl - comp->rlvls, prcno, lyrno)) { return -1; } } } } pos = jas_stream_tell(out); /* Check the rate constraint. */ assert(pos >= 0); if (pos > cumlen) { /* The rate is too high. */ lo = thresh; } else if (pos <= cumlen) { /* The rate is low enough, so try higher. */ hi = thresh; if (!success || thresh < goodthresh) { goodthresh = thresh; success = 1; } } /* Save the tier 2 coding state. */ jpc_restore_t2state(enc); if (jas_stream_seek(out, oldpos, SEEK_SET) < 0) { abort(); }if (jas_getdbglevel()) {fprintf(stderr, "maxlen=%08ld actuallen=%08ld thresh=%f\n", cumlen, pos, thresh);} ++numiters; } while (lo < hi - 1e-3 && numiters < 32); if (!success) { fprintf(stderr, "warning: empty layer generated\n"); }if (jas_getdbglevel()) {fprintf(stderr, "success %d goodthresh %f\n", success, goodthresh);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -