Home | History | Annotate | Download | only in tests
      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 "SkData.h"
      9 #include "SkFlate.h"
     10 #include "SkStream.h"
     11 #include "Test.h"
     12 
     13 // A memory stream that reports zero size with the standard call, like
     14 // an unseekable file stream would.
     15 class SkZeroSizeMemStream : public SkMemoryStream {
     16 public:
     17     virtual size_t read(void* buffer, size_t size) {
     18         if (buffer == NULL && size == 0)
     19             return 0;
     20         if (buffer == NULL && size == kGetSizeKey)
     21             size = 0;
     22         return SkMemoryStream::read(buffer, size);
     23     }
     24 
     25     static const size_t kGetSizeKey = 0xDEADBEEF;
     26 };
     27 
     28 // Returns a deterministic data of the given size that should be
     29 // very compressible.
     30 static SkData* new_test_data(size_t dataSize) {
     31     SkAutoTMalloc<uint8_t> testBuffer(dataSize);
     32     for (size_t i = 0; i < dataSize; ++i) {
     33         testBuffer[i] = i % 64;
     34     }
     35     return SkData::NewFromMalloc(testBuffer.detach(), dataSize);
     36 }
     37 
     38 static void TestFlate(skiatest::Reporter* reporter, SkMemoryStream* testStream,
     39                       size_t dataSize) {
     40     SkASSERT(testStream != NULL);
     41 
     42     SkAutoDataUnref testData(new_test_data(dataSize));
     43     SkASSERT(testData->size() == dataSize);
     44 
     45     testStream->setMemory(testData->data(), dataSize, /*copyData=*/ true);
     46     SkDynamicMemoryWStream compressed;
     47     bool deflateSuccess = SkFlate::Deflate(testStream, &compressed);
     48     REPORTER_ASSERT(reporter, deflateSuccess);
     49 
     50     // Check that the input data wasn't changed.
     51     size_t inputSize = testStream->getLength();
     52     if (inputSize == 0) {
     53         inputSize = testStream->read(NULL, SkZeroSizeMemStream::kGetSizeKey);
     54     }
     55     REPORTER_ASSERT(reporter, dataSize == inputSize);
     56     if (dataSize == inputSize) {
     57         REPORTER_ASSERT(reporter, memcmp(testData->data(),
     58                                          testStream->getMemoryBase(),
     59                                          dataSize) == 0);
     60     }
     61 
     62     size_t compressedSize = compressed.getOffset();
     63 
     64     SkAutoDataUnref compressedData(compressed.copyToData());
     65     testStream->setData(compressedData.get());
     66 
     67     SkDynamicMemoryWStream uncompressed;
     68     bool inflateSuccess = SkFlate::Inflate(testStream, &uncompressed);
     69     REPORTER_ASSERT(reporter, inflateSuccess);
     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     }
     76     REPORTER_ASSERT(reporter,  compressedSize == inputSize);
     77     if (compressedData->size() == inputSize) {
     78         REPORTER_ASSERT(reporter, memcmp(testStream->getMemoryBase(),
     79                                          compressedData->data(),
     80                                          compressedData->size()) == 0);
     81     }
     82 
     83     // Check that the uncompressed data matches the source data.
     84     SkAutoDataUnref uncompressedData(uncompressed.copyToData());
     85     REPORTER_ASSERT(reporter, dataSize == uncompressedData->size());
     86     if (dataSize == uncompressedData->size()) {
     87         REPORTER_ASSERT(reporter, memcmp(testData->data(),
     88                                          uncompressedData->data(),
     89                                          dataSize) == 0);
     90     }
     91 
     92     if (compressedSize < 1) { return; }
     93 
     94     double compressionRatio = static_cast<double>(dataSize) / compressedSize;
     95     // Assert that some compression took place.
     96     REPORTER_ASSERT(reporter, compressionRatio > 1.2);
     97 
     98     if (reporter->verbose()) {
     99         SkDebugf("Flate Test: \t input size: " SK_SIZE_T_SPECIFIER
    100                  "\tcompressed size: " SK_SIZE_T_SPECIFIER
    101                  "\tratio: %.4g\n",
    102                  dataSize, compressedSize, compressionRatio);
    103     }
    104 }
    105 
    106 DEF_TEST(Flate, reporter) {
    107 #ifdef SK_HAS_ZLIB
    108     REPORTER_ASSERT(reporter, SkFlate::HaveFlate());
    109 #endif
    110     if (SkFlate::HaveFlate()) {
    111         SkMemoryStream memStream;
    112         TestFlate(reporter, &memStream, 512);
    113         TestFlate(reporter, &memStream, 10240);
    114 
    115         SkZeroSizeMemStream fileStream;
    116         TestFlate(reporter, &fileStream, 512);
    117         TestFlate(reporter, &fileStream, 10240);
    118     }
    119 }
    120