Flutter Engine
The Flutter Engine
Classes | Namespaces | Macros | Functions | Variables
SkPngCodec.cpp File Reference
#include "src/codec/SkPngCodec.h"
#include "include/codec/SkPngChunkReader.h"
#include "include/codec/SkPngDecoder.h"
#include "include/core/SkAlphaType.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorType.h"
#include "include/core/SkData.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkRect.h"
#include "include/core/SkSize.h"
#include "include/core/SkStream.h"
#include "include/core/SkTypes.h"
#include "include/private/SkEncodedInfo.h"
#include "include/private/base/SkNoncopyable.h"
#include "include/private/base/SkTemplates.h"
#include "modules/skcms/skcms.h"
#include "src/codec/SkCodecPriv.h"
#include "src/codec/SkColorPalette.h"
#include "src/codec/SkPngPriv.h"
#include "src/codec/SkSwizzler.h"
#include "src/core/SkMemset.h"
#include "src/core/SkSwizzlePriv.h"
#include <csetjmp>
#include <algorithm>
#include <cstring>
#include <utility>
#include <png.h>
#include <pngconf.h>

Go to the source code of this file.

Classes

class  AutoCleanPng
 
class  SkPngNormalDecoder
 
class  SkPngInterlacedDecoder
 

Namespaces

namespace  SkPngDecoder
 

Macros

#define PNG_JMPBUF(x)   png_jmpbuf((png_structp) x)
 

Functions

static void sk_error_fn (png_structp png_ptr, png_const_charp msg)
 
void sk_warning_fn (png_structp, png_const_charp msg)
 
static bool is_chunk (const png_byte *chunk, const char *tag)
 
static bool process_data (png_structp png_ptr, png_infop info_ptr, SkStream *stream, void *buffer, size_t bufferSize, size_t length)
 
static bool needs_premul (SkAlphaType dstAT, SkEncodedInfo::Alpha encodedAlpha)
 
std::unique_ptr< SkEncodedInfo::ICCProfileread_color_profile (png_structp png_ptr, png_infop info_ptr)
 
static skcms_PixelFormat png_select_xform_format (const SkEncodedInfo &info)
 
static SkCodec::Result log_and_return_error (bool success)
 
static SkCodec::Result read_header (SkStream *stream, SkPngChunkReader *chunkReader, SkCodec **outCodec, png_structp *png_ptrp, png_infop *info_ptrp)
 
SK_API bool SkPngDecoder::IsPng (const void *, size_t)
 
SK_API std::unique_ptr< SkCodecSkPngDecoder::Decode (std::unique_ptr< SkStream >, SkCodec::Result *, SkCodecs::DecodeContext=nullptr)
 
SK_API std::unique_ptr< SkCodecSkPngDecoder::Decode (sk_sp< SkData >, SkCodec::Result *, SkCodecs::DecodeContext=nullptr)
 

Variables

constexpr int kSetJmpOkay = 0
 
constexpr int kPngError = 1
 
constexpr int kStopDecoding = 2
 
static constexpr SkColorType kXformSrcColorType = kRGBA_8888_SkColorType
 

Macro Definition Documentation

◆ PNG_JMPBUF

#define PNG_JMPBUF (   x)    png_jmpbuf((png_structp) x)

Definition at line 54 of file SkPngCodec.cpp.

Function Documentation

◆ is_chunk()

static bool is_chunk ( const png_byte *  chunk,
const char *  tag 
)
inlinestatic

Definition at line 147 of file SkPngCodec.cpp.

147 {
148 return memcmp(chunk + 4, tag, 4) == 0;
149}

◆ log_and_return_error()

static SkCodec::Result log_and_return_error ( bool  success)
static

Definition at line 501 of file SkPngCodec.cpp.

501 {
502 if (success) return SkCodec::kIncompleteInput;
503#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
504 SkAndroidFrameworkUtils::SafetyNetLog("117838472");
505#endif
507}
@ kIncompleteInput
Definition: SkCodec.h:84
@ kErrorInInput
Definition: SkCodec.h:91

◆ needs_premul()

static bool needs_premul ( SkAlphaType  dstAT,
SkEncodedInfo::Alpha  encodedAlpha 
)
inlinestatic

Definition at line 270 of file SkPngCodec.cpp.

270 {
271 return kPremul_SkAlphaType == dstAT && SkEncodedInfo::kUnpremul_Alpha == encodedAlpha;
272}
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29

◆ png_select_xform_format()

static skcms_PixelFormat png_select_xform_format ( const SkEncodedInfo info)
static

Definition at line 471 of file SkPngCodec.cpp.

471 {
472 // We use kRGB and kRGBA formats because color PNGs are always RGB or RGBA.
473 if (16 == info.bitsPerComponent()) {
474 if (SkEncodedInfo::kRGBA_Color == info.color()) {
476 } else if (SkEncodedInfo::kRGB_Color == info.color()) {
478 }
479 } else if (SkEncodedInfo::kGray_Color == info.color()) {
481 }
482
484}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
@ skcms_PixelFormat_RGBA_16161616BE
Definition: skcms_public.h:302
@ skcms_PixelFormat_RGBA_8888
Definition: skcms_public.h:287
@ skcms_PixelFormat_G_8
Definition: skcms_public.h:276
@ skcms_PixelFormat_RGB_161616BE
Definition: skcms_public.h:300

