1/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkColor.h"
9#include "SkColorPriv.h"
10#include "SkMathPriv.h"
11#include "SkRandom.h"
12#include "SkUnPreMultiply.h"
13#include "Test.h"
14
15#define GetPackedR16As32(packed)    (SkGetPackedR16(dc) << (8 - SK_R16_BITS))
16#define GetPackedG16As32(packed)    (SkGetPackedG16(dc) << (8 - SK_G16_BITS))
17#define GetPackedB16As32(packed)    (SkGetPackedB16(dc) << (8 - SK_B16_BITS))
18
19static inline void test_premul(skiatest::Reporter* reporter) {
20    for (int a = 0; a <= 255; a++) {
21        for (int x = 0; x <= 255; x++) {
22            SkColor c0 = SkColorSetARGB(a, x, x, x);
23            SkPMColor p0 = SkPreMultiplyColor(c0);
24
25            SkColor c1 = SkUnPreMultiply::PMColorToColor(p0);
26            SkPMColor p1 = SkPreMultiplyColor(c1);
27
28            // we can't promise that c0 == c1, since c0 -> p0 is a many to one
29            // function, however, we can promise that p0 -> c1 -> p1 : p0 == p1
30            REPORTER_ASSERT(reporter, p0 == p1);
31
32            {
33                int ax = SkMulDiv255Ceiling(x, a);
34                REPORTER_ASSERT(reporter, ax <= a);
35            }
36        }
37    }
38}
39
40/**
41  This test fails: SkFourByteInterp does *not* preserve opaque destinations.
42  SkAlpha255To256 implemented as (alpha + 1) is faster than
43  (alpha + (alpha >> 7)), but inaccurate, and Skia intends to phase it out.
44*/
45/*
46static void test_interp(skiatest::Reporter* reporter) {
47    SkRandom r;
48
49    U8CPU a0 = 0;
50    U8CPU a255 = 255;
51    for (int i = 0; i < 200; i++) {
52        SkColor colorSrc = r.nextU();
53        SkColor colorDst = r.nextU();
54        SkPMColor src = SkPreMultiplyColor(colorSrc);
55        SkPMColor dst = SkPreMultiplyColor(colorDst);
56
57        REPORTER_ASSERT(reporter, SkFourByteInterp(src, dst, a0) == dst);
58        REPORTER_ASSERT(reporter, SkFourByteInterp(src, dst, a255) == src);
59    }
60}
61*/
62
63static inline void test_fast_interp(skiatest::Reporter* reporter) {
64    SkRandom r;
65
66    U8CPU a0 = 0;
67    U8CPU a255 = 255;
68    for (int i = 0; i < 200; i++) {
69        SkColor colorSrc = r.nextU();
70        SkColor colorDst = r.nextU();
71        SkPMColor src = SkPreMultiplyColor(colorSrc);
72        SkPMColor dst = SkPreMultiplyColor(colorDst);
73
74        REPORTER_ASSERT(reporter, SkFastFourByteInterp(src, dst, a0) == dst);
75        REPORTER_ASSERT(reporter, SkFastFourByteInterp(src, dst, a255) == src);
76    }
77}
78
79DEF_TEST(Color, reporter) {
80    test_premul(reporter);
81    //test_interp(reporter);
82    test_fast_interp(reporter);
83    //test_565blend();
84}
85