1 /*
2   ==============================================================================
3 
4    This file is part of the JUCE library.
5    Copyright (c) 2020 - 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 6 End-User License
11    Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
12 
13    End User License Agreement: www.juce.com/juce-6-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 
26 namespace juce
27 {
28 
29 //==============================================================================
30 /**
31     Base-class for codecs that can read and write image file formats such
32     as PNG, JPEG, etc.
33 
34     This class also contains static methods to make it easy to load images
35     from files, streams or from memory.
36 
37     @see Image, ImageCache
38 
39     @tags{Graphics}
40 */
41 class JUCE_API  ImageFileFormat
42 {
43 protected:
44     //==============================================================================
45     /** Creates an ImageFormat. */
46     ImageFileFormat() = default;
47 
48 public:
49     /** Destructor. */
50     virtual ~ImageFileFormat() = default;
51 
52     //==============================================================================
53     /** Returns a description of this file format.
54 
55         E.g. "JPEG", "PNG"
56     */
57     virtual String getFormatName() = 0;
58 
59     /** Returns true if the given stream seems to contain data that this format understands.
60 
61         The format class should only read the first few bytes of the stream and sniff
62         for header bytes that it understands.
63 
64         Note that this will advance the stream and leave it in a new position, so if you're
65         planning on re-using it, you may want to rewind it after calling this method.
66 
67         @see decodeImage
68     */
69     virtual bool canUnderstand (InputStream& input) = 0;
70 
71     /** Returns true if this format uses the file extension of the given file. */
72     virtual bool usesFileExtension (const File& possibleFile) = 0;
73 
74     /** Tries to decode and return an image from the given stream.
75 
76         This will be called for an image format after calling its canUnderStand() method
77         to see if it can handle the stream.
78 
79         @param input    the stream to read the data from. The stream will be positioned
80                         at the start of the image data (but this may not necessarily
81                         be position 0)
82         @returns        the image that was decoded, or an invalid image if it fails.
83         @see loadFrom
84     */
85     virtual Image decodeImage (InputStream& input) = 0;
86 
87     //==============================================================================
88     /** Attempts to write an image to a stream.
89 
90         To specify extra information like encoding quality, there will be appropriate parameters
91         in the subclasses of the specific file types.
92 
93         @returns        true if it nothing went wrong.
94     */
95     virtual bool writeImageToStream (const Image& sourceImage,
96                                      OutputStream& destStream) = 0;
97 
98     //==============================================================================
99     /** Tries the built-in formats to see if it can find one to read this stream.
100         There are currently built-in decoders for PNG, JPEG and GIF formats.
101         The object that is returned should not be deleted by the caller.
102         @see canUnderstand, decodeImage, loadFrom
103     */
104     static ImageFileFormat* findImageFormatForStream (InputStream& input);
105 
106     /** Looks for a format that can handle the given file extension.
107         There are currently built-in formats for PNG, JPEG and GIF formats.
108         The object that is returned should not be deleted by the caller.
109     */
110     static ImageFileFormat* findImageFormatForFileExtension (const File& file);
111 
112     //==============================================================================
113     /** Tries to load an image from a stream.
114 
115         This will use the findImageFormatForStream() method to locate a suitable
116         codec, and use that to load the image.
117 
118         @returns        the image that was decoded, or an invalid image if it fails.
119     */
120     static Image loadFrom (InputStream& input);
121 
122     /** Tries to load an image from a file.
123 
124         This will use the findImageFormatForStream() method to locate a suitable
125         codec, and use that to load the image.
126 
127         @returns        the image that was decoded, or an invalid image if it fails.
128     */
129     static Image loadFrom (const File& file);
130 
131     /** Tries to load an image from a block of raw image data.
132 
133         This will use the findImageFormatForStream() method to locate a suitable
134         codec, and use that to load the image.
135 
136         @returns        the image that was decoded, or an invalid image if it fails.
137     */
138     static Image loadFrom (const void* rawData,
139                            size_t numBytesOfData);
140 };
141 
142 //==============================================================================
143 /**
144     A subclass of ImageFileFormat for reading and writing PNG files.
145 
146     @see ImageFileFormat, JPEGImageFormat
147 
148     @tags{Graphics}
149 */
150 class JUCE_API  PNGImageFormat  : public ImageFileFormat
151 {
152 public:
153     //==============================================================================
154     PNGImageFormat();
155     ~PNGImageFormat() override;
156 
157     //==============================================================================
158     String getFormatName() override;
159     bool usesFileExtension (const File&) override;
160     bool canUnderstand (InputStream&) override;
161     Image decodeImage (InputStream&) override;
162     bool writeImageToStream (const Image&, OutputStream&) override;
163 };
164 
165 
166 //==============================================================================
167 /**
168     A subclass of ImageFileFormat for reading and writing JPEG files.
169 
170     @see ImageFileFormat, PNGImageFormat
171 
172     @tags{Graphics}
173 */
174 class JUCE_API  JPEGImageFormat  : public ImageFileFormat
175 {
176 public:
177     //==============================================================================
178     JPEGImageFormat();
179     ~JPEGImageFormat() override;
180 
181     //==============================================================================
182     /** Specifies the quality to be used when writing a JPEG file.
183 
184         @param newQuality  a value 0 to 1.0, where 0 is low quality, 1.0 is best, or
185                            any negative value is "default" quality
186     */
187     void setQuality (float newQuality);
188 
189     //==============================================================================
190     String getFormatName() override;
191     bool usesFileExtension (const File&) override;
192     bool canUnderstand (InputStream&) override;
193     Image decodeImage (InputStream&) override;
194     bool writeImageToStream (const Image&, OutputStream&) override;
195 
196 private:
197     float quality;
198 };
199 
200 //==============================================================================
201 /**
202     A subclass of ImageFileFormat for reading GIF files.
203 
204     @see ImageFileFormat, PNGImageFormat, JPEGImageFormat
205 
206     @tags{Graphics}
207 */
208 class JUCE_API  GIFImageFormat  : public ImageFileFormat
209 {
210 public:
211     //==============================================================================
212     GIFImageFormat();
213     ~GIFImageFormat() override;
214 
215     //==============================================================================
216     String getFormatName() override;
217     bool usesFileExtension (const File&) override;
218     bool canUnderstand (InputStream&) override;
219     Image decodeImage (InputStream&) override;
220     bool writeImageToStream (const Image&, OutputStream&) override;
221 };
222 
223 } // namespace juce
224