1// Copyright 2016 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <stdint.h>
6
7#include <limits>
8
9#include "core/fpdfapi/parser/fpdf_parser_decode.h"
10#include "core/fxcodec/codec/ccodec_basicmodule.h"
11#include "core/fxcodec/fx_codec.h"
12#include "testing/gtest/include/gtest/gtest.h"
13
14TEST(fxcodec, RLETestBadInputs) {
15  const uint8_t src_buf[] = {1};
16  uint8_t* dest_buf = nullptr;
17  uint32_t src_size = 4;
18  uint32_t dest_size = 0;
19
20  CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule();
21  EXPECT_TRUE(pEncoders);
22
23  // Error codes, not segvs, should callers pass us a nullptr pointer.
24  EXPECT_FALSE(
25      pEncoders->RunLengthEncode(src_buf, src_size, &dest_buf, nullptr));
26  EXPECT_FALSE(
27      pEncoders->RunLengthEncode(src_buf, src_size, nullptr, &dest_size));
28  EXPECT_FALSE(pEncoders->RunLengthEncode(src_buf, 0, &dest_buf, &dest_size));
29  EXPECT_FALSE(
30      pEncoders->RunLengthEncode(nullptr, src_size, &dest_buf, &dest_size));
31}
32
33// Check length 1 input works. Check terminating character is applied.
34TEST(fxcodec, RLETestShortInput) {
35  const uint8_t src_buf[] = {1};
36  uint8_t* dest_buf = nullptr;
37  uint32_t src_size = 1;
38  uint32_t dest_size = 0;
39
40  CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule();
41  EXPECT_TRUE(pEncoders);
42
43  EXPECT_TRUE(
44      pEncoders->RunLengthEncode(src_buf, src_size, &dest_buf, &dest_size));
45  ASSERT_EQ(3u, dest_size);
46  EXPECT_EQ(0, dest_buf[0]);
47  EXPECT_EQ(1, dest_buf[1]);
48  EXPECT_EQ(128, dest_buf[2]);
49
50  FX_Free(dest_buf);
51}
52
53// Check a few basic cases (2 matching runs in a row, matching run followed
54// by a non-matching run, and non-matching run followed by a matching run).
55TEST(fxcodec, RLETestNormalInputs) {
56  // Match, match
57  const uint8_t src_buf_1[] = {2, 2, 2, 2, 4, 4, 4, 4, 4, 4};
58
59  // Match, non-match
60  const uint8_t src_buf_2[] = {2, 2, 2, 2, 1, 2, 3, 4, 5, 6};
61
62  // Non-match, match
63  const uint8_t src_buf_3[] = {1, 2, 3, 4, 5, 3, 3, 3, 3, 3};
64
65  uint32_t src_size = 10;
66  uint32_t dest_size = 0;
67  uint8_t* dest_buf = nullptr;
68
69  CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule();
70  EXPECT_TRUE(pEncoders);
71
72  // Case 1:
73  EXPECT_TRUE(
74      pEncoders->RunLengthEncode(src_buf_1, src_size, &dest_buf, &dest_size));
75  uint8_t* decoded_buf = nullptr;
76  uint32_t decoded_size = 0;
77  RunLengthDecode(dest_buf, dest_size, &decoded_buf, &decoded_size);
78  ASSERT_EQ(src_size, decoded_size);
79  for (uint32_t i = 0; i < src_size; i++)
80    EXPECT_EQ(src_buf_1[i], decoded_buf[i]) << " at " << i;
81  FX_Free(dest_buf);
82  FX_Free(decoded_buf);
83
84  // Case 2:
85  dest_buf = nullptr;
86  dest_size = 0;
87  EXPECT_TRUE(
88      pEncoders->RunLengthEncode(src_buf_2, src_size, &dest_buf, &dest_size));
89  decoded_buf = nullptr;
90  decoded_size = 0;
91  RunLengthDecode(dest_buf, dest_size, &decoded_buf, &decoded_size);
92  ASSERT_EQ(src_size, decoded_size);
93  for (uint32_t i = 0; i < src_size; i++)
94    EXPECT_EQ(src_buf_2[i], decoded_buf[i]) << " at " << i;
95  FX_Free(dest_buf);
96  FX_Free(decoded_buf);
97
98  // Case 3:
99  dest_buf = nullptr;
100  dest_size = 0;
101  EXPECT_TRUE(
102      pEncoders->RunLengthEncode(src_buf_3, src_size, &dest_buf, &dest_size));
103  decoded_buf = nullptr;
104  decoded_size = 0;
105  RunLengthDecode(dest_buf, dest_size, &decoded_buf, &decoded_size);
106  ASSERT_EQ(src_size, decoded_size);
107  for (uint32_t i = 0; i < src_size; i++)
108    EXPECT_EQ(src_buf_3[i], decoded_buf[i]) << " at " << i;
109  FX_Free(dest_buf);
110  FX_Free(decoded_buf);
111}
112
113// Check that runs longer than 128 are broken up properly, both matched and
114// non-matched.
115TEST(fxcodec, RLETestFullLengthInputs) {
116  // Match, match
117  const uint8_t src_buf_1[260] = {1};
118
119  // Match, non-match
120  uint8_t src_buf_2[260] = {2};
121  for (uint16_t i = 128; i < 260; i++)
122    src_buf_2[i] = (uint8_t)(i - 125);
123
124  // Non-match, match
125  uint8_t src_buf_3[260] = {3};
126  for (uint8_t i = 0; i < 128; i++)
127    src_buf_3[i] = i;
128
129  // Non-match, non-match
130  uint8_t src_buf_4[260];
131  for (uint16_t i = 0; i < 260; i++)
132    src_buf_4[i] = (uint8_t)(i);
133
134  uint32_t src_size = 260;
135  uint32_t dest_size = 0;
136  uint8_t* dest_buf = nullptr;
137
138  CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule();
139  EXPECT_TRUE(pEncoders);
140
141  // Case 1:
142  EXPECT_TRUE(
143      pEncoders->RunLengthEncode(src_buf_1, src_size, &dest_buf, &dest_size));
144  uint8_t* decoded_buf = nullptr;
145  uint32_t decoded_size = 0;
146  RunLengthDecode(dest_buf, dest_size, &decoded_buf, &decoded_size);
147  ASSERT_EQ(src_size, decoded_size);
148  for (uint32_t i = 0; i < src_size; i++)
149    EXPECT_EQ(src_buf_1[i], decoded_buf[i]) << " at " << i;
150  FX_Free(dest_buf);
151  FX_Free(decoded_buf);
152
153  // Case 2:
154  dest_buf = nullptr;
155  dest_size = 0;
156  EXPECT_TRUE(
157      pEncoders->RunLengthEncode(src_buf_2, src_size, &dest_buf, &dest_size));
158  decoded_buf = nullptr;
159  decoded_size = 0;
160  RunLengthDecode(dest_buf, dest_size, &decoded_buf, &decoded_size);
161  ASSERT_EQ(src_size, decoded_size);
162  for (uint32_t i = 0; i < src_size; i++)
163    EXPECT_EQ(src_buf_2[i], decoded_buf[i]) << " at " << i;
164  FX_Free(dest_buf);
165  FX_Free(decoded_buf);
166
167  // Case 3:
168  dest_buf = nullptr;
169  dest_size = 0;
170  EXPECT_TRUE(
171      pEncoders->RunLengthEncode(src_buf_3, src_size, &dest_buf, &dest_size));
172  decoded_buf = nullptr;
173  decoded_size = 0;
174  RunLengthDecode(dest_buf, dest_size, &decoded_buf, &decoded_size);
175  ASSERT_EQ(src_size, decoded_size);
176  for (uint32_t i = 0; i < src_size; i++)
177    EXPECT_EQ(src_buf_3[i], decoded_buf[i]) << " at " << i;
178  FX_Free(dest_buf);
179  FX_Free(decoded_buf);
180
181  // Case 4:
182  dest_buf = nullptr;
183  dest_size = 0;
184  EXPECT_TRUE(
185      pEncoders->RunLengthEncode(src_buf_4, src_size, &dest_buf, &dest_size));
186  decoded_buf = nullptr;
187  decoded_size = 0;
188  RunLengthDecode(dest_buf, dest_size, &decoded_buf, &decoded_size);
189  ASSERT_EQ(src_size, decoded_size);
190  for (uint32_t i = 0; i < src_size; i++)
191    EXPECT_EQ(src_buf_4[i], decoded_buf[i]) << " at " << i;
192  FX_Free(dest_buf);
193  FX_Free(decoded_buf);
194}
195