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