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