◆ process_data()

static bool process_data ( png_structp  png_ptr,
png_infop  info_ptr,
SkStream stream,
void *  buffer,
size_t  bufferSize,
size_t  length 
)
inlinestatic

Definition at line 151 of file SkPngCodec.cpp.

152 {
153 while (length > 0) {
154 const size_t bytesToProcess = std::min(bufferSize, length);
155 const size_t bytesRead = stream->read(buffer, bytesToProcess);
156 png_process_data(png_ptr, info_ptr, (png_bytep) buffer, bytesRead);
157 if (bytesRead < bytesToProcess) {
158 return false;
159 }
160 length -= bytesToProcess;
161 }
162 return true;
163}
static float min(float r, float g, float b)
Definition: hsl.cpp:48
size_t length
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126

◆ read_color_profile()

std::unique_ptr< SkEncodedInfo::ICCProfile > read_color_profile ( png_structp  png_ptr,
png_infop  info_ptr 
)

Definition at line 366 of file SkPngCodec.cpp.

367 {
368
369#if (PNG_LIBPNG_VER_MAJOR > 1) || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR >= 6)
370 // First check for an ICC profile
371 png_bytep profile;
372 png_uint_32 length;
373 // The below variables are unused, however, we need to pass them in anyway or
374 // png_get_iCCP() will return nothing.
375 // Could knowing the |name| of the profile ever be interesting? Maybe for debugging?
376 png_charp name;
377 // The |compression| is uninteresting since:
378 // (1) libpng has already decompressed the profile for us.
379 // (2) "deflate" is the only mode of decompression that libpng supports.
380 int compression;
381 if (PNG_INFO_iCCP == png_get_iCCP(png_ptr, info_ptr, &name, &compression, &profile,
382 &length)) {
384 return SkEncodedInfo::ICCProfile::Make(std::move(data));
385 }
386
387 // Second, check for sRGB.
388 // Note that Blink does this first. This code checks ICC first, with the thinking that
389 // an image has both truly wants the potentially more specific ICC chunk, with sRGB as a
390 // backup in case the decoder does not support full color management.
391 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sRGB)) {
392 // sRGB chunks also store a rendering intent: Absolute, Relative,
393 // Perceptual, and Saturation.
394 // FIXME (scroggo): Extract this information from the sRGB chunk once
395 // we are able to handle this information in
396 // skcms_ICCProfile
397 return nullptr;
398 }
399
400 // Default to SRGB gamut.
402 // Next, check for chromaticities.
403 png_fixed_point chrm[8];
404 png_fixed_point gamma;
405 if (png_get_cHRM_fixed(png_ptr, info_ptr, &chrm[0], &chrm[1], &chrm[2], &chrm[3], &chrm[4],
406 &chrm[5], &chrm[6], &chrm[7]))
407 {
408 float rx = png_fixed_point_to_float(chrm[2]);
409 float ry = png_fixed_point_to_float(chrm[3]);
410 float gx = png_fixed_point_to_float(chrm[4]);
411 float gy = png_fixed_point_to_float(chrm[5]);
412 float bx = png_fixed_point_to_float(chrm[6]);
413 float by = png_fixed_point_to_float(chrm[7]);
414 float wx = png_fixed_point_to_float(chrm[0]);
415 float wy = png_fixed_point_to_float(chrm[1]);
416
417 skcms_Matrix3x3 tmp;
418 if (skcms_PrimariesToXYZD50(rx, ry, gx, gy, bx, by, wx, wy, &tmp)) {
419 toXYZD50 = tmp;
420 } else {
421 // Note that Blink simply returns nullptr in this case. We'll fall
422 // back to srgb.
423 }
424 }
425
427 if (PNG_INFO_gAMA == png_get_gAMA_fixed(png_ptr, info_ptr, &gamma)) {
428 fn.a = 1.0f;
429 fn.b = fn.c = fn.d = fn.e = fn.f = 0.0f;
430 fn.g = png_inverted_fixed_point_to_float(gamma);
431 } else {
432 // Default to sRGB gamma if the image has color space information,
433 // but does not specify gamma.
434 // Note that Blink would again return nullptr in this case.
436 }
437
438 skcms_ICCProfile skcmsProfile;
439 skcms_Init(&skcmsProfile);
440 skcms_SetTransferFunction(&skcmsProfile, &fn);
441 skcms_SetXYZD50(&skcmsProfile, &toXYZD50);
442
443 return SkEncodedInfo::ICCProfile::Make(skcmsProfile);
444#else // LIBPNG >= 1.6
445 return nullptr;
446#endif // LIBPNG >= 1.6
447}
static sk_sp< SkData > MakeWithCopy(const void *data, size_t length)
Definition: SkData.cpp:111
static std::unique_ptr< ICCProfile > Make(sk_sp< SkData >)
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
bool skcms_PrimariesToXYZD50(float rx, float ry, float gx, float gy, float bx, float by, float wx, float wy, skcms_Matrix3x3 *toXYZD50)
Definition: skcms.cc:1747
const skcms_ICCProfile * skcms_sRGB_profile()
Definition: skcms.cc:1393
const skcms_TransferFunction * skcms_sRGB_TransferFunction()
Definition: skcms.cc:1587
static void skcms_SetXYZD50(skcms_ICCProfile *p, const skcms_Matrix3x3 *m)
Definition: skcms_public.h:399
static void skcms_SetTransferFunction(skcms_ICCProfile *p, const skcms_TransferFunction *tf)
Definition: skcms_public.h:390
static void skcms_Init(skcms_ICCProfile *p)
Definition: skcms_public.h:384
skcms_Matrix3x3 toXYZD50
Definition: skcms_public.h:191
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63

