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

#ifndef SkLinearBitmapPipeline_sampler_DEFINED
#define SkLinearBitmapPipeline_sampler_DEFINED

#include <tuple>

#include "SkColor.h"
#include "SkColorPriv.h"
#include "SkFixed.h"
#include "SkHalf.h"
#include "SkLinearBitmapPipeline_core.h"
#include "SkNx.h"
#include "SkPM4fPriv.h"

namespace {
// Explaination of the math:
//              1 - x      x
//           +--------+--------+
//           |        |        |
//  1 - y    |  px00  |  px10  |
//           |        |        |
//           +--------+--------+
//           |        |        |
//    y      |  px01  |  px11  |
//           |        |        |
//           +--------+--------+
//
//
// Given a pixelxy each is multiplied by a different factor derived from the fractional part of x
// and y:
// * px00 -> (1 - x)(1 - y) = 1 - x - y + xy
// * px10 -> x(1 - y) = x - xy
// * px01 -> (1 - x)y = y - xy
// * px11 -> xy
// So x * y is calculated first and then used to calculate all the other factors.
static Sk4s SK_VECTORCALL bilerp4(Sk4s xs, Sk4s ys, Sk4f px00, Sk4f px10,
                                                    Sk4f px01, Sk4f px11) {
    // Calculate fractional xs and ys.
    Sk4s fxs = xs - xs.floor();
    Sk4s fys = ys - ys.floor();
    Sk4s fxys{fxs * fys};
    Sk4f sum = px11 * fxys;
    sum = sum + px01 * (fys - fxys);
    sum = sum + px10 * (fxs - fxys);
    sum = sum + px00 * (Sk4f{1.0f} - fxs - fys + fxys);
    return sum;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// PixelGetter is the lowest level interface to the source data. There is a PixelConverter for each
// of the different SkColorTypes.
template <SkColorType, SkGammaType> class PixelConverter;

// Alpha handling:
//   The alpha from the paint (tintColor) is used in the blend part of the pipeline to modulate
// the entire bitmap. So, the tint color is given an alpha of 1.0 so that the later alpha can
// modulate this color later.
template <>
class PixelConverter<kAlpha_8_SkColorType, kLinear_SkGammaType> {
public:
    using Element = uint8_t;
    PixelConverter(const SkPixmap& srcPixmap, SkColor tintColor) {
        fTintColor = SkColor4f::FromColor(tintColor);
        fTintColor.fA = 1.0f;
    }

    Sk4f toSk4f(const Element pixel) const {
        return Sk4f::Load(&fTintColor) * (pixel * (1.0f/255.0f));
    }

private:
    SkColor4f fTintColor;
};

template <SkGammaType gammaType>
static inline Sk4f pmcolor_to_rgba(SkPMColor pixel) {
    return swizzle_rb_if_bgra(
            (gammaType == kSRGB_SkGammaType) ? Sk4f_fromS32(pixel)
                                             : Sk4f_fromL32(pixel));
}

template <SkGammaType gammaType>
class PixelConverter<kRGB_565_SkColorType, gammaType> {
public:
    using Element = uint16_t;
    PixelConverter(const SkPixmap& srcPixmap) { }

    Sk4f toSk4f(Element pixel) const {
        return pmcolor_to_rgba<gammaType>(SkPixel16ToPixel32(pixel));
    }
};

template <SkGammaType gammaType>
class PixelConverter<kARGB_4444_SkColorType, gammaType> {
public:
    using Element = uint16_t;
    PixelConverter(const SkPixmap& srcPixmap) { }

    Sk4f toSk4f(Element pixel) const {
        return pmcolor_to_rgba<gammaType>(SkPixel4444ToPixel32(pixel));
    }
};

template <SkGammaType gammaType>
class PixelConverter<kRGBA_8888_SkColorType, gammaType> {
public:
    using Element = uint32_t;
    PixelConverter(const SkPixmap& srcPixmap) { }

    Sk4f toSk4f(Element pixel) const {
        return gammaType == kSRGB_SkGammaType
               ? Sk4f_fromS32(pixel)
               : Sk4f_fromL32(pixel);
    }
};

template <SkGammaType gammaType>
class PixelConverter<kBGRA_8888_SkColorType, gammaType> {
public:
    using Element = uint32_t;
    PixelConverter(const SkPixmap& srcPixmap) { }

    Sk4f toSk4f(Element pixel) const {
        return swizzle_rb(
                   gammaType == kSRGB_SkGammaType ? Sk4f_fromS32(pixel) : Sk4f_fromL32(pixel));
    }
};

template <SkGammaType gammaType>
class PixelConverter<kIndex_8_SkColorType, gammaType> {
public:
    using Element = uint8_t;
    PixelConverter(const SkPixmap& srcPixmap)
    : fColorTableSize(srcPixmap.ctable()->count()){
        SkColorTable* skColorTable = srcPixmap.ctable();
        SkASSERT(skColorTable != nullptr);

        fColorTable = (Sk4f*)SkAlign16((intptr_t)fColorTableStorage.get());
        for (int i = 0; i < fColorTableSize; i++) {
            fColorTable[i] = pmcolor_to_rgba<gammaType>((*skColorTable)[i]);
        }
    }

    PixelConverter(const PixelConverter& strategy)
    : fColorTableSize{strategy.fColorTableSize}{
        fColorTable = (Sk4f*)SkAlign16((intptr_t)fColorTableStorage.get());
        for (int i = 0; i < fColorTableSize; i++) {
            fColorTable[i] = strategy.fColorTable[i];
        }
    }

    Sk4f toSk4f(Element index) const {
        return fColorTable[index];
    }

private:
    static const size_t kColorTableSize = sizeof(Sk4f[256]) + 12;
    const int           fColorTableSize;
    SkAutoMalloc        fColorTableStorage{kColorTableSize};
    Sk4f*               fColorTable;
};

template <SkGammaType gammaType>
class PixelConverter<kGray_8_SkColorType, gammaType> {
public:
    using Element = uint8_t;
    PixelConverter(const SkPixmap& srcPixmap) { }

    Sk4f toSk4f(Element pixel) const {
        float gray = (gammaType == kSRGB_SkGammaType)
            ? sk_linear_from_srgb[pixel]
            : pixel * (1/255.0f);
        return {gray, gray, gray, 1.0f};
    }
};

template <>
class PixelConverter<kRGBA_F16_SkColorType, kLinear_SkGammaType> {
public:
    using Element = uint64_t;
    PixelConverter(const SkPixmap& srcPixmap) { }

    Sk4f toSk4f(const Element pixel) const {
        return SkHalfToFloat_finite_ftz(pixel);
    }
};

class PixelAccessorShim {
public:
    explicit PixelAccessorShim(SkLinearBitmapPipeline::PixelAccessorInterface* accessor)
        : fPixelAccessor(accessor) { }

    void SK_VECTORCALL getFewPixels(
        int n, Sk4i xs, Sk4i ys, Sk4f* px0, Sk4f* px1, Sk4f* px2) const {
        fPixelAccessor->getFewPixels(n, xs, ys, px0, px1, px2);
    }

    void SK_VECTORCALL get4Pixels(
        Sk4i xs, Sk4i ys, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* px3) const {
        fPixelAccessor->get4Pixels(xs, ys, px0, px1, px2, px3);
    }

    void get4Pixels(
        const void* src, int index, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* px3) const {
        fPixelAccessor->get4Pixels(src, index, px0, px1, px2, px3);
    }

    Sk4f getPixelFromRow(const void* row, int index) const {
        return fPixelAccessor->getPixelFromRow(row, index);
    }

    Sk4f getPixelAt(int index) const {
        return fPixelAccessor->getPixelAt(index);
    }

    const void* row(int y) const {
        return fPixelAccessor->row(y);
    }

private:
    SkLinearBitmapPipeline::PixelAccessorInterface* const fPixelAccessor;
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// PixelAccessor handles all the same plumbing for all the PixelGetters.
template <SkColorType colorType, SkGammaType gammaType>
class PixelAccessor final : public SkLinearBitmapPipeline::PixelAccessorInterface {
    using Element = typename PixelConverter<colorType, gammaType>::Element;
public:
    template <typename... Args>
    PixelAccessor(const SkPixmap& srcPixmap, Args&&... args)
        : fSrc{static_cast<const Element*>(srcPixmap.addr())}
        , fWidth{srcPixmap.rowBytesAsPixels()}
        , fConverter{srcPixmap, std::move<Args>(args)...} { }

    void SK_VECTORCALL getFewPixels (
        int n, Sk4i xs, Sk4i ys, Sk4f* px0, Sk4f* px1, Sk4f* px2) const override {
        Sk4i bufferLoc = ys * fWidth + xs;
        switch (n) {
            case 3:
                *px2 = this->getPixelAt(bufferLoc[2]);
            case 2:
                *px1 = this->getPixelAt(bufferLoc[1]);
            case 1:
                *px0 = this->getPixelAt(bufferLoc[0]);
            default:
                break;
        }
    }

    void SK_VECTORCALL get4Pixels(
        Sk4i xs, Sk4i ys, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* px3) const override {
        Sk4i bufferLoc = ys * fWidth + xs;
        *px0 = this->getPixelAt(bufferLoc[0]);
        *px1 = this->getPixelAt(bufferLoc[1]);
        *px2 = this->getPixelAt(bufferLoc[2]);
        *px3 = this->getPixelAt(bufferLoc[3]);
    }

    void get4Pixels(
        const void* src, int index, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* px3) const override {
        *px0 = this->getPixelFromRow(src, index + 0);
        *px1 = this->getPixelFromRow(src, index + 1);
        *px2 = this->getPixelFromRow(src, index + 2);
        *px3 = this->getPixelFromRow(src, index + 3);
    }

    Sk4f getPixelFromRow(const void* row, int index) const override {
        const Element* src = static_cast<const Element*>(row);
        return fConverter.toSk4f(src[index]);
    }

    Sk4f getPixelAt(int index) const override {
        return this->getPixelFromRow(fSrc, index);
    }

    const void* row(int y) const override { return fSrc + y * fWidth; }

private:
    const Element* const                 fSrc;
    const int                            fWidth;
    PixelConverter<colorType, gammaType> fConverter;
};

// We're moving through source space at a rate of 1 source pixel per 1 dst pixel.
// We'll never re-use pixels, but we can at least load contiguous pixels.
template <typename Next, typename Strategy>
static void src_strategy_blend(Span span, Next* next, Strategy* strategy) {
    SkPoint start;
    SkScalar length;
    int count;
    std::tie(start, length, count) = span;
    int ix = SkScalarFloorToInt(X(start));
    const void* row = strategy->row((int)std::floor(Y(start)));
    if (length > 0) {
        while (count >= 4) {
            Sk4f px0, px1, px2, px3;
            strategy->get4Pixels(row, ix, &px0, &px1, &px2, &px3);
            next->blend4Pixels(px0, px1, px2, px3);
            ix += 4;
            count -= 4;
        }

        while (count > 0) {
            next->blendPixel(strategy->getPixelFromRow(row, ix));
            ix += 1;
            count -= 1;
        }
    } else {
        while (count >= 4) {
            Sk4f px0, px1, px2, px3;
            strategy->get4Pixels(row, ix - 3, &px3, &px2, &px1, &px0);
            next->blend4Pixels(px0, px1, px2, px3);
            ix -= 4;
            count -= 4;
        }

        while (count > 0) {
            next->blendPixel(strategy->getPixelFromRow(row, ix));
            ix -= 1;
            count -= 1;
        }
    }
}

// -- NearestNeighborSampler -----------------------------------------------------------------------
// NearestNeighborSampler - use nearest neighbor filtering to create runs of destination pixels.
template<typename Accessor, typename Next>
class NearestNeighborSampler : public SkLinearBitmapPipeline::SampleProcessorInterface {
public:
    template<typename... Args>
    NearestNeighborSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next, Args&& ... args)
    : fNext{next}, fAccessor{std::forward<Args>(args)...} { }

    NearestNeighborSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next,
    const NearestNeighborSampler& sampler)
    : fNext{next}, fAccessor{sampler.fAccessor} { }

    void SK_VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override {
        SkASSERT(0 < n && n < 4);
        Sk4f px0, px1, px2;
        fAccessor.getFewPixels(n, SkNx_cast<int>(xs), SkNx_cast<int>(ys), &px0, &px1, &px2);
        if (n >= 1) fNext->blendPixel(px0);
        if (n >= 2) fNext->blendPixel(px1);
        if (n >= 3) fNext->blendPixel(px2);
    }

    void SK_VECTORCALL pointList4(Sk4s xs, Sk4s ys) override {
        Sk4f px0, px1, px2, px3;
        fAccessor.get4Pixels(SkNx_cast<int>(xs), SkNx_cast<int>(ys), &px0, &px1, &px2, &px3);
        fNext->blend4Pixels(px0, px1, px2, px3);
    }

    void pointSpan(Span span) override {
        SkASSERT(!span.isEmpty());
        SkPoint start;
        SkScalar length;
        int count;
        std::tie(start, length, count) = span;
        SkScalar absLength = SkScalarAbs(length);
        if (absLength < (count - 1)) {
            this->spanSlowRate(span);
        } else if (absLength == (count - 1)) {
            src_strategy_blend(span, fNext, &fAccessor);
        } else {
            this->spanFastRate(span);
        }
    }

    void repeatSpan(Span span, int32_t repeatCount) override {
        while (repeatCount > 0) {
            this->pointSpan(span);
            repeatCount--;
        }
    }

private:
    // When moving through source space more slowly than dst space (zoomed in),
    // we'll be sampling from the same source pixel more than once.
    void spanSlowRate(Span span) {
        SkPoint start; SkScalar length; int count;
        std::tie(start, length, count) = span;
        SkScalar x = X(start);
        SkFixed fx = SkScalarToFixed(x);
        SkScalar dx = length / (count - 1);
        SkFixed fdx = SkScalarToFixed(dx);

        const void* row = fAccessor.row((int)std::floor(Y(start)));
        Next* next = fNext;

        int ix = SkFixedFloorToInt(fx);
        int prevIX = ix;
        Sk4f fpixel = fAccessor.getPixelFromRow(row, ix);

        // When dx is less than one, each pixel is used more than once. Using the fixed point fx
        // allows the code to quickly check that the same pixel is being used. The code uses this
        // same pixel check to do the sRGB and normalization only once.
        auto getNextPixel = [&]() {
            if (ix != prevIX) {
                fpixel = fAccessor.getPixelFromRow(row, ix);
                prevIX = ix;
            }
            fx += fdx;
            ix = SkFixedFloorToInt(fx);
            return fpixel;
        };

        while (count >= 4) {
            Sk4f px0 = getNextPixel();
            Sk4f px1 = getNextPixel();
            Sk4f px2 = getNextPixel();
            Sk4f px3 = getNextPixel();
            next->blend4Pixels(px0, px1, px2, px3);
            count -= 4;
        }
        while (count > 0) {
            next->blendPixel(getNextPixel());
            count -= 1;
        }
    }

    // We're moving through source space at a rate of 1 source pixel per 1 dst pixel.
    // We'll never re-use pixels, but we can at least load contiguous pixels.
    void spanUnitRate(Span span) {
        src_strategy_blend(span, fNext, &fAccessor);
    }

    // We're moving through source space faster than dst (zoomed out),
    // so we'll never reuse a source pixel or be able to do contiguous loads.
    void spanFastRate(Span span) {
        span_fallback(span, this);
    }

    Next* const fNext;
    Accessor    fAccessor;
};

// From an edgeType, the integer value of a pixel vs, and the integer value of the extreme edge
// vMax, take the point which might be off the tile by one pixel and either wrap it or pin it to
// generate the right pixel. The value vs is on the interval [-1, vMax + 1]. It produces a value
// on the interval [0, vMax].
// Note: vMax is not width or height, but width-1 or height-1 because it is the largest valid pixel.
static inline int adjust_edge(SkShader::TileMode edgeType, int vs, int vMax) {
    SkASSERT(-1 <= vs && vs <= vMax + 1);
    switch (edgeType) {
        case SkShader::kClamp_TileMode:
        case SkShader::kMirror_TileMode:
            vs = std::max(vs, 0);
            vs = std::min(vs, vMax);
            break;
        case SkShader::kRepeat_TileMode:
            vs = (vs <= vMax) ? vs : 0;
            vs =    (vs >= 0) ? vs : vMax;
            break;
    }
    SkASSERT(0 <= vs && vs <= vMax);
    return vs;
}

// From a sample point on the tile, return the top or left filter value.
// The result r should be in the range (0, 1]. Since this represents the weight given to the top
// left element, then if x == 0.5 the filter value should be 1.0.
// The input sample point must be on the tile, therefore it must be >= 0.
static SkScalar sample_to_filter(SkScalar x) {
    SkASSERT(x >= 0.0f);
    // The usual form of the top or left edge is x - .5, but since we are working on the unit
    // square, then x + .5 works just as well. This also guarantees that v > 0.0 allowing the use
    // of trunc.
    SkScalar v = x + 0.5f;
    // Produce the top or left offset a value on the range [0, 1).
    SkScalar f = v - SkScalarTruncToScalar(v);
    // Produce the filter value which is on the range (0, 1].
    SkScalar r =  1.0f - f;
    SkASSERT(0.0f < r && r <= 1.0f);
    return r;
}

// -- BilerpSampler --------------------------------------------------------------------------------
// BilerpSampler - use a bilerp filter to create runs of destination pixels.
// Note: in the code below, there are two types of points
//       * sample points - these are the points passed in by pointList* and Spans.
//       * filter points - are created from a sample point to form the coordinates of the points
//                         to use in the filter and to generate the filter values.
template<typename Accessor, typename Next>
class BilerpSampler : public SkLinearBitmapPipeline::SampleProcessorInterface {
public:
    template<typename... Args>
    BilerpSampler(
        SkLinearBitmapPipeline::BlendProcessorInterface* next,
        SkISize dimensions,
        SkShader::TileMode xTile, SkShader::TileMode yTile,
        Args&& ... args
    )
        : fNext{next}
        , fXEdgeType{xTile}
        , fXMax{dimensions.width() - 1}
        , fYEdgeType{yTile}
        , fYMax{dimensions.height() - 1}
        , fAccessor{std::forward<Args>(args)...} { }

    BilerpSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next,
                   const BilerpSampler& sampler)
        : fNext{next}
        , fXEdgeType{sampler.fXEdgeType}
        , fXMax{sampler.fXMax}
        , fYEdgeType{sampler.fYEdgeType}
        , fYMax{sampler.fYMax}
        , fAccessor{sampler.fAccessor} { }

    void SK_VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override {
        SkASSERT(0 < n && n < 4);
        auto bilerpPixel = [&](int index) {
            return this->bilerpSamplePoint(SkPoint{xs[index], ys[index]});
        };

        if (n >= 1) fNext->blendPixel(bilerpPixel(0));
        if (n >= 2) fNext->blendPixel(bilerpPixel(1));
        if (n >= 3) fNext->blendPixel(bilerpPixel(2));
    }

    void SK_VECTORCALL pointList4(Sk4s xs, Sk4s ys) override {
        auto bilerpPixel = [&](int index) {
            return this->bilerpSamplePoint(SkPoint{xs[index], ys[index]});
        };
        fNext->blend4Pixels(bilerpPixel(0), bilerpPixel(1), bilerpPixel(2), bilerpPixel(3));
    }

    void pointSpan(Span span) override {
        SkASSERT(!span.isEmpty());
        SkPoint start;
        SkScalar length;
        int count;
        std::tie(start, length, count) = span;

        // Nothing to do.
        if (count == 0) {
            return;
        }

        // Trivial case. No sample points are generated other than start.
        if (count == 1) {
            fNext->blendPixel(this->bilerpSamplePoint(start));
            return;
        }

        // Note: the following code could be done in terms of dx = length / (count -1), but that
        // would introduce a divide that is not needed for the most common dx == 1 cases.
        SkScalar absLength = SkScalarAbs(length);
        if (absLength == 0.0f) {
            // |dx| == 0
            // length is zero, so clamp an edge pixel.
            this->spanZeroRate(span);
        } else if (absLength < (count - 1)) {
            // 0 < |dx| < 1.
            this->spanSlowRate(span);
        } else if (absLength == (count - 1)) {
            // |dx| == 1.
            if (sample_to_filter(span.startX()) == 1.0f
                && sample_to_filter(span.startY()) == 1.0f) {
                // All the pixels are aligned with the dest; go fast.
                src_strategy_blend(span, fNext, &fAccessor);
            } else {
                // There is some sub-pixel offsets, so bilerp.
                this->spanUnitRate(span);
            }
        } else if (absLength < 2.0f * (count - 1)) {
            // 1 < |dx| < 2.
            this->spanMediumRate(span);
        } else {
            // |dx| >= 2.
            this->spanFastRate(span);
        }
    }

