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/SkEncodedOrigin.h" 13 #include "include/core/SkEncodedImageFormat.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 onGetGainmapInfo(SkGainmapInfo* info, 78 std::unique_ptr<SkStream>* gainmapImageStream) override; 79 80 private: 81 /* 82 * Allows SkRawCodec to communicate the color profile from the exif data. 83 */ 84 static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*, 85 std::unique_ptr<SkEncodedInfo::ICCProfile> defaultColorProfile); 86 87 /* 88 * Read enough of the stream to initialize the SkJpegCodec. 89 * Returns a bool representing success or failure. 90 * 91 * @param codecOut 92 * If this returns true, and codecOut was not nullptr, 93 * codecOut will be set to a new SkJpegCodec. 94 * 95 * @param decoderMgrOut 96 * If this returns true, and codecOut was nullptr, 97 * decoderMgrOut must be non-nullptr and decoderMgrOut will be set to a new 98 * JpegDecoderMgr pointer. 99 * 100 * @param stream 101 * Deleted on failure. 102 * codecOut will take ownership of it in the case where we created a codec. 103 * Ownership is unchanged when we set decoderMgrOut. 104 * 105 * @param defaultColorProfile 106 * If the jpeg does not have an embedded color profile, the image data should 107 * be tagged with this color profile. 108 */ 109 static Result ReadHeader(SkStream* stream, SkCodec** codecOut, 110 JpegDecoderMgr** decoderMgrOut, 111 std::unique_ptr<SkEncodedInfo::ICCProfile> defaultColorProfile); 112 113 /* 114 * Creates an instance of the decoder 115 * Called only by NewFromStream 116 * 117 * @param info contains properties of the encoded data 118 * @param stream the encoded image data 119 * @param decoderMgr holds decompress struct, src manager, and error manager 120 * takes ownership 121 * @param origin indicates the image orientation as specified in Exif metadata. 122 * @param xmpMetadata holds the XMP metadata included in the image, if any. 123 */ 124 SkJpegCodec(SkEncodedInfo&& info, 125 std::unique_ptr<SkStream> stream, 126 JpegDecoderMgr* decoderMgr, 127 SkEncodedOrigin origin); 128 129 void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options, 130 bool needsCMYKToRGB); 131 bool SK_WARN_UNUSED_RESULT allocateStorage(const SkImageInfo& dstInfo); 132 int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int count, const Options&); 133 134 /* 135 * Scanline decoding. 136 */ 137 SkSampler* getSampler(bool createIfNecessary) override; 138 Result onStartScanlineDecode(const SkImageInfo& dstInfo, 139 const Options& options) override; 140 int onGetScanlines(void* dst, int count, size_t rowBytes) override; 141 bool onSkipScanlines(int count) override; 142 143 std::unique_ptr<JpegDecoderMgr> fDecoderMgr; 144 145 // We will save the state of the decompress struct after reading the header. 146 // This allows us to safely call onGetScaledDimensions() at any time. 147 const int fReadyState; 148 149 150 skia_private::AutoTMalloc<uint8_t> fStorage; 151 uint8_t* fSwizzleSrcRow = nullptr; 152 uint32_t* fColorXformSrcRow = nullptr; 153 154 // libjpeg-turbo provides some subsetting. In the case that libjpeg-turbo 155 // cannot take the exact the subset that we need, we will use the swizzler 156 // to further subset the output from libjpeg-turbo. 157 SkIRect fSwizzlerSubset = SkIRect::MakeEmpty(); 158 159 std::unique_ptr<SkSwizzler> fSwizzler; 160 161 friend class SkRawCodec; 162 163 using INHERITED = SkCodec; 164 }; 165 166 #endif 167