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:
read(void * buffer,size_t size)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
TestFlate(skiatest::Reporter * reporter,SkMemoryStream * testStream,size_t dataSize)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
DEF_TEST(Flate,reporter)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