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 "SkCodec.h" 12 #include "SkColorSpace.h" 13 #include "SkColorSpaceXform.h" 14 #include "SkImageInfo.h" 15 #include "SkSwizzler.h" 16 #include "SkStream.h" 17 #include "SkTemplates.h" 18 19 class JpegDecoderMgr; 20 21 /* 22 * 23 * This class implements the decoding for jpeg images 24 * 25 */ 26 class SkJpegCodec : public SkCodec { 27 public: 28 static bool IsJpeg(const void*, size_t); 29 30 /* 31 * Assumes IsJpeg was called and returned true 32 * Creates a jpeg decoder 33 * Takes ownership of the stream 34 */ 35 static SkCodec* NewFromStream(SkStream*); 36 37 protected: 38 39 /* 40 * Recommend a set of destination dimensions given a requested scale 41 */ 42 SkISize onGetScaledDimensions(float desiredScale) const override; 43 44 /* 45 * Initiates the jpeg decode 46 */ 47 Result onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, const Options&, 48 SkPMColor*, int*, int*) override; 49 50 bool onQueryYUV8(SkYUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const override; 51 52 Result onGetYUV8Planes(const SkYUVSizeInfo& sizeInfo, void* planes[3]) override; 53 onGetEncodedFormat()54 SkEncodedImageFormat onGetEncodedFormat() const override { 55 return SkEncodedImageFormat::kJPEG; 56 } 57 58 bool onRewind() override; 59 60 bool onDimensionsSupported(const SkISize&) override; 61 62 private: 63 64 /* 65 * Allows SkRawCodec to communicate the color space from the exif data. 66 */ 67 static SkCodec* NewFromStream(SkStream*, sk_sp<SkColorSpace> defaultColorSpace); 68 69 /* 70 * Read enough of the stream to initialize the SkJpegCodec. 71 * Returns a bool representing success or failure. 72 * 73 * @param codecOut 74 * If this returns true, and codecOut was not nullptr, 75 * codecOut will be set to a new SkJpegCodec. 76 * 77 * @param decoderMgrOut 78 * If this returns true, and codecOut was nullptr, 79 * decoderMgrOut must be non-nullptr and decoderMgrOut will be set to a new 80 * JpegDecoderMgr pointer. 81 * 82 * @param stream 83 * Deleted on failure. 84 * codecOut will take ownership of it in the case where we created a codec. 85 * Ownership is unchanged when we set decoderMgrOut. 86 * 87 * @param defaultColorSpace 88 * If the jpeg does not have an embedded color space, the image data should 89 * be tagged with this color space. 90 */ 91 static bool ReadHeader(SkStream* stream, SkCodec** codecOut, 92 JpegDecoderMgr** decoderMgrOut, sk_sp<SkColorSpace> defaultColorSpace); 93 94 /* 95 * Creates an instance of the decoder 96 * Called only by NewFromStream 97 * 98 * @param info contains properties of the encoded data 99 * @param stream the encoded image data 100 * @param decoderMgr holds decompress struct, src manager, and error manager 101 * takes ownership 102 */ 103 SkJpegCodec(int width, int height, const SkEncodedInfo& info, SkStream* stream, 104 JpegDecoderMgr* decoderMgr, sk_sp<SkColorSpace> colorSpace, Origin origin); 105 106 /* 107 * Checks if the conversion between the input image and the requested output 108 * image has been implemented. 109 * 110 * Sets the output color space. 111 */ 112 bool setOutputColorSpace(const SkImageInfo& dst); 113 114 void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options, 115 bool needsCMYKToRGB); 116 void allocateStorage(const SkImageInfo& dstInfo); 117 int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int count, const Options&); 118 119 /* 120 * Scanline decoding. 121 */ 122 SkSampler* getSampler(bool createIfNecessary) override; 123 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& options, 124 SkPMColor ctable[], int* ctableCount) override; 125 int onGetScanlines(void* dst, int count, size_t rowBytes) override; 126 bool onSkipScanlines(int count) override; 127 128 std::unique_ptr<JpegDecoderMgr> fDecoderMgr; 129 130 // We will save the state of the decompress struct after reading the header. 131 // This allows us to safely call onGetScaledDimensions() at any time. 132 const int fReadyState; 133 134 135 SkAutoTMalloc<uint8_t> fStorage; 136 uint8_t* fSwizzleSrcRow; 137 uint32_t* fColorXformSrcRow; 138 139 // libjpeg-turbo provides some subsetting. In the case that libjpeg-turbo 140 // cannot take the exact the subset that we need, we will use the swizzler 141 // to further subset the output from libjpeg-turbo. 142 SkIRect fSwizzlerSubset; 143 144 std::unique_ptr<SkSwizzler> fSwizzler; 145 146 friend class SkRawCodec; 147 148 typedef SkCodec INHERITED; 149 }; 150 151 #endif 152