fx_codec_flate.cpp revision ee451cb395940862dad63c85adfe8f2fd55e864c
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/fxcodec/fx_codec.h" 9#include "codec_int.h" 10extern "C" 11{ 12 static void* my_alloc_func (void* opaque, unsigned int items, unsigned int size) 13 { 14 return FX_Alloc(FX_BYTE, items * size); 15 } 16 static void my_free_func (void* opaque, void* address) 17 { 18 FX_Free(address); 19 } 20 void* FPDFAPI_FlateInit(void* (*alloc_func)(void*, unsigned int, unsigned int), 21 void (*free_func)(void*, void*)) 22 { 23 z_stream* p = (z_stream*)alloc_func(0, 1, sizeof(z_stream)); 24 if (p == NULL) { 25 return NULL; 26 } 27 FXSYS_memset32(p, 0, sizeof(z_stream)); 28 p->zalloc = alloc_func; 29 p->zfree = free_func; 30 inflateInit(p); 31 return p; 32 } 33 void FPDFAPI_FlateInput(void* context, const unsigned char* src_buf, unsigned int src_size) 34 { 35 ((z_stream*)context)->next_in = (unsigned char*)src_buf; 36 ((z_stream*)context)->avail_in = src_size; 37 } 38 int FPDFAPI_FlateGetTotalOut(void* context) 39 { 40 return ((z_stream*)context)->total_out; 41 } 42 int FPDFAPI_FlateOutput(void* context, unsigned char* dest_buf, unsigned int dest_size) 43 { 44 ((z_stream*)context)->next_out = dest_buf; 45 ((z_stream*)context)->avail_out = dest_size; 46 unsigned int pre_pos = (unsigned int)FPDFAPI_FlateGetTotalOut(context); 47 int ret = inflate((z_stream*)context, Z_SYNC_FLUSH); 48 unsigned int post_pos = (unsigned int)FPDFAPI_FlateGetTotalOut(context); 49 unsigned int written = post_pos - pre_pos; 50 if (written < dest_size) { 51 FXSYS_memset8(dest_buf + written, '\0', dest_size - written); 52 } 53 return ret; 54 } 55 int FPDFAPI_FlateGetTotalIn(void* context) 56 { 57 return ((z_stream*)context)->total_in; 58 } 59 int FPDFAPI_FlateGetAvailOut(void* context) 60 { 61 return ((z_stream*)context)->avail_out; 62 } 63 int FPDFAPI_FlateGetAvailIn(void* context) 64 { 65 return ((z_stream*)context)->avail_in; 66 } 67 void FPDFAPI_FlateEnd(void* context) 68 { 69 inflateEnd((z_stream*)context); 70 ((z_stream*)context)->zfree(0, context); 71 } 72 void FPDFAPI_FlateCompress(unsigned char* dest_buf, unsigned long* dest_size, const unsigned char* src_buf, unsigned long src_size) 73 { 74 compress(dest_buf, dest_size, src_buf, src_size); 75 } 76} 77class CLZWDecoder : public CFX_Object 78{ 79public: 80 FX_BOOL Decode(FX_LPBYTE output, FX_DWORD& outlen, const FX_BYTE* input, FX_DWORD& size, FX_BOOL bEarlyChange); 81private: 82 FX_DWORD m_InPos; 83 FX_DWORD m_OutPos; 84 FX_LPBYTE m_pOutput; 85 const FX_BYTE* m_pInput; 86 FX_BOOL m_Early; 87 void AddCode(FX_DWORD prefix_code, FX_BYTE append_char); 88 FX_DWORD m_CodeArray[5021]; 89 FX_DWORD m_nCodes; 90 FX_BYTE m_DecodeStack[4000]; 91 FX_DWORD m_StackLen; 92 void DecodeString(FX_DWORD code); 93 int m_CodeLen; 94}; 95void CLZWDecoder::AddCode(FX_DWORD prefix_code, FX_BYTE append_char) 96{ 97 if (m_nCodes + m_Early == 4094) { 98 return; 99 } 100 m_CodeArray[m_nCodes ++] = (prefix_code << 16) | append_char; 101 if (m_nCodes + m_Early == 512 - 258) { 102 m_CodeLen = 10; 103 } else if (m_nCodes + m_Early == 1024 - 258) { 104 m_CodeLen = 11; 105 } else if (m_nCodes + m_Early == 2048 - 258) { 106 m_CodeLen = 12; 107 } 108} 109void CLZWDecoder::DecodeString(FX_DWORD code) 110{ 111 while (1) { 112 int index = code - 258; 113 if (index < 0 || index >= (int)m_nCodes) { 114 break; 115 } 116 FX_DWORD data = m_CodeArray[index]; 117 if (m_StackLen >= sizeof(m_DecodeStack)) { 118 return; 119 } 120 m_DecodeStack[m_StackLen++] = (FX_BYTE)data; 121 code = data >> 16; 122 } 123 if (m_StackLen >= sizeof(m_DecodeStack)) { 124 return; 125 } 126 m_DecodeStack[m_StackLen++] = (FX_BYTE)code; 127} 128int CLZWDecoder::Decode(FX_LPBYTE dest_buf, FX_DWORD& dest_size, const FX_BYTE* src_buf, FX_DWORD& src_size, FX_BOOL bEarlyChange) 129{ 130 m_CodeLen = 9; 131 m_InPos = 0; 132 m_OutPos = 0; 133 m_pInput = src_buf; 134 m_pOutput = dest_buf; 135 m_Early = bEarlyChange ? 1 : 0; 136 m_nCodes = 0; 137 FX_DWORD old_code = (FX_DWORD) - 1; 138 FX_BYTE last_char; 139 while (1) { 140 if (m_InPos + m_CodeLen > src_size * 8) { 141 break; 142 } 143 int byte_pos = m_InPos / 8; 144 int bit_pos = m_InPos % 8, bit_left = m_CodeLen; 145 FX_DWORD code = 0; 146 if (bit_pos) { 147 bit_left -= 8 - bit_pos; 148 code = (m_pInput[byte_pos++] & ((1 << (8 - bit_pos)) - 1)) << bit_left; 149 } 150 if (bit_left < 8) { 151 code |= m_pInput[byte_pos] >> (8 - bit_left); 152 } else { 153 bit_left -= 8; 154 code |= m_pInput[byte_pos++] << bit_left; 155 if (bit_left) { 156 code |= m_pInput[byte_pos] >> (8 - bit_left); 157 } 158 } 159 m_InPos += m_CodeLen; 160 if (code < 256) { 161 if (m_OutPos == dest_size) { 162 return -5; 163 } 164 if (m_pOutput) { 165 m_pOutput[m_OutPos] = (FX_BYTE)code; 166 } 167 m_OutPos ++; 168 last_char = (FX_BYTE)code; 169 if (old_code != (FX_DWORD) - 1) { 170 AddCode(old_code, last_char); 171 } 172 old_code = code; 173 } else if (code == 256) { 174 m_CodeLen = 9; 175 m_nCodes = 0; 176 old_code = (FX_DWORD) - 1; 177 } else if (code == 257) { 178 break; 179 } else { 180 if (old_code == (FX_DWORD) - 1) { 181 return 2; 182 } 183 m_StackLen = 0; 184 if (code >= m_nCodes + 258) { 185 if (m_StackLen < sizeof(m_DecodeStack)) { 186 m_DecodeStack[m_StackLen++] = last_char; 187 } 188 DecodeString(old_code); 189 } else { 190 DecodeString(code); 191 } 192 if (m_OutPos + m_StackLen > dest_size) { 193 return -5; 194 } 195 if (m_pOutput) { 196 for (FX_DWORD i = 0; i < m_StackLen; i ++) { 197 m_pOutput[m_OutPos + i] = m_DecodeStack[m_StackLen - i - 1]; 198 } 199 } 200 m_OutPos += m_StackLen; 201 last_char = m_DecodeStack[m_StackLen - 1]; 202 if (old_code < 256) { 203 AddCode(old_code, last_char); 204 } else if (old_code - 258 >= m_nCodes) { 205 dest_size = m_OutPos; 206 src_size = (m_InPos + 7) / 8; 207 return 0; 208 } else { 209 AddCode(old_code, last_char); 210 } 211 old_code = code; 212 } 213 } 214 dest_size = m_OutPos; 215 src_size = (m_InPos + 7) / 8; 216 return 0; 217} 218static FX_BYTE PaethPredictor(int a, int b, int c) 219{ 220 int p = a + b - c; 221 int pa = FXSYS_abs(p - a); 222 int pb = FXSYS_abs(p - b); 223 int pc = FXSYS_abs(p - c); 224 if (pa <= pb && pa <= pc) { 225 return (FX_BYTE)a; 226 } 227 if (pb <= pc) { 228 return (FX_BYTE)b; 229 } 230 return (FX_BYTE)c; 231} 232static void PNG_PredictorEncode(FX_LPBYTE& data_buf, FX_DWORD& data_size, int predictor, int Colors, int BitsPerComponent, int Columns) 233{ 234 int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; 235 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; 236 int row_count = (data_size + row_size - 1) / row_size; 237 int last_row_size = data_size % row_size; 238 FX_LPBYTE dest_buf = FX_Alloc( FX_BYTE, (row_size + 1) * row_count); 239 if (dest_buf == NULL) { 240 return; 241 } 242 int byte_cnt = 0; 243 FX_LPBYTE pSrcData = data_buf; 244 FX_LPBYTE pDestData = dest_buf; 245 for (int row = 0; row < row_count; row++) { 246 if (predictor == 10) { 247 pDestData[0] = 0; 248 int move_size = row_size; 249 if (move_size * (row + 1) > (int)data_size) { 250 move_size = data_size - (move_size * row); 251 } 252 FXSYS_memmove32(pDestData + 1, pSrcData, move_size); 253 pDestData += (move_size + 1); 254 pSrcData += move_size; 255 byte_cnt += move_size; 256 continue; 257 } 258 for (int byte = 0; byte < row_size && byte_cnt < (int)data_size; byte++) { 259 switch (predictor) { 260 case 11: { 261 pDestData[0] = 1; 262 FX_BYTE left = 0; 263 if (byte >= BytesPerPixel) { 264 left = pSrcData[byte - BytesPerPixel]; 265 } 266 pDestData[byte + 1] = pSrcData[byte] - left; 267 } 268 break; 269 case 12: { 270 pDestData[0] = 2; 271 FX_BYTE up = 0; 272 if (row) { 273 up = pSrcData[byte - row_size]; 274 } 275 pDestData[byte + 1] = pSrcData[byte] - up; 276 } 277 break; 278 case 13: { 279 pDestData[0] = 3; 280 FX_BYTE left = 0; 281 if (byte >= BytesPerPixel) { 282 left = pSrcData[byte - BytesPerPixel]; 283 } 284 FX_BYTE up = 0; 285 if (row) { 286 up = pSrcData[byte - row_size]; 287 } 288 pDestData[byte + 1] = pSrcData[byte] - (left + up) / 2; 289 } 290 break; 291 case 14: { 292 pDestData[0] = 4; 293 FX_BYTE left = 0; 294 if (byte >= BytesPerPixel) { 295 left = pSrcData[byte - BytesPerPixel]; 296 } 297 FX_BYTE up = 0; 298 if (row) { 299 up = pSrcData[byte - row_size]; 300 } 301 FX_BYTE upper_left = 0; 302 if (byte >= BytesPerPixel && row) { 303 upper_left = pSrcData[byte - row_size - BytesPerPixel]; 304 } 305 pDestData[byte + 1] = pSrcData[byte] - PaethPredictor(left, up, upper_left); 306 } 307 break; 308 default: { 309 pDestData[byte + 1] = pSrcData[byte]; 310 } 311 break; 312 } 313 byte_cnt++; 314 } 315 pDestData += (row_size + 1); 316 pSrcData += row_size; 317 } 318 FX_Free(data_buf); 319 data_buf = dest_buf; 320 data_size = (row_size + 1) * row_count - (last_row_size > 0 ? (row_size - last_row_size) : 0); 321} 322static void PNG_PredictLine(FX_LPBYTE pDestData, FX_LPCBYTE pSrcData, FX_LPCBYTE pLastLine, 323 int bpc, int nColors, int nPixels) 324{ 325 int row_size = (nPixels * bpc * nColors + 7) / 8; 326 int BytesPerPixel = (bpc * nColors + 7) / 8; 327 FX_BYTE tag = pSrcData[0]; 328 if (tag == 0) { 329 FXSYS_memmove32(pDestData, pSrcData + 1, row_size); 330 return; 331 } 332 for (int byte = 0; byte < row_size; byte ++) { 333 FX_BYTE raw_byte = pSrcData[byte + 1]; 334 switch (tag) { 335 case 1: { 336 FX_BYTE left = 0; 337 if (byte >= BytesPerPixel) { 338 left = pDestData[byte - BytesPerPixel]; 339 } 340 pDestData[byte] = raw_byte + left; 341 break; 342 } 343 case 2: { 344 FX_BYTE up = 0; 345 if (pLastLine) { 346 up = pLastLine[byte]; 347 } 348 pDestData[byte] = raw_byte + up; 349 break; 350 } 351 case 3: { 352 FX_BYTE left = 0; 353 if (byte >= BytesPerPixel) { 354 left = pDestData[byte - BytesPerPixel]; 355 } 356 FX_BYTE up = 0; 357 if (pLastLine) { 358 up = pLastLine[byte]; 359 } 360 pDestData[byte] = raw_byte + (up + left) / 2; 361 break; 362 } 363 case 4: { 364 FX_BYTE left = 0; 365 if (byte >= BytesPerPixel) { 366 left = pDestData[byte - BytesPerPixel]; 367 } 368 FX_BYTE up = 0; 369 if (pLastLine) { 370 up = pLastLine[byte]; 371 } 372 FX_BYTE upper_left = 0; 373 if (byte >= BytesPerPixel && pLastLine) { 374 upper_left = pLastLine[byte - BytesPerPixel]; 375 } 376 pDestData[byte] = raw_byte + PaethPredictor(left, up, upper_left); 377 break; 378 } 379 default: 380 pDestData[byte] = raw_byte; 381 break; 382 } 383 } 384} 385static void PNG_Predictor(FX_LPBYTE& data_buf, FX_DWORD& data_size, 386 int Colors, int BitsPerComponent, int Columns) 387{ 388 int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; 389 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; 390 int row_count = (data_size + row_size) / (row_size + 1); 391 int last_row_size = data_size % (row_size + 1); 392 FX_LPBYTE dest_buf = FX_Alloc( FX_BYTE, row_size * row_count); 393 if (dest_buf == NULL) { 394 return; 395 } 396 int byte_cnt = 0; 397 FX_LPBYTE pSrcData = data_buf; 398 FX_LPBYTE pDestData = dest_buf; 399 for (int row = 0; row < row_count; row ++) { 400 FX_BYTE tag = pSrcData[0]; 401 if (tag == 0) { 402 int move_size = row_size; 403 if ((row + 1) * (move_size + 1) > (int)data_size) { 404 move_size = last_row_size - 1; 405 } 406 FXSYS_memmove32(pDestData, pSrcData + 1, move_size); 407 pSrcData += move_size + 1; 408 pDestData += move_size; 409 byte_cnt += move_size + 1; 410 continue; 411 } 412 for (int byte = 0; byte < row_size && byte_cnt < (int)data_size; byte ++) { 413 FX_BYTE raw_byte = pSrcData[byte + 1]; 414 switch (tag) { 415 case 1: { 416 FX_BYTE left = 0; 417 if (byte >= BytesPerPixel) { 418 left = pDestData[byte - BytesPerPixel]; 419 } 420 pDestData[byte] = raw_byte + left; 421 break; 422 } 423 case 2: { 424 FX_BYTE up = 0; 425 if (row) { 426 up = pDestData[byte - row_size]; 427 } 428 pDestData[byte] = raw_byte + up; 429 break; 430 } 431 case 3: { 432 FX_BYTE left = 0; 433 if (byte >= BytesPerPixel) { 434 left = pDestData[byte - BytesPerPixel]; 435 } 436 FX_BYTE up = 0; 437 if (row) { 438 up = pDestData[byte - row_size]; 439 } 440 pDestData[byte] = raw_byte + (up + left) / 2; 441 break; 442 } 443 case 4: { 444 FX_BYTE left = 0; 445 if (byte >= BytesPerPixel) { 446 left = pDestData[byte - BytesPerPixel]; 447 } 448 FX_BYTE up = 0; 449 if (row) { 450 up = pDestData[byte - row_size]; 451 } 452 FX_BYTE upper_left = 0; 453 if (byte >= BytesPerPixel && row) { 454 upper_left = pDestData[byte - row_size - BytesPerPixel]; 455 } 456 pDestData[byte] = raw_byte + PaethPredictor(left, up, upper_left); 457 break; 458 } 459 default: 460 pDestData[byte] = raw_byte; 461 break; 462 } 463 byte_cnt++; 464 } 465 pSrcData += row_size + 1; 466 pDestData += row_size; 467 byte_cnt++; 468 } 469 FX_Free(data_buf); 470 data_buf = dest_buf; 471 data_size = row_size * row_count - (last_row_size > 0 ? (row_size + 1 - last_row_size) : 0); 472} 473static void TIFF_PredictorEncodeLine(FX_LPBYTE dest_buf, int row_size, int BitsPerComponent, int Colors, int Columns) 474{ 475 int BytesPerPixel = BitsPerComponent * Colors / 8; 476 if (BitsPerComponent < 8) { 477 FX_BYTE mask = 0x01; 478 if (BitsPerComponent == 2) { 479 mask = 0x03; 480 } else if (BitsPerComponent == 4) { 481 mask = 0x0F; 482 } 483 int row_bits = Colors * BitsPerComponent * Columns; 484 for (int i = row_bits - BitsPerComponent; i >= BitsPerComponent; i -= BitsPerComponent) { 485 int col = i % 8; 486 int index = i / 8; 487 int col_pre = (col == 0) ? (8 - BitsPerComponent) : (col - BitsPerComponent); 488 int index_pre = (col == 0) ? (index - 1) : index; 489 FX_BYTE cur = (dest_buf[index] >> (8 - col - BitsPerComponent)) & mask; 490 FX_BYTE left = (dest_buf[index_pre] >> (8 - col_pre - BitsPerComponent)) & mask; 491 cur -= left; 492 cur &= mask; 493 cur <<= (8 - col - BitsPerComponent); 494 dest_buf[index] &= ~(mask << ((8 - col - BitsPerComponent))); 495 dest_buf[index] |= cur; 496 } 497 } else if (BitsPerComponent == 8) { 498 for (int i = row_size - 1; i >= BytesPerPixel; i--) { 499 dest_buf[i] -= dest_buf[i - BytesPerPixel]; 500 } 501 } else { 502 for (int i = row_size - BytesPerPixel; i >= BytesPerPixel; i -= BytesPerPixel) { 503 FX_WORD pixel = (dest_buf[i] << 8) | dest_buf[i + 1]; 504 pixel -= (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1]; 505 dest_buf[i] = pixel >> 8; 506 dest_buf[i + 1] = (FX_BYTE)pixel; 507 } 508 } 509} 510static void TIFF_PredictorEncode(FX_LPBYTE& data_buf, FX_DWORD& data_size, 511 int Colors, int BitsPerComponent, int Columns) 512{ 513 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; 514 int row_count = (data_size + row_size - 1) / row_size; 515 int last_row_size = data_size % row_size; 516 for (int row = 0; row < row_count; row++) { 517 FX_LPBYTE scan_line = data_buf + row * row_size; 518 if ((row + 1) * row_size > (int)data_size) { 519 row_size = last_row_size; 520 } 521 TIFF_PredictorEncodeLine(scan_line, row_size, BitsPerComponent, Colors, Columns); 522 } 523} 524static void TIFF_PredictLine(FX_LPBYTE dest_buf, int row_size, int BitsPerComponent, int Colors, int Columns) 525{ 526 if (BitsPerComponent == 1) { 527 int row_bits = BitsPerComponent * Colors * Columns; 528 for(int i = 1; i < row_bits; i ++) { 529 int col = i % 8; 530 int index = i / 8; 531 int index_pre = (col == 0) ? (index - 1) : index; 532 int col_pre = (col == 0) ? 8 : col; 533 if( ((dest_buf[index] >> (7 - col)) & 1) ^ ((dest_buf[index_pre] >> (8 - col_pre)) & 1) ) { 534 dest_buf[index] |= 1 << (7 - col); 535 } else { 536 dest_buf[index] &= ~(1 << (7 - col)); 537 } 538 } 539 return; 540 } 541 int BytesPerPixel = BitsPerComponent * Colors / 8; 542 if (BitsPerComponent == 16) { 543 for (int i = BytesPerPixel; i < row_size; i += 2) { 544 FX_WORD pixel = (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1]; 545 pixel += (dest_buf[i] << 8) | dest_buf[i + 1]; 546 dest_buf[i] = pixel >> 8; 547 dest_buf[i + 1] = (FX_BYTE)pixel; 548 } 549 } else { 550 for (int i = BytesPerPixel; i < row_size; i ++) { 551 dest_buf[i] += dest_buf[i - BytesPerPixel]; 552 } 553 } 554} 555static void TIFF_Predictor(FX_LPBYTE& data_buf, FX_DWORD& data_size, 556 int Colors, int BitsPerComponent, int Columns) 557{ 558 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; 559 int row_count = (data_size + row_size - 1) / row_size; 560 int last_row_size = data_size % row_size; 561 for (int row = 0; row < row_count; row ++) { 562 FX_LPBYTE scan_line = data_buf + row * row_size; 563 if ((row + 1) * row_size > (int)data_size) { 564 row_size = last_row_size; 565 } 566 TIFF_PredictLine(scan_line, row_size, BitsPerComponent, Colors, Columns); 567 } 568} 569class CCodec_FlateScanlineDecoder : public CCodec_ScanlineDecoder 570{ 571public: 572 CCodec_FlateScanlineDecoder(); 573 ~CCodec_FlateScanlineDecoder(); 574 FX_BOOL Create(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height, int nComps, int bpc, 575 int predictor, int Colors, int BitsPerComponent, int Columns); 576 virtual void Destroy() 577 { 578 delete this; 579 } 580 virtual void v_DownScale(int dest_width, int dest_height) {} 581 virtual FX_BOOL v_Rewind(); 582 virtual FX_LPBYTE v_GetNextLine(); 583 virtual FX_DWORD GetSrcOffset(); 584 void* m_pFlate; 585 FX_LPCBYTE m_SrcBuf; 586 FX_DWORD m_SrcSize; 587 FX_LPBYTE m_pScanline; 588 FX_LPBYTE m_pLastLine; 589 FX_LPBYTE m_pPredictBuffer; 590 FX_LPBYTE m_pPredictRaw; 591 int m_Predictor; 592 int m_Colors, m_BitsPerComponent, m_Columns, m_PredictPitch, m_LeftOver; 593}; 594CCodec_FlateScanlineDecoder::CCodec_FlateScanlineDecoder() 595{ 596 m_pFlate = NULL; 597 m_pScanline = NULL; 598 m_pLastLine = NULL; 599 m_pPredictBuffer = NULL; 600 m_pPredictRaw = NULL; 601 m_LeftOver = 0; 602} 603CCodec_FlateScanlineDecoder::~CCodec_FlateScanlineDecoder() 604{ 605 if (m_pScanline) { 606 FX_Free(m_pScanline); 607 } 608 if (m_pLastLine) { 609 FX_Free(m_pLastLine); 610 } 611 if (m_pPredictBuffer) { 612 FX_Free(m_pPredictBuffer); 613 } 614 if (m_pPredictRaw) { 615 FX_Free(m_pPredictRaw); 616 } 617 if (m_pFlate) { 618 FPDFAPI_FlateEnd(m_pFlate); 619 } 620} 621FX_BOOL CCodec_FlateScanlineDecoder::Create(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height, 622 int nComps, int bpc, int predictor, int Colors, int BitsPerComponent, int Columns) 623{ 624 m_SrcBuf = src_buf; 625 m_SrcSize = src_size; 626 m_OutputWidth = m_OrigWidth = width; 627 m_OutputHeight = m_OrigHeight = height; 628 m_nComps = nComps; 629 m_bpc = bpc; 630 m_bColorTransformed = FALSE; 631 m_Pitch = (width * nComps * bpc + 7) / 8; 632 m_pScanline = FX_Alloc(FX_BYTE, m_Pitch); 633 if (m_pScanline == NULL) { 634 return FALSE; 635 } 636 m_Predictor = 0; 637 if (predictor) { 638 if (predictor >= 10) { 639 m_Predictor = 2; 640 } else if (predictor == 2) { 641 m_Predictor = 1; 642 } 643 if (m_Predictor) { 644 if (BitsPerComponent * Colors * Columns == 0) { 645 BitsPerComponent = m_bpc; 646 Colors = m_nComps; 647 Columns = m_OrigWidth; 648 } 649 m_Colors = Colors; 650 m_BitsPerComponent = BitsPerComponent; 651 m_Columns = Columns; 652 m_PredictPitch = (m_BitsPerComponent * m_Colors * m_Columns + 7) / 8; 653 m_pLastLine = FX_Alloc(FX_BYTE, m_PredictPitch); 654 if (m_pLastLine == NULL) { 655 return FALSE; 656 } 657 FXSYS_memset32(m_pLastLine, 0, m_PredictPitch); 658 m_pPredictRaw = FX_Alloc(FX_BYTE, m_PredictPitch + 1); 659 if (m_pPredictRaw == NULL) { 660 return FALSE; 661 } 662 m_pPredictBuffer = FX_Alloc(FX_BYTE, m_PredictPitch); 663 if (m_pPredictBuffer == NULL) { 664 return FALSE; 665 } 666 } 667 } 668 return TRUE; 669} 670FX_BOOL CCodec_FlateScanlineDecoder::v_Rewind() 671{ 672 if (m_pFlate) { 673 FPDFAPI_FlateEnd(m_pFlate); 674 } 675 m_pFlate = FPDFAPI_FlateInit(my_alloc_func, my_free_func); 676 if (m_pFlate == NULL) { 677 return FALSE; 678 } 679 FPDFAPI_FlateInput(m_pFlate, m_SrcBuf, m_SrcSize); 680 m_LeftOver = 0; 681 return TRUE; 682} 683FX_LPBYTE CCodec_FlateScanlineDecoder::v_GetNextLine() 684{ 685 if (m_Predictor) { 686 if (m_Pitch == m_PredictPitch) { 687 if (m_Predictor == 2) { 688 FPDFAPI_FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1); 689 PNG_PredictLine(m_pScanline, m_pPredictRaw, m_pLastLine, m_BitsPerComponent, m_Colors, m_Columns); 690 FXSYS_memcpy32(m_pLastLine, m_pScanline, m_PredictPitch); 691 } else { 692 FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch); 693 TIFF_PredictLine(m_pScanline, m_PredictPitch, m_bpc, m_nComps, m_OutputWidth); 694 } 695 } else { 696 int bytes_to_go = m_Pitch; 697 int read_leftover = m_LeftOver > bytes_to_go ? bytes_to_go : m_LeftOver; 698 if (read_leftover) { 699 FXSYS_memcpy32(m_pScanline, m_pPredictBuffer + m_PredictPitch - m_LeftOver, read_leftover); 700 m_LeftOver -= read_leftover; 701 bytes_to_go -= read_leftover; 702 } 703 while (bytes_to_go) { 704 if (m_Predictor == 2) { 705 FPDFAPI_FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1); 706 PNG_PredictLine(m_pPredictBuffer, m_pPredictRaw, m_pLastLine, m_BitsPerComponent, m_Colors, m_Columns); 707 FXSYS_memcpy32(m_pLastLine, m_pPredictBuffer, m_PredictPitch); 708 } else { 709 FPDFAPI_FlateOutput(m_pFlate, m_pPredictBuffer, m_PredictPitch); 710 TIFF_PredictLine(m_pPredictBuffer, m_PredictPitch, m_BitsPerComponent, m_Colors, m_Columns); 711 } 712 int read_bytes = m_PredictPitch > bytes_to_go ? bytes_to_go : m_PredictPitch; 713 FXSYS_memcpy32(m_pScanline + m_Pitch - bytes_to_go, m_pPredictBuffer, read_bytes); 714 m_LeftOver += m_PredictPitch - read_bytes; 715 bytes_to_go -= read_bytes; 716 } 717 } 718 } else { 719 FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch); 720 } 721 return m_pScanline; 722} 723FX_DWORD CCodec_FlateScanlineDecoder::GetSrcOffset() 724{ 725 return FPDFAPI_FlateGetTotalIn(m_pFlate); 726} 727static void FlateUncompress(FX_LPCBYTE src_buf, FX_DWORD src_size, FX_DWORD orig_size, 728 FX_LPBYTE& dest_buf, FX_DWORD& dest_size, FX_DWORD& offset) 729{ 730 FX_DWORD guess_size = orig_size ? orig_size : src_size * 2; 731 FX_DWORD alloc_step = orig_size ? 10240 : (src_size < 10240 ? 10240 : src_size); 732 static const FX_DWORD kMaxInitialAllocSize = 10000000; 733 if (guess_size > kMaxInitialAllocSize) { 734 guess_size = kMaxInitialAllocSize; 735 alloc_step = kMaxInitialAllocSize; 736 } 737 FX_LPBYTE guess_buf = FX_Alloc(FX_BYTE, guess_size + 1); 738 if (!guess_buf) { 739 dest_buf = NULL; 740 dest_size = 0; 741 return; 742 } 743 guess_buf[guess_size] = '\0'; 744 FX_BOOL useOldImpl = src_size < 10240; 745 void* context = FPDFAPI_FlateInit(my_alloc_func, my_free_func); 746 if (context == NULL) { 747 dest_buf = NULL; 748 dest_size = 0; 749 return ; 750 } 751 FPDFAPI_FlateInput(context, src_buf, src_size); 752 CFX_ArrayTemplate<FX_LPBYTE> result_tmp_bufs; 753 FX_LPBYTE buf = guess_buf; 754 FX_DWORD buf_size = guess_size; 755 FX_DWORD last_buf_size = buf_size; 756 while (1) { 757 FX_INT32 ret = FPDFAPI_FlateOutput(context, buf, buf_size); 758 FX_INT32 avail_buf_size = FPDFAPI_FlateGetAvailOut(context); 759 if (!useOldImpl) { 760 if (ret != Z_OK) { 761 last_buf_size = buf_size - avail_buf_size; 762 result_tmp_bufs.Add(buf); 763 break; 764 } 765 if (avail_buf_size == 0) { 766 result_tmp_bufs.Add(buf); 767 buf = NULL; 768 buf = FX_Alloc(FX_BYTE, buf_size + 1); 769 if (!buf) { 770 dest_buf = NULL; 771 dest_size = 0; 772 return; 773 } 774 buf[buf_size] = '\0'; 775 } else { 776 last_buf_size = buf_size - avail_buf_size; 777 result_tmp_bufs.Add(buf); 778 buf = NULL; 779 break; 780 } 781 } else { 782 if (ret != Z_OK) { 783 break; 784 } 785 if (avail_buf_size == 0) { 786 FX_DWORD old_size = guess_size; 787 guess_size += alloc_step; 788 if (guess_size < old_size || guess_size + 1 < guess_size) { 789 dest_buf = NULL; 790 dest_size = 0; 791 return; 792 } 793 guess_buf = FX_Realloc(FX_BYTE, guess_buf, guess_size + 1); 794 if (!guess_buf) { 795 dest_buf = NULL; 796 dest_size = 0; 797 return; 798 } 799 guess_buf[guess_size] = '\0'; 800 buf = guess_buf + old_size; 801 buf_size = guess_size - old_size; 802 } else { 803 break; 804 } 805 } 806 } 807 dest_size = FPDFAPI_FlateGetTotalOut(context); 808 offset = FPDFAPI_FlateGetTotalIn(context); 809 if (!useOldImpl) { 810 if (result_tmp_bufs.GetSize() == 1) { 811 dest_buf = result_tmp_bufs[0]; 812 } else { 813 FX_LPBYTE result_buf = FX_Alloc(FX_BYTE, dest_size); 814 if (!result_buf) { 815 dest_buf = NULL; 816 dest_size = 0; 817 return; 818 } 819 FX_DWORD result_pos = 0; 820 for (FX_INT32 i = 0; i < result_tmp_bufs.GetSize(); i++) { 821 FX_LPBYTE tmp_buf = result_tmp_bufs[i]; 822 FX_DWORD tmp_buf_size = buf_size; 823 if (i == result_tmp_bufs.GetSize() - 1) { 824 tmp_buf_size = last_buf_size; 825 } 826 FXSYS_memcpy32(result_buf + result_pos, tmp_buf, tmp_buf_size); 827 result_pos += tmp_buf_size; 828 FX_Free(tmp_buf); 829 tmp_buf = NULL; 830 result_tmp_bufs[i] = NULL; 831 } 832 dest_buf = result_buf; 833 } 834 } else { 835 if (guess_size / 2 > dest_size) { 836 guess_buf = FX_Realloc(FX_BYTE, guess_buf, dest_size + 1); 837 if (!guess_buf) { 838 dest_buf = NULL; 839 dest_size = 0; 840 return; 841 } 842 guess_size = dest_size; 843 guess_buf[guess_size] = '\0'; 844 } 845 dest_buf = guess_buf; 846 } 847 FPDFAPI_FlateEnd(context); 848 context = NULL; 849} 850ICodec_ScanlineDecoder* CCodec_FlateModule::CreateDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height, 851 int nComps, int bpc, int predictor, int Colors, int BitsPerComponent, int Columns) 852{ 853 CCodec_FlateScanlineDecoder* pDecoder = FX_NEW CCodec_FlateScanlineDecoder; 854 if (pDecoder == NULL) { 855 return NULL; 856 } 857 pDecoder->Create(src_buf, src_size, width, height, nComps, bpc, predictor, Colors, BitsPerComponent, Columns); 858 return pDecoder; 859} 860FX_DWORD CCodec_FlateModule::FlateOrLZWDecode(FX_BOOL bLZW, const FX_BYTE* src_buf, FX_DWORD src_size, FX_BOOL bEarlyChange, 861 int predictor, int Colors, int BitsPerComponent, int Columns, 862 FX_DWORD estimated_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size) 863{ 864 CLZWDecoder* pDecoder = NULL; 865 dest_buf = NULL; 866 FX_DWORD offset = 0; 867 int predictor_type = 0; 868 if (predictor) { 869 if (predictor >= 10) { 870 predictor_type = 2; 871 } else if (predictor == 2) { 872 predictor_type = 1; 873 } 874 } 875 if (bLZW) { 876 pDecoder = FX_NEW CLZWDecoder; 877 if (pDecoder == NULL) { 878 return -1; 879 } 880 dest_size = (FX_DWORD) - 1; 881 offset = src_size; 882 int err = pDecoder->Decode(NULL, dest_size, src_buf, offset, bEarlyChange); 883 delete pDecoder; 884 if (err || dest_size == 0 || dest_size + 1 < dest_size) { 885 return (FX_DWORD) - 1; 886 } 887 pDecoder = FX_NEW CLZWDecoder; 888 if (pDecoder == NULL) { 889 return -1; 890 } 891 dest_buf = FX_Alloc( FX_BYTE, dest_size + 1); 892 if (dest_buf == NULL) { 893 return -1; 894 } 895 dest_buf[dest_size] = '\0'; 896 pDecoder->Decode(dest_buf, dest_size, src_buf, offset, bEarlyChange); 897 delete pDecoder; 898 } else { 899 FlateUncompress(src_buf, src_size, estimated_size, dest_buf, dest_size, offset); 900 } 901 if (predictor_type == 0) { 902 return offset; 903 } 904 if (predictor_type == 2) { 905 PNG_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns); 906 } else if (predictor_type == 1) { 907 TIFF_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns); 908 } 909 return offset; 910} 911FX_BOOL CCodec_FlateModule::Encode(const FX_BYTE* src_buf, FX_DWORD src_size, 912 int predictor, int Colors, int BitsPerComponent, int Columns, 913 FX_LPBYTE& dest_buf, FX_DWORD& dest_size) 914{ 915 if (predictor != 2 && predictor < 10) { 916 return Encode(src_buf, src_size, dest_buf, dest_size); 917 } 918 FX_BOOL ret = FALSE; 919 FX_LPBYTE pSrcBuf = NULL; 920 pSrcBuf = FX_Alloc(FX_BYTE, src_size); 921 if (pSrcBuf == NULL) { 922 return FALSE; 923 } 924 FXSYS_memcpy32(pSrcBuf, src_buf, src_size); 925 if (predictor == 2) { 926 TIFF_PredictorEncode(pSrcBuf, src_size, Colors, BitsPerComponent, Columns); 927 } else if (predictor >= 10) { 928 PNG_PredictorEncode(pSrcBuf, src_size, predictor, Colors, BitsPerComponent, Columns); 929 } 930 ret = Encode(pSrcBuf, src_size, dest_buf, dest_size); 931 FX_Free(pSrcBuf); 932 return ret; 933} 934FX_BOOL CCodec_FlateModule::Encode(FX_LPCBYTE src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size) 935{ 936 dest_size = src_size + src_size / 1000 + 12; 937 dest_buf = FX_Alloc( FX_BYTE, dest_size); 938 if (dest_buf == NULL) { 939 return FALSE; 940 } 941 unsigned long temp_size = dest_size; 942 FPDFAPI_FlateCompress(dest_buf, &temp_size, src_buf, src_size); 943 dest_size = (FX_DWORD)temp_size; 944 return TRUE; 945} 946