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 |
| 11 #include <algorithm> | 11 #include <algorithm> |
| 12 #include <memory> | 12 #include <memory> |
| 13 #include <utility> | 13 #include <utility> |
| 14 #include <vector> | 14 #include <vector> |
| 15 | 15 |
| 16 #include "core/fpdfapi/fpdf_page/cpdf_psengine.h" | |
| 16 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" | 17 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" |
| 17 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" | 18 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" |
| 18 #include "core/fpdfapi/fpdf_parser/include/cpdf_simple_parser.h" | 19 #include "core/fpdfapi/fpdf_parser/include/cpdf_simple_parser.h" |
| 19 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h" | 20 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h" |
| 20 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h" | 21 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h" |
| 21 #include "core/fxcrt/include/fx_safe_types.h" | 22 #include "core/fxcrt/include/fx_safe_types.h" |
| 22 #include "third_party/base/numerics/safe_conversions_impl.h" | 23 #include "third_party/base/numerics/safe_conversions_impl.h" |
| 23 | 24 |
| 24 namespace { | |
| 25 | |
| 26 enum PDF_PSOP { | |
| 27 PSOP_ADD, | |
| 28 PSOP_SUB, | |
| 29 PSOP_MUL, | |
| 30 PSOP_DIV, | |
| 31 PSOP_IDIV, | |
| 32 PSOP_MOD, | |
| 33 PSOP_NEG, | |
| 34 PSOP_ABS, | |
| 35 PSOP_CEILING, | |
| 36 PSOP_FLOOR, | |
| 37 PSOP_ROUND, | |
| 38 PSOP_TRUNCATE, | |
| 39 PSOP_SQRT, | |
| 40 PSOP_SIN, | |
| 41 PSOP_COS, | |
| 42 PSOP_ATAN, | |
| 43 PSOP_EXP, | |
| 44 PSOP_LN, | |
| 45 PSOP_LOG, | |
| 46 PSOP_CVI, | |
| 47 PSOP_CVR, | |
| 48 PSOP_EQ, | |
| 49 PSOP_NE, | |
| 50 PSOP_GT, | |
| 51 PSOP_GE, | |
| 52 PSOP_LT, | |
| 53 PSOP_LE, | |
| 54 PSOP_AND, | |
| 55 PSOP_OR, | |
| 56 PSOP_XOR, | |
| 57 PSOP_NOT, | |
| 58 PSOP_BITSHIFT, | |
| 59 PSOP_TRUE, | |
| 60 PSOP_FALSE, | |
| 61 PSOP_IF, | |
| 62 PSOP_IFELSE, | |
| 63 PSOP_POP, | |
| 64 PSOP_EXCH, | |
| 65 PSOP_DUP, | |
| 66 PSOP_COPY, | |
| 67 PSOP_INDEX, | |
| 68 PSOP_ROLL, | |
| 69 PSOP_PROC, | |
| 70 PSOP_CONST | |
| 71 }; | |
| 72 | |
| 73 class CPDF_PSEngine; | |
| 74 class CPDF_PSProc; | |
| 75 | |
| 76 class CPDF_PSOP { | 25 class CPDF_PSOP { |
|
Lei Zhang
2016/08/18 06:21:39
Would be nice to move these out to their own file
Tom Sepez
2016/08/18 21:23:07
Agreed, someday.
| |
| 77 public: | 26 public: |
| 78 explicit CPDF_PSOP(PDF_PSOP op) : m_op(op), m_value(0) { | 27 explicit CPDF_PSOP(PDF_PSOP op) : m_op(op), m_value(0) { |
| 79 ASSERT(m_op != PSOP_CONST); | 28 ASSERT(m_op != PSOP_CONST); |
| 80 ASSERT(m_op != PSOP_PROC); | 29 ASSERT(m_op != PSOP_PROC); |
| 81 } | 30 } |
| 82 explicit CPDF_PSOP(FX_FLOAT value) : m_op(PSOP_CONST), m_value(value) {} | 31 explicit CPDF_PSOP(FX_FLOAT value) : m_op(PSOP_CONST), m_value(value) {} |
| 83 explicit CPDF_PSOP(std::unique_ptr<CPDF_PSProc> proc) | 32 explicit CPDF_PSOP(std::unique_ptr<CPDF_PSProc> proc) |
| 84 : m_op(PSOP_PROC), m_value(0), m_proc(std::move(proc)) {} | 33 : m_op(PSOP_PROC), m_value(0), m_proc(std::move(proc)) {} |
| 85 | 34 |
| 86 FX_FLOAT GetFloatValue() const { | 35 FX_FLOAT GetFloatValue() const { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 98 } | 47 } |
| 99 | 48 |
| 100 PDF_PSOP GetOp() const { return m_op; } | 49 PDF_PSOP GetOp() const { return m_op; } |
| 101 | 50 |
| 102 private: | 51 private: |
| 103 const PDF_PSOP m_op; | 52 const PDF_PSOP m_op; |
| 104 const FX_FLOAT m_value; | 53 const FX_FLOAT m_value; |
| 105 std::unique_ptr<CPDF_PSProc> m_proc; | 54 std::unique_ptr<CPDF_PSProc> m_proc; |
| 106 }; | 55 }; |
| 107 | 56 |
| 108 class CPDF_PSProc { | 57 FX_BOOL CPDF_PSEngine::Execute() { |
| 109 public: | 58 return m_MainProc.Execute(this); |
| 110 CPDF_PSProc() {} | 59 } |
| 111 ~CPDF_PSProc() {} | |
| 112 | 60 |
| 113 FX_BOOL Parse(CPDF_SimpleParser* parser); | 61 CPDF_PSProc::CPDF_PSProc() {} |
| 114 FX_BOOL Execute(CPDF_PSEngine* pEngine); | 62 CPDF_PSProc::~CPDF_PSProc() {} |
| 115 | |
| 116 private: | |
| 117 std::vector<std::unique_ptr<CPDF_PSOP>> m_Operators; | |
| 118 }; | |
| 119 | |
| 120 const uint32_t PSENGINE_STACKSIZE = 100; | |
| 121 | |
| 122 class CPDF_PSEngine { | |
| 123 public: | |
| 124 CPDF_PSEngine(); | |
| 125 ~CPDF_PSEngine(); | |
| 126 | |
| 127 FX_BOOL Parse(const FX_CHAR* str, int size); | |
| 128 FX_BOOL Execute() { return m_MainProc.Execute(this); } | |
| 129 FX_BOOL DoOperator(PDF_PSOP op); | |
| 130 void Reset() { m_StackCount = 0; } | |
| 131 void Push(FX_FLOAT value); | |
| 132 void Push(int value) { Push((FX_FLOAT)value); } | |
| 133 FX_FLOAT Pop(); | |
| 134 uint32_t GetStackSize() const { return m_StackCount; } | |
| 135 | |
| 136 private: | |
| 137 FX_FLOAT m_Stack[PSENGINE_STACKSIZE]; | |
| 138 uint32_t m_StackCount; | |
| 139 CPDF_PSProc m_MainProc; | |
| 140 }; | |
| 141 | 63 |
| 142 FX_BOOL CPDF_PSProc::Execute(CPDF_PSEngine* pEngine) { | 64 FX_BOOL CPDF_PSProc::Execute(CPDF_PSEngine* pEngine) { |
| 143 for (size_t i = 0; i < m_Operators.size(); ++i) { | 65 for (size_t i = 0; i < m_Operators.size(); ++i) { |
| 144 const PDF_PSOP op = m_Operators[i]->GetOp(); | 66 const PDF_PSOP op = m_Operators[i]->GetOp(); |
| 145 if (op == PSOP_PROC) | 67 if (op == PSOP_PROC) |
| 146 continue; | 68 continue; |
| 147 | 69 |
| 148 if (op == PSOP_CONST) { | 70 if (op == PSOP_CONST) { |
| 149 pEngine->Push(m_Operators[i]->GetFloatValue()); | 71 pEngine->Push(m_Operators[i]->GetFloatValue()); |
| 150 continue; | 72 continue; |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 273 Push(d1 * d2); | 195 Push(d1 * d2); |
| 274 break; | 196 break; |
| 275 case PSOP_DIV: | 197 case PSOP_DIV: |
| 276 d2 = Pop(); | 198 d2 = Pop(); |
| 277 d1 = Pop(); | 199 d1 = Pop(); |
| 278 Push(d1 / d2); | 200 Push(d1 / d2); |
| 279 break; | 201 break; |
| 280 case PSOP_IDIV: | 202 case PSOP_IDIV: |
| 281 i2 = (int)Pop(); | 203 i2 = (int)Pop(); |
| 282 i1 = (int)Pop(); | 204 i1 = (int)Pop(); |
| 283 Push(i1 / i2); | 205 if (i2) |
|
Lei Zhang
2016/08/18 06:21:39
1 Push() with a ternary operator inside? Ditto for
Tom Sepez
2016/08/18 21:23:07
Done.
| |
| 206 Push(i1 / i2); | |
| 207 else | |
| 208 Push(0); | |
| 284 break; | 209 break; |
| 285 case PSOP_MOD: | 210 case PSOP_MOD: |
| 286 i2 = (int)Pop(); | 211 i2 = (int)Pop(); |
| 287 i1 = (int)Pop(); | 212 i1 = (int)Pop(); |
| 288 Push(i1 % i2); | 213 if (i2) |
| 214 Push(i1 % i2); | |
| 215 else | |
| 216 Push(0); | |
| 289 break; | 217 break; |
| 290 case PSOP_NEG: | 218 case PSOP_NEG: |
| 291 d1 = Pop(); | 219 d1 = Pop(); |
| 292 Push(-d1); | 220 Push(-d1); |
| 293 break; | 221 break; |
| 294 case PSOP_ABS: | 222 case PSOP_ABS: |
| 295 d1 = Pop(); | 223 d1 = Pop(); |
| 296 Push((FX_FLOAT)FXSYS_fabs(d1)); | 224 Push((FX_FLOAT)FXSYS_fabs(d1)); |
| 297 break; | 225 break; |
| 298 case PSOP_CEILING: | 226 case PSOP_CEILING: |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 531 for (uint32_t i = 0; i < m_nInputs; i++) | 459 for (uint32_t i = 0; i < m_nInputs; i++) |
| 532 PS.Push(inputs[i]); | 460 PS.Push(inputs[i]); |
| 533 PS.Execute(); | 461 PS.Execute(); |
| 534 if (PS.GetStackSize() < m_nOutputs) | 462 if (PS.GetStackSize() < m_nOutputs) |
| 535 return FALSE; | 463 return FALSE; |
| 536 for (uint32_t i = 0; i < m_nOutputs; i++) | 464 for (uint32_t i = 0; i < m_nOutputs; i++) |
| 537 results[m_nOutputs - i - 1] = PS.Pop(); | 465 results[m_nOutputs - i - 1] = PS.Pop(); |
| 538 return TRUE; | 466 return TRUE; |
| 539 } | 467 } |
| 540 | 468 |
| 541 } // namespace | |
| 542 | 469 |
| 543 CPDF_SampledFunc::CPDF_SampledFunc() : CPDF_Function(Type::kType0Sampled) {} | 470 CPDF_SampledFunc::CPDF_SampledFunc() : CPDF_Function(Type::kType0Sampled) {} |
| 544 | 471 |
| 545 CPDF_SampledFunc::~CPDF_SampledFunc() {} | 472 CPDF_SampledFunc::~CPDF_SampledFunc() {} |
| 546 | 473 |
| 547 FX_BOOL CPDF_SampledFunc::v_Init(CPDF_Object* pObj) { | 474 FX_BOOL CPDF_SampledFunc::v_Init(CPDF_Object* pObj) { |
| 548 CPDF_Stream* pStream = pObj->AsStream(); | 475 CPDF_Stream* pStream = pObj->AsStream(); |
| 549 if (!pStream) | 476 if (!pStream) |
| 550 return false; | 477 return false; |
| 551 | 478 |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 912 return m_Type == Type::kType2ExpotentialInterpolation | 839 return m_Type == Type::kType2ExpotentialInterpolation |
| 913 ? static_cast<const CPDF_ExpIntFunc*>(this) | 840 ? static_cast<const CPDF_ExpIntFunc*>(this) |
| 914 : nullptr; | 841 : nullptr; |
| 915 } | 842 } |
| 916 | 843 |
| 917 const CPDF_StitchFunc* CPDF_Function::ToStitchFunc() const { | 844 const CPDF_StitchFunc* CPDF_Function::ToStitchFunc() const { |
| 918 return m_Type == Type::kType3Stitching | 845 return m_Type == Type::kType3Stitching |
| 919 ? static_cast<const CPDF_StitchFunc*>(this) | 846 ? static_cast<const CPDF_StitchFunc*>(this) |
| 920 : nullptr; | 847 : nullptr; |
| 921 } | 848 } |
| OLD | NEW |