Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1075)

Side by Side Diff: core/fxcodec/codec/fx_codec_fax.cpp

Issue 2357173005: Clean up fx_codec_fax.cpp. (Closed)
Patch Set: typo Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « core/fxcodec/codec/fx_codec.cpp ('k') | testing/libfuzzer/pdf_codec_fax_fuzzer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 }
OLDNEW
« no previous file with comments | « core/fxcodec/codec/fx_codec.cpp ('k') | testing/libfuzzer/pdf_codec_fax_fuzzer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698