Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

juce_JPEGLoader.cpp 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2013 - Raw Material Software Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. #if JUCE_MSVC
  18. #pragma warning (push)
  19. #pragma warning (disable: 4365)
  20. #endif
  21. namespace jpeglibNamespace
  22. {
  23. #if JUCE_INCLUDE_JPEGLIB_CODE || ! defined (JUCE_INCLUDE_JPEGLIB_CODE)
  24. #if JUCE_MINGW
  25. typedef unsigned char boolean;
  26. #endif
  27. #if JUCE_CLANG
  28. #pragma clang diagnostic push
  29. #pragma clang diagnostic ignored "-Wconversion"
  30. #endif
  31. #define JPEG_INTERNALS
  32. #undef FAR
  33. #include "jpglib/jpeglib.h"
  34. #include "jpglib/jcapimin.c"
  35. #include "jpglib/jcapistd.c"
  36. #include "jpglib/jccoefct.c"
  37. #include "jpglib/jccolor.c"
  38. #undef FIX
  39. #include "jpglib/jcdctmgr.c"
  40. #undef CONST_BITS
  41. #include "jpglib/jchuff.c"
  42. #undef emit_byte
  43. #include "jpglib/jcinit.c"
  44. #include "jpglib/jcmainct.c"
  45. #include "jpglib/jcmarker.c"
  46. #include "jpglib/jcmaster.c"
  47. #include "jpglib/jcomapi.c"
  48. #include "jpglib/jcparam.c"
  49. #include "jpglib/jcphuff.c"
  50. #include "jpglib/jcprepct.c"
  51. #include "jpglib/jcsample.c"
  52. #include "jpglib/jctrans.c"
  53. #include "jpglib/jdapistd.c"
  54. #include "jpglib/jdapimin.c"
  55. #include "jpglib/jdatasrc.c"
  56. #include "jpglib/jdcoefct.c"
  57. #undef FIX
  58. #include "jpglib/jdcolor.c"
  59. #undef FIX
  60. #include "jpglib/jddctmgr.c"
  61. #undef CONST_BITS
  62. #undef ASSIGN_STATE
  63. #include "jpglib/jdhuff.c"
  64. #include "jpglib/jdinput.c"
  65. #include "jpglib/jdmainct.c"
  66. #include "jpglib/jdmarker.c"
  67. #include "jpglib/jdmaster.c"
  68. #undef FIX
  69. #include "jpglib/jdmerge.c"
  70. #undef ASSIGN_STATE
  71. #include "jpglib/jdphuff.c"
  72. #include "jpglib/jdpostct.c"
  73. #undef FIX
  74. #include "jpglib/jdsample.c"
  75. #include "jpglib/jdtrans.c"
  76. #include "jpglib/jfdctflt.c"
  77. #include "jpglib/jfdctint.c"
  78. #undef CONST_BITS
  79. #undef MULTIPLY
  80. #undef FIX_0_541196100
  81. #include "jpglib/jfdctfst.c"
  82. #undef FIX_0_541196100
  83. #include "jpglib/jidctflt.c"
  84. #undef CONST_BITS
  85. #undef FIX_1_847759065
  86. #undef MULTIPLY
  87. #undef DEQUANTIZE
  88. #undef DESCALE
  89. #include "jpglib/jidctfst.c"
  90. #undef CONST_BITS
  91. #undef FIX_1_847759065
  92. #undef MULTIPLY
  93. #undef DEQUANTIZE
  94. #include "jpglib/jidctint.c"
  95. #include "jpglib/jidctred.c"
  96. #include "jpglib/jmemmgr.c"
  97. #include "jpglib/jmemnobs.c"
  98. #include "jpglib/jquant1.c"
  99. #include "jpglib/jquant2.c"
  100. #include "jpglib/jutils.c"
  101. #include "jpglib/transupp.c"
  102. #if JUCE_CLANG
  103. #pragma clang diagnostic pop
  104. #endif
  105. #else
  106. #define JPEG_INTERNALS
  107. #undef FAR
  108. #include <jpeglib.h>
  109. #endif
  110. }
  111. #undef max
  112. #undef min
  113. #if JUCE_MSVC
  114. #pragma warning (pop)
  115. #endif
  116. //==============================================================================
  117. namespace JPEGHelpers
  118. {
  119. using namespace jpeglibNamespace;
  120. #if ! JUCE_MSVC
  121. using jpeglibNamespace::boolean;
  122. #endif
  123. struct JPEGDecodingFailure {};
  124. static void fatalErrorHandler (j_common_ptr) { throw JPEGDecodingFailure(); }
  125. static void silentErrorCallback1 (j_common_ptr) {}
  126. static void silentErrorCallback2 (j_common_ptr, int) {}
  127. static void silentErrorCallback3 (j_common_ptr, char*) {}
  128. static void setupSilentErrorHandler (struct jpeg_error_mgr& err)
  129. {
  130. zerostruct (err);
  131. err.error_exit = fatalErrorHandler;
  132. err.emit_message = silentErrorCallback2;
  133. err.output_message = silentErrorCallback1;
  134. err.format_message = silentErrorCallback3;
  135. err.reset_error_mgr = silentErrorCallback1;
  136. }
  137. //==============================================================================
  138. #if ! JUCE_USING_COREIMAGE_LOADER
  139. static void dummyCallback1 (j_decompress_ptr) {}
  140. static void jpegSkip (j_decompress_ptr decompStruct, long num)
  141. {
  142. decompStruct->src->next_input_byte += num;
  143. num = jmin (num, (long) decompStruct->src->bytes_in_buffer);
  144. decompStruct->src->bytes_in_buffer -= (size_t) num;
  145. }
  146. static boolean jpegFill (j_decompress_ptr)
  147. {
  148. return 0;
  149. }
  150. #endif
  151. //==============================================================================
  152. const int jpegBufferSize = 512;
  153. struct JuceJpegDest : public jpeg_destination_mgr
  154. {
  155. OutputStream* output;
  156. char* buffer;
  157. };
  158. static void jpegWriteInit (j_compress_ptr) {}
  159. static void jpegWriteTerminate (j_compress_ptr cinfo)
  160. {
  161. JuceJpegDest* const dest = static_cast <JuceJpegDest*> (cinfo->dest);
  162. const size_t numToWrite = jpegBufferSize - dest->free_in_buffer;
  163. dest->output->write (dest->buffer, numToWrite);
  164. }
  165. static boolean jpegWriteFlush (j_compress_ptr cinfo)
  166. {
  167. JuceJpegDest* const dest = static_cast <JuceJpegDest*> (cinfo->dest);
  168. const int numToWrite = jpegBufferSize;
  169. dest->next_output_byte = reinterpret_cast <JOCTET*> (dest->buffer);
  170. dest->free_in_buffer = jpegBufferSize;
  171. return (boolean) dest->output->write (dest->buffer, (size_t) numToWrite);
  172. }
  173. }
  174. //==============================================================================
  175. JPEGImageFormat::JPEGImageFormat()
  176. : quality (-1.0f)
  177. {
  178. }
  179. JPEGImageFormat::~JPEGImageFormat() {}
  180. void JPEGImageFormat::setQuality (const float newQuality)
  181. {
  182. quality = newQuality;
  183. }
  184. String JPEGImageFormat::getFormatName() { return "JPEG"; }
  185. bool JPEGImageFormat::usesFileExtension (const File& f) { return f.hasFileExtension ("jpeg;jpg"); }
  186. bool JPEGImageFormat::canUnderstand (InputStream& in)
  187. {
  188. const int bytesNeeded = 10;
  189. uint8 header [bytesNeeded];
  190. return in.read (header, bytesNeeded) == bytesNeeded
  191. && header[0] == 0xff
  192. && header[1] == 0xd8
  193. && header[2] == 0xff;
  194. }
  195. #if JUCE_USING_COREIMAGE_LOADER
  196. Image juce_loadWithCoreImage (InputStream& input);
  197. #endif
  198. Image JPEGImageFormat::decodeImage (InputStream& in)
  199. {
  200. #if JUCE_USING_COREIMAGE_LOADER
  201. return juce_loadWithCoreImage (in);
  202. #else
  203. using namespace jpeglibNamespace;
  204. using namespace JPEGHelpers;
  205. MemoryOutputStream mb;
  206. mb << in;
  207. Image image;
  208. if (mb.getDataSize() > 16)
  209. {
  210. struct jpeg_decompress_struct jpegDecompStruct;
  211. struct jpeg_error_mgr jerr;
  212. setupSilentErrorHandler (jerr);
  213. jpegDecompStruct.err = &jerr;
  214. jpeg_create_decompress (&jpegDecompStruct);
  215. jpegDecompStruct.src = (jpeg_source_mgr*)(jpegDecompStruct.mem->alloc_small)
  216. ((j_common_ptr)(&jpegDecompStruct), JPOOL_PERMANENT, sizeof (jpeg_source_mgr));
  217. jpegDecompStruct.src->init_source = dummyCallback1;
  218. jpegDecompStruct.src->fill_input_buffer = jpegFill;
  219. jpegDecompStruct.src->skip_input_data = jpegSkip;
  220. jpegDecompStruct.src->resync_to_restart = jpeg_resync_to_restart;
  221. jpegDecompStruct.src->term_source = dummyCallback1;
  222. jpegDecompStruct.src->next_input_byte = static_cast <const unsigned char*> (mb.getData());
  223. jpegDecompStruct.src->bytes_in_buffer = mb.getDataSize();
  224. try
  225. {
  226. jpeg_read_header (&jpegDecompStruct, TRUE);
  227. jpeg_calc_output_dimensions (&jpegDecompStruct);
  228. const int width = (int) jpegDecompStruct.output_width;
  229. const int height = (int) jpegDecompStruct.output_height;
  230. jpegDecompStruct.out_color_space = JCS_RGB;
  231. JSAMPARRAY buffer
  232. = (*jpegDecompStruct.mem->alloc_sarray) ((j_common_ptr) &jpegDecompStruct,
  233. JPOOL_IMAGE,
  234. (JDIMENSION) width * 3, 1);
  235. if (jpeg_start_decompress (&jpegDecompStruct))
  236. {
  237. image = Image (Image::RGB, width, height, false);
  238. image.getProperties()->set ("originalImageHadAlpha", false);
  239. const bool hasAlphaChan = image.hasAlphaChannel(); // (the native image creator may not give back what we expect)
  240. const Image::BitmapData destData (image, Image::BitmapData::writeOnly);
  241. for (int y = 0; y < height; ++y)
  242. {
  243. jpeg_read_scanlines (&jpegDecompStruct, buffer, 1);
  244. const uint8* src = *buffer;
  245. uint8* dest = destData.getLinePointer (y);
  246. if (hasAlphaChan)
  247. {
  248. for (int i = width; --i >= 0;)
  249. {
  250. ((PixelARGB*) dest)->setARGB (0xff, src[0], src[1], src[2]);
  251. ((PixelARGB*) dest)->premultiply();
  252. dest += destData.pixelStride;
  253. src += 3;
  254. }
  255. }
  256. else
  257. {
  258. for (int i = width; --i >= 0;)
  259. {
  260. ((PixelRGB*) dest)->setARGB (0xff, src[0], src[1], src[2]);
  261. dest += destData.pixelStride;
  262. src += 3;
  263. }
  264. }
  265. }
  266. jpeg_finish_decompress (&jpegDecompStruct);
  267. in.setPosition (((char*) jpegDecompStruct.src->next_input_byte) - (char*) mb.getData());
  268. }
  269. jpeg_destroy_decompress (&jpegDecompStruct);
  270. }
  271. catch (...)
  272. {}
  273. }
  274. return image;
  275. #endif
  276. }
  277. bool JPEGImageFormat::writeImageToStream (const Image& image, OutputStream& out)
  278. {
  279. using namespace jpeglibNamespace;
  280. using namespace JPEGHelpers;
  281. jpeg_compress_struct jpegCompStruct;
  282. zerostruct (jpegCompStruct);
  283. jpeg_create_compress (&jpegCompStruct);
  284. struct jpeg_error_mgr jerr;
  285. setupSilentErrorHandler (jerr);
  286. jpegCompStruct.err = &jerr;
  287. JuceJpegDest dest;
  288. jpegCompStruct.dest = &dest;
  289. dest.output = &out;
  290. HeapBlock <char> tempBuffer (jpegBufferSize);
  291. dest.buffer = tempBuffer;
  292. dest.next_output_byte = (JOCTET*) dest.buffer;
  293. dest.free_in_buffer = jpegBufferSize;
  294. dest.init_destination = jpegWriteInit;
  295. dest.empty_output_buffer = jpegWriteFlush;
  296. dest.term_destination = jpegWriteTerminate;
  297. jpegCompStruct.image_width = (JDIMENSION) image.getWidth();
  298. jpegCompStruct.image_height = (JDIMENSION) image.getHeight();
  299. jpegCompStruct.input_components = 3;
  300. jpegCompStruct.in_color_space = JCS_RGB;
  301. jpegCompStruct.write_JFIF_header = 1;
  302. jpegCompStruct.X_density = 72;
  303. jpegCompStruct.Y_density = 72;
  304. jpeg_set_defaults (&jpegCompStruct);
  305. jpegCompStruct.dct_method = JDCT_FLOAT;
  306. jpegCompStruct.optimize_coding = 1;
  307. if (quality < 0.0f)
  308. quality = 0.85f;
  309. jpeg_set_quality (&jpegCompStruct, jlimit (0, 100, roundToInt (quality * 100.0f)), TRUE);
  310. jpeg_start_compress (&jpegCompStruct, TRUE);
  311. const int strideBytes = (int) (jpegCompStruct.image_width * (unsigned int) jpegCompStruct.input_components);
  312. JSAMPARRAY buffer = (*jpegCompStruct.mem->alloc_sarray) ((j_common_ptr) &jpegCompStruct,
  313. JPOOL_IMAGE, (JDIMENSION) strideBytes, 1);
  314. const Image::BitmapData srcData (image, Image::BitmapData::readOnly);
  315. while (jpegCompStruct.next_scanline < jpegCompStruct.image_height)
  316. {
  317. uint8* dst = *buffer;
  318. if (srcData.pixelFormat == Image::RGB)
  319. {
  320. const uint8* src = srcData.getLinePointer ((int) jpegCompStruct.next_scanline);
  321. for (int i = srcData.width; --i >= 0;)
  322. {
  323. *dst++ = ((const PixelRGB*) src)->getRed();
  324. *dst++ = ((const PixelRGB*) src)->getGreen();
  325. *dst++ = ((const PixelRGB*) src)->getBlue();
  326. src += srcData.pixelStride;
  327. }
  328. }
  329. else
  330. {
  331. for (int x = 0; x < srcData.width; ++x)
  332. {
  333. const Colour pixel (srcData.getPixelColour (x, (int) jpegCompStruct.next_scanline));
  334. *dst++ = pixel.getRed();
  335. *dst++ = pixel.getGreen();
  336. *dst++ = pixel.getBlue();
  337. }
  338. }
  339. jpeg_write_scanlines (&jpegCompStruct, buffer, 1);
  340. }
  341. jpeg_finish_compress (&jpegCompStruct);
  342. jpeg_destroy_compress (&jpegCompStruct);
  343. return true;
  344. }