    void repeatSpan(Span span, int32_t repeatCount) override {
        while (repeatCount > 0) {
            this->pointSpan(span);
            repeatCount--;
        }
    }

private:

    // Convert a sample point to the points used by the filter.
    void filterPoints(SkPoint sample, Sk4i* filterXs, Sk4i* filterYs) {
        // May be less than zero. Be careful to use Floor.
        int x0 = adjust_edge(fXEdgeType, SkScalarFloorToInt(X(sample) - 0.5), fXMax);
        // Always greater than zero. Use the faster Trunc.
        int x1 = adjust_edge(fXEdgeType, SkScalarTruncToInt(X(sample) + 0.5), fXMax);
        int y0 = adjust_edge(fYEdgeType, SkScalarFloorToInt(Y(sample) - 0.5), fYMax);
        int y1 = adjust_edge(fYEdgeType, SkScalarTruncToInt(Y(sample) + 0.5), fYMax);

        *filterXs = Sk4i{x0, x1, x0, x1};
        *filterYs = Sk4i{y0, y0, y1, y1};
    }

    // Given a sample point, generate a color by bilerping the four filter points.
    Sk4f bilerpSamplePoint(SkPoint sample) {
        Sk4i iXs, iYs;
        filterPoints(sample, &iXs, &iYs);
        Sk4f px00, px10, px01, px11;
        fAccessor.get4Pixels(iXs, iYs, &px00, &px10, &px01, &px11);
        return bilerp4(Sk4f{X(sample) - 0.5f}, Sk4f{Y(sample) - 0.5f}, px00, px10, px01, px11);
    }

