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

📄 decoder.c

📁 实现图像的jpeg无损压缩
💻 C
📖 第 1 页 / 共 3 页
字号:

#ifndef FIXRESET
		RESET=head_scan[0]->RES;
#else
		if (head_scan[0]->RES != DEFAULT_RESET) {
			fprintf(stderr,"ERROR: Version compiled for fixed RESET=%d parameter: got %d\n",DEFAULT_RESET,head_scan[0]->RES);
			exit(10);
		}
#endif

		/* Check to see if lossless or lossy */
		if (NEAR == 0)
			lossy=FALSE;
		else
			lossy=TRUE;

		/* Check for 16 or 8 bit mode */
		if (alpha0 <= MAXA16 && alpha0 > MAXA8)
		{
			/* 16 bit */
			bpp16 = TRUE;
			lutmax = LUTMAX16;
		}
		else if (alpha0 <= MAXA8 && alpha0 >= 1)
		{
			/* 8 bit */
			bpp16 = FALSE;
			lutmax = LUTMAX8;
		}
		else { 
			fprintf(stderr,"Got alpha = %d\n",alpha0+1);
			error("Bad value for alpha. Sorry...\n");
		}


		check_compatibility(head_frame,head_scan[0],0);

		for (i=0;i<components;i++) {
			samplingx[i]=head_frame->samplingx[i];
			samplingy[i]=head_frame->samplingy[i];
			if ((!multi) && ((samplingx[i]!=1) || (samplingy[i]!=1)) && (components>1))
			{
				fprintf(stderr,"\nERROR: Cannot use -P (PPM output) with subsampled compressed components\n");
				exit(10);
			}
		}

		if ((!multi) && (color_mode==PLANE_INT))
			if (components>1) {
				fprintf(stderr,"\nERROR: Cannot use -P (PPM output) with plane intereleaved mode\n");
				exit(10);
			}
			else multi=1;

			if ((multi) && (color_mode==PIXEL_INT)) {
				multi = 0;   /* equivalent to specifying -P flag */
			}

			if ((out_files>1) && (color_mode==PIXEL_INT)) {
				fprintf(stderr,"ERROR: Pixel interleaved mode uses only 1 output file\n");
				exit(10);
			}

			if ((multi) && (out_files) && (out_files!=components)) {
				fprintf(stderr,"ERROR: Number of files, %d%, for output must be equal to number of image components, %d\n",out_files,components);
				exit(10);
			}

			/* Compute the image size for the different components */
			if (components==1) {
				c_columns[0]=columns;
				c_rows[0]=rows;
				whose_max_size_rows=0;
				samplingy[0]=1;
			}
			else
			{
				max_samp_columns=0;
				max_samp_rows=0;
				for(i=0;i<components;i++) {
					if (samplingx[i]>max_samp_columns) {
						max_samp_columns=samplingx[i];
						whose_max_size_columns=i;
					}
					if (samplingy[i]>max_samp_rows) {
						max_samp_rows=samplingy[i];
						whose_max_size_rows=i;
					}
				}

				c_columns[whose_max_size_columns]=columns;	
				c_rows[whose_max_size_rows]=rows;

				for(i=0;i<components;i++) {
					if (i!=whose_max_size_columns)
					{
						c_columns[i]=c_columns[whose_max_size_columns]*samplingx[i];
						c_columns[i]/=samplingx[whose_max_size_columns];
					}
					if (i!=whose_max_size_rows) {
						c_rows[i]=c_rows[whose_max_size_rows]*samplingy[i];
						c_rows[i]/=samplingy[whose_max_size_rows];
					}
				}
			}


			/* Open out file */
			if ( outfilename == NULL ) {
				usage();
				exit(0);
			}
			else {
				if ( strcmp(outfilename,"-")==0 ) {
					out = stdout;
					msgfile = stderr;
				}
				else {
					if (multi==0) {
						if ( (out=fopen(outfilename,"wb")) == NULL ) {
							perror(outfilename);
							exit(10);
						}
					}
					else 
						for (i=0;i<components;i++)
							if ( (c_out[i]=fopen(c_outfilename[i],"wb")) == NULL )
							{
								perror(c_outfilename[i]);
								exit(10);
							}

				}
			}


			/* check that color mode is valid and pick color mode string */
			switch ( color_mode ) {

	case PLANE_INT:
		color_mode_string = plane_int_string;
		break;

	case LINE_INT:
		color_mode_string = line_int_string;
		break;

	case PIXEL_INT:
		color_mode_string = pixel_int_string;
		break;

	default:
		fprintf(stderr,"ERROR: Invalid color mode %d\n",color_mode);
		usage();
		exit(10);
			}

			if ( verbose ) {
				fprintf(msgfile,"%s\n",banner);
			}

			if ( verbose ) {
				if (!multi) {
					fprintf(msgfile,"Input  file: %s\nOutput file: %s\n",infilename,outfilename);
				}
				else {
					fprintf(msgfile,"Input  file: %s\nOutput files: ",infilename);
					for (i=0;i<components;i++)
						fprintf(msgfile," %s ",c_outfilename[i]);
					fprintf(msgfile,"\n");
				}
			}

#ifdef FIXALPHA
			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;
			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	

			if (lossy==TRUE)
			{
				/* compute auxiliary parameters for near-lossless (globals) */
				quant = 2*NEAR+1;
				qbeta = (alpha + 2*NEAR + quant-1 )/quant;
				beta = quant*qbeta;
				ceil_half_qbeta = (qbeta+1)/2;
				negNEAR = -NEAR;
				alpha1eps = alpha-1+NEAR;
				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++ );

			/* 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;   

			/* print out parameters */
			if ( verbose ) {
				if (!multi)
					fprintf(msgfile,"Image: cols=%d rows=%d alpha=%d comp=%d mode=%d (%s)\nParameters: Ta=%d Tb=%d Tc=%d RESET=%d limit=%d",
					columns, rows, alpha0, components, 
					color_mode, color_mode_string,
					T1, T2, T3, RESET,limit);
				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)\nParameters: Ta=%d Tb=%d Tc=%d RESET=%d limit=%d",
						alpha0, components, 
						color_mode, color_mode_string,
						T1, T2, T3,RESET,limit);
				}
			}

			if ( verbose )
				fprintf(msgfile,"\n");


			/* Write out the image header for PGM or PPM files */
			/* Must look at if there are Mapping Tables used */

			/* No Mapping Tables used */
			if (!head_scan[0]->need_table)
			{
				if (!multi) {
					if (components==1) fputs("P5\n", out);
					else if (components==3) fputs("P6\n", out);	
					else if (components==4) fputs("P7\n", out);
					else fprintf(out,"P%d\n",10+components);

					fprintf(out,"%d %d\n", columns, rows);
					fprintf(out,"%d\n", alpha - 1);
				}
				else
					for (i=0;i<components;i++) {
						fputs("P5\n", c_out[i]);
						fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
						fprintf(c_out[i],"%d\n", alpha - 1);
					}
			}

			/* Mapping Tables used */
			else
			{
				/* only 8 bit indexes supported for mapping tables */
				if (bpp16==TRUE)
				{
					fprintf(stderr, "Sorry, mapping tables are only supported for 8 bpp images in this implementation.\n");
					exit(0);
				}

				/* Mapping Table elements are 1 or 2 bytes */
				if (head_scan[0]->Wt==1 || head_scan[0]->Wt==2)
				{
					int alpha_temp;
					if (head_scan[0]->Wt==1)
						alpha_temp = alpha;
					else
						alpha_temp = alpha*alpha;

					if (!multi) 
					{
						if (components==1) fputs("P5\n", out);
						else if (components==3) fputs("P6\n", out);	
						else if (components==4) fputs("P7\n", out);
						else fprintf(out,"P%d\n",10+components);

						fprintf(out,"%d %d\n", columns, rows);
						fprintf(out,"%d\n", alpha_temp - 1);
					}
					else
						for (i=0;i<components;i++) 
						{
							fputs("P5\n", c_out[i]);
							fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
							fprintf(c_out[i],"%d\n", alpha_temp - 1);
						}
				}

				/* Mapping Table elements are 3 bytes */
				else if (head_scan[0]->Wt==3)
				{
					if (!multi) 
					{
						if (components==1) fputs("P6\n", out);
						else
						{
							fprintf(stderr,"Error : Cannot have a multi-component image and a mapping table with 3 bytes per element.\n");
							exit(0);
						}

						fprintf(out,"%d %d\n", columns, rows);
						fprintf(out,"%d\n", alpha - 1);
					}
					else
						for (i=0;i<components;i++) 
						{
							fputs("P6\n", c_out[i]);
							fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
							fprintf(c_out[i],"%d\n", alpha - 1);
						}
				}

				/* Mapping Table elements aren't 1 to 3 bytes */
				else
				{
					fprintf(stderr, "Sorry, mapping tables elements can only be 1 to 3 bytes in this implementation.\n");
					exit(0);
				}
			}


			/* Allocate memory pools. */
			initbuffers(multi, components);


			/* return size of the header, in bytes */
			return pos;

}




