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_ImageOps_h
8 #define mozilla_image_ImageOps_h
9 
10 #include "nsCOMPtr.h"
11 #include "nsRect.h"
12 #include "ImageMetadata.h"
13 
14 class gfxDrawable;
15 class imgIContainer;
16 class nsIInputStream;
17 
18 namespace mozilla {
19 
20 namespace gfx {
21 class SourceSurface;
22 }
23 
24 namespace image {
25 
26 class Image;
27 struct Orientation;
28 class SourceBuffer;
29 
30 class ImageOps {
31  public:
32   class ImageBuffer {
33    public:
34     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageOps::ImageBuffer);
35 
36    protected:
37     friend class ImageOps;
38 
39     ImageBuffer() = default;
40     virtual ~ImageBuffer() = default;
41 
42     virtual already_AddRefed<SourceBuffer> GetSourceBuffer() const = 0;
43   };
44 
45   /**
46    * Creates a version of an existing image which does not animate and is frozen
47    * at the first frame.
48    *
49    * @param aImage         The existing image.
50    */
51   static already_AddRefed<Image> Freeze(Image* aImage);
52   static already_AddRefed<imgIContainer> Freeze(imgIContainer* aImage);
53 
54   /**
55    * Creates a clipped version of an existing image. Animation is unaffected.
56    *
57    * @param aImage           The existing image.
58    * @param aClip            The rectangle to clip the image against.
59    * @param aSVGViewportSize The specific viewort size of aImage. Unless aImage
60    *                         is a vector image without intrinsic size, this
61    *                         argument should be pass as Nothing().
62    */
63   static already_AddRefed<Image> Clip(
64       Image* aImage, nsIntRect aClip,
65       const Maybe<nsSize>& aSVGViewportSize = Nothing());
66   static already_AddRefed<imgIContainer> Clip(
67       imgIContainer* aImage, nsIntRect aClip,
68       const Maybe<nsSize>& aSVGViewportSize = Nothing());
69 
70   /**
71    * Creates a version of an existing image which is rotated and/or flipped to
72    * the specified orientation.
73    *
74    * @param aImage         The existing image.
75    * @param aOrientation   The desired orientation.
76    */
77   static already_AddRefed<Image> Orient(Image* aImage,
78                                         Orientation aOrientation);
79   static already_AddRefed<imgIContainer> Orient(imgIContainer* aImage,
80                                                 Orientation aOrientation);
81 
82   /**
83    * Creates a version of an existing image which undoes any rotation and/or
84    * flipping that it has automatically handled.
85    *
86    * This only undoes the effect of a RasterImage's automatic orientation
87    * handling.
88    */
89   static already_AddRefed<imgIContainer> Unorient(imgIContainer* aImage);
90 
91   /**
92    * Creates an image from a gfxDrawable.
93    *
94    * @param aDrawable      The gfxDrawable.
95    */
96   static already_AddRefed<imgIContainer> CreateFromDrawable(
97       gfxDrawable* aDrawable);
98 
99   /**
100    * Create a buffer to be used with DecodeMetadata and DecodeToSurface. Reusing
101    * an ImageBuffer representing the given input stream is more efficient if one
102    * has multiple Decode* calls to make on that stream.
103    *
104    * @param aInputStream An input stream containing an encoded image. The
105    * ownership is taken.
106    * @return An image buffer derived from the input stream.
107    */
108   static already_AddRefed<ImageBuffer> CreateImageBuffer(
109       already_AddRefed<nsIInputStream> aInputStream);
110 
111   /**
112    * Decodes an image's metadata from an nsIInputStream into the given
113    * structure. This function may be called off-main-thread.
114    *
115    * @param aInputStream An input stream containing an encoded image. Ownership
116    * is taken.
117    * @param aMimeType The MIME type of the image.
118    * @param aMetadata Where the image metadata is stored upon success.
119    * @return The status of the operation.
120    */
121   static nsresult DecodeMetadata(already_AddRefed<nsIInputStream> aInputStream,
122                                  const nsACString& aMimeType,
123                                  ImageMetadata& aMetadata);
124 
125   /**
126    * Same as above but takes an ImageBuffer instead of nsIInputStream.
127    */
128   static nsresult DecodeMetadata(ImageBuffer* aBuffer,
129                                  const nsACString& aMimeType,
130                                  ImageMetadata& aMetadata);
131 
132   /**
133    * Decodes an image from an nsIInputStream directly into a SourceSurface,
134    * without ever creating an Image or imgIContainer (which are mostly
135    * main-thread-only). That means that this function may be called
136    * off-main-thread.
137    *
138    * @param aInputStream An input stream containing an encoded image. The
139    * ownership is taken.
140    * @param aMimeType The MIME type of the image.
141    * @param aFlags Flags of the imgIContainer::FLAG_DECODE_* variety.
142    * @return A SourceSurface containing the first frame of the image at its
143    *         intrinsic size, or nullptr if the image cannot be decoded.
144    */
145   static already_AddRefed<gfx::SourceSurface> DecodeToSurface(
146       already_AddRefed<nsIInputStream> aInputStream,
147       const nsACString& aMimeType, uint32_t aFlags,
148       const Maybe<gfx::IntSize>& aSize = Nothing());
149 
150   /**
151    * Same as above but takes an ImageBuffer instead of nsIInputStream.
152    */
153   static already_AddRefed<gfx::SourceSurface> DecodeToSurface(
154       ImageBuffer* aBuffer, const nsACString& aMimeType, uint32_t aFlags,
155       const Maybe<gfx::IntSize>& aSize = Nothing());
156 
157  private:
158   class ImageBufferImpl;
159 
160   // This is a static utility class, so disallow instantiation.
161   virtual ~ImageOps() = 0;
162 };
163 
164 }  // namespace image
165 }  // namespace mozilla
166 
167 #endif  // mozilla_image_ImageOps_h
168