www.pudn.com > Cimage.zip > IMAJPG.CPP
/* * File: imajpg.cc * Purpose: Platform Independent JPEG Image Class * Author: Alejandro Aguilar Sierra * Created: 1995 * Copyright: (c) 1995, Alejandro Aguilar Sierra* * This software is based in part on the work of the Independent JPEG Group. * */ // #include "stdafx.h" #include "imajpg.h" #if CIMAGE_SUPPORT_JPEG #include extern "C" { #include "jpeglib.h" } #include "imaiter.h" #include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif struct ima_error_mgr { struct jpeg_error_mgr pub; /* "public" fields */ jmp_buf setjmp_buffer; /* for return to caller */ }; typedef ima_error_mgr *ima_error_ptr; /* * 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); } BOOL CImageJPG::ReadFile(const CString& imageFileName) { if (imageFileName != "") filename = imageFileName; CImageIterator iter(this); /* 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((const char *)filename, "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. */ Create(cinfo.image_width, cinfo.image_height, 8*cinfo.output_components); if (cinfo.jpeg_color_space==JCS_GRAYSCALE) CreateGrayColourMap(256); else SetPalette(cinfo.actual_number_of_colors, cinfo.colormap[0], cinfo.colormap[1], cinfo.colormap[2]); /* 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. */ iter.Upset(); 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 (int i=0; i alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); // puts("now itera"); iter.Upset(); while (cinfo.next_scanline < cinfo.image_height) { if (GetPalette()) { buf2 = new byte[GetWidth()]; iter.GetRow(buf2, GetWidth()); int k=0; for (int i=0; i GetRGB(buf2[i], &buffer[0][k], &buffer[0][k+1], &buffer[0][k+2]); } else iter.GetRow(buffer[0], row_stride); iter.PrevRow(); (void) jpeg_write_scanlines(&cinfo, buffer, 1); } delete buf2; // puts("iterado"); /* 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 */ // puts("destroy"); /* This is an important step since it will release a good deal of memory. */ jpeg_destroy_compress(&cinfo); /* And we're done! */ return TRUE; } void CImageJPG::CreateGrayColourMap(int n) { byte g[256]; for (int i=0; i