PDFDeflateWStreamTest.cpp revision 2880df2609eba09b555ca37be04b6ad89290c765
12880df2609eba09b555ca37be04b6ad89290c765Tom Hudson/* 22880df2609eba09b555ca37be04b6ad89290c765Tom Hudson * Copyright 2015 Google Inc. 32880df2609eba09b555ca37be04b6ad89290c765Tom Hudson * 42880df2609eba09b555ca37be04b6ad89290c765Tom Hudson * Use of this source code is governed by a BSD-style license that can be 52880df2609eba09b555ca37be04b6ad89290c765Tom Hudson * found in the LICENSE file. 62880df2609eba09b555ca37be04b6ad89290c765Tom Hudson */ 72880df2609eba09b555ca37be04b6ad89290c765Tom Hudson 82880df2609eba09b555ca37be04b6ad89290c765Tom Hudson#include "SkDeflate.h" 92880df2609eba09b555ca37be04b6ad89290c765Tom Hudson#include "SkRandom.h" 102880df2609eba09b555ca37be04b6ad89290c765Tom Hudson#include "Test.h" 112880df2609eba09b555ca37be04b6ad89290c765Tom Hudson 122880df2609eba09b555ca37be04b6ad89290c765Tom Hudsonnamespace { 132880df2609eba09b555ca37be04b6ad89290c765Tom Hudson 142880df2609eba09b555ca37be04b6ad89290c765Tom Hudson#ifdef ZLIB_INCLUDE 152880df2609eba09b555ca37be04b6ad89290c765Tom Hudson #include ZLIB_INCLUDE 162880df2609eba09b555ca37be04b6ad89290c765Tom Hudson#else 172880df2609eba09b555ca37be04b6ad89290c765Tom Hudson #include "zlib.h" 182880df2609eba09b555ca37be04b6ad89290c765Tom Hudson#endif 192880df2609eba09b555ca37be04b6ad89290c765Tom Hudson 202880df2609eba09b555ca37be04b6ad89290c765Tom Hudson// Different zlib implementations use different T. 212880df2609eba09b555ca37be04b6ad89290c765Tom Hudson// We've seen size_t and unsigned. 222880df2609eba09b555ca37be04b6ad89290c765Tom Hudsontemplate <typename T> void* skia_alloc_func(void*, T items, T size) { 232880df2609eba09b555ca37be04b6ad89290c765Tom Hudson return sk_calloc_throw(SkToSizeT(items) * SkToSizeT(size)); 242880df2609eba09b555ca37be04b6ad89290c765Tom Hudson} 252880df2609eba09b555ca37be04b6ad89290c765Tom Hudson 262880df2609eba09b555ca37be04b6ad89290c765Tom Hudsonvoid skia_free_func(void*, void* address) { sk_free(address); } 272880df2609eba09b555ca37be04b6ad89290c765Tom Hudson 282880df2609eba09b555ca37be04b6ad89290c765Tom Hudson/** 292880df2609eba09b555ca37be04b6ad89290c765Tom Hudson * Use the un-deflate compression algorithm to decompress the data in src, 302880df2609eba09b555ca37be04b6ad89290c765Tom Hudson * returning the result. Returns nullptr if an error occurs. 312880df2609eba09b555ca37be04b6ad89290c765Tom Hudson */ 322880df2609eba09b555ca37be04b6ad89290c765Tom HudsonSkStreamAsset* stream_inflate(SkStream* src) { 332880df2609eba09b555ca37be04b6ad89290c765Tom Hudson SkDynamicMemoryWStream decompressedDynamicMemoryWStream; 342880df2609eba09b555ca37be04b6ad89290c765Tom Hudson SkWStream* dst = &decompressedDynamicMemoryWStream; 352880df2609eba09b555ca37be04b6ad89290c765Tom Hudson 362880df2609eba09b555ca37be04b6ad89290c765Tom Hudson static const size_t kBufferSize = 1024; 372880df2609eba09b555ca37be04b6ad89290c765Tom Hudson uint8_t inputBuffer[kBufferSize]; 382880df2609eba09b555ca37be04b6ad89290c765Tom Hudson uint8_t outputBuffer[kBufferSize]; 392880df2609eba09b555ca37be04b6ad89290c765Tom Hudson z_stream flateData; 402880df2609eba09b555ca37be04b6ad89290c765Tom Hudson flateData.zalloc = &skia_alloc_func; 412880df2609eba09b555ca37be04b6ad89290c765Tom Hudson flateData.zfree = &skia_free_func; 422880df2609eba09b555ca37be04b6ad89290c765Tom Hudson flateData.opaque = nullptr; 432880df2609eba09b555ca37be04b6ad89290c765Tom Hudson flateData.next_in = nullptr; 442880df2609eba09b555ca37be04b6ad89290c765Tom Hudson flateData.avail_in = 0; 452880df2609eba09b555ca37be04b6ad89290c765Tom Hudson flateData.next_out = outputBuffer; 462880df2609eba09b555ca37be04b6ad89290c765Tom Hudson flateData.avail_out = kBufferSize; 472880df2609eba09b555ca37be04b6ad89290c765Tom Hudson int rc; 482880df2609eba09b555ca37be04b6ad89290c765Tom Hudson rc = inflateInit(&flateData); 492880df2609eba09b555ca37be04b6ad89290c765Tom Hudson if (rc != Z_OK) 502880df2609eba09b555ca37be04b6ad89290c765Tom Hudson return nullptr; 512880df2609eba09b555ca37be04b6ad89290c765Tom Hudson 522880df2609eba09b555ca37be04b6ad89290c765Tom Hudson uint8_t* input = (uint8_t*)src->getMemoryBase(); 532880df2609eba09b555ca37be04b6ad89290c765Tom Hudson size_t inputLength = src->getLength(); 542880df2609eba09b555ca37be04b6ad89290c765Tom Hudson if (input == nullptr || inputLength == 0) { 552880df2609eba09b555ca37be04b6ad89290c765Tom Hudson input = nullptr; 562880df2609eba09b555ca37be04b6ad89290c765Tom Hudson flateData.next_in = inputBuffer; 572880df2609eba09b555ca37be04b6ad89290c765Tom Hudson flateData.avail_in = 0; 582880df2609eba09b555ca37be04b6ad89290c765Tom Hudson } else { 592880df2609eba09b555ca37be04b6ad89290c765Tom Hudson flateData.next_in = input; 602880df2609eba09b555ca37be04b6ad89290c765Tom Hudson flateData.avail_in = SkToUInt(inputLength); 612880df2609eba09b555ca37be04b6ad89290c765Tom Hudson } 622880df2609eba09b555ca37be04b6ad89290c765Tom Hudson 632880df2609eba09b555ca37be04b6ad89290c765Tom Hudson rc = Z_OK; 642880df2609eba09b555ca37be04b6ad89290c765Tom Hudson while (true) { 652880df2609eba09b555ca37be04b6ad89290c765Tom Hudson if (flateData.avail_out < kBufferSize) { 662880df2609eba09b555ca37be04b6ad89290c765Tom Hudson if (!dst->write(outputBuffer, kBufferSize - flateData.avail_out)) { 672880df2609eba09b555ca37be04b6ad89290c765Tom Hudson rc = Z_BUF_ERROR; 682880df2609eba09b555ca37be04b6ad89290c765Tom Hudson break; 692880df2609eba09b555ca37be04b6ad89290c765Tom Hudson } 702880df2609eba09b555ca37be04b6ad89290c765Tom Hudson flateData.next_out = outputBuffer; 712880df2609eba09b555ca37be04b6ad89290c765Tom Hudson flateData.avail_out = kBufferSize; 722880df2609eba09b555ca37be04b6ad89290c765Tom Hudson } 732880df2609eba09b555ca37be04b6ad89290c765Tom Hudson if (rc != Z_OK) 742880df2609eba09b555ca37be04b6ad89290c765Tom Hudson break; 752880df2609eba09b555ca37be04b6ad89290c765Tom Hudson if (flateData.avail_in == 0) { 762880df2609eba09b555ca37be04b6ad89290c765Tom Hudson if (input != nullptr) 772880df2609eba09b555ca37be04b6ad89290c765Tom Hudson break; 782880df2609eba09b555ca37be04b6ad89290c765Tom Hudson size_t read = src->read(&inputBuffer, kBufferSize); 792880df2609eba09b555ca37be04b6ad89290c765Tom Hudson if (read == 0) 802880df2609eba09b555ca37be04b6ad89290c765Tom Hudson break; 812880df2609eba09b555ca37be04b6ad89290c765Tom Hudson flateData.next_in = inputBuffer; 822880df2609eba09b555ca37be04b6ad89290c765Tom Hudson flateData.avail_in = SkToUInt(read); 832880df2609eba09b555ca37be04b6ad89290c765Tom Hudson } 842880df2609eba09b555ca37be04b6ad89290c765Tom Hudson rc = inflate(&flateData, Z_NO_FLUSH); 852880df2609eba09b555ca37be04b6ad89290c765Tom Hudson } 862880df2609eba09b555ca37be04b6ad89290c765Tom Hudson while (rc == Z_OK) { 872880df2609eba09b555ca37be04b6ad89290c765Tom Hudson rc = inflate(&flateData, Z_FINISH); 882880df2609eba09b555ca37be04b6ad89290c765Tom Hudson if (flateData.avail_out < kBufferSize) { 892880df2609eba09b555ca37be04b6ad89290c765Tom Hudson if (!dst->write(outputBuffer, kBufferSize - flateData.avail_out)) 902880df2609eba09b555ca37be04b6ad89290c765Tom Hudson return nullptr; 912880df2609eba09b555ca37be04b6ad89290c765Tom Hudson flateData.next_out = outputBuffer; 922880df2609eba09b555ca37be04b6ad89290c765Tom Hudson flateData.avail_out = kBufferSize; 932880df2609eba09b555ca37be04b6ad89290c765Tom Hudson } 942880df2609eba09b555ca37be04b6ad89290c765Tom Hudson } 952880df2609eba09b555ca37be04b6ad89290c765Tom Hudson 962880df2609eba09b555ca37be04b6ad89290c765Tom Hudson inflateEnd(&flateData); 972880df2609eba09b555ca37be04b6ad89290c765Tom Hudson if (rc != Z_STREAM_END) { 982880df2609eba09b555ca37be04b6ad89290c765Tom Hudson return nullptr; 992880df2609eba09b555ca37be04b6ad89290c765Tom Hudson } 1002880df2609eba09b555ca37be04b6ad89290c765Tom Hudson return decompressedDynamicMemoryWStream.detachAsStream(); 1012880df2609eba09b555ca37be04b6ad89290c765Tom Hudson} 1022880df2609eba09b555ca37be04b6ad89290c765Tom Hudson} // namespace 1032880df2609eba09b555ca37be04b6ad89290c765Tom Hudson 1042880df2609eba09b555ca37be04b6ad89290c765Tom HudsonDEF_TEST(SkDeflateWStream, r) { 1052880df2609eba09b555ca37be04b6ad89290c765Tom Hudson SkRandom random(123456); 1062880df2609eba09b555ca37be04b6ad89290c765Tom Hudson for (int i = 0; i < 50; ++i) { 1072880df2609eba09b555ca37be04b6ad89290c765Tom Hudson uint32_t size = random.nextULessThan(10000); 1082880df2609eba09b555ca37be04b6ad89290c765Tom Hudson SkAutoTMalloc<uint8_t> buffer(size); 1092880df2609eba09b555ca37be04b6ad89290c765Tom Hudson for (uint32_t j = 0; j < size; ++j) { 1102880df2609eba09b555ca37be04b6ad89290c765Tom Hudson buffer[j] = random.nextU() & 0xff; 1112880df2609eba09b555ca37be04b6ad89290c765Tom Hudson } 1122880df2609eba09b555ca37be04b6ad89290c765Tom Hudson 1132880df2609eba09b555ca37be04b6ad89290c765Tom Hudson SkDynamicMemoryWStream dynamicMemoryWStream; 1142880df2609eba09b555ca37be04b6ad89290c765Tom Hudson { 1152880df2609eba09b555ca37be04b6ad89290c765Tom Hudson SkDeflateWStream deflateWStream(&dynamicMemoryWStream); 1162880df2609eba09b555ca37be04b6ad89290c765Tom Hudson uint32_t j = 0; 1172880df2609eba09b555ca37be04b6ad89290c765Tom Hudson while (j < size) { 1182880df2609eba09b555ca37be04b6ad89290c765Tom Hudson uint32_t writeSize = 1192880df2609eba09b555ca37be04b6ad89290c765Tom Hudson SkTMin(size - j, random.nextRangeU(1, 400)); 1202880df2609eba09b555ca37be04b6ad89290c765Tom Hudson if (!deflateWStream.write(&buffer[j], writeSize)) { 1212880df2609eba09b555ca37be04b6ad89290c765Tom Hudson ERRORF(r, "something went wrong."); 1222880df2609eba09b555ca37be04b6ad89290c765Tom Hudson return; 1232880df2609eba09b555ca37be04b6ad89290c765Tom Hudson } 1242880df2609eba09b555ca37be04b6ad89290c765Tom Hudson j += writeSize; 1252880df2609eba09b555ca37be04b6ad89290c765Tom Hudson } 1262880df2609eba09b555ca37be04b6ad89290c765Tom Hudson } 1272880df2609eba09b555ca37be04b6ad89290c765Tom Hudson SkAutoTDelete<SkStreamAsset> compressed( 1282880df2609eba09b555ca37be04b6ad89290c765Tom Hudson dynamicMemoryWStream.detachAsStream()); 1292880df2609eba09b555ca37be04b6ad89290c765Tom Hudson SkAutoTDelete<SkStreamAsset> decompressed(stream_inflate(compressed)); 1302880df2609eba09b555ca37be04b6ad89290c765Tom Hudson 1312880df2609eba09b555ca37be04b6ad89290c765Tom Hudson if (decompressed->getLength() != size) { 1322880df2609eba09b555ca37be04b6ad89290c765Tom Hudson ERRORF(r, "Decompression failed to get right size [%d]." 1332880df2609eba09b555ca37be04b6ad89290c765Tom Hudson " %u != %u", i, (unsigned)(decompressed->getLength()), 1342880df2609eba09b555ca37be04b6ad89290c765Tom Hudson (unsigned)size); 1352880df2609eba09b555ca37be04b6ad89290c765Tom Hudson SkString s = SkStringPrintf("/tmp/deftst_compressed_%d", i); 1362880df2609eba09b555ca37be04b6ad89290c765Tom Hudson SkFILEWStream o(s.c_str()); 1372880df2609eba09b555ca37be04b6ad89290c765Tom Hudson o.writeStream(compressed.get(), compressed->getLength()); 1382880df2609eba09b555ca37be04b6ad89290c765Tom Hudson compressed->rewind(); 1392880df2609eba09b555ca37be04b6ad89290c765Tom Hudson 1402880df2609eba09b555ca37be04b6ad89290c765Tom Hudson s = SkStringPrintf("/tmp/deftst_input_%d", i); 1412880df2609eba09b555ca37be04b6ad89290c765Tom Hudson SkFILEWStream o2(s.c_str()); 1422880df2609eba09b555ca37be04b6ad89290c765Tom Hudson o2.write(&buffer[0], size); 1432880df2609eba09b555ca37be04b6ad89290c765Tom Hudson 1442880df2609eba09b555ca37be04b6ad89290c765Tom Hudson continue; 1452880df2609eba09b555ca37be04b6ad89290c765Tom Hudson } 1462880df2609eba09b555ca37be04b6ad89290c765Tom Hudson uint32_t minLength = SkTMin(size, 1472880df2609eba09b555ca37be04b6ad89290c765Tom Hudson (uint32_t)(decompressed->getLength())); 1482880df2609eba09b555ca37be04b6ad89290c765Tom Hudson for (uint32_t i = 0; i < minLength; ++i) { 1492880df2609eba09b555ca37be04b6ad89290c765Tom Hudson uint8_t c; 1502880df2609eba09b555ca37be04b6ad89290c765Tom Hudson SkDEBUGCODE(size_t rb =)decompressed->read(&c, sizeof(uint8_t)); 1512880df2609eba09b555ca37be04b6ad89290c765Tom Hudson SkASSERT(sizeof(uint8_t) == rb); 1522880df2609eba09b555ca37be04b6ad89290c765Tom Hudson if (buffer[i] != c) { 1532880df2609eba09b555ca37be04b6ad89290c765Tom Hudson ERRORF(r, "Decompression failed at byte %u.", (unsigned)i); 1542880df2609eba09b555ca37be04b6ad89290c765Tom Hudson break; 1552880df2609eba09b555ca37be04b6ad89290c765Tom Hudson } 1562880df2609eba09b555ca37be04b6ad89290c765Tom Hudson } 1572880df2609eba09b555ca37be04b6ad89290c765Tom Hudson } 1582880df2609eba09b555ca37be04b6ad89290c765Tom Hudson} 159