xref: /aosp_15_r20/external/skia/src/codec/SkJpegCodec.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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