    // Get two pixels at x from row0 and row1.
    void get2PixelColumn(const void* row0, const void* row1, int x, Sk4f* px0, Sk4f* px1) {
        *px0 = fAccessor.getPixelFromRow(row0, x);
        *px1 = fAccessor.getPixelFromRow(row1, x);
    }

    // |dx| == 0. This code assumes that length is zero.
    void spanZeroRate(Span span) {
        SkPoint start; SkScalar length; int count;
        std::tie(start, length, count) = span;
        SkASSERT(length == 0.0f);

        // Filter for the blending of the top and bottom pixels.
        SkScalar filterY = sample_to_filter(Y(start));

        // Generate the four filter points from the sample point start. Generate the row* values.
        Sk4i iXs, iYs;
        this->filterPoints(start, &iXs, &iYs);
        const void* const row0 = fAccessor.row(iYs[0]);
        const void* const row1 = fAccessor.row(iYs[2]);

        // Get the two pixels that make up the clamping pixel.
        Sk4f pxTop, pxBottom;
        this->get2PixelColumn(row0, row1, SkScalarFloorToInt(X(start)), &pxTop, &pxBottom);
        Sk4f pixel = pxTop * filterY + (1.0f - filterY) * pxBottom;

        while (count >= 4) {
            fNext->blend4Pixels(pixel, pixel, pixel, pixel);
            count -= 4;
        }
        while (count > 0) {
            fNext->blendPixel(pixel);
            count -= 1;
        }
    }

