Home | History | Annotate | Download | only in fpdf_parser
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "../../fx_zlib.h"
      8 #include "../../../include/fpdfapi/fpdf_parser.h"
      9 #include "../../../include/fxcodec/fx_codec.h"
     10 #include "../../../include/fpdfapi/fpdf_module.h"
     11 #include "filters_int.h"
     12 CFX_DataFilter::CFX_DataFilter()
     13 {
     14     m_bEOF = FALSE;
     15     m_pDestFilter = NULL;
     16     m_SrcPos = 0;
     17 }
     18 CFX_DataFilter::~CFX_DataFilter()
     19 {
     20     if (m_pDestFilter) {
     21         delete m_pDestFilter;
     22     }
     23 }
     24 void CFX_DataFilter::SetDestFilter(CFX_DataFilter* pFilter)
     25 {
     26     if (m_pDestFilter) {
     27         m_pDestFilter->SetDestFilter(pFilter);
     28     } else {
     29         m_pDestFilter = pFilter;
     30     }
     31 }
     32 void CFX_DataFilter::FilterIn(FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf)
     33 {
     34     if (m_bEOF) {
     35         return;
     36     }
     37     m_SrcPos += src_size;
     38     if (m_pDestFilter) {
     39         CFX_BinaryBuf temp_buf;
     40         temp_buf.EstimateSize(FPDF_FILTER_BUFFER_SIZE, FPDF_FILTER_BUFFER_SIZE);
     41         v_FilterIn(src_buf, src_size, temp_buf);
     42         m_pDestFilter->FilterIn(temp_buf.GetBuffer(), temp_buf.GetSize(), dest_buf);
     43     } else {
     44         v_FilterIn(src_buf, src_size, dest_buf);
     45     }
     46 }
     47 void CFX_DataFilter::FilterFinish(CFX_BinaryBuf& dest_buf)
     48 {
     49     if (m_pDestFilter) {
     50         CFX_BinaryBuf temp_buf;
     51         v_FilterFinish(temp_buf);
     52         if (temp_buf.GetSize()) {
     53             m_pDestFilter->FilterIn(temp_buf.GetBuffer(), temp_buf.GetSize(), dest_buf);
     54         }
     55         m_pDestFilter->FilterFinish(dest_buf);
     56     } else {
     57         v_FilterFinish(dest_buf);
     58     }
     59     m_bEOF = TRUE;
     60 }
     61 void CFX_DataFilter::ReportEOF(FX_DWORD left_input)
     62 {
     63     if (m_bEOF) {
     64         return;
     65     }
     66     m_bEOF = TRUE;
     67     m_SrcPos -= left_input;
     68 }
     69 CFX_DataFilter* FPDF_CreateFilter(FX_BSTR name, const CPDF_Dictionary* pParam, int width, int height)
     70 {
     71     FX_DWORD id = name.GetID();
     72     switch (id) {
     73         case FXBSTR_ID('F', 'l', 'a', 't'):
     74         case FXBSTR_ID('F', 'l', 0, 0):
     75         case FXBSTR_ID('L', 'Z', 'W', 'D'):
     76         case FXBSTR_ID('L', 'Z', 'W', 0): {
     77                 CFX_DataFilter* pFilter;
     78                 if (id == FXBSTR_ID('L', 'Z', 'W', 'D') || id == FXBSTR_ID('L', 'Z', 'W', 0)) {
     79                     pFilter = new CPDF_LzwFilter(pParam ? pParam->GetInteger("EarlyChange", 1) : 1);
     80                 } else {
     81                     pFilter = new CPDF_FlateFilter;
     82                 }
     83                 if ((pParam ? pParam->GetInteger("Predictor", 1) : 1) > 1) {
     84                     CFX_DataFilter* pPredictor = new CPDF_PredictorFilter(pParam->GetInteger(FX_BSTRC("Predictor"), 1),
     85                                                  pParam->GetInteger(FX_BSTRC("Colors"), 1), pParam->GetInteger(FX_BSTRC("BitsPerComponent"), 8),
     86                                                  pParam->GetInteger(FX_BSTRC("Columns"), 1));
     87                     pFilter->SetDestFilter(pPredictor);
     88                 }
     89                 return pFilter;
     90             }
     91         case FXBSTR_ID('A', 'S', 'C', 'I'):
     92             if (name == "ASCIIHexDecode") {
     93                 return new CPDF_AsciiHexFilter;
     94             }
     95             return new CPDF_Ascii85Filter;
     96         case FXBSTR_ID('A', 'H', 'x', 0):
     97             return new CPDF_AsciiHexFilter;
     98         case FXBSTR_ID('A', '8', '5', 0):
     99             return new CPDF_Ascii85Filter;
    100         case FXBSTR_ID('R', 'u', 'n', 'L'):
    101             return new CPDF_RunLenFilter;
    102         case FXBSTR_ID('C', 'C', 'I', 'T'): {
    103                 int Encoding = 0;
    104                 int bEndOfLine = FALSE;
    105                 int bByteAlign = FALSE;
    106                 int bBlack = FALSE;
    107                 int nRows = 0;
    108                 int nColumns = 1728;
    109                 if (pParam) {
    110                     Encoding = pParam->GetInteger(FX_BSTRC("K"));
    111                     bEndOfLine = pParam->GetInteger(FX_BSTRC("EndOfLine"));
    112                     bByteAlign = pParam->GetInteger(FX_BSTRC("EncodedByteAlign"));
    113                     bBlack = pParam->GetInteger(FX_BSTRC("BlackIs1"));
    114                     nColumns = pParam->GetInteger(FX_BSTRC("Columns"), 1728);
    115                     nRows = pParam->GetInteger(FX_BSTRC("Rows"));
    116                 }
    117                 if (nColumns == 0) {
    118                     nColumns = width;
    119                 }
    120                 if (nRows == 0) {
    121                     nRows = height;
    122                 }
    123                 CPDF_FaxFilter* pFilter = new CPDF_FaxFilter();
    124                 pFilter->Initialize(Encoding, bEndOfLine, bByteAlign, bBlack, nRows, nColumns);
    125                 return pFilter;
    126             }
    127         case FXBSTR_ID('D', 'C', 'T', 'D'):
    128             return new CPDF_JpegFilter;
    129         default:
    130             return NULL;
    131     }
    132 }
    133 CFX_DataFilter* _FPDF_CreateFilterFromDict(CPDF_Dictionary* pDict)
    134 {
    135     CPDF_Object* pDecoder = pDict->GetElementValue("Filter");
    136     if (pDecoder == NULL) {
    137         return NULL;
    138     }
    139     CFX_DataFilter* pFirstFilter = NULL;
    140     int width = pDict->GetInteger(FX_BSTRC("Width")), height = pDict->GetInteger(FX_BSTRC("Height"));
    141     CPDF_Object* pParams = pDict->GetElementValue("DecodeParms");
    142     if (pDecoder->GetType() == PDFOBJ_ARRAY) {
    143         if (pParams && pParams->GetType() != PDFOBJ_ARRAY) {
    144             pParams = NULL;
    145         }
    146         for (FX_DWORD i = 0; i < ((CPDF_Array*)pDecoder)->GetCount(); i ++) {
    147             CFX_ByteString name = ((CPDF_Array*)pDecoder)->GetString(i);
    148             CPDF_Dictionary* pParam = NULL;
    149             if (pParams) {
    150                 pParam = ((CPDF_Array*)pParams)->GetDict(i);
    151             }
    152             CFX_DataFilter* pDestFilter = FPDF_CreateFilter(name, pParam, width, height);
    153             if (pDestFilter) {
    154                 if (pFirstFilter == NULL) {
    155                     pFirstFilter = pDestFilter;
    156                 } else {
    157                     pFirstFilter->SetDestFilter(pDestFilter);
    158                 }
    159             }
    160         }
    161     } else {
    162         if (pParams && pParams->GetType() != PDFOBJ_DICTIONARY) {
    163             pParams = NULL;
    164         }
    165         pFirstFilter = FPDF_CreateFilter(pDecoder->GetString(), (CPDF_Dictionary*)pParams, width, height);
    166     }
    167     return pFirstFilter;
    168 }
    169 CPDF_StreamFilter* CPDF_Stream::GetStreamFilter(FX_BOOL bRaw) const
    170 {
    171     CFX_DataFilter* pFirstFilter = NULL;
    172     if (m_pCryptoHandler) {
    173         pFirstFilter = new CPDF_DecryptFilter(m_pCryptoHandler, m_ObjNum, m_GenNum);
    174     }
    175     if (!bRaw) {
    176         CFX_DataFilter* pFilter = _FPDF_CreateFilterFromDict(m_pDict);
    177         if (pFilter) {
    178             if (pFirstFilter == NULL) {
    179                 pFirstFilter = pFilter;
    180             } else {
    181                 pFirstFilter->SetDestFilter(pFilter);
    182             }
    183         }
    184     }
    185     CPDF_StreamFilter* pStreamFilter = new CPDF_StreamFilter;
    186     pStreamFilter->m_pStream = this;
    187     pStreamFilter->m_pFilter = pFirstFilter;
    188     pStreamFilter->m_pBuffer = NULL;
    189     pStreamFilter->m_SrcOffset = 0;
    190     return pStreamFilter;
    191 }
    192 CPDF_StreamFilter::~CPDF_StreamFilter()
    193 {
    194     if (m_pFilter) {
    195         delete m_pFilter;
    196     }
    197     if (m_pBuffer) {
    198         delete m_pBuffer;
    199     }
    200 }
    201 #define FPDF_FILTER_BUFFER_IN_SIZE	FPDF_FILTER_BUFFER_SIZE
    202 FX_DWORD CPDF_StreamFilter::ReadBlock(FX_LPBYTE buffer, FX_DWORD buf_size)
    203 {
    204     if (m_pFilter == NULL) {
    205         FX_DWORD read_size = m_pStream->GetRawSize() - m_SrcOffset;
    206         if (read_size == 0) {
    207             return 0;
    208         }
    209         if (read_size > buf_size) {
    210             read_size = buf_size;
    211         }
    212         m_pStream->ReadRawData(m_SrcOffset, buffer, read_size);
    213         m_SrcOffset += read_size;
    214         return read_size;
    215     }
    216     FX_DWORD read_size = 0;
    217     if (m_pBuffer) {
    218         read_size = ReadLeftOver(buffer, buf_size);
    219         if (read_size == buf_size) {
    220             return read_size;
    221         }
    222         buffer += read_size;
    223         buf_size -= read_size;
    224     }
    225     ASSERT(m_pBuffer == NULL);
    226     if (m_pFilter->IsEOF()) {
    227         return read_size;
    228     }
    229     m_pBuffer = new CFX_BinaryBuf;
    230     m_pBuffer->EstimateSize(FPDF_FILTER_BUFFER_SIZE, FPDF_FILTER_BUFFER_SIZE);
    231     m_BufOffset = 0;
    232     while (1) {
    233         int src_size = m_pStream->GetRawSize() - m_SrcOffset;
    234         if (src_size == 0) {
    235             m_pFilter->FilterFinish(*m_pBuffer);
    236             break;
    237         }
    238         if (src_size > FPDF_FILTER_BUFFER_IN_SIZE) {
    239             src_size = FPDF_FILTER_BUFFER_IN_SIZE;
    240         }
    241         if (!m_pStream->ReadRawData(m_SrcOffset, m_SrcBuffer, src_size)) {
    242             return 0;
    243         }
    244         m_SrcOffset += src_size;
    245         m_pFilter->FilterIn(m_SrcBuffer, src_size, *m_pBuffer);
    246         if (m_pBuffer->GetSize() >= (int)buf_size) {
    247             break;
    248         }
    249     }
    250     return read_size + ReadLeftOver(buffer, buf_size);
    251 }
    252 FX_DWORD CPDF_StreamFilter::ReadLeftOver(FX_LPBYTE buffer, FX_DWORD buf_size)
    253 {
    254     FX_DWORD read_size = m_pBuffer->GetSize() - m_BufOffset;
    255     if (read_size > buf_size) {
    256         read_size = buf_size;
    257     }
    258     FXSYS_memcpy32(buffer, m_pBuffer->GetBuffer() + m_BufOffset, read_size);
    259     m_BufOffset += read_size;
    260     if (m_BufOffset == (FX_DWORD)m_pBuffer->GetSize()) {
    261         delete m_pBuffer;
    262         m_pBuffer = NULL;
    263     }
    264     return read_size;
    265 }
    266 CPDF_DecryptFilter::CPDF_DecryptFilter(CPDF_CryptoHandler* pCryptoHandler, FX_DWORD objnum, FX_DWORD gennum)
    267 {
    268     m_pCryptoHandler = pCryptoHandler;
    269     m_pContext = NULL;
    270     m_ObjNum = objnum;
    271     m_GenNum = gennum;
    272 }
    273 CPDF_DecryptFilter::~CPDF_DecryptFilter()
    274 {
    275     CFX_BinaryBuf buf;
    276     if (m_pContext) {
    277         m_pCryptoHandler->DecryptFinish(m_pContext, buf);
    278     }
    279 }
    280 void CPDF_DecryptFilter::v_FilterIn(FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf)
    281 {
    282     if (m_pContext == NULL) {
    283         m_pContext = m_pCryptoHandler->DecryptStart(m_ObjNum, m_GenNum);
    284     }
    285     m_pCryptoHandler->DecryptStream(m_pContext, src_buf, src_size, dest_buf);
    286 }
    287 void CPDF_DecryptFilter::v_FilterFinish(CFX_BinaryBuf& dest_buf)
    288 {
    289     m_bEOF = TRUE;
    290     if (m_pContext == NULL) {
    291         return;
    292     }
    293     m_pCryptoHandler->DecryptFinish(m_pContext, dest_buf);
    294     m_pContext = NULL;
    295 }
    296 extern "C" {
    297     static void* my_alloc_func (void* opaque, unsigned int items, unsigned int size)
    298     {
    299         return FX_Alloc2D(FX_BYTE, items, size);
    300     }
    301     static void   my_free_func  (void* opaque, void* address)
    302     {
    303         FX_Free(address);
    304     }
    305     void* FPDFAPI_FlateInit(void* (*alloc_func)(void*, unsigned int, unsigned int),
    306                             void (*free_func)(void*, void*));
    307     void FPDFAPI_FlateInput(void* context, const unsigned char* src_buf, unsigned int src_size);
    308     int FPDFAPI_FlateOutput(void* context, unsigned char* dest_buf, unsigned int dest_size);
    309     int FPDFAPI_FlateGetAvailIn(void* context);
    310     int FPDFAPI_FlateGetAvailOut(void* context);
    311     void FPDFAPI_FlateEnd(void* context);
    312 }
    313 CPDF_FlateFilter::CPDF_FlateFilter()
    314 {
    315     m_pContext = NULL;
    316 }
    317 CPDF_FlateFilter::~CPDF_FlateFilter()
    318 {
    319     if (m_pContext) {
    320         FPDFAPI_FlateEnd(m_pContext);
    321     }
    322 }
    323 void CPDF_FlateFilter::v_FilterIn(FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf)
    324 {
    325     if (m_pContext == NULL) {
    326         m_pContext = FPDFAPI_FlateInit(my_alloc_func, my_free_func);
    327     }
    328     FPDFAPI_FlateInput(m_pContext, src_buf, src_size);
    329     while (1) {
    330         int ret = FPDFAPI_FlateOutput(m_pContext, m_DestBuffer, FPDF_FILTER_BUFFER_SIZE);
    331         int out_size = FPDF_FILTER_BUFFER_SIZE - FPDFAPI_FlateGetAvailOut(m_pContext);
    332         dest_buf.AppendBlock(m_DestBuffer, out_size);
    333         if (ret == Z_BUF_ERROR) {
    334             break;
    335         }
    336         if (ret != Z_OK) {
    337             ReportEOF(FPDFAPI_FlateGetAvailIn(m_pContext));
    338             break;
    339         }
    340     }
    341 }
    342 CPDF_LzwFilter::CPDF_LzwFilter(FX_BOOL bEarlyChange)
    343 {
    344     m_bEarlyChange = bEarlyChange ? 1 : 0;
    345     m_CodeLen = 9;
    346     m_nCodes = 0;
    347     m_nLeftBits = 0;
    348     m_LeftBits = 0;
    349     m_OldCode = (FX_DWORD) - 1;
    350 }
    351 void CPDF_LzwFilter::v_FilterIn(FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf)
    352 {
    353     for (FX_DWORD i = 0; i < src_size; i ++) {
    354         if (m_nLeftBits + 8 < m_CodeLen) {
    355             m_nLeftBits += 8;
    356             m_LeftBits = (m_LeftBits << 8) | src_buf[i];
    357             continue;
    358         }
    359         FX_DWORD new_bits = m_CodeLen - m_nLeftBits;
    360         FX_DWORD code = (m_LeftBits << new_bits) | (src_buf[i] >> (8 - new_bits));
    361         m_nLeftBits = 8 - new_bits;
    362         m_LeftBits = src_buf[i] % (1 << m_nLeftBits);
    363         if (code < 256) {
    364             dest_buf.AppendByte((FX_BYTE)code);
    365             m_LastChar = (FX_BYTE)code;
    366             if (m_OldCode != -1) {
    367                 AddCode(m_OldCode, m_LastChar);
    368             }
    369             m_OldCode = code;
    370         } else if (code == 256) {
    371             m_CodeLen = 9;
    372             m_nCodes = 0;
    373             m_OldCode = (FX_DWORD) - 1;
    374         } else if (code == 257) {
    375             ReportEOF(src_size - i - 1);
    376             return;
    377         } else {
    378             if (m_OldCode == -1) {
    379                 ReportEOF(src_size - i - 1);
    380                 return;
    381             }
    382             m_StackLen = 0;
    383             if (code >= m_nCodes + 258) {
    384                 if (m_StackLen < sizeof(m_DecodeStack)) {
    385                     m_DecodeStack[m_StackLen++] = m_LastChar;
    386                 }
    387                 DecodeString(m_OldCode);
    388             } else {
    389                 DecodeString(code);
    390             }
    391             dest_buf.AppendBlock(NULL, m_StackLen);
    392             FX_LPBYTE pOutput = dest_buf.GetBuffer() + dest_buf.GetSize() - m_StackLen;
    393             for (FX_DWORD cc = 0; cc < m_StackLen; cc ++) {
    394                 pOutput[cc] = m_DecodeStack[m_StackLen - cc - 1];
    395             }
    396             m_LastChar = m_DecodeStack[m_StackLen - 1];
    397             if (m_OldCode < 256) {
    398                 AddCode(m_OldCode, m_LastChar);
    399             } else if (m_OldCode - 258 >= m_nCodes) {
    400                 ReportEOF(src_size - i - 1);
    401                 return;
    402             } else {
    403                 AddCode(m_OldCode, m_LastChar);
    404             }
    405             m_OldCode = code;
    406         }
    407     }
    408 }
    409 void CPDF_LzwFilter::AddCode(FX_DWORD prefix_code, FX_BYTE append_char)
    410 {
    411     if (m_nCodes + m_bEarlyChange == 4094) {
    412         return;
    413     }
    414     m_CodeArray[m_nCodes ++] = (prefix_code << 16) | append_char;
    415     if (m_nCodes + m_bEarlyChange == 512 - 258) {
    416         m_CodeLen = 10;
    417     } else if (m_nCodes + m_bEarlyChange == 1024 - 258) {
    418         m_CodeLen = 11;
    419     } else if (m_nCodes + m_bEarlyChange == 2048 - 258) {
    420         m_CodeLen = 12;
    421     }
    422 }
    423 void CPDF_LzwFilter::DecodeString(FX_DWORD code)
    424 {
    425     while (1) {
    426         int index = code - 258;
    427         if (index < 0 || index >= (int)m_nCodes) {
    428             break;
    429         }
    430         FX_DWORD data = m_CodeArray[index];
    431         if (m_StackLen >= sizeof(m_DecodeStack)) {
    432             return;
    433         }
    434         m_DecodeStack[m_StackLen++] = (FX_BYTE)data;
    435         code = data >> 16;
    436     }
    437     if (m_StackLen >= sizeof(m_DecodeStack)) {
    438         return;
    439     }
    440     m_DecodeStack[m_StackLen++] = (FX_BYTE)code;
    441 }
    442 CPDF_PredictorFilter::CPDF_PredictorFilter(int predictor, int colors, int bpc, int cols)
    443 {
    444     m_bTiff = predictor < 10;
    445     m_pRefLine = NULL;
    446     m_pCurLine = NULL;
    447     m_iLine = 0;
    448     m_LineInSize = 0;
    449     m_Bpp = (colors * bpc + 7) / 8;
    450     m_Pitch = (colors * bpc * cols + 7) / 8;
    451     if (!m_bTiff) {
    452         m_Pitch ++;
    453     }
    454 }
    455 CPDF_PredictorFilter::~CPDF_PredictorFilter()
    456 {
    457     if (m_pCurLine) {
    458         FX_Free(m_pCurLine);
    459     }
    460     if (m_pRefLine) {
    461         FX_Free(m_pRefLine);
    462     }
    463 }
    464 static FX_BYTE PaethPredictor(int a, int b, int c)
    465 {
    466     int p = a + b - c;
    467     int pa = FXSYS_abs(p - a);
    468     int pb = FXSYS_abs(p - b);
    469     int pc = FXSYS_abs(p - c);
    470     if (pa <= pb && pa <= pc) {
    471         return (FX_BYTE)a;
    472     }
    473     if (pb <= pc) {
    474         return (FX_BYTE)b;
    475     }
    476     return (FX_BYTE)c;
    477 }
    478 static void PNG_PredictorLine(FX_LPBYTE cur_buf, FX_LPBYTE ref_buf, int pitch, int Bpp)
    479 {
    480     FX_BYTE tag = cur_buf[0];
    481     if (tag == 0) {
    482         return;
    483     }
    484     cur_buf ++;
    485     if (ref_buf) {
    486         ref_buf ++;
    487     }
    488     for (int byte = 0; byte < pitch; byte ++) {
    489         FX_BYTE raw_byte = cur_buf[byte];
    490         switch (tag) {
    491             case 1:	{
    492                     FX_BYTE left = 0;
    493                     if (byte >= Bpp) {
    494                         left = cur_buf[byte - Bpp];
    495                     }
    496                     cur_buf[byte] = raw_byte + left;
    497                     break;
    498                 }
    499             case 2: {
    500                     FX_BYTE up = 0;
    501                     if (ref_buf) {
    502                         up = ref_buf[byte];
    503                     }
    504                     cur_buf[byte] = raw_byte + up;
    505                     break;
    506                 }
    507             case 3: {
    508                     FX_BYTE left = 0;
    509                     if (byte >= Bpp) {
    510                         left = cur_buf[byte - Bpp];
    511                     }
    512                     FX_BYTE up = 0;
    513                     if (ref_buf) {
    514                         up = ref_buf[byte];
    515                     }
    516                     cur_buf[byte] = raw_byte + (up + left) / 2;
    517                     break;
    518                 }
    519             case 4: {
    520                     FX_BYTE left = 0;
    521                     if (byte >= Bpp) {
    522                         left = cur_buf[byte - Bpp];
    523                     }
    524                     FX_BYTE up = 0;
    525                     if (ref_buf) {
    526                         up = ref_buf[byte];
    527                     }
    528                     FX_BYTE upper_left = 0;
    529                     if (byte >= Bpp && ref_buf) {
    530                         upper_left = ref_buf[byte - Bpp];
    531                     }
    532                     cur_buf[byte] = raw_byte + PaethPredictor(left, up, upper_left);
    533                     break;
    534                 }
    535         }
    536     }
    537 }
    538 void CPDF_PredictorFilter::v_FilterIn(FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf)
    539 {
    540     if (m_pCurLine == NULL) {
    541         m_pCurLine = FX_Alloc(FX_BYTE, m_Pitch);
    542         if (!m_bTiff) {
    543             m_pRefLine = FX_Alloc(FX_BYTE, m_Pitch);
    544         }
    545     }
    546     while (1) {
    547         FX_DWORD read_size = m_Pitch - m_LineInSize;
    548         if (read_size > src_size) {
    549             read_size = src_size;
    550         }
    551         FXSYS_memcpy32(m_pCurLine + m_LineInSize, src_buf, read_size);
    552         m_LineInSize += read_size;
    553         if (m_LineInSize < m_Pitch) {
    554             break;
    555         }
    556         src_buf += read_size;
    557         src_size -= read_size;
    558         if (m_bTiff) {
    559             for (FX_DWORD byte = m_Bpp; byte < m_Pitch; byte ++) {
    560                 m_pCurLine[byte] += m_pCurLine[byte - m_Bpp];
    561             }
    562             dest_buf.AppendBlock(m_pCurLine, m_Pitch);
    563         } else {
    564             PNG_PredictorLine(m_pCurLine, m_iLine ? m_pRefLine : NULL, m_Pitch - 1, m_Bpp);
    565             dest_buf.AppendBlock(m_pCurLine + 1, m_Pitch - 1);
    566             m_iLine ++;
    567             FX_LPBYTE temp = m_pCurLine;
    568             m_pCurLine = m_pRefLine;
    569             m_pRefLine = temp;
    570         }
    571         m_LineInSize = 0;
    572     }
    573 }
    574 CPDF_Ascii85Filter::CPDF_Ascii85Filter()
    575 {
    576     m_State = 0;
    577     m_CharCount = 0;
    578 }
    579 void CPDF_Ascii85Filter::v_FilterIn(FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf)
    580 {
    581     for (FX_DWORD i = 0; i < src_size; i ++) {
    582         FX_BYTE byte = src_buf[i];
    583         if (PDF_CharType[byte] == 'W') {
    584             continue;
    585         }
    586         switch (m_State) {
    587             case 0:
    588                 if (byte >= '!' && byte <= 'u') {
    589                     int digit = byte - '!';
    590                     m_CurDWord = digit;
    591                     m_CharCount = 1;
    592                     m_State = 1;
    593                 } else if (byte == 'z') {
    594                     int zero = 0;
    595                     dest_buf.AppendBlock(&zero, 4);
    596                 } else if (byte == '~') {
    597                     m_State = 2;
    598                 }
    599                 break;
    600             case 1: {
    601                     if (byte >= '!' && byte <= 'u') {
    602                         int digit = byte - '!';
    603                         m_CurDWord = m_CurDWord * 85 + digit;
    604                         m_CharCount ++;
    605                         if (m_CharCount == 5) {
    606                             for (int i = 0; i < 4; i ++) {
    607                                 dest_buf.AppendByte((FX_BYTE)(m_CurDWord >> (3 - i) * 8));
    608                             }
    609                             m_State = 0;
    610                         }
    611                     } else if (byte == '~') {
    612                         if (m_CharCount > 1) {
    613                             int i;
    614                             for (i = m_CharCount; i < 5; i ++) {
    615                                 m_CurDWord = m_CurDWord * 85 + 84;
    616                             }
    617                             for (i = 0; i < m_CharCount - 1; i ++) {
    618                                 dest_buf.AppendByte((FX_BYTE)(m_CurDWord >> (3 - i) * 8));
    619                             }
    620                         }
    621                         m_State = 2;
    622                     }
    623                     break;
    624                 }
    625             case 2:
    626                 if (byte == '>') {
    627                     ReportEOF(src_size - i - 1);
    628                     return;
    629                 }
    630                 break;
    631         }
    632     }
    633 }
    634 CPDF_AsciiHexFilter::CPDF_AsciiHexFilter()
    635 {
    636     m_State = 0;
    637 }
    638 void CPDF_AsciiHexFilter::v_FilterIn(FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf)
    639 {
    640     for (FX_DWORD i = 0; i < src_size; i ++) {
    641         FX_BYTE byte = src_buf[i];
    642         if (PDF_CharType[byte] == 'W') {
    643             continue;
    644         }
    645         int digit;
    646         if (byte >= '0' && byte <= '9') {
    647             digit = byte - '0';
    648         } else if (byte >= 'a' && byte <= 'f') {
    649             digit = byte - 'a' + 10;
    650         } else if (byte >= 'A' && byte <= 'F') {
    651             digit = byte - 'A' + 10;
    652         } else {
    653             if (m_State) {
    654                 dest_buf.AppendByte(m_FirstDigit * 16);
    655             }
    656             ReportEOF(src_size - i - 1);
    657             return;
    658         }
    659         if (m_State == 0) {
    660             m_FirstDigit = digit;
    661             m_State ++;
    662         } else {
    663             dest_buf.AppendByte(m_FirstDigit * 16 + digit);
    664             m_State --;
    665         }
    666     }
    667 }
    668 CPDF_RunLenFilter::CPDF_RunLenFilter()
    669 {
    670     m_State = 0;
    671     m_Count = 0;
    672 }
    673 void CPDF_RunLenFilter::v_FilterIn(FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf)
    674 {
    675     for (FX_DWORD i = 0; i < src_size; i ++) {
    676         FX_BYTE byte = src_buf[i];
    677         switch (m_State) {
    678             case 0:
    679                 if (byte < 128) {
    680                     m_State = 1;
    681                     m_Count = byte + 1;
    682                 } else if (byte == 128) {
    683                     ReportEOF(src_size - i - 1);
    684                     return;
    685                 } else {
    686                     m_State = 2;
    687                     m_Count = 257 - byte;
    688                 }
    689                 break;
    690             case 1:
    691                 dest_buf.AppendByte(byte);
    692                 m_Count --;
    693                 if (m_Count == 0) {
    694                     m_State = 0;
    695                 }
    696                 break;
    697             case 2:	{
    698                     dest_buf.AppendBlock(NULL, m_Count);
    699                     FXSYS_memset8(dest_buf.GetBuffer() + dest_buf.GetSize() - m_Count, byte, m_Count);
    700                     m_State = 0;
    701                     break;
    702                 }
    703         }
    704     }
    705 }
    706 CPDF_JpegFilter::CPDF_JpegFilter()
    707 {
    708     m_pContext = NULL;
    709     m_bGotHeader = FALSE;
    710     m_pScanline = NULL;
    711     m_iLine = 0;
    712 }
    713 CPDF_JpegFilter::~CPDF_JpegFilter()
    714 {
    715     if (m_pScanline) {
    716         FX_Free(m_pScanline);
    717     }
    718     if (m_pContext) {
    719         CPDF_ModuleMgr::Get()->GetJpegModule()->Finish(m_pContext);
    720     }
    721 }
    722 void CPDF_JpegFilter::v_FilterIn(FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf)
    723 {
    724     if (m_pContext == NULL) {
    725         m_pContext = CPDF_ModuleMgr::Get()->GetJpegModule()->Start();
    726     }
    727     FX_LPCBYTE jpeg_src_buf;
    728     FX_DWORD jpeg_src_size;
    729     CFX_BinaryBuf temp_buf;
    730     if (m_InputBuf.GetSize()) {
    731         temp_buf.EstimateSize(m_InputBuf.GetSize() + src_size);
    732         temp_buf.AppendBlock(m_InputBuf.GetBuffer(), m_InputBuf.GetSize());
    733         m_InputBuf.Clear();
    734         temp_buf.AppendBlock(src_buf, src_size);
    735         jpeg_src_buf = temp_buf.GetBuffer();
    736         jpeg_src_size = temp_buf.GetSize();
    737     } else {
    738         jpeg_src_buf = src_buf;
    739         jpeg_src_size = src_size;
    740     }
    741     CPDF_ModuleMgr::Get()->GetJpegModule()->Input(m_pContext, jpeg_src_buf, jpeg_src_size);
    742     if (!m_bGotHeader) {
    743         int ret = CPDF_ModuleMgr::Get()->GetJpegModule()->ReadHeader(m_pContext, &m_Width, &m_Height, &m_nComps);
    744         int left_size = CPDF_ModuleMgr::Get()->GetJpegModule()->GetAvailInput(m_pContext);
    745         if (ret == 1) {
    746             ReportEOF(left_size);
    747             return;
    748         }
    749         if (ret == 2) {
    750             m_InputBuf.AppendBlock(jpeg_src_buf + jpeg_src_size - left_size, left_size);
    751             return;
    752         }
    753         CPDF_ModuleMgr::Get()->GetJpegModule()->StartScanline(m_pContext, 1);
    754         m_bGotHeader = TRUE;
    755         m_Pitch = m_Width * m_nComps;
    756     }
    757     if (m_pScanline == NULL) {
    758         m_pScanline = FX_Alloc(FX_BYTE, m_Pitch + 4);
    759     }
    760     while (1) {
    761         if (!CPDF_ModuleMgr::Get()->GetJpegModule()->ReadScanline(m_pContext, m_pScanline)) {
    762             int left_size = CPDF_ModuleMgr::Get()->GetJpegModule()->GetAvailInput(m_pContext);
    763             m_InputBuf.AppendBlock(jpeg_src_buf + jpeg_src_size - left_size, left_size);
    764             break;
    765         }
    766         dest_buf.AppendBlock(m_pScanline, m_Pitch);
    767         m_iLine ++;
    768         if (m_iLine == m_Height) {
    769             ReportEOF(CPDF_ModuleMgr::Get()->GetJpegModule()->GetAvailInput(m_pContext));
    770             return;
    771         }
    772     }
    773 }
    774 CPDF_FaxFilter::CPDF_FaxFilter()
    775 {
    776     m_Encoding = 0;
    777     m_bEndOfLine = FALSE;
    778     m_bByteAlign = FALSE;
    779     m_bBlack = FALSE;
    780     m_nRows = 0;
    781     m_nColumns = 0;
    782     m_Pitch = 0;
    783     m_pScanlineBuf = NULL;
    784     m_pRefBuf = NULL;
    785     m_iRow = 0;
    786     m_InputBitPos = 0;
    787 }
    788 CPDF_FaxFilter::~CPDF_FaxFilter()
    789 {
    790     if (m_pScanlineBuf) {
    791         FX_Free(m_pScanlineBuf);
    792     }
    793     if (m_pRefBuf) {
    794         FX_Free(m_pRefBuf);
    795     }
    796 }
    797 FX_BOOL CPDF_FaxFilter::Initialize(int Encoding, int bEndOfLine, int bByteAlign, int bBlack, int nRows, int nColumns)
    798 {
    799     m_Encoding = Encoding;
    800     m_bEndOfLine = bEndOfLine;
    801     m_bByteAlign = bByteAlign;
    802     m_bBlack = bBlack;
    803     m_nRows = nRows;
    804     m_nColumns = nColumns;
    805     m_Pitch = (m_nColumns + 7) / 8;
    806     m_pScanlineBuf = FX_Alloc(FX_BYTE, m_Pitch);
    807     m_pRefBuf = FX_Alloc(FX_BYTE, m_Pitch);
    808     FXSYS_memset8(m_pScanlineBuf, 0xff, m_Pitch);
    809     FXSYS_memset8(m_pRefBuf, 0xff, m_Pitch);
    810     m_iRow = 0;
    811     m_InputBitPos = 0;
    812     return TRUE;
    813 }
    814 void CPDF_FaxFilter::v_FilterIn(FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf)
    815 {
    816     FX_LPCBYTE fax_src_buf;
    817     FX_DWORD fax_src_size;
    818     CFX_BinaryBuf temp_buf;
    819     int bitpos;
    820     if (m_InputBuf.GetSize()) {
    821         temp_buf.EstimateSize(m_InputBuf.GetSize() + src_size);
    822         temp_buf.AppendBlock(m_InputBuf.GetBuffer(), m_InputBuf.GetSize());
    823         m_InputBuf.Clear();
    824         temp_buf.AppendBlock(src_buf, src_size);
    825         fax_src_buf = temp_buf.GetBuffer();
    826         fax_src_size = temp_buf.GetSize();
    827         bitpos = m_InputBitPos;
    828     } else {
    829         fax_src_buf = src_buf;
    830         fax_src_size = src_size;
    831         bitpos = 0;
    832     }
    833     ProcessData(fax_src_buf, fax_src_size, bitpos, FALSE, dest_buf);
    834     int left_bits = fax_src_size * 8 - bitpos;
    835     m_InputBuf.AppendBlock(fax_src_buf + bitpos / 8, (left_bits + 7) / 8);
    836     m_InputBitPos = bitpos % 8;
    837 }
    838 void CPDF_FaxFilter::v_FilterFinish(CFX_BinaryBuf& dest_buf)
    839 {
    840     ProcessData(m_InputBuf.GetBuffer(), m_InputBuf.GetSize(), m_InputBitPos, TRUE, dest_buf);
    841 }
    842 FX_BOOL _FaxSkipEOL(const FX_BYTE* src_buf, int bitsize, int& bitpos);
    843 FX_BOOL _FaxG4GetRow(const FX_BYTE* src_buf, int bitsize, int& bitpos, FX_LPBYTE dest_buf, const FX_BYTE* ref_buf, int columns);
    844 FX_BOOL _FaxGet1DLine(const FX_BYTE* src_buf, int bitsize, int& bitpos, FX_LPBYTE dest_buf, int columns);
    845 void CPDF_FaxFilter::ProcessData(FX_LPCBYTE src_buf, FX_DWORD src_size, int& bitpos, FX_BOOL bFinish,
    846                                  CFX_BinaryBuf& dest_buf)
    847 {
    848     int bitsize = src_size * 8;
    849     while (1) {
    850         if ((bitsize < bitpos + 256) && !bFinish) {
    851             return;
    852         }
    853         int start_bitpos = bitpos;
    854         FXSYS_memset8(m_pScanlineBuf, 0xff, m_Pitch);
    855         if (!ReadLine(src_buf, bitsize, bitpos)) {
    856             bitpos = start_bitpos;
    857             return;
    858         }
    859         if (m_Encoding) {
    860             FXSYS_memcpy32(m_pRefBuf, m_pScanlineBuf, m_Pitch);
    861         }
    862         if (m_bBlack) {
    863             for (int i = 0; i < m_Pitch; i ++) {
    864                 m_pScanlineBuf[i] = ~m_pScanlineBuf[i];
    865             }
    866         }
    867         dest_buf.AppendBlock(m_pScanlineBuf, m_Pitch);
    868         m_iRow ++;
    869         if (m_iRow == m_nRows) {
    870             ReportEOF(src_size - (bitpos + 7) / 8);
    871             return;
    872         }
    873     }
    874 }
    875 FX_BOOL CPDF_FaxFilter::ReadLine(FX_LPCBYTE src_buf, int bitsize, int& bitpos)
    876 {
    877     if (!_FaxSkipEOL(src_buf, bitsize, bitpos)) {
    878         return FALSE;
    879     }
    880     FX_BOOL ret;
    881     if (m_Encoding < 0) {
    882         ret = _FaxG4GetRow(src_buf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, m_nColumns);
    883     } else if (m_Encoding == 0) {
    884         ret = _FaxGet1DLine(src_buf, bitsize, bitpos, m_pScanlineBuf, m_nColumns);
    885     } else {
    886         if (bitpos == bitsize) {
    887             return FALSE;
    888         }
    889         FX_BOOL bNext1D = src_buf[bitpos / 8] & (1 << (7 - bitpos % 8));
    890         bitpos ++;
    891         if (bNext1D) {
    892             ret = _FaxGet1DLine(src_buf, bitsize, bitpos, m_pScanlineBuf, m_nColumns);
    893         } else {
    894             ret = _FaxG4GetRow(src_buf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, m_nColumns);
    895         }
    896     }
    897     if (!ret) {
    898         return FALSE;
    899     }
    900     if (m_bEndOfLine)
    901         if (!_FaxSkipEOL(src_buf, bitsize, bitpos)) {
    902             return FALSE;
    903         }
    904     if (m_bByteAlign) {
    905         bitpos = (bitpos + 7) / 8 * 8;
    906     }
    907     return TRUE;
    908 }
    909