| 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 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 } | 483 } |
| 484 return TRUE; | 484 return TRUE; |
| 485 } | 485 } |
| 486 static FX_FLOAT PDF_Interpolate(FX_FLOAT x, | 486 static FX_FLOAT PDF_Interpolate(FX_FLOAT x, |
| 487 FX_FLOAT xmin, | 487 FX_FLOAT xmin, |
| 488 FX_FLOAT xmax, | 488 FX_FLOAT xmax, |
| 489 FX_FLOAT ymin, | 489 FX_FLOAT ymin, |
| 490 FX_FLOAT ymax) { | 490 FX_FLOAT ymax) { |
| 491 return ((x - xmin) * (ymax - ymin) / (xmax - xmin)) + ymin; | 491 return ((x - xmin) * (ymax - ymin) / (xmax - xmin)) + ymin; |
| 492 } | 492 } |
| 493 static FX_DWORD _GetBits32(const uint8_t* pData, int bitpos, int nbits) { | 493 static uint32_t _GetBits32(const uint8_t* pData, int bitpos, int nbits) { |
| 494 int result = 0; | 494 int result = 0; |
| 495 for (int i = 0; i < nbits; i++) | 495 for (int i = 0; i < nbits; i++) |
| 496 if (pData[(bitpos + i) / 8] & (1 << (7 - (bitpos + i) % 8))) { | 496 if (pData[(bitpos + i) / 8] & (1 << (7 - (bitpos + i) % 8))) { |
| 497 result |= 1 << (nbits - i - 1); | 497 result |= 1 << (nbits - i - 1); |
| 498 } | 498 } |
| 499 return result; | 499 return result; |
| 500 } | 500 } |
| 501 typedef struct { | 501 typedef struct { |
| 502 FX_FLOAT encode_max, encode_min; | 502 FX_FLOAT encode_max, encode_min; |
| 503 int sizes; | 503 int sizes; |
| 504 } SampleEncodeInfo; | 504 } SampleEncodeInfo; |
| 505 typedef struct { FX_FLOAT decode_max, decode_min; } SampleDecodeInfo; | 505 typedef struct { FX_FLOAT decode_max, decode_min; } SampleDecodeInfo; |
| 506 | 506 |
| 507 class CPDF_SampledFunc : public CPDF_Function { | 507 class CPDF_SampledFunc : public CPDF_Function { |
| 508 public: | 508 public: |
| 509 CPDF_SampledFunc(); | 509 CPDF_SampledFunc(); |
| 510 ~CPDF_SampledFunc() override; | 510 ~CPDF_SampledFunc() override; |
| 511 | 511 |
| 512 // CPDF_Function | 512 // CPDF_Function |
| 513 FX_BOOL v_Init(CPDF_Object* pObj) override; | 513 FX_BOOL v_Init(CPDF_Object* pObj) override; |
| 514 FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override; | 514 FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override; |
| 515 | 515 |
| 516 SampleEncodeInfo* m_pEncodeInfo; | 516 SampleEncodeInfo* m_pEncodeInfo; |
| 517 SampleDecodeInfo* m_pDecodeInfo; | 517 SampleDecodeInfo* m_pDecodeInfo; |
| 518 FX_DWORD m_nBitsPerSample; | 518 uint32_t m_nBitsPerSample; |
| 519 FX_DWORD m_SampleMax; | 519 uint32_t m_SampleMax; |
| 520 CPDF_StreamAcc* m_pSampleStream; | 520 CPDF_StreamAcc* m_pSampleStream; |
| 521 }; | 521 }; |
| 522 | 522 |
| 523 CPDF_SampledFunc::CPDF_SampledFunc() : CPDF_Function(Type::kType0Sampled) { | 523 CPDF_SampledFunc::CPDF_SampledFunc() : CPDF_Function(Type::kType0Sampled) { |
| 524 m_pSampleStream = NULL; | 524 m_pSampleStream = NULL; |
| 525 m_pEncodeInfo = NULL; | 525 m_pEncodeInfo = NULL; |
| 526 m_pDecodeInfo = NULL; | 526 m_pDecodeInfo = NULL; |
| 527 } | 527 } |
| 528 | 528 |
| 529 CPDF_SampledFunc::~CPDF_SampledFunc() { | 529 CPDF_SampledFunc::~CPDF_SampledFunc() { |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 FX_SAFE_INT32 range_check = bitpos; | 625 FX_SAFE_INT32 range_check = bitpos; |
| 626 range_check += bits_to_output.ValueOrDie(); | 626 range_check += bits_to_output.ValueOrDie(); |
| 627 if (!range_check.IsValid()) { | 627 if (!range_check.IsValid()) { |
| 628 return FALSE; | 628 return FALSE; |
| 629 } | 629 } |
| 630 const uint8_t* pSampleData = m_pSampleStream->GetData(); | 630 const uint8_t* pSampleData = m_pSampleStream->GetData(); |
| 631 if (!pSampleData) { | 631 if (!pSampleData) { |
| 632 return FALSE; | 632 return FALSE; |
| 633 } | 633 } |
| 634 for (int j = 0; j < m_nOutputs; j++) { | 634 for (int j = 0; j < m_nOutputs; j++) { |
| 635 FX_DWORD sample = | 635 uint32_t sample = |
| 636 _GetBits32(pSampleData, bitpos.ValueOrDie() + j * m_nBitsPerSample, | 636 _GetBits32(pSampleData, bitpos.ValueOrDie() + j * m_nBitsPerSample, |
| 637 m_nBitsPerSample); | 637 m_nBitsPerSample); |
| 638 FX_FLOAT encoded = (FX_FLOAT)sample; | 638 FX_FLOAT encoded = (FX_FLOAT)sample; |
| 639 for (int i = 0; i < m_nInputs; i++) { | 639 for (int i = 0; i < m_nInputs; i++) { |
| 640 if (index[i] == m_pEncodeInfo[i].sizes - 1) { | 640 if (index[i] == m_pEncodeInfo[i].sizes - 1) { |
| 641 if (index[i] == 0) { | 641 if (index[i] == 0) { |
| 642 encoded = encoded_input[i] * (FX_FLOAT)sample; | 642 encoded = encoded_input[i] * (FX_FLOAT)sample; |
| 643 } | 643 } |
| 644 } else { | 644 } else { |
| 645 FX_SAFE_INT32 bitpos2 = blocksize[i]; | 645 FX_SAFE_INT32 bitpos2 = blocksize[i]; |
| 646 bitpos2 += pos; | 646 bitpos2 += pos; |
| 647 bitpos2 *= m_nOutputs; | 647 bitpos2 *= m_nOutputs; |
| 648 bitpos2 += j; | 648 bitpos2 += j; |
| 649 bitpos2 *= m_nBitsPerSample; | 649 bitpos2 *= m_nBitsPerSample; |
| 650 if (!bitpos2.IsValid()) { | 650 if (!bitpos2.IsValid()) { |
| 651 return FALSE; | 651 return FALSE; |
| 652 } | 652 } |
| 653 FX_DWORD sample1 = | 653 uint32_t sample1 = |
| 654 _GetBits32(pSampleData, bitpos2.ValueOrDie(), m_nBitsPerSample); | 654 _GetBits32(pSampleData, bitpos2.ValueOrDie(), m_nBitsPerSample); |
| 655 encoded += (encoded_input[i] - index[i]) * | 655 encoded += (encoded_input[i] - index[i]) * |
| 656 ((FX_FLOAT)sample1 - (FX_FLOAT)sample); | 656 ((FX_FLOAT)sample1 - (FX_FLOAT)sample); |
| 657 } | 657 } |
| 658 } | 658 } |
| 659 results[j] = PDF_Interpolate(encoded, 0, (FX_FLOAT)m_SampleMax, | 659 results[j] = PDF_Interpolate(encoded, 0, (FX_FLOAT)m_SampleMax, |
| 660 m_pDecodeInfo[j].decode_min, | 660 m_pDecodeInfo[j].decode_min, |
| 661 m_pDecodeInfo[j].decode_max); | 661 m_pDecodeInfo[j].decode_max); |
| 662 } | 662 } |
| 663 return TRUE; | 663 return TRUE; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 763 if (!pDict) { | 763 if (!pDict) { |
| 764 return FALSE; | 764 return FALSE; |
| 765 } | 765 } |
| 766 if (m_nInputs != kRequiredNumInputs) { | 766 if (m_nInputs != kRequiredNumInputs) { |
| 767 return FALSE; | 767 return FALSE; |
| 768 } | 768 } |
| 769 CPDF_Array* pArray = pDict->GetArrayBy("Functions"); | 769 CPDF_Array* pArray = pDict->GetArrayBy("Functions"); |
| 770 if (!pArray) { | 770 if (!pArray) { |
| 771 return FALSE; | 771 return FALSE; |
| 772 } | 772 } |
| 773 FX_DWORD nSubs = pArray->GetCount(); | 773 uint32_t nSubs = pArray->GetCount(); |
| 774 if (nSubs == 0) { | 774 if (nSubs == 0) { |
| 775 return FALSE; | 775 return FALSE; |
| 776 } | 776 } |
| 777 m_nOutputs = 0; | 777 m_nOutputs = 0; |
| 778 for (FX_DWORD i = 0; i < nSubs; i++) { | 778 for (uint32_t i = 0; i < nSubs; i++) { |
| 779 CPDF_Object* pSub = pArray->GetElementValue(i); | 779 CPDF_Object* pSub = pArray->GetElementValue(i); |
| 780 if (pSub == pObj) { | 780 if (pSub == pObj) { |
| 781 return FALSE; | 781 return FALSE; |
| 782 } | 782 } |
| 783 std::unique_ptr<CPDF_Function> pFunc(CPDF_Function::Load(pSub)); | 783 std::unique_ptr<CPDF_Function> pFunc(CPDF_Function::Load(pSub)); |
| 784 if (!pFunc) { | 784 if (!pFunc) { |
| 785 return FALSE; | 785 return FALSE; |
| 786 } | 786 } |
| 787 // Check that the input dimensionality is 1, and that all output | 787 // Check that the input dimensionality is 1, and that all output |
| 788 // dimensionalities are the same. | 788 // dimensionalities are the same. |
| 789 if (pFunc->CountInputs() != kRequiredNumInputs) { | 789 if (pFunc->CountInputs() != kRequiredNumInputs) { |
| 790 return FALSE; | 790 return FALSE; |
| 791 } | 791 } |
| 792 if (pFunc->CountOutputs() != m_nOutputs) { | 792 if (pFunc->CountOutputs() != m_nOutputs) { |
| 793 if (m_nOutputs) | 793 if (m_nOutputs) |
| 794 return FALSE; | 794 return FALSE; |
| 795 | 795 |
| 796 m_nOutputs = pFunc->CountOutputs(); | 796 m_nOutputs = pFunc->CountOutputs(); |
| 797 } | 797 } |
| 798 | 798 |
| 799 m_pSubFunctions.push_back(pFunc.release()); | 799 m_pSubFunctions.push_back(pFunc.release()); |
| 800 } | 800 } |
| 801 m_pBounds = FX_Alloc(FX_FLOAT, nSubs + 1); | 801 m_pBounds = FX_Alloc(FX_FLOAT, nSubs + 1); |
| 802 m_pBounds[0] = m_pDomains[0]; | 802 m_pBounds[0] = m_pDomains[0]; |
| 803 pArray = pDict->GetArrayBy("Bounds"); | 803 pArray = pDict->GetArrayBy("Bounds"); |
| 804 if (!pArray) { | 804 if (!pArray) { |
| 805 return FALSE; | 805 return FALSE; |
| 806 } | 806 } |
| 807 for (FX_DWORD i = 0; i < nSubs - 1; i++) { | 807 for (uint32_t i = 0; i < nSubs - 1; i++) { |
| 808 m_pBounds[i + 1] = pArray->GetFloatAt(i); | 808 m_pBounds[i + 1] = pArray->GetFloatAt(i); |
| 809 } | 809 } |
| 810 m_pBounds[nSubs] = m_pDomains[1]; | 810 m_pBounds[nSubs] = m_pDomains[1]; |
| 811 m_pEncode = FX_Alloc2D(FX_FLOAT, nSubs, 2); | 811 m_pEncode = FX_Alloc2D(FX_FLOAT, nSubs, 2); |
| 812 pArray = pDict->GetArrayBy("Encode"); | 812 pArray = pDict->GetArrayBy("Encode"); |
| 813 if (!pArray) { | 813 if (!pArray) { |
| 814 return FALSE; | 814 return FALSE; |
| 815 } | 815 } |
| 816 for (FX_DWORD i = 0; i < nSubs * 2; i++) { | 816 for (uint32_t i = 0; i < nSubs * 2; i++) { |
| 817 m_pEncode[i] = pArray->GetFloatAt(i); | 817 m_pEncode[i] = pArray->GetFloatAt(i); |
| 818 } | 818 } |
| 819 return TRUE; | 819 return TRUE; |
| 820 } | 820 } |
| 821 FX_BOOL CPDF_StitchFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* outputs) const { | 821 FX_BOOL CPDF_StitchFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* outputs) const { |
| 822 FX_FLOAT input = inputs[0]; | 822 FX_FLOAT input = inputs[0]; |
| 823 size_t i; | 823 size_t i; |
| 824 for (i = 0; i < m_pSubFunctions.size() - 1; i++) | 824 for (i = 0; i < m_pSubFunctions.size() - 1; i++) |
| 825 if (input < m_pBounds[i + 1]) { | 825 if (input < m_pBounds[i + 1]) { |
| 826 break; | 826 break; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 893 } | 893 } |
| 894 CPDF_Array* pRanges = pDict->GetArrayBy("Range"); | 894 CPDF_Array* pRanges = pDict->GetArrayBy("Range"); |
| 895 m_nOutputs = 0; | 895 m_nOutputs = 0; |
| 896 if (pRanges) { | 896 if (pRanges) { |
| 897 m_nOutputs = pRanges->GetCount() / 2; | 897 m_nOutputs = pRanges->GetCount() / 2; |
| 898 m_pRanges = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2); | 898 m_pRanges = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2); |
| 899 for (int i = 0; i < m_nOutputs * 2; i++) { | 899 for (int i = 0; i < m_nOutputs * 2; i++) { |
| 900 m_pRanges[i] = pRanges->GetFloatAt(i); | 900 m_pRanges[i] = pRanges->GetFloatAt(i); |
| 901 } | 901 } |
| 902 } | 902 } |
| 903 FX_DWORD old_outputs = m_nOutputs; | 903 uint32_t old_outputs = m_nOutputs; |
| 904 if (!v_Init(pObj)) { | 904 if (!v_Init(pObj)) { |
| 905 return FALSE; | 905 return FALSE; |
| 906 } | 906 } |
| 907 if (m_pRanges && m_nOutputs > (int)old_outputs) { | 907 if (m_pRanges && m_nOutputs > (int)old_outputs) { |
| 908 m_pRanges = FX_Realloc(FX_FLOAT, m_pRanges, m_nOutputs * 2); | 908 m_pRanges = FX_Realloc(FX_FLOAT, m_pRanges, m_nOutputs * 2); |
| 909 if (m_pRanges) { | 909 if (m_pRanges) { |
| 910 FXSYS_memset(m_pRanges + (old_outputs * 2), 0, | 910 FXSYS_memset(m_pRanges + (old_outputs * 2), 0, |
| 911 sizeof(FX_FLOAT) * (m_nOutputs - old_outputs) * 2); | 911 sizeof(FX_FLOAT) * (m_nOutputs - old_outputs) * 2); |
| 912 } | 912 } |
| 913 } | 913 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 933 for (int i = 0; i < m_nOutputs; i++) { | 933 for (int i = 0; i < m_nOutputs; i++) { |
| 934 if (results[i] < m_pRanges[i * 2]) { | 934 if (results[i] < m_pRanges[i * 2]) { |
| 935 results[i] = m_pRanges[i * 2]; | 935 results[i] = m_pRanges[i * 2]; |
| 936 } else if (results[i] > m_pRanges[i * 2 + 1]) { | 936 } else if (results[i] > m_pRanges[i * 2 + 1]) { |
| 937 results[i] = m_pRanges[i * 2 + 1]; | 937 results[i] = m_pRanges[i * 2 + 1]; |
| 938 } | 938 } |
| 939 } | 939 } |
| 940 } | 940 } |
| 941 return TRUE; | 941 return TRUE; |
| 942 } | 942 } |
| OLD | NEW |