Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
@ skcms_PixelFormat_RGBA_8888
@ skcms_PixelFormat_G_8
@ skcms_PixelFormat_RGB_161616BE

◆ 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 const uint8_t buffer[]
size_t length

◆ 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)) {
383 auto data = SkData::MakeWithCopy(profile, 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 >)
const char * name
Definition fuchsia.cc:50
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41
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)
static void skcms_SetTransferFunction(skcms_ICCProfile *p, const skcms_TransferFunction *tf)
static void skcms_Init(skcms_ICCProfile *p)
skcms_Matrix3x3 toXYZD50

◆ 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)
void sk_warning_fn(png_structp, png_const_charp msg)
#define PNG_JMPBUF(x)
@ 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

◆ 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.