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 "SkData.h" 12 #include "SkFlate.h" 13 #include "SkStream.h" 14 #include "Test.h" 15 16 // A memory stream that reports zero size with the standard call, like 17 // an unseekable file stream would. 18 class SkZeroSizeMemStream : public SkMemoryStream { 19 public: 20 virtual size_t read(void* buffer, size_t size) { 21 if (buffer == NULL && size == 0) 22 return 0; 23 if (buffer == NULL && size == kGetSizeKey) 24 size = 0; 25 return SkMemoryStream::read(buffer, size); 26 } 27 28 static const size_t kGetSizeKey = 0xDEADBEEF; 29 }; 30 31 static void TestFlate(skiatest::Reporter* reporter, SkMemoryStream* testStream, 32 size_t dataSize) { 33 if (testStream == NULL) 34 return; 35 36 SkMemoryStream testData(dataSize); 37 uint8_t* data = (uint8_t*)testData.getMemoryBase(); 38 srand(0); // Make data deterministic. 39 for (size_t i = 0; i < dataSize; i++) 40 data[i] = rand() & 0xFF; 41 42 testStream->setMemory(testData.getMemoryBase(), dataSize, true); 43 SkDynamicMemoryWStream compressed; 44 bool status = SkFlate::Deflate(testStream, &compressed); 45 REPORTER_ASSERT(reporter, status); 46 47 // Check that the input data wasn't changed. 48 size_t inputSize = testStream->getLength(); 49 if (inputSize == 0) 50 inputSize = testStream->read(NULL, SkZeroSizeMemStream::kGetSizeKey); 51 REPORTER_ASSERT(reporter, testData.getLength() == inputSize); 52 REPORTER_ASSERT(reporter, memcmp(testData.getMemoryBase(), 53 testStream->getMemoryBase(), 54 testData.getLength()) == 0); 55 56 // Assume there are two test sizes, big and small. 57 if (dataSize < 1024) 58 REPORTER_ASSERT(reporter, compressed.getOffset() < 1024); 59 else 60 REPORTER_ASSERT(reporter, compressed.getOffset() > 1024); 61 62 SkAutoDataUnref data1(compressed.copyToData()); 63 64 testStream->setData(data1.get())->unref(); 65 SkDynamicMemoryWStream uncompressed; 66 status = SkFlate::Inflate(testStream, &uncompressed); 67 REPORTER_ASSERT(reporter, status); 68 69 // Check that the input data wasn't changed. 70 inputSize = testStream->getLength(); 71 if (inputSize == 0) 72 inputSize = testStream->read(NULL, SkZeroSizeMemStream::kGetSizeKey); 73 REPORTER_ASSERT(reporter, data1->size() == inputSize); 74 REPORTER_ASSERT(reporter, memcmp(testStream->getMemoryBase(), 75 data1->data(), 76 data1->size()) == 0); 77 78 // Check that the uncompressed data matches the source data. 79 SkAutoDataUnref data2(uncompressed.copyToData()); 80 REPORTER_ASSERT(reporter, testData.getLength() == uncompressed.getOffset()); 81 REPORTER_ASSERT(reporter, memcmp(testData.getMemoryBase(), 82 data2->data(), 83 testData.getLength()) == 0); 84 } 85 86 DEF_TEST(Flate, 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