• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
decoderMgr()43     JpegDecoderMgr* decoderMgr() {return fDecoderMgr.get();}
44 
45     /*
46      * Assumes IsJpeg was called and returned true
47      * Takes ownership of the stream
48      */
49     static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*);
50 
51 protected:
52 
53     /*
54      * Recommend a set of destination dimensions given a requested scale
55      */
56     SkISize onGetScaledDimensions(float desiredScale) const override;
57 
58     /*
59      * Initiates the jpeg decode
60      */
61     Result onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, const Options&,
62             int*) override;
63 
64     bool onQueryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes&,
65                          SkYUVAPixmapInfo*) const override;
66 
67     Result onGetYUVAPlanes(const SkYUVAPixmaps& yuvaPixmaps) override;
68 
onGetEncodedFormat()69     SkEncodedImageFormat onGetEncodedFormat() const override {
70         return SkEncodedImageFormat::kJPEG;
71     }
72 
73     bool onRewind() override;
74 
75     bool onDimensionsSupported(const SkISize&) override;
76 
77     bool conversionSupported(const SkImageInfo&, bool, bool) override;
78 
79     bool onGetGainmapCodec(SkGainmapInfo* info, std::unique_ptr<SkCodec>* gainmapCodec) override;
80     bool onGetGainmapInfo(SkGainmapInfo* info,
81                           std::unique_ptr<SkStream>* gainmapImageStream) override;
82 
83 private:
84     /*
85      * Allows SkRawCodec to communicate the color profile from the exif data.
86      */
87     static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*,
88             std::unique_ptr<SkEncodedInfo::ICCProfile> defaultColorProfile);
89 
90     /*
91      * Read enough of the stream to initialize the SkJpegCodec.
92      * Returns a bool representing success or failure.
93      *
94      * @param codecOut
95      * If this returns true, and codecOut was not nullptr,
96      * codecOut will be set to a new SkJpegCodec.
97      *
98      * @param decoderMgrOut
99      * If this returns true, and codecOut was nullptr,
100      * decoderMgrOut must be non-nullptr and decoderMgrOut will be set to a new
101      * JpegDecoderMgr pointer.
102      *
103      * @param stream
104      * Deleted on failure.
105      * codecOut will take ownership of it in the case where we created a codec.
106      * Ownership is unchanged when we set decoderMgrOut.
107      *
108      * @param defaultColorProfile
109      * If the jpeg does not have an embedded color profile, the image data should
110      * be tagged with this color profile.
111      */
112     static Result ReadHeader(SkStream* stream, SkCodec** codecOut,
113             JpegDecoderMgr** decoderMgrOut,
114             std::unique_ptr<SkEncodedInfo::ICCProfile> defaultColorProfile);
115 
116     /*
117      * Creates an instance of the decoder
118      * Called only by NewFromStream
119      *
120      * @param info contains properties of the encoded data
121      * @param stream the encoded image data
122      * @param decoderMgr holds decompress struct, src manager, and error manager
123      *                   takes ownership
124      * @param origin indicates the image orientation as specified in Exif metadata.
125      * @param xmpMetadata holds the XMP metadata included in the image, if any.
126      */
127     SkJpegCodec(SkEncodedInfo&& info,
128                 std::unique_ptr<SkStream> stream,
129                 JpegDecoderMgr* decoderMgr,
130                 SkEncodedOrigin origin);
131 
132     void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options,
133                             bool needsCMYKToRGB);
134     [[nodiscard]] bool allocateStorage(const SkImageInfo& dstInfo);
135     Result readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int count,
136                   const Options&, int* rowsDecoded);
137 
138     /*
139      * Scanline decoding.
140      */
141     SkSampler* getSampler(bool createIfNecessary) override;
142     Result onStartScanlineDecode(const SkImageInfo& dstInfo,
143             const Options& options) override;
144     int onGetScanlines(void* dst, int count, size_t rowBytes) override;
145     bool onSkipScanlines(int count) override;
146 
147     std::unique_ptr<JpegDecoderMgr>    fDecoderMgr;
148 
149     // We will save the state of the decompress struct after reading the header.
150     // This allows us to safely call onGetScaledDimensions() at any time.
151     const int                          fReadyState;
152 
153 
154     skia_private::AutoTMalloc<uint8_t>             fStorage;
155     uint8_t* fSwizzleSrcRow = nullptr;
156     uint32_t* fColorXformSrcRow = nullptr;
157 
158     // libjpeg-turbo provides some subsetting.  In the case that libjpeg-turbo
159     // cannot take the exact the subset that we need, we will use the swizzler
160     // to further subset the output from libjpeg-turbo.
161     SkIRect fSwizzlerSubset = SkIRect::MakeEmpty();
162 
163     std::unique_ptr<SkSwizzler>        fSwizzler;
164 
165     friend class SkRawCodec;
166 
167     using INHERITED = SkCodec;
168 };
169 
170 #endif
171