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

📄 jpc_enc.c

📁 用C语言实现的JPEG编码
💻 C
📖 第 1 页 / 共 5 页
字号:
	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 + -