1#include "DMUtil.h"
2
3#include "SkColorPriv.h"
4#include "SkPicture.h"
5#include "SkPictureRecorder.h"
6
7namespace DM {
8
9SkString UnderJoin(const char* a, const char* b) {
10    SkString s;
11    s.appendf("%s_%s", a, b);
12    return s;
13}
14
15SkString FileToTaskName(SkString filename) {
16    for (size_t i = 0; i < filename.size(); i++) {
17        if ('_' == filename[i]) { filename[i] = '-'; }
18        if ('.' == filename[i]) { filename[i] = '_'; }
19    }
20    return filename;
21}
22
23SkPicture* RecordPicture(skiagm::GM* gm, uint32_t recordFlags, SkBBHFactory* factory) {
24    const SkISize size = gm->getISize();
25    SkPictureRecorder recorder;
26    SkCanvas* canvas = recorder.beginRecording(size.width(), size.height(), factory, recordFlags);
27    canvas->concat(gm->getInitialTransform());
28    gm->draw(canvas);
29    canvas->flush();
30    return recorder.endRecording();
31}
32
33void AllocatePixels(SkColorType ct, int width, int height, SkBitmap* bitmap) {
34    bitmap->allocPixels(SkImageInfo::Make(width, height, ct, kPremul_SkAlphaType));
35    bitmap->eraseColor(0x00000000);
36}
37
38void AllocatePixels(const SkBitmap& reference, SkBitmap* bitmap) {
39    AllocatePixels(reference.colorType(), reference.width(), reference.height(), bitmap);
40}
41
42void DrawPicture(SkPicture* picture, SkBitmap* bitmap) {
43    SkASSERT(picture != NULL);
44    SkASSERT(bitmap != NULL);
45    SkCanvas canvas(*bitmap);
46    canvas.drawPicture(picture);
47    canvas.flush();
48}
49
50static void unpack_565(uint16_t pixel, unsigned* r, unsigned* g, unsigned* b) {
51    *r = SkGetPackedR16(pixel);
52    *g = SkGetPackedG16(pixel);
53    *b = SkGetPackedB16(pixel);
54}
55
56// Returns |a-b|.
57static unsigned abs_diff(unsigned a, unsigned b) {
58    return a > b ? a - b : b - a;
59}
60
61unsigned MaxComponentDifference(const SkBitmap& a, const SkBitmap& b) {
62    if (a.info() != b.info()) {
63        SkFAIL("Can't compare bitmaps of different shapes.");
64    }
65
66    unsigned max = 0;
67
68    const SkAutoLockPixels lockA(a), lockB(b);
69    if (a.info().colorType() == kRGB_565_SkColorType) {
70        // 565 is special/annoying because its 3 components straddle 2 bytes.
71        const uint16_t* aPixels = (const uint16_t*)a.getPixels();
72        const uint16_t* bPixels = (const uint16_t*)b.getPixels();
73        for (size_t i = 0; i < a.getSize() / 2; i++) {
74            unsigned ar, ag, ab,
75                     br, bg, bb;
76            unpack_565(aPixels[i], &ar, &ag, &ab);
77            unpack_565(bPixels[i], &br, &bg, &bb);
78            max = SkTMax(max, abs_diff(ar, br));
79            max = SkTMax(max, abs_diff(ag, bg));
80            max = SkTMax(max, abs_diff(ab, bb));
81        }
82    } else {
83        // Everything else we produce is byte aligned, so max component diff == max byte diff.
84        const uint8_t* aBytes = (const uint8_t*)a.getPixels();
85        const uint8_t* bBytes = (const uint8_t*)b.getPixels();
86        for (size_t i = 0; i < a.getSize(); i++) {
87            max = SkTMax(max, abs_diff(aBytes[i], bBytes[i]));
88        }
89    }
90
91    return max;
92}
93
94bool BitmapsEqual(const SkBitmap& a, const SkBitmap& b) {
95    if (a.info() != b.info()) {
96        return false;
97    }
98    const SkAutoLockPixels lockA(a), lockB(b);
99    return 0 == memcmp(a.getPixels(), b.getPixels(), a.getSize());
100}
101
102}  // namespace DM
103