1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  *
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef mozilla_image_DecoderFactory_h
8 #define mozilla_image_DecoderFactory_h
9 
10 #include "DecoderFlags.h"
11 #include "mozilla/Attributes.h"
12 #include "mozilla/Maybe.h"
13 #include "mozilla/NotNull.h"
14 #include "mozilla/gfx/2D.h"
15 #include "nsCOMPtr.h"
16 #include "Orientation.h"
17 #include "SurfaceFlags.h"
18 
19 namespace mozilla::image {
20 
21 class Decoder;
22 class IDecodingTask;
23 class nsICODecoder;
24 class RasterImage;
25 class SourceBuffer;
26 class SourceBufferIterator;
27 
28 /**
29  * The type of decoder; this is usually determined from a MIME type using
30  * DecoderFactory::GetDecoderType().
31  */
32 enum class DecoderType {
33   PNG,
34   GIF,
35   JPEG,
36   BMP,
37   BMP_CLIPBOARD,
38   ICO,
39   ICON,
40   WEBP,
41   AVIF,
42   JXL,
43   UNKNOWN
44 };
45 
46 class DecoderFactory {
47  public:
48   /// @return the type of decoder which is appropriate for @aMimeType.
49   static DecoderType GetDecoderType(const char* aMimeType);
50 
51   /**
52    * Creates and initializes a decoder for non-animated images of type @aType.
53    * (If the image *is* animated, only the first frame will be decoded.) The
54    * decoder will send notifications to @aImage.
55    *
56    * @param aType Which type of decoder to create - JPEG, PNG, etc.
57    * @param aImage The image will own the decoder and which should receive
58    *               notifications as decoding progresses.
59    * @param aSourceBuffer The SourceBuffer which the decoder will read its data
60    *                      from.
61    * @param aIntrinsicSize The intrinsic size of the image, normally obtained
62    *                       during the metadata decode.
63    * @param aOutputSize The output size for the decoder. If this is smaller than
64    *                    the intrinsic size, the decoder will downscale the
65    *                    image.
66    * @param aDecoderFlags Flags specifying the behavior of this decoder.
67    * @param aSurfaceFlags Flags specifying the type of output this decoder
68    *                      should produce.
69    * @param aOutTask Task representing the decoder.
70    * @return NS_OK if the decoder has been created/initialized successfully;
71    *         NS_ERROR_ALREADY_INITIALIZED if there is already an active decoder
72    *           for this image;
73    *         Else some other unrecoverable error occurred.
74    */
75   static nsresult CreateDecoder(DecoderType aType, NotNull<RasterImage*> aImage,
76                                 NotNull<SourceBuffer*> aSourceBuffer,
77                                 const gfx::IntSize& aIntrinsicSize,
78                                 const gfx::IntSize& aOutputSize,
79                                 DecoderFlags aDecoderFlags,
80                                 SurfaceFlags aSurfaceFlags,
81                                 IDecodingTask** aOutTask);
82 
83   /**
84    * Creates and initializes a decoder for animated images of type @aType.
85    * The decoder will send notifications to @aImage.
86    *
87    * @param aType Which type of decoder to create - JPEG, PNG, etc.
88    * @param aImage The image will own the decoder and which should receive
89    *               notifications as decoding progresses.
90    * @param aSourceBuffer The SourceBuffer which the decoder will read its data
91    *                      from.
92    * @param aIntrinsicSize The intrinsic size of the image, normally obtained
93    *                       during the metadata decode.
94    * @param aDecoderFlags Flags specifying the behavior of this decoder.
95    * @param aSurfaceFlags Flags specifying the type of output this decoder
96    *                      should produce.
97    * @param aCurrentFrame The current frame the decoder should auto advance to.
98    * @param aOutTask Task representing the decoder.
99    * @return NS_OK if the decoder has been created/initialized successfully;
100    *         NS_ERROR_ALREADY_INITIALIZED if there is already an active decoder
101    *           for this image;
102    *         Else some other unrecoverable error occurred.
103    */
104   static nsresult CreateAnimationDecoder(
105       DecoderType aType, NotNull<RasterImage*> aImage,
106       NotNull<SourceBuffer*> aSourceBuffer, const gfx::IntSize& aIntrinsicSize,
107       DecoderFlags aDecoderFlags, SurfaceFlags aSurfaceFlags,
108       size_t aCurrentFrame, IDecodingTask** aOutTask);
109 
110   /**
111    * Creates and initializes a decoder for animated images, cloned from the
112    * given decoder.
113    *
114    * @param aDecoder Decoder to clone.
115    */
116   static already_AddRefed<Decoder> CloneAnimationDecoder(Decoder* aDecoder);
117 
118   /**
119    * Creates and initializes a metadata decoder of type @aType. This decoder
120    * will only decode the image's header, extracting metadata like the size of
121    * the image. No actual image data will be decoded and no surfaces will be
122    * allocated. The decoder will send notifications to @aImage.
123    *
124    * @param aType Which type of decoder to create - JPEG, PNG, etc.
125    * @param aImage The image will own the decoder and which should receive
126    *               notifications as decoding progresses.
127    * @param aSourceBuffer The SourceBuffer which the decoder will read its data
128    *                      from.
129    */
130   static already_AddRefed<IDecodingTask> CreateMetadataDecoder(
131       DecoderType aType, NotNull<RasterImage*> aImage,
132       NotNull<SourceBuffer*> aSourceBuffer);
133 
134   /**
135    * Creates and initializes a decoder for an ICO resource, which may be either
136    * a BMP or PNG image.
137    *
138    * @param aType Which type of decoder to create. This must be either BMP or
139    *              PNG.
140    * @param aIterator The SourceBufferIterator which the decoder will read its
141    *                  data from.
142    * @param aICODecoder The ICO decoder which is controlling this resource
143    *                    decoder. @aICODecoder's settings will be copied to the
144    *                    resource decoder, so the two decoders will have the
145    *                    same decoder flags, surface flags, target size, and
146    *                    other parameters.
147    * @param aIsMetadataDecode Indicates whether or not this decoder is for
148    *                          metadata or not. Independent of the state of the
149    *                          parent decoder.
150    * @param aExpectedSize The expected size of the resource from the ICO header.
151    * @param aDataOffset If @aType is BMP, specifies the offset at which data
152    *                    begins in the BMP resource. Must be Some() if and only
153    *                    if @aType is BMP.
154    */
155   static already_AddRefed<Decoder> CreateDecoderForICOResource(
156       DecoderType aType, SourceBufferIterator&& aIterator,
157       NotNull<nsICODecoder*> aICODecoder, bool aIsMetadataDecode,
158       const Maybe<OrientedIntSize>& aExpectedSize,
159       const Maybe<uint32_t>& aDataOffset = Nothing());
160 
161   /**
162    * Creates and initializes an anonymous decoder (one which isn't associated
163    * with an Image object). Only the first frame of the image will be decoded.
164    *
165    * @param aType Which type of decoder to create - JPEG, PNG, etc.
166    * @param aSourceBuffer The SourceBuffer which the decoder will read its data
167    *                      from.
168    * @param aOutputSize If Some(), the output size for the decoder. If this is
169    *                    smaller than the intrinsic size, the decoder will
170    *                    downscale the image. If Nothing(), the output size will
171    *                    be the intrinsic size.
172    * @param aDecoderFlags Flags specifying the behavior of this decoder.
173    * @param aSurfaceFlags Flags specifying the type of output this decoder
174    *                      should produce.
175    */
176   static already_AddRefed<Decoder> CreateAnonymousDecoder(
177       DecoderType aType, NotNull<SourceBuffer*> aSourceBuffer,
178       const Maybe<gfx::IntSize>& aOutputSize, DecoderFlags aDecoderFlags,
179       SurfaceFlags aSurfaceFlags);
180 
181   /**
182    * Creates and initializes an anonymous metadata decoder (one which isn't
183    * associated with an Image object). This decoder will only decode the image's
184    * header, extracting metadata like the size of the image. No actual image
185    * data will be decoded and no surfaces will be allocated.
186    *
187    * @param aType Which type of decoder to create - JPEG, PNG, etc.
188    * @param aSourceBuffer The SourceBuffer which the decoder will read its data
189    *                      from.
190    */
191   static already_AddRefed<Decoder> CreateAnonymousMetadataDecoder(
192       DecoderType aType, NotNull<SourceBuffer*> aSourceBuffer);
193 
194  private:
195   virtual ~DecoderFactory() = 0;
196 
197   /**
198    * An internal method which allocates a new decoder of the requested @aType.
199    */
200   static already_AddRefed<Decoder> GetDecoder(DecoderType aType,
201                                               RasterImage* aImage,
202                                               bool aIsRedecode);
203 };
204 
205 }  // namespace mozilla::image
206 
207 #endif  // mozilla_image_DecoderFactory_h
208