Chromium Code Reviews| 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) { | |
|
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 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 = |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |