| 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 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 int result = 0; | 508 int result = 0; |
| 509 for (int i = 0; i < nbits; i++) { | 509 for (int i = 0; i < nbits; i++) { |
| 510 if (pData[(bitpos + i) / 8] & (1 << (7 - (bitpos + i) % 8))) | 510 if (pData[(bitpos + i) / 8] & (1 << (7 - (bitpos + i) % 8))) |
| 511 result |= 1 << (nbits - i - 1); | 511 result |= 1 << (nbits - i - 1); |
| 512 } | 512 } |
| 513 return result; | 513 return result; |
| 514 } | 514 } |
| 515 | 515 |
| 516 class CPDF_PSFunc : public CPDF_Function { | 516 class CPDF_PSFunc : public CPDF_Function { |
| 517 public: | 517 public: |
| 518 CPDF_PSFunc() {} | 518 CPDF_PSFunc() : CPDF_Function(Type::kType4PostScript) {} |
| 519 ~CPDF_PSFunc() override {} | 519 ~CPDF_PSFunc() override {} |
| 520 | 520 |
| 521 // CPDF_Function | 521 // CPDF_Function |
| 522 FX_BOOL v_Init(CPDF_Object* pObj) override; | 522 FX_BOOL v_Init(CPDF_Object* pObj) override; |
| 523 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; |
| 524 | 524 |
| 525 private: | 525 private: |
| 526 CPDF_PSEngine m_PS; | 526 CPDF_PSEngine m_PS; |
| 527 }; | 527 }; |
| 528 | 528 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 541 PS.Execute(); | 541 PS.Execute(); |
| 542 if (PS.GetStackSize() < m_nOutputs) | 542 if (PS.GetStackSize() < m_nOutputs) |
| 543 return FALSE; | 543 return FALSE; |
| 544 for (uint32_t i = 0; i < m_nOutputs; i++) | 544 for (uint32_t i = 0; i < m_nOutputs; i++) |
| 545 results[m_nOutputs - i - 1] = PS.Pop(); | 545 results[m_nOutputs - i - 1] = PS.Pop(); |
| 546 return TRUE; | 546 return TRUE; |
| 547 } | 547 } |
| 548 | 548 |
| 549 } // namespace | 549 } // namespace |
| 550 | 550 |
| 551 CPDF_SampledFunc::CPDF_SampledFunc() {} | 551 CPDF_SampledFunc::CPDF_SampledFunc() : CPDF_Function(Type::kType0Sampled) {} |
| 552 | 552 |
| 553 CPDF_SampledFunc::~CPDF_SampledFunc() {} | 553 CPDF_SampledFunc::~CPDF_SampledFunc() {} |
| 554 | 554 |
| 555 FX_BOOL CPDF_SampledFunc::v_Init(CPDF_Object* pObj) { | 555 FX_BOOL CPDF_SampledFunc::v_Init(CPDF_Object* pObj) { |
| 556 CPDF_Stream* pStream = pObj->AsStream(); | 556 CPDF_Stream* pStream = pObj->AsStream(); |
| 557 if (!pStream) | 557 if (!pStream) |
| 558 return false; | 558 return false; |
| 559 | 559 |
| 560 CPDF_Dictionary* pDict = pStream->GetDict(); | 560 CPDF_Dictionary* pDict = pStream->GetDict(); |
| 561 CPDF_Array* pSize = pDict->GetArrayBy("Size"); | 561 CPDF_Array* pSize = pDict->GetArrayBy("Size"); |
| 562 CPDF_Array* pEncode = pDict->GetArrayBy("Encode"); | 562 CPDF_Array* pEncode = pDict->GetArrayBy("Encode"); |
| 563 CPDF_Array* pDecode = pDict->GetArrayBy("Decode"); | 563 CPDF_Array* pDecode = pDict->GetArrayBy("Decode"); |
| 564 m_nBitsPerSample = pDict->GetIntegerBy("BitsPerSample"); | 564 m_nBitsPerSample = pDict->GetIntegerBy("BitsPerSample"); |
| 565 if (!IsValidBitsPerSample(m_nBitsPerSample)) | 565 if (!IsValidBitsPerSample(m_nBitsPerSample)) |
| 566 return FALSE; | 566 return FALSE; |
| 567 | 567 |
| 568 m_SampleMax = 0xffffffff >> (32 - m_nBitsPerSample); | 568 m_SampleMax = 0xffffffff >> (32 - m_nBitsPerSample); |
| 569 m_pSampleStream.reset(new CPDF_StreamAcc); | 569 m_pSampleStream.reset(new CPDF_StreamAcc); |
| 570 m_pSampleStream->LoadAllData(pStream, FALSE); | 570 m_pSampleStream->LoadAllData(pStream, FALSE); |
| 571 FX_SAFE_UINT32 nTotalSampleBits = 1; | 571 FX_SAFE_UINT32 nTotalSampleBits = 1; |
| 572 m_pEncodeInfo.resize(m_nInputs); | 572 m_EncodeInfo.resize(m_nInputs); |
| 573 for (uint32_t i = 0; i < m_nInputs; i++) { | 573 for (uint32_t i = 0; i < m_nInputs; i++) { |
| 574 m_pEncodeInfo[i].sizes = pSize ? pSize->GetIntegerAt(i) : 0; | 574 m_EncodeInfo[i].sizes = pSize ? pSize->GetIntegerAt(i) : 0; |
| 575 if (!pSize && i == 0) | 575 if (!pSize && i == 0) |
| 576 m_pEncodeInfo[i].sizes = pDict->GetIntegerBy("Size"); | 576 m_EncodeInfo[i].sizes = pDict->GetIntegerBy("Size"); |
| 577 nTotalSampleBits *= m_pEncodeInfo[i].sizes; | 577 nTotalSampleBits *= m_EncodeInfo[i].sizes; |
| 578 if (pEncode) { | 578 if (pEncode) { |
| 579 m_pEncodeInfo[i].encode_min = pEncode->GetFloatAt(i * 2); | 579 m_EncodeInfo[i].encode_min = pEncode->GetFloatAt(i * 2); |
| 580 m_pEncodeInfo[i].encode_max = pEncode->GetFloatAt(i * 2 + 1); | 580 m_EncodeInfo[i].encode_max = pEncode->GetFloatAt(i * 2 + 1); |
| 581 } else { | 581 } else { |
| 582 m_pEncodeInfo[i].encode_min = 0; | 582 m_EncodeInfo[i].encode_min = 0; |
| 583 m_pEncodeInfo[i].encode_max = m_pEncodeInfo[i].sizes == 1 | 583 m_EncodeInfo[i].encode_max = |
| 584 ? 1 | 584 m_EncodeInfo[i].sizes == 1 ? 1 : (FX_FLOAT)m_EncodeInfo[i].sizes - 1; |
| 585 : (FX_FLOAT)m_pEncodeInfo[i].sizes - 1; | |
| 586 } | 585 } |
| 587 } | 586 } |
| 588 nTotalSampleBits *= m_nBitsPerSample; | 587 nTotalSampleBits *= m_nBitsPerSample; |
| 589 nTotalSampleBits *= m_nOutputs; | 588 nTotalSampleBits *= m_nOutputs; |
| 590 FX_SAFE_UINT32 nTotalSampleBytes = nTotalSampleBits; | 589 FX_SAFE_UINT32 nTotalSampleBytes = nTotalSampleBits; |
| 591 nTotalSampleBytes += 7; | 590 nTotalSampleBytes += 7; |
| 592 nTotalSampleBytes /= 8; | 591 nTotalSampleBytes /= 8; |
| 593 if (!nTotalSampleBytes.IsValid() || nTotalSampleBytes.ValueOrDie() == 0 || | 592 if (!nTotalSampleBytes.IsValid() || nTotalSampleBytes.ValueOrDie() == 0 || |
| 594 nTotalSampleBytes.ValueOrDie() > m_pSampleStream->GetSize()) { | 593 nTotalSampleBytes.ValueOrDie() > m_pSampleStream->GetSize()) { |
| 595 return FALSE; | 594 return FALSE; |
| 596 } | 595 } |
| 597 m_pDecodeInfo.resize(m_nOutputs); | 596 m_DecodeInfo.resize(m_nOutputs); |
| 598 for (uint32_t i = 0; i < m_nOutputs; i++) { | 597 for (uint32_t i = 0; i < m_nOutputs; i++) { |
| 599 if (pDecode) { | 598 if (pDecode) { |
| 600 m_pDecodeInfo[i].decode_min = pDecode->GetFloatAt(2 * i); | 599 m_DecodeInfo[i].decode_min = pDecode->GetFloatAt(2 * i); |
| 601 m_pDecodeInfo[i].decode_max = pDecode->GetFloatAt(2 * i + 1); | 600 m_DecodeInfo[i].decode_max = pDecode->GetFloatAt(2 * i + 1); |
| 602 } else { | 601 } else { |
| 603 m_pDecodeInfo[i].decode_min = m_pRanges[i * 2]; | 602 m_DecodeInfo[i].decode_min = m_pRanges[i * 2]; |
| 604 m_pDecodeInfo[i].decode_max = m_pRanges[i * 2 + 1]; | 603 m_DecodeInfo[i].decode_max = m_pRanges[i * 2 + 1]; |
| 605 } | 604 } |
| 606 } | 605 } |
| 607 return TRUE; | 606 return TRUE; |
| 608 } | 607 } |
| 609 | 608 |
| 610 FX_BOOL CPDF_SampledFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const { | 609 FX_BOOL CPDF_SampledFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const { |
| 611 int pos = 0; | 610 int pos = 0; |
| 612 CFX_FixedBufGrow<FX_FLOAT, 16> encoded_input_buf(m_nInputs); | 611 CFX_FixedBufGrow<FX_FLOAT, 16> encoded_input_buf(m_nInputs); |
| 613 FX_FLOAT* encoded_input = encoded_input_buf; | 612 FX_FLOAT* encoded_input = encoded_input_buf; |
| 614 CFX_FixedBufGrow<uint32_t, 32> int_buf(m_nInputs * 2); | 613 CFX_FixedBufGrow<uint32_t, 32> int_buf(m_nInputs * 2); |
| 615 uint32_t* index = int_buf; | 614 uint32_t* index = int_buf; |
| 616 uint32_t* blocksize = index + m_nInputs; | 615 uint32_t* blocksize = index + m_nInputs; |
| 617 for (uint32_t i = 0; i < m_nInputs; i++) { | 616 for (uint32_t i = 0; i < m_nInputs; i++) { |
| 618 if (i == 0) | 617 if (i == 0) |
| 619 blocksize[i] = 1; | 618 blocksize[i] = 1; |
| 620 else | 619 else |
| 621 blocksize[i] = blocksize[i - 1] * m_pEncodeInfo[i - 1].sizes; | 620 blocksize[i] = blocksize[i - 1] * m_EncodeInfo[i - 1].sizes; |
| 622 encoded_input[i] = PDF_Interpolate( | 621 encoded_input[i] = |
| 623 inputs[i], m_pDomains[i * 2], m_pDomains[i * 2 + 1], | 622 PDF_Interpolate(inputs[i], m_pDomains[i * 2], m_pDomains[i * 2 + 1], |
| 624 m_pEncodeInfo[i].encode_min, m_pEncodeInfo[i].encode_max); | 623 m_EncodeInfo[i].encode_min, m_EncodeInfo[i].encode_max); |
| 625 index[i] = std::min((uint32_t)std::max(0.f, encoded_input[i]), | 624 index[i] = std::min((uint32_t)std::max(0.f, encoded_input[i]), |
| 626 m_pEncodeInfo[i].sizes - 1); | 625 m_EncodeInfo[i].sizes - 1); |
| 627 pos += index[i] * blocksize[i]; | 626 pos += index[i] * blocksize[i]; |
| 628 } | 627 } |
| 629 FX_SAFE_INT32 bits_to_output = m_nOutputs; | 628 FX_SAFE_INT32 bits_to_output = m_nOutputs; |
| 630 bits_to_output *= m_nBitsPerSample; | 629 bits_to_output *= m_nBitsPerSample; |
| 631 if (!bits_to_output.IsValid()) | 630 if (!bits_to_output.IsValid()) |
| 632 return FALSE; | 631 return FALSE; |
| 633 | 632 |
| 634 FX_SAFE_INT32 bitpos = pos; | 633 FX_SAFE_INT32 bitpos = pos; |
| 635 bitpos *= bits_to_output.ValueOrDie(); | 634 bitpos *= bits_to_output.ValueOrDie(); |
| 636 if (!bitpos.IsValid()) | 635 if (!bitpos.IsValid()) |
| 637 return FALSE; | 636 return FALSE; |
| 638 | 637 |
| 639 FX_SAFE_INT32 range_check = bitpos; | 638 FX_SAFE_INT32 range_check = bitpos; |
| 640 range_check += bits_to_output.ValueOrDie(); | 639 range_check += bits_to_output.ValueOrDie(); |
| 641 if (!range_check.IsValid()) | 640 if (!range_check.IsValid()) |
| 642 return FALSE; | 641 return FALSE; |
| 643 | 642 |
| 644 const uint8_t* pSampleData = m_pSampleStream->GetData(); | 643 const uint8_t* pSampleData = m_pSampleStream->GetData(); |
| 645 if (!pSampleData) | 644 if (!pSampleData) |
| 646 return FALSE; | 645 return FALSE; |
| 647 | 646 |
| 648 for (uint32_t j = 0; j < m_nOutputs; j++) { | 647 for (uint32_t j = 0; j < m_nOutputs; j++) { |
| 649 uint32_t sample = | 648 uint32_t sample = |
| 650 GetBits32(pSampleData, bitpos.ValueOrDie() + j * m_nBitsPerSample, | 649 GetBits32(pSampleData, bitpos.ValueOrDie() + j * m_nBitsPerSample, |
| 651 m_nBitsPerSample); | 650 m_nBitsPerSample); |
| 652 FX_FLOAT encoded = (FX_FLOAT)sample; | 651 FX_FLOAT encoded = (FX_FLOAT)sample; |
| 653 for (uint32_t i = 0; i < m_nInputs; i++) { | 652 for (uint32_t i = 0; i < m_nInputs; i++) { |
| 654 if (index[i] == m_pEncodeInfo[i].sizes - 1) { | 653 if (index[i] == m_EncodeInfo[i].sizes - 1) { |
| 655 if (index[i] == 0) | 654 if (index[i] == 0) |
| 656 encoded = encoded_input[i] * (FX_FLOAT)sample; | 655 encoded = encoded_input[i] * (FX_FLOAT)sample; |
| 657 } else { | 656 } else { |
| 658 FX_SAFE_INT32 bitpos2 = blocksize[i]; | 657 FX_SAFE_INT32 bitpos2 = blocksize[i]; |
| 659 bitpos2 += pos; | 658 bitpos2 += pos; |
| 660 bitpos2 *= m_nOutputs; | 659 bitpos2 *= m_nOutputs; |
| 661 bitpos2 += j; | 660 bitpos2 += j; |
| 662 bitpos2 *= m_nBitsPerSample; | 661 bitpos2 *= m_nBitsPerSample; |
| 663 if (!bitpos2.IsValid()) | 662 if (!bitpos2.IsValid()) |
| 664 return FALSE; | 663 return FALSE; |
| 665 uint32_t sample1 = | 664 uint32_t sample1 = |
| 666 GetBits32(pSampleData, bitpos2.ValueOrDie(), m_nBitsPerSample); | 665 GetBits32(pSampleData, bitpos2.ValueOrDie(), m_nBitsPerSample); |
| 667 encoded += (encoded_input[i] - index[i]) * | 666 encoded += (encoded_input[i] - index[i]) * |
| 668 ((FX_FLOAT)sample1 - (FX_FLOAT)sample); | 667 ((FX_FLOAT)sample1 - (FX_FLOAT)sample); |
| 669 } | 668 } |
| 670 } | 669 } |
| 671 results[j] = PDF_Interpolate(encoded, 0, (FX_FLOAT)m_SampleMax, | 670 results[j] = |
| 672 m_pDecodeInfo[j].decode_min, | 671 PDF_Interpolate(encoded, 0, (FX_FLOAT)m_SampleMax, |
| 673 m_pDecodeInfo[j].decode_max); | 672 m_DecodeInfo[j].decode_min, m_DecodeInfo[j].decode_max); |
| 674 } | 673 } |
| 675 return TRUE; | 674 return TRUE; |
| 676 } | 675 } |
| 677 | 676 |
| 678 CPDF_ExpIntFunc::CPDF_ExpIntFunc() { | 677 CPDF_ExpIntFunc::CPDF_ExpIntFunc() |
| 679 m_pBeginValues = NULL; | 678 : CPDF_Function(Type::kType2ExpotentialInterpolation), |
| 680 m_pEndValues = NULL; | 679 m_pBeginValues(nullptr), |
| 681 } | 680 m_pEndValues(nullptr) {} |
| 682 | 681 |
| 683 CPDF_ExpIntFunc::~CPDF_ExpIntFunc() { | 682 CPDF_ExpIntFunc::~CPDF_ExpIntFunc() { |
| 684 FX_Free(m_pBeginValues); | 683 FX_Free(m_pBeginValues); |
| 685 FX_Free(m_pEndValues); | 684 FX_Free(m_pEndValues); |
| 686 } | 685 } |
| 687 FX_BOOL CPDF_ExpIntFunc::v_Init(CPDF_Object* pObj) { | 686 FX_BOOL CPDF_ExpIntFunc::v_Init(CPDF_Object* pObj) { |
| 688 CPDF_Dictionary* pDict = pObj->GetDict(); | 687 CPDF_Dictionary* pDict = pObj->GetDict(); |
| 689 if (!pDict) { | 688 if (!pDict) { |
| 690 return FALSE; | 689 return FALSE; |
| 691 } | 690 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 715 for (uint32_t i = 0; i < m_nInputs; i++) | 714 for (uint32_t i = 0; i < m_nInputs; i++) |
| 716 for (uint32_t j = 0; j < m_nOrigOutputs; j++) { | 715 for (uint32_t j = 0; j < m_nOrigOutputs; j++) { |
| 717 results[i * m_nOrigOutputs + j] = | 716 results[i * m_nOrigOutputs + j] = |
| 718 m_pBeginValues[j] + | 717 m_pBeginValues[j] + |
| 719 (FX_FLOAT)FXSYS_pow(inputs[i], m_Exponent) * | 718 (FX_FLOAT)FXSYS_pow(inputs[i], m_Exponent) * |
| 720 (m_pEndValues[j] - m_pBeginValues[j]); | 719 (m_pEndValues[j] - m_pBeginValues[j]); |
| 721 } | 720 } |
| 722 return TRUE; | 721 return TRUE; |
| 723 } | 722 } |
| 724 | 723 |
| 725 CPDF_StitchFunc::CPDF_StitchFunc() { | 724 CPDF_StitchFunc::CPDF_StitchFunc() |
| 726 m_pBounds = NULL; | 725 : CPDF_Function(Type::kType3Stitching), |
| 727 m_pEncode = NULL; | 726 m_pBounds(nullptr), |
| 728 } | 727 m_pEncode(nullptr) {} |
| 729 | 728 |
| 730 CPDF_StitchFunc::~CPDF_StitchFunc() { | 729 CPDF_StitchFunc::~CPDF_StitchFunc() { |
| 731 FX_Free(m_pBounds); | 730 FX_Free(m_pBounds); |
| 732 FX_Free(m_pEncode); | 731 FX_Free(m_pEncode); |
| 733 } | 732 } |
| 734 | 733 |
| 735 FX_BOOL CPDF_StitchFunc::v_Init(CPDF_Object* pObj) { | 734 FX_BOOL CPDF_StitchFunc::v_Init(CPDF_Object* pObj) { |
| 736 CPDF_Dictionary* pDict = pObj->GetDict(); | 735 CPDF_Dictionary* pDict = pObj->GetDict(); |
| 737 if (!pDict) { | 736 if (!pDict) { |
| 738 return FALSE; | 737 return FALSE; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 833 case 0: | 832 case 0: |
| 834 case 2: | 833 case 2: |
| 835 case 3: | 834 case 3: |
| 836 case 4: | 835 case 4: |
| 837 return static_cast<Type>(iType); | 836 return static_cast<Type>(iType); |
| 838 default: | 837 default: |
| 839 return Type::kTypeInvalid; | 838 return Type::kTypeInvalid; |
| 840 } | 839 } |
| 841 } | 840 } |
| 842 | 841 |
| 843 CPDF_Function::CPDF_Function() { | 842 CPDF_Function::CPDF_Function(Type type) |
| 844 m_pDomains = NULL; | 843 : m_pDomains(nullptr), m_pRanges(nullptr), m_Type(type) {} |
| 845 m_pRanges = NULL; | |
| 846 } | |
| 847 | 844 |
| 848 CPDF_Function::~CPDF_Function() { | 845 CPDF_Function::~CPDF_Function() { |
| 849 FX_Free(m_pDomains); | 846 FX_Free(m_pDomains); |
| 850 FX_Free(m_pRanges); | 847 FX_Free(m_pRanges); |
| 851 } | 848 } |
| 852 | 849 |
| 853 FX_BOOL CPDF_Function::Init(CPDF_Object* pObj) { | 850 FX_BOOL CPDF_Function::Init(CPDF_Object* pObj) { |
| 854 CPDF_Stream* pStream = pObj->AsStream(); | 851 CPDF_Stream* pStream = pObj->AsStream(); |
| 855 CPDF_Dictionary* pDict = pStream ? pStream->GetDict() : pObj->AsDictionary(); | 852 CPDF_Dictionary* pDict = pStream ? pStream->GetDict() : pObj->AsDictionary(); |
| 856 | 853 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 905 if (m_pRanges) { | 902 if (m_pRanges) { |
| 906 for (uint32_t i = 0; i < m_nOutputs; i++) { | 903 for (uint32_t i = 0; i < m_nOutputs; i++) { |
| 907 if (results[i] < m_pRanges[i * 2]) | 904 if (results[i] < m_pRanges[i * 2]) |
| 908 results[i] = m_pRanges[i * 2]; | 905 results[i] = m_pRanges[i * 2]; |
| 909 else if (results[i] > m_pRanges[i * 2 + 1]) | 906 else if (results[i] > m_pRanges[i * 2 + 1]) |
| 910 results[i] = m_pRanges[i * 2 + 1]; | 907 results[i] = m_pRanges[i * 2 + 1]; |
| 911 } | 908 } |
| 912 } | 909 } |
| 913 return TRUE; | 910 return TRUE; |
| 914 } | 911 } |
| 912 |
| 913 const CPDF_SampledFunc* CPDF_Function::ToSampledFunc() const { |
| 914 return m_Type == Type::kType0Sampled |
| 915 ? static_cast<const CPDF_SampledFunc*>(this) |
| 916 : nullptr; |
| 917 } |
| 918 |
| 919 const CPDF_ExpIntFunc* CPDF_Function::ToExpIntFunc() const { |
| 920 return m_Type == Type::kType2ExpotentialInterpolation |
| 921 ? static_cast<const CPDF_ExpIntFunc*>(this) |
| 922 : nullptr; |
| 923 } |
| 924 |
| 925 const CPDF_StitchFunc* CPDF_Function::ToStitchFunc() const { |
| 926 return m_Type == Type::kType3Stitching |
| 927 ? static_cast<const CPDF_StitchFunc*>(this) |
| 928 : nullptr; |
| 929 } |
| OLD | NEW |