| 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 |