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; i rgbtRed = *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; i rgbtRed ; *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; row 255) ? 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 ((thiscode huf_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 ]; }