1e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved. 2e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Use of this source code is governed by a BSD-style license that can be 3e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// found in the LICENSE file. 4ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 5e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 74d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include <algorithm> 84d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include <memory> 94d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include <vector> 104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "core/fxcodec/codec/ccodec_faxmodule.h" 12d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "core/fxcodec/codec/ccodec_scanlinedecoder.h" 134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fxcodec/codec/codec_int.h" 14d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "core/fxcrt/cfx_binarybuf.h" 154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fxcrt/fx_memory.h" 164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "third_party/base/ptr_util.h" 17d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "third_party/base/stl_util.h" 18ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 19ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannnamespace { 20ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 21ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannconst uint8_t OneLeadPos[256] = { 22ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 23ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 24ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 25ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 26ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}; 34ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannconst uint8_t ZeroLeadPos[256] = { 35ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 41ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 42ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 43ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 44ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 45e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, 46e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}; 47e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Limit of image dimension, an arbitrary large number. 494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannconst int kMaxImageDimension = 0x01FFFF; 504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 51ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannint FindBit(const uint8_t* data_buf, int max_pos, int start_pos, int bit) { 524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ASSERT(start_pos >= 0); 534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (start_pos >= max_pos) 54ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return max_pos; 554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 56ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const uint8_t* leading_pos = bit ? OneLeadPos : ZeroLeadPos; 57ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (start_pos % 8) { 58ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t data = data_buf[start_pos / 8]; 594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (bit) 60ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann data &= 0xff >> (start_pos % 8); 614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 62ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann data |= 0xff << (8 - start_pos % 8); 634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (leading_pos[data] < 8) 65ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return start_pos / 8 * 8 + leading_pos[data]; 664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 67ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann start_pos += 7; 68ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 69ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t skip = bit ? 0x00 : 0xff; 70ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int byte_pos = start_pos / 8; 71ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int max_byte = (max_pos + 7) / 8; 72ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann while (byte_pos < max_byte) { 734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (data_buf[byte_pos] != skip) 74ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ++byte_pos; 77ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (byte_pos == max_byte) 79ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return max_pos; 804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return std::min(leading_pos[data_buf[byte_pos]] + byte_pos * 8, max_pos); 82ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 83ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid FaxG4FindB1B2(const std::vector<uint8_t>& ref_buf, 85ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int columns, 86ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int a0, 87ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann bool a0color, 884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int* b1, 894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int* b2) { 90ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t first_bit = 91ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann (a0 < 0) ? 1 : ((ref_buf[a0 / 8] & (1 << (7 - a0 % 8))) != 0); 924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *b1 = FindBit(ref_buf.data(), columns, a0 + 1, !first_bit); 934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (*b1 >= columns) { 944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *b1 = *b2 = columns; 95ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return; 96ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 97ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (first_bit == !a0color) { 984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *b1 = FindBit(ref_buf.data(), columns, *b1 + 1, first_bit); 99ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann first_bit = !first_bit; 100ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 1014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (*b1 >= columns) { 1024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *b1 = *b2 = columns; 103ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return; 104ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 1054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *b2 = FindBit(ref_buf.data(), columns, *b1 + 1, first_bit); 106ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 107ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 108ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid FaxFillBits(uint8_t* dest_buf, int columns, int startpos, int endpos) { 1094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann startpos = std::max(startpos, 0); 110d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann endpos = pdfium::clamp(endpos, 0, columns); 1114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (startpos >= endpos) 112ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return; 1134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 114ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int first_byte = startpos / 8; 115ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int last_byte = (endpos - 1) / 8; 116ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (first_byte == last_byte) { 1174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (int i = startpos % 8; i <= (endpos - 1) % 8; ++i) 118ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann dest_buf[first_byte] -= 1 << (7 - i); 119ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return; 120ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 1214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (int i = startpos % 8; i < 8; ++i) 123ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann dest_buf[first_byte] -= 1 << (7 - i); 1244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (int i = 0; i <= (endpos - 1) % 8; ++i) 125ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann dest_buf[last_byte] -= 1 << (7 - i); 1264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (last_byte > first_byte + 1) 128d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann memset(dest_buf + first_byte + 1, 0, last_byte - first_byte - 1); 129e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 130ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmanninline bool NextBit(const uint8_t* src_buf, int* bitpos) { 1324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int pos = (*bitpos)++; 1334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return !!(src_buf[pos / 8] & (1 << (7 - pos % 8))); 1344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 135ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 136ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannconst uint8_t FaxBlackRunIns[] = { 137ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 2, 0x02, 3, 0, 0x03, 138ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2, 0, 2, 0x02, 1, 0, 139ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x03, 4, 0, 2, 0x02, 6, 140ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0x03, 5, 0, 1, 0x03, 141ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 7, 0, 2, 0x04, 9, 0, 142ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x05, 8, 0, 3, 0x04, 10, 143ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0x05, 11, 0, 0x07, 12, 144ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 2, 0x04, 13, 0, 0x07, 145ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 14, 0, 1, 0x18, 15, 0, 146ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 5, 0x08, 18, 0, 0x0f, 64, 147ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0x17, 16, 0, 0x18, 17, 148ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0x37, 0, 0, 10, 0x08, 149ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x00, 0x07, 0x0c, 0x40, 0x07, 0x0d, 150ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x80, 0x07, 0x17, 24, 0, 0x18, 151ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 25, 0, 0x28, 23, 0, 0x37, 152ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 22, 0, 0x67, 19, 0, 0x68, 153ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 20, 0, 0x6c, 21, 0, 54, 154ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x12, 1984 % 256, 1984 / 256, 0x13, 2048 % 256, 2048 / 256, 155ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x14, 2112 % 256, 2112 / 256, 0x15, 2176 % 256, 2176 / 256, 156ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x16, 2240 % 256, 2240 / 256, 0x17, 2304 % 256, 2304 / 256, 157ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x1c, 2368 % 256, 2368 / 256, 0x1d, 2432 % 256, 2432 / 256, 158ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x1e, 2496 % 256, 2496 / 256, 0x1f, 2560 % 256, 2560 / 256, 159ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x24, 52, 0, 0x27, 55, 0, 160ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x28, 56, 0, 0x2b, 59, 0, 161ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x2c, 60, 0, 0x33, 320 % 256, 320 / 256, 162ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x34, 384 % 256, 384 / 256, 0x35, 448 % 256, 448 / 256, 163ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x37, 53, 0, 0x38, 54, 0, 164ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x52, 50, 0, 0x53, 51, 0, 165ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x54, 44, 0, 0x55, 45, 0, 166ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x56, 46, 0, 0x57, 47, 0, 167ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x58, 57, 0, 0x59, 58, 0, 168ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x5a, 61, 0, 0x5b, 256 % 256, 256 / 256, 169ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x64, 48, 0, 0x65, 49, 0, 170ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x66, 62, 0, 0x67, 63, 0, 171ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x68, 30, 0, 0x69, 31, 0, 172ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x6a, 32, 0, 0x6b, 33, 0, 173ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x6c, 40, 0, 0x6d, 41, 0, 174ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0xc8, 128, 0, 0xc9, 192, 0, 175ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0xca, 26, 0, 0xcb, 27, 0, 176ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0xcc, 28, 0, 0xcd, 29, 0, 177ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0xd2, 34, 0, 0xd3, 35, 0, 178ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0xd4, 36, 0, 0xd5, 37, 0, 179ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0xd6, 38, 0, 0xd7, 39, 0, 180ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0xda, 42, 0, 0xdb, 43, 0, 181ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 20, 0x4a, 640 % 256, 640 / 256, 0x4b, 704 % 256, 182ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 704 / 256, 0x4c, 768 % 256, 768 / 256, 0x4d, 832 % 256, 183ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 832 / 256, 0x52, 1280 % 256, 1280 / 256, 0x53, 1344 % 256, 184ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1344 / 256, 0x54, 1408 % 256, 1408 / 256, 0x55, 1472 % 256, 185ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1472 / 256, 0x5a, 1536 % 256, 1536 / 256, 0x5b, 1600 % 256, 186ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1600 / 256, 0x64, 1664 % 256, 1664 / 256, 0x65, 1728 % 256, 187ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1728 / 256, 0x6c, 512 % 256, 512 / 256, 0x6d, 576 % 256, 188ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 576 / 256, 0x72, 896 % 256, 896 / 256, 0x73, 960 % 256, 189ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 960 / 256, 0x74, 1024 % 256, 1024 / 256, 0x75, 1088 % 256, 190ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1088 / 256, 0x76, 1152 % 256, 1152 / 256, 0x77, 1216 % 256, 191ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1216 / 256, 0xff}; 192ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 193ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannconst uint8_t FaxWhiteRunIns[] = { 194ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0, 0, 6, 0x07, 2, 195ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0x08, 3, 0, 0x0B, 4, 196ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0x0C, 5, 0, 0x0E, 6, 197ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0x0F, 7, 0, 6, 0x07, 198ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 10, 0, 0x08, 11, 0, 0x12, 199ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 128, 0, 0x13, 8, 0, 0x14, 200ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 9, 0, 0x1b, 64, 0, 9, 201ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x03, 13, 0, 0x07, 1, 0, 202ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x08, 12, 0, 0x17, 192, 0, 203ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x18, 1664 % 256, 1664 / 256, 0x2a, 16, 0, 204ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x2B, 17, 0, 0x34, 14, 0, 205ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x35, 15, 0, 12, 0x03, 22, 206ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0x04, 23, 0, 0x08, 20, 207ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0x0c, 19, 0, 0x13, 26, 208ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0x17, 21, 0, 0x18, 28, 209ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0x24, 27, 0, 0x27, 18, 210ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0x28, 24, 0, 0x2B, 25, 211ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 0x37, 256 % 256, 256 / 256, 42, 0x02, 212ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 29, 0, 0x03, 30, 0, 0x04, 213ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 45, 0, 0x05, 46, 0, 0x0a, 214ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 47, 0, 0x0b, 48, 0, 0x12, 215ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 33, 0, 0x13, 34, 0, 0x14, 216ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 35, 0, 0x15, 36, 0, 0x16, 217ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 37, 0, 0x17, 38, 0, 0x1a, 218ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 31, 0, 0x1b, 32, 0, 0x24, 219ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 53, 0, 0x25, 54, 0, 0x28, 220ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 39, 0, 0x29, 40, 0, 0x2a, 221ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 41, 0, 0x2b, 42, 0, 0x2c, 222ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 43, 0, 0x2d, 44, 0, 0x32, 223ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 61, 0, 0x33, 62, 0, 0x34, 224ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 63, 0, 0x35, 0, 0, 0x36, 225ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 320 % 256, 320 / 256, 0x37, 384 % 256, 384 / 256, 0x4a, 226ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 59, 0, 0x4b, 60, 0, 0x52, 227ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 49, 0, 0x53, 50, 0, 0x54, 228ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 51, 0, 0x55, 52, 0, 0x58, 229ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 55, 0, 0x59, 56, 0, 0x5a, 230ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 57, 0, 0x5b, 58, 0, 0x64, 231ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 448 % 256, 448 / 256, 0x65, 512 % 256, 512 / 256, 0x67, 232ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 640 % 256, 640 / 256, 0x68, 576 % 256, 576 / 256, 16, 233ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x98, 1472 % 256, 1472 / 256, 0x99, 1536 % 256, 1536 / 256, 234ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x9a, 1600 % 256, 1600 / 256, 0x9b, 1728 % 256, 1728 / 256, 235ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0xcc, 704 % 256, 704 / 256, 0xcd, 768 % 256, 768 / 256, 236ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0xd2, 832 % 256, 832 / 256, 0xd3, 896 % 256, 896 / 256, 237ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0xd4, 960 % 256, 960 / 256, 0xd5, 1024 % 256, 1024 / 256, 238ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0xd6, 1088 % 256, 1088 / 256, 0xd7, 1152 % 256, 1152 / 256, 239ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0xd8, 1216 % 256, 1216 / 256, 0xd9, 1280 % 256, 1280 / 256, 240ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0xda, 1344 % 256, 1344 / 256, 0xdb, 1408 % 256, 1408 / 256, 241ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 3, 0x08, 1792 % 256, 1792 / 256, 0x0c, 242ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1856 % 256, 1856 / 256, 0x0d, 1920 % 256, 1920 / 256, 10, 243ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x12, 1984 % 256, 1984 / 256, 0x13, 2048 % 256, 2048 / 256, 244ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x14, 2112 % 256, 2112 / 256, 0x15, 2176 % 256, 2176 / 256, 245ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x16, 2240 % 256, 2240 / 256, 0x17, 2304 % 256, 2304 / 256, 246ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x1c, 2368 % 256, 2368 / 256, 0x1d, 2432 % 256, 2432 / 256, 247ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x1e, 2496 % 256, 2496 / 256, 0x1f, 2560 % 256, 2560 / 256, 248ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0xff, 249ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann}; 250ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 251ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannint FaxGetRun(const uint8_t* ins_array, 252ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const uint8_t* src_buf, 2534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int* bitpos, 254ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int bitsize) { 2554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t code = 0; 256ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int ins_off = 0; 257ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann while (1) { 258ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t ins = ins_array[ins_off++]; 2594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (ins == 0xff) 260ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return -1; 2614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (*bitpos >= bitsize) 263ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return -1; 2644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 265ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann code <<= 1; 2664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (src_buf[*bitpos / 8] & (1 << (7 - *bitpos % 8))) 2674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ++code; 2684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ++(*bitpos); 270ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int next_off = ins_off + ins * 3; 271ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann for (; ins_off < next_off; ins_off += 3) { 272d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (ins_array[ins_off] == code) 273ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return ins_array[ins_off + 1] + ins_array[ins_off + 2] * 256; 274e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 275ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 276e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 277ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 278d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid FaxG4GetRow(const uint8_t* src_buf, 2794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int bitsize, 2804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int* bitpos, 2814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint8_t* dest_buf, 2824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const std::vector<uint8_t>& ref_buf, 2834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int columns) { 284ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int a0 = -1; 285ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann bool a0color = true; 286ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann while (1) { 2874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (*bitpos >= bitsize) 288d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 2894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int a1; 2914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int a2; 2924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int b1; 2934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int b2; 2944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FaxG4FindB1B2(ref_buf, columns, a0, a0color, &b1, &b2); 2954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 296ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int v_delta = 0; 2974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!NextBit(src_buf, bitpos)) { 2984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (*bitpos >= bitsize) 299d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 3004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool bit1 = NextBit(src_buf, bitpos); 3024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (*bitpos >= bitsize) 303d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 3044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool bit2 = NextBit(src_buf, bitpos); 3064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (bit1) { 3074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann v_delta = bit2 ? 1 : -1; 308ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else if (bit2) { 309ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int run_len1 = 0; 310ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann while (1) { 311ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int run = FaxGetRun(a0color ? FaxWhiteRunIns : FaxBlackRunIns, 312ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann src_buf, bitpos, bitsize); 313ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann run_len1 += run; 314d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (run < 64) 315ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 316e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 3174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (a0 < 0) 3184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ++run_len1; 319d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (run_len1 < 0) 320d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 3214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 322ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann a1 = a0 + run_len1; 3234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!a0color) 324ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FaxFillBits(dest_buf, columns, a0, a1); 3254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 326ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int run_len2 = 0; 327ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann while (1) { 328ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int run = FaxGetRun(a0color ? FaxBlackRunIns : FaxWhiteRunIns, 329ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann src_buf, bitpos, bitsize); 330ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann run_len2 += run; 331d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (run < 64) 332ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 333e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 334d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (run_len2 < 0) 335d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 336ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann a2 = a1 + run_len2; 3374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (a0color) 338ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FaxFillBits(dest_buf, columns, a1, a2); 3394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 340ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann a0 = a2; 3414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (a0 < columns) 342ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann continue; 3434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 344d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 345ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else { 3464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (*bitpos >= bitsize) 347d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 3484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (NextBit(src_buf, bitpos)) { 3504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!a0color) 351ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FaxFillBits(dest_buf, columns, a0, b2); 3524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (b2 >= columns) 354d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 3554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 356ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann a0 = b2; 357ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann continue; 3584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 3594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (*bitpos >= bitsize) 361d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 3624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool next_bit1 = NextBit(src_buf, bitpos); 3644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (*bitpos >= bitsize) 365d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 3664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool next_bit2 = NextBit(src_buf, bitpos); 3684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (next_bit1) { 3694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann v_delta = next_bit2 ? 2 : -2; 3704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } else if (next_bit2) { 3714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (*bitpos >= bitsize) 372d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 3734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann v_delta = NextBit(src_buf, bitpos) ? 3 : -3; 375e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } else { 3764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (*bitpos >= bitsize) 377d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 3784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (NextBit(src_buf, bitpos)) { 3804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *bitpos += 3; 3814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann continue; 382ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 3834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *bitpos += 5; 384d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 385e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 386ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 387e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 388ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann a1 = b1 + v_delta; 3894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!a0color) 390ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FaxFillBits(dest_buf, columns, a0, a1); 3914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (a1 >= columns) 393d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 3944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann // The position of picture element must be monotonic increasing. 3964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (a0 >= a1) 397d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 3984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 399ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann a0 = a1; 400ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann a0color = !a0color; 401ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 402e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 403ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 404d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid FaxSkipEOL(const uint8_t* src_buf, int bitsize, int* bitpos) { 4054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int startbit = *bitpos; 4064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (*bitpos < bitsize) { 4074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!NextBit(src_buf, bitpos)) 4084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann continue; 4094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (*bitpos - startbit <= 11) 4104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *bitpos = startbit; 411d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 4124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 413e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 414ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 415d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid FaxGet1DLine(const uint8_t* src_buf, 4164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int bitsize, 4174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int* bitpos, 4184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann std::vector<uint8_t>* dest_buf, 4194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int columns) { 420ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann bool color = true; 421ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int startpos = 0; 422ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann while (1) { 4234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (*bitpos >= bitsize) 424d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 4254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 426ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int run_len = 0; 427ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann while (1) { 428ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int run = FaxGetRun(color ? FaxWhiteRunIns : FaxBlackRunIns, src_buf, 429ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann bitpos, bitsize); 430ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (run < 0) { 4314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (*bitpos < bitsize) { 4324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (NextBit(src_buf, bitpos)) 433d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 434e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 435d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 436ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 437ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann run_len += run; 438d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (run < 64) 439ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 440ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 4414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!color) 4424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FaxFillBits(dest_buf->data(), columns, startpos, startpos + run_len); 4434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 444ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann startpos += run_len; 4454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (startpos >= columns) 446ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 4474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 448ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann color = !color; 449ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 450e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 451ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 4524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} // namespace 4534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannclass CCodec_FaxDecoder : public CCodec_ScanlineDecoder { 4554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann public: 4564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CCodec_FaxDecoder(const uint8_t* src_buf, 4574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t src_size, 4584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int width, 4594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int height, 4604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t pitch, 4614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int K, 4624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool EndOfLine, 4634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool EncodedByteAlign, 4644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool BlackIs1); 4654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ~CCodec_FaxDecoder() override; 4664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann // CCodec_ScanlineDecoder 4684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool v_Rewind() override; 4694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint8_t* v_GetNextLine() override; 4704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t GetSrcOffset() override; 4714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann private: 4734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const int m_Encoding; 4744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int m_bitpos; 4754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool m_bByteAlign; 4764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const bool m_bEndOfLine; 4774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const bool m_bBlack; 4784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const uint32_t m_SrcSize; 4794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const uint8_t* const m_pSrcBuf; 4804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann std::vector<uint8_t> m_ScanlineBuf; 4814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann std::vector<uint8_t> m_RefBuf; 4824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}; 4834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCCodec_FaxDecoder::CCodec_FaxDecoder(const uint8_t* src_buf, 4854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t src_size, 4864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int width, 4874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int height, 4884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t pitch, 4894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int K, 4904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool EndOfLine, 4914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool EncodedByteAlign, 4924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool BlackIs1) 4934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann : CCodec_ScanlineDecoder(width, height, width, height, 1, 1, pitch), 4944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_Encoding(K), 4954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_bitpos(0), 4964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_bByteAlign(EncodedByteAlign), 4974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_bEndOfLine(EndOfLine), 4984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_bBlack(BlackIs1), 4994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_SrcSize(src_size), 5004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_pSrcBuf(src_buf), 5014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_ScanlineBuf(pitch), 5024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_RefBuf(pitch) {} 5034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCCodec_FaxDecoder::~CCodec_FaxDecoder() {} 5054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CCodec_FaxDecoder::v_Rewind() { 507d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann memset(m_RefBuf.data(), 0xff, m_RefBuf.size()); 5084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_bitpos = 0; 5094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return true; 5104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 5114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannuint8_t* CCodec_FaxDecoder::v_GetNextLine() { 5134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int bitsize = m_SrcSize * 8; 5144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FaxSkipEOL(m_pSrcBuf, bitsize, &m_bitpos); 5154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (m_bitpos >= bitsize) 5164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return nullptr; 5174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 518d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann memset(m_ScanlineBuf.data(), 0xff, m_ScanlineBuf.size()); 5194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (m_Encoding < 0) { 5204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FaxG4GetRow(m_pSrcBuf, bitsize, &m_bitpos, m_ScanlineBuf.data(), m_RefBuf, 5214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_OrigWidth); 5224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_RefBuf = m_ScanlineBuf; 5234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } else if (m_Encoding == 0) { 5244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FaxGet1DLine(m_pSrcBuf, bitsize, &m_bitpos, &m_ScanlineBuf, m_OrigWidth); 5254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } else { 5264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (NextBit(m_pSrcBuf, &m_bitpos)) { 5274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FaxGet1DLine(m_pSrcBuf, bitsize, &m_bitpos, &m_ScanlineBuf, m_OrigWidth); 5284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } else { 5294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FaxG4GetRow(m_pSrcBuf, bitsize, &m_bitpos, m_ScanlineBuf.data(), m_RefBuf, 5304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_OrigWidth); 5314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_RefBuf = m_ScanlineBuf; 5334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (m_bEndOfLine) 5354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FaxSkipEOL(m_pSrcBuf, bitsize, &m_bitpos); 5364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (m_bByteAlign && m_bitpos < bitsize) { 5384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int bitpos0 = m_bitpos; 5394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int bitpos1 = (m_bitpos + 7) / 8 * 8; 5404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (m_bByteAlign && bitpos0 < bitpos1) { 5414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int bit = m_pSrcBuf[bitpos0 / 8] & (1 << (7 - bitpos0 % 8)); 542d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (bit != 0) 5434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_bByteAlign = false; 544d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann else 5454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ++bitpos0; 5464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (m_bByteAlign) 5484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_bitpos = bitpos1; 5494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (m_bBlack) { 551d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (uint32_t i = 0; i < m_Pitch; ++i) 5524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_ScanlineBuf[i] = ~m_ScanlineBuf[i]; 5534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return m_ScanlineBuf.data(); 5554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 5564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannuint32_t CCodec_FaxDecoder::GetSrcOffset() { 5584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return std::min(static_cast<uint32_t>((m_bitpos + 7) / 8), m_SrcSize); 5594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 5604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid FaxG4Decode(const uint8_t* src_buf, 5624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t src_size, 5634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int* pbitpos, 5644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint8_t* dest_buf, 5654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int width, 5664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int height, 5674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int pitch) { 5684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (pitch == 0) 5694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pitch = (width + 7) / 8; 5704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann std::vector<uint8_t> ref_buf(pitch, 0xff); 5724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int bitpos = *pbitpos; 5734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (int iRow = 0; iRow < height; iRow++) { 5744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint8_t* line_buf = dest_buf + iRow * pitch; 575d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann memset(line_buf, 0xff, pitch); 5764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FaxG4GetRow(src_buf, src_size << 3, &bitpos, line_buf, ref_buf, width); 577d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann memcpy(ref_buf.data(), line_buf, pitch); 5784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *pbitpos = bitpos; 5804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 5814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstd::unique_ptr<CCodec_ScanlineDecoder> CCodec_FaxModule::CreateDecoder( 5834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const uint8_t* src_buf, 5844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t src_size, 5854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int width, 5864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int height, 5874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int K, 5884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool EndOfLine, 5894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool EncodedByteAlign, 5904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool BlackIs1, 5914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int Columns, 5924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int Rows) { 5934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int actual_width = Columns ? Columns : width; 5944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int actual_height = Rows ? Rows : height; 5954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann // Reject invalid values. 5974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (actual_width <= 0 || actual_height <= 0) 5984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return nullptr; 5994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann // Reject unreasonable large input. 6014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (actual_width > kMaxImageDimension || actual_height > kMaxImageDimension) 6024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return nullptr; 6034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t pitch = (static_cast<uint32_t>(actual_width) + 31) / 32 * 4; 6054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return pdfium::MakeUnique<CCodec_FaxDecoder>( 6064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann src_buf, src_size, actual_width, actual_height, pitch, K, EndOfLine, 6074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann EncodedByteAlign, BlackIs1); 6084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 6094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 610d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ 6114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannnamespace { 612ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannconst uint8_t BlackRunTerminator[128] = { 613ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x37, 10, 0x02, 3, 0x03, 2, 0x02, 2, 0x03, 3, 0x03, 4, 0x02, 4, 614ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x03, 5, 0x05, 6, 0x04, 6, 0x04, 7, 0x05, 7, 0x07, 7, 0x04, 8, 615ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x07, 8, 0x18, 9, 0x17, 10, 0x18, 10, 0x08, 10, 0x67, 11, 0x68, 11, 616ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x6c, 11, 0x37, 11, 0x28, 11, 0x17, 11, 0x18, 11, 0xca, 12, 0xcb, 12, 617ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0xcc, 12, 0xcd, 12, 0x68, 12, 0x69, 12, 0x6a, 12, 0x6b, 12, 0xd2, 12, 618ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0xd3, 12, 0xd4, 12, 0xd5, 12, 0xd6, 12, 0xd7, 12, 0x6c, 12, 0x6d, 12, 619ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0xda, 12, 0xdb, 12, 0x54, 12, 0x55, 12, 0x56, 12, 0x57, 12, 0x64, 12, 620ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x65, 12, 0x52, 12, 0x53, 12, 0x24, 12, 0x37, 12, 0x38, 12, 0x27, 12, 621ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x28, 12, 0x58, 12, 0x59, 12, 0x2b, 12, 0x2c, 12, 0x5a, 12, 0x66, 12, 622ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x67, 12, 623e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}; 624ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 625ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannconst uint8_t BlackRunMarkup[80] = { 626ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x0f, 10, 0xc8, 12, 0xc9, 12, 0x5b, 12, 0x33, 12, 0x34, 12, 0x35, 12, 627ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x6c, 13, 0x6d, 13, 0x4a, 13, 0x4b, 13, 0x4c, 13, 0x4d, 13, 0x72, 13, 628ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x73, 13, 0x74, 13, 0x75, 13, 0x76, 13, 0x77, 13, 0x52, 13, 0x53, 13, 629ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x54, 13, 0x55, 13, 0x5a, 13, 0x5b, 13, 0x64, 13, 0x65, 13, 0x08, 11, 630ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12, 0x14, 12, 0x15, 12, 0x16, 12, 631ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12, 632e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}; 633ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 634ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannconst uint8_t WhiteRunTerminator[128] = { 635ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x35, 8, 0x07, 6, 0x07, 4, 0x08, 4, 0x0B, 4, 0x0C, 4, 0x0E, 4, 0x0F, 4, 636ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x13, 5, 0x14, 5, 0x07, 5, 0x08, 5, 0x08, 6, 0x03, 6, 0x34, 6, 0x35, 6, 637ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x2a, 6, 0x2B, 6, 0x27, 7, 0x0c, 7, 0x08, 7, 0x17, 7, 0x03, 7, 0x04, 7, 638ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x28, 7, 0x2B, 7, 0x13, 7, 0x24, 7, 0x18, 7, 0x02, 8, 0x03, 8, 0x1a, 8, 639ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x1b, 8, 0x12, 8, 0x13, 8, 0x14, 8, 0x15, 8, 0x16, 8, 0x17, 8, 0x28, 8, 640ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x29, 8, 0x2a, 8, 0x2b, 8, 0x2c, 8, 0x2d, 8, 0x04, 8, 0x05, 8, 0x0a, 8, 641ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x0b, 8, 0x52, 8, 0x53, 8, 0x54, 8, 0x55, 8, 0x24, 8, 0x25, 8, 0x58, 8, 642ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x59, 8, 0x5a, 8, 0x5b, 8, 0x4a, 8, 0x4b, 8, 0x32, 8, 0x33, 8, 0x34, 8, 643e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}; 644ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 645ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannconst uint8_t WhiteRunMarkup[80] = { 646ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x1b, 5, 0x12, 5, 0x17, 6, 0x37, 7, 0x36, 8, 0x37, 8, 0x64, 8, 647ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x65, 8, 0x68, 8, 0x67, 8, 0xcc, 9, 0xcd, 9, 0xd2, 9, 0xd3, 9, 648ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0xd4, 9, 0xd5, 9, 0xd6, 9, 0xd7, 9, 0xd8, 9, 0xd9, 9, 0xda, 9, 649ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0xdb, 9, 0x98, 9, 0x99, 9, 0x9a, 9, 0x18, 6, 0x9b, 9, 0x08, 11, 650ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12, 0x14, 12, 0x15, 12, 0x16, 12, 651ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12, 652e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}; 653ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 6544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid AddBitStream(uint8_t* dest_buf, int* dest_bitpos, int data, int bitlen) { 655ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann for (int i = bitlen - 1; i >= 0; i--) { 656d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (data & (1 << i)) 6574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest_buf[*dest_bitpos / 8] |= 1 << (7 - *dest_bitpos % 8); 6584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (*dest_bitpos)++; 659ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 660e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 661ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 6624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid FaxEncodeRun(uint8_t* dest_buf, int* dest_bitpos, int run, bool bWhite) { 663ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann while (run >= 2560) { 664ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann AddBitStream(dest_buf, dest_bitpos, 0x1f, 12); 665ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann run -= 2560; 666ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 667ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (run >= 64) { 668ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int markup = run - run % 64; 669ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const uint8_t* p = bWhite ? WhiteRunMarkup : BlackRunMarkup; 670ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann p += (markup / 64 - 1) * 2; 671ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann AddBitStream(dest_buf, dest_bitpos, *p, p[1]); 672ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 673ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann run %= 64; 674ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const uint8_t* p = bWhite ? WhiteRunTerminator : BlackRunTerminator; 675ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann p += run * 2; 676ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann AddBitStream(dest_buf, dest_bitpos, *p, p[1]); 677e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 678ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 679ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid FaxEncode2DLine(uint8_t* dest_buf, 6804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int* dest_bitpos, 681ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const uint8_t* src_buf, 6824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const std::vector<uint8_t>& ref_buf, 683ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int cols) { 684ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int a0 = -1; 685ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann bool a0color = true; 686ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann while (1) { 687ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int a1 = FindBit(src_buf, cols, a0 + 1, !a0color); 6884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int b1; 6894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int b2; 6904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FaxG4FindB1B2(ref_buf, cols, a0, a0color, &b1, &b2); 691ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (b2 < a1) { 6924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *dest_bitpos += 3; 6934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest_buf[*dest_bitpos / 8] |= 1 << (7 - *dest_bitpos % 8); 6944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (*dest_bitpos)++; 695ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann a0 = b2; 696ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else if (a1 - b1 <= 3 && b1 - a1 <= 3) { 697ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int delta = a1 - b1; 698ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann switch (delta) { 699ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann case 0: 7004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest_buf[*dest_bitpos / 8] |= 1 << (7 - *dest_bitpos % 8); 701ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 702ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann case 1: 703ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann case 2: 704ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann case 3: 7054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *dest_bitpos += delta == 1 ? 1 : delta + 2; 7064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest_buf[*dest_bitpos / 8] |= 1 << (7 - *dest_bitpos % 8); 7074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (*dest_bitpos)++; 7084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest_buf[*dest_bitpos / 8] |= 1 << (7 - *dest_bitpos % 8); 709ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 710ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann case -1: 711ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann case -2: 712ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann case -3: 7134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *dest_bitpos += delta == -1 ? 1 : -delta + 2; 7144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest_buf[*dest_bitpos / 8] |= 1 << (7 - *dest_bitpos % 8); 7154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (*dest_bitpos)++; 716ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 717ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 7184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (*dest_bitpos)++; 719ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann a0 = a1; 720ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann a0color = !a0color; 721ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else { 722ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int a2 = FindBit(src_buf, cols, a1 + 1, a0color); 7234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (*dest_bitpos)++; 7244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (*dest_bitpos)++; 7254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest_buf[*dest_bitpos / 8] |= 1 << (7 - *dest_bitpos % 8); 7264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (*dest_bitpos)++; 727d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (a0 < 0) 728ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann a0 = 0; 729ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FaxEncodeRun(dest_buf, dest_bitpos, a1 - a0, a0color); 730ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FaxEncodeRun(dest_buf, dest_bitpos, a2 - a1, !a0color); 731ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann a0 = a2; 732ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 733d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (a0 >= cols) 734ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return; 735ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 736ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 737ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 738ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannclass CCodec_FaxEncoder { 739ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann public: 740ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CCodec_FaxEncoder(const uint8_t* src_buf, int width, int height, int pitch); 741ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ~CCodec_FaxEncoder(); 7424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann void Encode(std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf, 7434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t* dest_size); 7444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann private: 746ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CFX_BinaryBuf m_DestBuf; 7474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann std::vector<uint8_t> m_RefLine; 748ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t* m_pLineBuf; 7494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const int m_Cols; 7504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const int m_Rows; 7514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const int m_Pitch; 752ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const uint8_t* m_pSrcBuf; 753e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}; 7544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 755ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannCCodec_FaxEncoder::CCodec_FaxEncoder(const uint8_t* src_buf, 756ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int width, 757ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int height, 7584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int pitch) 7594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann : m_Cols(width), m_Rows(height), m_Pitch(pitch), m_pSrcBuf(src_buf) { 7604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_RefLine.resize(m_Pitch); 761d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann memset(m_RefLine.data(), 0xff, m_Pitch); 762ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pLineBuf = FX_Alloc2D(uint8_t, m_Pitch, 8); 763ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_DestBuf.EstimateSize(0, 10240); 764e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 7654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 766ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannCCodec_FaxEncoder::~CCodec_FaxEncoder() { 767ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_Free(m_pLineBuf); 768e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 7694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CCodec_FaxEncoder::Encode( 7714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf, 7724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t* dest_size) { 773ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int dest_bitpos = 0; 774ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t last_byte = 0; 775ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann for (int i = 0; i < m_Rows; i++) { 776ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const uint8_t* scan_line = m_pSrcBuf + i * m_Pitch; 777d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann memset(m_pLineBuf, 0, m_Pitch * 8); 778ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pLineBuf[0] = last_byte; 7794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FaxEncode2DLine(m_pLineBuf, &dest_bitpos, scan_line, m_RefLine, m_Cols); 780ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_DestBuf.AppendBlock(m_pLineBuf, dest_bitpos / 8); 781ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann last_byte = m_pLineBuf[dest_bitpos / 8]; 782ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann dest_bitpos %= 8; 783d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann memcpy(m_RefLine.data(), scan_line, m_Pitch); 784ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 785d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (dest_bitpos) 786ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_DestBuf.AppendByte(last_byte); 7874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *dest_size = m_DestBuf.GetSize(); 7884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *dest_buf = m_DestBuf.DetachBuffer(); 789e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 7904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} // namespace 7924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CCodec_FaxModule::FaxEncode( 794ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const uint8_t* src_buf, 795ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int width, 796ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int height, 7974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int pitch, 7984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf, 7994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t* dest_size) { 8004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CCodec_FaxEncoder encoder(src_buf, width, height, pitch); 8014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann encoder.Encode(dest_buf, dest_size); 802e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 8034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 804d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#endif // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ 805