/* * 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 "SkFilterProc.h" class BILERP_BITMAP16_SHADER_CLASS : public HasSpan16_Sampler_BitmapShader { public: BILERP_BITMAP16_SHADER_CLASS(const SkBitmap& src) : HasSpan16_Sampler_BitmapShader(src, true, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode) { } virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) { SkASSERT(count > 0); U8CPU alpha = this->getPaintAlpha(); const SkMatrix& inv = this->getTotalInverse(); const SkBitmap& srcBitmap = this->getSrcBitmap(); unsigned srcMaxX = srcBitmap.width() - 1; unsigned srcMaxY = srcBitmap.height() - 1; unsigned srcRB = srcBitmap.rowBytes(); BILERP_BITMAP16_SHADER_PREAMBLE(srcBitmap); const SkFilterProc* proc_table = SkGetBilinearFilterProcTable(); const BILERP_BITMAP16_SHADER_TYPE* srcPixels = (const BILERP_BITMAP16_SHADER_TYPE*)srcBitmap.getPixels(); if (this->getInverseClass() == kPerspective_MatrixClass) { SkPerspIter iter(inv, SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf, count); while ((count = iter.next()) != 0) { const SkFixed* srcXY = iter.getXY(); while (--count >= 0) { SkFixed fx = *srcXY++ - SK_FixedHalf; SkFixed fy = *srcXY++ - SK_FixedHalf; int ix = fx >> 16; int iy = fy >> 16; int x = SkClampMax(ix, srcMaxX); int y = SkClampMax(iy, srcMaxY); const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11; p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels + y * srcRB)) + x; if ((unsigned)ix < srcMaxX) p01 += 1; p10 = p00; p11 = p01; if ((unsigned)iy < srcMaxY) { p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB); p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB); } SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy); uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)), SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)), SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)), SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11))); *dstC++ = expanded_rgb16_to_8888(c, alpha); } } } else // linear case { SkFixed fx, fy, dx, dy; // now init fx, fy, dx, dy { SkPoint srcPt; this->getInverseMapPtProc()(inv, SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf, &srcPt); fx = SkScalarToFixed(srcPt.fX) - SK_FixedHalf; fy = SkScalarToFixed(srcPt.fY) - SK_FixedHalf; if (this->getInverseClass() == kFixedStepInX_MatrixClass) (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy); else { dx = SkScalarToFixed(inv.getScaleX()); dy = SkScalarToFixed(inv.getSkewY()); } } do { int ix = fx >> 16; int iy = fy >> 16; const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11; p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels + SkClampMax(iy, srcMaxY) * srcRB)) + SkClampMax(ix, srcMaxX); if ((unsigned)ix < srcMaxX) p01 += 1; p10 = p00; p11 = p01; if ((unsigned)iy < srcMaxY) { p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB); p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB); } SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy); uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)), SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)), SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)), SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11))); *dstC++ = expanded_rgb16_to_8888(c, alpha); fx += dx; fy += dy; } while (--count != 0); } BILERP_BITMAP16_SHADER_POSTAMBLE(srcBitmap); } virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count) { SkASSERT(count > 0); const SkMatrix& inv = this->getTotalInverse(); const SkBitmap& srcBitmap = this->getSrcBitmap(); unsigned srcMaxX = srcBitmap.width() - 1; unsigned srcMaxY = srcBitmap.height() - 1; unsigned srcRB = srcBitmap.rowBytes(); BILERP_BITMAP16_SHADER_PREAMBLE(srcBitmap); const SkFilterProc* proc_table = SkGetBilinearFilterProcTable(); const BILERP_BITMAP16_SHADER_TYPE* srcPixels = (const BILERP_BITMAP16_SHADER_TYPE*)srcBitmap.getPixels(); if (this->getInverseClass() == kPerspective_MatrixClass) { SkPerspIter iter(inv, SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf, count); while ((count = iter.next()) != 0) { const SkFixed* srcXY = iter.getXY(); while (--count >= 0) { SkFixed fx = *srcXY++ - SK_FixedHalf; SkFixed fy = *srcXY++ - SK_FixedHalf; int ix = fx >> 16; int iy = fy >> 16; const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11; p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels + SkClampMax(iy, srcMaxY) * srcRB)) + SkClampMax(ix, srcMaxX); if ((unsigned)ix < srcMaxX) p01 += 1; p10 = p00; p11 = p01; if ((unsigned)iy < srcMaxY) { p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB); p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB); } SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy); uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)), SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)), SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)), SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11))); *dstC++ = SkCompact_rgb_16(c); } } } else // linear case { SkFixed fx, fy, dx, dy; // now init fx, fy, dx, dy { SkPoint srcPt; this->getInverseMapPtProc()(inv, SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf, &srcPt); fx = SkScalarToFixed(srcPt.fX) - SK_FixedHalf; fy = SkScalarToFixed(srcPt.fY) - SK_FixedHalf; if (this->getInverseClass() == kFixedStepInX_MatrixClass) (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy); else { dx = SkScalarToFixed(inv.getScaleX()); dy = SkScalarToFixed(inv.getSkewY()); } } do { int ix = fx >> 16; int iy = fy >> 16; const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11; p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels + SkClampMax(iy, srcMaxY) * srcRB)) + SkClampMax(ix, srcMaxX); if ((unsigned)ix < srcMaxX) p01 += 1; p10 = p00; p11 = p01; if ((unsigned)iy < srcMaxY) { p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB); p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB); } SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy); uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)), SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)), SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)), SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11))); *dstC++ = SkCompact_rgb_16(c); fx += dx; fy += dy; } while (--count != 0); } BILERP_BITMAP16_SHADER_POSTAMBLE(srcBitmap); } }; #undef BILERP_BITMAP16_SHADER_CLASS #undef BILERP_BITMAP16_SHADER_TYPE #undef BILERP_BITMAP16_SHADER_PREAMBLE #undef BILERP_BITMAP16_SHADER_PIXEL #undef BILERP_BITMAP16_SHADER_POSTAMBLE