/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkMask_DEFINED
#define SkMask_DEFINED

#include "include/core/SkRect.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkTemplates.h"
#include "src/core/SkColorData.h"
#include "src/core/SkColorPriv.h"

#include <cstddef>
#include <cstdint>
#include <memory>

/** \class SkMask
    SkMask is used to describe alpha bitmaps, either 1bit, 8bit, or
    the 3-channel 3D format. These are passed to SkMaskFilter objects.
*/
struct SkMask {
    enum Format : uint8_t {
        kBW_Format, //!< 1bit per pixel mask (e.g. monochrome)
        kA8_Format, //!< 8bits per pixel mask (e.g. antialiasing)
        k3D_Format, //!< 3 8bit per pixl planes: alpha, mul, add
        kARGB32_Format,         //!< SkPMColor
        kLCD16_Format,          //!< 565 alpha for r/g/b
        kSDF_Format,            //!< 8bits representing signed distance field
    };

    enum {
        kCountMaskFormats = kSDF_Format + 1
    };

    SkMask(const uint8_t* img, const SkIRect& bounds, uint32_t rowBytes, Format format)
        : fImage(img), fBounds(bounds), fRowBytes(rowBytes), fFormat(format) {}
    uint8_t const * const fImage;
    const SkIRect fBounds;
    const uint32_t fRowBytes;
    const Format fFormat;

    static bool IsValidFormat(uint8_t format) { return format < kCountMaskFormats; }

    /** Returns true if the mask is empty: i.e. it has an empty bounds.
     */
    bool isEmpty() const { return fBounds.isEmpty(); }

    /** Return the byte size of the mask, assuming only 1 plane.
        Does not account for k3D_Format. For that, use computeTotalImageSize().
        If there is an overflow of 32bits, then returns 0.
    */
    size_t computeImageSize() const;

    /** Return the byte size of the mask, taking into account
        any extra planes (e.g. k3D_Format).
        If there is an overflow of 32bits, then returns 0.
    */
    size_t computeTotalImageSize() const;

    /** Returns the address of the byte that holds the specified bit.
        Asserts that the mask is kBW_Format, and that x,y are in range.
        x,y are in the same coordiate space as fBounds.
    */
    const uint8_t* getAddr1(int x, int y) const {
        SkASSERT(kBW_Format == fFormat);
        SkASSERT(fBounds.contains(x, y));
        SkASSERT(fImage != nullptr);
        return fImage + ((x - fBounds.fLeft) >> 3) + (y - fBounds.fTop) * fRowBytes;
    }

    /** Returns the address of the specified byte.
        Asserts that the mask is kA8_Format, and that x,y are in range.
        x,y are in the same coordiate space as fBounds.
    */
    const uint8_t* getAddr8(int x, int y) const {
        SkASSERT(kA8_Format == fFormat || kSDF_Format == fFormat);
        SkASSERT(fBounds.contains(x, y));
        SkASSERT(fImage != nullptr);
        return fImage + x - fBounds.fLeft + (y - fBounds.fTop) * fRowBytes;
    }

    /**
     *  Return the address of the specified 16bit mask. In the debug build,
     *  this asserts that the mask's format is kLCD16_Format, and that (x,y)
     *  are contained in the mask's fBounds.
     */
    const uint16_t* getAddrLCD16(int x, int y) const {
        SkASSERT(kLCD16_Format == fFormat);
        SkASSERT(fBounds.contains(x, y));
        SkASSERT(fImage != nullptr);
        const uint16_t* row = (const uint16_t*)(fImage + (y - fBounds.fTop) * fRowBytes);
        return row + (x - fBounds.fLeft);
    }

    /**
     *  Return the address of the specified 32bit mask. In the debug build,
     *  this asserts that the mask's format is 32bits, and that (x,y)
     *  are contained in the mask's fBounds.
     */
    const uint32_t* getAddr32(int x, int y) const {
        SkASSERT(kARGB32_Format == fFormat);
        SkASSERT(fBounds.contains(x, y));
        SkASSERT(fImage != nullptr);
        const uint32_t* row = (const uint32_t*)(fImage + (y - fBounds.fTop) * fRowBytes);
        return row + (x - fBounds.fLeft);
    }

