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 = FX_NEW CPDF_LzwFilter(pParam->GetInteger("EarlyChange", 1));
     80                 } else {
     81                     pFilter = FX_NEW CPDF_FlateFilter;
     82                 }
     83                 if (pParam->GetInteger("Predictor", 1) > 1) {
     84                     CFX_DataFilter* pPredictor = FX_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 FX_NEW CPDF_AsciiHexFilter;
     94             }
     95             return FX_NEW CPDF_Ascii85Filter;
     96         case FXBSTR_ID('A', 'H', 'x', 0):
     97             return FX_NEW CPDF_AsciiHexFilter;
     98         case FXBSTR_ID('A', '8', '5', 0):
     99             return FX_NEW CPDF_Ascii85Filter;
    100         case FXBSTR_ID('R', 'u', 'n', 'L'):
    101             return FX_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 = FX_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 FX_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 = FX_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 = FX_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 = FX_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_Alloc(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 extern const FX_LPCSTR _PDF_CharType;
    580 void CPDF_Ascii85Filter::v_FilterIn(FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf)
    581 {
    582     for (FX_DWORD i = 0; i < src_size; i ++) {
    583         FX_BYTE byte = src_buf[i];
    584         if (_PDF_CharType[byte] == 'W') {
    585             continue;
    586         }
    587         switch (m_State) {
    588             case 0:
    589                 if (byte >= '!' && byte <= 'u') {
    590                     int digit = byte - '!';
    591                     m_CurDWord = digit;
    592                     m_CharCount = 1;
    593                     m_State = 1;
    594                 } else if (byte == 'z') {
    595                     int zero = 0;
    596                     dest_buf.AppendBlock(&zero, 4);
    597                 } else if (byte == '~') {
    598                     m_State = 2;
    599                 }
    600                 break;
    601             case 1: {
    602                     if (byte >= '!' && byte <= 'u') {
    603                         int digit = byte - '!';
    604                         m_CurDWord = m_CurDWord * 85 + digit;
    605                         m_CharCount ++;
    606                         if (m_CharCount == 5) {
    607                             for (int i = 0; i < 4; i ++) {
    608                                 dest_buf.AppendByte((FX_BYTE)(m_CurDWord >> (3 - i) * 8));
    609                             }
    610                             m_State = 0;
    611                         }
    612                     } else if (byte == '~') {
    613                         if (m_CharCount > 1) {
    614                             int i;
    615                             for (i = m_CharCount; i < 5; i ++) {
    616                                 m_CurDWord = m_CurDWord * 85 + 84;
    617                             }
    618                             for (i = 0; i < m_CharCount - 1; i ++) {
    619                                 dest_buf.AppendByte((FX_BYTE)(m_CurDWord >> (3 - i) * 8));
    620                             }
    621                         }
    622                         m_State = 2;
    623                     }
    624                     break;
    625                 }
    626             case 2:
    627                 if (byte == '>') {
    628                     ReportEOF(src_size - i - 1);
    629                     return;
    630                 }
    631                 break;
    632         }
    633     }
    634 }
    635 CPDF_AsciiHexFilter::CPDF_AsciiHexFilter()
    636 {
    637     m_State = 0;
    638 }
    639 void CPDF_AsciiHexFilter::v_FilterIn(FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf)
    640 {
    641     for (FX_DWORD i = 0; i < src_size; i ++) {
    642         FX_BYTE byte = src_buf[i];
    643         if (_PDF_CharType[byte] == 'W') {
    644             continue;
    645         }
    646         int digit;
    647         if (byte >= '0' && byte <= '9') {
    648             digit = byte - '0';
    649         } else if (byte >= 'a' && byte <= 'f') {
    650             digit = byte - 'a' + 10;
    651         } else if (byte >= 'A' && byte <= 'F') {
    652             digit = byte - 'A' + 10;
    653         } else {
    654             if (m_State) {
    655                 dest_buf.AppendByte(m_FirstDigit * 16);
    656             }
    657             ReportEOF(src_size - i - 1);
    658             return;
    659         }
    660         if (m_State == 0) {
    661             m_FirstDigit = digit;
    662             m_State ++;
    663         } else {
    664             dest_buf.AppendByte(m_FirstDigit * 16 + digit);
    665             m_State --;
    666         }
    667     }
    668 }
    669 CPDF_RunLenFilter::CPDF_RunLenFilter()
    670 {
    671     m_State = 0;
    672     m_Count = 0;
    673 }
    674 void CPDF_RunLenFilter::v_FilterIn(FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf)
    675 {
    676     for (FX_DWORD i = 0; i < src_size; i ++) {
    677         FX_BYTE byte = src_buf[i];
    678         switch (m_State) {
    679             case 0:
    680                 if (byte < 128) {
    681                     m_State = 1;
    682                     m_Count = byte + 1;
    683                 } else if (byte == 128) {
    684                     ReportEOF(src_size - i - 1);
    685                     return;
    686                 } else {
    687                     m_State = 2;
    688                     m_Count = 257 - byte;
    689                 }
    690                 break;
    691             case 1:
    692                 dest_buf.AppendByte(byte);
    693                 m_Count --;
    694                 if (m_Count == 0) {
    695                     m_State = 0;
    696                 }
    697                 break;
    698             case 2:	{
    699                     dest_buf.AppendBlock(NULL, m_Count);
    700                     FXSYS_memset8(dest_buf.GetBuffer() + dest_buf.GetSize() - m_Count, byte, m_Count);
    701                     m_State = 0;
    702                     break;
    703                 }
    704         }
    705     }
    706 }
    707 CPDF_JpegFilter::CPDF_JpegFilter()
    708 {
    709     m_pContext = NULL;
    710     m_bGotHeader = FALSE;
    711     m_pScanline = NULL;
    712     m_iLine = 0;
    713 }
    714 CPDF_JpegFilter::~CPDF_JpegFilter()
    715 {
    716     if (m_pScanline) {
    717         FX_Free(m_pScanline);
    718     }
    719     if (m_pContext) {
    720         CPDF_ModuleMgr::Get()->GetJpegModule()->Finish(m_pContext);
    721     }
    722 }
    723 void CPDF_JpegFilter::v_FilterIn(FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf)
    724 {
    725     if (m_pContext == NULL) {
    726         m_pContext = CPDF_ModuleMgr::Get()->GetJpegModule()->Start();
    727     }
    728     FX_LPCBYTE jpeg_src_buf;
    729     FX_DWORD jpeg_src_size;
    730     CFX_BinaryBuf temp_buf;
    731     if (m_InputBuf.GetSize()) {
    732         temp_buf.EstimateSize(m_InputBuf.GetSize() + src_size);
    733         temp_buf.AppendBlock(m_InputBuf.GetBuffer(), m_InputBuf.GetSize());
    734         m_InputBuf.Clear();
    735         temp_buf.AppendBlock(src_buf, src_size);
    736         jpeg_src_buf = temp_buf.GetBuffer();
    737         jpeg_src_size = temp_buf.GetSize();
    738     } else {
    739         jpeg_src_buf = src_buf;
    740         jpeg_src_size = src_size;
    741     }
    742     CPDF_ModuleMgr::Get()->GetJpegModule()->Input(m_pContext, jpeg_src_buf, jpeg_src_size);
    743     if (!m_bGotHeader) {
    744         int ret = CPDF_ModuleMgr::Get()->GetJpegModule()->ReadHeader(m_pContext, &m_Width, &m_Height, &m_nComps);
    745         int left_size = CPDF_ModuleMgr::Get()->GetJpegModule()->GetAvailInput(m_pContext);
    746         if (ret == 1) {
    747             ReportEOF(left_size);
    748             return;
    749         }
    750         if (ret == 2) {
    751             m_InputBuf.AppendBlock(jpeg_src_buf + jpeg_src_size - left_size, left_size);
    752             return;
    753         }
    754         CPDF_ModuleMgr::Get()->GetJpegModule()->StartScanline(m_pContext, 1);
    755         m_bGotHeader = TRUE;
    756         m_Pitch = m_Width * m_nComps;
    757     }
    758     if (m_pScanline == NULL) {
    759         m_pScanline = FX_Alloc(FX_BYTE, m_Pitch + 4);
    760     }
    761     while (1) {
    762         if (!CPDF_ModuleMgr::Get()->GetJpegModule()->ReadScanline(m_pContext, m_pScanline)) {
    763             int left_size = CPDF_ModuleMgr::Get()->GetJpegModule()->GetAvailInput(m_pContext);
    764             m_InputBuf.AppendBlock(jpeg_src_buf + jpeg_src_size - left_size, left_size);
    765             break;
    766         }
    767         dest_buf.AppendBlock(m_pScanline, m_Pitch);
    768         m_iLine ++;
    769         if (m_iLine == m_Height) {
    770             ReportEOF(CPDF_ModuleMgr::Get()->GetJpegModule()->GetAvailInput(m_pContext));
    771             return;
    772         }
    773     }
    774 }
    775 CPDF_FaxFilter::CPDF_FaxFilter()
    776 {
    777     m_Encoding = 0;
    778     m_bEndOfLine = FALSE;
    779     m_bByteAlign = FALSE;
    780     m_bBlack = FALSE;
    781     m_nRows = 0;
    782     m_nColumns = 0;
    783     m_Pitch = 0;
    784     m_pScanlineBuf = NULL;
    785     m_pRefBuf = NULL;
    786     m_iRow = 0;
    787     m_InputBitPos = 0;
    788 }
    789 CPDF_FaxFilter::~CPDF_FaxFilter()
    790 {
    791     if (m_pScanlineBuf) {
    792         FX_Free(m_pScanlineBuf);
    793     }
    794     if (m_pRefBuf) {
    795         FX_Free(m_pRefBuf);
    796     }
    797 }
    798 FX_BOOL CPDF_FaxFilter::Initialize(int Encoding, int bEndOfLine, int bByteAlign, int bBlack, int nRows, int nColumns)
    799 {
    800     m_Encoding = Encoding;
    801     m_bEndOfLine = bEndOfLine;
    802     m_bByteAlign = bByteAlign;
    803     m_bBlack = bBlack;
    804     m_nRows = nRows;
    805     m_nColumns = nColumns;
    806     m_Pitch = (m_nColumns + 7) / 8;
    807     m_pScanlineBuf = FX_Alloc(FX_BYTE, m_Pitch);
    808     m_pRefBuf = FX_Alloc(FX_BYTE, m_Pitch);
    809     FXSYS_memset8(m_pScanlineBuf, 0xff, m_Pitch);
    810     FXSYS_memset8(m_pRefBuf, 0xff, m_Pitch);
    811     m_iRow = 0;
    812     m_InputBitPos = 0;
    813     return TRUE;
    814 }
    815 void CPDF_FaxFilter::v_FilterIn(FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf)
    816 {
    817     FX_LPCBYTE fax_src_buf;
    818     FX_DWORD fax_src_size;
    819     CFX_BinaryBuf temp_buf;
    820     int bitpos;
    821     if (m_InputBuf.GetSize()) {
    822         temp_buf.EstimateSize(m_InputBuf.GetSize() + src_size);
    823         temp_buf.AppendBlock(m_InputBuf.GetBuffer(), m_InputBuf.GetSize());
    824         m_InputBuf.Clear();
    825         temp_buf.AppendBlock(src_buf, src_size);
    826         fax_src_buf = temp_buf.GetBuffer();
    827         fax_src_size = temp_buf.GetSize();
    828         bitpos = m_InputBitPos;
    829     } else {
    830         fax_src_buf = src_buf;
    831         fax_src_size = src_size;
    832         bitpos = 0;
    833     }
    834     ProcessData(fax_src_buf, fax_src_size, bitpos, FALSE, dest_buf);
    835     int left_bits = fax_src_size * 8 - bitpos;
    836     m_InputBuf.AppendBlock(fax_src_buf + bitpos / 8, (left_bits + 7) / 8);
    837     m_InputBitPos = bitpos % 8;
    838 }
    839 void CPDF_FaxFilter::v_FilterFinish(CFX_BinaryBuf& dest_buf)
    840 {
    841     ProcessData(m_InputBuf.GetBuffer(), m_InputBuf.GetSize(), m_InputBitPos, TRUE, dest_buf);
    842 }
    843 FX_BOOL _FaxSkipEOL(const FX_BYTE* src_buf, int bitsize, int& bitpos);
    844 FX_BOOL _FaxG4GetRow(const FX_BYTE* src_buf, int bitsize, int& bitpos, FX_LPBYTE dest_buf, const FX_BYTE* ref_buf, int columns);
    845 FX_BOOL _FaxGet1DLine(const FX_BYTE* src_buf, int bitsize, int& bitpos, FX_LPBYTE dest_buf, int columns);
    846 void CPDF_FaxFilter::ProcessData(FX_LPCBYTE src_buf, FX_DWORD src_size, int& bitpos, FX_BOOL bFinish,
    847                                  CFX_BinaryBuf& dest_buf)
    848 {
    849     int bitsize = src_size * 8;
    850     while (1) {
    851         if ((bitsize < bitpos + 256) && !bFinish) {
    852             return;
    853         }
    854         int start_bitpos = bitpos;
    855         FXSYS_memset8(m_pScanlineBuf, 0xff, m_Pitch);
    856         if (!ReadLine(src_buf, bitsize, bitpos)) {
    857             bitpos = start_bitpos;
    858             return;
    859         }
    860         if (m_Encoding) {
    861             FXSYS_memcpy32(m_pRefBuf, m_pScanlineBuf, m_Pitch);
    862         }
    863         if (m_bBlack) {
    864             for (int i = 0; i < m_Pitch; i ++) {
    865                 m_pScanlineBuf[i] = ~m_pScanlineBuf[i];
    866             }
    867         }
    868         dest_buf.AppendBlock(m_pScanlineBuf, m_Pitch);
    869         m_iRow ++;
    870         if (m_iRow == m_nRows) {
    871             ReportEOF(src_size - (bitpos + 7) / 8);
    872             return;
    873         }
    874     }
    875 }
    876 FX_BOOL CPDF_FaxFilter::ReadLine(FX_LPCBYTE src_buf, int bitsize, int& bitpos)
    877 {
    878     if (!_FaxSkipEOL(src_buf, bitsize, bitpos)) {
    879         return FALSE;
    880     }
    881     FX_BOOL ret;
    882     if (m_Encoding < 0) {
    883         ret = _FaxG4GetRow(src_buf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, m_nColumns);
    884     } else if (m_Encoding == 0) {
    885         ret = _FaxGet1DLine(src_buf, bitsize, bitpos, m_pScanlineBuf, m_nColumns);
    886     } else {
    887         if (bitpos == bitsize) {
    888             return FALSE;
    889         }
    890         FX_BOOL bNext1D = src_buf[bitpos / 8] & (1 << (7 - bitpos % 8));
    891         bitpos ++;
    892         if (bNext1D) {
    893             ret = _FaxGet1DLine(src_buf, bitsize, bitpos, m_pScanlineBuf, m_nColumns);
    894         } else {
    895             ret = _FaxG4GetRow(src_buf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, m_nColumns);
    896         }
    897     }
    898     if (!ret) {
    899         return FALSE;
    900     }
    901     if (m_bEndOfLine)
    902         if (!_FaxSkipEOL(src_buf, bitsize, bitpos)) {
    903             return FALSE;
    904         }
    905     if (m_bByteAlign) {
    906         bitpos = (bitpos + 7) / 8 * 8;
    907     }
    908     return TRUE;
    909 }
    910