180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2009 The Android Open Source Project
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkColorPriv.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Filter_32_opaque
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    There is no hard-n-fast rule that the filtering must produce
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    exact results for the color components, but if the 4 incoming colors are
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    all opaque, then the output color must also be opaque. Subsequent parts of
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    the drawing pipeline may rely on this (e.g. which blitrow proc to use).
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline void Filter_32_opaque(unsigned x, unsigned y,
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                    SkPMColor a00, SkPMColor a01,
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                    SkPMColor a10, SkPMColor a11,
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                    SkPMColor* dstColor) {
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((unsigned)x <= 0xF);
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((unsigned)y <= 0xF);
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int xy = x * y;
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static const uint32_t mask = gMask_00FF00FF; //0xFF00FF;
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int scale = 256 - 16*y - 16*x + xy;
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t lo = (a00 & mask) * scale;
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t hi = ((a00 >> 8) & mask) * scale;
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    scale = 16*x - xy;
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    lo += (a01 & mask) * scale;
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    hi += ((a01 >> 8) & mask) * scale;
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    scale = 16*y - xy;
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    lo += (a10 & mask) * scale;
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    hi += ((a10 >> 8) & mask) * scale;
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    lo += (a11 & mask) * xy;
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    hi += ((a11 >> 8) & mask) * xy;
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    *dstColor = ((lo >> 8) & mask) | (hi & ~mask);
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline void Filter_32_alpha(unsigned x, unsigned y,
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                   SkPMColor a00, SkPMColor a01,
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                   SkPMColor a10, SkPMColor a11,
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                   SkPMColor* dstColor,
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                   unsigned alphaScale) {
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((unsigned)x <= 0xF);
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((unsigned)y <= 0xF);
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(alphaScale <= 256);
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int xy = x * y;
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static const uint32_t mask = gMask_00FF00FF; //0xFF00FF;
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int scale = 256 - 16*y - 16*x + xy;
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t lo = (a00 & mask) * scale;
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t hi = ((a00 >> 8) & mask) * scale;
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    scale = 16*x - xy;
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    lo += (a01 & mask) * scale;
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    hi += ((a01 >> 8) & mask) * scale;
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    scale = 16*y - xy;
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    lo += (a10 & mask) * scale;
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    hi += ((a10 >> 8) & mask) * scale;
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    lo += (a11 & mask) * xy;
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    hi += ((a11 >> 8) & mask) * xy;
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    lo = ((lo >> 8) & mask) * alphaScale;
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    hi = ((hi >> 8) & mask) * alphaScale;
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    *dstColor = ((lo >> 8) & mask) | (hi & ~mask);
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
82d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger// Two color version, where we filter only along 1 axis
83d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstatic inline void Filter_32_opaque(unsigned t,
84d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                    SkPMColor color0,
85d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                    SkPMColor color1,
86d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                    SkPMColor* dstColor) {
87d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    SkASSERT((unsigned)t <= 0xF);
88d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
89d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    static const uint32_t mask = gMask_00FF00FF; //0x00FF00FF;
90d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
91d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    int scale = 256 - 16*t;
92d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    uint32_t lo = (color0 & mask) * scale;
93d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    uint32_t hi = ((color0 >> 8) & mask) * scale;
94d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
95d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    scale = 16*t;
96d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    lo += (color1 & mask) * scale;
97d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    hi += ((color1 >> 8) & mask) * scale;
98d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
99d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    *dstColor = ((lo >> 8) & mask) | (hi & ~mask);
100d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
101d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
102d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger// Two color version, where we filter only along 1 axis
103d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstatic inline void Filter_32_alpha(unsigned t,
104d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                   SkPMColor color0,
105d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                   SkPMColor color1,
106d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                   SkPMColor* dstColor,
107d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                   unsigned alphaScale) {
108d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    SkASSERT((unsigned)t <= 0xF);
109d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    SkASSERT(alphaScale <= 256);
110d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
111d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    static const uint32_t mask = gMask_00FF00FF; //0x00FF00FF;
112d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
113d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    int scale = 256 - 16*t;
114d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    uint32_t lo = (color0 & mask) * scale;
115d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    uint32_t hi = ((color0 >> 8) & mask) * scale;
116d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
117d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    scale = 16*t;
118d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    lo += (color1 & mask) * scale;
119d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    hi += ((color1 >> 8) & mask) * scale;
120d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
121d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    lo = ((lo >> 8) & mask) * alphaScale;
122d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    hi = ((hi >> 8) & mask) * alphaScale;
123d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
124d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    *dstColor = ((lo >> 8) & mask) | (hi & ~mask);
125d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
126