1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
7e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.org
8ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#include "SkPackBits.h"
98f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "Test.h"
10ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
11ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic const uint16_t gTest0[] = { 0, 0, 1, 1 };
12ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic const uint16_t gTest1[] = { 1, 2, 3, 4, 5, 6 };
13ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic const uint16_t gTest2[] = { 0, 0, 0, 1, 2, 3, 3, 3 };
14ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic const uint16_t gTest3[] = { 0, 0, 0, 0, 0, 0, 1, 2, 3, 3, 3, 0, 0, 1 };
15ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
16ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#include "SkRandom.h"
17e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.orgstatic SkRandom gRand;
18ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void rand_fill(uint16_t buffer[], int count) {
19ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    for (int i = 0; i < count; i++)
20ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        buffer[i] = (uint16_t)gRand.nextU();
21ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
22ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
23ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void test_pack16(skiatest::Reporter* reporter) {
24ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    static const struct {
25ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        const uint16_t* fSrc;
26ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        int             fCount;
27ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    } gTests[] = {
28ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        { gTest0, SK_ARRAY_COUNT(gTest0) },
29ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        { gTest1, SK_ARRAY_COUNT(gTest1) },
30ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        { gTest2, SK_ARRAY_COUNT(gTest2) },
31ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        { gTest3, SK_ARRAY_COUNT(gTest3) }
32ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    };
3380e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
34ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gTests); i++) {
35ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        uint8_t dst[100];
36ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        size_t dstSize = SkPackBits::Pack16(gTests[i].fSrc,
37ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com                                            gTests[i].fCount, dst);
38ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        uint16_t src[100];
39ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        int srcCount = SkPackBits::Unpack16(dst, dstSize, src);
40ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        bool match = gTests[i].fCount == srcCount && memcmp(gTests[i].fSrc, src,
41ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com                                    gTests[i].fCount * sizeof(uint16_t)) == 0;
42ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, match);
43ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
4480e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
45ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    for (int n = 1000; n; n--) {
46ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        size_t size = 50;
47ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        uint16_t src[100], src2[100];
48ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        uint8_t dst[200];
49ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        rand_fill(src, size);
50ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
51ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        size_t dstSize = SkPackBits::Pack16(src, size, dst);
52ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        size_t maxSize = SkPackBits::ComputeMaxSize16(size);
53ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, maxSize >= dstSize);
54ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
5504225dcdec5a01bc9889b7fb03e7aceb87fccc6ereed@android.com        size_t srcCount = SkPackBits::Unpack16(dst, dstSize, src2);
56ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, size == srcCount);
57ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        bool match = memcmp(src, src2, size * sizeof(uint16_t)) == 0;
58ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, match);
59ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
60ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
61ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
62ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic const uint8_t gTest80[] = { 0, 0, 1, 1 };
63ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic const uint8_t gTest81[] = { 1, 2, 3, 4, 5, 6 };
64ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic const uint8_t gTest82[] = { 0, 0, 0, 1, 2, 3, 3, 3 };
65ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic const uint8_t gTest83[] = { 0, 0, 0, 0, 0, 0, 1, 2, 3, 3, 3, 0, 0, 1 };
66ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic const uint8_t gTest84[] = { 1, 0, 3, 0, 0, 0, 2, 1, 1, 2 };
67ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
68ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void rand_fill(uint8_t buffer[], int count) {
69ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    for (int i = 0; i < count; i++)
70ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        buffer[i] = (uint8_t)((gRand.nextU() >> 8) & 0x3);
71ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
72ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
73ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void test_pack8(skiatest::Reporter* reporter) {
74ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    static const struct {
75ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        const uint8_t* fSrc;
76ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        int             fCount;
77ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    } gTests[] = {
78ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        { gTest80, SK_ARRAY_COUNT(gTest80) },
79ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        { gTest81, SK_ARRAY_COUNT(gTest81) },
80ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        { gTest82, SK_ARRAY_COUNT(gTest82) },
81ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        { gTest83, SK_ARRAY_COUNT(gTest83) },
82ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        { gTest84, SK_ARRAY_COUNT(gTest84) }
83ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    };
8480e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
85ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    for (size_t i = 4; i < SK_ARRAY_COUNT(gTests); i++) {
86ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        uint8_t dst[100];
87ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        size_t maxSize = SkPackBits::ComputeMaxSize8(gTests[i].fCount);
88ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        size_t dstSize = SkPackBits::Pack8(gTests[i].fSrc,
89ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com                                           gTests[i].fCount, dst);
90ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, dstSize <= maxSize);
91ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        uint8_t src[100];
92ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        int srcCount = SkPackBits::Unpack8(dst, dstSize, src);
93ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        bool match = gTests[i].fCount == srcCount &&
94ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com                    memcmp(gTests[i].fSrc, src,
95ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com                           gTests[i].fCount * sizeof(uint8_t)) == 0;
96ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, match);
97ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
98ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
99ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    for (size_t size = 1; size <= 512; size += 1) {
100e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com        for (int n = 100; n; n--) {
101ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            uint8_t src[600], src2[600];
102ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            uint8_t dst[600];
103ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            rand_fill(src, size);
104ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
105ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            size_t dstSize = SkPackBits::Pack8(src, size, dst);
106ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            size_t maxSize = SkPackBits::ComputeMaxSize8(size);
107ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            REPORTER_ASSERT(reporter, maxSize >= dstSize);
108ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
10904225dcdec5a01bc9889b7fb03e7aceb87fccc6ereed@android.com            size_t srcCount = SkPackBits::Unpack8(dst, dstSize, src2);
110ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            REPORTER_ASSERT(reporter, size == srcCount);
111ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            bool match = memcmp(src, src2, size * sizeof(uint8_t)) == 0;
112ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            REPORTER_ASSERT(reporter, match);
11380e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
114e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com            for (int j = 0; j < 100; j++) {
115ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com                size_t skip = gRand.nextU() % size;
116ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com                size_t write = gRand.nextU() % size;
117ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com                if (skip + write > size) {
118ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com                    write = size - skip;
119ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com                }
120ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com                SkPackBits::Unpack8(src, skip, write, dst);
121ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com                bool match = memcmp(src, src2 + skip, write) == 0;
122ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com                REPORTER_ASSERT(reporter, match);
123ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            }
124ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        }
125ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
126ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
127ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
128e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.orgDEF_TEST(PackBits, reporter) {
129d8730ea8b25d692c0656f8cf03f02aecfab2a17creed@android.com    test_pack8(reporter);
130d8730ea8b25d692c0656f8cf03f02aecfab2a17creed@android.com    test_pack16(reporter);
131ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
132