JUCE-7.0.12-0-g4f43011b96 JUCE-7.0.12-0-g4f43011b96
JUCE — C++ application framework with suport for VST, VST3, LV2 audio plug-ins

« « « Anklang Documentation
Loading...
Searching...
No Matches
juce_JPEGLoader.cpp
Go to the documentation of this file.
1 /*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce
27{
28
29JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4365 6240 6326 6386 6385 28182 28183 6387 6011 6001)
30
31namespace jpeglibNamespace
32{
33#if JUCE_INCLUDE_JPEGLIB_CODE || ! defined (JUCE_INCLUDE_JPEGLIB_CODE)
34 #if JUCE_MINGW
35 typedef unsigned char boolean;
36 #endif
37
38 JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wconversion",
39 "-Wdeprecated-register",
40 "-Wdeprecated-declarations",
41 "-Wsign-conversion",
42 "-Wcast-align",
43 "-Wswitch-enum",
44 "-Wswitch-default",
45 "-Wimplicit-fallthrough",
46 "-Wzero-as-null-pointer-constant",
47 "-Wshift-negative-value",
48 "-Wcomma")
49
50 #define JPEG_INTERNALS
51 #undef FAR
52 #include "jpglib/jpeglib.h"
53
54 #include "jpglib/jcapimin.c"
55 #include "jpglib/jcapistd.c"
56 #include "jpglib/jccoefct.c"
57 #include "jpglib/jccolor.c"
58 #undef FIX
59 #include "jpglib/jcdctmgr.c"
60 #undef CONST_BITS
61 #include "jpglib/jchuff.c"
62 #undef emit_byte
63 #include "jpglib/jcinit.c"
64 #include "jpglib/jcmainct.c"
65 #include "jpglib/jcmarker.c"
66 #include "jpglib/jcmaster.c"
67 #include "jpglib/jcomapi.c"
68 #include "jpglib/jcparam.c"
69 #include "jpglib/jcphuff.c"
70 #include "jpglib/jcprepct.c"
71 #include "jpglib/jcsample.c"
72 #include "jpglib/jctrans.c"
73 #include "jpglib/jdapistd.c"
74 #include "jpglib/jdapimin.c"
75 #include "jpglib/jdatasrc.c"
76 #include "jpglib/jdcoefct.c"
77 #undef FIX
78 #include "jpglib/jdcolor.c"
79 #undef FIX
80 #include "jpglib/jddctmgr.c"
81 #undef CONST_BITS
82 #undef ASSIGN_STATE
83 #include "jpglib/jdhuff.c"
84 #include "jpglib/jdinput.c"
85 #include "jpglib/jdmainct.c"
86 #include "jpglib/jdmarker.c"
87 #include "jpglib/jdmaster.c"
88 #undef FIX
89 #include "jpglib/jdmerge.c"
90 #undef ASSIGN_STATE
91 #include "jpglib/jdphuff.c"
92 #include "jpglib/jdpostct.c"
93 #undef FIX
94 #include "jpglib/jdsample.c"
95 #include "jpglib/jdtrans.c"
96 #include "jpglib/jfdctflt.c"
97 #include "jpglib/jfdctint.c"
98 #undef CONST_BITS
99 #undef MULTIPLY
100 #undef FIX_0_541196100
101 #include "jpglib/jfdctfst.c"
102 #undef FIX_0_541196100
103 #include "jpglib/jidctflt.c"
104 #undef CONST_BITS
105 #undef FIX_1_847759065
106 #undef MULTIPLY
107 #undef DEQUANTIZE
108 #undef DESCALE
109 #include "jpglib/jidctfst.c"
110 #undef CONST_BITS
111 #undef FIX_1_847759065
112 #undef MULTIPLY
113 #undef DEQUANTIZE
114 #include "jpglib/jidctint.c"
115 #include "jpglib/jidctred.c"
116 #include "jpglib/jmemmgr.c"
117 #include "jpglib/jmemnobs.c"
118 #include "jpglib/jquant1.c"
119 #include "jpglib/jquant2.c"
120 #include "jpglib/jutils.c"
121 #include "jpglib/transupp.c"
122
123 JUCE_END_IGNORE_WARNINGS_GCC_LIKE
124#else
125 #define JPEG_INTERNALS
126 #undef FAR
127 #include <jpeglib.h>
128#endif
129}
130
131#undef max
132#undef min
133
134JUCE_END_IGNORE_WARNINGS_MSVC
135
136//==============================================================================
137namespace JPEGHelpers
138{
139 using namespace jpeglibNamespace;
140
141 #if ! (JUCE_WINDOWS && (JUCE_MSVC || JUCE_CLANG))
142 using jpeglibNamespace::boolean;
143 #endif
144
145 static void fatalErrorHandler (j_common_ptr p) { *((bool*) (p->client_data)) = true; }
146 static void silentErrorCallback1 (j_common_ptr) {}
147 static void silentErrorCallback2 (j_common_ptr, int) {}
148 static void silentErrorCallback3 (j_common_ptr, char*) {}
149
150 static void setupSilentErrorHandler (struct jpeg_error_mgr& err)
151 {
152 zerostruct (err);
153
154 err.error_exit = fatalErrorHandler;
155 err.emit_message = silentErrorCallback2;
156 err.output_message = silentErrorCallback1;
157 err.format_message = silentErrorCallback3;
158 err.reset_error_mgr = silentErrorCallback1;
159 }
160
161 //==============================================================================
162 #if ! JUCE_USING_COREIMAGE_LOADER
163 static void dummyCallback1 (j_decompress_ptr) {}
164
165 static void jpegSkip (j_decompress_ptr decompStruct, long num)
166 {
167 decompStruct->src->next_input_byte += num;
168
169 num = jmin (num, (long) decompStruct->src->bytes_in_buffer);
170 decompStruct->src->bytes_in_buffer -= (size_t) num;
171 }
172
173 static boolean jpegFill (j_decompress_ptr)
174 {
175 return 0;
176 }
177 #endif
178
179 //==============================================================================
180 const int jpegBufferSize = 512;
181
183 {
184 OutputStream* output;
185 char* buffer;
186 };
187
188 static void jpegWriteInit (j_compress_ptr) {}
189
190 static void jpegWriteTerminate (j_compress_ptr cinfo)
191 {
192 JuceJpegDest* const dest = static_cast<JuceJpegDest*> (cinfo->dest);
193
194 const size_t numToWrite = jpegBufferSize - dest->free_in_buffer;
195 dest->output->write (dest->buffer, numToWrite);
196 }
197
198 static boolean jpegWriteFlush (j_compress_ptr cinfo)
199 {
200 JuceJpegDest* const dest = static_cast<JuceJpegDest*> (cinfo->dest);
201
202 const int numToWrite = jpegBufferSize;
203
204 dest->next_output_byte = reinterpret_cast<JOCTET*> (dest->buffer);
205 dest->free_in_buffer = jpegBufferSize;
206
207 return (boolean) dest->output->write (dest->buffer, (size_t) numToWrite);
208 }
209}
210
211//==============================================================================
212JPEGImageFormat::JPEGImageFormat()
213 : quality (-1.0f)
214{
215}
216
217JPEGImageFormat::~JPEGImageFormat() {}
218
220{
221 quality = newQuality;
222}
223
225bool JPEGImageFormat::usesFileExtension (const File& f) { return f.hasFileExtension ("jpeg;jpg"); }
226
228{
229 const int bytesNeeded = 24;
230 uint8 header [bytesNeeded];
231
232 if (in.read (header, bytesNeeded) == bytesNeeded
233 && header[0] == 0xff
234 && header[1] == 0xd8
235 && header[2] == 0xff)
236 return true;
237
238 #if JUCE_USING_COREIMAGE_LOADER
239 return header[20] == 'j'
240 && header[21] == 'p'
241 && header[22] == '2'
242 && header[23] == ' ';
243 #endif
244
245 return false;
246}
247
248#if JUCE_USING_COREIMAGE_LOADER
250#endif
251
253{
254 #if JUCE_USING_COREIMAGE_LOADER
255 return juce_loadWithCoreImage (in);
256 #else
257 using namespace jpeglibNamespace;
258 using namespace JPEGHelpers;
259
261 mb << in;
262
263 Image image;
264
265 if (mb.getDataSize() > 16)
266 {
268
269 struct jpeg_error_mgr jerr;
270 setupSilentErrorHandler (jerr);
271 jpegDecompStruct.err = &jerr;
272
274
275 jpegDecompStruct.src = (jpeg_source_mgr*)(jpegDecompStruct.mem->alloc_small)
277
278 bool hasFailed = false;
279 jpegDecompStruct.client_data = &hasFailed;
280
281 jpegDecompStruct.src->init_source = dummyCallback1;
282 jpegDecompStruct.src->fill_input_buffer = jpegFill;
283 jpegDecompStruct.src->skip_input_data = jpegSkip;
284 jpegDecompStruct.src->resync_to_restart = jpeg_resync_to_restart;
285 jpegDecompStruct.src->term_source = dummyCallback1;
286
287 jpegDecompStruct.src->next_input_byte = static_cast<const unsigned char*> (mb.getData());
288 jpegDecompStruct.src->bytes_in_buffer = mb.getDataSize();
289
291
292 if (! hasFailed)
293 {
295
296 if (! hasFailed)
297 {
298 const int width = (int) jpegDecompStruct.output_width;
299 const int height = (int) jpegDecompStruct.output_height;
300
301 jpegDecompStruct.out_color_space = JCS_RGB;
302
303 JSAMPARRAY buffer
304 = (*jpegDecompStruct.mem->alloc_sarray) ((j_common_ptr) &jpegDecompStruct,
306 (JDIMENSION) width * 3, 1);
307
309 {
310 image = Image (Image::RGB, width, height, false);
311 image.getProperties()->set ("originalImageHadAlpha", false);
312 const bool hasAlphaChan = image.hasAlphaChannel(); // (the native image creator may not give back what we expect)
313
314 const Image::BitmapData destData (image, Image::BitmapData::writeOnly);
315
316 for (int y = 0; y < height; ++y)
317 {
319
320 if (hasFailed)
321 break;
322
323 const uint8* src = *buffer;
324 uint8* dest = destData.getLinePointer (y);
325
326 if (hasAlphaChan)
327 {
328 for (int i = width; --i >= 0;)
329 {
330 ((PixelARGB*) dest)->setARGB (0xff, src[0], src[1], src[2]);
331 ((PixelARGB*) dest)->premultiply();
332 dest += destData.pixelStride;
333 src += 3;
334 }
335 }
336 else
337 {
338 for (int i = width; --i >= 0;)
339 {
340 ((PixelRGB*) dest)->setARGB (0xff, src[0], src[1], src[2]);
341 dest += destData.pixelStride;
342 src += 3;
343 }
344 }
345 }
346
347 if (! hasFailed)
349
350 in.setPosition (((char*) jpegDecompStruct.src->next_input_byte) - (char*) mb.getData());
351 }
352 }
353 }
354
356 }
357
358 return image;
359 #endif
360}
361
363{
364 using namespace jpeglibNamespace;
365 using namespace JPEGHelpers;
366
370
371 struct jpeg_error_mgr jerr;
372 setupSilentErrorHandler (jerr);
373 jpegCompStruct.err = &jerr;
374
375 JuceJpegDest dest;
376 jpegCompStruct.dest = &dest;
377
378 dest.output = &out;
379 HeapBlock<char> tempBuffer (jpegBufferSize);
380 dest.buffer = tempBuffer;
381 dest.next_output_byte = (JOCTET*) dest.buffer;
382 dest.free_in_buffer = jpegBufferSize;
383 dest.init_destination = jpegWriteInit;
384 dest.empty_output_buffer = jpegWriteFlush;
385 dest.term_destination = jpegWriteTerminate;
386
387 jpegCompStruct.image_width = (JDIMENSION) image.getWidth();
388 jpegCompStruct.image_height = (JDIMENSION) image.getHeight();
389 jpegCompStruct.input_components = 3;
390 jpegCompStruct.in_color_space = JCS_RGB;
391 jpegCompStruct.write_JFIF_header = 1;
392
393 jpegCompStruct.X_density = 72;
394 jpegCompStruct.Y_density = 72;
395
397
398 jpegCompStruct.dct_method = JDCT_FLOAT;
399 jpegCompStruct.optimize_coding = 1;
400
401 if (quality < 0.0f)
402 quality = 0.85f;
403
404 jpeg_set_quality (&jpegCompStruct, jlimit (0, 100, roundToInt (quality * 100.0f)), TRUE);
405
407
408 const int strideBytes = (int) (jpegCompStruct.image_width * (unsigned int) jpegCompStruct.input_components);
409
410 JSAMPARRAY buffer = (*jpegCompStruct.mem->alloc_sarray) ((j_common_ptr) &jpegCompStruct,
412
413 const Image::BitmapData srcData (image, Image::BitmapData::readOnly);
414
415 while (jpegCompStruct.next_scanline < jpegCompStruct.image_height)
416 {
417 uint8* dst = *buffer;
418
419 if (srcData.pixelFormat == Image::RGB)
420 {
421 const uint8* src = srcData.getLinePointer ((int) jpegCompStruct.next_scanline);
422
423 for (int i = srcData.width; --i >= 0;)
424 {
425 *dst++ = ((const PixelRGB*) src)->getRed();
426 *dst++ = ((const PixelRGB*) src)->getGreen();
427 *dst++ = ((const PixelRGB*) src)->getBlue();
428 src += srcData.pixelStride;
429 }
430 }
431 else
432 {
433 for (int x = 0; x < srcData.width; ++x)
434 {
435 const Colour pixel (srcData.getPixelColour (x, (int) jpegCompStruct.next_scanline));
436 *dst++ = pixel.getRed();
437 *dst++ = pixel.getGreen();
438 *dst++ = pixel.getBlue();
439 }
440 }
441
443 }
444
447
448 return true;
449}
450
451} // namespace juce
Represents a colour, also including a transparency value.
Definition juce_Colour.h:38
Represents a local file or directory.
Definition juce_File.h:45
bool hasFileExtension(StringRef extensionToTest) const
Checks whether the file has a given extension.
Very simple container class to hold a pointer to some data on the heap.
Retrieves a section of an image as raw pixel data, so it can be read or written to.
Definition juce_Image.h:310
int pixelStride
The number of bytes between each pixel.
Definition juce_Image.h:355
uint8 * getLinePointer(int y) const noexcept
Returns a pointer to the start of a line in the image.
Definition juce_Image.h:328
Colour getPixelColour(int x, int y) const noexcept
Returns the colour of a given pixel.
PixelFormat pixelFormat
The format of the data.
Definition juce_Image.h:353
Holds a fixed-size bitmap.
Definition juce_Image.h:58
@ RGB
< each pixel is a 3-byte packed RGB colour value.
Definition juce_Image.h:66
The base class for streams that read data.
virtual bool setPosition(int64 newPosition)=0
Tries to move the current read position of the stream.
virtual int read(void *destBuffer, int maxBytesToRead)=0
Reads some data from the stream into a memory buffer.
void setQuality(float newQuality)
Specifies the quality to be used when writing a JPEG file.
bool writeImageToStream(const Image &, OutputStream &) override
Attempts to write an image to a stream.
bool usesFileExtension(const File &) override
Returns true if this format uses the file extension of the given file.
String getFormatName() override
Returns a description of this file format.
bool canUnderstand(InputStream &) override
Returns true if the given stream seems to contain data that this format understands.
Image decodeImage(InputStream &) override
Tries to decode and return an image from the given stream.
Writes data to an internal memory buffer, which grows as required.
The base class for streams that write data to some kind of destination.
Represents a 32-bit INTERNAL pixel with premultiplied alpha, and can perform compositing operations w...
Represents a 24-bit RGB pixel, and can perform compositing operations on it.
The JUCE String class!
Definition juce_String.h:53
typedef int
JUCE Namespace.
void zerostruct(Type &structure) noexcept
Overwrites a structure or object with zeros.
Definition juce_Memory.h:32
constexpr Type jmin(Type a, Type b)
Returns the smaller of two values.
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Constrains a value to keep it within a given range.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
Definition juce_Memory.h:88
unsigned char uint8
A platform-independent 8-bit unsigned integer type.
int roundToInt(const FloatType value) noexcept
Fast floating-point-to-integer conversion.
typedef size_t