⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jpc_enc.c

📁 自主研发的一种电子文档格式。也算是多年技术的积累吧。 系统主要包含虚拟驱动和浏览器
💻 C
📖 第 1 页 / 共 5 页
字号:
			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) {
				jas_eprintf("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) {
				jas_eprintf("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)) {
				jas_eprintf("ignoring bad rate specifier %s\n",
				  jas_tvparser_getval(tvp));
			}
			break;
		case OPT_ILYRRATES:
			if (jpc_atoaf(jas_tvparser_getval(tvp), &numilyrrates,
			  &ilyrrates)) {
				jas_eprintf("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:
			jas_eprintf("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) {
			jas_eprintf("warning: overriding imgareatlx value\n");
		}
		cp->imgareatlx *= hsteplcm;
	}
	if (cp->imgareatly == UINT_FAST32_MAX) {
		cp->imgareatly = 0;
	} else {
		if (vsteplcm != 1) {
			jas_eprintf("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) {
		jas_eprintf("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) {
		jas_eprintf("invalid tile width %lu\n", (unsigned long)
		  cp->tilewidth);
		goto error;
	}
	if (!cp->tileheight) {
		jas_eprintf("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) {
		jas_eprintf("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)) {
		jas_eprintf("cannot use real mode for lossless coding\n");
		goto error;
	}

	/* Ensure that the precinct width is valid. */
	if (prcwidthexpn > 15) {
		jas_eprintf("invalid precinct width\n");
		goto error;
	}

	/* Ensure that the precinct height is valid. */
	if (prcheightexpn > 15) {
		jas_eprintf("invalid precinct height\n");
		goto error;
	}

	/* Ensure that the code block width is valid. */
	if (cp->tccp.cblkwidthexpn < 2 || cp->tccp.cblkwidthexpn > 12) {
		jas_eprintf("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) {
		jas_eprintf("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) {
		jas_eprintf("code block size too large\n");
		goto error;
	}

	/* Ensure that the number of layers is valid. */
	if (cp->tcp.numlyrs > 16384) {
		jas_eprintf("too many layers\n");
		goto error;
	}

	/* There must be at least one resolution level. */
	if (cp->tccp.maxrlvls < 1) {
		jas_eprintf("must be at least one resolution level\n");
		goto error;
	}

	/* Ensure that the number of guard bits is valid. */
	if (cp->tccp.numgbits > 8) {
		jas_eprintf("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) {
		jas_eprintf("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]) {
				jas_eprintf("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) {
					jas_eprintf("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)) {
		jas_eprintf("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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -