11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc.
405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger */
805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include <stdlib.h>
1105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include <string.h>
1205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
1305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "Test.h"
141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkData.h"
1505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "SkFlate.h"
1605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "SkStream.h"
1705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
1805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// A memory stream that reports zero size with the standard call, like
1905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// an unseekable file stream would.
2005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerclass SkZeroSizeMemStream : public SkMemoryStream {
2105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerpublic:
2205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    virtual size_t read(void* buffer, size_t size) {
2305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        if (buffer == NULL && size == 0)
2405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            return 0;
2505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        if (buffer == NULL && size == kGetSizeKey)
2605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            size = 0;
2705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return SkMemoryStream::read(buffer, size);
2805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
2905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
3005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    static const size_t kGetSizeKey = 0xDEADBEEF;
3105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger};
3205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
3305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerstatic void TestFlate(skiatest::Reporter* reporter, SkMemoryStream* testStream,
3405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                      size_t dataSize) {
3505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (testStream == NULL)
3605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger      return;
3705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
3805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkMemoryStream testData(dataSize);
3905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    uint8_t* data = (uint8_t*)testData.getMemoryBase();
4005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    srand(0);  // Make data deterministic.
4105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    for (size_t i = 0; i < dataSize; i++)
4205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        data[i] = rand() & 0xFF;
4305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
4405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    testStream->setMemory(testData.getMemoryBase(), dataSize, true);
4505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkDynamicMemoryWStream compressed;
4605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    bool status = SkFlate::Deflate(testStream, &compressed);
4705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    REPORTER_ASSERT(reporter, status);
4805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
4905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    // Check that the input data wasn't changed.
5005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    size_t inputSize = testStream->getLength();
5105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (inputSize == 0)
5205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        inputSize = testStream->read(NULL, SkZeroSizeMemStream::kGetSizeKey);
5305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    REPORTER_ASSERT(reporter, testData.getLength() == inputSize);
5405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    REPORTER_ASSERT(reporter, memcmp(testData.getMemoryBase(),
5505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                     testStream->getMemoryBase(),
5605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                     testData.getLength()) == 0);
5705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
5805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    // Assume there are two test sizes, big and small.
5905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (dataSize < 1024)
6005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger      REPORTER_ASSERT(reporter, compressed.getOffset() < 1024);
6105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    else
6205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger      REPORTER_ASSERT(reporter, compressed.getOffset() > 1024);
6305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkAutoDataUnref data1(compressed.copyToData());
651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    testStream->setData(data1.get())->unref();
6705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkDynamicMemoryWStream uncompressed;
6805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    status = SkFlate::Inflate(testStream, &uncompressed);
6905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    REPORTER_ASSERT(reporter, status);
7005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
7105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    // Check that the input data wasn't changed.
7205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    inputSize = testStream->getLength();
7305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (inputSize == 0)
7405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        inputSize = testStream->read(NULL, SkZeroSizeMemStream::kGetSizeKey);
751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, data1.size() == inputSize);
7605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    REPORTER_ASSERT(reporter, memcmp(testStream->getMemoryBase(),
771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                     data1.data(), data1.size()) == 0);
7805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
7905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    // Check that the uncompressed data matches the source data.
801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkAutoDataUnref data2(uncompressed.copyToData());
8105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    REPORTER_ASSERT(reporter, testData.getLength() == uncompressed.getOffset());
821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, memcmp(testData.getMemoryBase(), data2.data(),
8305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                     testData.getLength()) == 0);
8405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
8505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
8605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerstatic void TestFlateCompression(skiatest::Reporter* reporter) {
8705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    TestFlate(reporter, NULL, 0);
8835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#if defined(SK_ZLIB_INCLUDE) && !defined(SK_DEBUG)
8905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    REPORTER_ASSERT(reporter, SkFlate::HaveFlate());
9005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
9105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkMemoryStream memStream;
9205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    TestFlate(reporter, &memStream, 512);
9305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    TestFlate(reporter, &memStream, 10240);
9405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
9505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkZeroSizeMemStream fileStream;
9605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    TestFlate(reporter, &fileStream, 512);
9705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    TestFlate(reporter, &fileStream, 10240);
9805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#endif
9905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
10005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
10105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "TestClassDef.h"
10205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerDEFINE_TESTCLASS("Flate", FlateTestClass, TestFlateCompression)
103