
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SkKernel33MaskFilter.h"
#include "SkColorPriv.h"
#include "SkFlattenableBuffers.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) const {
    this->INHERITED::flatten(wb);
    wb.writeInt(fPercent256);
}

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

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

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) const {
    this->INHERITED::flatten(wb);
    wb.writeIntArray(&fKernel[0][0], 9);
    wb.writeInt(fShift);
}

SkKernel33MaskFilter::SkKernel33MaskFilter(SkFlattenableReadBuffer& rb)
        : SkKernel33ProcMaskFilter(rb) {
    const uint32_t count = rb.readIntArray(&fKernel[0][0]);
    SkASSERT(9 == count);
    fShift = rb.readInt();
}

