| 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 "../../../include/fxcodec/fx_codec.h" | 7 #include "../../../include/fxcodec/fx_codec.h" |
| 8 #include "codec_int.h" | 8 #include "codec_int.h" |
| 9 |
| 10 namespace { |
| 11 |
| 9 const uint8_t OneLeadPos[256] = { | 12 const uint8_t OneLeadPos[256] = { |
| 10 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, | 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, |
| 11 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | 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, |
| 12 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, | 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, |
| 13 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, |
| 14 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | 17 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
| 15 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 18 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 16 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 19 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 17 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 20 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 18 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 21 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 19 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 22 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 20 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 23 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 21 }; | 24 }; |
| 22 const uint8_t ZeroLeadPos[256] = { | 25 const uint8_t ZeroLeadPos[256] = { |
| 23 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 26 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 24 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 27 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 25 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 28 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 26 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 29 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 27 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 30 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 28 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | 31 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
| 29 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | 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, |
| 30 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, |
| 31 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | 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, |
| 32 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | 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, |
| 33 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, | 36 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, |
| 34 }; | 37 }; |
| 35 | 38 |
| 36 int _FindBit(const uint8_t* data_buf, int max_pos, int start_pos, int bit) { | 39 int FindBit(const uint8_t* data_buf, int max_pos, int start_pos, int bit) { |
| 37 if (start_pos >= max_pos) { | 40 if (start_pos >= max_pos) { |
| 38 return max_pos; | 41 return max_pos; |
| 39 } | 42 } |
| 40 const uint8_t* leading_pos = bit ? OneLeadPos : ZeroLeadPos; | 43 const uint8_t* leading_pos = bit ? OneLeadPos : ZeroLeadPos; |
| 41 if (start_pos % 8) { | 44 if (start_pos % 8) { |
| 42 uint8_t data = data_buf[start_pos / 8]; | 45 uint8_t data = data_buf[start_pos / 8]; |
| 43 if (bit) { | 46 if (bit) { |
| 44 data &= 0xff >> (start_pos % 8); | 47 data &= 0xff >> (start_pos % 8); |
| 45 } else { | 48 } else { |
| 46 data |= 0xff << (8 - start_pos % 8); | 49 data |= 0xff << (8 - start_pos % 8); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 61 } | 64 } |
| 62 if (byte_pos == max_byte) { | 65 if (byte_pos == max_byte) { |
| 63 return max_pos; | 66 return max_pos; |
| 64 } | 67 } |
| 65 int pos = leading_pos[data_buf[byte_pos]] + byte_pos * 8; | 68 int pos = leading_pos[data_buf[byte_pos]] + byte_pos * 8; |
| 66 if (pos > max_pos) { | 69 if (pos > max_pos) { |
| 67 pos = max_pos; | 70 pos = max_pos; |
| 68 } | 71 } |
| 69 return pos; | 72 return pos; |
| 70 } | 73 } |
| 71 void _FaxG4FindB1B2(const uint8_t* ref_buf, | 74 |
| 72 int columns, | 75 void FaxG4FindB1B2(const uint8_t* ref_buf, |
| 73 int a0, | 76 int columns, |
| 74 FX_BOOL a0color, | 77 int a0, |
| 75 int& b1, | 78 bool a0color, |
| 76 int& b2) { | 79 int& b1, |
| 77 if (a0color) { | 80 int& b2) { |
| 78 a0color = 1; | |
| 79 } | |
| 80 uint8_t first_bit = | 81 uint8_t first_bit = |
| 81 (a0 < 0) ? 1 : ((ref_buf[a0 / 8] & (1 << (7 - a0 % 8))) != 0); | 82 (a0 < 0) ? 1 : ((ref_buf[a0 / 8] & (1 << (7 - a0 % 8))) != 0); |
| 82 b1 = _FindBit(ref_buf, columns, a0 + 1, !first_bit); | 83 b1 = FindBit(ref_buf, columns, a0 + 1, !first_bit); |
| 83 if (b1 >= columns) { | 84 if (b1 >= columns) { |
| 84 b1 = b2 = columns; | 85 b1 = b2 = columns; |
| 85 return; | 86 return; |
| 86 } | 87 } |
| 87 if (first_bit == !a0color) { | 88 if (first_bit == !a0color) { |
| 88 b1 = _FindBit(ref_buf, columns, b1 + 1, first_bit); | 89 b1 = FindBit(ref_buf, columns, b1 + 1, first_bit); |
| 89 first_bit = !first_bit; | 90 first_bit = !first_bit; |
| 90 } | 91 } |
| 91 if (b1 >= columns) { | 92 if (b1 >= columns) { |
| 92 b1 = b2 = columns; | 93 b1 = b2 = columns; |
| 93 return; | 94 return; |
| 94 } | 95 } |
| 95 b2 = _FindBit(ref_buf, columns, b1 + 1, first_bit); | 96 b2 = FindBit(ref_buf, columns, b1 + 1, first_bit); |
| 96 } | 97 } |
| 97 void _FaxFillBits(uint8_t* dest_buf, int columns, int startpos, int endpos) { | 98 |
| 99 void FaxFillBits(uint8_t* dest_buf, int columns, int startpos, int endpos) { |
| 98 if (startpos < 0) { | 100 if (startpos < 0) { |
| 99 startpos = 0; | 101 startpos = 0; |
| 100 } | 102 } |
| 101 if (endpos < 0) { | 103 if (endpos < 0) { |
| 102 endpos = 0; | 104 endpos = 0; |
| 103 } | 105 } |
| 104 if (endpos >= columns) { | 106 if (endpos >= columns) { |
| 105 endpos = columns; | 107 endpos = columns; |
| 106 } | 108 } |
| 107 if (startpos >= endpos) { | 109 if (startpos >= endpos) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 119 for (i = startpos % 8; i < 8; i++) { | 121 for (i = startpos % 8; i < 8; i++) { |
| 120 dest_buf[first_byte] -= 1 << (7 - i); | 122 dest_buf[first_byte] -= 1 << (7 - i); |
| 121 } | 123 } |
| 122 for (i = 0; i <= (endpos - 1) % 8; i++) { | 124 for (i = 0; i <= (endpos - 1) % 8; i++) { |
| 123 dest_buf[last_byte] -= 1 << (7 - i); | 125 dest_buf[last_byte] -= 1 << (7 - i); |
| 124 } | 126 } |
| 125 if (last_byte > first_byte + 1) { | 127 if (last_byte > first_byte + 1) { |
| 126 FXSYS_memset(dest_buf + first_byte + 1, 0, last_byte - first_byte - 1); | 128 FXSYS_memset(dest_buf + first_byte + 1, 0, last_byte - first_byte - 1); |
| 127 } | 129 } |
| 128 } | 130 } |
| 131 |
| 129 #define NEXTBIT \ | 132 #define NEXTBIT \ |
| 130 src_buf[bitpos / 8] & (1 << (7 - bitpos % 8)); \ | 133 src_buf[bitpos / 8] & (1 << (7 - bitpos % 8)); \ |
| 131 bitpos++; | 134 bitpos++; |
| 132 #define ADDBIT(code, bit) \ | 135 #define ADDBIT(code, bit) \ |
| 133 code = code << 1; \ | 136 code = code << 1; \ |
| 134 if (bit) \ | 137 if (bit) \ |
| 135 code++; | 138 code++; |
| 136 #define GETBIT(bitpos) src_buf[bitpos / 8] & (1 << (7 - bitpos % 8)) | 139 #define GETBIT(bitpos) src_buf[bitpos / 8] & (1 << (7 - bitpos % 8)) |
| 137 static const uint8_t FaxBlackRunIns[] = { | 140 |
| 141 const uint8_t FaxBlackRunIns[] = { |
| 138 0, 2, 0x02, 3, 0, 0x03, | 142 0, 2, 0x02, 3, 0, 0x03, |
| 139 2, 0, 2, 0x02, 1, 0, | 143 2, 0, 2, 0x02, 1, 0, |
| 140 0x03, 4, 0, 2, 0x02, 6, | 144 0x03, 4, 0, 2, 0x02, 6, |
| 141 0, 0x03, 5, 0, 1, 0x03, | 145 0, 0x03, 5, 0, 1, 0x03, |
| 142 7, 0, 2, 0x04, 9, 0, | 146 7, 0, 2, 0x04, 9, 0, |
| 143 0x05, 8, 0, 3, 0x04, 10, | 147 0x05, 8, 0, 3, 0x04, 10, |
| 144 0, 0x05, 11, 0, 0x07, 12, | 148 0, 0x05, 11, 0, 0x07, 12, |
| 145 0, 2, 0x04, 13, 0, 0x07, | 149 0, 2, 0x04, 13, 0, 0x07, |
| 146 14, 0, 1, 0x18, 15, 0, | 150 14, 0, 1, 0x18, 15, 0, |
| 147 5, 0x08, 18, 0, 0x0f, 64, | 151 5, 0x08, 18, 0, 0x0f, 64, |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 704 / 256, 0x4c, 768 % 256, 768 / 256, 0x4d, 832 % 256, | 187 704 / 256, 0x4c, 768 % 256, 768 / 256, 0x4d, 832 % 256, |
| 184 832 / 256, 0x52, 1280 % 256, 1280 / 256, 0x53, 1344 % 256, | 188 832 / 256, 0x52, 1280 % 256, 1280 / 256, 0x53, 1344 % 256, |
| 185 1344 / 256, 0x54, 1408 % 256, 1408 / 256, 0x55, 1472 % 256, | 189 1344 / 256, 0x54, 1408 % 256, 1408 / 256, 0x55, 1472 % 256, |
| 186 1472 / 256, 0x5a, 1536 % 256, 1536 / 256, 0x5b, 1600 % 256, | 190 1472 / 256, 0x5a, 1536 % 256, 1536 / 256, 0x5b, 1600 % 256, |
| 187 1600 / 256, 0x64, 1664 % 256, 1664 / 256, 0x65, 1728 % 256, | 191 1600 / 256, 0x64, 1664 % 256, 1664 / 256, 0x65, 1728 % 256, |
| 188 1728 / 256, 0x6c, 512 % 256, 512 / 256, 0x6d, 576 % 256, | 192 1728 / 256, 0x6c, 512 % 256, 512 / 256, 0x6d, 576 % 256, |
| 189 576 / 256, 0x72, 896 % 256, 896 / 256, 0x73, 960 % 256, | 193 576 / 256, 0x72, 896 % 256, 896 / 256, 0x73, 960 % 256, |
| 190 960 / 256, 0x74, 1024 % 256, 1024 / 256, 0x75, 1088 % 256, | 194 960 / 256, 0x74, 1024 % 256, 1024 / 256, 0x75, 1088 % 256, |
| 191 1088 / 256, 0x76, 1152 % 256, 1152 / 256, 0x77, 1216 % 256, | 195 1088 / 256, 0x76, 1152 % 256, 1152 / 256, 0x77, 1216 % 256, |
| 192 1216 / 256, 0xff}; | 196 1216 / 256, 0xff}; |
| 193 static const uint8_t FaxWhiteRunIns[] = { | 197 |
| 198 const uint8_t FaxWhiteRunIns[] = { |
| 194 0, 0, 0, 6, 0x07, 2, | 199 0, 0, 0, 6, 0x07, 2, |
| 195 0, 0x08, 3, 0, 0x0B, 4, | 200 0, 0x08, 3, 0, 0x0B, 4, |
| 196 0, 0x0C, 5, 0, 0x0E, 6, | 201 0, 0x0C, 5, 0, 0x0E, 6, |
| 197 0, 0x0F, 7, 0, 6, 0x07, | 202 0, 0x0F, 7, 0, 6, 0x07, |
| 198 10, 0, 0x08, 11, 0, 0x12, | 203 10, 0, 0x08, 11, 0, 0x12, |
| 199 128, 0, 0x13, 8, 0, 0x14, | 204 128, 0, 0x13, 8, 0, 0x14, |
| 200 9, 0, 0x1b, 64, 0, 9, | 205 9, 0, 0x1b, 64, 0, 9, |
| 201 0x03, 13, 0, 0x07, 1, 0, | 206 0x03, 13, 0, 0x07, 1, 0, |
| 202 0x08, 12, 0, 0x17, 192, 0, | 207 0x08, 12, 0, 0x17, 192, 0, |
| 203 0x18, 1664 % 256, 1664 / 256, 0x2a, 16, 0, | 208 0x18, 1664 % 256, 1664 / 256, 0x2a, 16, 0, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 0xda, 1344 % 256, 1344 / 256, 0xdb, 1408 % 256, 1408 / 256, | 245 0xda, 1344 % 256, 1344 / 256, 0xdb, 1408 % 256, 1408 / 256, |
| 241 0, 3, 0x08, 1792 % 256, 1792 / 256, 0x0c, | 246 0, 3, 0x08, 1792 % 256, 1792 / 256, 0x0c, |
| 242 1856 % 256, 1856 / 256, 0x0d, 1920 % 256, 1920 / 256, 10, | 247 1856 % 256, 1856 / 256, 0x0d, 1920 % 256, 1920 / 256, 10, |
| 243 0x12, 1984 % 256, 1984 / 256, 0x13, 2048 % 256, 2048 / 256, | 248 0x12, 1984 % 256, 1984 / 256, 0x13, 2048 % 256, 2048 / 256, |
| 244 0x14, 2112 % 256, 2112 / 256, 0x15, 2176 % 256, 2176 / 256, | 249 0x14, 2112 % 256, 2112 / 256, 0x15, 2176 % 256, 2176 / 256, |
| 245 0x16, 2240 % 256, 2240 / 256, 0x17, 2304 % 256, 2304 / 256, | 250 0x16, 2240 % 256, 2240 / 256, 0x17, 2304 % 256, 2304 / 256, |
| 246 0x1c, 2368 % 256, 2368 / 256, 0x1d, 2432 % 256, 2432 / 256, | 251 0x1c, 2368 % 256, 2368 / 256, 0x1d, 2432 % 256, 2432 / 256, |
| 247 0x1e, 2496 % 256, 2496 / 256, 0x1f, 2560 % 256, 2560 / 256, | 252 0x1e, 2496 % 256, 2496 / 256, 0x1f, 2560 % 256, 2560 / 256, |
| 248 0xff, | 253 0xff, |
| 249 }; | 254 }; |
| 250 int _FaxGetRun(const uint8_t* ins_array, | 255 |
| 251 const uint8_t* src_buf, | 256 int FaxGetRun(const uint8_t* ins_array, |
| 252 int& bitpos, | 257 const uint8_t* src_buf, |
| 253 int bitsize) { | 258 int& bitpos, |
| 259 int bitsize) { |
| 254 FX_DWORD code = 0; | 260 FX_DWORD code = 0; |
| 255 int ins_off = 0; | 261 int ins_off = 0; |
| 256 while (1) { | 262 while (1) { |
| 257 uint8_t ins = ins_array[ins_off++]; | 263 uint8_t ins = ins_array[ins_off++]; |
| 258 if (ins == 0xff) { | 264 if (ins == 0xff) { |
| 259 return -1; | 265 return -1; |
| 260 } | 266 } |
| 261 if (bitpos >= bitsize) { | 267 if (bitpos >= bitsize) { |
| 262 return -1; | 268 return -1; |
| 263 } | 269 } |
| 264 code <<= 1; | 270 code <<= 1; |
| 265 if (src_buf[bitpos / 8] & (1 << (7 - bitpos % 8))) { | 271 if (src_buf[bitpos / 8] & (1 << (7 - bitpos % 8))) { |
| 266 code++; | 272 code++; |
| 267 } | 273 } |
| 268 bitpos++; | 274 bitpos++; |
| 269 int next_off = ins_off + ins * 3; | 275 int next_off = ins_off + ins * 3; |
| 270 for (; ins_off < next_off; ins_off += 3) { | 276 for (; ins_off < next_off; ins_off += 3) { |
| 271 if (ins_array[ins_off] == code) { | 277 if (ins_array[ins_off] == code) { |
| 272 return ins_array[ins_off + 1] + ins_array[ins_off + 2] * 256; | 278 return ins_array[ins_off + 1] + ins_array[ins_off + 2] * 256; |
| 273 } | 279 } |
| 274 } | 280 } |
| 275 } | 281 } |
| 276 } | 282 } |
| 277 FX_BOOL _FaxG4GetRow(const uint8_t* src_buf, | 283 |
| 278 int bitsize, | 284 FX_BOOL FaxG4GetRow(const uint8_t* src_buf, |
| 279 int& bitpos, | 285 int bitsize, |
| 280 uint8_t* dest_buf, | 286 int& bitpos, |
| 281 const uint8_t* ref_buf, | 287 uint8_t* dest_buf, |
| 282 int columns) { | 288 const uint8_t* ref_buf, |
| 283 int a0 = -1, a0color = 1; | 289 int columns) { |
| 290 int a0 = -1; |
| 291 bool a0color = true; |
| 284 while (1) { | 292 while (1) { |
| 285 if (bitpos >= bitsize) { | 293 if (bitpos >= bitsize) { |
| 286 return FALSE; | 294 return FALSE; |
| 287 } | 295 } |
| 288 int a1, a2, b1, b2; | 296 int a1, a2, b1, b2; |
| 289 _FaxG4FindB1B2(ref_buf, columns, a0, a0color, b1, b2); | 297 FaxG4FindB1B2(ref_buf, columns, a0, a0color, b1, b2); |
| 290 FX_BOOL bit = NEXTBIT; | 298 FX_BOOL bit = NEXTBIT; |
| 291 int v_delta = 0; | 299 int v_delta = 0; |
| 292 if (bit) { | 300 if (bit) { |
| 293 } else { | 301 } else { |
| 294 if (bitpos >= bitsize) { | 302 if (bitpos >= bitsize) { |
| 295 return FALSE; | 303 return FALSE; |
| 296 } | 304 } |
| 297 FX_BOOL bit1 = NEXTBIT; | 305 FX_BOOL bit1 = NEXTBIT; |
| 298 if (bitpos >= bitsize) { | 306 if (bitpos >= bitsize) { |
| 299 return FALSE; | 307 return FALSE; |
| 300 } | 308 } |
| 301 FX_BOOL bit2 = NEXTBIT; | 309 FX_BOOL bit2 = NEXTBIT; |
| 302 if (bit1 && bit2) { | 310 if (bit1 && bit2) { |
| 303 v_delta = 1; | 311 v_delta = 1; |
| 304 } else if (bit1) { | 312 } else if (bit1) { |
| 305 v_delta = -1; | 313 v_delta = -1; |
| 306 } else if (bit2) { | 314 } else if (bit2) { |
| 307 int run_len1 = 0; | 315 int run_len1 = 0; |
| 308 while (1) { | 316 while (1) { |
| 309 int run = _FaxGetRun(a0color ? FaxWhiteRunIns : FaxBlackRunIns, | 317 int run = FaxGetRun(a0color ? FaxWhiteRunIns : FaxBlackRunIns, |
| 310 src_buf, bitpos, bitsize); | 318 src_buf, bitpos, bitsize); |
| 311 run_len1 += run; | 319 run_len1 += run; |
| 312 if (run < 64) { | 320 if (run < 64) { |
| 313 break; | 321 break; |
| 314 } | 322 } |
| 315 } | 323 } |
| 316 if (a0 < 0) { | 324 if (a0 < 0) { |
| 317 run_len1++; | 325 run_len1++; |
| 318 } | 326 } |
| 319 a1 = a0 + run_len1; | 327 a1 = a0 + run_len1; |
| 320 if (!a0color) { | 328 if (!a0color) { |
| 321 _FaxFillBits(dest_buf, columns, a0, a1); | 329 FaxFillBits(dest_buf, columns, a0, a1); |
| 322 } | 330 } |
| 323 int run_len2 = 0; | 331 int run_len2 = 0; |
| 324 while (1) { | 332 while (1) { |
| 325 int run = _FaxGetRun(a0color ? FaxBlackRunIns : FaxWhiteRunIns, | 333 int run = FaxGetRun(a0color ? FaxBlackRunIns : FaxWhiteRunIns, |
| 326 src_buf, bitpos, bitsize); | 334 src_buf, bitpos, bitsize); |
| 327 run_len2 += run; | 335 run_len2 += run; |
| 328 if (run < 64) { | 336 if (run < 64) { |
| 329 break; | 337 break; |
| 330 } | 338 } |
| 331 } | 339 } |
| 332 a2 = a1 + run_len2; | 340 a2 = a1 + run_len2; |
| 333 if (a0color) { | 341 if (a0color) { |
| 334 _FaxFillBits(dest_buf, columns, a1, a2); | 342 FaxFillBits(dest_buf, columns, a1, a2); |
| 335 } | 343 } |
| 336 a0 = a2; | 344 a0 = a2; |
| 337 if (a0 < columns) { | 345 if (a0 < columns) { |
| 338 continue; | 346 continue; |
| 339 } | 347 } |
| 340 return TRUE; | 348 return TRUE; |
| 341 } else { | 349 } else { |
| 342 if (bitpos >= bitsize) { | 350 if (bitpos >= bitsize) { |
| 343 return FALSE; | 351 return FALSE; |
| 344 } | 352 } |
| 345 bit = NEXTBIT; | 353 bit = NEXTBIT; |
| 346 if (bit) { | 354 if (bit) { |
| 347 if (!a0color) { | 355 if (!a0color) { |
| 348 _FaxFillBits(dest_buf, columns, a0, b2); | 356 FaxFillBits(dest_buf, columns, a0, b2); |
| 349 } | 357 } |
| 350 if (b2 >= columns) { | 358 if (b2 >= columns) { |
| 351 return TRUE; | 359 return TRUE; |
| 352 } | 360 } |
| 353 a0 = b2; | 361 a0 = b2; |
| 354 continue; | 362 continue; |
| 355 } else { | 363 } else { |
| 356 if (bitpos >= bitsize) { | 364 if (bitpos >= bitsize) { |
| 357 return FALSE; | 365 return FALSE; |
| 358 } | 366 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 386 } else { | 394 } else { |
| 387 bitpos += 5; | 395 bitpos += 5; |
| 388 return TRUE; | 396 return TRUE; |
| 389 } | 397 } |
| 390 } | 398 } |
| 391 } | 399 } |
| 392 } | 400 } |
| 393 } | 401 } |
| 394 a1 = b1 + v_delta; | 402 a1 = b1 + v_delta; |
| 395 if (!a0color) { | 403 if (!a0color) { |
| 396 _FaxFillBits(dest_buf, columns, a0, a1); | 404 FaxFillBits(dest_buf, columns, a0, a1); |
| 397 } | 405 } |
| 398 if (a1 >= columns) { | 406 if (a1 >= columns) { |
| 399 return TRUE; | 407 return TRUE; |
| 400 } | 408 } |
| 401 a0 = a1; | 409 a0 = a1; |
| 402 a0color = !a0color; | 410 a0color = !a0color; |
| 403 } | 411 } |
| 404 } | 412 } |
| 405 FX_BOOL _FaxSkipEOL(const uint8_t* src_buf, int bitsize, int& bitpos) { | 413 |
| 414 FX_BOOL FaxSkipEOL(const uint8_t* src_buf, int bitsize, int& bitpos) { |
| 406 int startbit = bitpos; | 415 int startbit = bitpos; |
| 407 while (bitpos < bitsize) { | 416 while (bitpos < bitsize) { |
| 408 int bit = NEXTBIT; | 417 int bit = NEXTBIT; |
| 409 if (bit) { | 418 if (bit) { |
| 410 if (bitpos - startbit <= 11) { | 419 if (bitpos - startbit <= 11) { |
| 411 bitpos = startbit; | 420 bitpos = startbit; |
| 412 } | 421 } |
| 413 return TRUE; | 422 return TRUE; |
| 414 } | 423 } |
| 415 } | 424 } |
| 416 return FALSE; | 425 return FALSE; |
| 417 } | 426 } |
| 418 FX_BOOL _FaxGet1DLine(const uint8_t* src_buf, | 427 |
| 419 int bitsize, | 428 FX_BOOL FaxGet1DLine(const uint8_t* src_buf, |
| 420 int& bitpos, | 429 int bitsize, |
| 421 uint8_t* dest_buf, | 430 int& bitpos, |
| 422 int columns) { | 431 uint8_t* dest_buf, |
| 423 int color = TRUE; | 432 int columns) { |
| 433 bool color = true; |
| 424 int startpos = 0; | 434 int startpos = 0; |
| 425 while (1) { | 435 while (1) { |
| 426 if (bitpos >= bitsize) { | 436 if (bitpos >= bitsize) { |
| 427 return FALSE; | 437 return FALSE; |
| 428 } | 438 } |
| 429 int run_len = 0; | 439 int run_len = 0; |
| 430 while (1) { | 440 while (1) { |
| 431 int run = _FaxGetRun(color ? FaxWhiteRunIns : FaxBlackRunIns, src_buf, | 441 int run = FaxGetRun(color ? FaxWhiteRunIns : FaxBlackRunIns, src_buf, |
| 432 bitpos, bitsize); | 442 bitpos, bitsize); |
| 433 if (run < 0) { | 443 if (run < 0) { |
| 434 while (bitpos < bitsize) { | 444 while (bitpos < bitsize) { |
| 435 int bit = NEXTBIT; | 445 int bit = NEXTBIT; |
| 436 if (bit) { | 446 if (bit) { |
| 437 return TRUE; | 447 return TRUE; |
| 438 } | 448 } |
| 439 } | 449 } |
| 440 return FALSE; | 450 return FALSE; |
| 441 } | 451 } |
| 442 run_len += run; | 452 run_len += run; |
| 443 if (run < 64) { | 453 if (run < 64) { |
| 444 break; | 454 break; |
| 445 } | 455 } |
| 446 } | 456 } |
| 447 if (!color) { | 457 if (!color) { |
| 448 _FaxFillBits(dest_buf, columns, startpos, startpos + run_len); | 458 FaxFillBits(dest_buf, columns, startpos, startpos + run_len); |
| 449 } | 459 } |
| 450 startpos += run_len; | 460 startpos += run_len; |
| 451 if (startpos >= columns) { | 461 if (startpos >= columns) { |
| 452 break; | 462 break; |
| 453 } | 463 } |
| 454 color = !color; | 464 color = !color; |
| 455 } | 465 } |
| 456 return TRUE; | 466 return TRUE; |
| 457 } | 467 } |
| 458 | 468 |
| 469 const uint8_t BlackRunTerminator[128] = { |
| 470 0x37, 10, 0x02, 3, 0x03, 2, 0x02, 2, 0x03, 3, 0x03, 4, 0x02, 4, |
| 471 0x03, 5, 0x05, 6, 0x04, 6, 0x04, 7, 0x05, 7, 0x07, 7, 0x04, 8, |
| 472 0x07, 8, 0x18, 9, 0x17, 10, 0x18, 10, 0x08, 10, 0x67, 11, 0x68, 11, |
| 473 0x6c, 11, 0x37, 11, 0x28, 11, 0x17, 11, 0x18, 11, 0xca, 12, 0xcb, 12, |
| 474 0xcc, 12, 0xcd, 12, 0x68, 12, 0x69, 12, 0x6a, 12, 0x6b, 12, 0xd2, 12, |
| 475 0xd3, 12, 0xd4, 12, 0xd5, 12, 0xd6, 12, 0xd7, 12, 0x6c, 12, 0x6d, 12, |
| 476 0xda, 12, 0xdb, 12, 0x54, 12, 0x55, 12, 0x56, 12, 0x57, 12, 0x64, 12, |
| 477 0x65, 12, 0x52, 12, 0x53, 12, 0x24, 12, 0x37, 12, 0x38, 12, 0x27, 12, |
| 478 0x28, 12, 0x58, 12, 0x59, 12, 0x2b, 12, 0x2c, 12, 0x5a, 12, 0x66, 12, |
| 479 0x67, 12, |
| 480 }; |
| 481 |
| 482 const uint8_t BlackRunMarkup[80] = { |
| 483 0x0f, 10, 0xc8, 12, 0xc9, 12, 0x5b, 12, 0x33, 12, 0x34, 12, 0x35, 12, |
| 484 0x6c, 13, 0x6d, 13, 0x4a, 13, 0x4b, 13, 0x4c, 13, 0x4d, 13, 0x72, 13, |
| 485 0x73, 13, 0x74, 13, 0x75, 13, 0x76, 13, 0x77, 13, 0x52, 13, 0x53, 13, |
| 486 0x54, 13, 0x55, 13, 0x5a, 13, 0x5b, 13, 0x64, 13, 0x65, 13, 0x08, 11, |
| 487 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12, 0x14, 12, 0x15, 12, 0x16, 12, |
| 488 0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12, |
| 489 }; |
| 490 |
| 491 const uint8_t WhiteRunTerminator[128] = { |
| 492 0x35, 8, 0x07, 6, 0x07, 4, 0x08, 4, 0x0B, 4, 0x0C, 4, 0x0E, 4, 0x0F, 4, |
| 493 0x13, 5, 0x14, 5, 0x07, 5, 0x08, 5, 0x08, 6, 0x03, 6, 0x34, 6, 0x35, 6, |
| 494 0x2a, 6, 0x2B, 6, 0x27, 7, 0x0c, 7, 0x08, 7, 0x17, 7, 0x03, 7, 0x04, 7, |
| 495 0x28, 7, 0x2B, 7, 0x13, 7, 0x24, 7, 0x18, 7, 0x02, 8, 0x03, 8, 0x1a, 8, |
| 496 0x1b, 8, 0x12, 8, 0x13, 8, 0x14, 8, 0x15, 8, 0x16, 8, 0x17, 8, 0x28, 8, |
| 497 0x29, 8, 0x2a, 8, 0x2b, 8, 0x2c, 8, 0x2d, 8, 0x04, 8, 0x05, 8, 0x0a, 8, |
| 498 0x0b, 8, 0x52, 8, 0x53, 8, 0x54, 8, 0x55, 8, 0x24, 8, 0x25, 8, 0x58, 8, |
| 499 0x59, 8, 0x5a, 8, 0x5b, 8, 0x4a, 8, 0x4b, 8, 0x32, 8, 0x33, 8, 0x34, 8, |
| 500 }; |
| 501 |
| 502 const uint8_t WhiteRunMarkup[80] = { |
| 503 0x1b, 5, 0x12, 5, 0x17, 6, 0x37, 7, 0x36, 8, 0x37, 8, 0x64, 8, |
| 504 0x65, 8, 0x68, 8, 0x67, 8, 0xcc, 9, 0xcd, 9, 0xd2, 9, 0xd3, 9, |
| 505 0xd4, 9, 0xd5, 9, 0xd6, 9, 0xd7, 9, 0xd8, 9, 0xd9, 9, 0xda, 9, |
| 506 0xdb, 9, 0x98, 9, 0x99, 9, 0x9a, 9, 0x18, 6, 0x9b, 9, 0x08, 11, |
| 507 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12, 0x14, 12, 0x15, 12, 0x16, 12, |
| 508 0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12, |
| 509 }; |
| 510 |
| 511 void AddBitStream(uint8_t* dest_buf, int& dest_bitpos, int data, int bitlen) { |
| 512 for (int i = bitlen - 1; i >= 0; i--) { |
| 513 if (data & (1 << i)) { |
| 514 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); |
| 515 } |
| 516 dest_bitpos++; |
| 517 } |
| 518 } |
| 519 |
| 520 void FaxEncodeRun(uint8_t* dest_buf, int& dest_bitpos, int run, bool bWhite) { |
| 521 while (run >= 2560) { |
| 522 AddBitStream(dest_buf, dest_bitpos, 0x1f, 12); |
| 523 run -= 2560; |
| 524 } |
| 525 if (run >= 64) { |
| 526 int markup = run - run % 64; |
| 527 const uint8_t* p = bWhite ? WhiteRunMarkup : BlackRunMarkup; |
| 528 p += (markup / 64 - 1) * 2; |
| 529 AddBitStream(dest_buf, dest_bitpos, *p, p[1]); |
| 530 } |
| 531 run %= 64; |
| 532 const uint8_t* p = bWhite ? WhiteRunTerminator : BlackRunTerminator; |
| 533 p += run * 2; |
| 534 AddBitStream(dest_buf, dest_bitpos, *p, p[1]); |
| 535 } |
| 536 |
| 537 void FaxEncode2DLine(uint8_t* dest_buf, |
| 538 int& dest_bitpos, |
| 539 const uint8_t* src_buf, |
| 540 const uint8_t* ref_buf, |
| 541 int cols) { |
| 542 int a0 = -1; |
| 543 bool a0color = true; |
| 544 while (1) { |
| 545 int a1 = FindBit(src_buf, cols, a0 + 1, !a0color); |
| 546 int b1, b2; |
| 547 FaxG4FindB1B2(ref_buf, cols, a0, a0color, b1, b2); |
| 548 if (b2 < a1) { |
| 549 dest_bitpos += 3; |
| 550 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); |
| 551 dest_bitpos++; |
| 552 a0 = b2; |
| 553 } else if (a1 - b1 <= 3 && b1 - a1 <= 3) { |
| 554 int delta = a1 - b1; |
| 555 switch (delta) { |
| 556 case 0: |
| 557 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); |
| 558 break; |
| 559 case 1: |
| 560 case 2: |
| 561 case 3: |
| 562 dest_bitpos += delta == 1 ? 1 : delta + 2; |
| 563 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); |
| 564 dest_bitpos++; |
| 565 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); |
| 566 break; |
| 567 case -1: |
| 568 case -2: |
| 569 case -3: |
| 570 dest_bitpos += delta == -1 ? 1 : -delta + 2; |
| 571 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); |
| 572 dest_bitpos++; |
| 573 break; |
| 574 } |
| 575 dest_bitpos++; |
| 576 a0 = a1; |
| 577 a0color = !a0color; |
| 578 } else { |
| 579 int a2 = FindBit(src_buf, cols, a1 + 1, a0color); |
| 580 dest_bitpos++; |
| 581 dest_bitpos++; |
| 582 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); |
| 583 dest_bitpos++; |
| 584 if (a0 < 0) { |
| 585 a0 = 0; |
| 586 } |
| 587 FaxEncodeRun(dest_buf, dest_bitpos, a1 - a0, a0color); |
| 588 FaxEncodeRun(dest_buf, dest_bitpos, a2 - a1, !a0color); |
| 589 a0 = a2; |
| 590 } |
| 591 if (a0 >= cols) { |
| 592 return; |
| 593 } |
| 594 } |
| 595 } |
| 596 |
| 597 } // namespace |
| 598 |
| 459 class CCodec_FaxDecoder : public CCodec_ScanlineDecoder { | 599 class CCodec_FaxDecoder : public CCodec_ScanlineDecoder { |
| 460 public: | 600 public: |
| 461 CCodec_FaxDecoder(); | 601 CCodec_FaxDecoder(); |
| 462 ~CCodec_FaxDecoder() override; | 602 ~CCodec_FaxDecoder() override; |
| 463 | 603 |
| 464 FX_BOOL Create(const uint8_t* src_buf, | 604 FX_BOOL Create(const uint8_t* src_buf, |
| 465 FX_DWORD src_size, | 605 FX_DWORD src_size, |
| 466 int width, | 606 int width, |
| 467 int height, | 607 int height, |
| 468 int K, | 608 int K, |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 m_bColorTransformed = FALSE; | 668 m_bColorTransformed = FALSE; |
| 529 return TRUE; | 669 return TRUE; |
| 530 } | 670 } |
| 531 FX_BOOL CCodec_FaxDecoder::v_Rewind() { | 671 FX_BOOL CCodec_FaxDecoder::v_Rewind() { |
| 532 FXSYS_memset(m_pRefBuf, 0xff, m_Pitch); | 672 FXSYS_memset(m_pRefBuf, 0xff, m_Pitch); |
| 533 bitpos = 0; | 673 bitpos = 0; |
| 534 return TRUE; | 674 return TRUE; |
| 535 } | 675 } |
| 536 uint8_t* CCodec_FaxDecoder::v_GetNextLine() { | 676 uint8_t* CCodec_FaxDecoder::v_GetNextLine() { |
| 537 int bitsize = m_SrcSize * 8; | 677 int bitsize = m_SrcSize * 8; |
| 538 _FaxSkipEOL(m_pSrcBuf, bitsize, bitpos); | 678 FaxSkipEOL(m_pSrcBuf, bitsize, bitpos); |
| 539 if (bitpos >= bitsize) { | 679 if (bitpos >= bitsize) { |
| 540 return NULL; | 680 return NULL; |
| 541 } | 681 } |
| 542 FXSYS_memset(m_pScanlineBuf, 0xff, m_Pitch); | 682 FXSYS_memset(m_pScanlineBuf, 0xff, m_Pitch); |
| 543 if (m_Encoding < 0) { | 683 if (m_Encoding < 0) { |
| 544 _FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, | 684 FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, |
| 545 m_OrigWidth); | 685 m_OrigWidth); |
| 546 FXSYS_memcpy(m_pRefBuf, m_pScanlineBuf, m_Pitch); | 686 FXSYS_memcpy(m_pRefBuf, m_pScanlineBuf, m_Pitch); |
| 547 } else if (m_Encoding == 0) { | 687 } else if (m_Encoding == 0) { |
| 548 _FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidth); | 688 FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidth); |
| 549 } else { | 689 } else { |
| 550 FX_BOOL bNext1D = m_pSrcBuf[bitpos / 8] & (1 << (7 - bitpos % 8)); | 690 FX_BOOL bNext1D = m_pSrcBuf[bitpos / 8] & (1 << (7 - bitpos % 8)); |
| 551 bitpos++; | 691 bitpos++; |
| 552 if (bNext1D) { | 692 if (bNext1D) { |
| 553 _FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidth); | 693 FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidth); |
| 554 } else { | 694 } else { |
| 555 _FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, | 695 FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, |
| 556 m_OrigWidth); | 696 m_OrigWidth); |
| 557 } | 697 } |
| 558 FXSYS_memcpy(m_pRefBuf, m_pScanlineBuf, m_Pitch); | 698 FXSYS_memcpy(m_pRefBuf, m_pScanlineBuf, m_Pitch); |
| 559 } | 699 } |
| 560 if (m_bEndOfLine) { | 700 if (m_bEndOfLine) { |
| 561 _FaxSkipEOL(m_pSrcBuf, bitsize, bitpos); | 701 FaxSkipEOL(m_pSrcBuf, bitsize, bitpos); |
| 562 } | 702 } |
| 563 if (m_bByteAlign && bitpos < bitsize) { | 703 if (m_bByteAlign && bitpos < bitsize) { |
| 564 int bitpos0 = bitpos; | 704 int bitpos0 = bitpos; |
| 565 int bitpos1 = (bitpos + 7) / 8 * 8; | 705 int bitpos1 = (bitpos + 7) / 8 * 8; |
| 566 while (m_bByteAlign && bitpos0 < bitpos1) { | 706 while (m_bByteAlign && bitpos0 < bitpos1) { |
| 567 int bit = m_pSrcBuf[bitpos0 / 8] & (1 << (7 - bitpos0 % 8)); | 707 int bit = m_pSrcBuf[bitpos0 / 8] & (1 << (7 - bitpos0 % 8)); |
| 568 if (bit != 0) { | 708 if (bit != 0) { |
| 569 m_bByteAlign = FALSE; | 709 m_bByteAlign = FALSE; |
| 570 } else { | 710 } else { |
| 571 bitpos0++; | 711 bitpos0++; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 582 } | 722 } |
| 583 return m_pScanlineBuf; | 723 return m_pScanlineBuf; |
| 584 } | 724 } |
| 585 FX_DWORD CCodec_FaxDecoder::GetSrcOffset() { | 725 FX_DWORD CCodec_FaxDecoder::GetSrcOffset() { |
| 586 FX_DWORD ret = (bitpos + 7) / 8; | 726 FX_DWORD ret = (bitpos + 7) / 8; |
| 587 if (ret > m_SrcSize) { | 727 if (ret > m_SrcSize) { |
| 588 ret = m_SrcSize; | 728 ret = m_SrcSize; |
| 589 } | 729 } |
| 590 return ret; | 730 return ret; |
| 591 } | 731 } |
| 592 extern "C" { | 732 |
| 593 void _FaxG4Decode(const uint8_t* src_buf, | 733 void FaxG4Decode(const uint8_t* src_buf, |
| 594 FX_DWORD src_size, | 734 FX_DWORD src_size, |
| 595 int* pbitpos, | 735 int* pbitpos, |
| 596 uint8_t* dest_buf, | 736 uint8_t* dest_buf, |
| 597 int width, | 737 int width, |
| 598 int height, | 738 int height, |
| 599 int pitch) { | 739 int pitch) { |
| 600 if (pitch == 0) { | 740 if (pitch == 0) { |
| 601 pitch = (width + 7) / 8; | 741 pitch = (width + 7) / 8; |
| 602 } | 742 } |
| 603 uint8_t* ref_buf = FX_Alloc(uint8_t, pitch); | 743 uint8_t* ref_buf = FX_Alloc(uint8_t, pitch); |
| 604 FXSYS_memset(ref_buf, 0xff, pitch); | 744 FXSYS_memset(ref_buf, 0xff, pitch); |
| 605 int bitpos = *pbitpos; | 745 int bitpos = *pbitpos; |
| 606 for (int iRow = 0; iRow < height; iRow++) { | 746 for (int iRow = 0; iRow < height; iRow++) { |
| 607 uint8_t* line_buf = dest_buf + iRow * pitch; | 747 uint8_t* line_buf = dest_buf + iRow * pitch; |
| 608 FXSYS_memset(line_buf, 0xff, pitch); | 748 FXSYS_memset(line_buf, 0xff, pitch); |
| 609 _FaxG4GetRow(src_buf, src_size << 3, bitpos, line_buf, ref_buf, width); | 749 FaxG4GetRow(src_buf, src_size << 3, bitpos, line_buf, ref_buf, width); |
| 610 FXSYS_memcpy(ref_buf, line_buf, pitch); | 750 FXSYS_memcpy(ref_buf, line_buf, pitch); |
| 611 } | 751 } |
| 612 FX_Free(ref_buf); | 752 FX_Free(ref_buf); |
| 613 *pbitpos = bitpos; | 753 *pbitpos = bitpos; |
| 614 } | 754 } |
| 615 }; | 755 |
| 616 static const uint8_t BlackRunTerminator[128] = { | |
| 617 0x37, 10, 0x02, 3, 0x03, 2, 0x02, 2, 0x03, 3, 0x03, 4, 0x02, 4, | |
| 618 0x03, 5, 0x05, 6, 0x04, 6, 0x04, 7, 0x05, 7, 0x07, 7, 0x04, 8, | |
| 619 0x07, 8, 0x18, 9, 0x17, 10, 0x18, 10, 0x08, 10, 0x67, 11, 0x68, 11, | |
| 620 0x6c, 11, 0x37, 11, 0x28, 11, 0x17, 11, 0x18, 11, 0xca, 12, 0xcb, 12, | |
| 621 0xcc, 12, 0xcd, 12, 0x68, 12, 0x69, 12, 0x6a, 12, 0x6b, 12, 0xd2, 12, | |
| 622 0xd3, 12, 0xd4, 12, 0xd5, 12, 0xd6, 12, 0xd7, 12, 0x6c, 12, 0x6d, 12, | |
| 623 0xda, 12, 0xdb, 12, 0x54, 12, 0x55, 12, 0x56, 12, 0x57, 12, 0x64, 12, | |
| 624 0x65, 12, 0x52, 12, 0x53, 12, 0x24, 12, 0x37, 12, 0x38, 12, 0x27, 12, | |
| 625 0x28, 12, 0x58, 12, 0x59, 12, 0x2b, 12, 0x2c, 12, 0x5a, 12, 0x66, 12, | |
| 626 0x67, 12, | |
| 627 }; | |
| 628 static const uint8_t BlackRunMarkup[80] = { | |
| 629 0x0f, 10, 0xc8, 12, 0xc9, 12, 0x5b, 12, 0x33, 12, 0x34, 12, 0x35, 12, | |
| 630 0x6c, 13, 0x6d, 13, 0x4a, 13, 0x4b, 13, 0x4c, 13, 0x4d, 13, 0x72, 13, | |
| 631 0x73, 13, 0x74, 13, 0x75, 13, 0x76, 13, 0x77, 13, 0x52, 13, 0x53, 13, | |
| 632 0x54, 13, 0x55, 13, 0x5a, 13, 0x5b, 13, 0x64, 13, 0x65, 13, 0x08, 11, | |
| 633 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12, 0x14, 12, 0x15, 12, 0x16, 12, | |
| 634 0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12, | |
| 635 }; | |
| 636 static const uint8_t WhiteRunTerminator[128] = { | |
| 637 0x35, 8, 0x07, 6, 0x07, 4, 0x08, 4, 0x0B, 4, 0x0C, 4, 0x0E, 4, 0x0F, 4, | |
| 638 0x13, 5, 0x14, 5, 0x07, 5, 0x08, 5, 0x08, 6, 0x03, 6, 0x34, 6, 0x35, 6, | |
| 639 0x2a, 6, 0x2B, 6, 0x27, 7, 0x0c, 7, 0x08, 7, 0x17, 7, 0x03, 7, 0x04, 7, | |
| 640 0x28, 7, 0x2B, 7, 0x13, 7, 0x24, 7, 0x18, 7, 0x02, 8, 0x03, 8, 0x1a, 8, | |
| 641 0x1b, 8, 0x12, 8, 0x13, 8, 0x14, 8, 0x15, 8, 0x16, 8, 0x17, 8, 0x28, 8, | |
| 642 0x29, 8, 0x2a, 8, 0x2b, 8, 0x2c, 8, 0x2d, 8, 0x04, 8, 0x05, 8, 0x0a, 8, | |
| 643 0x0b, 8, 0x52, 8, 0x53, 8, 0x54, 8, 0x55, 8, 0x24, 8, 0x25, 8, 0x58, 8, | |
| 644 0x59, 8, 0x5a, 8, 0x5b, 8, 0x4a, 8, 0x4b, 8, 0x32, 8, 0x33, 8, 0x34, 8, | |
| 645 }; | |
| 646 static const uint8_t WhiteRunMarkup[80] = { | |
| 647 0x1b, 5, 0x12, 5, 0x17, 6, 0x37, 7, 0x36, 8, 0x37, 8, 0x64, 8, | |
| 648 0x65, 8, 0x68, 8, 0x67, 8, 0xcc, 9, 0xcd, 9, 0xd2, 9, 0xd3, 9, | |
| 649 0xd4, 9, 0xd5, 9, 0xd6, 9, 0xd7, 9, 0xd8, 9, 0xd9, 9, 0xda, 9, | |
| 650 0xdb, 9, 0x98, 9, 0x99, 9, 0x9a, 9, 0x18, 6, 0x9b, 9, 0x08, 11, | |
| 651 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12, 0x14, 12, 0x15, 12, 0x16, 12, | |
| 652 0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12, | |
| 653 }; | |
| 654 static void _AddBitStream(uint8_t* dest_buf, | |
| 655 int& dest_bitpos, | |
| 656 int data, | |
| 657 int bitlen) { | |
| 658 for (int i = bitlen - 1; i >= 0; i--) { | |
| 659 if (data & (1 << i)) { | |
| 660 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); | |
| 661 } | |
| 662 dest_bitpos++; | |
| 663 } | |
| 664 } | |
| 665 static void _FaxEncodeRun(uint8_t* dest_buf, | |
| 666 int& dest_bitpos, | |
| 667 int run, | |
| 668 FX_BOOL bWhite) { | |
| 669 while (run >= 2560) { | |
| 670 _AddBitStream(dest_buf, dest_bitpos, 0x1f, 12); | |
| 671 run -= 2560; | |
| 672 } | |
| 673 if (run >= 64) { | |
| 674 int markup = run - run % 64; | |
| 675 const uint8_t* p = bWhite ? WhiteRunMarkup : BlackRunMarkup; | |
| 676 p += (markup / 64 - 1) * 2; | |
| 677 _AddBitStream(dest_buf, dest_bitpos, *p, p[1]); | |
| 678 } | |
| 679 run %= 64; | |
| 680 const uint8_t* p = bWhite ? WhiteRunTerminator : BlackRunTerminator; | |
| 681 p += run * 2; | |
| 682 _AddBitStream(dest_buf, dest_bitpos, *p, p[1]); | |
| 683 } | |
| 684 static void _FaxEncode2DLine(uint8_t* dest_buf, | |
| 685 int& dest_bitpos, | |
| 686 const uint8_t* src_buf, | |
| 687 const uint8_t* ref_buf, | |
| 688 int cols) { | |
| 689 int a0 = -1, a0color = 1; | |
| 690 while (1) { | |
| 691 int a1 = _FindBit(src_buf, cols, a0 + 1, 1 - a0color); | |
| 692 int b1, b2; | |
| 693 _FaxG4FindB1B2(ref_buf, cols, a0, a0color, b1, b2); | |
| 694 if (b2 < a1) { | |
| 695 dest_bitpos += 3; | |
| 696 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); | |
| 697 dest_bitpos++; | |
| 698 a0 = b2; | |
| 699 } else if (a1 - b1 <= 3 && b1 - a1 <= 3) { | |
| 700 int delta = a1 - b1; | |
| 701 switch (delta) { | |
| 702 case 0: | |
| 703 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); | |
| 704 break; | |
| 705 case 1: | |
| 706 case 2: | |
| 707 case 3: | |
| 708 dest_bitpos += delta == 1 ? 1 : delta + 2; | |
| 709 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); | |
| 710 dest_bitpos++; | |
| 711 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); | |
| 712 break; | |
| 713 case -1: | |
| 714 case -2: | |
| 715 case -3: | |
| 716 dest_bitpos += delta == -1 ? 1 : -delta + 2; | |
| 717 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); | |
| 718 dest_bitpos++; | |
| 719 break; | |
| 720 } | |
| 721 dest_bitpos++; | |
| 722 a0 = a1; | |
| 723 a0color = 1 - a0color; | |
| 724 } else { | |
| 725 int a2 = _FindBit(src_buf, cols, a1 + 1, a0color); | |
| 726 dest_bitpos++; | |
| 727 dest_bitpos++; | |
| 728 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); | |
| 729 dest_bitpos++; | |
| 730 if (a0 < 0) { | |
| 731 a0 = 0; | |
| 732 } | |
| 733 _FaxEncodeRun(dest_buf, dest_bitpos, a1 - a0, a0color); | |
| 734 _FaxEncodeRun(dest_buf, dest_bitpos, a2 - a1, 1 - a0color); | |
| 735 a0 = a2; | |
| 736 } | |
| 737 if (a0 >= cols) { | |
| 738 return; | |
| 739 } | |
| 740 } | |
| 741 } | |
| 742 class CCodec_FaxEncoder { | 756 class CCodec_FaxEncoder { |
| 743 public: | 757 public: |
| 744 CCodec_FaxEncoder(const uint8_t* src_buf, int width, int height, int pitch); | 758 CCodec_FaxEncoder(const uint8_t* src_buf, int width, int height, int pitch); |
| 745 ~CCodec_FaxEncoder(); | 759 ~CCodec_FaxEncoder(); |
| 746 void Encode(uint8_t*& dest_buf, FX_DWORD& dest_size); | 760 void Encode(uint8_t*& dest_buf, FX_DWORD& dest_size); |
| 747 void Encode2DLine(const uint8_t* scan_line); | 761 void Encode2DLine(const uint8_t* scan_line); |
| 748 CFX_BinaryBuf m_DestBuf; | 762 CFX_BinaryBuf m_DestBuf; |
| 749 uint8_t* m_pRefLine; | 763 uint8_t* m_pRefLine; |
| 750 uint8_t* m_pLineBuf; | 764 uint8_t* m_pLineBuf; |
| 751 int m_Cols, m_Rows, m_Pitch; | 765 int m_Cols, m_Rows, m_Pitch; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 768 FX_Free(m_pRefLine); | 782 FX_Free(m_pRefLine); |
| 769 FX_Free(m_pLineBuf); | 783 FX_Free(m_pLineBuf); |
| 770 } | 784 } |
| 771 void CCodec_FaxEncoder::Encode(uint8_t*& dest_buf, FX_DWORD& dest_size) { | 785 void CCodec_FaxEncoder::Encode(uint8_t*& dest_buf, FX_DWORD& dest_size) { |
| 772 int dest_bitpos = 0; | 786 int dest_bitpos = 0; |
| 773 uint8_t last_byte = 0; | 787 uint8_t last_byte = 0; |
| 774 for (int i = 0; i < m_Rows; i++) { | 788 for (int i = 0; i < m_Rows; i++) { |
| 775 const uint8_t* scan_line = m_pSrcBuf + i * m_Pitch; | 789 const uint8_t* scan_line = m_pSrcBuf + i * m_Pitch; |
| 776 FXSYS_memset(m_pLineBuf, 0, m_Pitch * 8); | 790 FXSYS_memset(m_pLineBuf, 0, m_Pitch * 8); |
| 777 m_pLineBuf[0] = last_byte; | 791 m_pLineBuf[0] = last_byte; |
| 778 _FaxEncode2DLine(m_pLineBuf, dest_bitpos, scan_line, m_pRefLine, m_Cols); | 792 FaxEncode2DLine(m_pLineBuf, dest_bitpos, scan_line, m_pRefLine, m_Cols); |
| 779 m_DestBuf.AppendBlock(m_pLineBuf, dest_bitpos / 8); | 793 m_DestBuf.AppendBlock(m_pLineBuf, dest_bitpos / 8); |
| 780 last_byte = m_pLineBuf[dest_bitpos / 8]; | 794 last_byte = m_pLineBuf[dest_bitpos / 8]; |
| 781 dest_bitpos %= 8; | 795 dest_bitpos %= 8; |
| 782 FXSYS_memcpy(m_pRefLine, scan_line, m_Pitch); | 796 FXSYS_memcpy(m_pRefLine, scan_line, m_Pitch); |
| 783 } | 797 } |
| 784 if (dest_bitpos) { | 798 if (dest_bitpos) { |
| 785 m_DestBuf.AppendByte(last_byte); | 799 m_DestBuf.AppendByte(last_byte); |
| 786 } | 800 } |
| 787 dest_buf = m_DestBuf.GetBuffer(); | 801 dest_buf = m_DestBuf.GetBuffer(); |
| 788 dest_size = m_DestBuf.GetSize(); | 802 dest_size = m_DestBuf.GetSize(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 807 FX_BOOL EndOfLine, | 821 FX_BOOL EndOfLine, |
| 808 FX_BOOL EncodedByteAlign, | 822 FX_BOOL EncodedByteAlign, |
| 809 FX_BOOL BlackIs1, | 823 FX_BOOL BlackIs1, |
| 810 int Columns, | 824 int Columns, |
| 811 int Rows) { | 825 int Rows) { |
| 812 CCodec_FaxDecoder* pDecoder = new CCodec_FaxDecoder; | 826 CCodec_FaxDecoder* pDecoder = new CCodec_FaxDecoder; |
| 813 pDecoder->Create(src_buf, src_size, width, height, K, EndOfLine, | 827 pDecoder->Create(src_buf, src_size, width, height, K, EndOfLine, |
| 814 EncodedByteAlign, BlackIs1, Columns, Rows); | 828 EncodedByteAlign, BlackIs1, Columns, Rows); |
| 815 return pDecoder; | 829 return pDecoder; |
| 816 } | 830 } |
| OLD | NEW |