OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
| 7 #include <algorithm> |
| 8 #include <vector> |
| 9 |
7 #include "core/fxcodec/codec/codec_int.h" | 10 #include "core/fxcodec/codec/codec_int.h" |
8 #include "core/fxcodec/include/fx_codec.h" | 11 #include "core/fxcodec/include/fx_codec.h" |
9 | 12 |
10 namespace { | 13 namespace { |
11 | 14 |
12 const uint8_t OneLeadPos[256] = { | 15 const uint8_t OneLeadPos[256] = { |
13 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, | 16 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, |
14 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | 17 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
15 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, | 18 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, |
16 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | 19 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
(...skipping 15 matching lines...) Expand all Loading... |
32 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | 35 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
33 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | 36 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
34 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | 37 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
35 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | 38 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, |
36 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, | 39 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, |
37 }; | 40 }; |
38 | 41 |
39 // Limit of image dimension, an arbitrary large number. | 42 // Limit of image dimension, an arbitrary large number. |
40 const int kMaxImageDimension = 0x01FFFF; | 43 const int kMaxImageDimension = 0x01FFFF; |
41 | 44 |
42 int FindBit(const uint8_t* data_buf, int max_pos, int start_pos, int bit) { | 45 int FindBit(const std::vector<uint8_t>& data_buf, |
| 46 int max_pos, |
| 47 int start_pos, |
| 48 int bit) { |
43 ASSERT(start_pos >= 0); | 49 ASSERT(start_pos >= 0); |
44 if (start_pos >= max_pos) { | 50 if (start_pos >= max_pos) |
45 return max_pos; | 51 return max_pos; |
46 } | 52 |
47 const uint8_t* leading_pos = bit ? OneLeadPos : ZeroLeadPos; | 53 const uint8_t* leading_pos = bit ? OneLeadPos : ZeroLeadPos; |
48 if (start_pos % 8) { | 54 if (start_pos % 8) { |
49 uint8_t data = data_buf[start_pos / 8]; | 55 uint8_t data = data_buf[start_pos / 8]; |
50 if (bit) { | 56 if (bit) |
51 data &= 0xff >> (start_pos % 8); | 57 data &= 0xff >> (start_pos % 8); |
52 } else { | 58 else |
53 data |= 0xff << (8 - start_pos % 8); | 59 data |= 0xff << (8 - start_pos % 8); |
54 } | 60 |
55 if (leading_pos[data] < 8) { | 61 if (leading_pos[data] < 8) |
56 return start_pos / 8 * 8 + leading_pos[data]; | 62 return start_pos / 8 * 8 + leading_pos[data]; |
57 } | 63 |
58 start_pos += 7; | 64 start_pos += 7; |
59 } | 65 } |
60 uint8_t skip = bit ? 0x00 : 0xff; | 66 uint8_t skip = bit ? 0x00 : 0xff; |
61 int byte_pos = start_pos / 8; | 67 int byte_pos = start_pos / 8; |
62 int max_byte = (max_pos + 7) / 8; | 68 int max_byte = (max_pos + 7) / 8; |
63 while (byte_pos < max_byte) { | 69 while (byte_pos < max_byte) { |
64 if (data_buf[byte_pos] != skip) { | 70 if (data_buf[byte_pos] != skip) |
65 break; | 71 break; |
66 } | 72 |
67 byte_pos++; | 73 ++byte_pos; |
68 } | 74 } |
69 if (byte_pos == max_byte) { | 75 if (byte_pos == max_byte) |
70 return max_pos; | 76 return max_pos; |
71 } | 77 |
72 int pos = leading_pos[data_buf[byte_pos]] + byte_pos * 8; | 78 return std::min(leading_pos[data_buf[byte_pos]] + byte_pos * 8, max_pos); |
73 if (pos > max_pos) { | |
74 pos = max_pos; | |
75 } | |
76 return pos; | |
77 } | 79 } |
78 | 80 |
79 void FaxG4FindB1B2(const uint8_t* ref_buf, | 81 void FaxG4FindB1B2(const std::vector<uint8_t>& ref_buf, |
80 int columns, | 82 int columns, |
81 int a0, | 83 int a0, |
82 bool a0color, | 84 bool a0color, |
83 int& b1, | 85 int* b1, |
84 int& b2) { | 86 int* b2) { |
85 uint8_t first_bit = | 87 uint8_t first_bit = |
86 (a0 < 0) ? 1 : ((ref_buf[a0 / 8] & (1 << (7 - a0 % 8))) != 0); | 88 (a0 < 0) ? 1 : ((ref_buf[a0 / 8] & (1 << (7 - a0 % 8))) != 0); |
87 b1 = FindBit(ref_buf, columns, a0 + 1, !first_bit); | 89 *b1 = FindBit(ref_buf, columns, a0 + 1, !first_bit); |
88 if (b1 >= columns) { | 90 if (*b1 >= columns) { |
89 b1 = b2 = columns; | 91 *b1 = *b2 = columns; |
90 return; | 92 return; |
91 } | 93 } |
92 if (first_bit == !a0color) { | 94 if (first_bit == !a0color) { |
93 b1 = FindBit(ref_buf, columns, b1 + 1, first_bit); | 95 *b1 = FindBit(ref_buf, columns, *b1 + 1, first_bit); |
94 first_bit = !first_bit; | 96 first_bit = !first_bit; |
95 } | 97 } |
96 if (b1 >= columns) { | 98 if (*b1 >= columns) { |
97 b1 = b2 = columns; | 99 *b1 = *b2 = columns; |
98 return; | 100 return; |
99 } | 101 } |
100 b2 = FindBit(ref_buf, columns, b1 + 1, first_bit); | 102 *b2 = FindBit(ref_buf, columns, *b1 + 1, first_bit); |
101 } | 103 } |
102 | 104 |
103 void FaxFillBits(uint8_t* dest_buf, int columns, int startpos, int endpos) { | 105 void FaxFillBits(uint8_t* dest_buf, int columns, int startpos, int endpos) { |
104 if (startpos < 0) { | 106 startpos = std::max(startpos, 0); |
105 startpos = 0; | 107 endpos = std::min(std::max(endpos, 0), columns); |
106 } | 108 if (startpos >= endpos) |
107 if (endpos < 0) { | |
108 endpos = 0; | |
109 } | |
110 if (endpos >= columns) { | |
111 endpos = columns; | |
112 } | |
113 if (startpos >= endpos) { | |
114 return; | 109 return; |
115 } | 110 |
116 int first_byte = startpos / 8; | 111 int first_byte = startpos / 8; |
117 int last_byte = (endpos - 1) / 8; | 112 int last_byte = (endpos - 1) / 8; |
118 if (first_byte == last_byte) { | 113 if (first_byte == last_byte) { |
119 for (int i = startpos % 8; i <= (endpos - 1) % 8; i++) { | 114 for (int i = startpos % 8; i <= (endpos - 1) % 8; ++i) |
120 dest_buf[first_byte] -= 1 << (7 - i); | 115 dest_buf[first_byte] -= 1 << (7 - i); |
121 } | |
122 return; | 116 return; |
123 } | 117 } |
124 int i; | 118 |
125 for (i = startpos % 8; i < 8; i++) { | 119 for (int i = startpos % 8; i < 8; ++i) |
126 dest_buf[first_byte] -= 1 << (7 - i); | 120 dest_buf[first_byte] -= 1 << (7 - i); |
127 } | 121 for (int i = 0; i <= (endpos - 1) % 8; ++i) |
128 for (i = 0; i <= (endpos - 1) % 8; i++) { | |
129 dest_buf[last_byte] -= 1 << (7 - i); | 122 dest_buf[last_byte] -= 1 << (7 - i); |
130 } | 123 |
131 if (last_byte > first_byte + 1) { | 124 if (last_byte > first_byte + 1) |
132 FXSYS_memset(dest_buf + first_byte + 1, 0, last_byte - first_byte - 1); | 125 FXSYS_memset(dest_buf + first_byte + 1, 0, last_byte - first_byte - 1); |
133 } | |
134 } | 126 } |
135 | 127 |
136 #define NEXTBIT \ | 128 #define NEXTBIT() \ |
137 src_buf[bitpos / 8] & (1 << (7 - bitpos % 8)); \ | 129 src_buf[*bitpos / 8] & (1 << (7 - *bitpos % 8)); \ |
138 bitpos++; | 130 ++(*bitpos); |
139 | 131 |
140 const uint8_t FaxBlackRunIns[] = { | 132 const uint8_t FaxBlackRunIns[] = { |
141 0, 2, 0x02, 3, 0, 0x03, | 133 0, 2, 0x02, 3, 0, 0x03, |
142 2, 0, 2, 0x02, 1, 0, | 134 2, 0, 2, 0x02, 1, 0, |
143 0x03, 4, 0, 2, 0x02, 6, | 135 0x03, 4, 0, 2, 0x02, 6, |
144 0, 0x03, 5, 0, 1, 0x03, | 136 0, 0x03, 5, 0, 1, 0x03, |
145 7, 0, 2, 0x04, 9, 0, | 137 7, 0, 2, 0x04, 9, 0, |
146 0x05, 8, 0, 3, 0x04, 10, | 138 0x05, 8, 0, 3, 0x04, 10, |
147 0, 0x05, 11, 0, 0x07, 12, | 139 0, 0x05, 11, 0, 0x07, 12, |
148 0, 2, 0x04, 13, 0, 0x07, | 140 0, 2, 0x04, 13, 0, 0x07, |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 0x12, 1984 % 256, 1984 / 256, 0x13, 2048 % 256, 2048 / 256, | 239 0x12, 1984 % 256, 1984 / 256, 0x13, 2048 % 256, 2048 / 256, |
248 0x14, 2112 % 256, 2112 / 256, 0x15, 2176 % 256, 2176 / 256, | 240 0x14, 2112 % 256, 2112 / 256, 0x15, 2176 % 256, 2176 / 256, |
249 0x16, 2240 % 256, 2240 / 256, 0x17, 2304 % 256, 2304 / 256, | 241 0x16, 2240 % 256, 2240 / 256, 0x17, 2304 % 256, 2304 / 256, |
250 0x1c, 2368 % 256, 2368 / 256, 0x1d, 2432 % 256, 2432 / 256, | 242 0x1c, 2368 % 256, 2368 / 256, 0x1d, 2432 % 256, 2432 / 256, |
251 0x1e, 2496 % 256, 2496 / 256, 0x1f, 2560 % 256, 2560 / 256, | 243 0x1e, 2496 % 256, 2496 / 256, 0x1f, 2560 % 256, 2560 / 256, |
252 0xff, | 244 0xff, |
253 }; | 245 }; |
254 | 246 |
255 int FaxGetRun(const uint8_t* ins_array, | 247 int FaxGetRun(const uint8_t* ins_array, |
256 const uint8_t* src_buf, | 248 const uint8_t* src_buf, |
257 int& bitpos, | 249 int* bitpos, |
258 int bitsize) { | 250 int bitsize) { |
259 uint32_t code = 0; | 251 uint32_t code = 0; |
260 int ins_off = 0; | 252 int ins_off = 0; |
261 while (1) { | 253 while (1) { |
262 uint8_t ins = ins_array[ins_off++]; | 254 uint8_t ins = ins_array[ins_off++]; |
263 if (ins == 0xff) { | 255 if (ins == 0xff) |
264 return -1; | 256 return -1; |
265 } | 257 |
266 if (bitpos >= bitsize) { | 258 if (*bitpos >= bitsize) |
267 return -1; | 259 return -1; |
268 } | 260 |
269 code <<= 1; | 261 code <<= 1; |
270 if (src_buf[bitpos / 8] & (1 << (7 - bitpos % 8))) { | 262 if (src_buf[*bitpos / 8] & (1 << (7 - *bitpos % 8))) |
271 code++; | 263 ++code; |
272 } | 264 |
273 bitpos++; | 265 ++(*bitpos); |
274 int next_off = ins_off + ins * 3; | 266 int next_off = ins_off + ins * 3; |
275 for (; ins_off < next_off; ins_off += 3) { | 267 for (; ins_off < next_off; ins_off += 3) { |
276 if (ins_array[ins_off] == code) { | 268 if (ins_array[ins_off] == code) { |
277 return ins_array[ins_off + 1] + ins_array[ins_off + 2] * 256; | 269 return ins_array[ins_off + 1] + ins_array[ins_off + 2] * 256; |
278 } | 270 } |
279 } | 271 } |
280 } | 272 } |
281 } | 273 } |
282 | 274 |
283 FX_BOOL FaxG4GetRow(const uint8_t* src_buf, | 275 FX_BOOL FaxG4GetRow(const uint8_t* src_buf, |
284 int bitsize, | 276 int bitsize, |
285 int& bitpos, | 277 int* bitpos, |
286 uint8_t* dest_buf, | 278 uint8_t* dest_buf, |
287 const uint8_t* ref_buf, | 279 const std::vector<uint8_t>& ref_buf, |
288 int columns) { | 280 int columns) { |
289 int a0 = -1; | 281 int a0 = -1; |
290 bool a0color = true; | 282 bool a0color = true; |
291 while (1) { | 283 while (1) { |
292 if (bitpos >= bitsize) { | 284 if (*bitpos >= bitsize) |
293 return FALSE; | 285 return FALSE; |
294 } | 286 |
295 int a1, a2, b1, b2; | 287 int a1; |
296 FaxG4FindB1B2(ref_buf, columns, a0, a0color, b1, b2); | 288 int a2; |
297 FX_BOOL bit = NEXTBIT; | 289 int b1; |
| 290 int b2; |
| 291 FaxG4FindB1B2(ref_buf, columns, a0, a0color, &b1, &b2); |
| 292 FX_BOOL bit = NEXTBIT(); |
298 int v_delta = 0; | 293 int v_delta = 0; |
299 if (bit) { | 294 if (!bit) { |
300 } else { | 295 if (*bitpos >= bitsize) |
301 if (bitpos >= bitsize) { | |
302 return FALSE; | 296 return FALSE; |
303 } | 297 |
304 FX_BOOL bit1 = NEXTBIT; | 298 FX_BOOL bit1 = NEXTBIT(); |
305 if (bitpos >= bitsize) { | 299 if (*bitpos >= bitsize) |
306 return FALSE; | 300 return FALSE; |
307 } | 301 |
308 FX_BOOL bit2 = NEXTBIT; | 302 FX_BOOL bit2 = NEXTBIT(); |
309 if (bit1 && bit2) { | 303 if (bit1) { |
310 v_delta = 1; | 304 v_delta = bit2 ? 1 : -1; |
311 } else if (bit1) { | |
312 v_delta = -1; | |
313 } else if (bit2) { | 305 } else if (bit2) { |
314 int run_len1 = 0; | 306 int run_len1 = 0; |
315 while (1) { | 307 while (1) { |
316 int run = FaxGetRun(a0color ? FaxWhiteRunIns : FaxBlackRunIns, | 308 int run = FaxGetRun(a0color ? FaxWhiteRunIns : FaxBlackRunIns, |
317 src_buf, bitpos, bitsize); | 309 src_buf, bitpos, bitsize); |
318 run_len1 += run; | 310 run_len1 += run; |
319 if (run < 64) { | 311 if (run < 64) { |
320 break; | 312 break; |
321 } | 313 } |
322 } | 314 } |
323 if (a0 < 0) { | 315 if (a0 < 0) |
324 run_len1++; | 316 ++run_len1; |
325 } | 317 |
326 a1 = a0 + run_len1; | 318 a1 = a0 + run_len1; |
327 if (!a0color) { | 319 if (!a0color) |
328 FaxFillBits(dest_buf, columns, a0, a1); | 320 FaxFillBits(dest_buf, columns, a0, a1); |
329 } | 321 |
330 int run_len2 = 0; | 322 int run_len2 = 0; |
331 while (1) { | 323 while (1) { |
332 int run = FaxGetRun(a0color ? FaxBlackRunIns : FaxWhiteRunIns, | 324 int run = FaxGetRun(a0color ? FaxBlackRunIns : FaxWhiteRunIns, |
333 src_buf, bitpos, bitsize); | 325 src_buf, bitpos, bitsize); |
334 run_len2 += run; | 326 run_len2 += run; |
335 if (run < 64) { | 327 if (run < 64) { |
336 break; | 328 break; |
337 } | 329 } |
338 } | 330 } |
339 a2 = a1 + run_len2; | 331 a2 = a1 + run_len2; |
340 if (a0color) { | 332 if (a0color) |
341 FaxFillBits(dest_buf, columns, a1, a2); | 333 FaxFillBits(dest_buf, columns, a1, a2); |
342 } | 334 |
343 a0 = a2; | 335 a0 = a2; |
344 if (a0 < columns) { | 336 if (a0 < columns) |
| 337 continue; |
| 338 |
| 339 return TRUE; |
| 340 } else { |
| 341 if (*bitpos >= bitsize) |
| 342 return FALSE; |
| 343 |
| 344 bit = NEXTBIT(); |
| 345 if (bit) { |
| 346 if (!a0color) |
| 347 FaxFillBits(dest_buf, columns, a0, b2); |
| 348 |
| 349 if (b2 >= columns) |
| 350 return TRUE; |
| 351 |
| 352 a0 = b2; |
345 continue; | 353 continue; |
346 } | 354 } |
347 return TRUE; | 355 |
348 } else { | 356 if (*bitpos >= bitsize) |
349 if (bitpos >= bitsize) { | |
350 return FALSE; | 357 return FALSE; |
351 } | 358 |
352 bit = NEXTBIT; | 359 FX_BOOL next_bit1 = NEXTBIT(); |
353 if (bit) { | 360 if (*bitpos >= bitsize) |
354 if (!a0color) { | 361 return FALSE; |
355 FaxFillBits(dest_buf, columns, a0, b2); | 362 |
| 363 FX_BOOL next_bit2 = NEXTBIT(); |
| 364 if (next_bit1) { |
| 365 v_delta = next_bit2 ? 2 : -2; |
| 366 } else if (next_bit2) { |
| 367 if (*bitpos >= bitsize) |
| 368 return FALSE; |
| 369 |
| 370 bit = NEXTBIT(); |
| 371 v_delta = bit ? 3 : -3; |
| 372 } else { |
| 373 if (*bitpos >= bitsize) |
| 374 return FALSE; |
| 375 |
| 376 bit = NEXTBIT(); |
| 377 if (bit) { |
| 378 *bitpos += 3; |
| 379 continue; |
356 } | 380 } |
357 if (b2 >= columns) { | 381 *bitpos += 5; |
358 return TRUE; | 382 return TRUE; |
359 } | |
360 a0 = b2; | |
361 continue; | |
362 } else { | |
363 if (bitpos >= bitsize) { | |
364 return FALSE; | |
365 } | |
366 FX_BOOL next_bit1 = NEXTBIT; | |
367 if (bitpos >= bitsize) { | |
368 return FALSE; | |
369 } | |
370 FX_BOOL next_bit2 = NEXTBIT; | |
371 if (next_bit1 && next_bit2) { | |
372 v_delta = 2; | |
373 } else if (next_bit1) { | |
374 v_delta = -2; | |
375 } else if (next_bit2) { | |
376 if (bitpos >= bitsize) { | |
377 return FALSE; | |
378 } | |
379 bit = NEXTBIT; | |
380 if (bit) { | |
381 v_delta = 3; | |
382 } else { | |
383 v_delta = -3; | |
384 } | |
385 } else { | |
386 if (bitpos >= bitsize) { | |
387 return FALSE; | |
388 } | |
389 bit = NEXTBIT; | |
390 if (bit) { | |
391 bitpos += 3; | |
392 continue; | |
393 } else { | |
394 bitpos += 5; | |
395 return TRUE; | |
396 } | |
397 } | |
398 } | 383 } |
399 } | 384 } |
400 } | 385 } |
401 a1 = b1 + v_delta; | 386 a1 = b1 + v_delta; |
402 if (!a0color) { | 387 if (!a0color) |
403 FaxFillBits(dest_buf, columns, a0, a1); | 388 FaxFillBits(dest_buf, columns, a0, a1); |
404 } | 389 |
405 if (a1 >= columns) { | 390 if (a1 >= columns) |
406 return TRUE; | 391 return TRUE; |
407 } | 392 |
408 a0 = a1; | 393 a0 = a1; |
409 a0color = !a0color; | 394 a0color = !a0color; |
410 } | 395 } |
411 } | 396 } |
412 | 397 |
413 FX_BOOL FaxSkipEOL(const uint8_t* src_buf, int bitsize, int& bitpos) { | 398 FX_BOOL FaxSkipEOL(const uint8_t* src_buf, int bitsize, int* bitpos) { |
414 int startbit = bitpos; | 399 int startbit = *bitpos; |
415 while (bitpos < bitsize) { | 400 while (*bitpos < bitsize) { |
416 int bit = NEXTBIT; | 401 int bit = NEXTBIT(); |
417 if (bit) { | 402 if (!bit) |
418 if (bitpos - startbit <= 11) { | 403 continue; |
419 bitpos = startbit; | 404 |
420 } | 405 if (*bitpos - startbit <= 11) |
421 return TRUE; | 406 *bitpos = startbit; |
422 } | 407 return TRUE; |
423 } | 408 } |
424 return FALSE; | 409 return FALSE; |
425 } | 410 } |
426 | 411 |
427 FX_BOOL FaxGet1DLine(const uint8_t* src_buf, | 412 FX_BOOL FaxGet1DLine(const uint8_t* src_buf, |
428 int bitsize, | 413 int bitsize, |
429 int& bitpos, | 414 int* bitpos, |
430 uint8_t* dest_buf, | 415 std::vector<uint8_t>* dest_buf, |
431 int columns) { | 416 int columns) { |
432 bool color = true; | 417 bool color = true; |
433 int startpos = 0; | 418 int startpos = 0; |
434 while (1) { | 419 while (1) { |
435 if (bitpos >= bitsize) { | 420 if (*bitpos >= bitsize) |
436 return FALSE; | 421 return FALSE; |
437 } | 422 |
438 int run_len = 0; | 423 int run_len = 0; |
439 while (1) { | 424 while (1) { |
440 int run = FaxGetRun(color ? FaxWhiteRunIns : FaxBlackRunIns, src_buf, | 425 int run = FaxGetRun(color ? FaxWhiteRunIns : FaxBlackRunIns, src_buf, |
441 bitpos, bitsize); | 426 bitpos, bitsize); |
442 if (run < 0) { | 427 if (run < 0) { |
443 while (bitpos < bitsize) { | 428 while (*bitpos < bitsize) { |
444 int bit = NEXTBIT; | 429 int bit = NEXTBIT(); |
445 if (bit) { | 430 if (bit) { |
446 return TRUE; | 431 return TRUE; |
447 } | 432 } |
448 } | 433 } |
449 return FALSE; | 434 return FALSE; |
450 } | 435 } |
451 run_len += run; | 436 run_len += run; |
452 if (run < 64) { | 437 if (run < 64) { |
453 break; | 438 break; |
454 } | 439 } |
455 } | 440 } |
456 if (!color) { | 441 if (!color) |
457 FaxFillBits(dest_buf, columns, startpos, startpos + run_len); | 442 FaxFillBits(dest_buf->data(), columns, startpos, startpos + run_len); |
458 } | 443 |
459 startpos += run_len; | 444 startpos += run_len; |
460 if (startpos >= columns) { | 445 if (startpos >= columns) |
461 break; | 446 break; |
462 } | 447 |
463 color = !color; | 448 color = !color; |
464 } | 449 } |
465 return TRUE; | 450 return TRUE; |
466 } | 451 } |
467 | 452 |
468 } // namespace | 453 } // namespace |
469 | 454 |
470 class CCodec_FaxDecoder : public CCodec_ScanlineDecoder { | 455 class CCodec_FaxDecoder : public CCodec_ScanlineDecoder { |
471 public: | 456 public: |
472 CCodec_FaxDecoder(const uint8_t* src_buf, | 457 CCodec_FaxDecoder(const uint8_t* src_buf, |
473 uint32_t src_size, | 458 uint32_t src_size, |
474 int width, | 459 int width, |
475 int height, | 460 int height, |
| 461 uint32_t pitch, |
476 int K, | 462 int K, |
477 FX_BOOL EndOfLine, | 463 bool EndOfLine, |
478 FX_BOOL EncodedByteAlign, | 464 bool EncodedByteAlign, |
479 FX_BOOL BlackIs1, | 465 bool BlackIs1); |
480 int Columns, | |
481 int Rows); | |
482 ~CCodec_FaxDecoder() override; | 466 ~CCodec_FaxDecoder() override; |
483 | 467 |
484 | |
485 // CCodec_ScanlineDecoder | 468 // CCodec_ScanlineDecoder |
486 FX_BOOL v_Rewind() override; | 469 FX_BOOL v_Rewind() override; |
487 uint8_t* v_GetNextLine() override; | 470 uint8_t* v_GetNextLine() override; |
488 uint32_t GetSrcOffset() override; | 471 uint32_t GetSrcOffset() override; |
489 | 472 |
490 int m_Encoding, m_bEndOfLine, m_bByteAlign, m_bBlack; | 473 private: |
491 int bitpos; | 474 const int m_Encoding; |
492 const uint8_t* m_pSrcBuf; | 475 int m_bitpos; |
493 uint32_t m_SrcSize; | 476 bool m_bByteAlign; |
494 uint8_t* m_pScanlineBuf; | 477 const bool m_bEndOfLine; |
495 uint8_t* m_pRefBuf; | 478 const bool m_bBlack; |
| 479 const uint32_t m_SrcSize; |
| 480 const uint8_t* const m_pSrcBuf; |
| 481 std::vector<uint8_t> m_ScanlineBuf; |
| 482 std::vector<uint8_t> m_RefBuf; |
496 }; | 483 }; |
497 | 484 |
498 CCodec_FaxDecoder::CCodec_FaxDecoder(const uint8_t* src_buf, | 485 CCodec_FaxDecoder::CCodec_FaxDecoder(const uint8_t* src_buf, |
499 uint32_t src_size, | 486 uint32_t src_size, |
500 int width, | 487 int width, |
501 int height, | 488 int height, |
| 489 uint32_t pitch, |
502 int K, | 490 int K, |
503 FX_BOOL EndOfLine, | 491 bool EndOfLine, |
504 FX_BOOL EncodedByteAlign, | 492 bool EncodedByteAlign, |
505 FX_BOOL BlackIs1, | 493 bool BlackIs1) |
506 int Columns, | 494 : CCodec_ScanlineDecoder(width, height, width, height, 1, 1, pitch), |
507 int Rows) { | 495 m_Encoding(K), |
508 m_Encoding = K; | 496 m_bitpos(0), |
509 m_bEndOfLine = EndOfLine; | 497 m_bByteAlign(EncodedByteAlign), |
510 m_bByteAlign = EncodedByteAlign; | 498 m_bEndOfLine(EndOfLine), |
511 m_bBlack = BlackIs1; | 499 m_bBlack(BlackIs1), |
512 m_OrigWidth = Columns; | 500 m_SrcSize(src_size), |
513 m_OrigHeight = Rows; | 501 m_pSrcBuf(src_buf), |
514 if (m_OrigWidth == 0) | 502 m_ScanlineBuf(pitch), |
515 m_OrigWidth = width; | 503 m_RefBuf(pitch) {} |
516 if (m_OrigHeight == 0) | 504 |
517 m_OrigHeight = height; | 505 CCodec_FaxDecoder::~CCodec_FaxDecoder() {} |
518 // Should not overflow. Checked by CCodec_FaxDecoder::CreateDecoder. | 506 |
519 m_Pitch = (static_cast<uint32_t>(m_OrigWidth) + 31) / 32 * 4; | 507 FX_BOOL CCodec_FaxDecoder::v_Rewind() { |
520 m_OutputWidth = m_OrigWidth; | 508 FXSYS_memset(m_RefBuf.data(), 0xff, m_RefBuf.size()); |
521 m_OutputHeight = m_OrigHeight; | 509 m_bitpos = 0; |
522 m_pScanlineBuf = FX_Alloc(uint8_t, m_Pitch); | 510 return TRUE; |
523 m_pRefBuf = FX_Alloc(uint8_t, m_Pitch); | |
524 m_pSrcBuf = src_buf; | |
525 m_SrcSize = src_size; | |
526 m_nComps = 1; | |
527 m_bpc = 1; | |
528 } | 511 } |
529 | 512 |
530 CCodec_FaxDecoder::~CCodec_FaxDecoder() { | |
531 FX_Free(m_pScanlineBuf); | |
532 FX_Free(m_pRefBuf); | |
533 } | |
534 | |
535 FX_BOOL CCodec_FaxDecoder::v_Rewind() { | |
536 FXSYS_memset(m_pRefBuf, 0xff, m_Pitch); | |
537 bitpos = 0; | |
538 return TRUE; | |
539 } | |
540 uint8_t* CCodec_FaxDecoder::v_GetNextLine() { | 513 uint8_t* CCodec_FaxDecoder::v_GetNextLine() { |
541 int bitsize = m_SrcSize * 8; | 514 int bitsize = m_SrcSize * 8; |
542 FaxSkipEOL(m_pSrcBuf, bitsize, bitpos); | 515 FaxSkipEOL(m_pSrcBuf, bitsize, &m_bitpos); |
543 if (bitpos >= bitsize) { | 516 if (m_bitpos >= bitsize) |
544 return nullptr; | 517 return nullptr; |
545 } | 518 |
546 FXSYS_memset(m_pScanlineBuf, 0xff, m_Pitch); | 519 FXSYS_memset(m_ScanlineBuf.data(), 0xff, m_ScanlineBuf.size()); |
547 if (m_Encoding < 0) { | 520 if (m_Encoding < 0) { |
548 FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, | 521 FaxG4GetRow(m_pSrcBuf, bitsize, &m_bitpos, m_ScanlineBuf.data(), m_RefBuf, |
549 m_OrigWidth); | 522 m_OrigWidth); |
550 FXSYS_memcpy(m_pRefBuf, m_pScanlineBuf, m_Pitch); | 523 m_RefBuf = m_ScanlineBuf; |
551 } else if (m_Encoding == 0) { | 524 } else if (m_Encoding == 0) { |
552 FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidth); | 525 FaxGet1DLine(m_pSrcBuf, bitsize, &m_bitpos, &m_ScanlineBuf, m_OrigWidth); |
553 } else { | 526 } else { |
554 FX_BOOL bNext1D = m_pSrcBuf[bitpos / 8] & (1 << (7 - bitpos % 8)); | 527 FX_BOOL bNext1D = m_pSrcBuf[m_bitpos / 8] & (1 << (7 - m_bitpos % 8)); |
555 bitpos++; | 528 ++m_bitpos; |
556 if (bNext1D) { | 529 if (bNext1D) { |
557 FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidth); | 530 FaxGet1DLine(m_pSrcBuf, bitsize, &m_bitpos, &m_ScanlineBuf, m_OrigWidth); |
558 } else { | 531 } else { |
559 FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, | 532 FaxG4GetRow(m_pSrcBuf, bitsize, &m_bitpos, m_ScanlineBuf.data(), m_RefBuf, |
560 m_OrigWidth); | 533 m_OrigWidth); |
561 } | 534 } |
562 FXSYS_memcpy(m_pRefBuf, m_pScanlineBuf, m_Pitch); | 535 m_RefBuf = m_ScanlineBuf; |
563 } | 536 } |
564 if (m_bEndOfLine) { | 537 if (m_bEndOfLine) |
565 FaxSkipEOL(m_pSrcBuf, bitsize, bitpos); | 538 FaxSkipEOL(m_pSrcBuf, bitsize, &m_bitpos); |
566 } | 539 |
567 if (m_bByteAlign && bitpos < bitsize) { | 540 if (m_bByteAlign && m_bitpos < bitsize) { |
568 int bitpos0 = bitpos; | 541 int bitpos0 = m_bitpos; |
569 int bitpos1 = (bitpos + 7) / 8 * 8; | 542 int bitpos1 = (m_bitpos + 7) / 8 * 8; |
570 while (m_bByteAlign && bitpos0 < bitpos1) { | 543 while (m_bByteAlign && bitpos0 < bitpos1) { |
571 int bit = m_pSrcBuf[bitpos0 / 8] & (1 << (7 - bitpos0 % 8)); | 544 int bit = m_pSrcBuf[bitpos0 / 8] & (1 << (7 - bitpos0 % 8)); |
572 if (bit != 0) { | 545 if (bit != 0) { |
573 m_bByteAlign = FALSE; | 546 m_bByteAlign = false; |
574 } else { | 547 } else { |
575 bitpos0++; | 548 ++bitpos0; |
576 } | 549 } |
577 } | 550 } |
578 if (m_bByteAlign) { | 551 if (m_bByteAlign) |
579 bitpos = bitpos1; | 552 m_bitpos = bitpos1; |
| 553 } |
| 554 if (m_bBlack) { |
| 555 for (uint32_t i = 0; i < m_Pitch; ++i) { |
| 556 m_ScanlineBuf[i] = ~m_ScanlineBuf[i]; |
580 } | 557 } |
581 } | 558 } |
582 if (m_bBlack) { | 559 return m_ScanlineBuf.data(); |
583 for (uint32_t i = 0; i < m_Pitch; i++) { | |
584 m_pScanlineBuf[i] = ~m_pScanlineBuf[i]; | |
585 } | |
586 } | |
587 return m_pScanlineBuf; | |
588 } | 560 } |
| 561 |
589 uint32_t CCodec_FaxDecoder::GetSrcOffset() { | 562 uint32_t CCodec_FaxDecoder::GetSrcOffset() { |
590 uint32_t ret = (bitpos + 7) / 8; | 563 return std::min(static_cast<uint32_t>((m_bitpos + 7) / 8), m_SrcSize); |
591 if (ret > m_SrcSize) { | |
592 ret = m_SrcSize; | |
593 } | |
594 return ret; | |
595 } | 564 } |
596 | 565 |
597 void FaxG4Decode(const uint8_t* src_buf, | 566 void FaxG4Decode(const uint8_t* src_buf, |
598 uint32_t src_size, | 567 uint32_t src_size, |
599 int* pbitpos, | 568 int* pbitpos, |
600 uint8_t* dest_buf, | 569 uint8_t* dest_buf, |
601 int width, | 570 int width, |
602 int height, | 571 int height, |
603 int pitch) { | 572 int pitch) { |
604 if (pitch == 0) { | 573 if (pitch == 0) |
605 pitch = (width + 7) / 8; | 574 pitch = (width + 7) / 8; |
606 } | 575 |
607 uint8_t* ref_buf = FX_Alloc(uint8_t, pitch); | 576 std::vector<uint8_t> ref_buf(pitch, 0xff); |
608 FXSYS_memset(ref_buf, 0xff, pitch); | |
609 int bitpos = *pbitpos; | 577 int bitpos = *pbitpos; |
610 for (int iRow = 0; iRow < height; iRow++) { | 578 for (int iRow = 0; iRow < height; iRow++) { |
611 uint8_t* line_buf = dest_buf + iRow * pitch; | 579 uint8_t* line_buf = dest_buf + iRow * pitch; |
612 FXSYS_memset(line_buf, 0xff, pitch); | 580 FXSYS_memset(line_buf, 0xff, pitch); |
613 FaxG4GetRow(src_buf, src_size << 3, bitpos, line_buf, ref_buf, width); | 581 FaxG4GetRow(src_buf, src_size << 3, &bitpos, line_buf, ref_buf, width); |
614 FXSYS_memcpy(ref_buf, line_buf, pitch); | 582 FXSYS_memcpy(ref_buf.data(), line_buf, pitch); |
615 } | 583 } |
616 FX_Free(ref_buf); | |
617 *pbitpos = bitpos; | 584 *pbitpos = bitpos; |
618 } | 585 } |
619 | 586 |
620 CCodec_ScanlineDecoder* CCodec_FaxModule::CreateDecoder( | 587 CCodec_ScanlineDecoder* CCodec_FaxModule::CreateDecoder(const uint8_t* src_buf, |
621 const uint8_t* src_buf, | 588 uint32_t src_size, |
622 uint32_t src_size, | 589 int width, |
623 int width, | 590 int height, |
624 int height, | 591 int K, |
625 int K, | 592 bool EndOfLine, |
626 FX_BOOL EndOfLine, | 593 bool EncodedByteAlign, |
627 FX_BOOL EncodedByteAlign, | 594 bool BlackIs1, |
628 FX_BOOL BlackIs1, | 595 int Columns, |
629 int Columns, | 596 int Rows) { |
630 int Rows) { | 597 int actual_width = Columns ? Columns : width; |
| 598 int actual_height = Rows ? Rows : height; |
| 599 |
631 // Reject invalid values. | 600 // Reject invalid values. |
632 if (width <= 0 || height < 0 || Columns < 0 || Rows < 0) | 601 if (actual_width <= 0 || actual_height <= 0) |
633 return nullptr; | 602 return nullptr; |
| 603 |
634 // Reject unreasonable large input. | 604 // Reject unreasonable large input. |
635 if (width > kMaxImageDimension || height > kMaxImageDimension || | 605 if (actual_width > kMaxImageDimension || actual_height > kMaxImageDimension) |
636 Columns > kMaxImageDimension || Rows > kMaxImageDimension) | |
637 return nullptr; | 606 return nullptr; |
638 return new CCodec_FaxDecoder(src_buf, src_size, width, height, K, EndOfLine, | 607 |
639 EncodedByteAlign, BlackIs1, Columns, Rows); | 608 uint32_t pitch = (static_cast<uint32_t>(actual_width) + 31) / 32 * 4; |
| 609 return new CCodec_FaxDecoder(src_buf, src_size, actual_width, actual_height, |
| 610 pitch, K, EndOfLine, EncodedByteAlign, BlackIs1); |
640 } | 611 } |
OLD | NEW |