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

#ifndef SkPngEncoder_DEFINED
#define SkPngEncoder_DEFINED

#include "include/core/SkDataTable.h"
#include "include/encode/SkEncoder.h"

class SkPngEncoderMgr;
class SkWStream;
struct skcms_ICCProfile;

class SK_API SkPngEncoder : public SkEncoder {
public:

    enum class FilterFlag : int {
        kZero  = 0x00,
        kNone  = 0x08,
        kSub   = 0x10,
        kUp    = 0x20,
        kAvg   = 0x40,
        kPaeth = 0x80,
        kAll   = kNone | kSub | kUp | kAvg | kPaeth,
    };

    struct Options {
        /**
         *  Selects which filtering strategies to use.
         *
         *  If a single filter is chosen, libpng will use that filter for every row.
         *
         *  If multiple filters are chosen, libpng will use a heuristic to guess which filter
         *  will encode smallest, then apply that filter.  This happens on a per row basis,
         *  different rows can use different filters.
         *
         *  Using a single filter (or less filters) is typically faster.  Trying all of the
         *  filters may help minimize the output file size.
         *
         *  Our default value matches libpng's default.
         */
        FilterFlag fFilterFlags = FilterFlag::kAll;

        /**
         *  Must be in [0, 9] where 9 corresponds to maximal compression.  This value is passed
         *  directly to zlib.  0 is a special case to skip zlib entirely, creating dramatically
         *  larger pngs.
         *
         *  Our default value matches libpng's default.
         */
        int fZLibLevel = 6;

        /**
         *  Represents comments in the tEXt ancillary chunk of the png.
         *  The 2i-th entry is the keyword for the i-th comment,
         *  and the (2i + 1)-th entry is the text for the i-th comment.
         */
        sk_sp<SkDataTable> fComments;

        /**
         * An optional ICC profile to override the default behavior.
         *
         * The default behavior is to generate an ICC profile using a primary matrix and
         * analytic transfer function. If the color space of |src| cannot be represented
         * in this way (e.g, it is HLG or PQ), then no profile will be embedded.
         */
        const skcms_ICCProfile* fICCProfile = nullptr;
        const char* fICCProfileDescription = nullptr;
    };

    /**
     *  Encode the |src| pixels to the |dst| stream.
     *  |options| may be used to control the encoding behavior.
     *
     *  Returns true on success.  Returns false on an invalid or unsupported |src|.
     */
    static bool Encode(SkWStream* dst, const SkPixmap& src, const Options& options);

    /**
     *  Create a png encoder that will encode the |src| pixels to the |dst| stream.
     *  |options| may be used to control the encoding behavior.
     *
     *  |dst| is unowned but must remain valid for the lifetime of the object.
     *
     *  This returns nullptr on an invalid or unsupported |src|.
     */
    static std::unique_ptr<SkEncoder> Make(SkWStream* dst, const SkPixmap& src,
                                           const Options& options);

    ~SkPngEncoder() override;

protected:
    bool onEncodeRows(int numRows) override;

    SkPngEncoder(std::unique_ptr<SkPngEncoderMgr>, const SkPixmap& src);

    std::unique_ptr<SkPngEncoderMgr> fEncoderMgr;
    using INHERITED = SkEncoder;
};

static inline SkPngEncoder::FilterFlag operator|(SkPngEncoder::FilterFlag x,
                                                 SkPngEncoder::FilterFlag y) {
    return (SkPngEncoder::FilterFlag)((int)x | (int)y);
}

#endif
