| 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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 CPDF_PSProc() {} | 109 CPDF_PSProc() {} |
| 110 ~CPDF_PSProc() {} | 110 ~CPDF_PSProc() {} |
| 111 | 111 |
| 112 FX_BOOL Parse(CPDF_SimpleParser* parser); | 112 FX_BOOL Parse(CPDF_SimpleParser* parser); |
| 113 FX_BOOL Execute(CPDF_PSEngine* pEngine); | 113 FX_BOOL Execute(CPDF_PSEngine* pEngine); |
| 114 | 114 |
| 115 private: | 115 private: |
| 116 std::vector<std::unique_ptr<CPDF_PSOP>> m_Operators; | 116 std::vector<std::unique_ptr<CPDF_PSOP>> m_Operators; |
| 117 }; | 117 }; |
| 118 | 118 |
| 119 const size_t PSENGINE_STACKSIZE = 100; | 119 const uint32_t PSENGINE_STACKSIZE = 100; |
| 120 | 120 |
| 121 class CPDF_PSEngine { | 121 class CPDF_PSEngine { |
| 122 public: | 122 public: |
| 123 CPDF_PSEngine(); | 123 CPDF_PSEngine(); |
| 124 ~CPDF_PSEngine(); | 124 ~CPDF_PSEngine(); |
| 125 | 125 |
| 126 FX_BOOL Parse(const FX_CHAR* str, int size); | 126 FX_BOOL Parse(const FX_CHAR* str, int size); |
| 127 FX_BOOL Execute() { return m_MainProc.Execute(this); } | 127 FX_BOOL Execute() { return m_MainProc.Execute(this); } |
| 128 FX_BOOL DoOperator(PDF_PSOP op); | 128 FX_BOOL DoOperator(PDF_PSOP op); |
| 129 void Reset() { m_StackCount = 0; } | 129 void Reset() { m_StackCount = 0; } |
| 130 void Push(FX_FLOAT value); | 130 void Push(FX_FLOAT value); |
| 131 void Push(int value) { Push((FX_FLOAT)value); } | 131 void Push(int value) { Push((FX_FLOAT)value); } |
| 132 FX_FLOAT Pop(); | 132 FX_FLOAT Pop(); |
| 133 int GetStackSize() const { return m_StackCount; } | 133 uint32_t GetStackSize() const { return m_StackCount; } |
| 134 | 134 |
| 135 private: | 135 private: |
| 136 FX_FLOAT m_Stack[PSENGINE_STACKSIZE]; | 136 FX_FLOAT m_Stack[PSENGINE_STACKSIZE]; |
| 137 int m_StackCount; | 137 uint32_t m_StackCount; |
| 138 CPDF_PSProc m_MainProc; | 138 CPDF_PSProc m_MainProc; |
| 139 }; | 139 }; |
| 140 | 140 |
| 141 FX_BOOL CPDF_PSProc::Execute(CPDF_PSEngine* pEngine) { | 141 FX_BOOL CPDF_PSProc::Execute(CPDF_PSEngine* pEngine) { |
| 142 for (size_t i = 0; i < m_Operators.size(); ++i) { | 142 for (size_t i = 0; i < m_Operators.size(); ++i) { |
| 143 const PDF_PSOP op = m_Operators[i]->GetOp(); | 143 const PDF_PSOP op = m_Operators[i]->GetOp(); |
| 144 if (op == PSOP_PROC) | 144 if (op == PSOP_PROC) |
| 145 continue; | 145 continue; |
| 146 | 146 |
| 147 if (op == PSOP_CONST) { | 147 if (op == PSOP_CONST) { |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 d1 = Pop(); | 423 d1 = Pop(); |
| 424 Push(d2); | 424 Push(d2); |
| 425 Push(d1); | 425 Push(d1); |
| 426 break; | 426 break; |
| 427 case PSOP_DUP: | 427 case PSOP_DUP: |
| 428 d1 = Pop(); | 428 d1 = Pop(); |
| 429 Push(d1); | 429 Push(d1); |
| 430 Push(d1); | 430 Push(d1); |
| 431 break; | 431 break; |
| 432 case PSOP_COPY: { | 432 case PSOP_COPY: { |
| 433 int n = (int)Pop(); | 433 int n = static_cast<int>(Pop()); |
| 434 if (n < 0 || n > PSENGINE_STACKSIZE || | 434 if (n < 0 || m_StackCount + n > PSENGINE_STACKSIZE || |
| 435 m_StackCount + n > PSENGINE_STACKSIZE || n > m_StackCount) { | 435 n > static_cast<int>(m_StackCount)) |
| 436 break; | 436 break; |
| 437 } | 437 for (int i = 0; i < n; i++) |
| 438 for (int i = 0; i < n; i++) { | |
| 439 m_Stack[m_StackCount + i] = m_Stack[m_StackCount + i - n]; | 438 m_Stack[m_StackCount + i] = m_Stack[m_StackCount + i - n]; |
| 440 } | |
| 441 m_StackCount += n; | 439 m_StackCount += n; |
| 442 break; | 440 break; |
| 443 } | 441 } |
| 444 case PSOP_INDEX: { | 442 case PSOP_INDEX: { |
| 445 int n = (int)Pop(); | 443 int n = static_cast<int>(Pop()); |
| 446 if (n < 0 || n >= m_StackCount) { | 444 if (n < 0 || n >= static_cast<int>(m_StackCount)) |
| 447 break; | 445 break; |
| 448 } | |
| 449 Push(m_Stack[m_StackCount - n - 1]); | 446 Push(m_Stack[m_StackCount - n - 1]); |
| 450 break; | 447 break; |
| 451 } | 448 } |
| 452 case PSOP_ROLL: { | 449 case PSOP_ROLL: { |
| 453 int j = (int)Pop(); | 450 int j = static_cast<int>(Pop()); |
| 454 int n = (int)Pop(); | 451 int n = static_cast<int>(Pop()); |
| 455 if (m_StackCount == 0) { | 452 if (m_StackCount == 0) |
| 456 break; | 453 break; |
| 457 } | 454 if (n < 0 || n > static_cast<int>(m_StackCount)) |
| 458 if (n < 0 || n > m_StackCount) { | |
| 459 break; | 455 break; |
| 460 } | |
| 461 if (j < 0) { | 456 if (j < 0) { |
| 462 for (int i = 0; i < -j; i++) { | 457 for (int i = 0; i < -j; i++) { |
| 463 FX_FLOAT first = m_Stack[m_StackCount - n]; | 458 FX_FLOAT first = m_Stack[m_StackCount - n]; |
| 464 for (int ii = 0; ii < n - 1; ii++) { | 459 for (int ii = 0; ii < n - 1; ii++) |
| 465 m_Stack[m_StackCount - n + ii] = m_Stack[m_StackCount - n + ii + 1]; | 460 m_Stack[m_StackCount - n + ii] = m_Stack[m_StackCount - n + ii + 1]; |
| 466 } | |
| 467 m_Stack[m_StackCount - 1] = first; | 461 m_Stack[m_StackCount - 1] = first; |
| 468 } | 462 } |
| 469 } else { | 463 } else { |
| 470 for (int i = 0; i < j; i++) { | 464 for (int i = 0; i < j; i++) { |
| 471 FX_FLOAT last = m_Stack[m_StackCount - 1]; | 465 FX_FLOAT last = m_Stack[m_StackCount - 1]; |
| 472 int ii; | 466 int ii; |
| 473 for (ii = 0; ii < n - 1; ii++) { | 467 for (ii = 0; ii < n - 1; ii++) |
| 474 m_Stack[m_StackCount - ii - 1] = m_Stack[m_StackCount - ii - 2]; | 468 m_Stack[m_StackCount - ii - 1] = m_Stack[m_StackCount - ii - 2]; |
| 475 } | |
| 476 m_Stack[m_StackCount - ii - 1] = last; | 469 m_Stack[m_StackCount - ii - 1] = last; |
| 477 } | 470 } |
| 478 } | 471 } |
| 479 break; | 472 break; |
| 480 } | 473 } |
| 481 default: | 474 default: |
| 482 break; | 475 break; |
| 483 } | 476 } |
| 484 return TRUE; | 477 return TRUE; |
| 485 } | 478 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 CPDF_Array* pDecode = pDict->GetArrayBy("Decode"); | 535 CPDF_Array* pDecode = pDict->GetArrayBy("Decode"); |
| 543 m_nBitsPerSample = pDict->GetIntegerBy("BitsPerSample"); | 536 m_nBitsPerSample = pDict->GetIntegerBy("BitsPerSample"); |
| 544 if (m_nBitsPerSample > 32) { | 537 if (m_nBitsPerSample > 32) { |
| 545 return FALSE; | 538 return FALSE; |
| 546 } | 539 } |
| 547 m_SampleMax = 0xffffffff >> (32 - m_nBitsPerSample); | 540 m_SampleMax = 0xffffffff >> (32 - m_nBitsPerSample); |
| 548 m_pSampleStream = new CPDF_StreamAcc; | 541 m_pSampleStream = new CPDF_StreamAcc; |
| 549 m_pSampleStream->LoadAllData(pStream, FALSE); | 542 m_pSampleStream->LoadAllData(pStream, FALSE); |
| 550 m_pEncodeInfo = FX_Alloc(SampleEncodeInfo, m_nInputs); | 543 m_pEncodeInfo = FX_Alloc(SampleEncodeInfo, m_nInputs); |
| 551 FX_SAFE_DWORD nTotalSampleBits = 1; | 544 FX_SAFE_DWORD nTotalSampleBits = 1; |
| 552 for (int i = 0; i < m_nInputs; i++) { | 545 for (uint32_t i = 0; i < m_nInputs; i++) { |
| 553 m_pEncodeInfo[i].sizes = pSize ? pSize->GetIntegerAt(i) : 0; | 546 m_pEncodeInfo[i].sizes = pSize ? pSize->GetIntegerAt(i) : 0; |
| 554 if (!pSize && i == 0) { | 547 if (!pSize && i == 0) |
| 555 m_pEncodeInfo[i].sizes = pDict->GetIntegerBy("Size"); | 548 m_pEncodeInfo[i].sizes = pDict->GetIntegerBy("Size"); |
| 556 } | |
| 557 nTotalSampleBits *= m_pEncodeInfo[i].sizes; | 549 nTotalSampleBits *= m_pEncodeInfo[i].sizes; |
| 558 if (pEncode) { | 550 if (pEncode) { |
| 559 m_pEncodeInfo[i].encode_min = pEncode->GetFloatAt(i * 2); | 551 m_pEncodeInfo[i].encode_min = pEncode->GetFloatAt(i * 2); |
| 560 m_pEncodeInfo[i].encode_max = pEncode->GetFloatAt(i * 2 + 1); | 552 m_pEncodeInfo[i].encode_max = pEncode->GetFloatAt(i * 2 + 1); |
| 561 } else { | 553 } else { |
| 562 m_pEncodeInfo[i].encode_min = 0; | 554 m_pEncodeInfo[i].encode_min = 0; |
| 563 if (m_pEncodeInfo[i].sizes == 1) { | 555 if (m_pEncodeInfo[i].sizes == 1) |
| 564 m_pEncodeInfo[i].encode_max = 1; | 556 m_pEncodeInfo[i].encode_max = 1; |
| 565 } else { | 557 else |
| 566 m_pEncodeInfo[i].encode_max = (FX_FLOAT)m_pEncodeInfo[i].sizes - 1; | 558 m_pEncodeInfo[i].encode_max = (FX_FLOAT)m_pEncodeInfo[i].sizes - 1; |
| 567 } | |
| 568 } | 559 } |
| 569 } | 560 } |
| 570 nTotalSampleBits *= m_nBitsPerSample; | 561 nTotalSampleBits *= m_nBitsPerSample; |
| 571 nTotalSampleBits *= m_nOutputs; | 562 nTotalSampleBits *= m_nOutputs; |
| 572 FX_SAFE_DWORD nTotalSampleBytes = nTotalSampleBits; | 563 FX_SAFE_DWORD nTotalSampleBytes = nTotalSampleBits; |
| 573 nTotalSampleBytes += 7; | 564 nTotalSampleBytes += 7; |
| 574 nTotalSampleBytes /= 8; | 565 nTotalSampleBytes /= 8; |
| 575 if (!nTotalSampleBytes.IsValid() || nTotalSampleBytes.ValueOrDie() == 0 || | 566 if (!nTotalSampleBytes.IsValid() || nTotalSampleBytes.ValueOrDie() == 0 || |
| 576 nTotalSampleBytes.ValueOrDie() > m_pSampleStream->GetSize()) { | 567 nTotalSampleBytes.ValueOrDie() > m_pSampleStream->GetSize()) { |
| 577 return FALSE; | 568 return FALSE; |
| 578 } | 569 } |
| 579 m_pDecodeInfo = FX_Alloc(SampleDecodeInfo, m_nOutputs); | 570 m_pDecodeInfo = FX_Alloc(SampleDecodeInfo, m_nOutputs); |
| 580 for (int i = 0; i < m_nOutputs; i++) { | 571 for (uint32_t i = 0; i < m_nOutputs; i++) { |
| 581 if (pDecode) { | 572 if (pDecode) { |
| 582 m_pDecodeInfo[i].decode_min = pDecode->GetFloatAt(2 * i); | 573 m_pDecodeInfo[i].decode_min = pDecode->GetFloatAt(2 * i); |
| 583 m_pDecodeInfo[i].decode_max = pDecode->GetFloatAt(2 * i + 1); | 574 m_pDecodeInfo[i].decode_max = pDecode->GetFloatAt(2 * i + 1); |
| 584 } else { | 575 } else { |
| 585 m_pDecodeInfo[i].decode_min = m_pRanges[i * 2]; | 576 m_pDecodeInfo[i].decode_min = m_pRanges[i * 2]; |
| 586 m_pDecodeInfo[i].decode_max = m_pRanges[i * 2 + 1]; | 577 m_pDecodeInfo[i].decode_max = m_pRanges[i * 2 + 1]; |
| 587 } | 578 } |
| 588 } | 579 } |
| 589 return TRUE; | 580 return TRUE; |
| 590 } | 581 } |
| 591 FX_BOOL CPDF_SampledFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const { | 582 FX_BOOL CPDF_SampledFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const { |
| 592 int pos = 0; | 583 int pos = 0; |
| 593 CFX_FixedBufGrow<FX_FLOAT, 16> encoded_input_buf(m_nInputs); | 584 CFX_FixedBufGrow<FX_FLOAT, 16> encoded_input_buf(m_nInputs); |
| 594 FX_FLOAT* encoded_input = encoded_input_buf; | 585 FX_FLOAT* encoded_input = encoded_input_buf; |
| 595 CFX_FixedBufGrow<int, 32> int_buf(m_nInputs * 2); | 586 CFX_FixedBufGrow<int, 32> int_buf(m_nInputs * 2); |
| 596 int* index = int_buf; | 587 int* index = int_buf; |
| 597 int* blocksize = index + m_nInputs; | 588 int* blocksize = index + m_nInputs; |
| 598 for (int i = 0; i < m_nInputs; i++) { | 589 for (uint32_t i = 0; i < m_nInputs; i++) { |
| 599 if (i == 0) { | 590 if (i == 0) |
| 600 blocksize[i] = 1; | 591 blocksize[i] = 1; |
| 601 } else { | 592 else |
| 602 blocksize[i] = blocksize[i - 1] * m_pEncodeInfo[i - 1].sizes; | 593 blocksize[i] = blocksize[i - 1] * m_pEncodeInfo[i - 1].sizes; |
| 603 } | |
| 604 encoded_input[i] = PDF_Interpolate( | 594 encoded_input[i] = PDF_Interpolate( |
| 605 inputs[i], m_pDomains[i * 2], m_pDomains[i * 2 + 1], | 595 inputs[i], m_pDomains[i * 2], m_pDomains[i * 2 + 1], |
| 606 m_pEncodeInfo[i].encode_min, m_pEncodeInfo[i].encode_max); | 596 m_pEncodeInfo[i].encode_min, m_pEncodeInfo[i].encode_max); |
| 607 index[i] = (int)encoded_input[i]; | 597 index[i] = (int)encoded_input[i]; |
| 608 if (index[i] < 0) { | 598 if (index[i] < 0) |
| 609 index[i] = 0; | 599 index[i] = 0; |
| 610 } else if (index[i] > m_pEncodeInfo[i].sizes - 1) { | 600 else if (index[i] > m_pEncodeInfo[i].sizes - 1) |
| 611 index[i] = m_pEncodeInfo[i].sizes - 1; | 601 index[i] = m_pEncodeInfo[i].sizes - 1; |
| 612 } | |
| 613 pos += index[i] * blocksize[i]; | 602 pos += index[i] * blocksize[i]; |
| 614 } | 603 } |
| 615 FX_SAFE_INT32 bits_to_output = m_nOutputs; | 604 FX_SAFE_INT32 bits_to_output = m_nOutputs; |
| 616 bits_to_output *= m_nBitsPerSample; | 605 bits_to_output *= m_nBitsPerSample; |
| 617 if (!bits_to_output.IsValid()) { | 606 if (!bits_to_output.IsValid()) { |
| 618 return FALSE; | 607 return FALSE; |
| 619 } | 608 } |
| 620 FX_SAFE_INT32 bitpos = pos; | 609 FX_SAFE_INT32 bitpos = pos; |
| 621 bitpos *= bits_to_output.ValueOrDie(); | 610 bitpos *= bits_to_output.ValueOrDie(); |
| 622 if (!bitpos.IsValid()) { | 611 if (!bitpos.IsValid()) { |
| 623 return FALSE; | 612 return FALSE; |
| 624 } | 613 } |
| 625 FX_SAFE_INT32 range_check = bitpos; | 614 FX_SAFE_INT32 range_check = bitpos; |
| 626 range_check += bits_to_output.ValueOrDie(); | 615 range_check += bits_to_output.ValueOrDie(); |
| 627 if (!range_check.IsValid()) { | 616 if (!range_check.IsValid()) { |
| 628 return FALSE; | 617 return FALSE; |
| 629 } | 618 } |
| 630 const uint8_t* pSampleData = m_pSampleStream->GetData(); | 619 const uint8_t* pSampleData = m_pSampleStream->GetData(); |
| 631 if (!pSampleData) { | 620 if (!pSampleData) { |
| 632 return FALSE; | 621 return FALSE; |
| 633 } | 622 } |
| 634 for (int j = 0; j < m_nOutputs; j++) { | 623 for (uint32_t j = 0; j < m_nOutputs; j++) { |
| 635 uint32_t sample = | 624 uint32_t sample = |
| 636 _GetBits32(pSampleData, bitpos.ValueOrDie() + j * m_nBitsPerSample, | 625 _GetBits32(pSampleData, bitpos.ValueOrDie() + j * m_nBitsPerSample, |
| 637 m_nBitsPerSample); | 626 m_nBitsPerSample); |
| 638 FX_FLOAT encoded = (FX_FLOAT)sample; | 627 FX_FLOAT encoded = (FX_FLOAT)sample; |
| 639 for (int i = 0; i < m_nInputs; i++) { | 628 for (uint32_t i = 0; i < m_nInputs; i++) { |
| 640 if (index[i] == m_pEncodeInfo[i].sizes - 1) { | 629 if (index[i] == m_pEncodeInfo[i].sizes - 1) { |
| 641 if (index[i] == 0) { | 630 if (index[i] == 0) |
| 642 encoded = encoded_input[i] * (FX_FLOAT)sample; | 631 encoded = encoded_input[i] * (FX_FLOAT)sample; |
| 643 } | |
| 644 } else { | 632 } else { |
| 645 FX_SAFE_INT32 bitpos2 = blocksize[i]; | 633 FX_SAFE_INT32 bitpos2 = blocksize[i]; |
| 646 bitpos2 += pos; | 634 bitpos2 += pos; |
| 647 bitpos2 *= m_nOutputs; | 635 bitpos2 *= m_nOutputs; |
| 648 bitpos2 += j; | 636 bitpos2 += j; |
| 649 bitpos2 *= m_nBitsPerSample; | 637 bitpos2 *= m_nBitsPerSample; |
| 650 if (!bitpos2.IsValid()) { | 638 if (!bitpos2.IsValid()) |
| 651 return FALSE; | 639 return FALSE; |
| 652 } | |
| 653 uint32_t sample1 = | 640 uint32_t sample1 = |
| 654 _GetBits32(pSampleData, bitpos2.ValueOrDie(), m_nBitsPerSample); | 641 _GetBits32(pSampleData, bitpos2.ValueOrDie(), m_nBitsPerSample); |
| 655 encoded += (encoded_input[i] - index[i]) * | 642 encoded += (encoded_input[i] - index[i]) * |
| 656 ((FX_FLOAT)sample1 - (FX_FLOAT)sample); | 643 ((FX_FLOAT)sample1 - (FX_FLOAT)sample); |
| 657 } | 644 } |
| 658 } | 645 } |
| 659 results[j] = PDF_Interpolate(encoded, 0, (FX_FLOAT)m_SampleMax, | 646 results[j] = PDF_Interpolate(encoded, 0, (FX_FLOAT)m_SampleMax, |
| 660 m_pDecodeInfo[j].decode_min, | 647 m_pDecodeInfo[j].decode_min, |
| 661 m_pDecodeInfo[j].decode_max); | 648 m_pDecodeInfo[j].decode_max); |
| 662 } | 649 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 675 | 662 |
| 676 FX_BOOL CPDF_PSFunc::v_Init(CPDF_Object* pObj) { | 663 FX_BOOL CPDF_PSFunc::v_Init(CPDF_Object* pObj) { |
| 677 CPDF_Stream* pStream = pObj->AsStream(); | 664 CPDF_Stream* pStream = pObj->AsStream(); |
| 678 CPDF_StreamAcc acc; | 665 CPDF_StreamAcc acc; |
| 679 acc.LoadAllData(pStream, FALSE); | 666 acc.LoadAllData(pStream, FALSE); |
| 680 return m_PS.Parse((const FX_CHAR*)acc.GetData(), acc.GetSize()); | 667 return m_PS.Parse((const FX_CHAR*)acc.GetData(), acc.GetSize()); |
| 681 } | 668 } |
| 682 FX_BOOL CPDF_PSFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const { | 669 FX_BOOL CPDF_PSFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const { |
| 683 CPDF_PSEngine& PS = (CPDF_PSEngine&)m_PS; | 670 CPDF_PSEngine& PS = (CPDF_PSEngine&)m_PS; |
| 684 PS.Reset(); | 671 PS.Reset(); |
| 685 int i; | 672 for (uint32_t i = 0; i < m_nInputs; i++) |
| 686 for (i = 0; i < m_nInputs; i++) { | |
| 687 PS.Push(inputs[i]); | 673 PS.Push(inputs[i]); |
| 688 } | |
| 689 PS.Execute(); | 674 PS.Execute(); |
| 690 if (PS.GetStackSize() < m_nOutputs) { | 675 if (PS.GetStackSize() < m_nOutputs) |
| 691 return FALSE; | 676 return FALSE; |
| 692 } | 677 for (uint32_t i = 0; i < m_nOutputs; i++) |
| 693 for (i = 0; i < m_nOutputs; i++) { | |
| 694 results[m_nOutputs - i - 1] = PS.Pop(); | 678 results[m_nOutputs - i - 1] = PS.Pop(); |
| 695 } | |
| 696 return TRUE; | 679 return TRUE; |
| 697 } | 680 } |
| 698 | 681 |
| 699 } // namespace | 682 } // namespace |
| 700 | 683 |
| 701 CPDF_ExpIntFunc::CPDF_ExpIntFunc() | 684 CPDF_ExpIntFunc::CPDF_ExpIntFunc() |
| 702 : CPDF_Function(Type::kType2ExpotentialInterpolation) { | 685 : CPDF_Function(Type::kType2ExpotentialInterpolation) { |
| 703 m_pBeginValues = NULL; | 686 m_pBeginValues = NULL; |
| 704 m_pEndValues = NULL; | 687 m_pEndValues = NULL; |
| 705 } | 688 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 716 CPDF_Array* pArray0 = pDict->GetArrayBy("C0"); | 699 CPDF_Array* pArray0 = pDict->GetArrayBy("C0"); |
| 717 if (m_nOutputs == 0) { | 700 if (m_nOutputs == 0) { |
| 718 m_nOutputs = 1; | 701 m_nOutputs = 1; |
| 719 if (pArray0) { | 702 if (pArray0) { |
| 720 m_nOutputs = pArray0->GetCount(); | 703 m_nOutputs = pArray0->GetCount(); |
| 721 } | 704 } |
| 722 } | 705 } |
| 723 CPDF_Array* pArray1 = pDict->GetArrayBy("C1"); | 706 CPDF_Array* pArray1 = pDict->GetArrayBy("C1"); |
| 724 m_pBeginValues = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2); | 707 m_pBeginValues = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2); |
| 725 m_pEndValues = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2); | 708 m_pEndValues = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2); |
| 726 for (int i = 0; i < m_nOutputs; i++) { | 709 for (uint32_t i = 0; i < m_nOutputs; i++) { |
| 727 m_pBeginValues[i] = pArray0 ? pArray0->GetFloatAt(i) : 0.0f; | 710 m_pBeginValues[i] = pArray0 ? pArray0->GetFloatAt(i) : 0.0f; |
| 728 m_pEndValues[i] = pArray1 ? pArray1->GetFloatAt(i) : 1.0f; | 711 m_pEndValues[i] = pArray1 ? pArray1->GetFloatAt(i) : 1.0f; |
| 729 } | 712 } |
| 730 m_Exponent = pDict->GetFloatBy("N"); | 713 m_Exponent = pDict->GetFloatBy("N"); |
| 731 m_nOrigOutputs = m_nOutputs; | 714 m_nOrigOutputs = m_nOutputs; |
| 732 if (m_nOutputs && m_nInputs > INT_MAX / m_nOutputs) { | 715 if (m_nOutputs && m_nInputs > INT_MAX / m_nOutputs) { |
| 733 return FALSE; | 716 return FALSE; |
| 734 } | 717 } |
| 735 m_nOutputs *= m_nInputs; | 718 m_nOutputs *= m_nInputs; |
| 736 return TRUE; | 719 return TRUE; |
| 737 } | 720 } |
| 738 FX_BOOL CPDF_ExpIntFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const { | 721 FX_BOOL CPDF_ExpIntFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const { |
| 739 for (int i = 0; i < m_nInputs; i++) | 722 for (uint32_t i = 0; i < m_nInputs; i++) |
| 740 for (int j = 0; j < m_nOrigOutputs; j++) { | 723 for (uint32_t j = 0; j < m_nOrigOutputs; j++) { |
| 741 results[i * m_nOrigOutputs + j] = | 724 results[i * m_nOrigOutputs + j] = |
| 742 m_pBeginValues[j] + | 725 m_pBeginValues[j] + |
| 743 (FX_FLOAT)FXSYS_pow(inputs[i], m_Exponent) * | 726 (FX_FLOAT)FXSYS_pow(inputs[i], m_Exponent) * |
| 744 (m_pEndValues[j] - m_pBeginValues[j]); | 727 (m_pEndValues[j] - m_pBeginValues[j]); |
| 745 } | 728 } |
| 746 return TRUE; | 729 return TRUE; |
| 747 } | 730 } |
| 748 | 731 |
| 749 CPDF_StitchFunc::CPDF_StitchFunc() : CPDF_Function(Type::kType3Stitching) { | 732 CPDF_StitchFunc::CPDF_StitchFunc() : CPDF_Function(Type::kType3Stitching) { |
| 750 m_pBounds = NULL; | 733 m_pBounds = NULL; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 764 return FALSE; | 747 return FALSE; |
| 765 } | 748 } |
| 766 if (m_nInputs != kRequiredNumInputs) { | 749 if (m_nInputs != kRequiredNumInputs) { |
| 767 return FALSE; | 750 return FALSE; |
| 768 } | 751 } |
| 769 CPDF_Array* pArray = pDict->GetArrayBy("Functions"); | 752 CPDF_Array* pArray = pDict->GetArrayBy("Functions"); |
| 770 if (!pArray) { | 753 if (!pArray) { |
| 771 return FALSE; | 754 return FALSE; |
| 772 } | 755 } |
| 773 uint32_t nSubs = pArray->GetCount(); | 756 uint32_t nSubs = pArray->GetCount(); |
| 774 if (nSubs == 0) { | 757 if (nSubs == 0) |
| 775 return FALSE; | 758 return FALSE; |
| 776 } | |
| 777 m_nOutputs = 0; | 759 m_nOutputs = 0; |
| 778 for (uint32_t i = 0; i < nSubs; i++) { | 760 for (uint32_t i = 0; i < nSubs; i++) { |
| 779 CPDF_Object* pSub = pArray->GetElementValue(i); | 761 CPDF_Object* pSub = pArray->GetElementValue(i); |
| 780 if (pSub == pObj) { | 762 if (pSub == pObj) |
| 781 return FALSE; | 763 return FALSE; |
| 782 } | |
| 783 std::unique_ptr<CPDF_Function> pFunc(CPDF_Function::Load(pSub)); | 764 std::unique_ptr<CPDF_Function> pFunc(CPDF_Function::Load(pSub)); |
| 784 if (!pFunc) { | 765 if (!pFunc) |
| 785 return FALSE; | 766 return FALSE; |
| 786 } | |
| 787 // Check that the input dimensionality is 1, and that all output | 767 // Check that the input dimensionality is 1, and that all output |
| 788 // dimensionalities are the same. | 768 // dimensionalities are the same. |
| 789 if (pFunc->CountInputs() != kRequiredNumInputs) { | 769 if (pFunc->CountInputs() != kRequiredNumInputs) |
| 790 return FALSE; | 770 return FALSE; |
| 791 } | |
| 792 if (pFunc->CountOutputs() != m_nOutputs) { | 771 if (pFunc->CountOutputs() != m_nOutputs) { |
| 793 if (m_nOutputs) | 772 if (m_nOutputs) |
| 794 return FALSE; | 773 return FALSE; |
| 795 | 774 |
| 796 m_nOutputs = pFunc->CountOutputs(); | 775 m_nOutputs = pFunc->CountOutputs(); |
| 797 } | 776 } |
| 798 | 777 |
| 799 m_pSubFunctions.push_back(pFunc.release()); | 778 m_pSubFunctions.push_back(pFunc.release()); |
| 800 } | 779 } |
| 801 m_pBounds = FX_Alloc(FX_FLOAT, nSubs + 1); | 780 m_pBounds = FX_Alloc(FX_FLOAT, nSubs + 1); |
| 802 m_pBounds[0] = m_pDomains[0]; | 781 m_pBounds[0] = m_pDomains[0]; |
| 803 pArray = pDict->GetArrayBy("Bounds"); | 782 pArray = pDict->GetArrayBy("Bounds"); |
| 804 if (!pArray) { | 783 if (!pArray) |
| 805 return FALSE; | 784 return FALSE; |
| 806 } | 785 for (uint32_t i = 0; i < nSubs - 1; i++) |
| 807 for (uint32_t i = 0; i < nSubs - 1; i++) { | |
| 808 m_pBounds[i + 1] = pArray->GetFloatAt(i); | 786 m_pBounds[i + 1] = pArray->GetFloatAt(i); |
| 809 } | |
| 810 m_pBounds[nSubs] = m_pDomains[1]; | 787 m_pBounds[nSubs] = m_pDomains[1]; |
| 811 m_pEncode = FX_Alloc2D(FX_FLOAT, nSubs, 2); | 788 m_pEncode = FX_Alloc2D(FX_FLOAT, nSubs, 2); |
| 812 pArray = pDict->GetArrayBy("Encode"); | 789 pArray = pDict->GetArrayBy("Encode"); |
| 813 if (!pArray) { | 790 if (!pArray) |
| 814 return FALSE; | 791 return FALSE; |
| 815 } | 792 |
| 816 for (uint32_t i = 0; i < nSubs * 2; i++) { | 793 for (uint32_t i = 0; i < nSubs * 2; i++) |
| 817 m_pEncode[i] = pArray->GetFloatAt(i); | 794 m_pEncode[i] = pArray->GetFloatAt(i); |
| 818 } | |
| 819 return TRUE; | 795 return TRUE; |
| 820 } | 796 } |
| 821 FX_BOOL CPDF_StitchFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* outputs) const { | 797 FX_BOOL CPDF_StitchFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* outputs) const { |
| 822 FX_FLOAT input = inputs[0]; | 798 FX_FLOAT input = inputs[0]; |
| 823 size_t i; | 799 size_t i; |
| 824 for (i = 0; i < m_pSubFunctions.size() - 1; i++) | 800 for (i = 0; i < m_pSubFunctions.size() - 1; i++) { |
| 825 if (input < m_pBounds[i + 1]) { | 801 if (input < m_pBounds[i + 1]) |
| 826 break; | 802 break; |
| 827 } | 803 } |
| 828 if (!m_pSubFunctions[i]) { | 804 if (!m_pSubFunctions[i]) { |
| 829 return FALSE; | 805 return FALSE; |
| 830 } | 806 } |
| 831 input = PDF_Interpolate(input, m_pBounds[i], m_pBounds[i + 1], | 807 input = PDF_Interpolate(input, m_pBounds[i], m_pBounds[i + 1], |
| 832 m_pEncode[i * 2], m_pEncode[i * 2 + 1]); | 808 m_pEncode[i * 2], m_pEncode[i * 2 + 1]); |
| 833 int nresults; | 809 int nresults; |
| 834 m_pSubFunctions[i]->Call(&input, kRequiredNumInputs, outputs, nresults); | 810 m_pSubFunctions[i]->Call(&input, kRequiredNumInputs, outputs, nresults); |
| 835 return TRUE; | 811 return TRUE; |
| 836 } | 812 } |
| 837 | 813 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 | 857 |
| 882 CPDF_Array* pDomains = pDict->GetArrayBy("Domain"); | 858 CPDF_Array* pDomains = pDict->GetArrayBy("Domain"); |
| 883 if (!pDomains) | 859 if (!pDomains) |
| 884 return FALSE; | 860 return FALSE; |
| 885 | 861 |
| 886 m_nInputs = pDomains->GetCount() / 2; | 862 m_nInputs = pDomains->GetCount() / 2; |
| 887 if (m_nInputs == 0) | 863 if (m_nInputs == 0) |
| 888 return FALSE; | 864 return FALSE; |
| 889 | 865 |
| 890 m_pDomains = FX_Alloc2D(FX_FLOAT, m_nInputs, 2); | 866 m_pDomains = FX_Alloc2D(FX_FLOAT, m_nInputs, 2); |
| 891 for (int i = 0; i < m_nInputs * 2; i++) { | 867 for (uint32_t i = 0; i < m_nInputs * 2; i++) { |
| 892 m_pDomains[i] = pDomains->GetFloatAt(i); | 868 m_pDomains[i] = pDomains->GetFloatAt(i); |
| 893 } | 869 } |
| 894 CPDF_Array* pRanges = pDict->GetArrayBy("Range"); | 870 CPDF_Array* pRanges = pDict->GetArrayBy("Range"); |
| 895 m_nOutputs = 0; | 871 m_nOutputs = 0; |
| 896 if (pRanges) { | 872 if (pRanges) { |
| 897 m_nOutputs = pRanges->GetCount() / 2; | 873 m_nOutputs = pRanges->GetCount() / 2; |
| 898 m_pRanges = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2); | 874 m_pRanges = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2); |
| 899 for (int i = 0; i < m_nOutputs * 2; i++) { | 875 for (uint32_t i = 0; i < m_nOutputs * 2; i++) |
| 900 m_pRanges[i] = pRanges->GetFloatAt(i); | 876 m_pRanges[i] = pRanges->GetFloatAt(i); |
| 901 } | |
| 902 } | 877 } |
| 903 uint32_t old_outputs = m_nOutputs; | 878 uint32_t old_outputs = m_nOutputs; |
| 904 if (!v_Init(pObj)) { | 879 if (!v_Init(pObj)) |
| 905 return FALSE; | 880 return FALSE; |
| 906 } | 881 if (m_pRanges && m_nOutputs > old_outputs) { |
| 907 if (m_pRanges && m_nOutputs > (int)old_outputs) { | |
| 908 m_pRanges = FX_Realloc(FX_FLOAT, m_pRanges, m_nOutputs * 2); | 882 m_pRanges = FX_Realloc(FX_FLOAT, m_pRanges, m_nOutputs * 2); |
| 909 if (m_pRanges) { | 883 if (m_pRanges) { |
| 910 FXSYS_memset(m_pRanges + (old_outputs * 2), 0, | 884 FXSYS_memset(m_pRanges + (old_outputs * 2), 0, |
| 911 sizeof(FX_FLOAT) * (m_nOutputs - old_outputs) * 2); | 885 sizeof(FX_FLOAT) * (m_nOutputs - old_outputs) * 2); |
| 912 } | 886 } |
| 913 } | 887 } |
| 914 return TRUE; | 888 return TRUE; |
| 915 } | 889 } |
| 916 FX_BOOL CPDF_Function::Call(FX_FLOAT* inputs, | 890 FX_BOOL CPDF_Function::Call(FX_FLOAT* inputs, |
| 917 int ninputs, | 891 uint32_t ninputs, |
| 918 FX_FLOAT* results, | 892 FX_FLOAT* results, |
| 919 int& nresults) const { | 893 int& nresults) const { |
| 920 if (m_nInputs != ninputs) { | 894 if (m_nInputs != ninputs) { |
| 921 return FALSE; | 895 return FALSE; |
| 922 } | 896 } |
| 923 nresults = m_nOutputs; | 897 nresults = m_nOutputs; |
| 924 for (int i = 0; i < m_nInputs; i++) { | 898 for (uint32_t i = 0; i < m_nInputs; i++) { |
| 925 if (inputs[i] < m_pDomains[i * 2]) { | 899 if (inputs[i] < m_pDomains[i * 2]) |
| 926 inputs[i] = m_pDomains[i * 2]; | 900 inputs[i] = m_pDomains[i * 2]; |
| 927 } else if (inputs[i] > m_pDomains[i * 2 + 1]) { | 901 else if (inputs[i] > m_pDomains[i * 2 + 1]) |
| 928 inputs[i] = m_pDomains[i * 2] + 1; | 902 inputs[i] = m_pDomains[i * 2] + 1; |
| 929 } | |
| 930 } | 903 } |
| 931 v_Call(inputs, results); | 904 v_Call(inputs, results); |
| 932 if (m_pRanges) { | 905 if (m_pRanges) { |
| 933 for (int i = 0; i < m_nOutputs; i++) { | 906 for (uint32_t i = 0; i < m_nOutputs; i++) { |
| 934 if (results[i] < m_pRanges[i * 2]) { | 907 if (results[i] < m_pRanges[i * 2]) |
| 935 results[i] = m_pRanges[i * 2]; | 908 results[i] = m_pRanges[i * 2]; |
| 936 } else if (results[i] > m_pRanges[i * 2 + 1]) { | 909 else if (results[i] > m_pRanges[i * 2 + 1]) |
| 937 results[i] = m_pRanges[i * 2 + 1]; | 910 results[i] = m_pRanges[i * 2 + 1]; |
| 938 } | |
| 939 } | 911 } |
| 940 } | 912 } |
| 941 return TRUE; | 913 return TRUE; |
| 942 } | 914 } |
| OLD | NEW |