/*
|
* Copyright 2015 Google Inc.
|
*
|
* Use of this source code is governed by a BSD-style license that can be
|
* found in the LICENSE file.
|
*/
|
#ifndef SkPngCodec_DEFINED
|
#define SkPngCodec_DEFINED
|
|
#include "SkCodec.h"
|
#include "SkColorTable.h"
|
#include "SkPngChunkReader.h"
|
#include "SkEncodedImageFormat.h"
|
#include "SkImageInfo.h"
|
#include "SkRefCnt.h"
|
#include "SkSwizzler.h"
|
|
class SkStream;
|
|
class SkPngCodec : public SkCodec {
|
public:
|
static bool IsPng(const char*, size_t);
|
|
// Assume IsPng was called and returned true.
|
static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*,
|
SkPngChunkReader* = nullptr);
|
|
// FIXME (scroggo): Temporarily needed by AutoCleanPng.
|
void setIdatLength(size_t len) { fIdatLength = len; }
|
|
~SkPngCodec() override;
|
|
protected:
|
// We hold the png_ptr and info_ptr as voidp to avoid having to include png.h
|
// or forward declare their types here. voidp auto-casts to the real pointer types.
|
struct voidp {
|
voidp(void* ptr) : fPtr(ptr) {}
|
|
template <typename T>
|
operator T*() const { return (T*)fPtr; }
|
|
explicit operator bool() const { return fPtr != nullptr; }
|
|
void* fPtr;
|
};
|
|
SkPngCodec(SkEncodedInfo&&, std::unique_ptr<SkStream>, SkPngChunkReader*,
|
void* png_ptr, void* info_ptr, int bitDepth);
|
|
Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, int*)
|
override;
|
SkEncodedImageFormat onGetEncodedFormat() const override { return SkEncodedImageFormat::kPNG; }
|
bool onRewind() override;
|
|
SkSampler* getSampler(bool createIfNecessary) override;
|
void applyXformRow(void* dst, const void* src);
|
|
voidp png_ptr() { return fPng_ptr; }
|
voidp info_ptr() { return fInfo_ptr; }
|
|
SkSwizzler* swizzler() { return fSwizzler.get(); }
|
|
// Initialize variables used by applyXformRow.
|
void initializeXformParams();
|
|
/**
|
* Pass available input to libpng to process it.
|
*
|
* libpng will call any relevant callbacks installed. This will continue decoding
|
* until it reaches the end of the file, or until a callback tells libpng to stop.
|
*/
|
bool processData();
|
|
Result onStartIncrementalDecode(const SkImageInfo& dstInfo, void* pixels, size_t rowBytes,
|
const SkCodec::Options&) override;
|
Result onIncrementalDecode(int*) override;
|
|
sk_sp<SkPngChunkReader> fPngChunkReader;
|
voidp fPng_ptr;
|
voidp fInfo_ptr;
|
|
// These are stored here so they can be used both by normal decoding and scanline decoding.
|
sk_sp<SkColorTable> fColorTable; // May be unpremul.
|
std::unique_ptr<SkSwizzler> fSwizzler;
|
SkAutoTMalloc<uint8_t> fStorage;
|
void* fColorXformSrcRow;
|
const int fBitDepth;
|
|
private:
|
|
enum XformMode {
|
// Requires only a swizzle pass.
|
kSwizzleOnly_XformMode,
|
|
// Requires only a color xform pass.
|
kColorOnly_XformMode,
|
|
// Requires a swizzle and a color xform.
|
kSwizzleColor_XformMode,
|
};
|
|
bool createColorTable(const SkImageInfo& dstInfo);
|
// Helper to set up swizzler, color xforms, and color table. Also calls png_read_update_info.
|
SkCodec::Result initializeXforms(const SkImageInfo& dstInfo, const Options&);
|
void initializeSwizzler(const SkImageInfo& dstInfo, const Options&, bool skipFormatConversion);
|
void allocateStorage(const SkImageInfo& dstInfo);
|
void destroyReadStruct();
|
|
virtual Result decodeAllRows(void* dst, size_t rowBytes, int* rowsDecoded) = 0;
|
virtual void setRange(int firstRow, int lastRow, void* dst, size_t rowBytes) = 0;
|
virtual Result decode(int* rowsDecoded) = 0;
|
|
XformMode fXformMode;
|
int fXformWidth;
|
|
size_t fIdatLength;
|
bool fDecodedIdat;
|
|
typedef SkCodec INHERITED;
|
};
|
#endif // SkPngCodec_DEFINED
|