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

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: Fix bug 596530 as well 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) {
Tom Sepez 2016/05/19 16:53:40 This has got to be mind-numbingly slow, consider m
Lei Zhang 2016/05/19 21:16:19 Ack. Will merge with the fx_skia_device.cpp copy i
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 =
554 m_pSampleStream = new CPDF_StreamAcc; 569 0xffffffff >> (m_nBitsPerSample == 32 ? 0 : 32 - m_nBitsPerSample);
Tom Sepez 2016/05/19 16:58:48 Not groking why we need the ? operator, isn't 32 -
Lei Zhang 2016/05/19 21:16:19 Uh, I'm being silly. It was the m_nBitsPerSample =
570 m_pSampleStream.reset(new CPDF_StreamAcc);
555 m_pSampleStream->LoadAllData(pStream, FALSE); 571 m_pSampleStream->LoadAllData(pStream, FALSE);
556 m_pEncodeInfo = FX_Alloc(SampleEncodeInfo, m_nInputs);
557 FX_SAFE_UINT32 nTotalSampleBits = 1; 572 FX_SAFE_UINT32 nTotalSampleBits = 1;
573 m_pEncodeInfo.resize(m_nInputs);
558 for (uint32_t i = 0; i < m_nInputs; i++) { 574 for (uint32_t i = 0; i < m_nInputs; i++) {
559 m_pEncodeInfo[i].sizes = pSize ? pSize->GetIntegerAt(i) : 0; 575 m_pEncodeInfo[i].sizes = pSize ? pSize->GetIntegerAt(i) : 0;
560 if (!pSize && i == 0) 576 if (!pSize && i == 0)
561 m_pEncodeInfo[i].sizes = pDict->GetIntegerBy("Size"); 577 m_pEncodeInfo[i].sizes = pDict->GetIntegerBy("Size");
562 nTotalSampleBits *= m_pEncodeInfo[i].sizes; 578 nTotalSampleBits *= m_pEncodeInfo[i].sizes;
563 if (pEncode) { 579 if (pEncode) {
564 m_pEncodeInfo[i].encode_min = pEncode->GetFloatAt(i * 2); 580 m_pEncodeInfo[i].encode_min = pEncode->GetFloatAt(i * 2);
565 m_pEncodeInfo[i].encode_max = pEncode->GetFloatAt(i * 2 + 1); 581 m_pEncodeInfo[i].encode_max = pEncode->GetFloatAt(i * 2 + 1);
566 } else { 582 } else {
567 m_pEncodeInfo[i].encode_min = 0; 583 m_pEncodeInfo[i].encode_min = 0;
568 if (m_pEncodeInfo[i].sizes == 1) 584 m_pEncodeInfo[i].encode_max = m_pEncodeInfo[i].sizes == 1
569 m_pEncodeInfo[i].encode_max = 1; 585 ? 1
570 else 586 : (FX_FLOAT)m_pEncodeInfo[i].sizes - 1;
571 m_pEncodeInfo[i].encode_max = (FX_FLOAT)m_pEncodeInfo[i].sizes - 1;
572 } 587 }
573 } 588 }
574 nTotalSampleBits *= m_nBitsPerSample; 589 nTotalSampleBits *= m_nBitsPerSample;
575 nTotalSampleBits *= m_nOutputs; 590 nTotalSampleBits *= m_nOutputs;
576 FX_SAFE_UINT32 nTotalSampleBytes = nTotalSampleBits; 591 FX_SAFE_UINT32 nTotalSampleBytes = nTotalSampleBits;
577 nTotalSampleBytes += 7; 592 nTotalSampleBytes += 7;
578 nTotalSampleBytes /= 8; 593 nTotalSampleBytes /= 8;
579 if (!nTotalSampleBytes.IsValid() || nTotalSampleBytes.ValueOrDie() == 0 || 594 if (!nTotalSampleBytes.IsValid() || nTotalSampleBytes.ValueOrDie() == 0 ||
580 nTotalSampleBytes.ValueOrDie() > m_pSampleStream->GetSize()) { 595 nTotalSampleBytes.ValueOrDie() > m_pSampleStream->GetSize()) {
581 return FALSE; 596 return FALSE;
582 } 597 }
583 m_pDecodeInfo = FX_Alloc(SampleDecodeInfo, m_nOutputs); 598 m_pDecodeInfo.resize(m_nOutputs);
584 for (uint32_t i = 0; i < m_nOutputs; i++) { 599 for (uint32_t i = 0; i < m_nOutputs; i++) {
585 if (pDecode) { 600 if (pDecode) {
586 m_pDecodeInfo[i].decode_min = pDecode->GetFloatAt(2 * i); 601 m_pDecodeInfo[i].decode_min = pDecode->GetFloatAt(2 * i);
587 m_pDecodeInfo[i].decode_max = pDecode->GetFloatAt(2 * i + 1); 602 m_pDecodeInfo[i].decode_max = pDecode->GetFloatAt(2 * i + 1);
588 } else { 603 } else {
589 m_pDecodeInfo[i].decode_min = m_pRanges[i * 2]; 604 m_pDecodeInfo[i].decode_min = m_pRanges[i * 2];
590 m_pDecodeInfo[i].decode_max = m_pRanges[i * 2 + 1]; 605 m_pDecodeInfo[i].decode_max = m_pRanges[i * 2 + 1];
591 } 606 }
592 } 607 }
593 return TRUE; 608 return TRUE;
(...skipping 13 matching lines...) Expand all
607 blocksize[i] = blocksize[i - 1] * m_pEncodeInfo[i - 1].sizes; 622 blocksize[i] = blocksize[i - 1] * m_pEncodeInfo[i - 1].sizes;
608 encoded_input[i] = PDF_Interpolate( 623 encoded_input[i] = PDF_Interpolate(
609 inputs[i], m_pDomains[i * 2], m_pDomains[i * 2 + 1], 624 inputs[i], m_pDomains[i * 2], m_pDomains[i * 2 + 1],
610 m_pEncodeInfo[i].encode_min, m_pEncodeInfo[i].encode_max); 625 m_pEncodeInfo[i].encode_min, m_pEncodeInfo[i].encode_max);
611 index[i] = std::min((uint32_t)std::max(0.f, encoded_input[i]), 626 index[i] = std::min((uint32_t)std::max(0.f, encoded_input[i]),
612 m_pEncodeInfo[i].sizes - 1); 627 m_pEncodeInfo[i].sizes - 1);
613 pos += index[i] * blocksize[i]; 628 pos += index[i] * blocksize[i];
614 } 629 }
615 FX_SAFE_INT32 bits_to_output = m_nOutputs; 630 FX_SAFE_INT32 bits_to_output = m_nOutputs;
616 bits_to_output *= m_nBitsPerSample; 631 bits_to_output *= m_nBitsPerSample;
617 if (!bits_to_output.IsValid()) { 632 if (!bits_to_output.IsValid())
618 return FALSE; 633 return FALSE;
619 } 634
620 FX_SAFE_INT32 bitpos = pos; 635 FX_SAFE_INT32 bitpos = pos;
621 bitpos *= bits_to_output.ValueOrDie(); 636 bitpos *= bits_to_output.ValueOrDie();
622 if (!bitpos.IsValid()) { 637 if (!bitpos.IsValid())
623 return FALSE; 638 return FALSE;
624 } 639
625 FX_SAFE_INT32 range_check = bitpos; 640 FX_SAFE_INT32 range_check = bitpos;
626 range_check += bits_to_output.ValueOrDie(); 641 range_check += bits_to_output.ValueOrDie();
627 if (!range_check.IsValid()) { 642 if (!range_check.IsValid())
628 return FALSE; 643 return FALSE;
629 } 644
630 const uint8_t* pSampleData = m_pSampleStream->GetData(); 645 const uint8_t* pSampleData = m_pSampleStream->GetData();
631 if (!pSampleData) { 646 if (!pSampleData)
632 return FALSE; 647 return FALSE;
633 } 648
634 for (uint32_t j = 0; j < m_nOutputs; j++) { 649 for (uint32_t j = 0; j < m_nOutputs; j++) {
635 uint32_t sample = 650 uint32_t sample =
636 _GetBits32(pSampleData, bitpos.ValueOrDie() + j * m_nBitsPerSample, 651 GetBits32(pSampleData, bitpos.ValueOrDie() + j * m_nBitsPerSample,
637 m_nBitsPerSample); 652 m_nBitsPerSample);
638 FX_FLOAT encoded = (FX_FLOAT)sample; 653 FX_FLOAT encoded = (FX_FLOAT)sample;
639 for (uint32_t i = 0; i < m_nInputs; i++) { 654 for (uint32_t i = 0; i < m_nInputs; i++) {
640 if (index[i] == m_pEncodeInfo[i].sizes - 1) { 655 if (index[i] == m_pEncodeInfo[i].sizes - 1) {
641 if (index[i] == 0) 656 if (index[i] == 0)
642 encoded = encoded_input[i] * (FX_FLOAT)sample; 657 encoded = encoded_input[i] * (FX_FLOAT)sample;
643 } else { 658 } else {
644 FX_SAFE_INT32 bitpos2 = blocksize[i]; 659 FX_SAFE_INT32 bitpos2 = blocksize[i];
645 bitpos2 += pos; 660 bitpos2 += pos;
646 bitpos2 *= m_nOutputs; 661 bitpos2 *= m_nOutputs;
647 bitpos2 += j; 662 bitpos2 += j;
648 bitpos2 *= m_nBitsPerSample; 663 bitpos2 *= m_nBitsPerSample;
649 if (!bitpos2.IsValid()) 664 if (!bitpos2.IsValid())
650 return FALSE; 665 return FALSE;
651 uint32_t sample1 = 666 uint32_t sample1 =
652 _GetBits32(pSampleData, bitpos2.ValueOrDie(), m_nBitsPerSample); 667 GetBits32(pSampleData, bitpos2.ValueOrDie(), m_nBitsPerSample);
653 encoded += (encoded_input[i] - index[i]) * 668 encoded += (encoded_input[i] - index[i]) *
654 ((FX_FLOAT)sample1 - (FX_FLOAT)sample); 669 ((FX_FLOAT)sample1 - (FX_FLOAT)sample);
655 } 670 }
656 } 671 }
657 results[j] = PDF_Interpolate(encoded, 0, (FX_FLOAT)m_SampleMax, 672 results[j] = PDF_Interpolate(encoded, 0, (FX_FLOAT)m_SampleMax,
658 m_pDecodeInfo[j].decode_min, 673 m_pDecodeInfo[j].decode_min,
659 m_pDecodeInfo[j].decode_max); 674 m_pDecodeInfo[j].decode_max);
660 } 675 }
661 return TRUE; 676 return TRUE;
662 } 677 }
663 678
664 CPDF_ExpIntFunc::CPDF_ExpIntFunc() 679 CPDF_ExpIntFunc::CPDF_ExpIntFunc() {
665 : CPDF_Function(Type::kType2ExpotentialInterpolation) {
666 m_pBeginValues = NULL; 680 m_pBeginValues = NULL;
667 m_pEndValues = NULL; 681 m_pEndValues = NULL;
668 } 682 }
669 683
670 CPDF_ExpIntFunc::~CPDF_ExpIntFunc() { 684 CPDF_ExpIntFunc::~CPDF_ExpIntFunc() {
671 FX_Free(m_pBeginValues); 685 FX_Free(m_pBeginValues);
672 FX_Free(m_pEndValues); 686 FX_Free(m_pEndValues);
673 } 687 }
674 FX_BOOL CPDF_ExpIntFunc::v_Init(CPDF_Object* pObj) { 688 FX_BOOL CPDF_ExpIntFunc::v_Init(CPDF_Object* pObj) {
675 CPDF_Dictionary* pDict = pObj->GetDict(); 689 CPDF_Dictionary* pDict = pObj->GetDict();
(...skipping 26 matching lines...) Expand all
702 for (uint32_t i = 0; i < m_nInputs; i++) 716 for (uint32_t i = 0; i < m_nInputs; i++)
703 for (uint32_t j = 0; j < m_nOrigOutputs; j++) { 717 for (uint32_t j = 0; j < m_nOrigOutputs; j++) {
704 results[i * m_nOrigOutputs + j] = 718 results[i * m_nOrigOutputs + j] =
705 m_pBeginValues[j] + 719 m_pBeginValues[j] +
706 (FX_FLOAT)FXSYS_pow(inputs[i], m_Exponent) * 720 (FX_FLOAT)FXSYS_pow(inputs[i], m_Exponent) *
707 (m_pEndValues[j] - m_pBeginValues[j]); 721 (m_pEndValues[j] - m_pBeginValues[j]);
708 } 722 }
709 return TRUE; 723 return TRUE;
710 } 724 }
711 725
712 CPDF_StitchFunc::CPDF_StitchFunc() : CPDF_Function(Type::kType3Stitching) { 726 CPDF_StitchFunc::CPDF_StitchFunc() {
713 m_pBounds = NULL; 727 m_pBounds = NULL;
714 m_pEncode = NULL; 728 m_pEncode = NULL;
715 } 729 }
716 730
717 CPDF_StitchFunc::~CPDF_StitchFunc() { 731 CPDF_StitchFunc::~CPDF_StitchFunc() {
718 for (auto& sub : m_pSubFunctions) {
719 delete sub;
720 }
721 FX_Free(m_pBounds); 732 FX_Free(m_pBounds);
722 FX_Free(m_pEncode); 733 FX_Free(m_pEncode);
723 } 734 }
735
724 FX_BOOL CPDF_StitchFunc::v_Init(CPDF_Object* pObj) { 736 FX_BOOL CPDF_StitchFunc::v_Init(CPDF_Object* pObj) {
725 CPDF_Dictionary* pDict = pObj->GetDict(); 737 CPDF_Dictionary* pDict = pObj->GetDict();
726 if (!pDict) { 738 if (!pDict) {
727 return FALSE; 739 return FALSE;
728 } 740 }
729 if (m_nInputs != kRequiredNumInputs) { 741 if (m_nInputs != kRequiredNumInputs) {
730 return FALSE; 742 return FALSE;
731 } 743 }
732 CPDF_Array* pArray = pDict->GetArrayBy("Functions"); 744 CPDF_Array* pArray = pDict->GetArrayBy("Functions");
733 if (!pArray) { 745 if (!pArray) {
(...skipping 14 matching lines...) Expand all
748 // dimensionalities are the same. 760 // dimensionalities are the same.
749 if (pFunc->CountInputs() != kRequiredNumInputs) 761 if (pFunc->CountInputs() != kRequiredNumInputs)
750 return FALSE; 762 return FALSE;
751 if (pFunc->CountOutputs() != m_nOutputs) { 763 if (pFunc->CountOutputs() != m_nOutputs) {
752 if (m_nOutputs) 764 if (m_nOutputs)
753 return FALSE; 765 return FALSE;
754 766
755 m_nOutputs = pFunc->CountOutputs(); 767 m_nOutputs = pFunc->CountOutputs();
756 } 768 }
757 769
758 m_pSubFunctions.push_back(pFunc.release()); 770 m_pSubFunctions.push_back(std::move(pFunc));
759 } 771 }
760 m_pBounds = FX_Alloc(FX_FLOAT, nSubs + 1); 772 m_pBounds = FX_Alloc(FX_FLOAT, nSubs + 1);
761 m_pBounds[0] = m_pDomains[0]; 773 m_pBounds[0] = m_pDomains[0];
762 pArray = pDict->GetArrayBy("Bounds"); 774 pArray = pDict->GetArrayBy("Bounds");
763 if (!pArray) 775 if (!pArray)
764 return FALSE; 776 return FALSE;
765 for (uint32_t i = 0; i < nSubs - 1; i++) 777 for (uint32_t i = 0; i < nSubs - 1; i++)
766 m_pBounds[i + 1] = pArray->GetFloatAt(i); 778 m_pBounds[i + 1] = pArray->GetFloatAt(i);
767 m_pBounds[nSubs] = m_pDomains[1]; 779 m_pBounds[nSubs] = m_pDomains[1];
768 m_pEncode = FX_Alloc2D(FX_FLOAT, nSubs, 2); 780 m_pEncode = FX_Alloc2D(FX_FLOAT, nSubs, 2);
769 pArray = pDict->GetArrayBy("Encode"); 781 pArray = pDict->GetArrayBy("Encode");
770 if (!pArray) 782 if (!pArray)
771 return FALSE; 783 return FALSE;
772 784
773 for (uint32_t i = 0; i < nSubs * 2; i++) 785 for (uint32_t i = 0; i < nSubs * 2; i++)
774 m_pEncode[i] = pArray->GetFloatAt(i); 786 m_pEncode[i] = pArray->GetFloatAt(i);
775 return TRUE; 787 return TRUE;
776 } 788 }
789
777 FX_BOOL CPDF_StitchFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* outputs) const { 790 FX_BOOL CPDF_StitchFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* outputs) const {
778 FX_FLOAT input = inputs[0]; 791 FX_FLOAT input = inputs[0];
779 size_t i; 792 size_t i;
780 for (i = 0; i < m_pSubFunctions.size() - 1; i++) { 793 for (i = 0; i < m_pSubFunctions.size() - 1; i++) {
781 if (input < m_pBounds[i + 1]) 794 if (input < m_pBounds[i + 1])
782 break; 795 break;
783 } 796 }
784 if (!m_pSubFunctions[i]) {
785 return FALSE;
786 }
787 input = PDF_Interpolate(input, m_pBounds[i], m_pBounds[i + 1], 797 input = PDF_Interpolate(input, m_pBounds[i], m_pBounds[i + 1],
788 m_pEncode[i * 2], m_pEncode[i * 2 + 1]); 798 m_pEncode[i * 2], m_pEncode[i * 2 + 1]);
789 int nresults; 799 int nresults;
790 m_pSubFunctions[i]->Call(&input, kRequiredNumInputs, outputs, nresults); 800 m_pSubFunctions[i]->Call(&input, kRequiredNumInputs, outputs, nresults);
791 return TRUE; 801 return TRUE;
792 } 802 }
793 803
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 type = -1;
799 if (CPDF_Stream* pStream = pFuncObj->AsStream()) { 809 if (CPDF_Stream* pStream = pFuncObj->AsStream())
800 type = pStream->GetDict()->GetIntegerBy("FunctionType"); 810 type = 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 type = pDict->GetIntegerBy("FunctionType");
803 } else { 813
804 return NULL; 814 std::unique_ptr<CPDF_Function> pFunc;
805 } 815 if (type == 0)
806 CPDF_Function* pFunc = NULL; 816 pFunc.reset(new CPDF_SampledFunc());
807 if (type == 0) { 817 else if (type == 2)
808 pFunc = new CPDF_SampledFunc(); 818 pFunc.reset(new CPDF_ExpIntFunc());
809 } else if (type == 2) { 819 else if (type == 3)
810 pFunc = new CPDF_ExpIntFunc(); 820 pFunc.reset(new CPDF_StitchFunc());
811 } else if (type == 3) { 821 else if (type == 4)
Tom Sepez 2016/05/19 16:53:40 Shouldn't this be kTypeFourPostScript and friends?
Lei Zhang 2016/05/19 21:16:19 I put CPDF_Function::Type back. It's not obvious w
812 pFunc = new CPDF_StitchFunc(); 822 pFunc.reset(new CPDF_PSFunc());
813 } else if (type == 4) { 823
814 pFunc = new CPDF_PSFunc(); 824 if (!pFunc || !pFunc->Init(pFuncObj))
815 } else { 825 return nullptr;
816 return NULL; 826 return pFunc.release();
817 }
818 if (!pFunc->Init(pFuncObj)) {
819 delete pFunc;
820 return NULL;
821 }
822 return pFunc;
823 } 827 }
824 828
825 CPDF_Function::CPDF_Function(Type type) : m_Type(type) { 829 CPDF_Function::CPDF_Function() {
826 m_pDomains = NULL; 830 m_pDomains = NULL;
827 m_pRanges = NULL; 831 m_pRanges = NULL;
828 } 832 }
829 833
830 CPDF_Function::~CPDF_Function() { 834 CPDF_Function::~CPDF_Function() {
831 FX_Free(m_pDomains); 835 FX_Free(m_pDomains);
832 FX_Free(m_pRanges); 836 FX_Free(m_pRanges);
833 } 837 }
838
834 FX_BOOL CPDF_Function::Init(CPDF_Object* pObj) { 839 FX_BOOL CPDF_Function::Init(CPDF_Object* pObj) {
835 CPDF_Stream* pStream = pObj->AsStream(); 840 CPDF_Stream* pStream = pObj->AsStream();
836 CPDF_Dictionary* pDict = pStream ? pStream->GetDict() : pObj->AsDictionary(); 841 CPDF_Dictionary* pDict = pStream ? pStream->GetDict() : pObj->AsDictionary();
837 842
838 CPDF_Array* pDomains = pDict->GetArrayBy("Domain"); 843 CPDF_Array* pDomains = pDict->GetArrayBy("Domain");
839 if (!pDomains) 844 if (!pDomains)
840 return FALSE; 845 return FALSE;
841 846
842 m_nInputs = pDomains->GetCount() / 2; 847 m_nInputs = pDomains->GetCount() / 2;
843 if (m_nInputs == 0) 848 if (m_nInputs == 0)
(...skipping 16 matching lines...) Expand all
860 return FALSE; 865 return FALSE;
861 if (m_pRanges && m_nOutputs > old_outputs) { 866 if (m_pRanges && m_nOutputs > old_outputs) {
862 m_pRanges = FX_Realloc(FX_FLOAT, m_pRanges, m_nOutputs * 2); 867 m_pRanges = FX_Realloc(FX_FLOAT, m_pRanges, m_nOutputs * 2);
863 if (m_pRanges) { 868 if (m_pRanges) {
864 FXSYS_memset(m_pRanges + (old_outputs * 2), 0, 869 FXSYS_memset(m_pRanges + (old_outputs * 2), 0,
865 sizeof(FX_FLOAT) * (m_nOutputs - old_outputs) * 2); 870 sizeof(FX_FLOAT) * (m_nOutputs - old_outputs) * 2);
866 } 871 }
867 } 872 }
868 return TRUE; 873 return TRUE;
869 } 874 }
875
870 FX_BOOL CPDF_Function::Call(FX_FLOAT* inputs, 876 FX_BOOL CPDF_Function::Call(FX_FLOAT* inputs,
871 uint32_t ninputs, 877 uint32_t ninputs,
872 FX_FLOAT* results, 878 FX_FLOAT* results,
873 int& nresults) const { 879 int& nresults) const {
874 if (m_nInputs != ninputs) { 880 if (m_nInputs != ninputs) {
875 return FALSE; 881 return FALSE;
876 } 882 }
877 nresults = m_nOutputs; 883 nresults = m_nOutputs;
878 for (uint32_t i = 0; i < m_nInputs; i++) { 884 for (uint32_t i = 0; i < m_nInputs; i++) {
879 if (inputs[i] < m_pDomains[i * 2]) 885 if (inputs[i] < m_pDomains[i * 2])
880 inputs[i] = m_pDomains[i * 2]; 886 inputs[i] = m_pDomains[i * 2];
881 else if (inputs[i] > m_pDomains[i * 2 + 1]) 887 else if (inputs[i] > m_pDomains[i * 2 + 1])
882 inputs[i] = m_pDomains[i * 2] + 1; 888 inputs[i] = m_pDomains[i * 2] + 1;
883 } 889 }
884 v_Call(inputs, results); 890 v_Call(inputs, results);
885 if (m_pRanges) { 891 if (m_pRanges) {
886 for (uint32_t i = 0; i < m_nOutputs; i++) { 892 for (uint32_t i = 0; i < m_nOutputs; i++) {
887 if (results[i] < m_pRanges[i * 2]) 893 if (results[i] < m_pRanges[i * 2])
888 results[i] = m_pRanges[i * 2]; 894 results[i] = m_pRanges[i * 2];
889 else if (results[i] > m_pRanges[i * 2 + 1]) 895 else if (results[i] > m_pRanges[i * 2 + 1])
890 results[i] = m_pRanges[i * 2 + 1]; 896 results[i] = m_pRanges[i * 2 + 1];
891 } 897 }
892 } 898 }
893 return TRUE; 899 return TRUE;
894 } 900 }
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