llimagejpeg.cpp 22 KB

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