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 |