    // 0 < |dx| < 1. This code reuses the calculations from previous pixels to reduce
    // computation. In particular, several destination pixels maybe generated from the same four
    // source pixels.
    // In the following code a "part" is a combination of two pixels from the same column of the
    // filter.
    void spanSlowRate(Span span) {
        SkPoint start; SkScalar length; int count;
        std::tie(start, length, count) = span;

        // Calculate the distance between each sample point.
        const SkScalar dx = length / (count - 1);
        SkASSERT(-1.0f < dx && dx < 1.0f && dx != 0.0f);

        // Generate the filter values for the top-left corner.
        // Note: these values are in filter space; this has implications about how to adjust
        // these values at each step. For example, as the sample point increases, the filter
        // value decreases, this is because the filter and position are related by
        // (1 - (X(sample) - .5)) % 1. The (1 - stuff) causes the filter to move in the opposite
        // direction of the sample point which is increasing by dx.
        SkScalar filterX = sample_to_filter(X(start));
        SkScalar filterY = sample_to_filter(Y(start));

        // Generate the four filter points from the sample point start. Generate the row* values.
        Sk4i iXs, iYs;
        this->filterPoints(start, &iXs, &iYs);
        const void* const row0 = fAccessor.row(iYs[0]);
        const void* const row1 = fAccessor.row(iYs[2]);

        // Generate part of the filter value at xColumn.
        auto partAtColumn = [&](int xColumn) {
            int adjustedColumn = adjust_edge(fXEdgeType, xColumn, fXMax);
            Sk4f pxTop, pxBottom;
            this->get2PixelColumn(row0, row1, adjustedColumn, &pxTop, &pxBottom);
            return pxTop * filterY + (1.0f - filterY) * pxBottom;
        };

        // The leftPart is made up of two pixels from the left column of the filter, right part
        // is similar. The top and bottom pixels in the *Part are created as a linear blend of
        // the top and bottom pixels using filterY. See the partAtColumn function above.
        Sk4f leftPart  = partAtColumn(iXs[0]);
        Sk4f rightPart = partAtColumn(iXs[1]);

        // Create a destination color by blending together a left and right part using filterX.
        auto bilerp = [&](const Sk4f& leftPart, const Sk4f& rightPart) {
            Sk4f pixel = leftPart * filterX + rightPart * (1.0f - filterX);
            return check_pixel(pixel);
        };

        // Send the first pixel to the destination. This simplifies the loop structure so that no
        // extra pixels are fetched for the last iteration of the loop.
        fNext->blendPixel(bilerp(leftPart, rightPart));
        count -= 1;

        if (dx > 0.0f) {
            // * positive direction - generate destination pixels by sliding the filter from left
            //                        to right.
            int rightPartCursor = iXs[1];

            // Advance the filter from left to right. Remember that moving the top-left corner of
            // the filter to the right actually makes the filter value smaller.
            auto advanceFilter = [&]() {
                filterX -= dx;
                if (filterX <= 0.0f) {
                    filterX += 1.0f;
                    leftPart = rightPart;
                    rightPartCursor += 1;
                    rightPart = partAtColumn(rightPartCursor);
                }
                SkASSERT(0.0f < filterX && filterX <= 1.0f);

                return bilerp(leftPart, rightPart);
            };

            while (count >= 4) {
                Sk4f px0 = advanceFilter(),
                     px1 = advanceFilter(),
                     px2 = advanceFilter(),
                     px3 = advanceFilter();
                fNext->blend4Pixels(px0, px1, px2, px3);
                count -= 4;
            }

            while (count > 0) {
                fNext->blendPixel(advanceFilter());
                count -= 1;
            }
        } else {
            // * negative direction - generate destination pixels by sliding the filter from
            //                        right to left.
            int leftPartCursor = iXs[0];

            // Advance the filter from right to left. Remember that moving the top-left corner of
            // the filter to the left actually makes the filter value larger.
            auto advanceFilter = [&]() {
                // Remember, dx < 0 therefore this adds |dx| to filterX.
                filterX -= dx;
                // At this point filterX may be > 1, and needs to be wrapped back on to the filter
                // interval, and the next column in the filter is calculated.
                if (filterX > 1.0f) {
                    filterX -= 1.0f;
                    rightPart = leftPart;
                    leftPartCursor -= 1;
                    leftPart = partAtColumn(leftPartCursor);
                }
                SkASSERT(0.0f < filterX && filterX <= 1.0f);

                return bilerp(leftPart, rightPart);
            };

            while (count >= 4) {
                Sk4f px0 = advanceFilter(),
                     px1 = advanceFilter(),
                     px2 = advanceFilter(),
                     px3 = advanceFilter();
                fNext->blend4Pixels(px0, px1, px2, px3);
                count -= 4;
            }

            while (count > 0) {
                fNext->blendPixel(advanceFilter());
                count -= 1;
            }
        }
    }

