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

📄 encoder.c

📁 JPEG连续色调静止图像无损压缩的最新标准JPEG LS的C语言实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	/* Print messages */	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;	/* 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 + -