/*
 * 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 <cstddef>
#include <cstdint>
#include <memory>
#include <optional>

#include "include/codec/SkCodec.h"
#include "include/core/SkRefCnt.h"
#include "include/private/SkGainmapInfo.h"
#include "src/codec/SkPngCodecBase.h"

class SkPngChunkReader;
class SkPngCompositeChunkReader;
class SkStream;
struct SkEncodedInfo;
struct SkImageInfo;
template <typename T> class SkSpan;

class SkPngCodec : public SkPngCodecBase {
public:
    static bool IsPng(const void*, 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; }

    bool onGetGainmapCodec(SkGainmapInfo*, std::unique_ptr<SkCodec>*) override;

    bool onGetGainmapInfo(SkGainmapInfo*) override;

    ~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>,
               sk_sp<SkPngCompositeChunkReader>,
               void* png_ptr,
               void* info_ptr,
               std::unique_ptr<SkStream>,
               std::optional<SkGainmapInfo>);

    Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, int*)
            override;
    bool onRewind() override;

    voidp png_ptr() { return fPng_ptr; }
    voidp info_ptr() { return fInfo_ptr; }

    /**
     *  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<SkPngCompositeChunkReader>     fPngChunkReader;
    voidp                                fPng_ptr;
    voidp                                fInfo_ptr;

private:
    // SkPngCodecBase overrides:
    std::optional<SkSpan<const PaletteColorEntry>> onTryGetPlteChunk() override;
    std::optional<SkSpan<const uint8_t>> onTryGetTrnsChunk() override;

    // Thin wrapper around `SkPngCodecBase::initializeXforms` that also sets up
    // some `libpng`-specific state.
    Result initializeXforms(const SkImageInfo& dstInfo, const Options&);

    void destroyReadStruct();

    virtual Result decodeAllRows(void* dst, size_t rowBytes, int* rowsDecoded) = 0;
    virtual Result setRange(int firstRow, int lastRow, void* dst, size_t rowBytes) = 0;
    virtual Result decode(int* rowsDecoded) = 0;

    size_t                         fIdatLength;
    bool                           fDecodedIdat;
    std::unique_ptr<SkStream> fGainmapStream;
    std::optional<SkGainmapInfo> fGainmapInfo;
};
#endif  // SkPngCodec_DEFINED