◆ read_header()

static SkCodec::Result read_header ( SkStream stream,
SkPngChunkReader chunkReader,
SkCodec **  outCodec,
png_structp *  png_ptrp,
png_infop *  info_ptrp 
)
static

Definition at line 795 of file SkPngCodec.cpp.

797 {
798 // The image is known to be a PNG. Decode enough to know the SkImageInfo.
799 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr,
801 if (!png_ptr) {
803 }
804
805#ifdef PNG_SET_OPTION_SUPPORTED
806 // This setting ensures that we display images with incorrect CMF bytes.
807 // See crbug.com/807324.
808 png_set_option(png_ptr, PNG_MAXIMUM_INFLATE_WINDOW, PNG_OPTION_ON);
809#endif
810
811 AutoCleanPng autoClean(png_ptr, stream, chunkReader, outCodec);
812
813 png_infop info_ptr = png_create_info_struct(png_ptr);
814 if (info_ptr == nullptr) {
816 }
817
818 autoClean.setInfoPtr(info_ptr);
819
820 if (setjmp(PNG_JMPBUF(png_ptr))) {
822 }
823
824#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
825 // Hookup our chunkReader so we can see any user-chunks the caller may be interested in.
826 // This needs to be installed before we read the png header. Android may store ninepatch
827 // chunks in the header.
828 if (chunkReader) {
829 png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_ALWAYS, (png_const_bytep)"", 0);
830 png_set_read_user_chunk_fn(png_ptr, (png_voidp) chunkReader, sk_read_user_chunk);
831 }
832#endif
833
834 const bool decodedBounds = autoClean.decodeBounds();
835
836 if (!decodedBounds) {
838 }
839
840 // On success, decodeBounds releases ownership of png_ptr and info_ptr.
841 if (png_ptrp) {
842 *png_ptrp = png_ptr;
843 }
844 if (info_ptrp) {
845 *info_ptrp = info_ptr;
846 }
847
848 // decodeBounds takes care of setting outCodec
849 if (outCodec) {
850 SkASSERT(*outCodec);
851 }
852 return SkCodec::kSuccess;
853}
#define SkASSERT(cond)
Definition: SkAssert.h:116
static void sk_error_fn(png_structp png_ptr, png_const_charp msg)
Definition: SkPngCodec.cpp:67
void sk_warning_fn(png_structp, png_const_charp msg)
Definition: SkPngCodec.cpp:72
#define PNG_JMPBUF(x)
Definition: SkPngCodec.cpp:54
@ kInvalidInput
Definition: SkCodec.h:109
@ kInternalError
Definition: SkCodec.h:118
@ kSuccess
Definition: SkCodec.h:80

◆ sk_error_fn()

static void sk_error_fn ( png_structp  png_ptr,
png_const_charp  msg 
)
static

Definition at line 67 of file SkPngCodec.cpp.

67 {
68 SkCodecPrintf("------ png error %s\n", msg);
69 longjmp(PNG_JMPBUF(png_ptr), kPngError);
70}
#define SkCodecPrintf(...)
Definition: SkCodecPriv.h:23
constexpr int kPngError
Definition: SkPngCodec.cpp:63

◆ sk_warning_fn()

void sk_warning_fn ( png_structp  ,
png_const_charp  msg 
)

Definition at line 72 of file SkPngCodec.cpp.

72 {
73 SkCodecPrintf("----- png warning %s\n", msg);
74}

Variable Documentation

◆ kPngError

constexpr int kPngError = 1
constexpr

Definition at line 63 of file SkPngCodec.cpp.

◆ kSetJmpOkay

constexpr int kSetJmpOkay = 0
constexpr

Definition at line 61 of file SkPngCodec.cpp.

◆ kStopDecoding

constexpr int kStopDecoding = 2
constexpr

Definition at line 65 of file SkPngCodec.cpp.

◆ kXformSrcColorType

constexpr SkColorType kXformSrcColorType = kRGBA_8888_SkColorType
staticconstexpr

Definition at line 268 of file SkPngCodec.cpp.