Krita Source Code Documentation
Loading...
Searching...
No Matches
KisRLE Namespace Reference

Functions

QByteArray compress (const QByteArray &data)
 
int compress (const QByteArray &src, QByteArray &dst)
 
QByteArray decompress (const QByteArray &input, int unpacked_len)
 

Function Documentation

◆ compress() [1/2]

QByteArray KisRLE::compress ( const QByteArray & data)

Definition at line 77 of file compression.cpp.

78{
79 QByteArray output;
80 const int result = KisRLE::compress(data, output);
81 if (result <= 0)
82 return QByteArray();
83 else
84 return output;
85}
int compress(const QByteArray &src, QByteArray &dst)

References compress().

◆ compress() [2/2]

int KisRLE::compress ( const QByteArray & src,
QByteArray & dst )

Definition at line 23 of file compression.cpp.

24{
25 int length = src.size();
26 dst.resize(length * 2);
27 dst.fill(0, length * 2);
28
29 int remaining = length;
30 quint8 i, j;
31 quint32 dest_ptr = 0;
32 const char *start = src.constData();
33
34 length = 0;
35 while (remaining > 0) {
36 /* Look for characters matching the first */
37 i = 0;
38 while ((i < 128) && (remaining - i > 0) && (start[0] == start[i]))
39 i++;
40
41 if (i > 1) /* Match found */
42 {
43 dst[dest_ptr++] = static_cast<char>(-(i - 1));
44 dst[dest_ptr++] = *start;
45
46 start += i;
47 remaining -= i;
48 length += 2;
49 } else { /* Look for characters different from the previous */
50 i = 0;
51 while ((i < 128) && (remaining - (i + 1) > 0) && (start[i] != start[(i + 1)] || remaining - (i + 2) <= 0 || start[i] != start[(i + 2)]))
52 i++;
53
54 /* If there's only 1 remaining, the previous WHILE stmt doesn't
55 catch it */
56
57 if (remaining == 1) {
58 i = 1;
59 }
60
61 if (i > 0) /* Some distinct ones found */
62 {
63 dst[dest_ptr++] = static_cast<char>(i - 1U);
64 for (j = 0; j < i; j++) {
65 dst[dest_ptr++] = start[j];
66 }
67 start += i;
68 remaining -= i;
69 length += i + 1;
70 }
71 }
72 }
73 dst.resize(length);
74 return length;
75}
qreal length(const QPointF &vec)
Definition Ellipse.cc:82

References length().

◆ decompress()

QByteArray KisRLE::decompress ( const QByteArray & input,
int unpacked_len )

Definition at line 87 of file compression.cpp.

88{
89 QByteArray output;
90 output.resize(unpacked_len);
91
92 const auto *src = input.cbegin();
93 auto *dst = output.begin();
94
95 while (src < input.end() && dst < output.end()) {
96 // NOLINTNEXTLINE(*-reinterpret-cast,readability-identifier-length)
97 const int8_t n = *reinterpret_cast<const int8_t *>(src);
98 src += 1;
99
100 if (n >= 0) { // copy next n+1 chars
101 const int bytes = 1 + n;
102 if (src + bytes > input.cend()) {
103 errFile << "Input buffer exhausted in replicate of" << bytes << "chars, left" << (input.cend() - src);
104 return {};
105 }
106 if (dst + bytes > output.end()) {
107 errFile << "Overrun in packbits replicate of" << bytes << "chars, left" << (output.end() - dst);
108 return {};
109 }
110 std::copy_n(src, bytes, dst);
111 src += bytes;
112 dst += bytes;
113 } else if (n >= -127 && n <= -1) { // replicate next char -n+1 times
114 const int bytes = 1 - n;
115 if (src >= input.cend()) {
116 errFile << "Input buffer exhausted in copy";
117 return {};
118 }
119 if (dst + bytes > output.end()) {
120 errFile << "Output buffer exhausted in copy of" << bytes << "chars, left" << (output.end() - dst);
121 return {};
122 }
123 const auto byte = *src;
124 std::fill_n(dst, bytes, byte);
125 src += 1;
126 dst += bytes;
127 } else if (n == -128) {
128 continue;
129 }
130 }
131
132 if (dst < output.end()) {
133 errFile << "Packbits decode - unpack left" << (output.end() - dst);
134 std::fill(dst, output.end(), 0);
135 }
136
137 // If the input line was odd width, there's a padding byte
138 if (src + 1 < input.cend()) {
139 QByteArray leftovers;
140 leftovers.resize(static_cast<int>(input.cend() - src));
141 std::copy(src, input.cend(), leftovers.begin());
142 errFile << "Packbits decode - pack left" << leftovers.size() << leftovers.toHex();
143 }
144
145 return output;
146}
#define errFile
Definition kis_debug.h:115

References errFile.