1ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org *
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.
6ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org */
7ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org
8ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org#include <stdlib.h>
9ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org#include <string.h>
10ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org
118a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com#include "SkData.h"
12ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org#include "SkFlate.h"
13ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org#include "SkStream.h"
148f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "Test.h"
15ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org
16ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org// A memory stream that reports zero size with the standard call, like
17ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org// an unseekable file stream would.
182a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.orgclass SkZeroSizeMemStream : public SkMemoryStream {
19ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.orgpublic:
20ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    virtual size_t read(void* buffer, size_t size) {
21ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org        if (buffer == NULL && size == 0)
22ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org            return 0;
23ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org        if (buffer == NULL && size == kGetSizeKey)
24ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org            size = 0;
25ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org        return SkMemoryStream::read(buffer, size);
26ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    }
27ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org
28ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    static const size_t kGetSizeKey = 0xDEADBEEF;
29ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org};
30ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org
31ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.orgstatic void TestFlate(skiatest::Reporter* reporter, SkMemoryStream* testStream,
32ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org                      size_t dataSize) {
33ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    if (testStream == NULL)
34ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org      return;
35ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org
36ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    SkMemoryStream testData(dataSize);
37ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    uint8_t* data = (uint8_t*)testData.getMemoryBase();
38ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    srand(0);  // Make data deterministic.
39ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    for (size_t i = 0; i < dataSize; i++)
40ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org        data[i] = rand() & 0xFF;
41ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org
42ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    testStream->setMemory(testData.getMemoryBase(), dataSize, true);
43ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    SkDynamicMemoryWStream compressed;
44ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    bool status = SkFlate::Deflate(testStream, &compressed);
45ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    REPORTER_ASSERT(reporter, status);
46ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org
47ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    // Check that the input data wasn't changed.
48ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    size_t inputSize = testStream->getLength();
49ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    if (inputSize == 0)
502a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        inputSize = testStream->read(NULL, SkZeroSizeMemStream::kGetSizeKey);
51ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    REPORTER_ASSERT(reporter, testData.getLength() == inputSize);
52ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    REPORTER_ASSERT(reporter, memcmp(testData.getMemoryBase(),
53ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org                                     testStream->getMemoryBase(),
54ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org                                     testData.getLength()) == 0);
55ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org
56ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    // Assume there are two test sizes, big and small.
57ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    if (dataSize < 1024)
58ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org      REPORTER_ASSERT(reporter, compressed.getOffset() < 1024);
59ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    else
60ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org      REPORTER_ASSERT(reporter, compressed.getOffset() > 1024);
61ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org
628a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    SkAutoDataUnref data1(compressed.copyToData());
638a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com
648a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    testStream->setData(data1.get())->unref();
65ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    SkDynamicMemoryWStream uncompressed;
66ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    status = SkFlate::Inflate(testStream, &uncompressed);
67ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    REPORTER_ASSERT(reporter, status);
68ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org
69ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    // Check that the input data wasn't changed.
70ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    inputSize = testStream->getLength();
71ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    if (inputSize == 0)
722a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        inputSize = testStream->read(NULL, SkZeroSizeMemStream::kGetSizeKey);
7359f46b81f8bdd1b524f5cc43bc27603f9604c71arobertphillips@google.com    REPORTER_ASSERT(reporter, data1->size() == inputSize);
74ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    REPORTER_ASSERT(reporter, memcmp(testStream->getMemoryBase(),
75d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com                                     data1->data(),
7659f46b81f8bdd1b524f5cc43bc27603f9604c71arobertphillips@google.com                                     data1->size()) == 0);
77ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org
78ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    // Check that the uncompressed data matches the source data.
798a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    SkAutoDataUnref data2(uncompressed.copyToData());
80ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    REPORTER_ASSERT(reporter, testData.getLength() == uncompressed.getOffset());
81d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    REPORTER_ASSERT(reporter, memcmp(testData.getMemoryBase(),
8259f46b81f8bdd1b524f5cc43bc27603f9604c71arobertphillips@google.com                                     data2->data(),
83ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org                                     testData.getLength()) == 0);
84ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org}
85ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org
86e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.orgDEF_TEST(Flate, reporter) {
87ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    TestFlate(reporter, NULL, 0);
88fb0b0edd86d71bb423fa921eaac1e2071602115cvandebo@chromium.org#if defined(SK_ZLIB_INCLUDE) && !defined(SK_DEBUG)
89ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    REPORTER_ASSERT(reporter, SkFlate::HaveFlate());
90ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org
91ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    SkMemoryStream memStream;
92ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    TestFlate(reporter, &memStream, 512);
93ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    TestFlate(reporter, &memStream, 10240);
94ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org
952a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    SkZeroSizeMemStream fileStream;
96ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    TestFlate(reporter, &fileStream, 512);
97ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org    TestFlate(reporter, &fileStream, 10240);
98ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org#endif
99ee34e35c8cefb5b384b34e4eb5ef8cb82774e5a0vandebo@chromium.org}
100