15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2014 PDFium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "../../../include/fxcodec/fx_codec.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "codec_int.h"
96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)extern const FX_BYTE OneLeadPos[256];
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const FX_BYTE ZeroLeadPos[256];
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int _FindBit(const FX_BYTE* data_buf, int max_pos, int start_pos, int bit)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (start_pos >= max_pos) {
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        return max_pos;
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    FX_LPCBYTE leading_pos = bit ? OneLeadPos : ZeroLeadPos;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (start_pos % 8) {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FX_BYTE data = data_buf[start_pos / 8];
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (bit) {
2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            data &= 0xff >> (start_pos % 8);
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            data |= 0xff << (8 - start_pos % 8);
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (leading_pos[data] < 8) {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return start_pos / 8 * 8 + leading_pos[data];
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        start_pos += 7;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    FX_BYTE skip = bit ? 0x00 : 0xff;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int byte_pos = start_pos / 8;
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int max_byte = (max_pos + 7) / 8;
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    while (byte_pos < max_byte) {
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if (data_buf[byte_pos] != skip) {
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            break;
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        }
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        byte_pos ++;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (byte_pos == max_byte) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return max_pos;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int pos = leading_pos[data_buf[byte_pos]] + byte_pos * 8;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pos > max_pos) {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pos = max_pos;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return pos;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void _FaxG4FindB1B2(const FX_BYTE* ref_buf, int columns, int a0, FX_BOOL a0color, int& b1, int& b2)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (a0color) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        a0color = 1;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FX_BYTE first_bit = (a0 < 0) ? 1 : ((ref_buf[a0 / 8] & (1 << (7 - a0 % 8))) != 0);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    b1 = _FindBit(ref_buf, columns, a0 + 1, !first_bit);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (b1 >= columns) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        b1 = b2 = columns;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (first_bit == !a0color) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        b1 = _FindBit(ref_buf, columns, b1 + 1, first_bit);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        first_bit = !first_bit;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (b1 >= columns) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        b1 = b2 = columns;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    b2 = _FindBit(ref_buf, columns, b1 + 1, first_bit);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void _FaxFillBits(FX_LPBYTE dest_buf, int columns, int startpos, int endpos)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (startpos < 0) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        startpos = 0;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (endpos < 0) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        endpos = 0;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (endpos >= columns) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        endpos = columns;
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (startpos >= endpos) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int first_byte = startpos / 8;
83a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    int last_byte = (endpos - 1) / 8;
84a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (first_byte == last_byte) {
85a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        for (int i = startpos % 8; i <= (endpos - 1) % 8; i ++) {
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            dest_buf[first_byte] -= 1 << (7 - i);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = startpos % 8; i < 8; i ++) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dest_buf[first_byte] -= 1 << (7 - i);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0; i <= (endpos - 1) % 8; i ++) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dest_buf[last_byte] -= 1 << (7 - i);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (last_byte > first_byte + 1) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FXSYS_memset32(dest_buf + first_byte + 1, 0, last_byte - first_byte - 1);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NEXTBIT src_buf[bitpos/8] & (1 << (7-bitpos%8)); bitpos ++;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ADDBIT(code, bit) code = code << 1; if (bit) code ++;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GETBIT(bitpos) src_buf[bitpos/8] & (1 << (7-bitpos%8))
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const FX_BYTE FaxBlackRunIns[] = {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    2,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x02, 3, 0,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x03, 2, 0,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    2,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x02, 1, 0,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x03, 4, 0,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    2,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x02, 6, 0,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x03, 5, 0,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    1,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x03, 7, 0,
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    2,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x04, 9, 0,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x05, 8, 0,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    3,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x04, 10, 0,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x05, 11, 0,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x07, 12, 0,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    2,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x04, 13, 0,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x07, 14, 0,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    1,
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x18, 15, 0,
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    5,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x08, 18, 0,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0f, 64, 0,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x17, 16, 0,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x18, 17, 0,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x37, 0, 0,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    10,
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    0x08, 0x00, 0x07,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0c, 0x40, 0x07,
1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    0x0d, 0x80, 0x07,
1396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    0x17, 24, 0,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x18, 25, 0,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x28, 23, 0,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x37, 22, 0,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x67, 19, 0,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x68, 20, 0,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x6c, 21, 0,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    54,
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    0x12, 1984 % 256, 1984 / 256,
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x13, 2048 % 256, 2048 / 256,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x14, 2112 % 256, 2112 / 256,
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x15, 2176 % 256, 2176 / 256,
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x16, 2240 % 256, 2240 / 256,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x17, 2304 % 256, 2304 / 256,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x1c, 2368 % 256, 2368 / 256,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x1d, 2432 % 256, 2432 / 256,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x1e, 2496 % 256, 2496 / 256,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x1f, 2560 % 256, 2560 / 256,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x24, 52, 0,
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x27, 55, 0,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x28, 56, 0,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x2b, 59, 0,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x2c, 60, 0,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x33, 320 % 256, 320 / 256,
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x34, 384 % 256, 384 / 256,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x35, 448 % 256, 448 / 256,
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x37, 53, 0,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x38, 54, 0,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x52, 50, 0,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x53, 51, 0,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x54, 44, 0,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x55, 45, 0,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x56, 46, 0,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x57, 47, 0,
1736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    0x58, 57, 0,
1746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    0x59, 58, 0,
1756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    0x5a, 61, 0,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x5b, 256 % 256, 256 / 256,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x64, 48, 0,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x65, 49, 0,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x66, 62, 0,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x67, 63, 0,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x68, 30, 0,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x69, 31, 0,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x6a, 32, 0,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x6b, 33, 0,
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x6c, 40, 0,
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x6d, 41, 0,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xc8, 128, 0,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xc9, 192, 0,
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xca, 26, 0,
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xcb, 27, 0,
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xcc, 28, 0,
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xcd, 29, 0,
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd2, 34, 0,
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd3, 35, 0,
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd4, 36, 0,
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd5, 37, 0,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd6, 38, 0,
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd7, 39, 0,
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xda, 42, 0,
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xdb, 43, 0,
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    20,
202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    0x4a, 640 % 256, 640 / 256,
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x4b, 704 % 256, 704 / 256,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x4c, 768 % 256, 768 / 256,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x4d, 832 % 256, 832 / 256,
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x52, 1280 % 256, 1280 / 256,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x53, 1344 % 256, 1344 / 256,
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x54, 1408 % 256, 1408 / 256,
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x55, 1472 % 256, 1472 / 256,
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x5a, 1536 % 256, 1536 / 256,
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x5b, 1600 % 256, 1600 / 256,
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x64, 1664 % 256, 1664 / 256,
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x65, 1728 % 256, 1728 / 256,
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x6c, 512 % 256, 512 / 256,
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x6d, 576 % 256, 576 / 256,
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x72, 896 % 256, 896 / 256,
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x73, 960 % 256, 960 / 256,
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x74, 1024 % 256, 1024 / 256,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x75, 1088 % 256, 1088 / 256,
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x76, 1152 % 256, 1152 / 256,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x77, 1216 % 256, 1216 / 256,
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xff
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const FX_BYTE FaxWhiteRunIns[] = {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0,
226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    0,
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    6,
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x07, 2, 0,
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x08, 3, 0,
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0B, 4, 0,
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0C, 5, 0,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0E, 6, 0,
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x0F, 7, 0,
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    6,
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x07, 10, 0,
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x08, 11, 0,
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x12, 128, 0,
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x13, 8, 0,
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x14, 9, 0,
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x1b, 64, 0,
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    9,
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x03, 13, 0,
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x07, 1, 0,
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x08, 12, 0,
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x17, 192, 0,
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x18, 1664 % 256, 1664 / 256,
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x2a, 16, 0,
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x2B, 17, 0,
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x34, 14, 0,
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x35, 15, 0,
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    12,
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x03, 22, 0,
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x04, 23, 0,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x08, 20, 0,
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    0x0c, 19, 0,
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    0x13, 26, 0,
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    0x17, 21, 0,
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    0x18, 28, 0,
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x24, 27, 0,
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x27, 18, 0,
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x28, 24, 0,
2636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    0x2B, 25, 0,
2646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    0x37, 256 % 256, 256 / 256,
2656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    42,
2666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    0x02, 29, 0,
2676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    0x03, 30, 0,
2686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    0x04, 45, 0,
2696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    0x05, 46, 0,
2706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    0x0a, 47, 0,
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0b, 48, 0,
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x12, 33, 0,
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x13, 34, 0,
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x14, 35, 0,
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x15, 36, 0,
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x16, 37, 0,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x17, 38, 0,
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x1a, 31, 0,
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x1b, 32, 0,
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x24, 53, 0,
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x25, 54, 0,
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x28, 39, 0,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x29, 40, 0,
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x2a, 41, 0,
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x2b, 42, 0,
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x2c, 43, 0,
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x2d, 44, 0,
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x32, 61, 0,
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x33, 62, 0,
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x34, 63, 0,
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x35, 0, 0,
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x36, 320 % 256, 320 / 256,
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x37, 384 % 256, 384 / 256,
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x4a, 59, 0,
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x4b, 60, 0,
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x52, 49, 0,
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x53, 50, 0,
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x54, 51, 0,
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x55, 52, 0,
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x58, 55, 0,
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x59, 56, 0,
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x5a, 57, 0,
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x5b, 58, 0,
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x64, 448 % 256, 448 / 256,
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x65, 512 % 256, 512 / 256,
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x67, 640 % 256, 640 / 256,
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x68, 576 % 256, 576 / 256,
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    16,
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x98, 1472 % 256, 1472 / 256,
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x99, 1536 % 256, 1536 / 256,
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x9a, 1600 % 256, 1600 / 256,
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x9b, 1728 % 256, 1728 / 256,
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xcc, 704 % 256, 704 / 256,
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xcd, 768 % 256, 768 / 256,
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd2, 832 % 256, 832 / 256,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd3, 896 % 256, 896 / 256,
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd4, 960 % 256, 960 / 256,
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd5, 1024 % 256, 1024 / 256,
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd6, 1088 % 256, 1088 / 256,
320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    0xd7, 1152 % 256, 1152 / 256,
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0xd8, 1216 % 256, 1216 / 256,
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd9, 1280 % 256, 1280 / 256,
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xda, 1344 % 256, 1344 / 256,
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xdb, 1408 % 256, 1408 / 256,
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0,
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    3,
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x08, 1792 % 256, 1792 / 256,
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0c, 1856 % 256, 1856 / 256,
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0d, 1920 % 256, 1920 / 256,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    10,
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x12, 1984 % 256, 1984 / 256,
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x13, 2048 % 256, 2048 / 256,
333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x14, 2112 % 256, 2112 / 256,
334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x15, 2176 % 256, 2176 / 256,
335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x16, 2240 % 256, 2240 / 256,
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x17, 2304 % 256, 2304 / 256,
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x1c, 2368 % 256, 2368 / 256,
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x1d, 2432 % 256, 2432 / 256,
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x1e, 2496 % 256, 2496 / 256,
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x1f, 2560 % 256, 2560 / 256,
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xff,
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int _FaxGetRun(FX_LPCBYTE ins_array, const FX_BYTE* src_buf, int& bitpos, int bitsize)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FX_DWORD code = 0;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ins_off = 0;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (1) {
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FX_BYTE ins = ins_array[ins_off++];
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (ins == 0xff) {
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return -1;
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (bitpos >= bitsize) {
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return -1;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code <<= 1;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (src_buf[bitpos / 8] & (1 << (7 - bitpos % 8))) {
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            code ++;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        bitpos ++;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int next_off = ins_off + ins * 3;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (; ins_off < next_off; ins_off += 3) {
362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            if (ins_array[ins_off] == code) {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return ins_array[ins_off + 1] + ins_array[ins_off + 2] * 256;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FX_BOOL _FaxG4GetRow(const FX_BYTE* src_buf, int bitsize, int& bitpos, FX_LPBYTE dest_buf, const FX_BYTE* ref_buf, int columns)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int a0 = -1, a0color = 1;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (1) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (bitpos >= bitsize) {
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return FALSE;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int a1, a2, b1, b2;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        _FaxG4FindB1B2(ref_buf, columns, a0, a0color, b1, b2);
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FX_BOOL bit = NEXTBIT;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int v_delta = 0;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (bit) {
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (bitpos >= bitsize) {
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return FALSE;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            FX_BOOL bit1 = NEXTBIT;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (bitpos >= bitsize) {
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return FALSE;
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            FX_BOOL bit2 = NEXTBIT;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (bit1 && bit2) {
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                v_delta = 1;
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else if (bit1) {
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                v_delta = -1;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else if (bit2) {
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                int run_len1 = 0;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                while (1) {
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    int run = _FaxGetRun(a0color ? FaxWhiteRunIns : FaxBlackRunIns, src_buf, bitpos, bitsize);
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    run_len1 += run;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if (run < 64) {
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        break;
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (a0 < 0) {
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    run_len1 ++;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                a1 = a0 + run_len1;
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                if (!a0color) {
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    _FaxFillBits(dest_buf, columns, a0, a1);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                int run_len2 = 0;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                while (1) {
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    int run = _FaxGetRun(a0color ? FaxBlackRunIns : FaxWhiteRunIns, src_buf, bitpos, bitsize);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    run_len2 += run;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if (run < 64) {
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        break;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                }
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                a2 = a1 + run_len2;
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                if (a0color) {
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    _FaxFillBits(dest_buf, columns, a1, a2);
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                a0 = a2;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (a0 < columns) {
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    continue;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return TRUE;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else {
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (bitpos >= bitsize) {
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    return FALSE;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                bit = NEXTBIT;
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (bit) {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if (!a0color) {
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        _FaxFillBits(dest_buf, columns, a0, b2);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    if (b2 >= columns) {
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        return TRUE;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    a0 = b2;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    continue;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                } else {
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if (bitpos >= bitsize) {
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        return FALSE;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    FX_BOOL bit1 = NEXTBIT;
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if (bitpos >= bitsize) {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        return FALSE;
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    }
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    FX_BOOL bit2 = NEXTBIT;
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if (bit1 && bit2) {
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        v_delta = 2;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    } else if (bit1) {
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        v_delta = -2;
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    } else if (bit2) {
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        if (bitpos >= bitsize) {
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            return FALSE;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        }
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        bit = NEXTBIT;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        if (bit) {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            v_delta = 3;
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        } else {
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            v_delta = -3;
4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        }
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    } else {
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        if (bitpos >= bitsize) {
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            return FALSE;
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        }
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        bit = NEXTBIT;
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        if (bit) {
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            bitpos += 3;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            continue;
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        } else {
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            bitpos += 5;
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            return TRUE;
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        }
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        a1 = b1 + v_delta;
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!a0color) {
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            _FaxFillBits(dest_buf, columns, a0, a1);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (a1 >= columns) {
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return TRUE;
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        a0 = a1;
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        a0color = !a0color;
4885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FX_BOOL _FaxSkipEOL(const FX_BYTE* src_buf, int bitsize, int& bitpos)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int startbit = bitpos;
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (bitpos < bitsize) {
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int bit = NEXTBIT;
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (bit) {
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (bitpos - startbit <= 11) {
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                bitpos = startbit;
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return TRUE;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return FALSE;
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FX_BOOL _FaxGet1DLine(const FX_BYTE* src_buf, int bitsize, int& bitpos, FX_LPBYTE dest_buf, int columns)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int color = TRUE;
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int startpos = 0;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (1) {
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (bitpos >= bitsize) {
5105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return FALSE;
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
5125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        int run_len = 0;
5135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        while (1) {
5145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            int run = _FaxGetRun(color ? FaxWhiteRunIns : FaxBlackRunIns, src_buf, bitpos, bitsize);
5155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if (run < 0) {
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                while (bitpos < bitsize) {
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    int bit = NEXTBIT;
5185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    if (bit) {
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        return TRUE;
5205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    }
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return FALSE;
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
5245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            run_len += run;
5255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if (run < 64) {
5265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                break;
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!color) {
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            _FaxFillBits(dest_buf, columns, startpos, startpos + run_len);
5315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        }
5325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        startpos += run_len;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (startpos >= columns) {
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
5366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        color = !color;
5376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
5386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return TRUE;
5396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
5406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class CCodec_FaxDecoder : public CCodec_ScanlineDecoder
5416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles){
5426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)public:
5436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    CCodec_FaxDecoder();
5446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    virtual ~CCodec_FaxDecoder();
5456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    FX_BOOL				Create(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height,
5466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                               int K, FX_BOOL EndOfLine, FX_BOOL EncodedByteAlign, FX_BOOL BlackIs1, int Columns, int Rows);
5476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    virtual void		v_DownScale(int dest_width, int dest_height) {}
5486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    virtual FX_BOOL		v_Rewind();
5496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    virtual FX_LPBYTE	v_GetNextLine();
5506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    virtual FX_DWORD	GetSrcOffset();
5516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int			m_Encoding, m_bEndOfLine, m_bByteAlign, m_bBlack;
5526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int			bitpos;
5536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    FX_LPCBYTE	m_pSrcBuf;
5546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    FX_DWORD	m_SrcSize;
5556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    FX_LPBYTE	m_pScanlineBuf, m_pRefBuf;
5566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)};
5576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)CCodec_FaxDecoder::CCodec_FaxDecoder()
5586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles){
5596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    m_pScanlineBuf = NULL;
5606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    m_pRefBuf = NULL;
5616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
5626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)CCodec_FaxDecoder::~CCodec_FaxDecoder()
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (m_pScanlineBuf) {
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FX_Free(m_pScanlineBuf);
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (m_pRefBuf) {
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FX_Free(m_pRefBuf);
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FX_BOOL CCodec_FaxDecoder::Create(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height,
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  int K, FX_BOOL EndOfLine, FX_BOOL EncodedByteAlign, FX_BOOL BlackIs1, int Columns, int Rows)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    m_Encoding = K;
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_bEndOfLine = EndOfLine;
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_bByteAlign = EncodedByteAlign;
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_bBlack = BlackIs1;
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_OrigWidth = Columns;
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_OrigHeight = Rows;
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (m_OrigWidth == 0) {
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        m_OrigWidth = width;
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (m_OrigHeight == 0) {
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        m_OrigHeight = height;
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_Pitch = (m_OrigWidth + 31) / 32 * 4;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_OutputWidth = m_OrigWidth;
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_OutputHeight = m_OrigHeight;
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_pScanlineBuf = FX_Alloc(FX_BYTE, m_Pitch);
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (m_pScanlineBuf == NULL) {
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return FALSE;
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_pRefBuf = FX_Alloc(FX_BYTE, m_Pitch);
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (m_pRefBuf == NULL) {
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return FALSE;
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_pSrcBuf = src_buf;
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_SrcSize = src_size;
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_nComps = 1;
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_bpc = 1;
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_bColorTransformed = FALSE;
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TRUE;
6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FX_BOOL CCodec_FaxDecoder::v_Rewind()
60546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles){
6065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FXSYS_memset8(m_pRefBuf, 0xff, m_Pitch);
6075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bitpos = 0;
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TRUE;
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FX_LPBYTE CCodec_FaxDecoder::v_GetNextLine()
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int bitsize = m_SrcSize * 8;
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    _FaxSkipEOL(m_pSrcBuf, bitsize, bitpos);
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (bitpos >= bitsize) {
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return NULL;
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FXSYS_memset8(m_pScanlineBuf, 0xff, m_Pitch);
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (m_Encoding < 0) {
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        _FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, m_OrigWidth);
6205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        FXSYS_memcpy32(m_pRefBuf, m_pScanlineBuf, m_Pitch);
6216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    } else if (m_Encoding == 0) {
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        _FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidth);
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        FX_BOOL bNext1D = m_pSrcBuf[bitpos / 8] & (1 << (7 - bitpos % 8));
6256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        bitpos ++;
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (bNext1D) {
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            _FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidth);
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            _FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, m_OrigWidth);
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
63146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        FXSYS_memcpy32(m_pRefBuf, m_pScanlineBuf, m_Pitch);
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (m_bEndOfLine) {
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        _FaxSkipEOL(m_pSrcBuf, bitsize, bitpos);
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (m_bByteAlign && bitpos < bitsize) {
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int bitpos0 = bitpos;
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int bitpos1 = (bitpos + 7) / 8 * 8;
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        while (m_bByteAlign && bitpos0 < bitpos1) {
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int bit = m_pSrcBuf[bitpos0 / 8] & (1 << (7 - bitpos0 % 8));
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (bit != 0) {
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                m_bByteAlign = FALSE;
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else {
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                bitpos0 ++;
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (m_bByteAlign) {
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bitpos = bitpos1;
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (m_bBlack) {
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (int i = 0; i < m_Pitch; i ++) {
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            m_pScanlineBuf[i] = ~m_pScanlineBuf[i];
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return m_pScanlineBuf;
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FX_DWORD CCodec_FaxDecoder::GetSrcOffset()
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FX_DWORD ret = (bitpos + 7) / 8;
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret > m_SrcSize) {
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret = m_SrcSize;
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ret;
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" {
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void _FaxG4Decode(void*, FX_LPCBYTE src_buf, FX_DWORD src_size, int* pbitpos, FX_LPBYTE dest_buf, int width, int height, int pitch)
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (pitch == 0) {
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            pitch = (width + 7) / 8;
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FX_LPBYTE ref_buf = FX_Alloc(FX_BYTE, pitch);
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (ref_buf == NULL) {
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return;
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FXSYS_memset8(ref_buf, 0xff, pitch);
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int bitpos = *pbitpos;
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (int iRow = 0; iRow < height; iRow ++) {
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            FX_LPBYTE line_buf = dest_buf + iRow * pitch;
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            FXSYS_memset8(line_buf, 0xff, pitch);
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            _FaxG4GetRow(src_buf, src_size << 3, bitpos, line_buf, ref_buf, width);
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            FXSYS_memcpy32(ref_buf, line_buf, pitch);
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FX_Free(ref_buf);
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *pbitpos = bitpos;
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const FX_BYTE BlackRunTerminator[128] = {
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x37, 10, 0x02, 3, 0x03, 2, 0x02, 2, 0x03, 3, 0x03, 4, 0x02, 4, 0x03, 5,
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x05, 6, 0x04, 6, 0x04, 7, 0x05, 7, 0x07, 7, 0x04, 8, 0x07, 8, 0x18, 9,
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x17, 10, 0x18, 10, 0x08, 10, 0x67, 11, 0x68, 11, 0x6c, 11, 0x37, 11, 0x28, 11,
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x17, 11, 0x18, 11, 0xca, 12, 0xcb, 12, 0xcc, 12, 0xcd, 12, 0x68, 12, 0x69, 12,
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x6a, 12, 0x6b, 12, 0xd2, 12, 0xd3, 12, 0xd4, 12, 0xd5, 12, 0xd6, 12, 0xd7, 12,
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x6c, 12, 0x6d, 12, 0xda, 12, 0xdb, 12, 0x54, 12, 0x55, 12, 0x56, 12, 0x57, 12,
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x64, 12, 0x65, 12, 0x52, 12, 0x53, 12, 0x24, 12, 0x37, 12, 0x38, 12, 0x27, 12,
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x28, 12, 0x58, 12, 0x59, 12, 0x2b, 12, 0x2c, 12, 0x5a, 12, 0x66, 12, 0x67, 12,
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const FX_BYTE BlackRunMarkup[80] = {
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0f, 10, 0xc8, 12, 0xc9, 12, 0x5b, 12, 0x33, 12, 0x34, 12, 0x35, 12, 0x6c, 13,
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x6d, 13, 0x4a, 13, 0x4b, 13, 0x4c, 13, 0x4d, 13, 0x72, 13, 0x73, 13, 0x74, 13,
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x75, 13, 0x76, 13, 0x77, 13, 0x52, 13, 0x53, 13, 0x54, 13, 0x55, 13, 0x5a, 13,
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x5b, 13, 0x64, 13, 0x65, 13, 0x08, 11, 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12,
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x14, 12, 0x15, 12, 0x16, 12, 0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12,
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const FX_BYTE WhiteRunTerminator[128] = {
7065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    0x35, 8,
7075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    0x07, 6,
7085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    0x07, 4,
7095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    0x08, 4,
7105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    0x0B, 4,
7115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    0x0C, 4,
7125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    0x0E, 4,
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0F, 4,
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x13, 5,
7156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    0x14, 5,
7166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    0x07, 5,
7176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    0x08, 5,
7186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    0x08, 6,
7196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    0x03, 6,
7206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    0x34, 6,
7216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    0x35, 6,
7226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    0x2a, 6,
7236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    0x2B, 6,
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x27, 7,
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0c, 7,
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x08, 7,
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x17, 7,
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x03, 7,
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x04, 7,
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x28, 7,
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x2B, 7,
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x13, 7,
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x24, 7,
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x18, 7,
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x02, 8,
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x03, 8,
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x1a, 8,
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x1b, 8,
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x12, 8,
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x13, 8,
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x14, 8,
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x15, 8,
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x16, 8,
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x17, 8,
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x28, 8,
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x29, 8,
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x2a, 8,
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x2b, 8,
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x2c, 8,
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x2d, 8,
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x04, 8,
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x05, 8,
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0a, 8,
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0b, 8,
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x52, 8,
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x53, 8,
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x54, 8,
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x55, 8,
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x24, 8,
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x25, 8,
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x58, 8,
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x59, 8,
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x5a, 8,
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x5b, 8,
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x4a, 8,
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x4b, 8,
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x32, 8,
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x33, 8,
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x34, 8,
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const FX_BYTE WhiteRunMarkup[80] = {
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x1b, 5,
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x12, 5,
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x17, 6,
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x37, 7,
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x36, 8,
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x37, 8,
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x64, 8,
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x65, 8,
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x68, 8,
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x67, 8,
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xcc, 9,
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xcd, 9,
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd2, 9,
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd3, 9,
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd4, 9,
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd5, 9,
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd6, 9,
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd7, 9,
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd8, 9,
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd9, 9,
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xda, 9,
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xdb, 9,
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x98, 9,
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x99, 9,
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x9a, 9,
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x18, 6,
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x9b, 9,
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x08, 11,
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0c, 11,
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0d, 11,
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x12, 12,
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x13, 12,
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x14, 12,
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x15, 12,
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x16, 12,
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x17, 12,
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x1c, 12,
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x1d, 12,
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x1e, 12,
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x1f, 12,
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void _AddBitStream(FX_LPBYTE dest_buf, int& dest_bitpos, int data, int bitlen)
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = bitlen - 1; i >= 0; i --) {
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (data & (1 << i)) {
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dest_bitpos ++;
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void _FaxEncodeRun(FX_LPBYTE dest_buf, int& dest_bitpos, int run, FX_BOOL bWhite)
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (run >= 2560) {
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        _AddBitStream(dest_buf, dest_bitpos, 0x1f, 12);
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        run -= 2560;
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (run >= 64) {
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int markup = run - run % 64;
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FX_LPCBYTE p = bWhite ? WhiteRunMarkup : BlackRunMarkup;
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        p += (markup / 64 - 1) * 2;
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        _AddBitStream(dest_buf, dest_bitpos, *p, p[1]);
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    run %= 64;
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FX_LPCBYTE p = bWhite ? WhiteRunTerminator : BlackRunTerminator;
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    p += run * 2;
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    _AddBitStream(dest_buf, dest_bitpos, *p, p[1]);
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void _FaxEncode2DLine(FX_LPBYTE dest_buf, int& dest_bitpos, FX_LPCBYTE src_buf, FX_LPCBYTE ref_buf, int cols)
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int a0 = -1, a0color = 1;
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (1) {
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int a1 = _FindBit(src_buf, cols, a0 + 1, 1 - a0color);
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int b1, b2;
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        _FaxG4FindB1B2(ref_buf, cols, a0, a0color, b1, b2);
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (b2 < a1) {
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            dest_bitpos += 3;
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            dest_bitpos ++;
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            a0 = b2;
8515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        } else if (a1 - b1 <= 3 && b1 - a1 <= 3) {
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int delta = a1 - b1;
8535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            switch (delta) {
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                case 0:
8555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    break;
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                case 1:
8585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                case 2:
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                case 3:
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    dest_bitpos += delta == 1 ? 1 : delta + 2;
8615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
8625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    dest_bitpos ++;
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    break;
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                case -1:
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                case -2:
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                case -3:
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    dest_bitpos += delta == -1 ? 1 : -delta + 2;
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    dest_bitpos ++;
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    break;
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            dest_bitpos ++;
8746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            a0 = a1;
8756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            a0color = 1 - a0color;
8766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        } else {
8776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            int a2 = _FindBit(src_buf, cols, a1 + 1, a0color);
8786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            dest_bitpos ++;
8796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            dest_bitpos ++;
8806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
8816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            dest_bitpos ++;
8826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            if (a0 < 0) {
8836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                a0 = 0;
8846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            }
8856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            _FaxEncodeRun(dest_buf, dest_bitpos, a1 - a0, a0color);
8866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            _FaxEncodeRun(dest_buf, dest_bitpos, a2 - a1, 1 - a0color);
8876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            a0 = a2;
8886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        }
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (a0 >= cols) {
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return;
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CCodec_FaxEncoder : public CFX_Object
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CCodec_FaxEncoder(FX_LPCBYTE src_buf, int width, int height, int pitch);
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~CCodec_FaxEncoder();
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void			Encode(FX_LPBYTE& dest_buf, FX_DWORD& dest_size);
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void			Encode2DLine(FX_LPCBYTE scan_line);
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CFX_BinaryBuf	m_DestBuf;
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FX_LPBYTE		m_pRefLine, m_pLineBuf;
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int				m_Cols, m_Rows, m_Pitch;
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FX_LPCBYTE		m_pSrcBuf;
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CCodec_FaxEncoder::CCodec_FaxEncoder(FX_LPCBYTE src_buf, int width, int height, int pitch)
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_pSrcBuf = src_buf;
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_Cols = width;
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_Rows = height;
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_Pitch = pitch;
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_pRefLine = FX_Alloc(FX_BYTE, m_Pitch);
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (m_pRefLine == NULL) {
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FXSYS_memset8(m_pRefLine, 0xff, m_Pitch);
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_pLineBuf = FX_Alloc(FX_BYTE, m_Pitch * 8);
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (m_pLineBuf == NULL) {
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_DestBuf.EstimateSize(0, 10240);
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CCodec_FaxEncoder::~CCodec_FaxEncoder()
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (m_pRefLine) {
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FX_Free(m_pRefLine);
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (m_pLineBuf) {
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FX_Free(m_pLineBuf);
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CCodec_FaxEncoder::Encode(FX_LPBYTE& dest_buf, FX_DWORD& dest_size)
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int dest_bitpos = 0;
935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FX_BYTE last_byte = 0;
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int i = 0; i < m_Rows; i ++) {
9375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        FX_LPCBYTE scan_line = m_pSrcBuf + i * m_Pitch;
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FXSYS_memset32(m_pLineBuf, 0, m_Pitch * 8);
9395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        m_pLineBuf[0] = last_byte;
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        _FaxEncode2DLine(m_pLineBuf, dest_bitpos, scan_line, m_pRefLine, m_Cols);
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        m_DestBuf.AppendBlock(m_pLineBuf, dest_bitpos / 8);
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        last_byte = m_pLineBuf[dest_bitpos / 8];
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dest_bitpos %= 8;
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FXSYS_memcpy32(m_pRefLine, scan_line, m_Pitch);
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (dest_bitpos) {
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        m_DestBuf.AppendByte(last_byte);
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dest_buf = m_DestBuf.GetBuffer();
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dest_size = m_DestBuf.GetSize();
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_DestBuf.DetachBuffer();
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FX_BOOL	CCodec_FaxModule::Encode(FX_LPCBYTE src_buf, int width, int height, int pitch, FX_LPBYTE& dest_buf, FX_DWORD& dest_size)
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
955f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    CCodec_FaxEncoder encoder(src_buf, width, height, pitch);
956f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    encoder.Encode(dest_buf, dest_size);
957f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return TRUE;
958f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
959f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)ICodec_ScanlineDecoder*	CCodec_FaxModule::CreateDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height,
960f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        int K, FX_BOOL EndOfLine, FX_BOOL EncodedByteAlign, FX_BOOL BlackIs1, int Columns, int Rows)
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CCodec_FaxDecoder* pDecoder = FX_NEW CCodec_FaxDecoder;
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pDecoder == NULL) {
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return NULL;
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pDecoder->Create(src_buf, src_size, width, height, K, EndOfLine, EncodedByteAlign, BlackIs1, Columns, Rows);
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return pDecoder;
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)