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