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