/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkCodec.h"
#include "SkColorSpaceXform.h"
#include "SkColorTable.h"
#include "SkPngChunkReader.h"
#include "SkEncodedFormat.h"
#include "SkImageInfo.h"
#include "SkRefCnt.h"
#include "SkSwizzler.h"

// FIXME (scroggo): GOOGLE3 is currently using an outdated version of libpng,
// so we need to work around the lack of the method png_process_data_pause.
// This code will be unnecessary once we update GOOGLE3. It would make more
// sense to condition this on the version of libpng being used, but we do not
// know that here because png.h is only included by the cpp file.
#define SK_GOOGLE3_PNG_HACK

class SkStream;

class SkPngCodec : public SkCodec {
public:
    static bool IsPng(const char*, size_t);

    // Assume IsPng was called and returned true.
    static SkCodec* NewFromStream(SkStream*, SkPngChunkReader* = NULL);

    virtual ~SkPngCodec();

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(const SkEncodedInfo&, const SkImageInfo&, SkStream*, SkPngChunkReader*,
            void* png_ptr, void* info_ptr, int bitDepth);

    Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, SkPMColor*, int*, int*)
            override;
    SkEncodedFormat onGetEncodedFormat() const override { return kPNG_SkEncodedFormat; }
    bool onRewind() override;
    uint64_t onGetFillValue(const SkImageInfo&) const 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; }

    // 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.
     */
    void processData();

#ifdef SK_GOOGLE3_PNG_HACK
    // In libpng 1.2.56, png_process_data_pause does not exist, so when we wanted to
    // read the header, we may have read too far. In that case, we need to delete the
    // png_ptr and info_ptr and recreate them. This method does that (and attaches the
    // chunk reader.
    bool rereadHeaderIfNecessary();

    // This method sets up the new png_ptr/info_ptr (created in rereadHeaderIfNecessary)
    // the way we set up the old one the first time in AutoCleanPng.decodeBounds's callback.
    void rereadInfoCallback();
#endif

    Result onStartIncrementalDecode(const SkImageInfo& dstInfo, void* pixels, size_t rowBytes,
            const SkCodec::Options&,
            SkPMColor* ctable, int* ctableCount) override;
    Result onIncrementalDecode(int*) override;

    SkAutoTUnref<SkPngChunkReader> fPngChunkReader;
    voidp                          fPng_ptr;
    voidp                          fInfo_ptr;

    // These are stored here so they can be used both by normal decoding and scanline decoding.
    SkAutoTUnref<SkColorTable>         fColorTable;    // May be unpremul.
    SkAutoTDelete<SkSwizzler>          fSwizzler;
    SkAutoTMalloc<uint8_t>             fStorage;
    uint32_t*                          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, int* ctableCount);
    // Helper to set up swizzler, color xforms, and color table. Also calls png_read_update_info.
    bool initializeXforms(const SkImageInfo& dstInfo, const Options&, SkPMColor* colorPtr,
                          int* colorCount);
    void initializeSwizzler(const SkImageInfo& dstInfo, const Options&);
    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;
    SkColorSpaceXform::ColorFormat fXformColorFormat;
    SkAlphaType                    fXformAlphaType;
    int                            fXformWidth;

#ifdef SK_GOOGLE3_PNG_HACK
    bool        fNeedsToRereadHeader;
#endif

    typedef SkCodec INHERITED;
};
