/*
 * 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.
 */

#include "src/core/SkBlitter_A8.h"

#include "include/core/SkBlendMode.h"
#include "include/core/SkColorType.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRect.h"
#include "include/core/SkShader.h" // IWYU pragma: keep
#include "include/core/SkTypes.h"
#include "include/private/base/SkDebug.h"
#include "src/base/SkArenaAlloc.h"
#include "src/core/SkDrawTypes.h"
#include "src/core/SkMask.h"

#include <cstring>
#include <optional>

SkA8_Coverage_Blitter::SkA8_Coverage_Blitter(const SkPixmap& device, const SkPaint& paint)
    : fDevice(device)
{
    SkASSERT(nullptr == paint.getShader());
    SkASSERT(nullptr == paint.getColorFilter());
}

void SkA8_Coverage_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
                                      const int16_t runs[]) {
    uint8_t* device = fDevice.writable_addr8(x, y);
    SkDEBUGCODE(int totalCount = 0;)

    for (;;) {
        int count = runs[0];
        SkASSERT(count >= 0);
        if (count == 0) {
            return;
        }
        if (antialias[0]) {
            memset(device, antialias[0], count);
        }
        runs += count;
        antialias += count;
        device += count;

        SkDEBUGCODE(totalCount += count;)
    }
    SkASSERT(fDevice.width() == totalCount);
}

void SkA8_Coverage_Blitter::blitH(int x, int y, int width) {
    memset(fDevice.writable_addr8(x, y), 0xFF, width);
}

void SkA8_Coverage_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
    if (0 == alpha) {
        return;
    }

    uint8_t* dst = fDevice.writable_addr8(x, y);
    const size_t dstRB = fDevice.rowBytes();
    while (--height >= 0) {
        *dst = alpha;
        dst += dstRB;
    }
}

void SkA8_Coverage_Blitter::blitRect(int x, int y, int width, int height) {
    uint8_t* dst = fDevice.writable_addr8(x, y);
    const size_t dstRB = fDevice.rowBytes();
    while (--height >= 0) {
        memset(dst, 0xFF, width);
        dst += dstRB;
    }
}

void SkA8_Coverage_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
    if (SkMask::kA8_Format != mask.fFormat) {
        this->SkBlitter::blitMask(mask, clip);
        return;
    }

    int x = clip.fLeft;
    int y = clip.fTop;
    int width = clip.width();
    int height = clip.height();

    uint8_t* dst = fDevice.writable_addr8(x, y);
    const uint8_t* src = mask.getAddr8(x, y);
    const size_t srcRB = mask.fRowBytes;
    const size_t dstRB = fDevice.rowBytes();

    while (--height >= 0) {
        memcpy(dst, src, width);
        dst += dstRB;
        src += srcRB;
    }
}

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

static inline uint8_t div255(unsigned prod) {
    SkASSERT(prod <= 255*255);
    return (prod + 128) * 257 >> 16;
}

static inline unsigned u8_lerp(uint8_t a, uint8_t b, uint8_t t) {
    return div255((255 - t) * a + t * b);
}

using AlphaProc = uint8_t(*)(uint8_t src, uint8_t dst);

static uint8_t srcover_p (uint8_t src, uint8_t dst) { return src + div255((255 - src) * dst); }
static uint8_t src_p     (uint8_t src, uint8_t dst) { return src; }

template <typename Mode> void A8_row_bw(uint8_t dst[], uint8_t src, int N, Mode proc) {
    for (int i = 0; i < N; ++i) {
        dst[i] = proc(src, dst[i]);
    }
}
using A8_RowBlitBW = void(*)(uint8_t[], uint8_t, int);

template <typename Mode>
void A8_row_aa(uint8_t dst[], uint8_t src, int N, uint8_t aa, Mode proc, const bool canFoldAA) {
    if (canFoldAA) {
        src = div255(src * aa);
        for (int i = 0; i < N; ++i) {
            dst[i] = proc(src, dst[i]);
        }
    } else {
        for (int i = 0; i < N; ++i) {
            dst[i] = u8_lerp(dst[i], proc(src, dst[i]), aa);
        }
    }
}
using A8_RowBlitAA = void(*)(uint8_t[], uint8_t, int, uint8_t aa);

#define WRAP_BLIT(proc, canFoldAA)                      \
    proc,                                               \
    [](uint8_t dst[], uint8_t src, int N)               \
      { A8_row_bw(dst, src, N, proc); },                \
    [](uint8_t dst[], uint8_t src, int N, uint8_t aa)   \
      { A8_row_aa(dst, src, N, aa, proc, canFoldAA); }

struct A8_RowBlitBWPair {
    SkBlendMode     mode;
    AlphaProc       oneProc;
    A8_RowBlitBW    bwProc;
    A8_RowBlitAA    aaProc;
};
constexpr A8_RowBlitBWPair gA8_RowBlitPairs[] = {
    {SkBlendMode::kSrcOver,  WRAP_BLIT(srcover_p,  true)},
    {SkBlendMode::kSrc,      WRAP_BLIT(src_p,      false)},
};
#undef WRAP_BLIT

