Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(456)

Side by Side Diff: core/fpdfapi/fpdf_page/fpdf_page_func.cpp

Issue 1990843004: Fix Undefined-shift in CPDF_SampledFunc::v_Init(). (Closed) Base URL: https://pdfium.googlesource.com/pdfium@master
Patch Set: rebase Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | core/fpdfapi/fpdf_page/pageint.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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;
Tom Sepez 2016/05/19 21:31:46 nit: I'd be tempted to write >> (32 - m_nBitsPerSa
Lei Zhang 2016/05/19 21:58:23 Whoops. Sadness.
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | core/fpdfapi/fpdf_page/pageint.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698