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 SkJpegEncoder_DEFINED 9 #define SkJpegEncoder_DEFINED 10 11 #include "include/encode/SkEncoder.h" 12 #include "include/private/base/SkAPI.h" 13 14 #include <memory> 15 16 class SkColorSpace; 17 class SkData; 18 class SkJpegEncoderMgr; 19 class SkPixmap; 20 class SkWStream; 21 class SkYUVAPixmaps; 22 struct skcms_ICCProfile; 23 24 class SK_API SkJpegEncoder : public SkEncoder { 25 public: 26 27 enum class AlphaOption { 28 kIgnore, 29 kBlendOnBlack, 30 }; 31 32 enum class Downsample { 33 /** 34 * Reduction by a factor of two in both the horizontal and vertical directions. 35 */ 36 k420, 37 38 /** 39 * Reduction by a factor of two in the horizontal direction. 40 */ 41 k422, 42 43 /** 44 * No downsampling. 45 */ 46 k444, 47 }; 48 49 struct Options { 50 /** 51 * |fQuality| must be in [0, 100] where 0 corresponds to the lowest quality. 52 */ 53 int fQuality = 100; 54 55 /** 56 * Choose the downsampling factor for the U and V components. This is only 57 * meaningful if the |src| is not kGray, since kGray will not be encoded as YUV. 58 * This is ignored in favor of |src|'s subsampling when |src| is an SkYUVAPixmaps. 59 * 60 * Our default value matches the libjpeg-turbo default. 61 */ 62 Downsample fDownsample = Downsample::k420; 63 64 /** 65 * Jpegs must be opaque. This instructs the encoder on how to handle input 66 * images with alpha. 67 * 68 * The default is to ignore the alpha channel and treat the image as opaque. 69 * Another option is to blend the pixels onto a black background before encoding. 70 * In the second case, the encoder supports linear or legacy blending. 71 */ 72 AlphaOption fAlphaOption = AlphaOption::kIgnore; 73 74 /** 75 * Optional XMP metadata. 76 */ 77 const SkData* xmpMetadata = nullptr; 78 79 /** 80 * An optional ICC profile to override the default behavior. 81 * 82 * The default behavior is to generate an ICC profile using a primary matrix and 83 * analytic transfer function. If the color space of |src| cannot be represented 84 * in this way (e.g, it is HLG or PQ), then no profile will be embedded. 85 */ 86 const skcms_ICCProfile* fICCProfile = nullptr; 87 const char* fICCProfileDescription = nullptr; 88 }; 89 90 /** 91 * Encode the |src| pixels to the |dst| stream. 92 * |options| may be used to control the encoding behavior. 93 * 94 * Returns true on success. Returns false on an invalid or unsupported |src|. 95 */ 96 static bool Encode(SkWStream* dst, const SkPixmap& src, const Options& options); 97 static bool Encode(SkWStream* dst, 98 const SkYUVAPixmaps& src, 99 const SkColorSpace* srcColorSpace, 100 const Options& options); 101 102 /** 103 * Create a jpeg encoder that will encode the |src| pixels to the |dst| stream. 104 * |options| may be used to control the encoding behavior. 105 * 106 * |dst| is unowned but must remain valid for the lifetime of the object. 107 * 108 * This returns nullptr on an invalid or unsupported |src|. 109 */ 110 static std::unique_ptr<SkEncoder> Make(SkWStream* dst, const SkPixmap& src, 111 const Options& options); 112 static std::unique_ptr<SkEncoder> Make(SkWStream* dst, 113 const SkYUVAPixmaps& src, 114 const SkColorSpace* srcColorSpace, 115 const Options& options); 116 117 ~SkJpegEncoder() override; 118 119 protected: 120 bool onEncodeRows(int numRows) override; 121 122 private: 123 SkJpegEncoder(std::unique_ptr<SkJpegEncoderMgr>, const SkPixmap& src); 124 SkJpegEncoder(std::unique_ptr<SkJpegEncoderMgr>, const SkYUVAPixmaps* srcYUVA); 125 126 static std::unique_ptr<SkEncoder> Make(SkWStream* dst, 127 const SkPixmap* src, 128 const SkYUVAPixmaps* srcYUVA, 129 const SkColorSpace* srcYUVAColorSpace, 130 const Options& options); 131 132 std::unique_ptr<SkJpegEncoderMgr> fEncoderMgr; 133 const SkYUVAPixmaps* fSrcYUVA = nullptr; 134 using INHERITED = SkEncoder; 135 }; 136 137 #endif 138