57static void sk_error_fn(png_structp png_ptr, png_const_charp msg) {
59 SkDebugf(
"libpng encode error: %s\n", msg);
62 longjmp(png_jmpbuf(png_ptr), 1);
65static void sk_write_fn(png_structp png_ptr, png_bytep data, png_size_t len) {
67 if (!stream->write(data, len)) {
68 png_error(png_ptr,
"sk_write_fn cannot write to stream");
78 static std::unique_ptr<SkPngEncoderMgr>
Make(
SkWStream* stream);
85 png_structp
pngPtr() {
return fPngPtr; }
97 int fPngBytesPerPixel;
103 png_create_write_struct(PNG_LIBPNG_VER_STRING,
nullptr,
sk_error_fn,
nullptr);
110 png_destroy_write_struct(&
pngPtr,
nullptr);
119 if (setjmp(png_jmpbuf(fPngPtr))) {
135 pngColorType = srcInfo.
isOpaque() ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA;
136 fPngBytesPerPixel = 8;
140 pngColorType = PNG_COLOR_TYPE_GRAY;
141 fPngBytesPerPixel = 1;
150 pngColorType = srcInfo.
isOpaque() ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA;
151 fPngBytesPerPixel = srcInfo.
isOpaque() ? 3 : 4;
157 pngColorType = PNG_COLOR_TYPE_RGB;
158 fPngBytesPerPixel = 3;
170 pngColorType = srcInfo.
isOpaque() ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA;
171 fPngBytesPerPixel = srcInfo.
isOpaque() ? 3 : 4;
177 pngColorType = PNG_COLOR_TYPE_RGB;
178 fPngBytesPerPixel = 3;
184 pngColorType = PNG_COLOR_TYPE_GRAY_ALPHA;
185 fPngBytesPerPixel = 2;
193 pngColorType = srcInfo.
isOpaque() ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA;
194 fPngBytesPerPixel = 8;
202 pngColorType = PNG_COLOR_TYPE_RGB;
203 fPngBytesPerPixel = 6;
209 png_set_IHDR(fPngPtr,
216 PNG_COMPRESSION_TYPE_BASE,
217 PNG_FILTER_TYPE_BASE);
218 png_set_sBIT(fPngPtr, fInfoPtr, &sigBit);
222 png_set_filter(fPngPtr, PNG_FILTER_TYPE_BASE, filters);
224 int zlibLevel = std::min(std::max(0,
options.fZLibLevel), 9);
226 png_set_compression_level(fPngPtr, zlibLevel);
230 if (comments !=
nullptr) {
231 std::vector<png_text> png_texts(comments->count());
232 std::vector<SkString> clippedKeys;
233 for (
int i = 0; i < comments->count() / 2; ++i) {
235 const char* originalKeyword = comments->atStr(2 * i);
236 const char*
text = comments->atStr(2 * i + 1);
237 if (strlen(originalKeyword) <= PNG_KEYWORD_MAX_LENGTH) {
238 keyword = originalKeyword;
240 SkDEBUGFAILF(
"PNG tEXt keyword should be no longer than %d.",
241 PNG_KEYWORD_MAX_LENGTH);
242 clippedKeys.emplace_back(originalKeyword, PNG_KEYWORD_MAX_LENGTH);
243 keyword = clippedKeys.back().c_str();
248 png_texts[i].compression = PNG_TEXT_COMPRESSION_NONE;
249 png_texts[i].key =
const_cast<png_charp
>(keyword);
250 png_texts[i].text =
const_cast<png_charp
>(
text);
252 png_set_text(fPngPtr, fInfoPtr, png_texts.data(), png_texts.size());
259 switch (
info.colorType()) {
270 switch (
info.alphaType()) {
282 switch (
info.alphaType()) {
298 switch (
info.alphaType()) {
312 switch (
info.alphaType()) {
323 switch (
info.alphaType()) {
334 switch (
info.alphaType()) {
345 switch (
info.alphaType()) {
360 switch (
info.alphaType()) {
388 const char* profile_description) {
394#if PNG_LIBPNG_VER_MAJOR > 1 || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR >= 5)
395 const char*
name =
"Skia";
396 png_const_bytep iccPtr = icc->bytes();
400 png_charp iccPtr = (png_charp)icc->writable_data();
402 png_set_iCCP(png_ptr, info_ptr,
name, 0, iccPtr, icc->size());
406 if (setjmp(png_jmpbuf(fPngPtr))) {
410 if (
info.colorSpace() &&
info.colorSpace()->isSRGB()) {
411 png_set_sRGB(fPngPtr, fInfoPtr, PNG_sRGB_INTENT_PERCEPTUAL);
420 if (setjmp(png_jmpbuf(fPngPtr))) {
424 png_write_info(fPngPtr, fInfoPtr);
429 png_set_filler(fPngPtr, 0, PNG_FILLER_AFTER);
439 , fEncoderMgr(
std::move(encoderMgr)) {}
449 for (
int y = 0;
y < numRows;
y++) {
459 srcRow = SkTAddOffset<const void>(srcRow,
fSrc.
rowBytes());
481 if (!encoderMgr->setHeader(src.info(),
options)) {
485 if (!encoderMgr->setColorSpace(src.info(),
options)) {
489 if (!encoderMgr->writeInfo(src.info())) {
493 encoderMgr->chooseProc(src.info());
495 return std::make_unique<SkPngEncoderImpl>(std::move(encoderMgr), src);
508 if (!
as_IB(img)->getROPixels(ctx, &bm)) {
513 return stream.detachAsData();
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
@ kOpaque_SkAlphaType
pixel is opaque
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
#define SkDEBUGFAIL(message)
#define SkDEBUGFAILF(fmt,...)
@ kR16G16B16A16_unorm_SkColorType
pixel with a little endian uint16_t for red, green, blue
@ kRGBA_10x6_SkColorType
pixel with 10 used bits (most significant) followed by 6 unused
@ kBGR_101010x_SkColorType
pixel with 10 bits each for blue, green, red; in 32-bit word
@ kARGB_4444_SkColorType
pixel with 4 bits for alpha, red, green, blue; in 16-bit word
@ kR8G8_unorm_SkColorType
pixel with a uint8_t for red and green
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
@ kA16_unorm_SkColorType
pixel with a little endian uint16_t for alpha
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
@ kRGB_101010x_SkColorType
pixel with 10 bits each for red, green, blue; in 32-bit word
@ kSRGBA_8888_SkColorType
@ kGray_8_SkColorType
pixel with grayscale level in 8-bit byte
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
@ kBGRA_10101010_XR_SkColorType
pixel with 10 bits each for blue, green, red, alpha; in 64-bit word, extended range
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
@ kRGB_888x_SkColorType
pixel with 8 bits each for red, green, blue; in 32-bit word
@ kBGRA_1010102_SkColorType
10 bits for blue, green, red; 2 bits for alpha; in 32-bit word
@ kA16_float_SkColorType
pixel with a half float for alpha
@ kRGBA_F32_SkColorType
pixel using C float for red, green, blue, alpha; in 128-bit word
@ kRGBA_1010102_SkColorType
10 bits for red, green, blue; 2 bits for alpha; in 32-bit word
@ kBGR_101010x_XR_SkColorType
pixel with 10 bits each for blue, green, red; in 32-bit word, extended range
@ kR16G16_unorm_SkColorType
pixel with a little endian uint16_t for red and green
@ kRGBA_F16Norm_SkColorType
pixel with half floats in [0,1] for red, green, blue, alpha;
@ kUnknown_SkColorType
uninitialized
@ kR16G16_float_SkColorType
pixel with a half float for red and green
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static void transform_scanline_RGBX(char *dst, const char *src, int width, int)
static void transform_scanline_bgr_101010x(char *dst, const char *src, int width, int)
static void transform_scanline_F32(char *dst, const char *src, int width, int)
static void transform_scanline_F16_premul(char *dst, const char *src, int width, int)
static void transform_scanline_F16(char *dst, const char *src, int width, int)
static void transform_scanline_bgra_1010102_premul(char *dst, const char *src, int width, int)
static void transform_scanline_1010102(char *dst, const char *src, int width, int)
static void transform_scanline_BGRX(char *dst, const char *src, int width, int)
static void transform_scanline_bgra_1010102(char *dst, const char *src, int width, int)
void(* transform_scanline_proc)(char *dst, const char *src, int width, int bpp)
static void transform_scanline_4444(char *dst, const char *src, int width, int)
static void transform_scanline_565(char *dst, const char *src, int width, int)
static void transform_scanline_memcpy(char *dst, const char *src, int width, int bpp)
static void transform_scanline_A8_to_GrayAlpha(char *dst, const char *src, int width, int)
static void transform_scanline_bgr_101010x_xr(char *dst, const char *src, int width, int)
static void transform_scanline_101010x(char *dst, const char *src, int width, int)
static void transform_scanline_444(char *dst, const char *src, int width, int)
static sk_sp< SkData > icc_from_color_space(const SkColorSpace *cs, const skcms_ICCProfile *profile, const char *profile_description)
static void transform_scanline_F32_premul(char *dst, const char *src, int width, int)
static void transform_scanline_1010102_premul(char *dst, const char *src, int width, int)
static void transform_scanline_rgbA(char *dst, const char *src, int width, int)
static void transform_scanline_BGRA(char *dst, const char *src, int width, int)
static void transform_scanline_bgrA(char *dst, const char *src, int width, int)
static bool SkPixmapIsValid(const SkPixmap &src)
SK_API int SkColorTypeBytesPerPixel(SkColorType ct)
static SkImage_Base * as_IB(SkImage *image)
static void sk_msan_assert_initialized(const void *begin, const void *end)
static void sk_error_fn(png_structp png_ptr, png_const_charp msg)
static transform_scanline_proc choose_proc(const SkImageInfo &info)
static void set_icc(png_structp png_ptr, png_infop info_ptr, const SkImageInfo &info, const skcms_ICCProfile *profile, const char *profile_description)
static void sk_write_fn(png_structp png_ptr, png_bytep data, png_size_t len)
static constexpr bool kSuppressPngEncodeWarnings
static constexpr int kGraySigBit_GrayAlphaIsJustAlpha
Type::kYUV Type::kRGBA() int(0.7 *637)
const SkPixmap & pixmap() const
skia_private::AutoTMalloc< uint8_t > fStorage
SkColorType colorType() const
const void * addr() const
int shiftPerPixel() const
SkPngEncoderImpl(std::unique_ptr< SkPngEncoderMgr >, const SkPixmap &src)
std::unique_ptr< SkPngEncoderMgr > fEncoderMgr
bool onEncodeRows(int numRows) override
~SkPngEncoderImpl() override
transform_scanline_proc proc() const
int pngBytesPerPixel() const
bool writeInfo(const SkImageInfo &srcInfo)
bool setColorSpace(const SkImageInfo &info, const SkPngEncoder::Options &options)
bool setHeader(const SkImageInfo &srcInfo, const SkPngEncoder::Options &options)
void chooseProc(const SkImageInfo &srcInfo)
static std::unique_ptr< SkPngEncoderMgr > Make(SkWStream *stream)
const char * data() const
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
SK_API std::unique_ptr< SkEncoder > Make(SkWStream *dst, const SkPixmap &src, const Options &options)
SkAlphaType alphaType() const
SkColorType colorType() const