1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkJpegCodec_DEFINED 9 #define SkJpegCodec_DEFINED 10 11 #include "include/codec/SkCodec.h" 12 #include "include/codec/SkEncodedImageFormat.h" 13 #include "include/codec/SkEncodedOrigin.h" 14 #include "include/core/SkRect.h" 15 #include "include/core/SkSize.h" 16 #include "include/core/SkTypes.h" 17 #include "include/core/SkYUVAPixmaps.h" 18 #include "include/private/SkEncodedInfo.h" 19 #include "include/private/base/SkTemplates.h" 20 21 #include <cstddef> 22 #include <cstdint> 23 #include <memory> 24 25 class JpegDecoderMgr; 26 class SkSampler; 27 class SkStream; 28 class SkSwizzler; 29 struct SkGainmapInfo; 30 struct SkImageInfo; 31 32 /* 33 * 34 * This class implements the decoding for jpeg images 35 * 36 */ 37 class SkJpegCodec : public SkCodec { 38 public: 39 ~SkJpegCodec() override; 40 41 static bool IsJpeg(const void*, size_t); 42 43 /* 44 * Assumes IsJpeg was called and returned true 45 * Takes ownership of the stream 46 */ 47 static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*); 48 49 protected: 50 51 /* 52 * Recommend a set of destination dimensions given a requested scale 53 */ 54 SkISize onGetScaledDimensions(float desiredScale) const override; 55 56 /* 57 * Initiates the jpeg decode 58 */ 59 Result onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, const Options&, 60 int*) override; 61 62 bool onQueryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes&, 63 SkYUVAPixmapInfo*) const override; 64 65 Result onGetYUVAPlanes(const SkYUVAPixmaps& yuvaPixmaps) override; 66 onGetEncodedFormat()67 SkEncodedImageFormat onGetEncodedFormat() const override { 68 return SkEncodedImageFormat::kJPEG; 69 } 70 71 bool onRewind() override; 72 73 bool onDimensionsSupported(const SkISize&) override; 74 75 bool conversionSupported(const SkImageInfo&, bool, bool) override; 76 77 bool onGetGainmapCodec(SkGainmapInfo* info, std::unique_ptr<SkCodec>* gainmapCodec) override; 78 bool onGetGainmapInfo(SkGainmapInfo* info, 79 std::unique_ptr<SkStream>* gainmapImageStream) override; 80 81 private: 82 /* 83 * Allows SkRawCodec to communicate the color profile from the exif data. 84 */ 85 static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*, 86 std::unique_ptr<SkEncodedInfo::ICCProfile> defaultColorProfile); 87 88 /* 89 * Read enough of the stream to initialize the SkJpegCodec. 90 * Returns a bool representing success or failure. 91 * 92 * @param codecOut 93 * If this returns true, and codecOut was not nullptr, 94 * codecOut will be set to a new SkJpegCodec. 95 * 96 * @param decoderMgrOut 97 * If this returns true, and codecOut was nullptr, 98 * decoderMgrOut must be non-nullptr and decoderMgrOut will be set to a new 99 * JpegDecoderMgr pointer. 100 * 101 * @param stream 102 * Deleted on failure. 103 * codecOut will take ownership of it in the case where we created a codec. 104 * Ownership is unchanged when we set decoderMgrOut. 105 * 106 * @param defaultColorProfile 107 * If the jpeg does not have an embedded color profile, the image data should 108 * be tagged with this color profile. 109 */ 110 static Result ReadHeader(SkStream* stream, SkCodec** codecOut, 111 JpegDecoderMgr** decoderMgrOut, 112 std::unique_ptr<SkEncodedInfo::ICCProfile> defaultColorProfile); 113 114 /* 115 * Creates an instance of the decoder 116 * Called only by NewFromStream 117 * 118 * @param info contains properties of the encoded data 119 * @param stream the encoded image data 120 * @param decoderMgr holds decompress struct, src manager, and error manager 121 * takes ownership 122 * @param origin indicates the image orientation as specified in Exif metadata. 123 * @param xmpMetadata holds the XMP metadata included in the image, if any. 124 */ 125 SkJpegCodec(SkEncodedInfo&& info, 126 std::unique_ptr<SkStream> stream, 127 JpegDecoderMgr* decoderMgr, 128 SkEncodedOrigin origin); 129 130 void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options, 131 bool needsCMYKToRGB); 132 [[nodiscard]] bool allocateStorage(const SkImageInfo& dstInfo); 133 int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int count, const Options&); 134 135 /* 136 * Scanline decoding. 137 */ 138 SkSampler* getSampler(bool createIfNecessary) override; 139 Result onStartScanlineDecode(const SkImageInfo& dstInfo, 140 const Options& options) override; 141 int onGetScanlines(void* dst, int count, size_t rowBytes) override; 142 bool onSkipScanlines(int count) override; 143 144 std::unique_ptr<JpegDecoderMgr> fDecoderMgr; 145 146 // We will save the state of the decompress struct after reading the header. 147 // This allows us to safely call onGetScaledDimensions() at any time. 148 const int fReadyState; 149 150 151 skia_private::AutoTMalloc<uint8_t> fStorage; 152 uint8_t* fSwizzleSrcRow = nullptr; 153 uint32_t* fColorXformSrcRow = nullptr; 154 155 // libjpeg-turbo provides some subsetting. In the case that libjpeg-turbo 156 // cannot take the exact the subset that we need, we will use the swizzler 157 // to further subset the output from libjpeg-turbo. 158 SkIRect fSwizzlerSubset = SkIRect::MakeEmpty(); 159 160 std::unique_ptr<SkSwizzler> fSwizzler; 161 162 friend class SkRawCodec; 163 164 using INHERITED = SkCodec; 165 }; 166 167 #endif 168