xref: /aosp_15_r20/external/skia/src/encode/SkJpegEncoderImpl.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2017 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 SkJpegEncoderImpl_DEFINED
9 #define SkJpegEncoderImpl_DEFINED
10 
11 #include "include/codec/SkEncodedOrigin.h"
12 #include "include/core/SkData.h"
13 #include "include/core/SkRefCnt.h"
14 #include "include/core/SkYUVAPixmaps.h"
15 #include "include/encode/SkEncoder.h"
16 
17 #include <cstdint>
18 #include <memory>
19 #include <optional>
20 #include <utility>
21 #include <vector>
22 
23 class SkColorSpace;
24 class SkJpegEncoderMgr;
25 class SkPixmap;
26 class SkWStream;
27 
28 namespace SkJpegEncoder {
29 struct Options;
30 }  // namespace SkJpegEncoder
31 
32 // JPEG metadata is included in marker-based segments in the header of the image (the part before
33 // the first StartOfScan marker). These functions append these parameters to an SkJpegMarkerList.
34 namespace SkJpegMetadataEncoder {
35 
36 // Metadata segments that will be added to the encoded file using
37 struct Segment {
SegmentSegment38     Segment(uint8_t marker, sk_sp<SkData> parameters)
39             : fMarker(marker), fParameters(std::move(parameters)) {}
40     uint8_t fMarker = 0;
41     sk_sp<SkData> fParameters;
42 };
43 
44 using SegmentList = std::vector<Segment>;
45 
46 // Include an ICC profile in the image. If |colorSpace| is nullptr, then include no profile. If
47 // |options| specifies ICC profile data, then use that data, otherwise, generate a profile for
48 // |colorSpace|.
49 void AppendICC(SegmentList& segmentList,
50                const SkJpegEncoder::Options& options,
51                const SkColorSpace* colorSpace);
52 
53 // Include a standard (as opposed to extended) XMP metadata segment.
54 void AppendXMPStandard(SegmentList& segmentList, const SkData* xmpMetadata);
55 
56 // Include an origin as part of an Exif metadata segment.
57 void AppendOrigin(SegmentList& segmentList, SkEncodedOrigin origin);
58 
59 }  // namespace SkJpegMetadataEncoder
60 
61 class SkJpegEncoderImpl : public SkEncoder {
62 public:
63     // Make an encoder from RGB or YUV data. Encoding options are specified in |options|. Metadata
64     // markers are listed in |metadata|. The ICC profile and XMP metadata are read from |metadata|
65     // and not from |options|.
66     static std::unique_ptr<SkEncoder> MakeRGB(SkWStream* dst,
67                                               const SkPixmap& src,
68                                               const SkJpegEncoder::Options& options,
69                                               const SkJpegMetadataEncoder::SegmentList& metadata);
70     static std::unique_ptr<SkEncoder> MakeYUV(SkWStream* dst,
71                                               const SkYUVAPixmaps& srcYUVA,
72                                               const SkColorSpace* srcYUVAColorSpace,
73                                               const SkJpegEncoder::Options& options,
74                                               const SkJpegMetadataEncoder::SegmentList& metadata);
75 
76     ~SkJpegEncoderImpl() override;
77 
78 protected:
79     bool onEncodeRows(int numRows) override;
80 
81 private:
82     SkJpegEncoderImpl(std::unique_ptr<SkJpegEncoderMgr>, const SkPixmap& src);
83     SkJpegEncoderImpl(std::unique_ptr<SkJpegEncoderMgr>, const SkYUVAPixmaps& srcYUVA);
84 
85     std::unique_ptr<SkJpegEncoderMgr> fEncoderMgr;
86     std::optional<SkYUVAPixmaps> fSrcYUVA;
87 };
88 
89 #endif
90