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

📄 encoder.c

📁 实现图像的jpeg无损压缩
💻 C
📖 第 1 页 / 共 3 页
字号:
		if ( verbose )			fprintf(msgfile,"%s\n",banner);#define LESS_CONTEXTS 1		if ( verbose>1 )			fprintf(msgfile,"Number of contexts (non-run): %d regular + %d EOR = %d\n",CONTEXTS-LESS_CONTEXTS,EOR_CONTEXTS,TOT_CONTEXTS-LESS_CONTEXTS);		/* Read image headers*/		if (multi==0) {			if ( read_header_6(in, &columns, &rows, &alpha0, &components) != 0 )				error("Could not read image header. Must be PPM or PGM file.\n");			/* Single component => PLANE_INT */			if ( (color_mode==LINE_INT || color_mode==PIXEL_INT) && components==1) {					/*				fprintf(msgfile,"Single component received: Color mode changed to PLANE INTERLEAVED\n");				*/				color_mode=PLANE_INT;				color_mode_string = plane_int_string;				multi=1;				c_columns[0]=columns;				c_rows[0] = rows;				c_in[0]=in;			}		}		else {			for (i=0;i<components;i++) {				if (read_header_5(c_in[i], &(c_columns[i]), &(c_rows[i]), &alpha0) != 0 )					error("ERROR: Could not read image header. Must be PGM file.\n");				if (i==0) {					common_rows=c_rows[0];					common_alpha=alpha0;				}				else if ((alpha0!=common_alpha)) {					fprintf(stderr,"\nERROR: All components must have same maximal value\n");					exit(10);				}			}		}#ifdef FIXALPHA		alpha0++;		if ( alpha0 != alpha ) {			fprintf(stderr, "Sorry, this version has been optimized for alphabet size = %d, got %d\n",alpha,alpha0);			exit(10);		}#else		alpha = alpha0+1;  /* number read from file header is alpha-1 */		ceil_half_alpha = (alpha+1)/2;#endif#ifdef POW2		highmask = -alpha;		/* check that alpha is a power of 2 */		for ( alpha0=alpha, i=-1; alpha0; alpha0>>=1, i++);		if ( alpha != (1<<i) ) {			fprintf(stderr, "Sorry, this version has been optimized for alphabet size = power of 2, got %d\n",alpha);			exit(10);		}#endif			/* Check for 16 or 8 bit mode */		if (alpha <= MAXA16 && alpha > MAXA8)		{			bpp16 = TRUE;			lutmax = LUTMAX16;		}		else if (alpha <= MAXA8 && alpha >= 1)		{			bpp16 = FALSE;			lutmax = LUTMAX8;		}		else { 			fprintf(stderr,"Got alpha = %d\n",alpha);			error("Bad value for alpha. Sorry...\n");		}		/* print out parameters */		if ( verbose ) {			if (!multi)				fprintf(msgfile,"Input  file: %s\nOutput file: %s\n",infilename,outfilename);			else {				fprintf(msgfile,"Input  files: ");				for (i=0;i<components;i++)					fprintf(msgfile," %s ",c_infilename[i]);				fprintf(msgfile,"\nOutput file: %s\n",outfilename);			}			if (!multi)				fprintf(msgfile,"Image: cols=%d rows=%d alpha=%d comp=%d mode=%d (%s)",				columns, rows, alpha, components, 				color_mode, color_mode_string);			else {				fprintf(msgfile,"Image: cols=");				for (i=0;i<components;i++)					fprintf(msgfile," %d",c_columns[i]);				fprintf(msgfile," rows=");				for (i=0;i<components;i++)					fprintf(msgfile," %d",c_rows[i]);				fprintf(msgfile," alpha=%d comp=%d mode=%d (%s)",					alpha, components, color_mode,					color_mode_string);			}			fprintf(msgfile,"\n");		}		/* compute auxiliary parameters for near-lossless (globals) */		if (lossy==TRUE) {			quant = 2*NEAR+1;			qbeta = (alpha + 2*NEAR + quant-1 )/quant;			beta = quant*qbeta;			ceil_half_qbeta = (qbeta+1)/2;			negNEAR = -NEAR;			if ( verbose )				fprintf(msgfile,"Near-lossless mode: NEAR = %d  beta = %d  qbeta = %d\n",NEAR,beta,qbeta);		}		/* compute bits per sample for input symbols */		for ( bpp=1; (1L<<bpp)<alpha; bpp++ );		/* check if alpha is a power of 2: */		if ( alpha != (1<<bpp) )			need_lse = 1; /* if not, MAXVAL will be non-default, and 						  we'll need to specify it in an LSE marker */		/* compute bits per sample for unencoded prediction errors */		if (lossy==TRUE)			for ( qbpp=1; (1L<<qbpp)<qbeta; qbpp++ );		else			qbpp = bpp;		if ( bpp < 2 ) bpp = 2;		/* limit for unary part of Golomb code */		if ( bpp < 8 )			limit = 2*(bpp + 8) - qbpp -1;		else			limit = 4*bpp - qbpp - 1;   		/* check for smallest subsampled file and compute the sampling */		if ((components>1) && (multi)) {			min_size_columns=c_columns[components-1];			min_size_rows=c_rows[components-1];			for (i=0;i<components-1;i++) {				if (c_columns[i]<min_size_columns) 					min_size_columns=c_columns[i];				if (c_rows[i]<min_size_rows) 					min_size_rows=c_rows[i];			}			for (i=0;i<components;i++) {				samplingx[i]=c_columns[i]/min_size_columns;				samplingy[i]=c_rows[i]/min_size_rows;				if ((samplingx[i]>4) || ((c_columns[i]%min_size_columns)!=0)) {					fprintf(stderr,"\nImage sizes not compatible\n");					exit(10);				}				if ((samplingy[i]>4) || ((c_rows[i]%min_size_rows)!=0)) {					fprintf(stderr,"\nImage sizes not compatible\n");					exit(10);				}			}			min_size_columns=c_columns[0];			whose_max_size_columns=0;			min_size_rows=c_rows[0];			whose_max_size_rows=0;			for (i=1;i<components;i++) { 				if (c_columns[i]>min_size_columns) {					whose_max_size_columns=i;					min_size_columns=c_columns[i];				}				if (c_rows[i]>min_size_rows) {					whose_max_size_rows=i;					min_size_rows=c_rows[i];				}			}		}		else {			for (i=0;i<components;i++) samplingx[i] = samplingy[i] = 1;		}		/* Allocate memory pools. */		initbuffers(multi, components);  }int main (int argc, char *argv[]) {	int n,n_c,n_r,my_i, number_of_scans, n_s, i;	double t0, t1, get_utime();	long tot_in = 0,		tot_out = 0,		pos0, pos1;	int temp_columns;	int MCUs_counted;	pixel *local_scanl0,*local_scanl1,*local_pscanline,*local_cscanline;	application_header = all_header = 0;	msgfile = stdout;	/* Parse the parameters, initialize */	initialize(argc, argv); 	/* Start timer (must be AFTER initialize()) */	t0 = get_utime();   	/* Compute the number of scans */	/* Multiple scans only for PLANE_INT in this implementation */	if (color_mode==PLANE_INT)		number_of_scans=components;	else		number_of_scans = 1;	/* Write the frame header - allocate memory for jpegls header */	head_frame = (jpeg_ls_header *) safecalloc(1,sizeof(jpeg_ls_header));	for (n_s=0;n_s<number_of_scans;n_s++)		head_scan[n_s] = (jpeg_ls_header *) safecalloc(1,sizeof(jpeg_ls_header));	/* Assigns columns/rows to head_frame */	if (!multi) {		head_frame->columns=columns;		head_frame->rows=rows;	}	else {		head_frame->columns=c_columns[whose_max_size_columns];		head_frame->rows=c_rows[whose_max_size_rows];	}	head_frame->alp=alpha;	head_frame->comp=components;	/* Assign component id and samplingx/samplingy */	for (i=0;i<components;i++) {		head_frame->comp_ids[i]=i+1;		head_frame->samplingx[i]=samplingx[i];		head_frame->samplingy[i]=samplingy[i];	}	head_frame->NEAR=NEAR; /* Not needed, scan information */	head_frame->need_lse=need_lse; /* Not needed, for commpletness  */	head_frame->color_mode=color_mode; /* Not needed, scan information */	head_frame->shift=shift; /* Not needed, scan information */	for (n_s=0;n_s<number_of_scans;n_s++) {		head_scan[n_s]->alp = alpha;		head_scan[n_s]->NEAR = NEAR;		head_scan[n_s]->T1 = T1;		head_scan[n_s]->T2 = T2;		head_scan[n_s]->T3 = T3;		head_scan[n_s]->RES = RESET;		head_scan[n_s]->shift = shift;		head_scan[n_s]->color_mode = color_mode;	}	if (color_mode==PLANE_INT) { /* One plane per scan */		for (n_s=0;n_s<number_of_scans;n_s++) {			head_scan[n_s]->comp=1;			head_scan[n_s]->comp_ids[0]=n_s+1;		}	}	else {		for (n_s=0;n_s<number_of_scans;n_s++) {			head_scan[n_s]->comp=head_frame->comp;			for (n_c=0;n_c<head_frame->comp;n_c++)				head_scan[n_s]->comp_ids[n_c]=n_c+1;		}	}	/* Write SOI */	all_header = write_marker(out, SOI);	/* Write the frame */	all_header += write_jpegls_frame(out, head_frame);	/* End of frame header writing */	if ((components>1) && (multi==0)) {		/* Received PPM file, allocate auxiliary buffers */		local_scanl0 = (pixel *)safecalloc(columns+LEFTMARGIN+RIGHTMARGIN,sizeof(pixel) );		local_scanl1 = (pixel *)safecalloc(columns+LEFTMARGIN+RIGHTMARGIN,sizeof(pixel) );		local_pscanline = local_scanl0 + LEFTMARGIN-1;		local_cscanline = local_scanl1 + LEFTMARGIN-1;	}	/* Go through each scan and process line by line */	for (n_s=0;n_s<number_of_scans;n_s++) {		/* process scans one by one */		if (n_s==0) {			/* The thresholds for the scan. Must re-do per scan is change. */			set_thresholds(alpha, NEAR, &T1, &T2, &T3);			for (i=0;i<number_of_scans;i++) {				head_scan[n_s]->T1=T1;				head_scan[n_s]->T2=T2;				head_scan[n_s]->T3=T3;			}			/* After the thresholds are set, write LSE marker if we have */			/* non-default parameters or if we need a mapping table */			if ( need_lse != 0 )				all_header += write_jpegls_extmarker(out, head_scan[n_s], LSE_PARAMS, mappingtablefilename);			if ( need_table != 0 )				all_header += write_jpegls_extmarker(out, head_scan[n_s], LSE_MAPTABLE, mappingtablefilename);			/* If using restart markers, write the DRI header */			if ( need_restart != 0 )			{					head_scan[n_s]->restart_interval = restart_interval;				all_header += write_jpegls_restartmarker(out, head_scan[n_s]);			}			/* Print out parameters */			if (verbose)				fprintf(msgfile,"Parameters: T1=%d T2=%d T3=%d RESET=%d limit=%d\n",T1, T2, T3,RESET,limit);			/* Prepare LUTs for context quantization */			/* Must re-do when Thresholds change */			prepareLUTs();			if (lossy==TRUE)				/* prepare div/mul tables for near-lossless quantization */				prepare_qtables(alpha, NEAR);			/* Check for errors */			check_compatibility(head_frame, head_scan[0],0);		}		/* Restart Marker is reset after every scan */		MCUs_counted = 0;		/* Write the scan header */		all_header += write_jpegls_scan(out, head_scan[n_s]);		pos0 = ftell(out);  /* position in output file, after header */		/* Initializations for each scan */		/* Start from 1st image row */		n=0;		/* initialize stats arrays */		if (lossy==TRUE)			init_stats(qbeta);		else			init_stats(alpha);		/* initialize run processing */		init_process_run(MAXRUN);		if (color_mode==LINE_INT) {	/* line interleaved */			if (!multi) { 			/* Single file received */				/***********************************************************************/				/*           Line interleaved mode with single file received           */				/***********************************************************************/				if (lossy==FALSE)					/* LOSSLESS mode */					while (++n <= rows) {						read_one_line(cscanline + components, components*columns, in);						tot_in += components*columns;						/* 'extend' the edges */						for (n_c=0;n_c<components;n_c++)							cscanline[-components+n_c] = cscanline[n_c]=pscanline[components+n_c];						for (n_c=0;n_c<components;n_c++) {							if (components > 1) {								for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++){									local_cscanline[-1+my_i]=cscanline[-components+my_i*components+n_c];									local_pscanline[-1+my_i]=pscanline[-components+my_i*components+n_c];								}							}							else {								local_cscanline=cscanline;								local_pscanline=pscanline;							}							/* process the lines */							lossless_doscanline(local_pscanline, local_cscanline, columns,n_c);						}						/* 'extend' the edges */						for (n_c=0;n_c<components;n_c++)							cscanline[components*(columns+1)+n_c]=cscanline[components*columns+n_c];						/* make the current scanline the previous one */						swaplines();						/* Insert restart markers if enabled */						if (need_restart)						{							/* Insert restart markers only after a restart interval */							if ((MCUs_counted % restart_interval) == 0)							{								bitoflush();								write_marker(out, (RSTm + ((MCUs_counted / restart_interval)%8)));							}							MCUs_counted++;						}					}				else					/* LOSSY mode */					while (++n <= rows) {						read_one_line(cscanline + components, components*columns, in);						tot_in += components*columns;						/* 'extend' the edges */						for (n_c=0;n_c<components;n_c++)							cscanline[-components+n_c] = cscanline[n_c]=pscanline[components+n_c];						for (n_c=0;n_c<components;n_c++) {							if (components > 1) {								for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++){									local_cscanline[-1+my_i]=cscanline[-components+my_i*components+n_c];									local_pscanline[-1+my_i]=pscanline[-components+my_i*components+n_c];								}							}							else {								local_cscanline=cscanline;								local_pscanline=pscanline;							}							/* process the lines */							lossy_doscanline(local_pscanline, local_cscanline, columns,n_c);							if (components>1)								for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)									cscanline[-components+my_i*components+n_c]=local_cscanline[-1+my_i];						}						/* 'extend' the edges */						for (n_c=0;n_c<components;n_c++)

⌨️ 快捷键说明

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