PDFDeflateWStreamTest.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * Copyright 2015 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. #include "tests/Test.h"
  8. #ifdef SK_SUPPORT_PDF
  9. #include "include/private/SkTo.h"
  10. #include "include/utils/SkRandom.h"
  11. #include "src/pdf/SkDeflate.h"
  12. namespace {
  13. #include "zlib.h"
  14. // Different zlib implementations use different T.
  15. // We've seen size_t and unsigned.
  16. template <typename T> void* skia_alloc_func(void*, T items, T size) {
  17. return sk_calloc_throw(SkToSizeT(items) * SkToSizeT(size));
  18. }
  19. void skia_free_func(void*, void* address) { sk_free(address); }
  20. /**
  21. * Use the un-deflate compression algorithm to decompress the data in src,
  22. * returning the result. Returns nullptr if an error occurs.
  23. */
  24. std::unique_ptr<SkStreamAsset> stream_inflate(skiatest::Reporter* reporter, SkStream* src) {
  25. SkDynamicMemoryWStream decompressedDynamicMemoryWStream;
  26. SkWStream* dst = &decompressedDynamicMemoryWStream;
  27. static const size_t kBufferSize = 1024;
  28. uint8_t inputBuffer[kBufferSize];
  29. uint8_t outputBuffer[kBufferSize];
  30. z_stream flateData;
  31. flateData.zalloc = &skia_alloc_func;
  32. flateData.zfree = &skia_free_func;
  33. flateData.opaque = nullptr;
  34. flateData.next_in = nullptr;
  35. flateData.avail_in = 0;
  36. flateData.next_out = outputBuffer;
  37. flateData.avail_out = kBufferSize;
  38. int rc;
  39. rc = inflateInit(&flateData);
  40. if (rc != Z_OK) {
  41. ERRORF(reporter, "Zlib: inflateInit failed");
  42. return nullptr;
  43. }
  44. uint8_t* input = (uint8_t*)src->getMemoryBase();
  45. size_t inputLength = src->getLength();
  46. if (input == nullptr || inputLength == 0) {
  47. input = nullptr;
  48. flateData.next_in = inputBuffer;
  49. flateData.avail_in = 0;
  50. } else {
  51. flateData.next_in = input;
  52. flateData.avail_in = SkToUInt(inputLength);
  53. }
  54. rc = Z_OK;
  55. while (true) {
  56. if (flateData.avail_out < kBufferSize) {
  57. if (!dst->write(outputBuffer, kBufferSize - flateData.avail_out)) {
  58. rc = Z_BUF_ERROR;
  59. break;
  60. }
  61. flateData.next_out = outputBuffer;
  62. flateData.avail_out = kBufferSize;
  63. }
  64. if (rc != Z_OK)
  65. break;
  66. if (flateData.avail_in == 0) {
  67. if (input != nullptr)
  68. break;
  69. size_t read = src->read(&inputBuffer, kBufferSize);
  70. if (read == 0)
  71. break;
  72. flateData.next_in = inputBuffer;
  73. flateData.avail_in = SkToUInt(read);
  74. }
  75. rc = inflate(&flateData, Z_NO_FLUSH);
  76. }
  77. while (rc == Z_OK) {
  78. rc = inflate(&flateData, Z_FINISH);
  79. if (flateData.avail_out < kBufferSize) {
  80. if (!dst->write(outputBuffer, kBufferSize - flateData.avail_out)) {
  81. ERRORF(reporter, "write failed");
  82. return nullptr;
  83. }
  84. flateData.next_out = outputBuffer;
  85. flateData.avail_out = kBufferSize;
  86. }
  87. }
  88. inflateEnd(&flateData);
  89. if (rc != Z_STREAM_END) {
  90. ERRORF(reporter, "Zlib: inflateEnd failed");
  91. return nullptr;
  92. }
  93. return decompressedDynamicMemoryWStream.detachAsStream();
  94. }
  95. } // namespace
  96. DEF_TEST(SkPDF_DeflateWStream, r) {
  97. SkRandom random(123456);
  98. for (int i = 0; i < 50; ++i) {
  99. uint32_t size = random.nextULessThan(10000);
  100. SkAutoTMalloc<uint8_t> buffer(size);
  101. for (uint32_t j = 0; j < size; ++j) {
  102. buffer[j] = random.nextU() & 0xff;
  103. }
  104. SkDynamicMemoryWStream dynamicMemoryWStream;
  105. {
  106. SkDeflateWStream deflateWStream(&dynamicMemoryWStream);
  107. uint32_t j = 0;
  108. while (j < size) {
  109. uint32_t writeSize =
  110. SkTMin(size - j, random.nextRangeU(1, 400));
  111. if (!deflateWStream.write(&buffer[j], writeSize)) {
  112. ERRORF(r, "something went wrong.");
  113. return;
  114. }
  115. j += writeSize;
  116. }
  117. REPORTER_ASSERT(r, deflateWStream.bytesWritten() == size);
  118. }
  119. std::unique_ptr<SkStreamAsset> compressed(dynamicMemoryWStream.detachAsStream());
  120. std::unique_ptr<SkStreamAsset> decompressed(stream_inflate(r, compressed.get()));
  121. if (!decompressed) {
  122. ERRORF(r, "Decompression failed.");
  123. return;
  124. }
  125. if (decompressed->getLength() != size) {
  126. ERRORF(r, "Decompression failed to get right size [%d]."
  127. " %u != %u", i, (unsigned)(decompressed->getLength()),
  128. (unsigned)size);
  129. SkString s = SkStringPrintf("/tmp/deftst_compressed_%d", i);
  130. SkFILEWStream o(s.c_str());
  131. o.writeStream(compressed.get(), compressed->getLength());
  132. compressed->rewind();
  133. s = SkStringPrintf("/tmp/deftst_input_%d", i);
  134. SkFILEWStream o2(s.c_str());
  135. o2.write(&buffer[0], size);
  136. continue;
  137. }
  138. uint32_t minLength = SkTMin(size,
  139. (uint32_t)(decompressed->getLength()));
  140. for (uint32_t i = 0; i < minLength; ++i) {
  141. uint8_t c;
  142. SkDEBUGCODE(size_t rb =)decompressed->read(&c, sizeof(uint8_t));
  143. SkASSERT(sizeof(uint8_t) == rb);
  144. if (buffer[i] != c) {
  145. ERRORF(r, "Decompression failed at byte %u.", (unsigned)i);
  146. break;
  147. }
  148. }
  149. }
  150. SkDeflateWStream emptyDeflateWStream(nullptr);
  151. REPORTER_ASSERT(r, !emptyDeflateWStream.writeText("FOO"));
  152. }
  153. #endif