#include "SkKernel33MaskFilter.h"
#include "SkColorPriv.h"

SkMask::Format SkKernel33ProcMaskFilter::getFormat() {
    return SkMask::kA8_Format;
}

bool SkKernel33ProcMaskFilter::filterMask(SkMask* dst, const SkMask& src,
                                          const SkMatrix&, SkIPoint* margin) {
    // margin???
    dst->fImage = NULL;
    dst->fBounds = src.fBounds;
    dst->fBounds.inset(-1, -1);
    dst->fFormat = SkMask::kA8_Format;
    
    if (NULL == src.fImage) {
        return true;
    }
    
    dst->fRowBytes = dst->fBounds.width();
    size_t size = dst->computeImageSize();
    if (0 == size) {
        return false;   // too big to allocate, abort
    }
    dst->fImage = SkMask::AllocImage(size);
    
    const int h = src.fBounds.height();
    const int w = src.fBounds.width();
    const int srcRB = src.fRowBytes;
    const uint8_t* srcImage = src.fImage;
    uint8_t* dstImage = dst->fImage;

    uint8_t* srcRows[3];
    uint8_t storage[3][3];
    
    srcRows[0] = storage[0];
    srcRows[1] = storage[1];
    srcRows[2] = storage[2];

    unsigned scale = fPercent256;
    
    for (int y = -1; y <= h; y++) {
        uint8_t* dstRow = dstImage;
        for (int x = -1; x <= w; x++) {
            memset(storage, 0, sizeof(storage));
            uint8_t* storagePtr = &storage[0][0];

            for (int ky = y - 1; ky <= y + 1; ky++) {
                const uint8_t* srcRow = srcImage + ky * srcRB;  // may be out-of-range
                for (int kx = x - 1; kx <= x + 1; kx++) {
                    if ((unsigned)ky < (unsigned)h && (unsigned)kx < (unsigned)w) {
                        *storagePtr = srcRow[kx];
                    }
                    storagePtr++;
                }
            }            
            int value = this->computeValue(srcRows);
            
            if (scale < 256) {
                value = SkAlphaBlend(value, srcRows[1][1], scale);
            }
            *dstRow++ = SkToU8(value);
        }
        dstImage += dst->fRowBytes;
    }
    return true;
}

void SkKernel33ProcMaskFilter::flatten(SkFlattenableWriteBuffer& wb) {
    this->INHERITED::flatten(wb);
    wb.write32(fPercent256);
}

SkKernel33ProcMaskFilter::SkKernel33ProcMaskFilter(SkFlattenableReadBuffer& rb)
        : SkMaskFilter(rb) {
    fPercent256 = rb.readS32();
}

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

uint8_t SkKernel33MaskFilter::computeValue(uint8_t* const* srcRows) {
    int value = 0;

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            value += fKernel[i][j] * srcRows[i][j];
        }
    }
    
    value >>= fShift;

    if (value < 0) {
        value = 0;
    } else if (value > 255) {
        value = 255;
    }
    return (uint8_t)value;
}

void SkKernel33MaskFilter::flatten(SkFlattenableWriteBuffer& wb) {
    this->INHERITED::flatten(wb);
    wb.writeMul4(fKernel, 9 * sizeof(int));
    wb.write32(fShift);
}

SkFlattenable::Factory SkKernel33MaskFilter::getFactory() {
    return Create;
}

SkFlattenable* SkKernel33MaskFilter::Create(SkFlattenableReadBuffer& rb) {
    return new SkKernel33MaskFilter(rb);
}

SkKernel33MaskFilter::SkKernel33MaskFilter(SkFlattenableReadBuffer& rb)
        : SkKernel33ProcMaskFilter(rb) {
    rb.read(fKernel, 9 * sizeof(int));
    fShift = rb.readS32();
}

