📄 jpc_enc.c
字号:
tcp->intmode = (tagid == MODE_INT); } break; case OPT_PRG: if ((tagid = jas_taginfo_nonull(jas_taginfos_lookup(prgordtab, jas_tvparser_getval(tvp)))->id) < 0) { fprintf(stderr, "ignoring invalid progression order %s\n", jas_tvparser_getval(tvp)); } else { tcp->prg = tagid; } break; case OPT_NOMCT: enablemct = false; break; case OPT_MAXRLVLS: tccp->maxrlvls = atoi(jas_tvparser_getval(tvp)); break; case OPT_SOP: cp->tcp.csty |= JPC_COD_SOP; break; case OPT_EPH: cp->tcp.csty |= JPC_COD_EPH; break; case OPT_LAZY: tccp->cblksty |= JPC_COX_LAZY; break; case OPT_TERMALL: tccp->cblksty |= JPC_COX_TERMALL; break; case OPT_SEGSYM: tccp->cblksty |= JPC_COX_SEGSYM; break; case OPT_VCAUSAL: tccp->cblksty |= JPC_COX_VSC; break; case OPT_RESET: tccp->cblksty |= JPC_COX_RESET; break; case OPT_PTERM: tccp->cblksty |= JPC_COX_PTERM; break; case OPT_NUMGBITS: cp->tccp.numgbits = atoi(jas_tvparser_getval(tvp)); break; case OPT_RATE: if (ratestrtosize(jas_tvparser_getval(tvp), cp->rawsize, &cp->totalsize)) { fprintf(stderr, "ignoring bad rate specifier %s\n", jas_tvparser_getval(tvp)); } break; case OPT_ILYRRATES: if (jpc_atoaf(jas_tvparser_getval(tvp), &numilyrrates, &ilyrrates)) { fprintf(stderr, "warning: invalid intermediate layer rates specifier ignored (%s)\n", jas_tvparser_getval(tvp)); } break; case OPT_JP2OVERHEAD: jp2overhead = atoi(jas_tvparser_getval(tvp)); break; default: fprintf(stderr, "warning: ignoring invalid option %s\n", jas_tvparser_gettag(tvp)); break; } } jas_tvparser_destroy(tvp); tvp = 0; if (cp->totalsize != UINT_FAST32_MAX) { cp->totalsize = (cp->totalsize > jp2overhead) ? (cp->totalsize - jp2overhead) : 0; } if (cp->imgareatlx == UINT_FAST32_MAX) { cp->imgareatlx = 0; } else { if (hsteplcm != 1) { fprintf(stderr, "warning: overriding imgareatlx value\n"); } cp->imgareatlx *= hsteplcm; } if (cp->imgareatly == UINT_FAST32_MAX) { cp->imgareatly = 0; } else { if (vsteplcm != 1) { fprintf(stderr, "warning: overriding imgareatly value\n"); } cp->imgareatly *= vsteplcm; } cp->refgrdwidth = cp->imgareatlx + jas_image_width(image); cp->refgrdheight = cp->imgareatly + jas_image_height(image); if (cp->tilegrdoffx == UINT_FAST32_MAX) { cp->tilegrdoffx = cp->imgareatlx; } if (cp->tilegrdoffy == UINT_FAST32_MAX) { cp->tilegrdoffy = cp->imgareatly; } if (!cp->tilewidth) { cp->tilewidth = cp->refgrdwidth - cp->tilegrdoffx; } if (!cp->tileheight) { cp->tileheight = cp->refgrdheight - cp->tilegrdoffy; } if (cp->numcmpts == 3) { mctvalid = true; for (cmptno = 0; cmptno < jas_image_numcmpts(image); ++cmptno) { if (jas_image_cmptprec(image, cmptno) != jas_image_cmptprec(image, 0) || jas_image_cmptsgnd(image, cmptno) != jas_image_cmptsgnd(image, 0) || jas_image_cmptwidth(image, cmptno) != jas_image_cmptwidth(image, 0) || jas_image_cmptheight(image, cmptno) != jas_image_cmptheight(image, 0)) { mctvalid = false; } } } else { mctvalid = false; } if (mctvalid && enablemct && jas_clrspc_fam(jas_image_clrspc(image)) != JAS_CLRSPC_FAM_RGB) { fprintf(stderr, "warning: color space apparently not RGB\n"); } if (mctvalid && enablemct && jas_clrspc_fam(jas_image_clrspc(image)) == JAS_CLRSPC_FAM_RGB) { tcp->mctid = (tcp->intmode) ? (JPC_MCT_RCT) : (JPC_MCT_ICT); } else { tcp->mctid = JPC_MCT_NONE; } tccp->qmfbid = (tcp->intmode) ? (JPC_COX_RFT) : (JPC_COX_INS); for (rlvlno = 0; rlvlno < tccp->maxrlvls; ++rlvlno) { tccp->prcwidthexpns[rlvlno] = prcwidthexpn; tccp->prcheightexpns[rlvlno] = prcheightexpn; } if (prcwidthexpn != 15 || prcheightexpn != 15) { tccp->csty |= JPC_COX_PRT; } /* Ensure that the tile width and height is valid. */ if (!cp->tilewidth) { fprintf(stderr, "invalid tile width %lu\n", (unsigned long) cp->tilewidth); goto error; } if (!cp->tileheight) { fprintf(stderr, "invalid tile height %lu\n", (unsigned long) cp->tileheight); goto error; } /* Ensure that the tile grid offset is valid. */ if (cp->tilegrdoffx > cp->imgareatlx || cp->tilegrdoffy > cp->imgareatly || cp->tilegrdoffx + cp->tilewidth < cp->imgareatlx || cp->tilegrdoffy + cp->tileheight < cp->imgareatly) { fprintf(stderr, "invalid tile grid offset (%lu, %lu)\n", (unsigned long) cp->tilegrdoffx, (unsigned long) cp->tilegrdoffy); goto error; } cp->numhtiles = JPC_CEILDIV(cp->refgrdwidth - cp->tilegrdoffx, cp->tilewidth); cp->numvtiles = JPC_CEILDIV(cp->refgrdheight - cp->tilegrdoffy, cp->tileheight); cp->numtiles = cp->numhtiles * cp->numvtiles; if (ilyrrates && numilyrrates > 0) { tcp->numlyrs = numilyrrates + 1; if (!(tcp->ilyrrates = jas_malloc((tcp->numlyrs - 1) * sizeof(jpc_fix_t)))) { goto error; } for (i = 0; i < JAS_CAST(int, tcp->numlyrs - 1); ++i) { tcp->ilyrrates[i] = jpc_dbltofix(ilyrrates[i]); } } /* Ensure that the integer mode is used in the case of lossless coding. */ if (cp->totalsize == UINT_FAST32_MAX && (!cp->tcp.intmode)) { fprintf(stderr, "cannot use real mode for lossless coding\n"); goto error; } /* Ensure that the precinct width is valid. */ if (prcwidthexpn > 15) { fprintf(stderr, "invalid precinct width\n"); goto error; } /* Ensure that the precinct height is valid. */ if (prcheightexpn > 15) { fprintf(stderr, "invalid precinct height\n"); goto error; } /* Ensure that the code block width is valid. */ if (cp->tccp.cblkwidthexpn < 2 || cp->tccp.cblkwidthexpn > 12) { fprintf(stderr, "invalid code block width %d\n", JPC_POW2(cp->tccp.cblkwidthexpn)); goto error; } /* Ensure that the code block height is valid. */ if (cp->tccp.cblkheightexpn < 2 || cp->tccp.cblkheightexpn > 12) { fprintf(stderr, "invalid code block height %d\n", JPC_POW2(cp->tccp.cblkheightexpn)); goto error; } /* Ensure that the code block size is not too large. */ if (cp->tccp.cblkwidthexpn + cp->tccp.cblkheightexpn > 12) { fprintf(stderr, "code block size too large\n"); goto error; } /* Ensure that the number of layers is valid. */ if (cp->tcp.numlyrs > 16384) { fprintf(stderr, "too many layers\n"); goto error; } /* There must be at least one resolution level. */ if (cp->tccp.maxrlvls < 1) { fprintf(stderr, "must be at least one resolution level\n"); goto error; } /* Ensure that the number of guard bits is valid. */ if (cp->tccp.numgbits > 8) { fprintf(stderr, "invalid number of guard bits\n"); goto error; } /* Ensure that the rate is within the legal range. */ if (cp->totalsize != UINT_FAST32_MAX && cp->totalsize > cp->rawsize) { fprintf(stderr, "warning: specified rate is unreasonably large (%lu > %lu)\n", (unsigned long) cp->totalsize, (unsigned long) cp->rawsize); } /* Ensure that the intermediate layer rates are valid. */ if (tcp->numlyrs > 1) { /* The intermediate layers rates must increase monotonically. */ for (lyrno = 0; lyrno + 2 < tcp->numlyrs; ++lyrno) { if (tcp->ilyrrates[lyrno] >= tcp->ilyrrates[lyrno + 1]) { fprintf(stderr, "intermediate layer rates must increase monotonically\n"); goto error; } } /* The intermediate layer rates must be less than the overall rate. */ if (cp->totalsize != UINT_FAST32_MAX) { for (lyrno = 0; lyrno < tcp->numlyrs - 1; ++lyrno) { if (jpc_fixtodbl(tcp->ilyrrates[lyrno]) > ((double) cp->totalsize) / cp->rawsize) { fprintf(stderr, "warning: intermediate layer rates must be less than overall rate\n"); goto error; } } } } if (ilyrrates) { jas_free(ilyrrates); } return cp;error: if (ilyrrates) { jas_free(ilyrrates); } if (tvp) { jas_tvparser_destroy(tvp); } if (cp) { jpc_enc_cp_destroy(cp); } return 0;}void jpc_enc_cp_destroy(jpc_enc_cp_t *cp){ if (cp->ccps) { if (cp->tcp.ilyrrates) { jas_free(cp->tcp.ilyrrates); } jas_free(cp->ccps); } jas_free(cp);}int ratestrtosize(char *s, uint_fast32_t rawsize, uint_fast32_t *size){ char *cp; jpc_flt_t f; /* Note: This function must not modify output size on failure. */ if ((cp = strchr(s, 'B'))) { *size = atoi(s); } else { f = atof(s); if (f < 0) { *size = 0; } else if (f > 1.0) { *size = rawsize + 1; } else { *size = f * rawsize; } } return 0;}/******************************************************************************\* Encoder constructor and destructor.\******************************************************************************/jpc_enc_t *jpc_enc_create(jpc_enc_cp_t *cp, jas_stream_t *out, jas_image_t *image){ jpc_enc_t *enc; enc = 0; if (!(enc = jas_malloc(sizeof(jpc_enc_t)))) { goto error; } enc->image = image; enc->out = out; enc->cp = cp; enc->cstate = 0; enc->tmpstream = 0; enc->mrk = 0; enc->curtile = 0; if (!(enc->cstate = jpc_cstate_create())) { goto error; } enc->len = 0; enc->mainbodysize = 0; return enc;error: if (enc) { jpc_enc_destroy(enc); } return 0;}void jpc_enc_destroy(jpc_enc_t *enc){ /* The image object (i.e., enc->image) and output stream object (i.e., enc->out) are created outside of the encoder. Therefore, they must not be destroyed here. */ if (enc->curtile) { jpc_enc_tile_destroy(enc->curtile); } if (enc->cp) { jpc_enc_cp_destroy(enc->cp); } if (enc->cstate) { jpc_cstate_destroy(enc->cstate); } if (enc->tmpstream) { jas_stream_close(enc->tmpstream); } jas_free(enc);}/******************************************************************************\* Code.\******************************************************************************/static int jpc_calcssmant(jpc_fix_t stepsize){ int n; int e; int m; n = jpc_firstone(stepsize); e = n - JPC_FIX_FRACBITS; if (n >= 11) { m = (stepsize >> (n - 11)) & 0x7ff; } else { m = (stepsize & ((1 << n) - 1)) << (11 - n); } return m;}static int jpc_calcssexp(jpc_fix_t stepsize){ return jpc_firstone(stepsize) - JPC_FIX_FRACBITS;}static int jpc_enc_encodemainhdr(jpc_enc_t *enc){ jpc_siz_t *siz; jpc_cod_t *cod; jpc_qcd_t *qcd; int i;long startoff;long mainhdrlen; jpc_enc_cp_t *cp; jpc_qcc_t *qcc; jpc_enc_tccp_t *tccp; uint_fast16_t cmptno; jpc_tsfb_band_t bandinfos[JPC_MAXBANDS]; jpc_fix_t mctsynweight; jpc_enc_tcp_t *tcp; jpc_tsfb_t *tsfb; jpc_tsfb_band_t *bandinfo; uint_fast16_t numbands; uint_fast16_t bandno; uint_fast16_t rlvlno; uint_fast16_t analgain; jpc_fix_t absstepsize; char buf[1024]; jpc_com_t *com; cp = enc->cp;startoff = jas_stream_getrwcount(enc->out); /* Write SOC marker segment. */ if (!(enc->mrk = jpc_ms_create(JPC_MS_SOC))) { return -1; } if (jpc_putms(enc->out, enc->cstate, enc->mrk)) { fprintf(stderr, "cannot write SOC marker\n"); return -1; } jpc_ms_destroy(enc->mrk); enc->mrk = 0; /* Write SIZ marker segment. */ if (!(enc->mrk = jpc_ms_create(JPC_MS_SIZ))) { return -1; } siz = &enc->mrk->parms.siz; siz->caps = 0; siz->xoff = cp->imgareatlx; siz->yoff = cp->imgareatly; siz->width = cp->refgrdwidth; siz->height = cp->refgrdheight; siz->tilexoff = cp->tilegrdoffx; siz->tileyoff = cp->tilegrdoffy; siz->tilewidth = cp->tilewidth; siz->tileheight = cp->tileheight; siz->numcomps = cp->numcmpts; siz->comps = jas_malloc(siz->numcomps * sizeof(jpc_sizcomp_t)); assert(siz->comps); for (i = 0; i < JAS_CAST(int, cp->numcmpts); ++i) { siz->comps[i].prec = cp->ccps[i].prec; siz->comps[i].sgnd = cp->ccps[i].sgnd; siz->comps[i].hsamp = cp->ccps[i].sampgrdstepx; siz->comps[i].vsamp = cp->ccps[i].sampgrdstepy; } if (jpc_putms(enc->out, enc->cstate, enc->mrk)) { fprintf(stderr, "cannot write SIZ marker\n"); return -1; } jpc_ms_destroy(enc->mrk); enc->mrk = 0; if (!(enc->mrk = jpc_ms_create(JPC_MS_COM))) { return -1; } sprintf(buf, "Creator: JasPer Version %s", jas_getversion()); com = &enc->mrk->parms.com; com->len = strlen(buf); com->regid = JPC_COM_LATIN; if (!(com->data = JAS_CAST(uchar *, jas_strdup(buf)))) { abort(); } if (jpc_putms(enc->out, enc->cstate, enc->mrk)) { fprintf(stderr, "cannot write COM marker\n"); return -1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -