www.pudn.com > 医学图像处理示例源代码.rar > Jpegfile.cpp


//////////////////////////////////////////////////////////// 
//	JpegFile - A C++ class to allow reading and writing of 
//	RGB and Grayscale JPEG images. 
//	It is based on the IJG V.6 code. 
// 
//	This class Copyright 1997, Chris Losinger 
//	This is free to use and modify provided my name is  
//	included. 
// 
//	See jpegfile.h for usage. 
// 
//////////////////////////////////////////////////////////// 
#include "stdafx.h" 
#include "image.h" 
#include "JpegFile.h" 
 
#include  
 
#ifdef __cplusplus 
	extern "C" { 
#endif // __cplusplus 
 
#include "jpeglib.h" 
 
#ifdef __cplusplus 
	} 
#endif // __cplusplus 
 
 
// is used for the optional error recovery mechanism shown in 
//the second part of the example. 
#include  
 
// error handler, to avoid those pesky exit(0)'s 
struct my_error_mgr  
{ 
  struct jpeg_error_mgr pub;	/* "public" fields */ 
  jmp_buf setjmp_buffer;	/* for return to caller */ 
}; 
 
typedef struct my_error_mgr * my_error_ptr; 
 
METHODDEF(void) my_error_exit (j_common_ptr cinfo); 
 
 
//	to handle fatal errors. 
//	the original JPEG code will just exit(0). can't really 
//	do that in Windows.... 
METHODDEF(void) my_error_exit (j_common_ptr cinfo) 
{ 
	// cinfo->err really points to a my_error_mgr struct, so coerce pointer  
	my_error_ptr myerr = (my_error_ptr) cinfo->err; 
 
	char buffer[JMSG_LENGTH_MAX]; 
 
	// Create the message  
	(*cinfo->err->format_message) (cinfo, buffer); 
 
	// Always display the message.  
	MessageBox(NULL,buffer,"JPEG Fatal Error",MB_ICONSTOP); 
 
 
	// Return control to the setjmp point  
	longjmp(myerr->setjmp_buffer, 1); 
} 
 
//	constructor doesn't do much - there's no real class here... 
JpegFile::JpegFile() 
{ 
} 
 
JpegFile::~JpegFile() 
{ 
} 
 
//	read a JPEG file 
BOOL JpegFile::JpegFileToRGB(CString fileName,  BYTE** lpimg) 
 
{ 
	// basic code from IJG Jpeg Code v6 example.c 
	UINT width,  height, Depth; 
	// This struct contains the JPEG decompression parameters and pointers to 
	// working space (which is allocated as needed by the JPEG library).	 
	struct jpeg_decompress_struct cinfo; 
	// We use our private extension JPEG error handler. 
	// Note that this struct must live as long as the main JPEG parameter 
	// struct, to avoid dangling-pointer problems. 
 	struct my_error_mgr jerr; 
	// More stuff   
	FILE * infile = NULL;	// source file   
 
	JSAMPARRAY buffer;		// Output row buffer       
	int  row_stride;		// physical row width in output buffer   
	char buf[250]; 
 
	// In this example we want to open the input file before doing anything else, 
	// so that the setjmp() error recovery below can assume the file is open. 
	// VERY IMPORTANT: use "b" option to fopen() if you are on a machine that 
	// requires it in order to read binary files.	  
	if ((infile = fopen(fileName, "rb")) == NULL)  
	{ 
		sprintf(buf, "JPEG :\nCan't open %s\n", fileName); 
		AfxMessageBox(buf); 
		return NULL; 
	} 
 
	// Step 1: allocate and initialize JPEG decompression object  
	// We set up the normal JPEG error routines, then override error_exit.   
	cinfo.err = jpeg_std_error(&jerr.pub); 
	jerr.pub.error_exit = my_error_exit; 
 
	// Establish the setjmp return context for my_error_exit to use.   
	if( setjmp(jerr.setjmp_buffer) ) 
	{ 
		// If we get here, the JPEG code has signaled an error. 
		// We need to clean up the JPEG object, close the input file, and return. 
		jpeg_destroy_decompress(&cinfo); 
		if( infile != NULL ) fclose(infile); 
		return NULL; 
	} 
	 
    //TRACE("Size of cinfo is %d\n",sizeof(cinfo)); 
	//TRACE("think Size of cinfo is %d\n",sizeof(struct jpeg_compress_struct)); 
	// Now we can initialize the JPEG decompression object.   
	jpeg_create_decompress(&cinfo); 
 
	// Step 2: specify data source (eg, a file)  
    // cinfo.dither_mode = JDITHER_NONE;	 
	jpeg_stdio_src(&cinfo, infile); 
 
	// Step 3: read file parameters with jpeg_read_header() 
	(void) jpeg_read_header(&cinfo, TRUE); 
	// We can ignore the return value from jpeg_read_header since 
	//  (a) suspension is not possible with the stdio data source, and 
	//   (b) we passed TRUE to reject a tables-only JPEG file as an error. 
	// See libjpeg.doc for more info. 
	// Step 4: set parameters for decompression   
 
	// In this example, we don't need to change any of the defaults set by 
	// jpeg_read_header(), so we do nothing here. 
 
	// Step 5: Start decompressor  
	(void) jpeg_start_decompress(&cinfo); 
	// We can ignore the return value since suspension is not possible 
	// with the stdio data source. 
 
	// We may need to do some setup of our own at this point before reading 
	// the data.  After jpeg_start_decompress() we have the correct scaled 
	// output image dimensions available, as well as the output colormap 
	// if we asked for color quantization. 
	// In this example, we need to make an output work buffer of the right size. 
	// get our buffer set to hold data 
	// alloc and open our new buffer	 
    cinfo.dct_method  = JDCT_IFAST; 
	// how big is this thing gonna be? 
	width  = cinfo.output_width; 
	height = cinfo.output_height; 
	Depth  = cinfo.num_components; 
	 
	// JSAMPLEs per row in output buffer 
	row_stride = cinfo.output_width * cinfo.output_components; 
 
	// Make a one-row-high sample array that will go away when done with image  
	buffer = (*cinfo.mem->alloc_sarray) 
		((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); 
 
	// Step 6: while (scan lines remain to be read)  
	//           jpeg_read_scanlines(...); 
 
	// Here we use the library's state variable cinfo.output_scanline as the 
	// loop counter, so that we don't have to keep track ourselves. 
	int row;  
	while (cinfo.output_scanline < cinfo.output_height)  
	{ 
		// jpeg_read_scanlines expects an array of pointers to scanlines. 
		// Here the array is only one element long, but you could ask for 
		// more than one scanline at a time if that's more convenient. 
		(void) jpeg_read_scanlines(&cinfo, buffer, 1); 
		// Assume put_scanline_someplace wants a pointer and sample count.  
		// asuumer all 3-components are RGBs 
		row = cinfo.output_scanline- 1; 
		if (cinfo.out_color_components==3)  
		{ 
			RGBTRIPLE* pixptr = (RGBTRIPLE*)lpimg[row]; 
			BYTE *lptemp = buffer[0]; 
			for(UINT i= 0; irgbtRed   = *lptemp++; 
				pixptr->rgbtGreen = *lptemp++; 
				pixptr->rgbtBlue  = *lptemp++; 
			} 
		} 
		else if (cinfo.out_color_components==1) 
		{ 
			memcpy(lpimg[row], buffer[0], width); 
		} 
	} 
 
	// Step 7: Finish decompression 
	(void) jpeg_finish_decompress(&cinfo); 
	// We can ignore the return value since suspension is not possible 
	// with the stdio data source. 
	// Step 8: Release JPEG decompression object   
	// This is an important step since it will release a good deal of memory. 
	jpeg_destroy_decompress(&cinfo); 
	// After finish_decompress, we can close the input file. 
	// Here we postpone it until after no more JPEG errors are possible, 
	// so as to simplify the setjmp error logic above.  (Actually, I don't 
	// think that jpeg_destroy can do an error exit, but why assume anything...) 
	fclose(infile); 
	// At this point you may want to check to see whether any corrupt-data 
	// warnings occurred (test whether jerr.pub.num_warnings is nonzero). 
	return true; 
} 
 
BOOL JpegFile::GetJPGDimensions(CString fileName, 
								UINT &width, 
								UINT &height, 
								UINT &Depth) 
{ 
	// basic code from IJG Jpeg Code v6 example.c 
 
	// This struct contains the JPEG decompression parameters and pointers to 
	// working space (which is allocated as needed by the JPEG library). 
	struct jpeg_decompress_struct cinfo; 
	// We use our private extension JPEG error handler. 
	// Note that this struct must live as long as the main JPEG parameter 
	// struct, to avoid dangling-pointer problems. 
	struct my_error_mgr jerr; 
	// More stuff  
	FILE * infile=NULL; 
	char buf[250]; 
 
	// In this example we want to open the input file before doing anything else, 
	// so that the setjmp() error recovery below can assume the file is open. 
	// VERY IMPORTANT: use "b" option to fopen() if you are on a machine that 
	// requires it in order to read binary files. 
 
	if ((infile = fopen(fileName, "rb")) == NULL)  
	{ 
		sprintf(buf, "JPEG :\nCan't open %s\n", fileName); 
		AfxMessageBox(buf); 
		return FALSE; 
	} 
 
	// Step 1: allocate and initialize JPEG decompression object 
	// We set up the normal JPEG error routines, then override error_exit. 
	cinfo.err = jpeg_std_error(&jerr.pub); 
	jerr.pub.error_exit = my_error_exit; 
 
 
	// Establish the setjmp return context for my_error_exit to use. 
	if (setjmp(jerr.setjmp_buffer))  
	{ 
		// If we get here, the JPEG code has signaled an error. 
		//  We need to clean up the JPEG object, close the input file, and return. 
		jpeg_destroy_decompress(&cinfo); 
 
		if (infile!=NULL) fclose(infile); 
		return FALSE; 
	} 
 
	// Now we can initialize the JPEG decompression object. 
	jpeg_create_decompress(&cinfo); 
 
	// Step 2: specify data source (eg, a file) 
 
	jpeg_stdio_src(&cinfo, infile); 
 
	// Step 3: read file parameters with jpeg_read_header() 
 
	(void) jpeg_read_header(&cinfo, TRUE); 
	// We can ignore the return value from jpeg_read_header since 
	//   (a) suspension is not possible with the stdio data source, and 
	//   (b) we passed TRUE to reject a tables-only JPEG file as an error. 
	// See libjpeg.doc for more info. 
	// how big is this thing ? 
	width  = cinfo.image_width; 
	height = cinfo.image_height; 
	Depth  = cinfo.num_components << 3; 
	// Step 8: Release JPEG decompression object 
	// This is an important step since it will release a good deal of memory. 
	jpeg_destroy_decompress(&cinfo); 
 
	// After finish_decompress, we can close the input file. 
	// Here we postpone it until after no more JPEG errors are possible, 
	// so as to simplify the setjmp error logic above.  (Actually, I don't 
	// think that jpeg_destroy can do an error exit, but why assume anything...) 
	fclose(infile); 
 
	return TRUE; 
} 
 
BOOL JpegFile::RGBToJpegFile(CString fileName,  
							BYTE **dataBuf, 
							UINT widthPix, 
							UINT height, 
							BOOL color,  
							int  quality) 
{ 
	if (dataBuf==NULL || widthPix==0 || height==0) return FALSE; 
 
	struct jpeg_compress_struct cinfo; 
	// More stuff  
	FILE * outfile=NULL;			// target file  
 
	struct my_error_mgr jerr; 
 
	// Step 1: allocate and initialize JPEG compression object  
	cinfo.err = jpeg_std_error(&jerr.pub); 
	jerr.pub.error_exit = my_error_exit; 
 
	// Establish the setjmp return context for my_error_exit to use.  
	if (setjmp(jerr.setjmp_buffer))  
	{ 
		// If we get here, the JPEG code has signaled an error. 
		// We need to clean up the JPEG object, close the input file, and return.  
		jpeg_destroy_compress(&cinfo); 
 
		if (outfile!=NULL) fclose(outfile); 
		return FALSE; 
	} 
 
	// Now we can initialize the JPEG compression object. 
	jpeg_create_compress(&cinfo); 
 
	// Step 2: specify data destination (eg, a file)  
	// Note: steps 2 and 3 can be done in either order.  
	if ((outfile = fopen(fileName, "wb")) == NULL)  
	{ 
		char buf[250]; 
		sprintf(buf, "JpegFile :\nCan't open %s\n", fileName); 
		AfxMessageBox(buf); 
		return FALSE; 
	} 
 
	jpeg_stdio_dest(&cinfo, outfile); 
 
	// Step 3: set parameters for compression  
												     
	// First we supply a description of the input image. 
	// Four fields of the cinfo struct must be filled in: 
 	cinfo.image_width  = widthPix; 	// image widthPix and height, in pixels  
	cinfo.image_height = height; 
	if (color)  
	{ 
		cinfo.input_components = 3;		// # of color components per pixel   
		cinfo.in_color_space = JCS_RGB; 	// colorspace of input image   
	} 
	else 
	{ 
		cinfo.input_components = 1;		//# of color components per pixel   
		cinfo.in_color_space = JCS_GRAYSCALE; 	// colorspace of input image  
	} 
 
    // Now use the library's routine to set default compression parameters. 
    // (You must set at least cinfo.in_color_space before calling this, 
    // since the defaults depend on the source color space.) 
	jpeg_set_defaults(&cinfo); 
    // Now you can set any non-default parameters you wish to. 
    // Here we just illustrate the use of quality (quantization table) scaling: 
    jpeg_set_quality(&cinfo, quality, TRUE );// limit to baseline-JPEG values 
    // Step 4: Start compressor   
    // TRUE ensures that we will write a complete interchange-JPEG file. 
    // Pass TRUE unless you are very sure of what you're doing. 
    jpeg_start_compress(&cinfo, TRUE); 
    // Step 5: while (scan lines remain to be written)   
    //           jpeg_write_scanlines(...);   
 
    // Here we use the library's state variable cinfo.next_scanline as the 
    // loop counter, so that we don't have to keep track ourselves. 
    // To keep things simple, we pass one scanline per call; you can pass 
    // more if you wish, though. 
 
	BYTE *outRow; 
	if( color ) 
	{ 
		UINT i; 
		RGBTRIPLE* pixptr; 
		BYTE *lptemp; 
		outRow = new BYTE[widthPix * 3]; 
		while (cinfo.next_scanline < cinfo.image_height)  
		{ 
			// jpeg_write_scanlines expects an array of pointers to scanlines. 
			// Here the array is only one element long, but you could pass 
			// more than one scanline at a time if that's more convenient. 
			pixptr = (RGBTRIPLE*)dataBuf[cinfo.next_scanline]; 
			lptemp = outRow; 
			for(i= 0; irgbtRed  ; 
				*lptemp++ = pixptr->rgbtGreen; 
				*lptemp++ = pixptr->rgbtBlue ; 
			} 
	 
			(void) jpeg_write_scanlines(&cinfo, &outRow, 1); 
		} 
		if(outRow != NULL) delete []outRow; 
	} 
	else 
	{ 
		while (cinfo.next_scanline < cinfo.image_height)  
		{ 
			// jpeg_write_scanlines expects an array of pointers to scanlines. 
			// Here the array is only one element long, but you could pass 
			// more than one scanline at a time if that's more convenient. 
			outRow = dataBuf[cinfo.next_scanline]; 
			(void) jpeg_write_scanlines(&cinfo, &outRow, 1); 
		} 
	} 
    // Step 6: Finish compression   
    jpeg_finish_compress(&cinfo); 
    // After finish_compress, we can close the output file.   
    fclose(outfile); 
    // Step 7: release JPEG compression object   
    // This is an important step since it will release a good deal of memory.   
    jpeg_destroy_compress(&cinfo); 
    return TRUE; 
} 
 
//	swap Rs and Bs 
//	Note! this does its stuff on buffers with a whole number of pixels 
//	per data row!! 
BOOL JpegFile::BGRFromRGB(BYTE *buf, UINT widthPix, UINT height) 
{ 
	if (buf==NULL) 	return FALSE; 
 
    UINT Pitch = widthPix*3; 
	BYTE *red,*blue,tmp; 
	BYTE *TmpBuf = buf; 
	for (UINT row=0; row255) ? 255 : i); 
	 
	for(i= 0; i<400; i++) 
		bClipArray[i] = 0; 
	for(i= 656; i<1024; i++) 
		bClipArray[i] = 255; 
	blpClip = bClipArray + 400; 
	for(i= 0; i<256; i++) 
		blpClip[i] = BYTE(i); 
 
} 
JpegFile1::~JpegFile1() 
{ 
	if( lpJpegBuf != NULL ) delete []lpJpegBuf; 
} 
BOOL JpegFile1::OpenJPGFile(CString FlieName) 
{ 
	CFile* pReadFile = new CFile( FlieName, CFile::modeRead | CFile::shareCompat); 
	//get jpg file length 
	JpegBufSize=pReadFile->GetLength(); 
	lpJpegBuf = new BYTE[JpegBufSize]; 
	pReadFile->ReadHuge(lpJpegBuf, JpegBufSize); 
	delete pReadFile; 
 
	BOOL bR = InitTag() == 0; 
	LineBytes = (ImgWidth* comp_num+ 3) & ~3 ; 
	ImgSize = LineBytes* ImgHeight; 
	return bR; 
} 
BOOL JpegFile1::ReadJPGData(BYTE **lpParam) 
{ 
	lpImgData = lpParam; 
	funcret = Decode(); 
	return true; 
} 
int JpegFile1::InitTag() 
{ 
	BOOL   finish = false; 
	short  llength, ccount; 
	short  i, j, k; 
	short  huftab1,huftab2; 
	short  huftabindex; 
	BYTE   id, hf_table_index, qt_table_index, comnum, *lptemp; 
 
	lp = lpJpegBuf + 2; 
 
	while (!finish) 
	{ 
		id = *(lp+ 1); 
		lp += 2; 
		switch( id ) 
		{ 
		case M_APP0: 
			llength = *(lp+1) | ( *lp<<8 ); 
			lp += llength; 
			break; 
		case M_DQT: 
			llength = *(lp+1) | ( *lp<<8 ); 
			qt_table_index = ( *(lp+ 2) ) & 0x0f; 
			lptemp = lp + 3; 
			if(llength<80) 
			{ 
				for(i= 0; i< 64; i++) 
					qt_table[qt_table_index][i] = *(lptemp++); 
			} 
			else 
			{ 
				for(i= 0; i< 64; i++) 
					qt_table[qt_table_index][i] = *(lptemp++); 
                qt_table_index = ( *(lptemp++) )&0x0f; 
  				for(i= 0; i< 64; i++) 
					qt_table[qt_table_index][i] = *(lptemp++); 
  			} 
  			lp += llength; 
			break; 
		case M_SOF0: 
	 		llength   = *(lp+1) | ( *lp<<8 ); 
	 		ImgHeight = *(lp+4) | ( *(lp+3)<<8 ); 
	 		ImgWidth  = *(lp+6) | ( *(lp+5)<<8 ); 
            comp_num  = *(lp+ 7); 
		    if( (comp_num!=1) && (comp_num!=3)) 
	  			return 1; 
			if( comp_num==3 ) 
			{ 
				comp_index[0] = *(lp+ 8); 
	  			SampRate_Y_H  = (*(lp+ 9))>>4; 
	  			SampRate_Y_V  = (*(lp+ 9))&0x0f; 
	  			YQtTable      = (short *)qt_table[*(lp+10)]; 
 
				comp_index[1] = *(lp+ 11); 
				SampRate_U_H  = (*(lp+ 12))>>4; 
	  			SampRate_U_V  = (*(lp+ 12))&0x0f; 
	  			UQtTable      = (short *)qt_table[*(lp+13)]; 
 
	  			comp_index[2] = *(lp+14); 
	  			SampRate_V_H  = (*(lp+15))>>4; 
	  			SampRate_V_V  = (*(lp+15))&0x0f; 
				VQtTable	  = (short *)qt_table[*(lp+16)]; 
	  		} 
			else 
			{ 
	  			comp_index[0] = *(lp+ 8); 
				SampRate_Y_H  = (*(lp+ 9))>>4; 
	  			SampRate_Y_V  = (*(lp+ 9))&0x0f; 
	  			YQtTable	  = (short *)qt_table[*(lp+10)]; 
 
				comp_index[1] = *(lp+ 8); 
	  			SampRate_U_H  = 1; 
	  			SampRate_U_V  = 1; 
	  			UQtTable	  = (short *)qt_table[*(lp+10)]; 
 
				comp_index[2] = *(lp+ 8); 
				SampRate_V_H  = 1; 
	  			SampRate_V_V  = 1; 
	  			VQtTable	  = (short *)qt_table[*(lp+10)]; 
			} 
			SampRate_Y_H8 = SampRate_Y_H << 3; 
			SampRate_Y_V8 = SampRate_Y_V << 3; 
  			lp += llength; 
			break; 
		case M_DHT:              
			llength = *(lp+1) | ( *lp<<8 ); 
			if (llength<0xd0) 
			{ 
				huftab1		= (short)(*(lp+ 2))>>4;     //huftab1=0,1 
		 		huftab2		= (short)(*(lp+ 2))&0x0f;   //huftab2=0,1 
				huftabindex = huftab1* 2 + huftab2; 
		 		lptemp = lp + 3; 
				for(i=0; i<16; i++) 
					code_len_table[huftabindex][i] = (short)(*(lptemp++)); 
				j = 0; 
				for(i=0; i<16; i++) 
				{ 
					if(code_len_table[huftabindex][i]!=0) 
					{ 
						k=0; 
						while(k>4;     //huftab1=0,1 
			 		huftab2 = (short)hf_table_index&0x0f;   //huftab2=0,1 
					huftabindex = huftab1* 2+huftab2; 
					lptemp = lp+1; 
					ccount = 0; 
					for(i=0; i<16; i++) 
					{ 
						code_len_table[huftabindex][i] = (short)(*(lptemp++)); 
						ccount += code_len_table[huftabindex][i]; 
					} 
					ccount += 17;	 
					j = 0; 
					for(i=0; i<16; i++) 
						if(code_len_table[huftabindex][i]!=0) 
						{ 
							k=0; 
							while(k>4;//Y 
					YAcIndex = ((*(lptemp+1))&0x0f)+2; 
				} 
				else 
				{ 
					UVDcIndex = (*(lptemp+1))>>4;//U,V 
					UVAcIndex = ((*(lptemp+1))&0x0f)+2; 
				} 
				lptemp += 2; 
			} 
			lp += llength; 
			finish = TRUE; 
			break; 
		case M_EOI:     
			return 1; 
			break; 
		default: 
 			if ((id&0xf0)!=0xd0) 
			{ 
				llength = *(lp+1) | ( *lp<<8 ); 
	 			lp += llength; 
			} 
			else  
				lp += 2; 
			break; 
  		}//switch 
	} //while 
	return 0; 
} 
 
int JpegFile1::Decode()  
{ 
	int funcret; 
 
	Y_in_MCU = SampRate_Y_H* SampRate_Y_V; 
	U_in_MCU = SampRate_U_H* SampRate_U_V; 
	V_in_MCU = SampRate_V_H* SampRate_V_V; 
	H_YtoU	 = SampRate_Y_H/ SampRate_U_H; 
	V_YtoU	 = SampRate_Y_V/ SampRate_U_V; 
	H_YtoV	 = SampRate_Y_H/ SampRate_V_H; 
	V_YtoV	 = SampRate_Y_V/ SampRate_V_V; 
 
	int add1 = SampRate_Y_H << 3; 
	int add2 = SampRate_Y_V << 3; 
	while((funcret=DecodeMCUBlock())==0) 
	{ 
		interval++; 
		IntervalFlag = restart && (interval % restart==0); 
		 
		IQtIZzMCUComponent(0); 
		IQtIZzMCUComponent(1); 
		IQtIZzMCUComponent(2); 
		GetYUV(0); 
		GetYUV(1); 
		GetYUV(2); 
		StoreBuffer(); 
		sizej += add1; 
		if( sizej >= ImgWidth) 
		{ 
			sizej  = 0; 
			sizei += add2; 
		} 
		if( (sizej==0) && (sizei>=ImgHeight)) 
			break; 
	} 
	return funcret; 
} 
///////////////////////////////////////////////////////////////////////////////////////// 
void  JpegFile1::GetYUV(short flag) 
{ 
	short	H, VV, i, j, k, h; 
	int		*buf, *pQtZzMCU; 
 
	switch(flag) 
	{ 
	case 0: 
		H   = SampRate_Y_H; 
		VV  = SampRate_Y_V; 
		buf = Y; 
		pQtZzMCU = QtZzMCUBuffer; 
		break; 
	case 1: 
		H   = SampRate_U_H; 
		VV  = SampRate_U_V; 
		buf = U; 
		pQtZzMCU = QtZzMCUBuffer + ( Y_in_MCU << 6 ); 
		break; 
	case 2: 
		H   = SampRate_V_H; 
		VV  = SampRate_V_V; 
		buf = V; 
		pQtZzMCU = QtZzMCUBuffer + ( (Y_in_MCU+ U_in_MCU) << 6 ); 
		break; 
	} 
	/*for (i= 0; i< VV; i++) 
		for(j= 0; j< H; j++) 
			for(k= 0; k< 8; k++) 
				for(h= 0; h< 8; h++) 
					buf[(i*8+k)*SampRate_Y_H8+j*8+h] = *pQtZzMCU++;//*/ 
 
	int add1= 0, add2= 0, num = 8* sizeof(int), inc = SampRate_Y_H8 << 3; 
	for (i= 0; i< VV; i++, add1 += inc) 
		for(h= 0, j= 0; j< H; j++, h += 8) 
			for(add2= 0, k= 0; k< 8; k++, add2 += SampRate_Y_H8, pQtZzMCU += 8) 
					memcpy( buf+ add1+ h+ add2, pQtZzMCU, num); //*/ 
} 
/////////////////////////////////////////////////////////////////////////////// 
void JpegFile1::StoreBuffer() 
{ 
	short		   i, j, k, l; 
	unsigned char *lpbmp; 
	int y, u, v, rr, gg, bb; 
 
	int Endi = SampRate_Y_V << 3; 
	int Endj = SampRate_Y_H << 3; 
	int OffX = sizej * comp_num; 
	int x1 = sizej, x2 = min(sizej+ Endj+ 1, ImgWidth); 
	int y1 = sizei, y2 = min(sizei+ Endi+ 1, ImgHeight); 
	int *ttt = new int[Endi+1]; 
	for(ttt[0]= 0, i= 1; i<= Endi; i++) 
		ttt[i] = ttt[i-1] + Endj; 
 
	if(comp_num == 3) 
	{ 
		for(i=0, k= y1; k< y2; k++, i++) 
		{ 
			lpbmp = lpImgData[k] + OffX; 
			for(j= 0, l= x1; l< x2; l++, j++) 
			{ 
				y  = Y[ttt[i] + j]; 
				u  = U[ttt[i/ V_YtoU] + j/ H_YtoU]; 
				v  = V[ttt[i/ V_YtoV] + j/ H_YtoV]; 
 
				rr = ((y<<8) + 18* u + 367*v) >>8; 
				gg = ((y<<8) - 159*u - 220*v) >>8; 
				bb = ((y<<8) + 411*u - 29 *v) >>8;//*/ 
 
				*lpbmp++ = *(blpClip + bb); 
				*lpbmp++ = *(blpClip + gg); 
				*lpbmp++ = *(blpClip + rr); 
			} 
		} 
	} 
	else 
	{ 
		for(i=0, k= y1; k< y2; k++, i++) 
		{ 
			lpbmp = lpImgData[k] + OffX; 
			for(j= 0, l= x1; l< x2; l++, j++) 
			{ 
				y  = Y[i*Endj + j]; 
				u  = U[(i/ V_YtoU)* Endj + j/ H_YtoU]; 
				v  = V[(i/ V_YtoV)* Endj + j/ H_YtoV]; 
				rr = ((y<<8) + 18* u + 367*v) >>8; 
				//gg = ((y<<8) - 159*u - 220*v) >>8; 
				//bb = ((y<<8) + 411*u - 29*v)  >>8; 
				*lpbmp++ = *(blpClip + rr); 
			} 
		} 
	} 
	if(ttt != NULL) delete []ttt; 
} 
/////////////////////////////////////////////////////////////////////////////// 
int JpegFile1::DecodeMCUBlock() 
{ 
	short *lpMCUBuffer; 
	short i,j; 
	int funcret; 
 
	if(IntervalFlag) 
	{ 
		lp     += 2; 
		ycoef   = ucoef = vcoef = 0; 
		BitPos  = 0; 
		CurByte = 0; 
	} 
	switch(comp_num) 
	{ 
	case 3: 
		lpMCUBuffer = MCUBuffer; 
		for (i= 0; i< Y_in_MCU; i++)  //Y 
		{ 
			funcret = HufBlock(YDcIndex, YAcIndex); 
			if(funcret!=0) return funcret; 
			BlockBuffer[0] = BlockBuffer[0] + ycoef; 
			ycoef = BlockBuffer[0]; 
			for(j= 0; j<64; j++) 
				*lpMCUBuffer++ = BlockBuffer[j]; 
		} 
		for (i=0; i< U_in_MCU; i++)  //U 
		{ 
			funcret = HufBlock(UVDcIndex, UVAcIndex); 
			if(funcret!=0)	return funcret; 
			BlockBuffer[0] = BlockBuffer[0] + ucoef; 
			ucoef = BlockBuffer[0]; 
			for(j= 0; j< 64; j++) 
				*lpMCUBuffer++ = BlockBuffer[j]; 
		} 
		for (i= 0; i< V_in_MCU; i++)  //V 
		{ 
			funcret = HufBlock(UVDcIndex, UVAcIndex); 
			if(funcret!=0) return funcret; 
			BlockBuffer[0] = BlockBuffer[0]+vcoef; 
			vcoef = BlockBuffer[0]; 
			for(j= 0; j< 64; j++) 
				*lpMCUBuffer++ = BlockBuffer[j]; 
		} 
		break; 
	case 1: 
		lpMCUBuffer = MCUBuffer; 
		funcret = HufBlock(YDcIndex, YAcIndex); 
		if(funcret!=0)	return funcret; 
		BlockBuffer[0] = BlockBuffer[0] + ycoef; 
		ycoef = BlockBuffer[0]; 
		for(j= 0; j< 64; j++) 
			*lpMCUBuffer++ = BlockBuffer[j]; 
		memset(lpMCUBuffer, 0, 128*sizeof(short)); 
		//for(i= 0; i< 128; i++)	*lpMCUBuffer++=0; 
		break; 
	default: 
		return 1; 
	} 
	return 0; 
} 
////////////////////////////////////////////////////////////////// 
int JpegFile1::HufBlock(BYTE dchufindex,BYTE achufindex) 
{ 
	short count= 0, i; 
	int funcret; 
 
	//dc 
	HufTabIndex = dchufindex; 
	funcret		= DecodeElement(); 
	if(funcret!=0) 	return funcret; 
 
	BlockBuffer[count++] = vvalue; 
	//ac 
	HufTabIndex = achufindex; 
	while (count<64) 
	{ 
		funcret = DecodeElement(); 
		if(funcret!=0) return funcret; 
		if ((rrun==0)&&(vvalue==0)) 
		{ 
			for (i= count; i<64; i++) 
				BlockBuffer[i]=0; 
			count = 64; 
		} 
		else 
		{ 
			for (i= 0; i< rrun; i++) 
				BlockBuffer[count++] =0 ; 
			BlockBuffer[count++] = vvalue; 
		} 
	} 
	return 0; 
} 
////////////////////////////////////////////////////////////////////////////// 
int JpegFile1::DecodeElement() 
{ 
	int   thiscode, tempcode; 
	BYTE  temp, valueex; 
	short codelen; 
	BYTE  hufexbyte, runsize, tempsize, sign; 
	BYTE  newbyte, lastbyte; 
 
	if(BitPos>=1) 
	{ 
		BitPos--; 
		thiscode = (BYTE)CurByte>>BitPos; 
		CurByte  = CurByte & And[BitPos]; 
	} 
	else 
	{ 
		lastbyte = ReadByte(); 
		BitPos--; 
		newbyte  = CurByte&And[BitPos]; 
		thiscode = lastbyte >> 7; 
		CurByte  = newbyte; 
	} 
	codelen = 1; 
	while ((thiscodehuf_max_value[HufTabIndex][codelen-1])) 
	{ 
		if(BitPos>=1) 
		{ 
			BitPos--; 
			tempcode = (BYTE)CurByte>>BitPos; 
			CurByte  = CurByte & And[BitPos]; 
		} 
		else 
		{ 
			lastbyte = ReadByte(); 
			BitPos--; 
			newbyte  = CurByte&And[BitPos]; 
			tempcode = (BYTE)lastbyte>>7; 
			CurByte  = newbyte; 
		} 
		thiscode = (thiscode<<1) + tempcode; 
		codelen++; 
		if(codelen>16) return 1; 
	}//while 
	temp = thiscode - huf_min_value[HufTabIndex][codelen-1] +  
		              code_pos_table[HufTabIndex][codelen-1]; 
	hufexbyte = (BYTE)code_value_table[HufTabIndex][temp]; 
	rrun      = (short)(hufexbyte>>4); 
	runsize	  = hufexbyte & 0x0f; 
	if(runsize==0) 
	{ 
		vvalue = 0; 
		return 0; 
	} 
	tempsize = runsize; 
	if(BitPos>=runsize) 
	{ 
		BitPos -= runsize; 
		valueex = (BYTE)CurByte>>BitPos; 
		CurByte = CurByte&And[BitPos]; 
	} 
	else 
	{ 
		valueex   = BYTE( CurByte ); 
		tempsize -= BitPos; 
		while(tempsize>8) 
		{ 
			lastbyte = ReadByte(); 
			valueex  = (valueex<<8) + (BYTE)lastbyte; 
			tempsize-= 8; 
		}  //while 
		lastbyte = ReadByte(); 
		BitPos  -= tempsize; 
		valueex  = (valueex<>BitPos); 
		CurByte  = lastbyte & And[BitPos]; 
	}  //else 
	sign = valueex >> (runsize-1); 
	if(sign) 
		vvalue = valueex; 
	else 
	{ 
		valueex = valueex ^ 0xffff; 
		temp    = 0xffff << runsize; 
		vvalue  =-(short)(valueex^temp); 
	} 
	return 0; 
} 
///////////////////////////////////////////////////////////////////////////////////// 
void JpegFile1::IQtIZzMCUComponent(short flag) 
{ 
	short H, VV, i, j, *pMCUBuffer; 
	int *pQtZzMCUBuffer; 
 
	switch(flag) 
	{ 
	case 0: 
		H  = SampRate_Y_H; 
		VV = SampRate_Y_V; 
		pMCUBuffer	   = MCUBuffer; 
		pQtZzMCUBuffer = QtZzMCUBuffer; 
		break; 
	case 1: 
		H  = SampRate_U_H; 
		VV = SampRate_U_V; 
		pMCUBuffer	   = MCUBuffer + (Y_in_MCU << 6); 
		pQtZzMCUBuffer = QtZzMCUBuffer + (Y_in_MCU << 6); 
		break; 
	case 2: 
		H  = SampRate_V_H; 
		VV = SampRate_V_V; 
		pMCUBuffer	   = MCUBuffer + ( (Y_in_MCU+ U_in_MCU) << 6); 
		pQtZzMCUBuffer = QtZzMCUBuffer + ((Y_in_MCU+ U_in_MCU) << 6); 
		break; 
	} 
	int add = 0; 
	for(i= 0; i> 8; 
	x4 = (181* (x4-x5)+ 128) >> 8; 
	//fourth stage 
	*blk = (x7+ x1) >> 8; 
	*(blk+ 1) = (x3+ x2) >> 8; 
	*(blk+ 2) = (x0+ x4) >> 8; 
	*(blk+ 3) = (x8+ x6) >> 8; 
	*(blk+ 4) = (x8- x6) >> 8; 
	*(blk+ 5) = (x0- x4) >> 8; 
	*(blk+ 6) = (x3- x2) >> 8; 
	*(blk+ 7) = (x7- x1) >> 8; 
} 
////////////////////////////////////////////////////////////////////////////// 
void JpegFile1::idctcol(int * blk) 
{ 
	int x0, x1, x2, x3, x4, x5, x6, x7, x8; 
	//intcut 
	if (!((x1 = (blk[32]<<8)) | (x2 = blk[48]) | (x3 = blk[16]) | 
		  (x4 = blk[8]) | (x5 = blk[56]) | (x6 = blk[40]) | (x7 = blk[24]))) 
	{ 
		blk[0]=blk[8]=blk[16]=blk[24]=blk[32]=blk[40]=blk[48]=blk[56] = (blk[0] + 32)>>6; 
		return; 
	} 
 
	x0 = (blk[0]<<8) + 8192; 
	//first stage 
	x8 = W7* (x4+ x5) + 4; 
	x4 =(x8+ (W1- W7)* x4) >> 3; 
	x5 =(x8- (W1+ W7)* x5) >> 3; 
	x8 = W3* (x6+ x7) + 4; 
	x6 =(x8- (W3- W5)* x6) >> 3; 
	x7 =(x8- (W3+ W5)* x7) >> 3; 
	//second stage 
	x8 = x0 + x1; 
	x0-= x1; 
	x1 = W6* (x3+ x2) + 4; 
	x2 =(x1- (W2+ W6)* x2) >> 3; 
	x3 =(x1+ (W2- W6)* x3) >> 3; 
	x1 = x4 + x6; 
	x4-= x6; 
	x6 = x5 + x7; 
	x5-= x7; 
	//third stage 
	x7 = x8 + x3; 
	x8-= x3; 
	x3 = x0 + x2; 
	x0-= x2; 
	x2 = (181* (x4+ x5) + 128) >> 8; 
	x4 = (181* (x4- x5) + 128) >> 8; 
	//fourth stage 
	*blk	   = iclp[ (x7+ x1) >> 14 ]; 
	*(blk+ 8 ) = iclp[ (x3+ x2) >> 14 ]; 
	*(blk+ 16) = iclp[ (x0+ x4) >> 14 ]; 
	*(blk+ 24) = iclp[ (x8+ x6) >> 14 ]; 
	*(blk+ 32) = iclp[ (x8- x6) >> 14 ]; 
	*(blk+ 40) = iclp[ (x0- x4) >> 14 ]; 
	*(blk+ 48) = iclp[ (x3- x2) >> 14 ]; 
	*(blk+ 56) = iclp[ (x7- x1) >> 14 ]; 
}