/* Main loop for decoding files */

int main (int argc, char *argv[]) {
	int n,n_c,n_r,my_i,n_s,mk,seek_return;
	int found_EOF = 0;
	double t0, t1, get_utime();
	long pos0, pos1,    
		tot_in = 0,
		tot_out = 0;
	pixel *local_scanl0,*local_scanl1,*local_pscanline,*local_cscanline;
	int MCUs_counted;
	char szArgv[4][256];

	msgfile = stdout;				// output msg to stdout


	/* Parse the parameters, initialize */
	/* Not yet fully implemented */
	bufiinit();
#ifdef CHIP_C5402
	argc	= 4;
	argv[1]="-P";
	argv[2]="F://Workspace//JPEG//jpeg_ls_v2.2//Encoder//lena24b.jls";
	argv[3]="-olena.ppm";
#endif
	
	pos0 = initialize(argc, argv); 


	/* start timer (must be AFTER initialize()) */
	t0 = get_utime();


	/* Initialize the scanline buffers */
	if (!multi)
		for (n = 0; n <= (columns + 1); ++n)
			pscanline[n] = 0;       
	else
		for (n_c=0;n_c<components;n_c++)
			for (n = 0; n <= (c_columns[n_c] + 1); ++n)
				c_pscanline[n_c][n] = 0;       

	if ((components>1) && (multi==0))
	{
		/* OUTPUT 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;
	}


	for (n_s=0;n_s<number_of_scans;n_s++)
	{
		/* Repeat prediction/quantization/statistics scanline by scanline,
		for each scan. */

		/* Reset Restart Markers for every scan */
		MCUs_counted = 0;

		/* This implementation supports parameters in 1st scan */
		if (n_s==0)
		{
			/* Prepare the quantization LUTs */
			prepareLUTs();

			if (lossy==TRUE)
				/* prepare div/mul tables for near-lossless quantization */
				prepare_qtables(alpha,NEAR);

		}
		else
		{	/* Read further scan headers */
			seek_return=seek_marker(in,&mk);
			if (seek_return == EOF)
			{
				fprintf(stderr,"*** Premature End of File seeking SOS marker\n");
				exit(10);
			}
			if ( seek_return > 2 )
			{
				fprintf(msgfile,"*** WARNING: %d extra bytes between end of scan and next marker.\n",seek_return-2);
				fprintf(msgfile,"***          Added to marker segment count.\n");
			}
			pos0 +=seek_return;
			if (mk != SOS)
			{
				fprintf(stderr,"Expecting SOS (%04x), got %04x\n",SOS,mk);
				exit(10);
			}
			seek_return = read_jpegls_scan(in,head_scan[n_s]); /* Read the scan header*/
			if (seek_return == EOF)
			{
				fprintf(stderr,"*** Premature End of File reading scan marker segment\n");
				exit(10);
			}
			pos0+=seek_return;
			if (head_scan[n_s]->shift!=0)
			{
				fprintf(stderr,"Got shift = %d != 0 : not implemented.\n",head_scan[n_s]->shift);
				exit(10);
			}
			if (head_scan[n_s]->NEAR != NEAR)
			{
				fprintf(stderr,"Got NEAR=%d after NEAR=%d: cannot change parameters between scans in this implementation\n",head_scan[n_s]->NEAR,NEAR);
				exit(10);
			}
			if ((head_scan[n_s]->color_mode != PLANE_INT) || (head_scan[n_s]->comp != 1) ||
				(head_scan[n_s]->comp_ids[0] != n_s+1))
			{
				fprintf(stderr,"This implementation supports multiple scans only in PLANE INTERLEAVED mode.\n");
				exit(10);
			}
		}

		/* Initializations for each scan */
		bitiinit();

		/* 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 int. */
			if (!multi) {
				/***********************************************************************/
				/*           Line interleaved mode with single file received           */
				/***********************************************************************/

				if (lossy==FALSE)

					/* LOSSLESS MODE */
					while (++n <= rows)
					{
						/* '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];

⌨️ 快捷键说明

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