xref: /aosp_15_r20/external/skia/src/codec/SkJpegCodec.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2015 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SkJpegCodec_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker #define SkJpegCodec_DEFINED
10*c8dee2aaSAndroid Build Coastguard Worker 
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkCodec.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkEncodedImageFormat.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkEncodedOrigin.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSize.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkYUVAPixmaps.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/SkEncodedInfo.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTemplates.h"
20*c8dee2aaSAndroid Build Coastguard Worker 
21*c8dee2aaSAndroid Build Coastguard Worker #include <cstddef>
22*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
23*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
24*c8dee2aaSAndroid Build Coastguard Worker 
25*c8dee2aaSAndroid Build Coastguard Worker class JpegDecoderMgr;
26*c8dee2aaSAndroid Build Coastguard Worker class SkSampler;
27*c8dee2aaSAndroid Build Coastguard Worker class SkStream;
28*c8dee2aaSAndroid Build Coastguard Worker class SkSwizzler;
29*c8dee2aaSAndroid Build Coastguard Worker struct SkGainmapInfo;
30*c8dee2aaSAndroid Build Coastguard Worker struct SkImageInfo;
31*c8dee2aaSAndroid Build Coastguard Worker 
32*c8dee2aaSAndroid Build Coastguard Worker /*
33*c8dee2aaSAndroid Build Coastguard Worker  *
34*c8dee2aaSAndroid Build Coastguard Worker  * This class implements the decoding for jpeg images
35*c8dee2aaSAndroid Build Coastguard Worker  *
36*c8dee2aaSAndroid Build Coastguard Worker  */
37*c8dee2aaSAndroid Build Coastguard Worker class SkJpegCodec : public SkCodec {
38*c8dee2aaSAndroid Build Coastguard Worker public:
39*c8dee2aaSAndroid Build Coastguard Worker     ~SkJpegCodec() override;
40*c8dee2aaSAndroid Build Coastguard Worker 
41*c8dee2aaSAndroid Build Coastguard Worker     static bool IsJpeg(const void*, size_t);
42*c8dee2aaSAndroid Build Coastguard Worker 
43*c8dee2aaSAndroid Build Coastguard Worker     /*
44*c8dee2aaSAndroid Build Coastguard Worker      * Assumes IsJpeg was called and returned true
45*c8dee2aaSAndroid Build Coastguard Worker      * Takes ownership of the stream
46*c8dee2aaSAndroid Build Coastguard Worker      */
47*c8dee2aaSAndroid Build Coastguard Worker     static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*);
48*c8dee2aaSAndroid Build Coastguard Worker 
49*c8dee2aaSAndroid Build Coastguard Worker protected:
50*c8dee2aaSAndroid Build Coastguard Worker 
51*c8dee2aaSAndroid Build Coastguard Worker     /*
52*c8dee2aaSAndroid Build Coastguard Worker      * Recommend a set of destination dimensions given a requested scale
53*c8dee2aaSAndroid Build Coastguard Worker      */
54*c8dee2aaSAndroid Build Coastguard Worker     SkISize onGetScaledDimensions(float desiredScale) const override;
55*c8dee2aaSAndroid Build Coastguard Worker 
56*c8dee2aaSAndroid Build Coastguard Worker     /*
57*c8dee2aaSAndroid Build Coastguard Worker      * Initiates the jpeg decode
58*c8dee2aaSAndroid Build Coastguard Worker      */
59*c8dee2aaSAndroid Build Coastguard Worker     Result onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, const Options&,
60*c8dee2aaSAndroid Build Coastguard Worker             int*) override;
61*c8dee2aaSAndroid Build Coastguard Worker 
62*c8dee2aaSAndroid Build Coastguard Worker     bool onQueryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes&,
63*c8dee2aaSAndroid Build Coastguard Worker                          SkYUVAPixmapInfo*) const override;
64*c8dee2aaSAndroid Build Coastguard Worker 
65*c8dee2aaSAndroid Build Coastguard Worker     Result onGetYUVAPlanes(const SkYUVAPixmaps& yuvaPixmaps) override;
66*c8dee2aaSAndroid Build Coastguard Worker 
onGetEncodedFormat()67*c8dee2aaSAndroid Build Coastguard Worker     SkEncodedImageFormat onGetEncodedFormat() const override {
68*c8dee2aaSAndroid Build Coastguard Worker         return SkEncodedImageFormat::kJPEG;
69*c8dee2aaSAndroid Build Coastguard Worker     }
70*c8dee2aaSAndroid Build Coastguard Worker 
71*c8dee2aaSAndroid Build Coastguard Worker     bool onRewind() override;
72*c8dee2aaSAndroid Build Coastguard Worker 
73*c8dee2aaSAndroid Build Coastguard Worker     bool onDimensionsSupported(const SkISize&) override;
74*c8dee2aaSAndroid Build Coastguard Worker 
75*c8dee2aaSAndroid Build Coastguard Worker     bool conversionSupported(const SkImageInfo&, bool, bool) override;
76*c8dee2aaSAndroid Build Coastguard Worker 
77*c8dee2aaSAndroid Build Coastguard Worker     bool onGetGainmapCodec(SkGainmapInfo* info, std::unique_ptr<SkCodec>* gainmapCodec) override;
78*c8dee2aaSAndroid Build Coastguard Worker     bool onGetGainmapInfo(SkGainmapInfo* info,
79*c8dee2aaSAndroid Build Coastguard Worker                           std::unique_ptr<SkStream>* gainmapImageStream) override;
80*c8dee2aaSAndroid Build Coastguard Worker 
81*c8dee2aaSAndroid Build Coastguard Worker private:
82*c8dee2aaSAndroid Build Coastguard Worker     /*
83*c8dee2aaSAndroid Build Coastguard Worker      * Allows SkRawCodec to communicate the color profile from the exif data.
84*c8dee2aaSAndroid Build Coastguard Worker      */
85*c8dee2aaSAndroid Build Coastguard Worker     static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*,
86*c8dee2aaSAndroid Build Coastguard Worker             std::unique_ptr<SkEncodedInfo::ICCProfile> defaultColorProfile);
87*c8dee2aaSAndroid Build Coastguard Worker 
88*c8dee2aaSAndroid Build Coastguard Worker     /*
89*c8dee2aaSAndroid Build Coastguard Worker      * Read enough of the stream to initialize the SkJpegCodec.
90*c8dee2aaSAndroid Build Coastguard Worker      * Returns a bool representing success or failure.
91*c8dee2aaSAndroid Build Coastguard Worker      *
92*c8dee2aaSAndroid Build Coastguard Worker      * @param codecOut
93*c8dee2aaSAndroid Build Coastguard Worker      * If this returns true, and codecOut was not nullptr,
94*c8dee2aaSAndroid Build Coastguard Worker      * codecOut will be set to a new SkJpegCodec.
95*c8dee2aaSAndroid Build Coastguard Worker      *
96*c8dee2aaSAndroid Build Coastguard Worker      * @param decoderMgrOut
97*c8dee2aaSAndroid Build Coastguard Worker      * If this returns true, and codecOut was nullptr,
98*c8dee2aaSAndroid Build Coastguard Worker      * decoderMgrOut must be non-nullptr and decoderMgrOut will be set to a new
99*c8dee2aaSAndroid Build Coastguard Worker      * JpegDecoderMgr pointer.
100*c8dee2aaSAndroid Build Coastguard Worker      *
101*c8dee2aaSAndroid Build Coastguard Worker      * @param stream
102*c8dee2aaSAndroid Build Coastguard Worker      * Deleted on failure.
103*c8dee2aaSAndroid Build Coastguard Worker      * codecOut will take ownership of it in the case where we created a codec.
104*c8dee2aaSAndroid Build Coastguard Worker      * Ownership is unchanged when we set decoderMgrOut.
105*c8dee2aaSAndroid Build Coastguard Worker      *
106*c8dee2aaSAndroid Build Coastguard Worker      * @param defaultColorProfile
107*c8dee2aaSAndroid Build Coastguard Worker      * If the jpeg does not have an embedded color profile, the image data should
108*c8dee2aaSAndroid Build Coastguard Worker      * be tagged with this color profile.
109*c8dee2aaSAndroid Build Coastguard Worker      */
110*c8dee2aaSAndroid Build Coastguard Worker     static Result ReadHeader(SkStream* stream, SkCodec** codecOut,
111*c8dee2aaSAndroid Build Coastguard Worker             JpegDecoderMgr** decoderMgrOut,
112*c8dee2aaSAndroid Build Coastguard Worker             std::unique_ptr<SkEncodedInfo::ICCProfile> defaultColorProfile);
113*c8dee2aaSAndroid Build Coastguard Worker 
114*c8dee2aaSAndroid Build Coastguard Worker     /*
115*c8dee2aaSAndroid Build Coastguard Worker      * Creates an instance of the decoder
116*c8dee2aaSAndroid Build Coastguard Worker      * Called only by NewFromStream
117*c8dee2aaSAndroid Build Coastguard Worker      *
118*c8dee2aaSAndroid Build Coastguard Worker      * @param info contains properties of the encoded data
119*c8dee2aaSAndroid Build Coastguard Worker      * @param stream the encoded image data
120*c8dee2aaSAndroid Build Coastguard Worker      * @param decoderMgr holds decompress struct, src manager, and error manager
121*c8dee2aaSAndroid Build Coastguard Worker      *                   takes ownership
122*c8dee2aaSAndroid Build Coastguard Worker      * @param origin indicates the image orientation as specified in Exif metadata.
123*c8dee2aaSAndroid Build Coastguard Worker      * @param xmpMetadata holds the XMP metadata included in the image, if any.
124*c8dee2aaSAndroid Build Coastguard Worker      */
125*c8dee2aaSAndroid Build Coastguard Worker     SkJpegCodec(SkEncodedInfo&& info,
126*c8dee2aaSAndroid Build Coastguard Worker                 std::unique_ptr<SkStream> stream,
127*c8dee2aaSAndroid Build Coastguard Worker                 JpegDecoderMgr* decoderMgr,
128*c8dee2aaSAndroid Build Coastguard Worker                 SkEncodedOrigin origin);
129*c8dee2aaSAndroid Build Coastguard Worker 
130*c8dee2aaSAndroid Build Coastguard Worker     void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options,
131*c8dee2aaSAndroid Build Coastguard Worker                             bool needsCMYKToRGB);
132*c8dee2aaSAndroid Build Coastguard Worker     [[nodiscard]] bool allocateStorage(const SkImageInfo& dstInfo);
133*c8dee2aaSAndroid Build Coastguard Worker     int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int count, const Options&);
134*c8dee2aaSAndroid Build Coastguard Worker 
135*c8dee2aaSAndroid Build Coastguard Worker     /*
136*c8dee2aaSAndroid Build Coastguard Worker      * Scanline decoding.
137*c8dee2aaSAndroid Build Coastguard Worker      */
138*c8dee2aaSAndroid Build Coastguard Worker     SkSampler* getSampler(bool createIfNecessary) override;
139*c8dee2aaSAndroid Build Coastguard Worker     Result onStartScanlineDecode(const SkImageInfo& dstInfo,
140*c8dee2aaSAndroid Build Coastguard Worker             const Options& options) override;
141*c8dee2aaSAndroid Build Coastguard Worker     int onGetScanlines(void* dst, int count, size_t rowBytes) override;
142*c8dee2aaSAndroid Build Coastguard Worker     bool onSkipScanlines(int count) override;
143*c8dee2aaSAndroid Build Coastguard Worker 
144*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<JpegDecoderMgr>    fDecoderMgr;
145*c8dee2aaSAndroid Build Coastguard Worker 
146*c8dee2aaSAndroid Build Coastguard Worker     // We will save the state of the decompress struct after reading the header.
147*c8dee2aaSAndroid Build Coastguard Worker     // This allows us to safely call onGetScaledDimensions() at any time.
148*c8dee2aaSAndroid Build Coastguard Worker     const int                          fReadyState;
149*c8dee2aaSAndroid Build Coastguard Worker 
150*c8dee2aaSAndroid Build Coastguard Worker 
151*c8dee2aaSAndroid Build Coastguard Worker     skia_private::AutoTMalloc<uint8_t>             fStorage;
152*c8dee2aaSAndroid Build Coastguard Worker     uint8_t* fSwizzleSrcRow = nullptr;
153*c8dee2aaSAndroid Build Coastguard Worker     uint32_t* fColorXformSrcRow = nullptr;
154*c8dee2aaSAndroid Build Coastguard Worker 
155*c8dee2aaSAndroid Build Coastguard Worker     // libjpeg-turbo provides some subsetting.  In the case that libjpeg-turbo
156*c8dee2aaSAndroid Build Coastguard Worker     // cannot take the exact the subset that we need, we will use the swizzler
157*c8dee2aaSAndroid Build Coastguard Worker     // to further subset the output from libjpeg-turbo.
158*c8dee2aaSAndroid Build Coastguard Worker     SkIRect fSwizzlerSubset = SkIRect::MakeEmpty();
159*c8dee2aaSAndroid Build Coastguard Worker 
160*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<SkSwizzler>        fSwizzler;
161*c8dee2aaSAndroid Build Coastguard Worker 
162*c8dee2aaSAndroid Build Coastguard Worker     friend class SkRawCodec;
163*c8dee2aaSAndroid Build Coastguard Worker 
164*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = SkCodec;
165*c8dee2aaSAndroid Build Coastguard Worker };
166*c8dee2aaSAndroid Build Coastguard Worker 
167*c8dee2aaSAndroid Build Coastguard Worker #endif
168