    /**
     *  Returns the address of the specified pixel, computing the pixel-size
     *  at runtime based on the mask format. This will be slightly slower than
     *  using one of the routines where the format is implied by the name
     *  e.g. getAddr8 or getAddr32.
     *
     *  x,y must be contained by the mask's bounds (this is asserted in the
     *  debug build, but not checked in the release build.)
     *
     *  This should not be called with kBW_Format, as it will give unspecified
     *  results (and assert in the debug build).
     */
    const void* getAddr(int x, int y) const;

    /** Iterates over the coverage values along a scanline in a given SkMask::Format. Provides
     *  constructor, copy constructor for creating
     *  operator++, operator-- for iterating over the coverage values on a scanline
     *  operator>>= to add row bytes
     *  operator* to get the coverage value at the current location
     *  operator< to compare two iterators
     */
    template <Format F> struct AlphaIter;
};

template <> struct SkMask::AlphaIter<SkMask::kBW_Format> {
    AlphaIter(const uint8_t* ptr, int offset) : fPtr(ptr), fOffset(7 - offset) {}
    AlphaIter(const AlphaIter& that) : fPtr(that.fPtr), fOffset(that.fOffset) {}
    AlphaIter& operator++() {
        if (0 < fOffset ) {
            --fOffset;
        } else {
            ++fPtr;
            fOffset = 7;
        }
        return *this;
    }
    AlphaIter& operator--() {
        if (fOffset < 7) {
            ++fOffset;
        } else {
            --fPtr;
            fOffset = 0;
        }
        return *this;
    }
    AlphaIter& operator>>=(uint32_t rb) {
        fPtr = SkTAddOffset<const uint8_t>(fPtr, rb);
        return *this;
    }
    uint8_t operator*() const { return ((*fPtr) >> fOffset) & 1 ? 0xFF : 0; }
    bool operator<(const AlphaIter& that) const {
        return fPtr < that.fPtr || (fPtr == that.fPtr && fOffset > that.fOffset);
    }
    const uint8_t* fPtr;
    int fOffset;
};

template <> struct SkMask::AlphaIter<SkMask::kA8_Format> {
    AlphaIter(const uint8_t* ptr) : fPtr(ptr) {}
    AlphaIter(const AlphaIter& that) : fPtr(that.fPtr) {}
    AlphaIter& operator++() { ++fPtr; return *this; }
    AlphaIter& operator--() { --fPtr; return *this; }
    AlphaIter& operator>>=(uint32_t rb) {
        fPtr = SkTAddOffset<const uint8_t>(fPtr, rb);
        return *this;
    }
    uint8_t operator*() const { return *fPtr; }
    bool operator<(const AlphaIter& that) const { return fPtr < that.fPtr; }
    const uint8_t* fPtr;
};

template <> struct SkMask::AlphaIter<SkMask::kARGB32_Format> {
    AlphaIter(const uint32_t* ptr) : fPtr(ptr) {}
    AlphaIter(const AlphaIter& that) : fPtr(that.fPtr) {}
    AlphaIter& operator++() { ++fPtr; return *this; }
    AlphaIter& operator--() { --fPtr; return *this; }
    AlphaIter& operator>>=(uint32_t rb) {
        fPtr = SkTAddOffset<const uint32_t>(fPtr, rb);
        return *this;
    }
    uint8_t operator*() const { return SkGetPackedA32(*fPtr); }
    bool operator<(const AlphaIter& that) const { return fPtr < that.fPtr; }
    const uint32_t* fPtr;
};

template <> struct SkMask::AlphaIter<SkMask::kLCD16_Format> {
    AlphaIter(const uint16_t* ptr) : fPtr(ptr) {}
    AlphaIter(const AlphaIter& that) : fPtr(that.fPtr) {}
    AlphaIter& operator++() { ++fPtr; return *this; }
    AlphaIter& operator--() { --fPtr; return *this; }
    AlphaIter& operator>>=(uint32_t rb) {
        fPtr = SkTAddOffset<const uint16_t>(fPtr, rb);
        return *this;
    }
    uint8_t operator*() const {
        unsigned packed = *fPtr;
        unsigned r = SkPacked16ToR32(packed);
        unsigned g = SkPacked16ToG32(packed);
        unsigned b = SkPacked16ToB32(packed);
        return (r + g + b) / 3;
    }
    bool operator<(const AlphaIter& that) const { return fPtr < that.fPtr; }
    const uint16_t* fPtr;
};

