xref: /aosp_15_r20/external/pdfium/core/fxcodec/basic/rle_unittest.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2016 The PDFium Authors
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 #include <memory>
9 
10 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
11 #include "core/fxcodec/basic/basicmodule.h"
12 #include "core/fxcrt/data_vector.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 
TEST(fxcodec,RLEEmptyInput)15 TEST(fxcodec, RLEEmptyInput) {
16   EXPECT_TRUE(BasicModule::RunLengthEncode({}).empty());
17 }
18 
19 // Check length 1 input works. Check terminating character is applied.
TEST(fxcodec,RLEShortInput)20 TEST(fxcodec, RLEShortInput) {
21   const uint8_t src_buf[] = {1};
22   DataVector<uint8_t> dest_buf = BasicModule::RunLengthEncode(src_buf);
23   ASSERT_EQ(3u, dest_buf.size());
24   EXPECT_EQ(0, dest_buf[0]);
25   EXPECT_EQ(1, dest_buf[1]);
26   EXPECT_EQ(128, dest_buf[2]);
27 }
28 
29 // Check a few basic cases (2 matching runs in a row, matching run followed
30 // by a non-matching run, and non-matching run followed by a matching run).
TEST(fxcodec,RLENormalInputs)31 TEST(fxcodec, RLENormalInputs) {
32   std::unique_ptr<uint8_t, FxFreeDeleter> decoded_buf;
33   uint32_t decoded_size = 0;
34 
35   {
36     // Case 1: Match, match
37     const uint8_t src_buf_1[] = {2, 2, 2, 2, 4, 4, 4, 4, 4, 4};
38     DataVector<uint8_t> dest_buf = BasicModule::RunLengthEncode(src_buf_1);
39     RunLengthDecode(dest_buf, &decoded_buf, &decoded_size);
40     ASSERT_EQ(sizeof(src_buf_1), decoded_size);
41     auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
42     for (uint32_t i = 0; i < decoded_size; i++)
43       EXPECT_EQ(src_buf_1[i], decoded_buf_span[i]) << " at " << i;
44   }
45 
46   {
47     // Case 2: Match, non-match
48     const uint8_t src_buf_2[] = {2, 2, 2, 2, 1, 2, 3, 4, 5, 6};
49     DataVector<uint8_t> dest_buf = BasicModule::RunLengthEncode(src_buf_2);
50     decoded_buf.reset();
51     decoded_size = 0;
52     RunLengthDecode(dest_buf, &decoded_buf, &decoded_size);
53     ASSERT_EQ(sizeof(src_buf_2), decoded_size);
54     auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
55     for (uint32_t i = 0; i < decoded_size; i++)
56       EXPECT_EQ(src_buf_2[i], decoded_buf_span[i]) << " at " << i;
57   }
58 
59   {
60     // Case 3: Non-match, match
61     const uint8_t src_buf_3[] = {1, 2, 3, 4, 5, 3, 3, 3, 3, 3};
62     DataVector<uint8_t> dest_buf = BasicModule::RunLengthEncode(src_buf_3);
63     decoded_buf.reset();
64     decoded_size = 0;
65     RunLengthDecode(dest_buf, &decoded_buf, &decoded_size);
66     ASSERT_EQ(sizeof(src_buf_3), decoded_size);
67     auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
68     for (uint32_t i = 0; i < decoded_size; i++)
69       EXPECT_EQ(src_buf_3[i], decoded_buf_span[i]) << " at " << i;
70   }
71 }
72 
73 // Check that runs longer than 128 are broken up properly, both matched and
74 // non-matched.
TEST(fxcodec,RLEFullLengthInputs)75 TEST(fxcodec, RLEFullLengthInputs) {
76   std::unique_ptr<uint8_t, FxFreeDeleter> decoded_buf;
77   uint32_t decoded_size = 0;
78 
79   {
80     // Case 1: Match, match
81     const uint8_t src_buf_1[260] = {1};
82     DataVector<uint8_t> dest_buf = BasicModule::RunLengthEncode(src_buf_1);
83     RunLengthDecode(dest_buf, &decoded_buf, &decoded_size);
84     ASSERT_EQ(sizeof(src_buf_1), decoded_size);
85     auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
86     for (uint32_t i = 0; i < decoded_size; i++)
87       EXPECT_EQ(src_buf_1[i], decoded_buf_span[i]) << " at " << i;
88   }
89 
90   {
91     // Case 2: Match, non-match
92     uint8_t src_buf_2[260] = {2};
93     for (uint16_t i = 128; i < 260; i++)
94       src_buf_2[i] = static_cast<uint8_t>(i - 125);
95     DataVector<uint8_t> dest_buf = BasicModule::RunLengthEncode(src_buf_2);
96     decoded_buf.reset();
97     decoded_size = 0;
98     RunLengthDecode(dest_buf, &decoded_buf, &decoded_size);
99     ASSERT_EQ(sizeof(src_buf_2), decoded_size);
100     auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
101     for (uint32_t i = 0; i < decoded_size; i++)
102       EXPECT_EQ(src_buf_2[i], decoded_buf_span[i]) << " at " << i;
103   }
104 
105   {
106     // Case 3: Non-match, match
107     uint8_t src_buf_3[260] = {3};
108     for (uint8_t i = 0; i < 128; i++)
109       src_buf_3[i] = i;
110     DataVector<uint8_t> dest_buf = BasicModule::RunLengthEncode(src_buf_3);
111     decoded_buf.reset();
112     decoded_size = 0;
113     RunLengthDecode(dest_buf, &decoded_buf, &decoded_size);
114     ASSERT_EQ(sizeof(src_buf_3), decoded_size);
115     auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
116     for (uint32_t i = 0; i < decoded_size; i++)
117       EXPECT_EQ(src_buf_3[i], decoded_buf_span[i]) << " at " << i;
118   }
119 
120   {
121     // Case 4: Non-match, non-match
122     uint8_t src_buf_4[260];
123     for (uint16_t i = 0; i < 260; i++)
124       src_buf_4[i] = static_cast<uint8_t>(i);
125     DataVector<uint8_t> dest_buf = BasicModule::RunLengthEncode(src_buf_4);
126     decoded_buf.reset();
127     decoded_size = 0;
128     RunLengthDecode(dest_buf, &decoded_buf, &decoded_size);
129     ASSERT_EQ(sizeof(src_buf_4), decoded_size);
130     auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
131     for (uint32_t i = 0; i < decoded_size; i++)
132       EXPECT_EQ(src_buf_4[i], decoded_buf_span[i]) << " at " << i;
133   }
134 }
135