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