📄 jpc_enc.c
字号:
/************************************************************************/
/************************************************************************/
/************************************************************************/
/************************************************************************/
/************************************************************************/
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) {
jas_eprintf("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 jpc_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) {
jas_eprintf("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) {
jas_eprintf("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) {
jas_eprintf("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()) {
jas_eprintf("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()) {
jas_eprintf("maxlen=%08ld actuallen=%08ld thresh=%f\n", cumlen, pos, thresh);
}
++numiters;
} while (lo < hi - 1e-3 && numiters < 32);
if (!success) {
jas_eprintf("warning: empty layer generated\n");
}
if (jas_getdbglevel()) {
jas_eprintf("success %d goodthresh %f\n", success, goodthresh);
}
/* Assign all passes with R-D slopes greater than or
equal to the selected 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;
if (success) {
for (pass = cblk->curpass; pass != endpasses; ++pass) {
if (pass->rdslope >= goodthresh) {
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;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -