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_ImageMetadata_h
8 #define mozilla_image_ImageMetadata_h
9 
10 #include <stdint.h>
11 #include <utility>
12 #include "FrameTimeout.h"
13 #include "Orientation.h"
14 #include "mozilla/Maybe.h"
15 #include "mozilla/gfx/Point.h"
16 #include "mozilla/gfx/Rect.h"
17 #include "mozilla/image/Resolution.h"
18 #include "nsSize.h"
19 #include "nsTArray.h"
20 
21 namespace mozilla::image {
22 
23 // The metadata about an image that decoders accumulate as they decode.
24 class ImageMetadata {
25  public:
26   ImageMetadata() = default;
27 
SetHotspot(uint16_t aHotspotX,uint16_t aHotspotY)28   void SetHotspot(uint16_t aHotspotX, uint16_t aHotspotY) {
29     mHotspot = Some(gfx::IntPoint(aHotspotX, aHotspotY));
30   }
GetHotspot()31   gfx::IntPoint GetHotspot() const { return *mHotspot; }
HasHotspot()32   bool HasHotspot() const { return mHotspot.isSome(); }
33 
SetLoopCount(int32_t loopcount)34   void SetLoopCount(int32_t loopcount) { mLoopCount = loopcount; }
GetLoopCount()35   int32_t GetLoopCount() const { return mLoopCount; }
36 
SetLoopLength(FrameTimeout aLength)37   void SetLoopLength(FrameTimeout aLength) { mLoopLength = Some(aLength); }
GetLoopLength()38   FrameTimeout GetLoopLength() const { return *mLoopLength; }
HasLoopLength()39   bool HasLoopLength() const { return mLoopLength.isSome(); }
40 
SetFirstFrameTimeout(FrameTimeout aTimeout)41   void SetFirstFrameTimeout(FrameTimeout aTimeout) {
42     mFirstFrameTimeout = aTimeout;
43   }
GetFirstFrameTimeout()44   FrameTimeout GetFirstFrameTimeout() const { return mFirstFrameTimeout; }
45 
SetFirstFrameRefreshArea(const gfx::IntRect & aRefreshArea)46   void SetFirstFrameRefreshArea(const gfx::IntRect& aRefreshArea) {
47     mFirstFrameRefreshArea = Some(aRefreshArea);
48   }
GetFirstFrameRefreshArea()49   gfx::IntRect GetFirstFrameRefreshArea() const {
50     return *mFirstFrameRefreshArea;
51   }
HasFirstFrameRefreshArea()52   bool HasFirstFrameRefreshArea() const {
53     return mFirstFrameRefreshArea.isSome();
54   }
55 
SetSize(int32_t aWidth,int32_t aHeight,Orientation aOrientation,Resolution aResolution)56   void SetSize(int32_t aWidth, int32_t aHeight, Orientation aOrientation,
57                Resolution aResolution) {
58     if (!HasSize()) {
59       mSize.emplace(
60           aOrientation.ToOriented(UnorientedIntSize(aWidth, aHeight)));
61       mOrientation.emplace(aOrientation);
62       mResolution = aResolution;
63     }
64   }
GetSize()65   OrientedIntSize GetSize() const { return *mSize; }
HasSize()66   bool HasSize() const { return mSize.isSome(); }
67 
AddNativeSize(const OrientedIntSize & aSize)68   void AddNativeSize(const OrientedIntSize& aSize) {
69     mNativeSizes.AppendElement(aSize);
70   }
71 
GetResolution()72   Resolution GetResolution() const { return mResolution; }
73 
GetNativeSizes()74   const nsTArray<OrientedIntSize>& GetNativeSizes() const {
75     return mNativeSizes;
76   }
77 
GetOrientation()78   Orientation GetOrientation() const { return *mOrientation; }
HasOrientation()79   bool HasOrientation() const { return mOrientation.isSome(); }
80 
SetHasAnimation()81   void SetHasAnimation() { mHasAnimation = true; }
HasAnimation()82   bool HasAnimation() const { return mHasAnimation; }
83 
84  private:
85   /// The hotspot found on cursors, if present.
86   Maybe<gfx::IntPoint> mHotspot;
87 
88   /// The loop count for animated images, or -1 for infinite loop.
89   int32_t mLoopCount = -1;
90 
91   /// The resolution of the image in dppx.
92   Resolution mResolution;
93 
94   // The total length of a single loop through an animated image.
95   Maybe<FrameTimeout> mLoopLength;
96 
97   /// The timeout of an animated image's first frame.
98   FrameTimeout mFirstFrameTimeout = FrameTimeout::Forever();
99 
100   // The area of the image that needs to be invalidated when the animation
101   // loops.
102   Maybe<gfx::IntRect> mFirstFrameRefreshArea;
103 
104   Maybe<OrientedIntSize> mSize;
105   Maybe<Orientation> mOrientation;
106 
107   // Sizes the image can natively decode to.
108   CopyableTArray<OrientedIntSize> mNativeSizes;
109 
110   bool mHasAnimation = false;
111 };
112 
113 }  // namespace mozilla::image
114 
115 #endif  // mozilla_image_ImageMetadata_h
116