| 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 "codec_int.h" | 7 #include "codec_int.h" |
| 8 #include "core/include/fxcodec/fx_codec.h" | 8 #include "core/include/fxcodec/fx_codec.h" |
| 9 #include "core/include/fxcodec/fx_codec_flate.h" | 9 #include "core/include/fxcodec/fx_codec_flate.h" |
| 10 #include "third_party/base/nonstd_unique_ptr.h" | 10 #include "third_party/base/nonstd_unique_ptr.h" |
| 11 #include "third_party/zlib_v128/zlib.h" | 11 #include "third_party/zlib_v128/zlib.h" |
| 12 | 12 |
| 13 extern "C" { | 13 extern "C" { |
| 14 static void* my_alloc_func(void* opaque, | 14 static void* my_alloc_func(void* opaque, |
| 15 unsigned int items, | 15 unsigned int items, |
| 16 unsigned int size) { | 16 unsigned int size) { |
| 17 return FX_Alloc2D(uint8_t, items, size); | 17 return FX_Alloc2D(uint8_t, items, size); |
| 18 } | 18 } |
| 19 static void my_free_func(void* opaque, void* address) { | 19 static void my_free_func(void* opaque, void* address) { |
| 20 FX_Free(address); | 20 FX_Free(address); |
| 21 } | 21 } |
| 22 static int FPDFAPI_FlateGetTotalOut(void* context) { | 22 static int FPDFAPI_FlateGetTotalOut(void* context) { |
| 23 return ((z_stream*)context)->total_out; | 23 return ((z_stream*)context)->total_out; |
| 24 } | 24 } |
| 25 static int FPDFAPI_FlateGetTotalIn(void* context) { | 25 static int FPDFAPI_FlateGetTotalIn(void* context) { |
| 26 return ((z_stream*)context)->total_in; | 26 return ((z_stream*)context)->total_in; |
| 27 } | 27 } |
| 28 static bool FPDFAPI_FlateCompress(unsigned char* dest_buf, | 28 static void FPDFAPI_FlateCompress(unsigned char* dest_buf, |
| 29 unsigned long* dest_size, | 29 unsigned long* dest_size, |
| 30 const unsigned char* src_buf, | 30 const unsigned char* src_buf, |
| 31 unsigned long src_size) { | 31 unsigned long src_size) { |
| 32 return compress(dest_buf, dest_size, src_buf, src_size) == Z_OK; | 32 compress(dest_buf, dest_size, src_buf, src_size); |
| 33 } | 33 } |
| 34 void* FPDFAPI_FlateInit(void* (*alloc_func)(void*, unsigned int, unsigned int), | 34 void* FPDFAPI_FlateInit(void* (*alloc_func)(void*, unsigned int, unsigned int), |
| 35 void (*free_func)(void*, void*)) { | 35 void (*free_func)(void*, void*)) { |
| 36 z_stream* p = (z_stream*)alloc_func(0, 1, sizeof(z_stream)); | 36 z_stream* p = (z_stream*)alloc_func(0, 1, sizeof(z_stream)); |
| 37 if (!p) { | 37 if (!p) { |
| 38 return NULL; | 38 return NULL; |
| 39 } | 39 } |
| 40 FXSYS_memset(p, 0, sizeof(z_stream)); | 40 FXSYS_memset(p, 0, sizeof(z_stream)); |
| 41 p->zalloc = alloc_func; | 41 p->zalloc = alloc_func; |
| 42 p->zfree = free_func; | 42 p->zfree = free_func; |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 AddCode(old_code, last_char); | 218 AddCode(old_code, last_char); |
| 219 } | 219 } |
| 220 old_code = code; | 220 old_code = code; |
| 221 } | 221 } |
| 222 } | 222 } |
| 223 dest_size = m_OutPos; | 223 dest_size = m_OutPos; |
| 224 src_size = (m_InPos + 7) / 8; | 224 src_size = (m_InPos + 7) / 8; |
| 225 return 0; | 225 return 0; |
| 226 } | 226 } |
| 227 | 227 |
| 228 uint8_t PathPredictor(int a, int b, int c) { | 228 uint8_t PaethPredictor(int a, int b, int c) { |
| 229 int p = a + b - c; | 229 int p = a + b - c; |
| 230 int pa = FXSYS_abs(p - a); | 230 int pa = FXSYS_abs(p - a); |
| 231 int pb = FXSYS_abs(p - b); | 231 int pb = FXSYS_abs(p - b); |
| 232 int pc = FXSYS_abs(p - c); | 232 int pc = FXSYS_abs(p - c); |
| 233 if (pa <= pb && pa <= pc) { | 233 if (pa <= pb && pa <= pc) { |
| 234 return (uint8_t)a; | 234 return (uint8_t)a; |
| 235 } | 235 } |
| 236 if (pb <= pc) { | 236 if (pb <= pc) { |
| 237 return (uint8_t)b; | 237 return (uint8_t)b; |
| 238 } | 238 } |
| 239 return (uint8_t)c; | 239 return (uint8_t)c; |
| 240 } | 240 } |
| 241 | 241 |
| 242 void PNG_PredictorEncode(uint8_t*& data_buf, FX_DWORD& data_size) { | 242 FX_BOOL PNG_PredictorEncode(uint8_t*& data_buf, |
| 243 const int row_size = 7; | 243 FX_DWORD& data_size, |
| 244 int predictor, |
| 245 int Colors, |
| 246 int BitsPerComponent, |
| 247 int Columns) { |
| 248 const int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; |
| 249 const int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; |
| 250 if (row_size <= 0) |
| 251 return FALSE; |
| 244 const int row_count = (data_size + row_size - 1) / row_size; | 252 const int row_count = (data_size + row_size - 1) / row_size; |
| 245 const int last_row_size = data_size % row_size; | 253 const int last_row_size = data_size % row_size; |
| 246 uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size + 1, row_count); | 254 uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size + 1, row_count); |
| 247 int byte_cnt = 0; | 255 int byte_cnt = 0; |
| 248 uint8_t* pSrcData = data_buf; | 256 uint8_t* pSrcData = data_buf; |
| 249 uint8_t* pDestData = dest_buf; | 257 uint8_t* pDestData = dest_buf; |
| 250 for (int row = 0; row < row_count; row++) { | 258 for (int row = 0; row < row_count; row++) { |
| 259 if (predictor == 10) { |
| 260 pDestData[0] = 0; |
| 261 int move_size = row_size; |
| 262 if (move_size * (row + 1) > (int)data_size) { |
| 263 move_size = data_size - (move_size * row); |
| 264 } |
| 265 FXSYS_memmove(pDestData + 1, pSrcData, move_size); |
| 266 pDestData += (move_size + 1); |
| 267 pSrcData += move_size; |
| 268 byte_cnt += move_size; |
| 269 continue; |
| 270 } |
| 251 for (int byte = 0; byte < row_size && byte_cnt < (int)data_size; byte++) { | 271 for (int byte = 0; byte < row_size && byte_cnt < (int)data_size; byte++) { |
| 272 switch (predictor) { |
| 273 case 11: { |
| 274 pDestData[0] = 1; |
| 275 uint8_t left = 0; |
| 276 if (byte >= BytesPerPixel) { |
| 277 left = pSrcData[byte - BytesPerPixel]; |
| 278 } |
| 279 pDestData[byte + 1] = pSrcData[byte] - left; |
| 280 } break; |
| 281 case 12: { |
| 252 pDestData[0] = 2; | 282 pDestData[0] = 2; |
| 253 uint8_t up = 0; | 283 uint8_t up = 0; |
| 254 if (row) | 284 if (row) { |
| 255 up = pSrcData[byte - row_size]; | 285 up = pSrcData[byte - row_size]; |
| 286 } |
| 256 pDestData[byte + 1] = pSrcData[byte] - up; | 287 pDestData[byte + 1] = pSrcData[byte] - up; |
| 288 } break; |
| 289 case 13: { |
| 290 pDestData[0] = 3; |
| 291 uint8_t left = 0; |
| 292 if (byte >= BytesPerPixel) { |
| 293 left = pSrcData[byte - BytesPerPixel]; |
| 294 } |
| 295 uint8_t up = 0; |
| 296 if (row) { |
| 297 up = pSrcData[byte - row_size]; |
| 298 } |
| 299 pDestData[byte + 1] = pSrcData[byte] - (left + up) / 2; |
| 300 } break; |
| 301 case 14: { |
| 302 pDestData[0] = 4; |
| 303 uint8_t left = 0; |
| 304 if (byte >= BytesPerPixel) { |
| 305 left = pSrcData[byte - BytesPerPixel]; |
| 306 } |
| 307 uint8_t up = 0; |
| 308 if (row) { |
| 309 up = pSrcData[byte - row_size]; |
| 310 } |
| 311 uint8_t upper_left = 0; |
| 312 if (byte >= BytesPerPixel && row) { |
| 313 upper_left = pSrcData[byte - row_size - BytesPerPixel]; |
| 314 } |
| 315 pDestData[byte + 1] = |
| 316 pSrcData[byte] - PaethPredictor(left, up, upper_left); |
| 317 } break; |
| 318 default: { pDestData[byte + 1] = pSrcData[byte]; } break; |
| 319 } |
| 257 byte_cnt++; | 320 byte_cnt++; |
| 258 } | 321 } |
| 259 pDestData += (row_size + 1); | 322 pDestData += (row_size + 1); |
| 260 pSrcData += row_size; | 323 pSrcData += row_size; |
| 261 } | 324 } |
| 262 FX_Free(data_buf); | 325 FX_Free(data_buf); |
| 263 data_buf = dest_buf; | 326 data_buf = dest_buf; |
| 264 data_size = (row_size + 1) * row_count - | 327 data_size = (row_size + 1) * row_count - |
| 265 (last_row_size > 0 ? (row_size - last_row_size) : 0); | 328 (last_row_size > 0 ? (row_size - last_row_size) : 0); |
| 329 return TRUE; |
| 266 } | 330 } |
| 267 | 331 |
| 268 void PNG_PredictLine(uint8_t* pDestData, | 332 void PNG_PredictLine(uint8_t* pDestData, |
| 269 const uint8_t* pSrcData, | 333 const uint8_t* pSrcData, |
| 270 const uint8_t* pLastLine, | 334 const uint8_t* pLastLine, |
| 271 int bpc, | 335 int bpc, |
| 272 int nColors, | 336 int nColors, |
| 273 int nPixels) { | 337 int nPixels) { |
| 274 int row_size = (nPixels * bpc * nColors + 7) / 8; | 338 int row_size = (nPixels * bpc * nColors + 7) / 8; |
| 275 int BytesPerPixel = (bpc * nColors + 7) / 8; | 339 int BytesPerPixel = (bpc * nColors + 7) / 8; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 left = pDestData[byte - BytesPerPixel]; | 379 left = pDestData[byte - BytesPerPixel]; |
| 316 } | 380 } |
| 317 uint8_t up = 0; | 381 uint8_t up = 0; |
| 318 if (pLastLine) { | 382 if (pLastLine) { |
| 319 up = pLastLine[byte]; | 383 up = pLastLine[byte]; |
| 320 } | 384 } |
| 321 uint8_t upper_left = 0; | 385 uint8_t upper_left = 0; |
| 322 if (byte >= BytesPerPixel && pLastLine) { | 386 if (byte >= BytesPerPixel && pLastLine) { |
| 323 upper_left = pLastLine[byte - BytesPerPixel]; | 387 upper_left = pLastLine[byte - BytesPerPixel]; |
| 324 } | 388 } |
| 325 pDestData[byte] = raw_byte + PathPredictor(left, up, upper_left); | 389 pDestData[byte] = raw_byte + PaethPredictor(left, up, upper_left); |
| 326 break; | 390 break; |
| 327 } | 391 } |
| 328 default: | 392 default: |
| 329 pDestData[byte] = raw_byte; | 393 pDestData[byte] = raw_byte; |
| 330 break; | 394 break; |
| 331 } | 395 } |
| 332 } | 396 } |
| 333 } | 397 } |
| 334 | 398 |
| 335 FX_BOOL PNG_Predictor(uint8_t*& data_buf, | 399 FX_BOOL PNG_Predictor(uint8_t*& data_buf, |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 left = pDestData[byte - BytesPerPixel]; | 464 left = pDestData[byte - BytesPerPixel]; |
| 401 } | 465 } |
| 402 uint8_t up = 0; | 466 uint8_t up = 0; |
| 403 if (row) { | 467 if (row) { |
| 404 up = pDestData[byte - row_size]; | 468 up = pDestData[byte - row_size]; |
| 405 } | 469 } |
| 406 uint8_t upper_left = 0; | 470 uint8_t upper_left = 0; |
| 407 if (byte >= BytesPerPixel && row) { | 471 if (byte >= BytesPerPixel && row) { |
| 408 upper_left = pDestData[byte - row_size - BytesPerPixel]; | 472 upper_left = pDestData[byte - row_size - BytesPerPixel]; |
| 409 } | 473 } |
| 410 pDestData[byte] = raw_byte + PathPredictor(left, up, upper_left); | 474 pDestData[byte] = raw_byte + PaethPredictor(left, up, upper_left); |
| 411 break; | 475 break; |
| 412 } | 476 } |
| 413 default: | 477 default: |
| 414 pDestData[byte] = raw_byte; | 478 pDestData[byte] = raw_byte; |
| 415 break; | 479 break; |
| 416 } | 480 } |
| 417 byte_cnt++; | 481 byte_cnt++; |
| 418 } | 482 } |
| 419 pSrcData += row_size + 1; | 483 pSrcData += row_size + 1; |
| 420 pDestData += row_size; | 484 pDestData += row_size; |
| 421 } | 485 } |
| 422 FX_Free(data_buf); | 486 FX_Free(data_buf); |
| 423 data_buf = dest_buf; | 487 data_buf = dest_buf; |
| 424 data_size = row_size * row_count - | 488 data_size = row_size * row_count - |
| 425 (last_row_size > 0 ? (row_size + 1 - last_row_size) : 0); | 489 (last_row_size > 0 ? (row_size + 1 - last_row_size) : 0); |
| 426 return TRUE; | 490 return TRUE; |
| 427 } | 491 } |
| 428 | 492 |
| 493 void TIFF_PredictorEncodeLine(uint8_t* dest_buf, |
| 494 int row_size, |
| 495 int BitsPerComponent, |
| 496 int Colors, |
| 497 int Columns) { |
| 498 int BytesPerPixel = BitsPerComponent * Colors / 8; |
| 499 if (BitsPerComponent < 8) { |
| 500 uint8_t mask = 0x01; |
| 501 if (BitsPerComponent == 2) { |
| 502 mask = 0x03; |
| 503 } else if (BitsPerComponent == 4) { |
| 504 mask = 0x0F; |
| 505 } |
| 506 int row_bits = Colors * BitsPerComponent * Columns; |
| 507 for (int i = row_bits - BitsPerComponent; i >= BitsPerComponent; |
| 508 i -= BitsPerComponent) { |
| 509 int col = i % 8; |
| 510 int index = i / 8; |
| 511 int col_pre = |
| 512 (col == 0) ? (8 - BitsPerComponent) : (col - BitsPerComponent); |
| 513 int index_pre = (col == 0) ? (index - 1) : index; |
| 514 uint8_t cur = (dest_buf[index] >> (8 - col - BitsPerComponent)) & mask; |
| 515 uint8_t left = |
| 516 (dest_buf[index_pre] >> (8 - col_pre - BitsPerComponent)) & mask; |
| 517 cur -= left; |
| 518 cur &= mask; |
| 519 cur <<= (8 - col - BitsPerComponent); |
| 520 dest_buf[index] &= ~(mask << ((8 - col - BitsPerComponent))); |
| 521 dest_buf[index] |= cur; |
| 522 } |
| 523 } else if (BitsPerComponent == 8) { |
| 524 for (int i = row_size - 1; i >= BytesPerPixel; i--) { |
| 525 dest_buf[i] -= dest_buf[i - BytesPerPixel]; |
| 526 } |
| 527 } else { |
| 528 for (int i = row_size - BytesPerPixel; i >= BytesPerPixel; |
| 529 i -= BytesPerPixel) { |
| 530 FX_WORD pixel = (dest_buf[i] << 8) | dest_buf[i + 1]; |
| 531 pixel -= |
| 532 (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1]; |
| 533 dest_buf[i] = pixel >> 8; |
| 534 dest_buf[i + 1] = (uint8_t)pixel; |
| 535 } |
| 536 } |
| 537 } |
| 538 |
| 539 FX_BOOL TIFF_PredictorEncode(uint8_t*& data_buf, |
| 540 FX_DWORD& data_size, |
| 541 int Colors, |
| 542 int BitsPerComponent, |
| 543 int Columns) { |
| 544 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; |
| 545 if (row_size == 0) |
| 546 return FALSE; |
| 547 const int row_count = (data_size + row_size - 1) / row_size; |
| 548 const int last_row_size = data_size % row_size; |
| 549 for (int row = 0; row < row_count; row++) { |
| 550 uint8_t* scan_line = data_buf + row * row_size; |
| 551 if ((row + 1) * row_size > (int)data_size) { |
| 552 row_size = last_row_size; |
| 553 } |
| 554 TIFF_PredictorEncodeLine(scan_line, row_size, BitsPerComponent, Colors, |
| 555 Columns); |
| 556 } |
| 557 return TRUE; |
| 558 } |
| 559 |
| 429 void TIFF_PredictLine(uint8_t* dest_buf, | 560 void TIFF_PredictLine(uint8_t* dest_buf, |
| 430 FX_DWORD row_size, | 561 FX_DWORD row_size, |
| 431 int BitsPerComponent, | 562 int BitsPerComponent, |
| 432 int Colors, | 563 int Colors, |
| 433 int Columns) { | 564 int Columns) { |
| 434 if (BitsPerComponent == 1) { | 565 if (BitsPerComponent == 1) { |
| 435 int row_bits = FX_MIN(BitsPerComponent * Colors * Columns, row_size * 8); | 566 int row_bits = FX_MIN(BitsPerComponent * Colors * Columns, row_size * 8); |
| 436 int index_pre = 0; | 567 int index_pre = 0; |
| 437 int col_pre = 0; | 568 int col_pre = 0; |
| 438 for (int i = 1; i < row_bits; i++) { | 569 for (int i = 1; i < row_bits; i++) { |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 825 } | 956 } |
| 826 FX_BOOL ret = TRUE; | 957 FX_BOOL ret = TRUE; |
| 827 if (predictor_type == 2) { | 958 if (predictor_type == 2) { |
| 828 ret = PNG_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns); | 959 ret = PNG_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns); |
| 829 } else if (predictor_type == 1) { | 960 } else if (predictor_type == 1) { |
| 830 ret = | 961 ret = |
| 831 TIFF_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns); | 962 TIFF_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns); |
| 832 } | 963 } |
| 833 return ret ? offset : -1; | 964 return ret ? offset : -1; |
| 834 } | 965 } |
| 835 | 966 FX_BOOL CCodec_FlateModule::Encode(const uint8_t* src_buf, |
| 836 bool CCodec_FlateModule::Encode(const uint8_t* src_buf, | |
| 837 FX_DWORD src_size, | |
| 838 uint8_t** dest_buf, | |
| 839 FX_DWORD* dest_size) { | |
| 840 *dest_size = src_size + src_size / 1000 + 12; | |
| 841 *dest_buf = FX_Alloc(uint8_t, *dest_size); | |
| 842 unsigned long temp_size = *dest_size; | |
| 843 if (!FPDFAPI_FlateCompress(*dest_buf, &temp_size, src_buf, src_size)) | |
| 844 return false; | |
| 845 | |
| 846 *dest_size = (FX_DWORD)temp_size; | |
| 847 return true; | |
| 848 } | |
| 849 | |
| 850 bool CCodec_FlateModule::PngEncode(const uint8_t* src_buf, | |
| 851 FX_DWORD src_size, | 967 FX_DWORD src_size, |
| 852 uint8_t** dest_buf, | 968 int predictor, |
| 853 FX_DWORD* dest_size) { | 969 int Colors, |
| 854 uint8_t* pSrcBuf = FX_Alloc(uint8_t, src_size); | 970 int BitsPerComponent, |
| 971 int Columns, |
| 972 uint8_t*& dest_buf, |
| 973 FX_DWORD& dest_size) { |
| 974 if (predictor != 2 && predictor < 10) { |
| 975 return Encode(src_buf, src_size, dest_buf, dest_size); |
| 976 } |
| 977 uint8_t* pSrcBuf = NULL; |
| 978 pSrcBuf = FX_Alloc(uint8_t, src_size); |
| 855 FXSYS_memcpy(pSrcBuf, src_buf, src_size); | 979 FXSYS_memcpy(pSrcBuf, src_buf, src_size); |
| 856 PNG_PredictorEncode(pSrcBuf, src_size); | 980 FX_BOOL ret = TRUE; |
| 857 FX_BOOL ret = Encode(pSrcBuf, src_size, dest_buf, dest_size); | 981 if (predictor == 2) { |
| 982 ret = TIFF_PredictorEncode(pSrcBuf, src_size, Colors, BitsPerComponent, |
| 983 Columns); |
| 984 } else if (predictor >= 10) { |
| 985 ret = PNG_PredictorEncode(pSrcBuf, src_size, predictor, Colors, |
| 986 BitsPerComponent, Columns); |
| 987 } |
| 988 if (ret) |
| 989 ret = Encode(pSrcBuf, src_size, dest_buf, dest_size); |
| 858 FX_Free(pSrcBuf); | 990 FX_Free(pSrcBuf); |
| 859 return ret; | 991 return ret; |
| 860 } | 992 } |
| 993 FX_BOOL CCodec_FlateModule::Encode(const uint8_t* src_buf, |
| 994 FX_DWORD src_size, |
| 995 uint8_t*& dest_buf, |
| 996 FX_DWORD& dest_size) { |
| 997 dest_size = src_size + src_size / 1000 + 12; |
| 998 dest_buf = FX_Alloc(uint8_t, dest_size); |
| 999 unsigned long temp_size = dest_size; |
| 1000 FPDFAPI_FlateCompress(dest_buf, &temp_size, src_buf, src_size); |
| 1001 dest_size = (FX_DWORD)temp_size; |
| 1002 return TRUE; |
| 1003 } |
| OLD | NEW |