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