static const A8_RowBlitBWPair* find_a8_rowproc_pair(SkBlendMode bm) {
    for (auto& pair : gA8_RowBlitPairs) {
        if (pair.mode == bm) {
            return &pair;
        }
    }
    return nullptr;
}

class SkA8_Blitter : public SkBlitter {
public:
    SkA8_Blitter(const SkPixmap& device, const SkPaint& paint);
    void blitH(int x, int y, int width) override;
    void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) override;
    void blitV(int x, int y, int height, SkAlpha alpha) override;
    void blitRect(int x, int y, int width, int height) override;
    void blitMask(const SkMask&, const SkIRect&) override;

private:
    const SkPixmap  fDevice;
    AlphaProc       fOneProc;
    A8_RowBlitBW    fBWProc;
    A8_RowBlitAA    fAAProc;
    SkAlpha         fSrc;

    using INHERITED = SkBlitter;
};

SkA8_Blitter::SkA8_Blitter(const SkPixmap& device,
                           const SkPaint& paint) : fDevice(device) {
    SkASSERT(nullptr == paint.getShader());
    SkASSERT(nullptr == paint.getColorFilter());
    auto mode = paint.asBlendMode();
    SkASSERT(mode);
    auto pair = find_a8_rowproc_pair(*mode);
    SkASSERT(pair);

    fOneProc = pair->oneProc;
    fBWProc  = pair->bwProc;
    fAAProc  = pair->aaProc;
    fSrc = paint.getAlpha();
}

void SkA8_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) {
    uint8_t* device = fDevice.writable_addr8(x, y);
    SkDEBUGCODE(int totalCount = 0;)

    for (;;) {
        int count = runs[0];
        SkASSERT(count >= 0);
        if (count == 0) {
            return;
        }

        if (antialias[0] == 0xFF) {
            fBWProc(device, fSrc, count);
        } else if (antialias[0] != 0) {
            fAAProc(device, fSrc, count, antialias[0]);
        }

        runs += count;
        antialias += count;
        device += count;

        SkDEBUGCODE(totalCount += count;)
    }
    SkASSERT(fDevice.width() == totalCount);
}

void SkA8_Blitter::blitH(int x, int y, int width) {
    fBWProc(fDevice.writable_addr8(x, y), fSrc, width);
}

void SkA8_Blitter::blitV(int x, int y, int height, SkAlpha aa) {
    uint8_t* device = fDevice.writable_addr8(x, y);
    const size_t dstRB = fDevice.rowBytes();

    if (aa == 0xFF) {
        while (--height >= 0) {
            *device = fOneProc(fSrc, *device);
            device += dstRB;
        }
    } else if (aa != 0) {
        while (--height >= 0) {
            fAAProc(device, fSrc, 1, aa);
            device += dstRB;
        }
    }
}

void SkA8_Blitter::blitRect(int x, int y, int width, int height) {
    uint8_t* device = fDevice.writable_addr8(x, y);
    const size_t dstRB = fDevice.rowBytes();

    while (--height >= 0) {
        fBWProc(device, fSrc, width);
        device += dstRB;
    }
}

void SkA8_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
    if (SkMask::kA8_Format != mask.fFormat) {
        this->INHERITED::blitMask(mask, clip);
        return;
    }

    int x = clip.fLeft;
    int y = clip.fTop;
    int width = clip.width();
    int height = clip.height();

    uint8_t* dst = fDevice.writable_addr8(x, y);
    const uint8_t* src = mask.getAddr8(x, y);
    const size_t srcRB = mask.fRowBytes;
    const size_t dstRB = fDevice.rowBytes();

    while (--height >= 0) {
        for (int i = 0; i < width; ++i) {
            dst[i] = u8_lerp(dst[i], fOneProc(fSrc, dst[i]), src[i]);
        }
        dst += dstRB;
        src += srcRB;
    }
}

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

SkBlitter* SkChooseA8Blitter(const SkPixmap& dst,
                             const SkMatrix& ctm,
                             const SkPaint& paint,
                             SkArenaAlloc* alloc,
                             SkDrawCoverage drawCoverage,
                             sk_sp<SkShader> clipShader) {
    if (dst.colorType() != SkColorType::kAlpha_8_SkColorType) {
        return nullptr;
    }
    if (paint.getShader() || paint.getColorFilter()) {
        return nullptr;
    }
    if (clipShader) {
        return nullptr; // would not be hard to support ...?
    }

    if (drawCoverage == SkDrawCoverage::kYes) {
        return alloc->make<SkA8_Coverage_Blitter>(dst, paint);
    } else {
        // we only support certain blendmodes...
        auto mode = paint.asBlendMode();
        if (mode && find_a8_rowproc_pair(*mode)) {
            return alloc->make<SkA8_Blitter>(dst, paint);
        }
    }
    return nullptr;
}

SkBlitter* SkA8Blitter_Choose(const SkPixmap& dst,
                              const SkMatrix& ctm,
                              const SkPaint& paint,
                              SkArenaAlloc* alloc,
                              SkDrawCoverage coverage,
                              sk_sp<SkShader> clipShader,
                              const SkSurfaceProps&,
                              const SkRect&) {
    return SkChooseA8Blitter(dst, ctm, paint, alloc, coverage, clipShader);
}
