llimagejpeg.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:22k
源码类别:

游戏引擎

开发平台:

C++ Builder

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