    // |dx| == 1. Moving through source space at a rate of 1 source pixel per 1 dst pixel.
    // Every filter part is used for two destination pixels, and the code can bulk load four
    // pixels at a time.
    void spanUnitRate(Span span) {
        SkPoint start; SkScalar length; int count;
        std::tie(start, length, count) = span;
        SkASSERT(SkScalarAbs(length) == (count - 1));

        // Calculate the four filter points of start, and use the two different Y values to
        // generate the row pointers.
        Sk4i iXs, iYs;
        filterPoints(start, &iXs, &iYs);
        const void* row0 = fAccessor.row(iYs[0]);
        const void* row1 = fAccessor.row(iYs[2]);

        // Calculate the filter values for the top-left filter element.
        const SkScalar filterX = sample_to_filter(X(start));
        const SkScalar filterY = sample_to_filter(Y(start));

        // Generate part of the filter value at xColumn.
        auto partAtColumn = [&](int xColumn) {
            int adjustedColumn = adjust_edge(fXEdgeType, xColumn, fXMax);
            Sk4f pxTop, pxBottom;
            this->get2PixelColumn(row0, row1, adjustedColumn, &pxTop, &pxBottom);
            return pxTop * filterY + (1.0f - filterY) * pxBottom;
        };

        auto get4Parts = [&](int ix, Sk4f* part0, Sk4f* part1, Sk4f* part2, Sk4f* part3) {
            // Check if the pixels needed are near the edges. If not go fast using bulk pixels,
            // otherwise be careful.
            if (0 <= ix && ix <= fXMax - 3) {
                Sk4f px00, px10, px20, px30,
                     px01, px11, px21, px31;
                fAccessor.get4Pixels(row0, ix, &px00, &px10, &px20, &px30);
                fAccessor.get4Pixels(row1, ix, &px01, &px11, &px21, &px31);
                *part0 = filterY * px00 + (1.0f - filterY) * px01;
                *part1 = filterY * px10 + (1.0f - filterY) * px11;
                *part2 = filterY * px20 + (1.0f - filterY) * px21;
                *part3 = filterY * px30 + (1.0f - filterY) * px31;
            } else {
                *part0 = partAtColumn(ix + 0);
                *part1 = partAtColumn(ix + 1);
                *part2 = partAtColumn(ix + 2);
                *part3 = partAtColumn(ix + 3);
            }
        };

        auto bilerp = [&](const Sk4f& part0, const Sk4f& part1) {
            return part0 * filterX + part1 * (1.0f - filterX);
        };

        if (length > 0) {
            // * positive direction - generate destination pixels by sliding the filter from left
            //                        to right.

            // overlapPart is the filter part from the end of the previous four pixels used at
            // the start of the next four pixels.
            Sk4f overlapPart = partAtColumn(iXs[0]);
            int rightColumnCursor = iXs[1];
            while (count >= 4) {
                Sk4f part0, part1, part2, part3;
                get4Parts(rightColumnCursor, &part0, &part1, &part2, &part3);
                Sk4f px0 = bilerp(overlapPart, part0);
                Sk4f px1 = bilerp(part0, part1);
                Sk4f px2 = bilerp(part1, part2);
                Sk4f px3 = bilerp(part2, part3);
                overlapPart = part3;
                fNext->blend4Pixels(px0, px1, px2, px3);
                rightColumnCursor += 4;
                count -= 4;
            }

            while (count > 0) {
                Sk4f rightPart = partAtColumn(rightColumnCursor);

                fNext->blendPixel(bilerp(overlapPart, rightPart));
                overlapPart = rightPart;
                rightColumnCursor += 1;
                count -= 1;
            }
        } else {
            // * negative direction - generate destination pixels by sliding the filter from
            //                        right to left.
            Sk4f overlapPart = partAtColumn(iXs[1]);
            int leftColumnCursor = iXs[0];

            while (count >= 4) {
                Sk4f part0, part1, part2, part3;
                get4Parts(leftColumnCursor - 3, &part3, &part2, &part1, &part0);
                Sk4f px0 = bilerp(part0, overlapPart);
                Sk4f px1 = bilerp(part1, part0);
                Sk4f px2 = bilerp(part2, part1);
                Sk4f px3 = bilerp(part3, part2);
                overlapPart = part3;
                fNext->blend4Pixels(px0, px1, px2, px3);
                leftColumnCursor -= 4;
                count -= 4;
            }

            while (count > 0) {
                Sk4f leftPart = partAtColumn(leftColumnCursor);

                fNext->blendPixel(bilerp(leftPart, overlapPart));
                overlapPart = leftPart;
                leftColumnCursor -= 1;
                count -= 1;
            }
        }
    }

