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