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/core/SkImageInfo.h" |
13 | #include "include/core/SkStream.h" |
14 | #include "include/private/SkTemplates.h" |
15 | #include "src/codec/SkSwizzler.h" |
16 | |
17 | class JpegDecoderMgr; |
18 | |
19 | /* |
20 | * |
21 | * This class implements the decoding for jpeg images |
22 | * |
23 | */ |
24 | class SkJpegCodec : public SkCodec { |
25 | public: |
26 | static bool IsJpeg(const void*, size_t); |
27 | |
28 | /* |
29 | * Assumes IsJpeg was called and returned true |
30 | * Takes ownership of the stream |
31 | */ |
32 | static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*); |
33 | |
34 | protected: |
35 | |
36 | /* |
37 | * Recommend a set of destination dimensions given a requested scale |
38 | */ |
39 | SkISize onGetScaledDimensions(float desiredScale) const override; |
40 | |
41 | /* |
42 | * Initiates the jpeg decode |
43 | */ |
44 | Result onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, const Options&, |
45 | int*) override; |
46 | |
47 | bool onQueryYUV8(SkYUVASizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const override; |
48 | |
49 | Result onGetYUV8Planes(const SkYUVASizeInfo& sizeInfo, |
50 | void* planes[SkYUVASizeInfo::kMaxCount]) override; |
51 | |
52 | SkEncodedImageFormat onGetEncodedFormat() const override { |
53 | return SkEncodedImageFormat::kJPEG; |
54 | } |
55 | |
56 | bool onRewind() override; |
57 | |
58 | bool onDimensionsSupported(const SkISize&) override; |
59 | |
60 | bool conversionSupported(const SkImageInfo&, bool, bool) override; |
61 | |
62 | private: |
63 | /* |
64 | * Allows SkRawCodec to communicate the color profile from the exif data. |
65 | */ |
66 | static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*, |
67 | std::unique_ptr<SkEncodedInfo::ICCProfile> defaultColorProfile); |
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 defaultColorProfile |
88 | * If the jpeg does not have an embedded color profile, the image data should |
89 | * be tagged with this color profile. |
90 | */ |
91 | static Result (SkStream* stream, SkCodec** codecOut, |
92 | JpegDecoderMgr** decoderMgrOut, |
93 | std::unique_ptr<SkEncodedInfo::ICCProfile> defaultColorProfile); |
94 | |
95 | /* |
96 | * Creates an instance of the decoder |
97 | * Called only by NewFromStream |
98 | * |
99 | * @param info contains properties of the encoded data |
100 | * @param stream the encoded image data |
101 | * @param decoderMgr holds decompress struct, src manager, and error manager |
102 | * takes ownership |
103 | */ |
104 | SkJpegCodec(SkEncodedInfo&& info, std::unique_ptr<SkStream> stream, |
105 | JpegDecoderMgr* decoderMgr, SkEncodedOrigin origin); |
106 | |
107 | void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options, |
108 | bool needsCMYKToRGB); |
109 | bool SK_WARN_UNUSED_RESULT allocateStorage(const SkImageInfo& dstInfo); |
110 | int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int count, const Options&); |
111 | |
112 | /* |
113 | * Scanline decoding. |
114 | */ |
115 | SkSampler* getSampler(bool createIfNecessary) override; |
116 | Result onStartScanlineDecode(const SkImageInfo& dstInfo, |
117 | const Options& options) override; |
118 | int onGetScanlines(void* dst, int count, size_t rowBytes) override; |
119 | bool onSkipScanlines(int count) override; |
120 | |
121 | std::unique_ptr<JpegDecoderMgr> fDecoderMgr; |
122 | |
123 | // We will save the state of the decompress struct after reading the header. |
124 | // This allows us to safely call onGetScaledDimensions() at any time. |
125 | const int fReadyState; |
126 | |
127 | |
128 | SkAutoTMalloc<uint8_t> fStorage; |
129 | uint8_t* fSwizzleSrcRow; |
130 | uint32_t* fColorXformSrcRow; |
131 | |
132 | // libjpeg-turbo provides some subsetting. In the case that libjpeg-turbo |
133 | // cannot take the exact the subset that we need, we will use the swizzler |
134 | // to further subset the output from libjpeg-turbo. |
135 | SkIRect fSwizzlerSubset; |
136 | |
137 | std::unique_ptr<SkSwizzler> fSwizzler; |
138 | |
139 | friend class SkRawCodec; |
140 | |
141 | typedef SkCodec INHERITED; |
142 | }; |
143 | |
144 | #endif |
145 | |