1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <SkAndroidCodec.h>
19 #include <SkCodec.h>
20 #include <SkColorSpace.h>
21 #include <SkImageInfo.h>
22 #include <SkPngChunkReader.h>
23 #include <SkRect.h>
24 #include <SkRefCnt.h>
25 #include <SkSize.h>
26 #include <cutils/compiler.h>
27 
28 #include <optional>
29 
30 namespace android {
31 
32 class Bitmap;
33 
34 class ANDROID_API ImageDecoder final {
35 public:
36     std::unique_ptr<SkAndroidCodec> mCodec;
37     sk_sp<SkPngChunkReader> mPeeker;
38 
39     ImageDecoder(std::unique_ptr<SkAndroidCodec> codec, sk_sp<SkPngChunkReader> peeker = nullptr,
40                  SkCodec::ZeroInitialized zeroInit = SkCodec::kNo_ZeroInitialized);
41     ~ImageDecoder();
42 
43     SkISize getSampledDimensions(int sampleSize) const;
44     bool setTargetSize(int width, int height);
45     bool setCropRect(const SkIRect*);
46 
47     bool setOutColorType(SkColorType outColorType);
48 
49     bool setUnpremultipliedRequired(bool unpremultipliedRequired);
50 
51     sk_sp<SkColorSpace> getDefaultColorSpace() const;
52     void setOutColorSpace(sk_sp<SkColorSpace> cs);
53 
54     // The size is the final size after scaling, adjusting for the origin, and
55     // cropping.
56     SkImageInfo getOutputInfo() const;
57 
58     int width() const;
59     int height() const;
60 
61     // True if the current frame is opaque.
62     bool opaque() const;
63 
64     bool gray() const;
65 
66     SkCodec::Result decode(void* pixels, size_t rowBytes);
67 
68     // Return true if the decoder has advanced beyond all frames.
69     bool finished() const;
70 
71     bool advanceFrame();
72     bool rewind();
73 
74     bool isAnimated();
75     int currentFrame() const;
76 
77     SkCodec::FrameInfo getCurrentFrameInfo();
78 
79     // Set whether the ImageDecoder should handle RestorePrevious frames.
80     void setHandleRestorePrevious(bool handle);
81 
82     SkCodec::Result extractGainmap(Bitmap* destination, bool isShared);
83 
84 private:
85     // State machine for keeping track of how to handle RestorePrevious (RP)
86     // frames in decode().
87     enum class RestoreState {
88         // Neither this frame nor the prior is RP, so there is no need to cache
89         // or restore.
90         kDoNothing,
91 
92         // This is the first in a sequence of one or more RP frames. decode()
93         // needs to cache the provided pixels.
94         kFirstRPFrame,
95 
96         // This is the second (or later) in a sequence of multiple RP frames.
97         // decode() needs to restore the cached frame that preceded the first RP
98         // frame in the sequence.
99         kRPFrame,
100 
101         // This is the first non-RP frame after a sequence of one or more RP
102         // frames. decode() still needs to restore the cached frame. Separate
103         // from kRPFrame because if the following frame is RP the state will
104         // change to kFirstRPFrame.
105         kNeedsRestore,
106     };
107 
108     SkISize mTargetSize;
109     SkISize mDecodeSize;
110     SkColorType mOutColorType;
111     bool mUnpremultipliedRequired;
112     sk_sp<SkColorSpace> mOutColorSpace;
113     SkAndroidCodec::AndroidOptions mOptions;
114     bool mCurrentFrameIsIndependent;
115     bool mCurrentFrameIsOpaque;
116     bool mHandleRestorePrevious;
117     RestoreState mRestoreState;
118     sk_sp<Bitmap> mRestoreFrame;
119     std::optional<SkIRect> mCropRect;
120     std::optional<SkEncodedOrigin> mOverrideOrigin;
121 
122     ImageDecoder(const ImageDecoder&) = delete;
123     ImageDecoder& operator=(const ImageDecoder&) = delete;
124 
125     SkAlphaType getOutAlphaType() const;
126     sk_sp<SkColorSpace> getOutputColorSpace() const;
127     bool swapWidthHeight() const;
128     // Store/restore a frame if necessary. Returns false on error.
129     bool handleRestorePrevious(const SkImageInfo&, void* pixels, size_t rowBytes);
130 
getOrigin()131     SkEncodedOrigin getOrigin() const {
132         return mOverrideOrigin.has_value() ? *mOverrideOrigin : mCodec->codec()->getOrigin();
133     }
134 };
135 
136 } // namespace android
137