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"
CFX_DataFilter()12 CFX_DataFilter::CFX_DataFilter()
13 {
14 m_bEOF = FALSE;
15 m_pDestFilter = NULL;
16 m_SrcPos = 0;
17 }
~CFX_DataFilter()18 CFX_DataFilter::~CFX_DataFilter()
19 {
20 if (m_pDestFilter) {
21 delete m_pDestFilter;
22 }
23 }
SetDestFilter(CFX_DataFilter * pFilter)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 }
FilterIn(FX_LPCBYTE src_buf,FX_DWORD src_size,CFX_BinaryBuf & dest_buf)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 }
FilterFinish(CFX_BinaryBuf & dest_buf)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 }
ReportEOF(FX_DWORD left_input)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 }
FPDF_CreateFilter(FX_BSTR name,const CPDF_Dictionary * pParam,int width,int height)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 }
_FPDF_CreateFilterFromDict(CPDF_Dictionary * pDict)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 }
GetStreamFilter(FX_BOOL bRaw) const169 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 }
~CPDF_StreamFilter()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
ReadBlock(FX_LPBYTE buffer,FX_DWORD buf_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 }
ReadLeftOver(FX_LPBYTE buffer,FX_DWORD buf_size)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 }
CPDF_DecryptFilter(CPDF_CryptoHandler * pCryptoHandler,FX_DWORD objnum,FX_DWORD gennum)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 }
~CPDF_DecryptFilter()273 CPDF_DecryptFilter::~CPDF_DecryptFilter()
274 {
275 CFX_BinaryBuf buf;
276 if (m_pContext) {
277 m_pCryptoHandler->DecryptFinish(m_pContext, buf);
278 }
279 }
v_FilterIn(FX_LPCBYTE src_buf,FX_DWORD src_size,CFX_BinaryBuf & dest_buf)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 }
v_FilterFinish(CFX_BinaryBuf & dest_buf)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" {
my_alloc_func(void * opaque,unsigned int items,unsigned int size)297 static void* my_alloc_func (void* opaque, unsigned int items, unsigned int size)
298 {
299 return FX_Alloc(FX_BYTE, items * size);
300 }
my_free_func(void * opaque,void * address)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 }
CPDF_FlateFilter()313 CPDF_FlateFilter::CPDF_FlateFilter()
314 {
315 m_pContext = NULL;
316 }
~CPDF_FlateFilter()317 CPDF_FlateFilter::~CPDF_FlateFilter()
318 {
319 if (m_pContext) {
320 FPDFAPI_FlateEnd(m_pContext);
321 }
322 }
v_FilterIn(FX_LPCBYTE src_buf,FX_DWORD src_size,CFX_BinaryBuf & dest_buf)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 }
CPDF_LzwFilter(FX_BOOL bEarlyChange)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 }
v_FilterIn(FX_LPCBYTE src_buf,FX_DWORD src_size,CFX_BinaryBuf & dest_buf)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 }
AddCode(FX_DWORD prefix_code,FX_BYTE append_char)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 }
DecodeString(FX_DWORD code)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 }
CPDF_PredictorFilter(int predictor,int colors,int bpc,int cols)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 }
~CPDF_PredictorFilter()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 }
PaethPredictor(int a,int b,int c)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 }
PNG_PredictorLine(FX_LPBYTE cur_buf,FX_LPBYTE ref_buf,int pitch,int Bpp)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 }
v_FilterIn(FX_LPCBYTE src_buf,FX_DWORD src_size,CFX_BinaryBuf & dest_buf)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 }
CPDF_Ascii85Filter()574 CPDF_Ascii85Filter::CPDF_Ascii85Filter()
575 {
576 m_State = 0;
577 m_CharCount = 0;
578 }
579 extern const FX_LPCSTR _PDF_CharType;
v_FilterIn(FX_LPCBYTE src_buf,FX_DWORD src_size,CFX_BinaryBuf & dest_buf)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 }
CPDF_AsciiHexFilter()635 CPDF_AsciiHexFilter::CPDF_AsciiHexFilter()
636 {
637 m_State = 0;
638 }
v_FilterIn(FX_LPCBYTE src_buf,FX_DWORD src_size,CFX_BinaryBuf & dest_buf)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 }
CPDF_RunLenFilter()669 CPDF_RunLenFilter::CPDF_RunLenFilter()
670 {
671 m_State = 0;
672 m_Count = 0;
673 }
v_FilterIn(FX_LPCBYTE src_buf,FX_DWORD src_size,CFX_BinaryBuf & dest_buf)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 }
CPDF_JpegFilter()707 CPDF_JpegFilter::CPDF_JpegFilter()
708 {
709 m_pContext = NULL;
710 m_bGotHeader = FALSE;
711 m_pScanline = NULL;
712 m_iLine = 0;
713 }
~CPDF_JpegFilter()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 }
v_FilterIn(FX_LPCBYTE src_buf,FX_DWORD src_size,CFX_BinaryBuf & dest_buf)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 }
CPDF_FaxFilter()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 }
~CPDF_FaxFilter()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 }
Initialize(int Encoding,int bEndOfLine,int bByteAlign,int bBlack,int nRows,int nColumns)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 }
v_FilterIn(FX_LPCBYTE src_buf,FX_DWORD src_size,CFX_BinaryBuf & dest_buf)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 }
v_FilterFinish(CFX_BinaryBuf & dest_buf)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);
ProcessData(FX_LPCBYTE src_buf,FX_DWORD src_size,int & bitpos,FX_BOOL bFinish,CFX_BinaryBuf & dest_buf)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 }
ReadLine(FX_LPCBYTE src_buf,int bitsize,int & bitpos)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