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