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. 20 class SkZeroSizeMemStream : public SkMemoryStream { 21 public: 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 33 static 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(), 78 data1->size()) == 0); 79 80 // Check that the uncompressed data matches the source data. 81 SkAutoDataUnref data2(uncompressed.copyToData()); 82 REPORTER_ASSERT(reporter, testData.getLength() == uncompressed.getOffset()); 83 REPORTER_ASSERT(reporter, memcmp(testData.getMemoryBase(), 84 data2->data(), 85 testData.getLength()) == 0); 86 } 87 88 static void TestFlateCompression(skiatest::Reporter* reporter) { 89 TestFlate(reporter, NULL, 0); 90 #if defined(SK_ZLIB_INCLUDE) && !defined(SK_DEBUG) 91 REPORTER_ASSERT(reporter, SkFlate::HaveFlate()); 92 93 SkMemoryStream memStream; 94 TestFlate(reporter, &memStream, 512); 95 TestFlate(reporter, &memStream, 10240); 96 97 SkZeroSizeMemStream fileStream; 98 TestFlate(reporter, &fileStream, 512); 99 TestFlate(reporter, &fileStream, 10240); 100 #endif 101 } 102 103 #include "TestClassDef.h" 104 DEFINE_TESTCLASS("Flate", FlateTestClass, TestFlateCompression) 105