| 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 "core/fpdfapi/fpdf_page/pageint.h" | 7 #include "core/fpdfapi/fpdf_page/pageint.h" |
| 8 | 8 |
| 9 #include <limits.h> | 9 #include <limits.h> |
| 10 | 10 |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 m_Stack[m_StackCount - ii - 1] = last; | 469 m_Stack[m_StackCount - ii - 1] = last; |
| 470 } | 470 } |
| 471 } | 471 } |
| 472 break; | 472 break; |
| 473 } | 473 } |
| 474 default: | 474 default: |
| 475 break; | 475 break; |
| 476 } | 476 } |
| 477 return TRUE; | 477 return TRUE; |
| 478 } | 478 } |
| 479 static FX_FLOAT PDF_Interpolate(FX_FLOAT x, | 479 |
| 480 FX_FLOAT xmin, | 480 // See PDF Reference 1.7, page 170, table 3.36. |
| 481 FX_FLOAT xmax, | 481 bool IsValidBitsPerSample(uint32_t x) { |
| 482 FX_FLOAT ymin, | 482 switch (x) { |
| 483 FX_FLOAT ymax) { | 483 case 1: |
| 484 return ((x - xmin) * (ymax - ymin) / (xmax - xmin)) + ymin; | 484 case 2: |
| 485 case 4: |
| 486 case 8: |
| 487 case 12: |
| 488 case 16: |
| 489 case 24: |
| 490 case 32: |
| 491 return true; |
| 492 default: |
| 493 return false; |
| 494 } |
| 485 } | 495 } |
| 486 static uint32_t _GetBits32(const uint8_t* pData, int bitpos, int nbits) { | 496 |
| 497 // See PDF Reference 1.7, page 170. |
| 498 FX_FLOAT PDF_Interpolate(FX_FLOAT x, |
| 499 FX_FLOAT xmin, |
| 500 FX_FLOAT xmax, |
| 501 FX_FLOAT ymin, |
| 502 FX_FLOAT ymax) { |
| 503 FX_FLOAT divisor = xmax - xmin; |
| 504 return ymin + (divisor ? (x - xmin) * (ymax - ymin) / divisor : 0); |
| 505 } |
| 506 |
| 507 uint32_t GetBits32(const uint8_t* pData, int bitpos, int nbits) { |
| 487 int result = 0; | 508 int result = 0; |
| 488 for (int i = 0; i < nbits; i++) | 509 for (int i = 0; i < nbits; i++) { |
| 489 if (pData[(bitpos + i) / 8] & (1 << (7 - (bitpos + i) % 8))) { | 510 if (pData[(bitpos + i) / 8] & (1 << (7 - (bitpos + i) % 8))) |
| 490 result |= 1 << (nbits - i - 1); | 511 result |= 1 << (nbits - i - 1); |
| 491 } | 512 } |
| 492 return result; | 513 return result; |
| 493 } | 514 } |
| 494 | 515 |
| 495 class CPDF_PSFunc : public CPDF_Function { | 516 class CPDF_PSFunc : public CPDF_Function { |
| 496 public: | 517 public: |
| 497 CPDF_PSFunc() : CPDF_Function(Type::kType4PostScript) {} | 518 CPDF_PSFunc() {} |
| 519 ~CPDF_PSFunc() override {} |
| 520 |
| 498 // CPDF_Function | 521 // CPDF_Function |
| 499 FX_BOOL v_Init(CPDF_Object* pObj) override; | 522 FX_BOOL v_Init(CPDF_Object* pObj) override; |
| 500 FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override; | 523 FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override; |
| 501 | 524 |
| 502 private: | 525 private: |
| 503 CPDF_PSEngine m_PS; | 526 CPDF_PSEngine m_PS; |
| 504 }; | 527 }; |
| 505 | 528 |
| 506 FX_BOOL CPDF_PSFunc::v_Init(CPDF_Object* pObj) { | 529 FX_BOOL CPDF_PSFunc::v_Init(CPDF_Object* pObj) { |
| 507 CPDF_StreamAcc acc; | 530 CPDF_StreamAcc acc; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 518 PS.Execute(); | 541 PS.Execute(); |
| 519 if (PS.GetStackSize() < m_nOutputs) | 542 if (PS.GetStackSize() < m_nOutputs) |
| 520 return FALSE; | 543 return FALSE; |
| 521 for (uint32_t i = 0; i < m_nOutputs; i++) | 544 for (uint32_t i = 0; i < m_nOutputs; i++) |
| 522 results[m_nOutputs - i - 1] = PS.Pop(); | 545 results[m_nOutputs - i - 1] = PS.Pop(); |
| 523 return TRUE; | 546 return TRUE; |
| 524 } | 547 } |
| 525 | 548 |
| 526 } // namespace | 549 } // namespace |
| 527 | 550 |
| 528 CPDF_SampledFunc::CPDF_SampledFunc() : CPDF_Function(Type::kType0Sampled) { | 551 CPDF_SampledFunc::CPDF_SampledFunc() {} |
| 529 m_pSampleStream = NULL; | |
| 530 m_pEncodeInfo = NULL; | |
| 531 m_pDecodeInfo = NULL; | |
| 532 } | |
| 533 | 552 |
| 534 CPDF_SampledFunc::~CPDF_SampledFunc() { | 553 CPDF_SampledFunc::~CPDF_SampledFunc() {} |
| 535 delete m_pSampleStream; | |
| 536 FX_Free(m_pEncodeInfo); | |
| 537 FX_Free(m_pDecodeInfo); | |
| 538 } | |
| 539 | 554 |
| 540 FX_BOOL CPDF_SampledFunc::v_Init(CPDF_Object* pObj) { | 555 FX_BOOL CPDF_SampledFunc::v_Init(CPDF_Object* pObj) { |
| 541 CPDF_Stream* pStream = pObj->AsStream(); | 556 CPDF_Stream* pStream = pObj->AsStream(); |
| 542 if (!pStream) | 557 if (!pStream) |
| 543 return false; | 558 return false; |
| 544 | 559 |
| 545 CPDF_Dictionary* pDict = pStream->GetDict(); | 560 CPDF_Dictionary* pDict = pStream->GetDict(); |
| 546 CPDF_Array* pSize = pDict->GetArrayBy("Size"); | 561 CPDF_Array* pSize = pDict->GetArrayBy("Size"); |
| 547 CPDF_Array* pEncode = pDict->GetArrayBy("Encode"); | 562 CPDF_Array* pEncode = pDict->GetArrayBy("Encode"); |
| 548 CPDF_Array* pDecode = pDict->GetArrayBy("Decode"); | 563 CPDF_Array* pDecode = pDict->GetArrayBy("Decode"); |
| 549 m_nBitsPerSample = pDict->GetIntegerBy("BitsPerSample"); | 564 m_nBitsPerSample = pDict->GetIntegerBy("BitsPerSample"); |
| 550 if (m_nBitsPerSample > 32) { | 565 if (!IsValidBitsPerSample(m_nBitsPerSample)) |
| 551 return FALSE; | 566 return FALSE; |
| 552 } | 567 |
| 553 m_SampleMax = 0xffffffff >> (32 - m_nBitsPerSample); | 568 m_SampleMax = 0xffffffff >> (32 - m_nBitsPerSample); |
| 554 m_pSampleStream = new CPDF_StreamAcc; | 569 m_pSampleStream.reset(new CPDF_StreamAcc); |
| 555 m_pSampleStream->LoadAllData(pStream, FALSE); | 570 m_pSampleStream->LoadAllData(pStream, FALSE); |
| 556 m_pEncodeInfo = FX_Alloc(SampleEncodeInfo, m_nInputs); | |
| 557 FX_SAFE_UINT32 nTotalSampleBits = 1; | 571 FX_SAFE_UINT32 nTotalSampleBits = 1; |
| 572 m_pEncodeInfo.resize(m_nInputs); |
| 558 for (uint32_t i = 0; i < m_nInputs; i++) { | 573 for (uint32_t i = 0; i < m_nInputs; i++) { |
| 559 m_pEncodeInfo[i].sizes = pSize ? pSize->GetIntegerAt(i) : 0; | 574 m_pEncodeInfo[i].sizes = pSize ? pSize->GetIntegerAt(i) : 0; |
| 560 if (!pSize && i == 0) | 575 if (!pSize && i == 0) |
| 561 m_pEncodeInfo[i].sizes = pDict->GetIntegerBy("Size"); | 576 m_pEncodeInfo[i].sizes = pDict->GetIntegerBy("Size"); |
| 562 nTotalSampleBits *= m_pEncodeInfo[i].sizes; | 577 nTotalSampleBits *= m_pEncodeInfo[i].sizes; |
| 563 if (pEncode) { | 578 if (pEncode) { |
| 564 m_pEncodeInfo[i].encode_min = pEncode->GetFloatAt(i * 2); | 579 m_pEncodeInfo[i].encode_min = pEncode->GetFloatAt(i * 2); |
| 565 m_pEncodeInfo[i].encode_max = pEncode->GetFloatAt(i * 2 + 1); | 580 m_pEncodeInfo[i].encode_max = pEncode->GetFloatAt(i * 2 + 1); |
| 566 } else { | 581 } else { |
| 567 m_pEncodeInfo[i].encode_min = 0; | 582 m_pEncodeInfo[i].encode_min = 0; |
| 568 if (m_pEncodeInfo[i].sizes == 1) | 583 m_pEncodeInfo[i].encode_max = m_pEncodeInfo[i].sizes == 1 |
| 569 m_pEncodeInfo[i].encode_max = 1; | 584 ? 1 |
| 570 else | 585 : (FX_FLOAT)m_pEncodeInfo[i].sizes - 1; |
| 571 m_pEncodeInfo[i].encode_max = (FX_FLOAT)m_pEncodeInfo[i].sizes - 1; | |
| 572 } | 586 } |
| 573 } | 587 } |
| 574 nTotalSampleBits *= m_nBitsPerSample; | 588 nTotalSampleBits *= m_nBitsPerSample; |
| 575 nTotalSampleBits *= m_nOutputs; | 589 nTotalSampleBits *= m_nOutputs; |
| 576 FX_SAFE_UINT32 nTotalSampleBytes = nTotalSampleBits; | 590 FX_SAFE_UINT32 nTotalSampleBytes = nTotalSampleBits; |
| 577 nTotalSampleBytes += 7; | 591 nTotalSampleBytes += 7; |
| 578 nTotalSampleBytes /= 8; | 592 nTotalSampleBytes /= 8; |
| 579 if (!nTotalSampleBytes.IsValid() || nTotalSampleBytes.ValueOrDie() == 0 || | 593 if (!nTotalSampleBytes.IsValid() || nTotalSampleBytes.ValueOrDie() == 0 || |
| 580 nTotalSampleBytes.ValueOrDie() > m_pSampleStream->GetSize()) { | 594 nTotalSampleBytes.ValueOrDie() > m_pSampleStream->GetSize()) { |
| 581 return FALSE; | 595 return FALSE; |
| 582 } | 596 } |
| 583 m_pDecodeInfo = FX_Alloc(SampleDecodeInfo, m_nOutputs); | 597 m_pDecodeInfo.resize(m_nOutputs); |
| 584 for (uint32_t i = 0; i < m_nOutputs; i++) { | 598 for (uint32_t i = 0; i < m_nOutputs; i++) { |
| 585 if (pDecode) { | 599 if (pDecode) { |
| 586 m_pDecodeInfo[i].decode_min = pDecode->GetFloatAt(2 * i); | 600 m_pDecodeInfo[i].decode_min = pDecode->GetFloatAt(2 * i); |
| 587 m_pDecodeInfo[i].decode_max = pDecode->GetFloatAt(2 * i + 1); | 601 m_pDecodeInfo[i].decode_max = pDecode->GetFloatAt(2 * i + 1); |
| 588 } else { | 602 } else { |
| 589 m_pDecodeInfo[i].decode_min = m_pRanges[i * 2]; | 603 m_pDecodeInfo[i].decode_min = m_pRanges[i * 2]; |
| 590 m_pDecodeInfo[i].decode_max = m_pRanges[i * 2 + 1]; | 604 m_pDecodeInfo[i].decode_max = m_pRanges[i * 2 + 1]; |
| 591 } | 605 } |
| 592 } | 606 } |
| 593 return TRUE; | 607 return TRUE; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 607 blocksize[i] = blocksize[i - 1] * m_pEncodeInfo[i - 1].sizes; | 621 blocksize[i] = blocksize[i - 1] * m_pEncodeInfo[i - 1].sizes; |
| 608 encoded_input[i] = PDF_Interpolate( | 622 encoded_input[i] = PDF_Interpolate( |
| 609 inputs[i], m_pDomains[i * 2], m_pDomains[i * 2 + 1], | 623 inputs[i], m_pDomains[i * 2], m_pDomains[i * 2 + 1], |
| 610 m_pEncodeInfo[i].encode_min, m_pEncodeInfo[i].encode_max); | 624 m_pEncodeInfo[i].encode_min, m_pEncodeInfo[i].encode_max); |
| 611 index[i] = std::min((uint32_t)std::max(0.f, encoded_input[i]), | 625 index[i] = std::min((uint32_t)std::max(0.f, encoded_input[i]), |
| 612 m_pEncodeInfo[i].sizes - 1); | 626 m_pEncodeInfo[i].sizes - 1); |
| 613 pos += index[i] * blocksize[i]; | 627 pos += index[i] * blocksize[i]; |
| 614 } | 628 } |
| 615 FX_SAFE_INT32 bits_to_output = m_nOutputs; | 629 FX_SAFE_INT32 bits_to_output = m_nOutputs; |
| 616 bits_to_output *= m_nBitsPerSample; | 630 bits_to_output *= m_nBitsPerSample; |
| 617 if (!bits_to_output.IsValid()) { | 631 if (!bits_to_output.IsValid()) |
| 618 return FALSE; | 632 return FALSE; |
| 619 } | 633 |
| 620 FX_SAFE_INT32 bitpos = pos; | 634 FX_SAFE_INT32 bitpos = pos; |
| 621 bitpos *= bits_to_output.ValueOrDie(); | 635 bitpos *= bits_to_output.ValueOrDie(); |
| 622 if (!bitpos.IsValid()) { | 636 if (!bitpos.IsValid()) |
| 623 return FALSE; | 637 return FALSE; |
| 624 } | 638 |
| 625 FX_SAFE_INT32 range_check = bitpos; | 639 FX_SAFE_INT32 range_check = bitpos; |
| 626 range_check += bits_to_output.ValueOrDie(); | 640 range_check += bits_to_output.ValueOrDie(); |
| 627 if (!range_check.IsValid()) { | 641 if (!range_check.IsValid()) |
| 628 return FALSE; | 642 return FALSE; |
| 629 } | 643 |
| 630 const uint8_t* pSampleData = m_pSampleStream->GetData(); | 644 const uint8_t* pSampleData = m_pSampleStream->GetData(); |
| 631 if (!pSampleData) { | 645 if (!pSampleData) |
| 632 return FALSE; | 646 return FALSE; |
| 633 } | 647 |
| 634 for (uint32_t j = 0; j < m_nOutputs; j++) { | 648 for (uint32_t j = 0; j < m_nOutputs; j++) { |
| 635 uint32_t sample = | 649 uint32_t sample = |
| 636 _GetBits32(pSampleData, bitpos.ValueOrDie() + j * m_nBitsPerSample, | 650 GetBits32(pSampleData, bitpos.ValueOrDie() + j * m_nBitsPerSample, |
| 637 m_nBitsPerSample); | 651 m_nBitsPerSample); |
| 638 FX_FLOAT encoded = (FX_FLOAT)sample; | 652 FX_FLOAT encoded = (FX_FLOAT)sample; |
| 639 for (uint32_t i = 0; i < m_nInputs; i++) { | 653 for (uint32_t i = 0; i < m_nInputs; i++) { |
| 640 if (index[i] == m_pEncodeInfo[i].sizes - 1) { | 654 if (index[i] == m_pEncodeInfo[i].sizes - 1) { |
| 641 if (index[i] == 0) | 655 if (index[i] == 0) |
| 642 encoded = encoded_input[i] * (FX_FLOAT)sample; | 656 encoded = encoded_input[i] * (FX_FLOAT)sample; |
| 643 } else { | 657 } else { |
| 644 FX_SAFE_INT32 bitpos2 = blocksize[i]; | 658 FX_SAFE_INT32 bitpos2 = blocksize[i]; |
| 645 bitpos2 += pos; | 659 bitpos2 += pos; |
| 646 bitpos2 *= m_nOutputs; | 660 bitpos2 *= m_nOutputs; |
| 647 bitpos2 += j; | 661 bitpos2 += j; |
| 648 bitpos2 *= m_nBitsPerSample; | 662 bitpos2 *= m_nBitsPerSample; |
| 649 if (!bitpos2.IsValid()) | 663 if (!bitpos2.IsValid()) |
| 650 return FALSE; | 664 return FALSE; |
| 651 uint32_t sample1 = | 665 uint32_t sample1 = |
| 652 _GetBits32(pSampleData, bitpos2.ValueOrDie(), m_nBitsPerSample); | 666 GetBits32(pSampleData, bitpos2.ValueOrDie(), m_nBitsPerSample); |
| 653 encoded += (encoded_input[i] - index[i]) * | 667 encoded += (encoded_input[i] - index[i]) * |
| 654 ((FX_FLOAT)sample1 - (FX_FLOAT)sample); | 668 ((FX_FLOAT)sample1 - (FX_FLOAT)sample); |
| 655 } | 669 } |
| 656 } | 670 } |
| 657 results[j] = PDF_Interpolate(encoded, 0, (FX_FLOAT)m_SampleMax, | 671 results[j] = PDF_Interpolate(encoded, 0, (FX_FLOAT)m_SampleMax, |
| 658 m_pDecodeInfo[j].decode_min, | 672 m_pDecodeInfo[j].decode_min, |
| 659 m_pDecodeInfo[j].decode_max); | 673 m_pDecodeInfo[j].decode_max); |
| 660 } | 674 } |
| 661 return TRUE; | 675 return TRUE; |
| 662 } | 676 } |
| 663 | 677 |
| 664 CPDF_ExpIntFunc::CPDF_ExpIntFunc() | 678 CPDF_ExpIntFunc::CPDF_ExpIntFunc() { |
| 665 : CPDF_Function(Type::kType2ExpotentialInterpolation) { | |
| 666 m_pBeginValues = NULL; | 679 m_pBeginValues = NULL; |
| 667 m_pEndValues = NULL; | 680 m_pEndValues = NULL; |
| 668 } | 681 } |
| 669 | 682 |
| 670 CPDF_ExpIntFunc::~CPDF_ExpIntFunc() { | 683 CPDF_ExpIntFunc::~CPDF_ExpIntFunc() { |
| 671 FX_Free(m_pBeginValues); | 684 FX_Free(m_pBeginValues); |
| 672 FX_Free(m_pEndValues); | 685 FX_Free(m_pEndValues); |
| 673 } | 686 } |
| 674 FX_BOOL CPDF_ExpIntFunc::v_Init(CPDF_Object* pObj) { | 687 FX_BOOL CPDF_ExpIntFunc::v_Init(CPDF_Object* pObj) { |
| 675 CPDF_Dictionary* pDict = pObj->GetDict(); | 688 CPDF_Dictionary* pDict = pObj->GetDict(); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 702 for (uint32_t i = 0; i < m_nInputs; i++) | 715 for (uint32_t i = 0; i < m_nInputs; i++) |
| 703 for (uint32_t j = 0; j < m_nOrigOutputs; j++) { | 716 for (uint32_t j = 0; j < m_nOrigOutputs; j++) { |
| 704 results[i * m_nOrigOutputs + j] = | 717 results[i * m_nOrigOutputs + j] = |
| 705 m_pBeginValues[j] + | 718 m_pBeginValues[j] + |
| 706 (FX_FLOAT)FXSYS_pow(inputs[i], m_Exponent) * | 719 (FX_FLOAT)FXSYS_pow(inputs[i], m_Exponent) * |
| 707 (m_pEndValues[j] - m_pBeginValues[j]); | 720 (m_pEndValues[j] - m_pBeginValues[j]); |
| 708 } | 721 } |
| 709 return TRUE; | 722 return TRUE; |
| 710 } | 723 } |
| 711 | 724 |
| 712 CPDF_StitchFunc::CPDF_StitchFunc() : CPDF_Function(Type::kType3Stitching) { | 725 CPDF_StitchFunc::CPDF_StitchFunc() { |
| 713 m_pBounds = NULL; | 726 m_pBounds = NULL; |
| 714 m_pEncode = NULL; | 727 m_pEncode = NULL; |
| 715 } | 728 } |
| 716 | 729 |
| 717 CPDF_StitchFunc::~CPDF_StitchFunc() { | 730 CPDF_StitchFunc::~CPDF_StitchFunc() { |
| 718 for (auto& sub : m_pSubFunctions) { | |
| 719 delete sub; | |
| 720 } | |
| 721 FX_Free(m_pBounds); | 731 FX_Free(m_pBounds); |
| 722 FX_Free(m_pEncode); | 732 FX_Free(m_pEncode); |
| 723 } | 733 } |
| 734 |
| 724 FX_BOOL CPDF_StitchFunc::v_Init(CPDF_Object* pObj) { | 735 FX_BOOL CPDF_StitchFunc::v_Init(CPDF_Object* pObj) { |
| 725 CPDF_Dictionary* pDict = pObj->GetDict(); | 736 CPDF_Dictionary* pDict = pObj->GetDict(); |
| 726 if (!pDict) { | 737 if (!pDict) { |
| 727 return FALSE; | 738 return FALSE; |
| 728 } | 739 } |
| 729 if (m_nInputs != kRequiredNumInputs) { | 740 if (m_nInputs != kRequiredNumInputs) { |
| 730 return FALSE; | 741 return FALSE; |
| 731 } | 742 } |
| 732 CPDF_Array* pArray = pDict->GetArrayBy("Functions"); | 743 CPDF_Array* pArray = pDict->GetArrayBy("Functions"); |
| 733 if (!pArray) { | 744 if (!pArray) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 748 // dimensionalities are the same. | 759 // dimensionalities are the same. |
| 749 if (pFunc->CountInputs() != kRequiredNumInputs) | 760 if (pFunc->CountInputs() != kRequiredNumInputs) |
| 750 return FALSE; | 761 return FALSE; |
| 751 if (pFunc->CountOutputs() != m_nOutputs) { | 762 if (pFunc->CountOutputs() != m_nOutputs) { |
| 752 if (m_nOutputs) | 763 if (m_nOutputs) |
| 753 return FALSE; | 764 return FALSE; |
| 754 | 765 |
| 755 m_nOutputs = pFunc->CountOutputs(); | 766 m_nOutputs = pFunc->CountOutputs(); |
| 756 } | 767 } |
| 757 | 768 |
| 758 m_pSubFunctions.push_back(pFunc.release()); | 769 m_pSubFunctions.push_back(std::move(pFunc)); |
| 759 } | 770 } |
| 760 m_pBounds = FX_Alloc(FX_FLOAT, nSubs + 1); | 771 m_pBounds = FX_Alloc(FX_FLOAT, nSubs + 1); |
| 761 m_pBounds[0] = m_pDomains[0]; | 772 m_pBounds[0] = m_pDomains[0]; |
| 762 pArray = pDict->GetArrayBy("Bounds"); | 773 pArray = pDict->GetArrayBy("Bounds"); |
| 763 if (!pArray) | 774 if (!pArray) |
| 764 return FALSE; | 775 return FALSE; |
| 765 for (uint32_t i = 0; i < nSubs - 1; i++) | 776 for (uint32_t i = 0; i < nSubs - 1; i++) |
| 766 m_pBounds[i + 1] = pArray->GetFloatAt(i); | 777 m_pBounds[i + 1] = pArray->GetFloatAt(i); |
| 767 m_pBounds[nSubs] = m_pDomains[1]; | 778 m_pBounds[nSubs] = m_pDomains[1]; |
| 768 m_pEncode = FX_Alloc2D(FX_FLOAT, nSubs, 2); | 779 m_pEncode = FX_Alloc2D(FX_FLOAT, nSubs, 2); |
| 769 pArray = pDict->GetArrayBy("Encode"); | 780 pArray = pDict->GetArrayBy("Encode"); |
| 770 if (!pArray) | 781 if (!pArray) |
| 771 return FALSE; | 782 return FALSE; |
| 772 | 783 |
| 773 for (uint32_t i = 0; i < nSubs * 2; i++) | 784 for (uint32_t i = 0; i < nSubs * 2; i++) |
| 774 m_pEncode[i] = pArray->GetFloatAt(i); | 785 m_pEncode[i] = pArray->GetFloatAt(i); |
| 775 return TRUE; | 786 return TRUE; |
| 776 } | 787 } |
| 788 |
| 777 FX_BOOL CPDF_StitchFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* outputs) const { | 789 FX_BOOL CPDF_StitchFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* outputs) const { |
| 778 FX_FLOAT input = inputs[0]; | 790 FX_FLOAT input = inputs[0]; |
| 779 size_t i; | 791 size_t i; |
| 780 for (i = 0; i < m_pSubFunctions.size() - 1; i++) { | 792 for (i = 0; i < m_pSubFunctions.size() - 1; i++) { |
| 781 if (input < m_pBounds[i + 1]) | 793 if (input < m_pBounds[i + 1]) |
| 782 break; | 794 break; |
| 783 } | 795 } |
| 784 if (!m_pSubFunctions[i]) { | |
| 785 return FALSE; | |
| 786 } | |
| 787 input = PDF_Interpolate(input, m_pBounds[i], m_pBounds[i + 1], | 796 input = PDF_Interpolate(input, m_pBounds[i], m_pBounds[i + 1], |
| 788 m_pEncode[i * 2], m_pEncode[i * 2 + 1]); | 797 m_pEncode[i * 2], m_pEncode[i * 2 + 1]); |
| 789 int nresults; | 798 int nresults; |
| 790 m_pSubFunctions[i]->Call(&input, kRequiredNumInputs, outputs, nresults); | 799 m_pSubFunctions[i]->Call(&input, kRequiredNumInputs, outputs, nresults); |
| 791 return TRUE; | 800 return TRUE; |
| 792 } | 801 } |
| 793 | 802 |
| 803 // static |
| 794 CPDF_Function* CPDF_Function::Load(CPDF_Object* pFuncObj) { | 804 CPDF_Function* CPDF_Function::Load(CPDF_Object* pFuncObj) { |
| 795 if (!pFuncObj) { | 805 if (!pFuncObj) |
| 796 return NULL; | 806 return nullptr; |
| 797 } | 807 |
| 798 int type; | 808 int iType = -1; |
| 799 if (CPDF_Stream* pStream = pFuncObj->AsStream()) { | 809 if (CPDF_Stream* pStream = pFuncObj->AsStream()) |
| 800 type = pStream->GetDict()->GetIntegerBy("FunctionType"); | 810 iType = pStream->GetDict()->GetIntegerBy("FunctionType"); |
| 801 } else if (CPDF_Dictionary* pDict = pFuncObj->AsDictionary()) { | 811 else if (CPDF_Dictionary* pDict = pFuncObj->AsDictionary()) |
| 802 type = pDict->GetIntegerBy("FunctionType"); | 812 iType = pDict->GetIntegerBy("FunctionType"); |
| 803 } else { | 813 |
| 804 return NULL; | 814 Type type = IntegerToFunctionType(iType); |
| 805 } | 815 std::unique_ptr<CPDF_Function> pFunc; |
| 806 CPDF_Function* pFunc = NULL; | 816 if (type == Type::kType0Sampled) |
| 807 if (type == 0) { | 817 pFunc.reset(new CPDF_SampledFunc()); |
| 808 pFunc = new CPDF_SampledFunc(); | 818 else if (type == Type::kType2ExpotentialInterpolation) |
| 809 } else if (type == 2) { | 819 pFunc.reset(new CPDF_ExpIntFunc()); |
| 810 pFunc = new CPDF_ExpIntFunc(); | 820 else if (type == Type::kType3Stitching) |
| 811 } else if (type == 3) { | 821 pFunc.reset(new CPDF_StitchFunc()); |
| 812 pFunc = new CPDF_StitchFunc(); | 822 else if (type == Type::kType4PostScript) |
| 813 } else if (type == 4) { | 823 pFunc.reset(new CPDF_PSFunc()); |
| 814 pFunc = new CPDF_PSFunc(); | 824 |
| 815 } else { | 825 if (!pFunc || !pFunc->Init(pFuncObj)) |
| 816 return NULL; | 826 return nullptr; |
| 817 } | 827 return pFunc.release(); |
| 818 if (!pFunc->Init(pFuncObj)) { | |
| 819 delete pFunc; | |
| 820 return NULL; | |
| 821 } | |
| 822 return pFunc; | |
| 823 } | 828 } |
| 824 | 829 |
| 825 CPDF_Function::CPDF_Function(Type type) : m_Type(type) { | 830 // static |
| 831 CPDF_Function::Type CPDF_Function::IntegerToFunctionType(int iType) { |
| 832 switch (iType) { |
| 833 case 0: |
| 834 case 2: |
| 835 case 3: |
| 836 case 4: |
| 837 return static_cast<Type>(iType); |
| 838 default: |
| 839 return Type::kTypeInvalid; |
| 840 } |
| 841 } |
| 842 |
| 843 CPDF_Function::CPDF_Function() { |
| 826 m_pDomains = NULL; | 844 m_pDomains = NULL; |
| 827 m_pRanges = NULL; | 845 m_pRanges = NULL; |
| 828 } | 846 } |
| 829 | 847 |
| 830 CPDF_Function::~CPDF_Function() { | 848 CPDF_Function::~CPDF_Function() { |
| 831 FX_Free(m_pDomains); | 849 FX_Free(m_pDomains); |
| 832 FX_Free(m_pRanges); | 850 FX_Free(m_pRanges); |
| 833 } | 851 } |
| 852 |
| 834 FX_BOOL CPDF_Function::Init(CPDF_Object* pObj) { | 853 FX_BOOL CPDF_Function::Init(CPDF_Object* pObj) { |
| 835 CPDF_Stream* pStream = pObj->AsStream(); | 854 CPDF_Stream* pStream = pObj->AsStream(); |
| 836 CPDF_Dictionary* pDict = pStream ? pStream->GetDict() : pObj->AsDictionary(); | 855 CPDF_Dictionary* pDict = pStream ? pStream->GetDict() : pObj->AsDictionary(); |
| 837 | 856 |
| 838 CPDF_Array* pDomains = pDict->GetArrayBy("Domain"); | 857 CPDF_Array* pDomains = pDict->GetArrayBy("Domain"); |
| 839 if (!pDomains) | 858 if (!pDomains) |
| 840 return FALSE; | 859 return FALSE; |
| 841 | 860 |
| 842 m_nInputs = pDomains->GetCount() / 2; | 861 m_nInputs = pDomains->GetCount() / 2; |
| 843 if (m_nInputs == 0) | 862 if (m_nInputs == 0) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 860 return FALSE; | 879 return FALSE; |
| 861 if (m_pRanges && m_nOutputs > old_outputs) { | 880 if (m_pRanges && m_nOutputs > old_outputs) { |
| 862 m_pRanges = FX_Realloc(FX_FLOAT, m_pRanges, m_nOutputs * 2); | 881 m_pRanges = FX_Realloc(FX_FLOAT, m_pRanges, m_nOutputs * 2); |
| 863 if (m_pRanges) { | 882 if (m_pRanges) { |
| 864 FXSYS_memset(m_pRanges + (old_outputs * 2), 0, | 883 FXSYS_memset(m_pRanges + (old_outputs * 2), 0, |
| 865 sizeof(FX_FLOAT) * (m_nOutputs - old_outputs) * 2); | 884 sizeof(FX_FLOAT) * (m_nOutputs - old_outputs) * 2); |
| 866 } | 885 } |
| 867 } | 886 } |
| 868 return TRUE; | 887 return TRUE; |
| 869 } | 888 } |
| 889 |
| 870 FX_BOOL CPDF_Function::Call(FX_FLOAT* inputs, | 890 FX_BOOL CPDF_Function::Call(FX_FLOAT* inputs, |
| 871 uint32_t ninputs, | 891 uint32_t ninputs, |
| 872 FX_FLOAT* results, | 892 FX_FLOAT* results, |
| 873 int& nresults) const { | 893 int& nresults) const { |
| 874 if (m_nInputs != ninputs) { | 894 if (m_nInputs != ninputs) { |
| 875 return FALSE; | 895 return FALSE; |
| 876 } | 896 } |
| 877 nresults = m_nOutputs; | 897 nresults = m_nOutputs; |
| 878 for (uint32_t i = 0; i < m_nInputs; i++) { | 898 for (uint32_t i = 0; i < m_nInputs; i++) { |
| 879 if (inputs[i] < m_pDomains[i * 2]) | 899 if (inputs[i] < m_pDomains[i * 2]) |
| 880 inputs[i] = m_pDomains[i * 2]; | 900 inputs[i] = m_pDomains[i * 2]; |
| 881 else if (inputs[i] > m_pDomains[i * 2 + 1]) | 901 else if (inputs[i] > m_pDomains[i * 2 + 1]) |
| 882 inputs[i] = m_pDomains[i * 2] + 1; | 902 inputs[i] = m_pDomains[i * 2] + 1; |
| 883 } | 903 } |
| 884 v_Call(inputs, results); | 904 v_Call(inputs, results); |
| 885 if (m_pRanges) { | 905 if (m_pRanges) { |
| 886 for (uint32_t i = 0; i < m_nOutputs; i++) { | 906 for (uint32_t i = 0; i < m_nOutputs; i++) { |
| 887 if (results[i] < m_pRanges[i * 2]) | 907 if (results[i] < m_pRanges[i * 2]) |
| 888 results[i] = m_pRanges[i * 2]; | 908 results[i] = m_pRanges[i * 2]; |
| 889 else if (results[i] > m_pRanges[i * 2 + 1]) | 909 else if (results[i] > m_pRanges[i * 2 + 1]) |
| 890 results[i] = m_pRanges[i * 2 + 1]; | 910 results[i] = m_pRanges[i * 2 + 1]; |
| 891 } | 911 } |
| 892 } | 912 } |
| 893 return TRUE; | 913 return TRUE; |
| 894 } | 914 } |
| OLD | NEW |