///////////////////////////////////////////////////////////////////////////////

struct SkMaskBuilder : public SkMask {
    SkMaskBuilder() : SkMask(nullptr, {0}, 0, SkMask::Format::kBW_Format) {}
    SkMaskBuilder(const SkMaskBuilder&) = delete;
    SkMaskBuilder(SkMaskBuilder&&) = default;
    SkMaskBuilder& operator=(const SkMaskBuilder&) = delete;
    SkMaskBuilder& operator=(SkMaskBuilder&& that) {
        this->image() = that.image();
        this->bounds() = that.bounds();
        this->rowBytes() = that.rowBytes();
        this->format() = that.format();
        that.image() = nullptr;
        return *this;
    }

    SkMaskBuilder(uint8_t* img, const SkIRect& bounds, uint32_t rowBytes, Format format)
        : SkMask(img, bounds, rowBytes, format) {}

    uint8_t*& image() { return *const_cast<uint8_t**>(&fImage); }
    SkIRect& bounds() { return *const_cast<SkIRect*>(&fBounds); }
    uint32_t& rowBytes() { return *const_cast<uint32_t*>(&fRowBytes); }
    Format& format() { return *const_cast<Format*>(&fFormat); }

    /** Returns the address of the byte that holds the specified bit.
        Asserts that the mask is kBW_Format, and that x,y are in range.
        x,y are in the same coordiate space as fBounds.
    */
    uint8_t* getAddr1(int x, int y) {
        return const_cast<uint8_t*>(this->SkMask::getAddr1(x, y));
    }

    /** Returns the address of the specified byte.
        Asserts that the mask is kA8_Format, and that x,y are in range.
        x,y are in the same coordiate space as fBounds.
    */
    uint8_t* getAddr8(int x, int y) {
        return const_cast<uint8_t*>(this->SkMask::getAddr8(x, y));
    }

    /**
     *  Return the address of the specified 16bit mask. In the debug build,
     *  this asserts that the mask's format is kLCD16_Format, and that (x,y)
     *  are contained in the mask's fBounds.
     */
    uint16_t* getAddrLCD16(int x, int y) {
        return const_cast<uint16_t*>(this->SkMask::getAddrLCD16(x, y));
    }

    /**
     *  Return the address of the specified 32bit mask. In the debug build,
     *  this asserts that the mask's format is 32bits, and that (x,y)
     *  are contained in the mask's fBounds.
     */
    uint32_t* getAddr32(int x, int y) {
        return const_cast<uint32_t*>(this->SkMask::getAddr32(x, y));
    }

    /**
     *  Returns the address of the specified pixel, computing the pixel-size
     *  at runtime based on the mask format. This will be slightly slower than
     *  using one of the routines where the format is implied by the name
     *  e.g. getAddr8 or getAddr32.
     *
     *  x,y must be contained by the mask's bounds (this is asserted in the
     *  debug build, but not checked in the release build.)
     *
     *  This should not be called with kBW_Format, as it will give unspecified
     *  results (and assert in the debug build).
     */
    void* getAddr(int x, int y) {
        return const_cast<void*>(this->SkMask::getAddr(x, y));
    }

    enum AllocType {
        kUninit_Alloc,
        kZeroInit_Alloc,
    };
    static uint8_t* AllocImage(size_t bytes, AllocType = kUninit_Alloc);
    static void FreeImage(void* image);

    enum CreateMode {
        kJustComputeBounds_CreateMode,      //!< compute bounds and return
        kJustRenderImage_CreateMode,        //!< render into preallocate mask
        kComputeBoundsAndRenderImage_CreateMode  //!< compute bounds, alloc image and render into it
    };

    /**
     *  Returns initial destination mask data padded by radiusX and radiusY
     */
    static SkMaskBuilder PrepareDestination(int radiusX, int radiusY, const SkMask& src);
};

/**
 *  \using SkAutoMaskImage
 *
 *  Stack class used to manage the fImage buffer in a SkMask.
 *  When this object loses scope, the buffer is freed with SkMask::FreeImage().
 */
using SkAutoMaskFreeImage = std::unique_ptr<uint8_t, SkFunctionObject<SkMaskBuilder::FreeImage>>;

#endif
