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 <SkImageInfo.h> 21 #include <SkPngChunkReader.h> 22 #include <SkRect.h> 23 #include <SkSize.h> 24 #include <cutils/compiler.h> 25 26 #include <optional> 27 28 namespace android { 29 30 class Bitmap; 31 32 class ANDROID_API ImageDecoder final { 33 public: 34 std::unique_ptr<SkAndroidCodec> mCodec; 35 sk_sp<SkPngChunkReader> mPeeker; 36 37 ImageDecoder(std::unique_ptr<SkAndroidCodec> codec, sk_sp<SkPngChunkReader> peeker = nullptr, 38 SkCodec::ZeroInitialized zeroInit = SkCodec::kNo_ZeroInitialized); 39 ~ImageDecoder(); 40 41 SkISize getSampledDimensions(int sampleSize) const; 42 bool setTargetSize(int width, int height); 43 bool setCropRect(const SkIRect*); 44 45 bool setOutColorType(SkColorType outColorType); 46 47 bool setUnpremultipliedRequired(bool unpremultipliedRequired); 48 49 sk_sp<SkColorSpace> getDefaultColorSpace() const; 50 void setOutColorSpace(sk_sp<SkColorSpace> cs); 51 52 // The size is the final size after scaling, adjusting for the origin, and 53 // cropping. 54 SkImageInfo getOutputInfo() const; 55 56 int width() const; 57 int height() const; 58 59 // True if the current frame is opaque. 60 bool opaque() const; 61 62 bool gray() const; 63 64 SkCodec::Result decode(void* pixels, size_t rowBytes); 65 66 // Return true if the decoder has advanced beyond all frames. 67 bool finished() const; 68 69 bool advanceFrame(); 70 bool rewind(); 71 72 bool isAnimated(); 73 int currentFrame() const; 74 75 SkCodec::FrameInfo getCurrentFrameInfo(); 76 77 // Set whether the ImageDecoder should handle RestorePrevious frames. 78 void setHandleRestorePrevious(bool handle); 79 80 private: 81 // State machine for keeping track of how to handle RestorePrevious (RP) 82 // frames in decode(). 83 enum class RestoreState { 84 // Neither this frame nor the prior is RP, so there is no need to cache 85 // or restore. 86 kDoNothing, 87 88 // This is the first in a sequence of one or more RP frames. decode() 89 // needs to cache the provided pixels. 90 kFirstRPFrame, 91 92 // This is the second (or later) in a sequence of multiple RP frames. 93 // decode() needs to restore the cached frame that preceded the first RP 94 // frame in the sequence. 95 kRPFrame, 96 97 // This is the first non-RP frame after a sequence of one or more RP 98 // frames. decode() still needs to restore the cached frame. Separate 99 // from kRPFrame because if the following frame is RP the state will 100 // change to kFirstRPFrame. 101 kNeedsRestore, 102 }; 103 104 SkISize mTargetSize; 105 SkISize mDecodeSize; 106 SkColorType mOutColorType; 107 bool mUnpremultipliedRequired; 108 sk_sp<SkColorSpace> mOutColorSpace; 109 SkAndroidCodec::AndroidOptions mOptions; 110 bool mCurrentFrameIsIndependent; 111 bool mCurrentFrameIsOpaque; 112 bool mHandleRestorePrevious; 113 RestoreState mRestoreState; 114 sk_sp<Bitmap> mRestoreFrame; 115 std::optional<SkIRect> mCropRect; 116 117 ImageDecoder(const ImageDecoder&) = delete; 118 ImageDecoder& operator=(const ImageDecoder&) = delete; 119 120 SkAlphaType getOutAlphaType() const; 121 sk_sp<SkColorSpace> getOutputColorSpace() const; 122 bool swapWidthHeight() const; 123 // Store/restore a frame if necessary. Returns false on error. 124 bool handleRestorePrevious(const SkImageInfo&, void* pixels, size_t rowBytes); 125 }; 126 127 } // namespace android 128