📄 jpc_enc.c
字号:
tcp = &cp->tcp; tcp->csty = 0; tcp->intmode = true; tcp->prg = JPC_COD_LRCPPRG; tcp->numlyrs = 1; tcp->ilyrrates = 0; tccp = &cp->tccp; tccp->csty = 0; tccp->maxrlvls = 6; tccp->cblkwidthexpn = 6; tccp->cblkheightexpn = 6; tccp->cblksty = 0; tccp->numgbits = 2; if (!(tvp = jas_tvparser_create(optstr ? optstr : ""))) { goto error; } while (!(ret = jas_tvparser_next(tvp))) { switch (jas_taginfo_nonull(jas_taginfos_lookup(encopts, jas_tvparser_gettag(tvp)))->id) { case OPT_DEBUG: cp->debug = atoi(jas_tvparser_getval(tvp)); break; case OPT_IMGAREAOFFX: cp->imgareatlx = atoi(jas_tvparser_getval(tvp)); break; case OPT_IMGAREAOFFY: cp->imgareatly = atoi(jas_tvparser_getval(tvp)); break; case OPT_TILEGRDOFFX: cp->tilegrdoffx = atoi(jas_tvparser_getval(tvp)); break; case OPT_TILEGRDOFFY: cp->tilegrdoffy = atoi(jas_tvparser_getval(tvp)); break; case OPT_TILEWIDTH: cp->tilewidth = atoi(jas_tvparser_getval(tvp)); break; case OPT_TILEHEIGHT: cp->tileheight = atoi(jas_tvparser_getval(tvp)); break; case OPT_PRCWIDTH: prcwidthexpn = jpc_floorlog2(atoi(jas_tvparser_getval(tvp))); break; case OPT_PRCHEIGHT: prcheightexpn = jpc_floorlog2(atoi(jas_tvparser_getval(tvp))); break; case OPT_CBLKWIDTH: tccp->cblkwidthexpn = jpc_floorlog2(atoi(jas_tvparser_getval(tvp))); break; case OPT_CBLKHEIGHT: tccp->cblkheightexpn = jpc_floorlog2(atoi(jas_tvparser_getval(tvp))); break; case OPT_MODE: if ((tagid = jas_taginfo_nonull(jas_taginfos_lookup(modetab, jas_tvparser_getval(tvp)))->id) < 0) { fprintf(stderr, "ignoring invalid mode %s\n", jas_tvparser_getval(tvp)); } else { 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -