PageRenderTime 63ms CodeModel.GetById 2ms app.highlight 46ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/llimage/llimagejpeg.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 648 lines | 306 code | 115 blank | 227 comment | 27 complexity | 15d5052df5ad3ec22e0b982500e96681 MD5 | raw file
  1/** 
  2 * @file llimagejpeg.cpp
  3 *
  4 * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  5 * Second Life Viewer Source Code
  6 * Copyright (C) 2010, Linden Research, Inc.
  7 * 
  8 * This library is free software; you can redistribute it and/or
  9 * modify it under the terms of the GNU Lesser General Public
 10 * License as published by the Free Software Foundation;
 11 * version 2.1 of the License only.
 12 * 
 13 * This library is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 16 * Lesser General Public License for more details.
 17 * 
 18 * You should have received a copy of the GNU Lesser General Public
 19 * License along with this library; if not, write to the Free Software
 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 21 * 
 22 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 23 * $/LicenseInfo$
 24 */
 25
 26#include "linden_common.h"
 27#include "stdtypes.h"
 28
 29#include "llimagejpeg.h"
 30
 31#include "llerror.h"
 32
 33jmp_buf	LLImageJPEG::sSetjmpBuffer ;
 34LLImageJPEG::LLImageJPEG(S32 quality) 
 35	:
 36	LLImageFormatted(IMG_CODEC_JPEG),
 37	mOutputBuffer( NULL ),
 38	mOutputBufferSize( 0 ),
 39	mEncodeQuality( quality ) // on a scale from 1 to 100
 40{
 41}
 42
 43LLImageJPEG::~LLImageJPEG()
 44{
 45	llassert( !mOutputBuffer ); // Should already be deleted at end of encode.
 46	delete[] mOutputBuffer;
 47}
 48
 49BOOL LLImageJPEG::updateData()
 50{
 51	resetLastError();
 52
 53	// Check to make sure that this instance has been initialized with data
 54	if (!getData() || (0 == getDataSize()))
 55	{
 56		setLastError("Uninitialized instance of LLImageJPEG");
 57		return FALSE;
 58	}
 59
 60	////////////////////////////////////////
 61	// Step 1: allocate and initialize JPEG decompression object
 62
 63	// This struct contains the JPEG decompression parameters and pointers to
 64	// working space (which is allocated as needed by the JPEG library).
 65	struct jpeg_decompress_struct cinfo;
 66	cinfo.client_data = this;
 67
 68	struct jpeg_error_mgr jerr;
 69	cinfo.err = jpeg_std_error(&jerr);
 70	
 71	// Customize with our own callbacks
 72	jerr.error_exit =		&LLImageJPEG::errorExit;			// Error exit handler: does not return to caller
 73	jerr.emit_message =		&LLImageJPEG::errorEmitMessage;		// Conditionally emit a trace or warning message
 74	jerr.output_message =	&LLImageJPEG::errorOutputMessage;	// Routine that actually outputs a trace or error message
 75	
 76	//
 77	//try/catch will crash on Mac and Linux if LLImageJPEG::errorExit throws an error
 78	//so as instead, we use setjmp/longjmp to avoid this crash, which is the best we can get. --bao 
 79	//
 80	if(setjmp(sSetjmpBuffer))
 81	{
 82		jpeg_destroy_decompress(&cinfo);
 83		return FALSE;
 84	}
 85	try
 86	{
 87		// Now we can initialize the JPEG decompression object.
 88		jpeg_create_decompress(&cinfo);
 89
 90		////////////////////////////////////////
 91		// Step 2: specify data source
 92		// (Code is modified version of jpeg_stdio_src();
 93		if (cinfo.src == NULL)
 94		{	
 95			cinfo.src = (struct jpeg_source_mgr *)
 96				(*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT,
 97				sizeof(struct jpeg_source_mgr));
 98		}
 99		cinfo.src->init_source	=		&LLImageJPEG::decodeInitSource;
100		cinfo.src->fill_input_buffer =	&LLImageJPEG::decodeFillInputBuffer;
101		cinfo.src->skip_input_data =	&LLImageJPEG::decodeSkipInputData;
102		cinfo.src->resync_to_restart = jpeg_resync_to_restart; // For now, use default method, but we should be able to do better.
103		cinfo.src->term_source =		&LLImageJPEG::decodeTermSource;
104
105		cinfo.src->bytes_in_buffer =	getDataSize();
106		cinfo.src->next_input_byte =	getData();
107		
108		////////////////////////////////////////
109		// Step 3: read file parameters with jpeg_read_header()
110		jpeg_read_header( &cinfo, TRUE );
111
112		// Data set by jpeg_read_header
113		setSize(cinfo.image_width, cinfo.image_height, 3); // Force to 3 components (RGB)
114
115		/*
116		// More data set by jpeg_read_header
117		cinfo.num_components;
118		cinfo.jpeg_color_space;	// Colorspace of image
119		cinfo.saw_JFIF_marker;		// TRUE if a JFIF APP0 marker was seen
120		cinfo.JFIF_major_version;	// Version information from JFIF marker
121		cinfo.JFIF_minor_version;  //
122		cinfo.density_unit;		// Resolution data from JFIF marker
123		cinfo.X_density;
124		cinfo.Y_density;
125		cinfo.saw_Adobe_marker;	// TRUE if an Adobe APP14 marker was seen
126		cinfo.Adobe_transform;     // Color transform code from Adobe marker
127		*/
128	}
129	catch (int)
130	{
131		jpeg_destroy_decompress(&cinfo);
132
133		return FALSE;
134	}
135	////////////////////////////////////////
136	// Step 4: Release JPEG decompression object 
137	jpeg_destroy_decompress(&cinfo);
138
139	return TRUE;
140}
141
142// Initialize source --- called by jpeg_read_header
143// before any data is actually read.
144void LLImageJPEG::decodeInitSource( j_decompress_ptr cinfo )
145{
146	// no work necessary here
147}
148
149// Fill the input buffer --- called whenever buffer is emptied.
150boolean LLImageJPEG::decodeFillInputBuffer( j_decompress_ptr cinfo )
151{
152//	jpeg_source_mgr* src = cinfo->src;
153//	LLImageJPEG* self = (LLImageJPEG*) cinfo->client_data;
154
155	// Should never get here, since we provide the entire buffer up front.
156	ERREXIT(cinfo, JERR_INPUT_EMPTY);
157
158	return TRUE;
159}
160
161// Skip data --- used to skip over a potentially large amount of
162// uninteresting data (such as an APPn marker).
163//
164// Writers of suspendable-input applications must note that skip_input_data
165// is not granted the right to give a suspension return.  If the skip extends
166// beyond the data currently in the buffer, the buffer can be marked empty so
167// that the next read will cause a fill_input_buffer call that can suspend.
168// Arranging for additional bytes to be discarded before reloading the input
169// buffer is the application writer's problem.
170void LLImageJPEG::decodeSkipInputData (j_decompress_ptr cinfo, long num_bytes)
171{
172	jpeg_source_mgr* src = cinfo->src;
173//	LLImageJPEG* self = (LLImageJPEG*) cinfo->client_data;
174
175    src->next_input_byte += (size_t) num_bytes;
176    src->bytes_in_buffer -= (size_t) num_bytes;
177}
178
179void LLImageJPEG::decodeTermSource (j_decompress_ptr cinfo)
180{
181  // no work necessary here
182}
183
184
185// Returns true when done, whether or not decode was successful.
186BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
187{
188	llassert_always(raw_image);
189	
190	resetLastError();
191	
192	// Check to make sure that this instance has been initialized with data
193	if (!getData() || (0 == getDataSize()))
194	{
195		setLastError("LLImageJPEG trying to decode an image with no data!");
196		return TRUE;  // done
197	}
198	
199	S32 row_stride = 0;
200	U8* raw_image_data = NULL;
201
202	////////////////////////////////////////
203	// Step 1: allocate and initialize JPEG decompression object
204
205	// This struct contains the JPEG decompression parameters and pointers to
206	// working space (which is allocated as needed by the JPEG library).
207	struct jpeg_decompress_struct cinfo;
208
209	struct jpeg_error_mgr jerr;
210	cinfo.err = jpeg_std_error(&jerr);
211	
212	// Customize with our own callbacks
213	jerr.error_exit =		&LLImageJPEG::errorExit;			// Error exit handler: does not return to caller
214	jerr.emit_message =		&LLImageJPEG::errorEmitMessage;		// Conditionally emit a trace or warning message
215	jerr.output_message =	&LLImageJPEG::errorOutputMessage;	// Routine that actually outputs a trace or error message
216	
217	//
218	//try/catch will crash on Mac and Linux if LLImageJPEG::errorExit throws an error
219	//so as instead, we use setjmp/longjmp to avoid this crash, which is the best we can get. --bao 
220	//
221	if(setjmp(sSetjmpBuffer))
222	{
223		jpeg_destroy_decompress(&cinfo);
224		return TRUE; // done
225	}
226	try
227	{
228		// Now we can initialize the JPEG decompression object.
229		jpeg_create_decompress(&cinfo);
230
231		////////////////////////////////////////
232		// Step 2: specify data source
233		// (Code is modified version of jpeg_stdio_src();
234		if (cinfo.src == NULL)
235		{	
236			cinfo.src = (struct jpeg_source_mgr *)
237				(*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT,
238				sizeof(struct jpeg_source_mgr));
239		}
240		cinfo.src->init_source	=		&LLImageJPEG::decodeInitSource;
241		cinfo.src->fill_input_buffer =	&LLImageJPEG::decodeFillInputBuffer;
242		cinfo.src->skip_input_data =	&LLImageJPEG::decodeSkipInputData;
243		cinfo.src->resync_to_restart = jpeg_resync_to_restart; // For now, use default method, but we should be able to do better.
244		cinfo.src->term_source =		&LLImageJPEG::decodeTermSource;
245		cinfo.src->bytes_in_buffer =	getDataSize();
246		cinfo.src->next_input_byte =	getData();
247		
248		////////////////////////////////////////
249		// Step 3: read file parameters with jpeg_read_header()
250		
251		jpeg_read_header(&cinfo, TRUE);
252
253		// We can ignore the return value from jpeg_read_header since
254		//   (a) suspension is not possible with our data source, and
255		//   (b) we passed TRUE to reject a tables-only JPEG file as an error.
256		// See libjpeg.doc for more info.
257
258		setSize(cinfo.image_width, cinfo.image_height, 3); // Force to 3 components (RGB)
259
260		raw_image->resize(getWidth(), getHeight(), getComponents());
261		raw_image_data = raw_image->getData();
262		
263		
264		////////////////////////////////////////
265		// Step 4: set parameters for decompression 
266		cinfo.out_color_components = 3;
267		cinfo.out_color_space = JCS_RGB;
268   
269
270		////////////////////////////////////////
271		// Step 5: Start decompressor 
272		
273		jpeg_start_decompress(&cinfo);
274		// We can ignore the return value since suspension is not possible
275		// with our data source.
276		
277		// We may need to do some setup of our own at this point before reading
278		// the data.  After jpeg_start_decompress() we have the correct scaled
279		// output image dimensions available, as well as the output colormap
280		// if we asked for color quantization.
281		// In this example, we need to make an output work buffer of the right size.
282    
283		// JSAMPLEs per row in output buffer 
284		row_stride = cinfo.output_width * cinfo.output_components;
285		
286		////////////////////////////////////////
287		// Step 6: while (scan lines remain to be read) 
288		//           jpeg_read_scanlines(...); 
289		
290		// Here we use the library's state variable cinfo.output_scanline as the
291		// loop counter, so that we don't have to keep track ourselves.
292		
293		// Move pointer to last line
294		raw_image_data += row_stride * (cinfo.output_height - 1);
295
296		while (cinfo.output_scanline < cinfo.output_height)
297		{
298			// jpeg_read_scanlines expects an array of pointers to scanlines.
299			// Here the array is only one element long, but you could ask for
300			// more than one scanline at a time if that's more convenient.
301			
302			jpeg_read_scanlines(&cinfo, &raw_image_data, 1);
303			raw_image_data -= row_stride;  // move pointer up a line
304		}
305
306		////////////////////////////////////////
307		// Step 7: Finish decompression 
308		jpeg_finish_decompress(&cinfo);
309
310		////////////////////////////////////////
311		// Step 8: Release JPEG decompression object 
312		jpeg_destroy_decompress(&cinfo);
313	}
314
315	catch (int)
316	{
317		jpeg_destroy_decompress(&cinfo);
318		return TRUE; // done
319	}
320
321	// Check to see whether any corrupt-data warnings occurred
322	if( jerr.num_warnings != 0 )
323	{
324		// TODO: extract the warning to find out what went wrong.
325		setLastError( "Unable to decode JPEG image.");
326		return TRUE; // done
327	}
328
329	return TRUE;
330}
331
332
333// Initialize destination --- called by jpeg_start_compress before any data is actually written.
334// static
335void LLImageJPEG::encodeInitDestination ( j_compress_ptr cinfo )
336{
337  LLImageJPEG* self = (LLImageJPEG*) cinfo->client_data;
338
339  cinfo->dest->next_output_byte = self->mOutputBuffer;
340  cinfo->dest->free_in_buffer = self->mOutputBufferSize;
341}
342
343
344//  Empty the output buffer --- called whenever buffer fills up.
345// 
346//  In typical applications, this should write the entire output buffer
347//  (ignoring the current state of next_output_byte & free_in_buffer),
348//  reset the pointer & count to the start of the buffer, and return TRUE
349//  indicating that the buffer has been dumped.
350// 
351//  In applications that need to be able to suspend compression due to output
352//  overrun, a FALSE return indicates that the buffer cannot be emptied now.
353//  In this situation, the compressor will return to its caller (possibly with
354//  an indication that it has not accepted all the supplied scanlines).  The
355//  application should resume compression after it has made more room in the
356//  output buffer.  Note that there are substantial restrictions on the use of
357//  suspension --- see the documentation.
358// 
359//  When suspending, the compressor will back up to a convenient restart point
360//  (typically the start of the current MCU). next_output_byte & free_in_buffer
361//  indicate where the restart point will be if the current call returns FALSE.
362//  Data beyond this point will be regenerated after resumption, so do not
363//  write it out when emptying the buffer externally.
364
365boolean LLImageJPEG::encodeEmptyOutputBuffer( j_compress_ptr cinfo )
366{
367  LLImageJPEG* self = (LLImageJPEG*) cinfo->client_data;
368
369  // Should very rarely happen, since our output buffer is
370  // as large as the input to start out with.
371  
372  // Double the buffer size;
373  S32 new_buffer_size = self->mOutputBufferSize * 2;
374  U8* new_buffer = new U8[ new_buffer_size ];
375  if (!new_buffer)
376  {
377  	llerrs << "Out of memory in LLImageJPEG::encodeEmptyOutputBuffer( j_compress_ptr cinfo )" << llendl;
378  	return FALSE;
379  }
380  memcpy( new_buffer, self->mOutputBuffer, self->mOutputBufferSize );	/* Flawfinder: ignore */
381  delete[] self->mOutputBuffer;
382  self->mOutputBuffer = new_buffer;
383
384  cinfo->dest->next_output_byte = self->mOutputBuffer + self->mOutputBufferSize;
385  cinfo->dest->free_in_buffer = self->mOutputBufferSize;
386  self->mOutputBufferSize = new_buffer_size;
387
388  return TRUE;
389}
390
391//  Terminate destination --- called by jpeg_finish_compress
392//  after all data has been written.  Usually needs to flush buffer.
393// 
394//  NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
395//  application must deal with any cleanup that should happen even
396//  for error exit.
397void LLImageJPEG::encodeTermDestination( j_compress_ptr cinfo )
398{
399	LLImageJPEG* self = (LLImageJPEG*) cinfo->client_data;
400
401	S32 file_bytes = (S32)(self->mOutputBufferSize - cinfo->dest->free_in_buffer);
402	self->allocateData(file_bytes);
403
404	memcpy( self->getData(), self->mOutputBuffer, file_bytes );	/* Flawfinder: ignore */
405}
406
407// static 
408void LLImageJPEG::errorExit( j_common_ptr cinfo )	
409{
410	//LLImageJPEG* self = (LLImageJPEG*) cinfo->client_data;
411
412	// Always display the message
413	(*cinfo->err->output_message)(cinfo);
414
415	// Let the memory manager delete any temp files
416	jpeg_destroy(cinfo);
417
418	// Return control to the setjmp point
419	longjmp(sSetjmpBuffer, 1) ;
420}
421
422// Decide whether to emit a trace or warning message.
423// msg_level is one of:
424//   -1: recoverable corrupt-data warning, may want to abort.
425//    0: important advisory messages (always display to user).
426//    1: first level of tracing detail.
427//    2,3,...: successively more detailed tracing messages.
428// An application might override this method if it wanted to abort on warnings
429// or change the policy about which messages to display.
430// static 
431void LLImageJPEG::errorEmitMessage( j_common_ptr cinfo, int msg_level )
432{
433  struct jpeg_error_mgr * err = cinfo->err;
434
435  if (msg_level < 0) 
436  {
437	  // It's a warning message.  Since corrupt files may generate many warnings,
438	  // the policy implemented here is to show only the first warning,
439	  // unless trace_level >= 3.
440	  if (err->num_warnings == 0 || err->trace_level >= 3)
441	  {
442		  (*err->output_message) (cinfo);
443	  }
444	  // Always count warnings in num_warnings.
445	  err->num_warnings++;
446  }
447  else 
448  {
449	  // It's a trace message.  Show it if trace_level >= msg_level.
450	  if (err->trace_level >= msg_level)
451	  {
452		  (*err->output_message) (cinfo);
453	  }
454  }
455}
456
457// static 
458void LLImageJPEG::errorOutputMessage( j_common_ptr cinfo )
459{
460	// Create the message
461	char buffer[JMSG_LENGTH_MAX];	/* Flawfinder: ignore */
462	(*cinfo->err->format_message) (cinfo, buffer);
463
464	std::string error = buffer ;
465	LLImage::setLastError(error);
466
467	BOOL is_decode = (cinfo->is_decompressor != 0);
468	llwarns << "LLImageJPEG " << (is_decode ? "decode " : "encode ") << " failed: " << buffer << llendl;
469}
470
471BOOL LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time )
472{
473	llassert_always(raw_image);
474	
475	resetLastError();
476
477	switch( raw_image->getComponents() )
478	{
479	case 1:
480	case 3:
481		break;
482	default:
483		setLastError("Unable to encode a JPEG image that doesn't have 1 or 3 components.");
484		return FALSE;
485	}
486
487	setSize(raw_image->getWidth(), raw_image->getHeight(), raw_image->getComponents());
488
489	// Allocate a temporary buffer big enough to hold the entire compressed image (and then some)
490	// (Note: we make it bigger in emptyOutputBuffer() if we need to)
491	delete[] mOutputBuffer;
492	mOutputBufferSize = getWidth() * getHeight() * getComponents() + 1024;
493	mOutputBuffer = new U8[ mOutputBufferSize ];
494
495	const U8* raw_image_data = NULL;
496	S32 row_stride = 0;
497
498	////////////////////////////////////////
499	// Step 1: allocate and initialize JPEG compression object
500
501	// This struct contains the JPEG compression parameters and pointers to
502	// working space (which is allocated as needed by the JPEG library).
503	struct jpeg_compress_struct cinfo;
504	cinfo.client_data = this;
505
506	// We have to set up the error handler first, in case the initialization
507	// step fails.  (Unlikely, but it could happen if you are out of memory.)
508	// This routine fills in the contents of struct jerr, and returns jerr's
509	// address which we place into the link field in cinfo.
510	struct jpeg_error_mgr jerr;
511	cinfo.err = jpeg_std_error(&jerr);
512
513	// Customize with our own callbacks
514	jerr.error_exit =		&LLImageJPEG::errorExit;			// Error exit handler: does not return to caller
515	jerr.emit_message =		&LLImageJPEG::errorEmitMessage;		// Conditionally emit a trace or warning message
516	jerr.output_message =	&LLImageJPEG::errorOutputMessage;	// Routine that actually outputs a trace or error message
517
518	//
519	//try/catch will crash on Mac and Linux if LLImageJPEG::errorExit throws an error
520	//so as instead, we use setjmp/longjmp to avoid this crash, which is the best we can get. --bao 
521	//
522	if( setjmp(sSetjmpBuffer) ) 
523	{
524		// If we get here, the JPEG code has signaled an error.
525		// We need to clean up the JPEG object, close the input file, and return.
526		jpeg_destroy_compress(&cinfo);
527		delete[] mOutputBuffer;
528		mOutputBuffer = NULL;
529		mOutputBufferSize = 0;
530		return FALSE;
531	}
532
533	try
534	{
535
536		// Now we can initialize the JPEG compression object.
537		jpeg_create_compress(&cinfo);
538
539		////////////////////////////////////////
540		// Step 2: specify data destination
541		// (code is a modified form of jpeg_stdio_dest() )
542		if( cinfo.dest == NULL)
543		{	
544			cinfo.dest = (struct jpeg_destination_mgr *)
545				(*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT,
546				sizeof(struct jpeg_destination_mgr));
547		}
548		cinfo.dest->next_output_byte =		mOutputBuffer;		// => next byte to write in buffer
549		cinfo.dest->free_in_buffer =		mOutputBufferSize;	// # of byte spaces remaining in buffer
550		cinfo.dest->init_destination =		&LLImageJPEG::encodeInitDestination;
551		cinfo.dest->empty_output_buffer =	&LLImageJPEG::encodeEmptyOutputBuffer;
552		cinfo.dest->term_destination =		&LLImageJPEG::encodeTermDestination;
553
554		////////////////////////////////////////
555		// Step 3: set parameters for compression 
556		//
557		// First we supply a description of the input image.
558		// Four fields of the cinfo struct must be filled in:
559		
560		cinfo.image_width = getWidth(); 	// image width and height, in pixels 
561		cinfo.image_height = getHeight();
562
563		switch( getComponents() )
564		{
565		case 1:
566			cinfo.input_components = 1;		// # of color components per pixel
567			cinfo.in_color_space = JCS_GRAYSCALE; // colorspace of input image
568			break;
569		case 3:
570			cinfo.input_components = 3;		// # of color components per pixel
571			cinfo.in_color_space = JCS_RGB; // colorspace of input image
572			break;
573		default:
574			setLastError("Unable to encode a JPEG image that doesn't have 1 or 3 components.");
575			return FALSE;
576		}
577
578		// Now use the library's routine to set default compression parameters.
579		// (You must set at least cinfo.in_color_space before calling this,
580		// since the defaults depend on the source color space.)
581		jpeg_set_defaults(&cinfo);
582
583		// Now you can set any non-default parameters you wish to.
584		jpeg_set_quality(&cinfo, mEncodeQuality, TRUE );  // limit to baseline-JPEG values
585
586		////////////////////////////////////////
587		// Step 4: Start compressor 
588		//
589		// TRUE ensures that we will write a complete interchange-JPEG file.
590		// Pass TRUE unless you are very sure of what you're doing.
591   
592		jpeg_start_compress(&cinfo, TRUE);
593
594		////////////////////////////////////////
595		// Step 5: while (scan lines remain to be written) 
596		//            jpeg_write_scanlines(...); 
597
598		// Here we use the library's state variable cinfo.next_scanline as the
599		// loop counter, so that we don't have to keep track ourselves.
600		// To keep things simple, we pass one scanline per call; you can pass
601		// more if you wish, though.
602   
603		row_stride = getWidth() * getComponents();	// JSAMPLEs per row in image_buffer
604
605		// NOTE: For compatibility with LLImage, we need to invert the rows.
606		raw_image_data = raw_image->getData();
607		
608		const U8* last_row_data = raw_image_data + (getHeight()-1) * row_stride;
609
610		JSAMPROW row_pointer[1];				// pointer to JSAMPLE row[s]
611		while (cinfo.next_scanline < cinfo.image_height) 
612		{
613			// jpeg_write_scanlines expects an array of pointers to scanlines.
614			// Here the array is only one element long, but you could pass
615			// more than one scanline at a time if that's more convenient.
616
617			//Ugly const uncast here (jpeg_write_scanlines should take a const* but doesn't)
618			//row_pointer[0] = (JSAMPROW)(raw_image_data + (cinfo.next_scanline * row_stride));
619			row_pointer[0] = (JSAMPROW)(last_row_data - (cinfo.next_scanline * row_stride));
620
621			jpeg_write_scanlines(&cinfo, row_pointer, 1);
622		}
623
624		////////////////////////////////////////
625		//   Step 6: Finish compression 
626		jpeg_finish_compress(&cinfo);
627
628		// After finish_compress, we can release the temp output buffer. 
629		delete[] mOutputBuffer;
630		mOutputBuffer = NULL;
631		mOutputBufferSize = 0;
632
633		////////////////////////////////////////
634		//   Step 7: release JPEG compression object 
635		jpeg_destroy_compress(&cinfo);
636	}
637
638	catch(int)
639	{
640		jpeg_destroy_compress(&cinfo);
641		delete[] mOutputBuffer;
642		mOutputBuffer = NULL;
643		mOutputBufferSize = 0;
644		return FALSE;
645	}
646
647	return TRUE;
648}