    // 1 < |dx| < 2. Going through the source pixels at a faster rate than the dest pixels, but
    // still slow enough to take advantage of previous calculations.
    void spanMediumRate(Span span) {
        SkPoint start; SkScalar length; int count;
        std::tie(start, length, count) = span;

        // Calculate the distance between each sample point.
        const SkScalar dx = length / (count - 1);
        SkASSERT((-2.0f < dx && dx < -1.0f) || (1.0f < dx && dx < 2.0f));

        // Generate the filter values for the top-left corner.
        // Note: these values are in filter space; this has implications about how to adjust
        // these values at each step. For example, as the sample point increases, the filter
        // value decreases, this is because the filter and position are related by
        // (1 - (X(sample) - .5)) % 1. The (1 - stuff) causes the filter to move in the opposite
        // direction of the sample point which is increasing by dx.
        SkScalar filterX = sample_to_filter(X(start));
        SkScalar filterY = sample_to_filter(Y(start));

        // Generate the four filter points from the sample point start. Generate the row* values.
        Sk4i iXs, iYs;
        this->filterPoints(start, &iXs, &iYs);
        const void* const row0 = fAccessor.row(iYs[0]);
        const void* const row1 = fAccessor.row(iYs[2]);

        // Generate part of the filter value at xColumn.
        auto partAtColumn = [&](int xColumn) {
            int adjustedColumn = adjust_edge(fXEdgeType, xColumn, fXMax);
            Sk4f pxTop, pxBottom;
            this->get2PixelColumn(row0, row1, adjustedColumn, &pxTop, &pxBottom);
            return pxTop * filterY + (1.0f - filterY) * pxBottom;
        };

        // The leftPart is made up of two pixels from the left column of the filter, right part
        // is similar. The top and bottom pixels in the *Part are created as a linear blend of
        // the top and bottom pixels using filterY. See the nextPart function below.
        Sk4f leftPart  = partAtColumn(iXs[0]);
        Sk4f rightPart = partAtColumn(iXs[1]);

        // Create a destination color by blending together a left and right part using filterX.
        auto bilerp = [&](const Sk4f& leftPart, const Sk4f& rightPart) {
            Sk4f pixel = leftPart * filterX + rightPart * (1.0f - filterX);
            return check_pixel(pixel);
        };

        // Send the first pixel to the destination. This simplifies the loop structure so that no
        // extra pixels are fetched for the last iteration of the loop.
        fNext->blendPixel(bilerp(leftPart, rightPart));
        count -= 1;

        if (dx > 0.0f) {
            // * positive direction - generate destination pixels by sliding the filter from left
            //                        to right.
            int rightPartCursor = iXs[1];

            // Advance the filter from left to right. Remember that moving the top-left corner of
            // the filter to the right actually makes the filter value smaller.
            auto advanceFilter = [&]() {
                filterX -= dx;
                // At this point filterX is less than zero, but might actually be less than -1.
                if (filterX > -1.0f) {
                    filterX += 1.0f;
                    leftPart = rightPart;
                    rightPartCursor += 1;
                    rightPart = partAtColumn(rightPartCursor);
                } else {
                    filterX += 2.0f;
                    rightPartCursor += 2;
                    leftPart = partAtColumn(rightPartCursor - 1);
                    rightPart = partAtColumn(rightPartCursor);
                }
                SkASSERT(0.0f < filterX && filterX <= 1.0f);

                return bilerp(leftPart, rightPart);
            };

            while (count >= 4) {
                Sk4f px0 = advanceFilter(),
                     px1 = advanceFilter(),
                     px2 = advanceFilter(),
                     px3 = advanceFilter();
                fNext->blend4Pixels(px0, px1, px2, px3);
                count -= 4;
            }

            while (count > 0) {
                fNext->blendPixel(advanceFilter());
                count -= 1;
            }
        } else {
            // * negative direction - generate destination pixels by sliding the filter from
            //                        right to left.
            int leftPartCursor = iXs[0];

            auto advanceFilter = [&]() {
                // Remember, dx < 0 therefore this adds |dx| to filterX.
                filterX -= dx;
                // At this point, filterX is greater than one, but may actually be greater than two.
                if (filterX < 2.0f) {
                    filterX -= 1.0f;
                    rightPart = leftPart;
                    leftPartCursor -= 1;
                    leftPart = partAtColumn(leftPartCursor);
                } else {
                    filterX -= 2.0f;
                    leftPartCursor -= 2;
                    rightPart = partAtColumn(leftPartCursor - 1);
                    leftPart = partAtColumn(leftPartCursor);
                }
                SkASSERT(0.0f < filterX && filterX <= 1.0f);
                return bilerp(leftPart, rightPart);
            };

            while (count >= 4) {
                Sk4f px0 = advanceFilter(),
                     px1 = advanceFilter(),
                     px2 = advanceFilter(),
                     px3 = advanceFilter();
                fNext->blend4Pixels(px0, px1, px2, px3);
                count -= 4;
            }

            while (count > 0) {
                fNext->blendPixel(advanceFilter());
                count -= 1;
            }
        }
    }

    // We're moving through source space faster than dst (zoomed out),
    // so we'll never reuse a source pixel or be able to do contiguous loads.
    void spanFastRate(Span span) {
        SkPoint start; SkScalar length; int count;
        std::tie(start, length, count) = span;
        SkScalar x = X(start);
        SkScalar y = Y(start);

        SkScalar dx = length / (count - 1);
        while (count > 0) {
            fNext->blendPixel(this->bilerpSamplePoint(SkPoint{x, y}));
            x += dx;
            count -= 1;
        }
    }

    Next* const              fNext;
    const SkShader::TileMode fXEdgeType;
    const int                fXMax;
    const SkShader::TileMode fYEdgeType;
    const int                fYMax;
    Accessor                 fAccessor;
};

}  // namespace

#endif  // SkLinearBitmapPipeline_sampler_DEFINED
