#include "stdafx.h" #include "Image.h" #include "ImagePixel.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CBaseImage extern "C" { #include "jpeglib.h" } /* * Here's the routine that will replace the standard error_exit method: */ METHODDEF void ima_jpeg_error_exit (j_common_ptr cinfo) { /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */ ima_error_ptr myerr = (ima_error_ptr) cinfo->err; char buffer[JMSG_LENGTH_MAX]; /* Create the message */ myerr->pub.format_message (cinfo, buffer); /* Send it to stderr, adding a newline */ //AfxMessageBox(buffer); /* Return control to the setjmp point */ longjmp(myerr->setjmp_buffer, 1); } // Function : CImage::LoadJPG // Descript : JPG À̹ÌÁö¸¦ °¡Á®¿Â´Ù. // Return : BOOL // Argument : LPCTSTR lpszFileName BOOL CImage::LoadJPG(LPCTSTR lpszFileName) { HDIB hHandle; BOOL bGray = FALSE; /* 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. */ struct ima_error_mgr jerr; //struct jpeg_error_mgr jerr; /* More stuff */ FILE * infile; /* source file */ JSAMPARRAY buffer; /* Output row buffer */ int row_stride; /* physical row width in output buffer */ /* 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(lpszFileName, "rb")) == NULL) { //fprintf(stderr, "can't open %s\n", filename); return 0; } /* 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 = ima_jpeg_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); fclose(infile); return 0; } /* 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); /* Step 4: set parameters for decompression */ // printf("info %d %d %d CS %d ", cinfo.image_width, cinfo.image_height, cinfo.output_components, cinfo.jpeg_color_space); if (cinfo.jpeg_color_space!=JCS_GRAYSCALE) { cinfo.quantize_colors = TRUE; cinfo.desired_number_of_colors = 128; } /* Step 5: Start decompressor */ jpeg_start_decompress(&cinfo); /* 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. */ if (cinfo.jpeg_color_space==JCS_GRAYSCALE) { bGray = TRUE; //CreateImage(cinfo.image_width, cinfo.image_height, 8); hHandle = ::DibCreate(cinfo.image_width, cinfo.image_height, 8); } else //CreateImage(cinfo.image_width, cinfo.image_height, 24); hHandle = ::DibCreate(cinfo.image_width, cinfo.image_height, 24); if (hHandle == NULL) { jpeg_destroy_decompress(&cinfo); fclose(infile); return FALSE; } /* JSAMPLEs per row in output buffer */ row_stride = cinfo.output_width * cinfo.output_components; // byte* buf2 = new byte[row_stride]; // printf("NCMPS cmp [%d %d %d]", cinfo.output_components, cinfo.actual_number_of_colors,row_stride); /* 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 line, col; if (bGray) { CPixelPtr ptr(hHandle); line = 0; while (cinfo.output_scanline < cinfo.output_height) { (void) jpeg_read_scanlines(&cinfo, buffer, 1); /* Assume put_scanline_someplace wants a pointer and sample count. */ memcpy(ptr[line++], buffer[0], row_stride); } } else { CColorPixelPtr ptrColor(hHandle); line = 0; if(cinfo.output_components == 3) { while (cinfo.output_scanline < cinfo.output_height) { (void) jpeg_read_scanlines(&cinfo, buffer, 1); /* Assume put_scanline_someplace wants a pointer and sample count. */ memcpy(ptrColor[line++], buffer[0], row_stride); } } else { while (cinfo.output_scanline < cinfo.output_height) { (void) jpeg_read_scanlines(&cinfo, buffer, 1); /* Assume put_scanline_someplace wants a pointer and sample count. */ for(col=0 ; colalloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); int line = 0; if (bGray) { CPixelPtr ptr(hHandle); while (cinfo.next_scanline < cinfo.image_height) { memcpy(buffer[0], ptr[line++], row_stride); (void) jpeg_write_scanlines(&cinfo, buffer, 1); } } else { CColorPixelPtr ptrColor(hHandle); while (cinfo.next_scanline < cinfo.image_height) { for(col=0, i=0 ; i