1 2/* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10#include <stdlib.h> 11#include <string.h> 12 13#include "Test.h" 14#include "SkData.h" 15#include "SkFlate.h" 16#include "SkStream.h" 17 18// A memory stream that reports zero size with the standard call, like 19// an unseekable file stream would. 20class SkZeroSizeMemStream : public SkMemoryStream { 21public: 22 virtual size_t read(void* buffer, size_t size) { 23 if (buffer == NULL && size == 0) 24 return 0; 25 if (buffer == NULL && size == kGetSizeKey) 26 size = 0; 27 return SkMemoryStream::read(buffer, size); 28 } 29 30 static const size_t kGetSizeKey = 0xDEADBEEF; 31}; 32 33static void TestFlate(skiatest::Reporter* reporter, SkMemoryStream* testStream, 34 size_t dataSize) { 35 if (testStream == NULL) 36 return; 37 38 SkMemoryStream testData(dataSize); 39 uint8_t* data = (uint8_t*)testData.getMemoryBase(); 40 srand(0); // Make data deterministic. 41 for (size_t i = 0; i < dataSize; i++) 42 data[i] = rand() & 0xFF; 43 44 testStream->setMemory(testData.getMemoryBase(), dataSize, true); 45 SkDynamicMemoryWStream compressed; 46 bool status = SkFlate::Deflate(testStream, &compressed); 47 REPORTER_ASSERT(reporter, status); 48 49 // Check that the input data wasn't changed. 50 size_t inputSize = testStream->getLength(); 51 if (inputSize == 0) 52 inputSize = testStream->read(NULL, SkZeroSizeMemStream::kGetSizeKey); 53 REPORTER_ASSERT(reporter, testData.getLength() == inputSize); 54 REPORTER_ASSERT(reporter, memcmp(testData.getMemoryBase(), 55 testStream->getMemoryBase(), 56 testData.getLength()) == 0); 57 58 // Assume there are two test sizes, big and small. 59 if (dataSize < 1024) 60 REPORTER_ASSERT(reporter, compressed.getOffset() < 1024); 61 else 62 REPORTER_ASSERT(reporter, compressed.getOffset() > 1024); 63 64 SkAutoDataUnref data1(compressed.copyToData()); 65 66 testStream->setData(data1.get())->unref(); 67 SkDynamicMemoryWStream uncompressed; 68 status = SkFlate::Inflate(testStream, &uncompressed); 69 REPORTER_ASSERT(reporter, status); 70 71 // Check that the input data wasn't changed. 72 inputSize = testStream->getLength(); 73 if (inputSize == 0) 74 inputSize = testStream->read(NULL, SkZeroSizeMemStream::kGetSizeKey); 75 REPORTER_ASSERT(reporter, data1.size() == inputSize); 76 REPORTER_ASSERT(reporter, memcmp(testStream->getMemoryBase(), 77 data1.data(), data1.size()) == 0); 78 79 // Check that the uncompressed data matches the source data. 80 SkAutoDataUnref data2(uncompressed.copyToData()); 81 REPORTER_ASSERT(reporter, testData.getLength() == uncompressed.getOffset()); 82 REPORTER_ASSERT(reporter, memcmp(testData.getMemoryBase(), data2.data(), 83 testData.getLength()) == 0); 84} 85 86static void TestFlateCompression(skiatest::Reporter* reporter) { 87 TestFlate(reporter, NULL, 0); 88#if defined(SK_ZLIB_INCLUDE) && !defined(SK_DEBUG) 89 REPORTER_ASSERT(reporter, SkFlate::HaveFlate()); 90 91 SkMemoryStream memStream; 92 TestFlate(reporter, &memStream, 512); 93 TestFlate(reporter, &memStream, 10240); 94 95 SkZeroSizeMemStream fileStream; 96 TestFlate(reporter, &fileStream, 512); 97 TestFlate(reporter, &fileStream, 10240); 98#endif 99} 100 101#include "TestClassDef.h" 102DEFINE_TESTCLASS("Flate", FlateTestClass, TestFlateCompression) 103