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

📄 jpc_enc.c

📁 用C语言实现的JPEG编码
💻 C
📖 第 1 页 / 共 5 页
字号:
		}		/* Write a SOD marker to indicate the end of the tile header. */		if (!(enc->mrk = jpc_ms_create(JPC_MS_SOD))) {			return -1;		}		if (jpc_putms(enc->tmpstream, enc->cstate, enc->mrk)) {			fprintf(stderr, "cannot write SOD marker\n");			return -1;		}		jpc_ms_destroy(enc->mrk);		enc->mrk = 0;tilehdrlen = jas_stream_getrwcount(enc->tmpstream);/************************************************************************//************************************************************************//************************************************************************/if (jpc_enc_enccblks(enc)) {	abort();	return -1;}		cp = enc->cp;		rho = (double) (tile->brx - tile->tlx) * (tile->bry - tile->tly) /		  ((cp->refgrdwidth - cp->imgareatlx) * (cp->refgrdheight -		  cp->imgareatly));		tile->rawsize = cp->rawsize * rho;		for (lyrno = 0; lyrno < tile->numlyrs - 1; ++lyrno) {			tile->lyrsizes[lyrno] = tile->rawsize * jpc_fixtodbl(			  cp->tcp.ilyrrates[lyrno]);		}		tile->lyrsizes[tile->numlyrs - 1] = (cp->totalsize != UINT_FAST32_MAX) ?		  (rho * enc->mainbodysize) : UINT_FAST32_MAX;		for (lyrno = 0; lyrno < tile->numlyrs; ++lyrno) {			if (tile->lyrsizes[lyrno] != UINT_FAST32_MAX) {				if (tilehdrlen <= JAS_CAST(long, tile->lyrsizes[lyrno])) {					tile->lyrsizes[lyrno] -= tilehdrlen;				} else {					tile->lyrsizes[lyrno] = 0;				}			}		}		if (rateallocate(enc, tile->numlyrs, tile->lyrsizes)) {			return -1;		}#if 0fprintf(stderr, "ENCODE TILE DATA\n");#endif		if (jpc_enc_encodetiledata(enc)) {			fprintf(stderr, "dotile failed\n");			return -1;		}/************************************************************************//************************************************************************//************************************************************************//************************************************************************//************************************************************************//************************************************************************/		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) {		fprintf(stderr, "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 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) {		fprintf(stderr, "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) {		fprintf(stderr, "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) {								fprintf(stderr, "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()) {	fprintf(stderr, "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()) {fprintf(stderr, "maxlen=%08ld actuallen=%08ld thresh=%f\n", cumlen, pos, thresh);}			++numiters;		} while (lo < hi - 1e-3 && numiters < 32);		if (!success) {			fprintf(stderr, "warning: empty layer generated\n");		}if (jas_getdbglevel()) {fprintf(stderr, "success %d goodthresh %f\n", success, goodthresh);

⌨️ 快捷键说明

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