aboutsummaryrefslogtreecommitdiffhomepage
path: root/gm/bitmappremul.cpp
blob: 31a565018da6c9187b40c7772549cb293f7dee7c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkColorPriv.h"

/**
 * This GM checks that bitmap pixels are unpremultiplied before being exported
 * to other formats. If unpremultiplication is implemented properly, this
 * GM should come out completely white. If not, this GM looks like a row of two
 * greyscale gradients above a row of grey lines.
 * This tests both the ARGB4444 and ARGB8888 bitmap configurations.
 */

constexpr int SLIDE_SIZE = 256;
constexpr int PIXEL_SIZE_8888 = SLIDE_SIZE / 256;
constexpr int PIXEL_SIZE_4444 = SLIDE_SIZE / 16;

static void init_bitmap(SkColorType ct, SkBitmap* bitmap) {
    bitmap->allocPixels(SkImageInfo::Make(SLIDE_SIZE, SLIDE_SIZE, ct,
                                          kPremul_SkAlphaType));
    bitmap->eraseColor(SK_ColorWHITE);
}

static SkBitmap make_argb8888_gradient() {
    SkBitmap bitmap;
    init_bitmap(kN32_SkColorType, &bitmap);
    uint8_t rowColor = 0;
    for (int y = 0; y < SLIDE_SIZE; y++) {
        uint32_t* dst = bitmap.getAddr32(0, y);
        for (int x = 0; x < SLIDE_SIZE; x++) {
            dst[x] = SkPackARGB32(rowColor, rowColor,
                                  rowColor, rowColor);
        }
        if (y % PIXEL_SIZE_8888 == PIXEL_SIZE_8888 - 1) {
            rowColor++;
        }
    }
    return bitmap;
}

static SkBitmap make_argb4444_gradient() {
    SkBitmap bitmap;
    init_bitmap(kARGB_4444_SkColorType, &bitmap);
    uint8_t rowColor = 0;
    for (int y = 0; y < SLIDE_SIZE; y++) {
        uint16_t* dst = bitmap.getAddr16(0, y);
        for (int x = 0; x < SLIDE_SIZE; x++) {
            dst[x] = SkPackARGB4444(rowColor, rowColor,
                                    rowColor, rowColor);
        }
        if (y % PIXEL_SIZE_4444 == PIXEL_SIZE_4444 - 1) {
            rowColor++;
        }
    }
    return bitmap;
}

static SkBitmap make_argb8888_stripes() {
    SkBitmap bitmap;
    init_bitmap(kN32_SkColorType, &bitmap);
    uint8_t rowColor = 0;
    for (int y = 0; y < SLIDE_SIZE; y++) {
        uint32_t* dst = bitmap.getAddr32(0, y);
        for (int x = 0; x < SLIDE_SIZE; x++) {
            dst[x] = SkPackARGB32(rowColor, rowColor,
                                  rowColor, rowColor);
        }
        if (rowColor == 0) {
            rowColor = 255;
        } else {
            rowColor = 0;
        }
    }
    return bitmap;
}

static SkBitmap make_argb4444_stripes() {
    SkBitmap bitmap;
    init_bitmap(kARGB_4444_SkColorType, &bitmap);
    uint8_t rowColor = 0;
    for (int y = 0; y < SLIDE_SIZE; y++) {
        uint16_t* dst = bitmap.getAddr16(0, y);
        for (int x = 0; x < SLIDE_SIZE; x++) {
            dst[x] = SkPackARGB4444(rowColor, rowColor,
                                    rowColor, rowColor);
        }
        if (rowColor == 0) {
            rowColor = 15;
        } else {
            rowColor = 0;
        }
    }
    return bitmap;
}

namespace skiagm {

class BitmapPremulGM : public GM {
public:
    BitmapPremulGM() {
        this->setBGColor(SK_ColorWHITE);
    }

protected:
    SkString onShortName() override {
        return SkString("bitmap_premul");
    }

    SkISize onISize() override {
        return SkISize::Make(SLIDE_SIZE * 2, SLIDE_SIZE * 2);
    }

    void onDraw(SkCanvas* canvas) override {
        SkScalar slideSize = SkIntToScalar(SLIDE_SIZE);
        canvas->drawBitmap(make_argb8888_gradient(), 0, 0);
        canvas->drawBitmap(make_argb4444_gradient(), slideSize, 0);
        canvas->drawBitmap(make_argb8888_stripes(), 0, slideSize);
        canvas->drawBitmap(make_argb4444_stripes(), slideSize, slideSize);
    }

private:
    typedef GM INHERITED;
};

DEF_GM( return new BitmapPremulGM; )
}