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; ialloc_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; iGetRGB(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