summaryrefslogtreecommitdiffstats
path: root/vendor/setasign/fpdi/src/PdfParser/Type
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-14 13:26:02 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-14 13:26:02 +0000
commitfcbf3ce37ca8f90a3e36d524a3274ffc063a40e3 (patch)
tree84c735df2e97350a721273e9dd425729d43cc8a2 /vendor/setasign/fpdi/src/PdfParser/Type
parentInitial commit. (diff)
downloadicingaweb2-module-pdfexport-upstream.tar.xz
icingaweb2-module-pdfexport-upstream.zip
Adding upstream version 0.10.2+dfsg1.upstream/0.10.2+dfsg1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--vendor/setasign/fpdi/src/PdfParser/Type/PdfArray.php85
-rw-r--r--vendor/setasign/fpdi/src/PdfParser/Type/PdfBoolean.php42
-rw-r--r--vendor/setasign/fpdi/src/PdfParser/Type/PdfDictionary.php134
-rw-r--r--vendor/setasign/fpdi/src/PdfParser/Type/PdfHexString.php77
-rw-r--r--vendor/setasign/fpdi/src/PdfParser/Type/PdfIndirectObject.php103
-rw-r--r--vendor/setasign/fpdi/src/PdfParser/Type/PdfIndirectObjectReference.php52
-rw-r--r--vendor/setasign/fpdi/src/PdfParser/Type/PdfName.php82
-rw-r--r--vendor/setasign/fpdi/src/PdfParser/Type/PdfNull.php19
-rw-r--r--vendor/setasign/fpdi/src/PdfParser/Type/PdfNumeric.php43
-rw-r--r--vendor/setasign/fpdi/src/PdfParser/Type/PdfStream.php326
-rw-r--r--vendor/setasign/fpdi/src/PdfParser/Type/PdfString.php172
-rw-r--r--vendor/setasign/fpdi/src/PdfParser/Type/PdfToken.php43
-rw-r--r--vendor/setasign/fpdi/src/PdfParser/Type/PdfType.php78
-rw-r--r--vendor/setasign/fpdi/src/PdfParser/Type/PdfTypeException.php24
14 files changed, 1280 insertions, 0 deletions
diff --git a/vendor/setasign/fpdi/src/PdfParser/Type/PdfArray.php b/vendor/setasign/fpdi/src/PdfParser/Type/PdfArray.php
new file mode 100644
index 0000000..5d0bbbd
--- /dev/null
+++ b/vendor/setasign/fpdi/src/PdfParser/Type/PdfArray.php
@@ -0,0 +1,85 @@
+<?php
+
+/**
+ * This file is part of FPDI
+ *
+ * @package setasign\Fpdi
+ * @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
+ * @license http://opensource.org/licenses/mit-license The MIT License
+ */
+
+namespace setasign\Fpdi\PdfParser\Type;
+
+use setasign\Fpdi\PdfParser\PdfParser;
+use setasign\Fpdi\PdfParser\Tokenizer;
+
+/**
+ * Class representing a PDF array object
+ *
+ * @property array $value The value of the PDF type.
+ */
+class PdfArray extends PdfType
+{
+ /**
+ * Parses an array of the passed tokenizer and parser.
+ *
+ * @param Tokenizer $tokenizer
+ * @param PdfParser $parser
+ * @return bool|self
+ * @throws PdfTypeException
+ */
+ public static function parse(Tokenizer $tokenizer, PdfParser $parser)
+ {
+ $result = [];
+
+ // Recurse into this function until we reach the end of the array.
+ while (($token = $tokenizer->getNextToken()) !== ']') {
+ if ($token === false || ($value = $parser->readValue($token)) === false) {
+ return false;
+ }
+
+ $result[] = $value;
+ }
+
+ $v = new self();
+ $v->value = $result;
+
+ return $v;
+ }
+
+ /**
+ * Helper method to create an instance.
+ *
+ * @param PdfType[] $values
+ * @return self
+ */
+ public static function create(array $values = [])
+ {
+ $v = new self();
+ $v->value = $values;
+
+ return $v;
+ }
+
+ /**
+ * Ensures that the passed array is a PdfArray instance with a (optional) specific size.
+ *
+ * @param mixed $array
+ * @param null|int $size
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($array, $size = null)
+ {
+ $result = PdfType::ensureType(self::class, $array, 'Array value expected.');
+
+ if ($size !== null && \count($array->value) !== $size) {
+ throw new PdfTypeException(
+ \sprintf('Array with %s entries expected.', $size),
+ PdfTypeException::INVALID_DATA_SIZE
+ );
+ }
+
+ return $result;
+ }
+}
diff --git a/vendor/setasign/fpdi/src/PdfParser/Type/PdfBoolean.php b/vendor/setasign/fpdi/src/PdfParser/Type/PdfBoolean.php
new file mode 100644
index 0000000..ba4233a
--- /dev/null
+++ b/vendor/setasign/fpdi/src/PdfParser/Type/PdfBoolean.php
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * This file is part of FPDI
+ *
+ * @package setasign\Fpdi
+ * @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
+ * @license http://opensource.org/licenses/mit-license The MIT License
+ */
+
+namespace setasign\Fpdi\PdfParser\Type;
+
+/**
+ * Class representing a boolean PDF object
+ */
+class PdfBoolean extends PdfType
+{
+ /**
+ * Helper method to create an instance.
+ *
+ * @param bool $value
+ * @return self
+ */
+ public static function create($value)
+ {
+ $v = new self();
+ $v->value = (bool) $value;
+ return $v;
+ }
+
+ /**
+ * Ensures that the passed value is a PdfBoolean instance.
+ *
+ * @param mixed $value
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($value)
+ {
+ return PdfType::ensureType(self::class, $value, 'Boolean value expected.');
+ }
+}
diff --git a/vendor/setasign/fpdi/src/PdfParser/Type/PdfDictionary.php b/vendor/setasign/fpdi/src/PdfParser/Type/PdfDictionary.php
new file mode 100644
index 0000000..2818842
--- /dev/null
+++ b/vendor/setasign/fpdi/src/PdfParser/Type/PdfDictionary.php
@@ -0,0 +1,134 @@
+<?php
+
+/**
+ * This file is part of FPDI
+ *
+ * @package setasign\Fpdi
+ * @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
+ * @license http://opensource.org/licenses/mit-license The MIT License
+ */
+
+namespace setasign\Fpdi\PdfParser\Type;
+
+use setasign\Fpdi\PdfParser\PdfParser;
+use setasign\Fpdi\PdfParser\StreamReader;
+use setasign\Fpdi\PdfParser\Tokenizer;
+
+/**
+ * Class representing a PDF dictionary object
+ */
+class PdfDictionary extends PdfType
+{
+ /**
+ * Parses a dictionary of the passed tokenizer, stream-reader and parser.
+ *
+ * @param Tokenizer $tokenizer
+ * @param StreamReader $streamReader
+ * @param PdfParser $parser
+ * @return bool|self
+ * @throws PdfTypeException
+ */
+ public static function parse(Tokenizer $tokenizer, StreamReader $streamReader, PdfParser $parser)
+ {
+ $entries = [];
+
+ while (true) {
+ $token = $tokenizer->getNextToken();
+ if ($token === '>' && $streamReader->getByte() === '>') {
+ $streamReader->addOffset(1);
+ break;
+ }
+
+ $key = $parser->readValue($token);
+ if ($key === false) {
+ return false;
+ }
+
+ // ensure the first value to be a Name object
+ if (!($key instanceof PdfName)) {
+ $lastToken = null;
+ // ignore all other entries and search for the closing brackets
+ while (($token = $tokenizer->getNextToken()) !== '>' && $token !== false && $lastToken !== '>') {
+ $lastToken = $token;
+ }
+
+ if ($token === false) {
+ return false;
+ }
+
+ break;
+ }
+
+
+ $value = $parser->readValue();
+ if ($value === false) {
+ return false;
+ }
+
+ if ($value instanceof PdfNull) {
+ continue;
+ }
+
+ // catch missing value
+ if ($value instanceof PdfToken && $value->value === '>' && $streamReader->getByte() === '>') {
+ $streamReader->addOffset(1);
+ break;
+ }
+
+ $entries[$key->value] = $value;
+ }
+
+ $v = new self();
+ $v->value = $entries;
+
+ return $v;
+ }
+
+ /**
+ * Helper method to create an instance.
+ *
+ * @param PdfType[] $entries The keys are the name entries of the dictionary.
+ * @return self
+ */
+ public static function create(array $entries = [])
+ {
+ $v = new self();
+ $v->value = $entries;
+
+ return $v;
+ }
+
+ /**
+ * Get a value by its key from a dictionary or a default value.
+ *
+ * @param mixed $dictionary
+ * @param string $key
+ * @param PdfType|null $default
+ * @return PdfNull|PdfType
+ * @throws PdfTypeException
+ */
+ public static function get($dictionary, $key, PdfType $default = null)
+ {
+ $dictionary = self::ensure($dictionary);
+
+ if (isset($dictionary->value[$key])) {
+ return $dictionary->value[$key];
+ }
+
+ return $default === null
+ ? new PdfNull()
+ : $default;
+ }
+
+ /**
+ * Ensures that the passed value is a PdfDictionary instance.
+ *
+ * @param mixed $dictionary
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($dictionary)
+ {
+ return PdfType::ensureType(self::class, $dictionary, 'Dictionary value expected.');
+ }
+}
diff --git a/vendor/setasign/fpdi/src/PdfParser/Type/PdfHexString.php b/vendor/setasign/fpdi/src/PdfParser/Type/PdfHexString.php
new file mode 100644
index 0000000..0084ada
--- /dev/null
+++ b/vendor/setasign/fpdi/src/PdfParser/Type/PdfHexString.php
@@ -0,0 +1,77 @@
+<?php
+
+/**
+ * This file is part of FPDI
+ *
+ * @package setasign\Fpdi
+ * @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
+ * @license http://opensource.org/licenses/mit-license The MIT License
+ */
+
+namespace setasign\Fpdi\PdfParser\Type;
+
+use setasign\Fpdi\PdfParser\StreamReader;
+
+/**
+ * Class representing a hexadecimal encoded PDF string object
+ */
+class PdfHexString extends PdfType
+{
+ /**
+ * Parses a hexadecimal string object from the stream reader.
+ *
+ * @param StreamReader $streamReader
+ * @return bool|self
+ */
+ public static function parse(StreamReader $streamReader)
+ {
+ $bufferOffset = $streamReader->getOffset();
+
+ while (true) {
+ $buffer = $streamReader->getBuffer(false);
+ $pos = \strpos($buffer, '>', $bufferOffset);
+ if ($pos === false) {
+ if (!$streamReader->increaseLength()) {
+ return false;
+ }
+ continue;
+ }
+
+ break;
+ }
+
+ $result = \substr($buffer, $bufferOffset, $pos - $bufferOffset);
+ $streamReader->setOffset($pos + 1);
+
+ $v = new self();
+ $v->value = $result;
+
+ return $v;
+ }
+
+ /**
+ * Helper method to create an instance.
+ *
+ * @param string $string The hex encoded string.
+ * @return self
+ */
+ public static function create($string)
+ {
+ $v = new self();
+ $v->value = $string;
+
+ return $v;
+ }
+
+ /**
+ * Ensures that the passed value is a PdfHexString instance.
+ *
+ * @param mixed $hexString
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($hexString)
+ {
+ return PdfType::ensureType(self::class, $hexString, 'Hex string value expected.');
+ }
+}
diff --git a/vendor/setasign/fpdi/src/PdfParser/Type/PdfIndirectObject.php b/vendor/setasign/fpdi/src/PdfParser/Type/PdfIndirectObject.php
new file mode 100644
index 0000000..15786d0
--- /dev/null
+++ b/vendor/setasign/fpdi/src/PdfParser/Type/PdfIndirectObject.php
@@ -0,0 +1,103 @@
+<?php
+
+/**
+ * This file is part of FPDI
+ *
+ * @package setasign\Fpdi
+ * @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
+ * @license http://opensource.org/licenses/mit-license The MIT License
+ */
+
+namespace setasign\Fpdi\PdfParser\Type;
+
+use setasign\Fpdi\PdfParser\PdfParser;
+use setasign\Fpdi\PdfParser\StreamReader;
+use setasign\Fpdi\PdfParser\Tokenizer;
+
+/**
+ * Class representing an indirect object
+ */
+class PdfIndirectObject extends PdfType
+{
+ /**
+ * Parses an indirect object from a tokenizer, parser and stream-reader.
+ *
+ * @param int $objectNumberToken
+ * @param int $objectGenerationNumberToken
+ * @param PdfParser $parser
+ * @param Tokenizer $tokenizer
+ * @param StreamReader $reader
+ * @return bool|self
+ * @throws PdfTypeException
+ */
+ public static function parse(
+ $objectNumberToken,
+ $objectGenerationNumberToken,
+ PdfParser $parser,
+ Tokenizer $tokenizer,
+ StreamReader $reader
+ ) {
+ $value = $parser->readValue();
+ if ($value === false) {
+ return false;
+ }
+
+ $nextToken = $tokenizer->getNextToken();
+ if ($nextToken === 'stream') {
+ $value = PdfStream::parse($value, $reader, $parser);
+ } elseif ($nextToken !== false) {
+ $tokenizer->pushStack($nextToken);
+ }
+
+ $v = new self();
+ $v->objectNumber = (int) $objectNumberToken;
+ $v->generationNumber = (int) $objectGenerationNumberToken;
+ $v->value = $value;
+
+ return $v;
+ }
+
+ /**
+ * Helper method to create an instance.
+ *
+ * @param int $objectNumber
+ * @param int $generationNumber
+ * @param PdfType $value
+ * @return self
+ */
+ public static function create($objectNumber, $generationNumber, PdfType $value)
+ {
+ $v = new self();
+ $v->objectNumber = (int) $objectNumber;
+ $v->generationNumber = (int) $generationNumber;
+ $v->value = $value;
+
+ return $v;
+ }
+
+ /**
+ * Ensures that the passed value is a PdfIndirectObject instance.
+ *
+ * @param mixed $indirectObject
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($indirectObject)
+ {
+ return PdfType::ensureType(self::class, $indirectObject, 'Indirect object expected.');
+ }
+
+ /**
+ * The object number.
+ *
+ * @var int
+ */
+ public $objectNumber;
+
+ /**
+ * The generation number.
+ *
+ * @var int
+ */
+ public $generationNumber;
+}
diff --git a/vendor/setasign/fpdi/src/PdfParser/Type/PdfIndirectObjectReference.php b/vendor/setasign/fpdi/src/PdfParser/Type/PdfIndirectObjectReference.php
new file mode 100644
index 0000000..2725d0c
--- /dev/null
+++ b/vendor/setasign/fpdi/src/PdfParser/Type/PdfIndirectObjectReference.php
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * This file is part of FPDI
+ *
+ * @package setasign\Fpdi
+ * @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
+ * @license http://opensource.org/licenses/mit-license The MIT License
+ */
+
+namespace setasign\Fpdi\PdfParser\Type;
+
+/**
+ * Class representing an indirect object reference
+ */
+class PdfIndirectObjectReference extends PdfType
+{
+ /**
+ * Helper method to create an instance.
+ *
+ * @param int $objectNumber
+ * @param int $generationNumber
+ * @return self
+ */
+ public static function create($objectNumber, $generationNumber)
+ {
+ $v = new self();
+ $v->value = (int) $objectNumber;
+ $v->generationNumber = (int) $generationNumber;
+
+ return $v;
+ }
+
+ /**
+ * Ensures that the passed value is a PdfIndirectObject instance.
+ *
+ * @param mixed $value
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($value)
+ {
+ return PdfType::ensureType(self::class, $value, 'Indirect reference value expected.');
+ }
+
+ /**
+ * The generation number.
+ *
+ * @var int
+ */
+ public $generationNumber;
+}
diff --git a/vendor/setasign/fpdi/src/PdfParser/Type/PdfName.php b/vendor/setasign/fpdi/src/PdfParser/Type/PdfName.php
new file mode 100644
index 0000000..194a13f
--- /dev/null
+++ b/vendor/setasign/fpdi/src/PdfParser/Type/PdfName.php
@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * This file is part of FPDI
+ *
+ * @package setasign\Fpdi
+ * @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
+ * @license http://opensource.org/licenses/mit-license The MIT License
+ */
+
+namespace setasign\Fpdi\PdfParser\Type;
+
+use setasign\Fpdi\PdfParser\StreamReader;
+use setasign\Fpdi\PdfParser\Tokenizer;
+
+/**
+ * Class representing a PDF name object
+ */
+class PdfName extends PdfType
+{
+ /**
+ * Parses a name object from the passed tokenizer and stream-reader.
+ *
+ * @param Tokenizer $tokenizer
+ * @param StreamReader $streamReader
+ * @return self
+ */
+ public static function parse(Tokenizer $tokenizer, StreamReader $streamReader)
+ {
+ $v = new self();
+ if (\strspn($streamReader->getByte(), "\x00\x09\x0A\x0C\x0D\x20()<>[]{}/%") === 0) {
+ $v->value = (string) $tokenizer->getNextToken();
+ return $v;
+ }
+
+ $v->value = '';
+ return $v;
+ }
+
+ /**
+ * Unescapes a name string.
+ *
+ * @param string $value
+ * @return string
+ */
+ public static function unescape($value)
+ {
+ if (strpos($value, '#') === false) {
+ return $value;
+ }
+
+ return preg_replace_callback('/#([a-fA-F\d]{2})/', function ($matches) {
+ return chr(hexdec($matches[1]));
+ }, $value);
+ }
+
+ /**
+ * Helper method to create an instance.
+ *
+ * @param string $string
+ * @return self
+ */
+ public static function create($string)
+ {
+ $v = new self();
+ $v->value = $string;
+
+ return $v;
+ }
+
+ /**
+ * Ensures that the passed value is a PdfName instance.
+ *
+ * @param mixed $name
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($name)
+ {
+ return PdfType::ensureType(self::class, $name, 'Name value expected.');
+ }
+}
diff --git a/vendor/setasign/fpdi/src/PdfParser/Type/PdfNull.php b/vendor/setasign/fpdi/src/PdfParser/Type/PdfNull.php
new file mode 100644
index 0000000..0c4c108
--- /dev/null
+++ b/vendor/setasign/fpdi/src/PdfParser/Type/PdfNull.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * This file is part of FPDI
+ *
+ * @package setasign\Fpdi
+ * @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
+ * @license http://opensource.org/licenses/mit-license The MIT License
+ */
+
+namespace setasign\Fpdi\PdfParser\Type;
+
+/**
+ * Class representing a PDF null object
+ */
+class PdfNull extends PdfType
+{
+ // empty body
+}
diff --git a/vendor/setasign/fpdi/src/PdfParser/Type/PdfNumeric.php b/vendor/setasign/fpdi/src/PdfParser/Type/PdfNumeric.php
new file mode 100644
index 0000000..9de912b
--- /dev/null
+++ b/vendor/setasign/fpdi/src/PdfParser/Type/PdfNumeric.php
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * This file is part of FPDI
+ *
+ * @package setasign\Fpdi
+ * @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
+ * @license http://opensource.org/licenses/mit-license The MIT License
+ */
+
+namespace setasign\Fpdi\PdfParser\Type;
+
+/**
+ * Class representing a numeric PDF object
+ */
+class PdfNumeric extends PdfType
+{
+ /**
+ * Helper method to create an instance.
+ *
+ * @param int|float $value
+ * @return PdfNumeric
+ */
+ public static function create($value)
+ {
+ $v = new self();
+ $v->value = $value + 0;
+
+ return $v;
+ }
+
+ /**
+ * Ensures that the passed value is a PdfNumeric instance.
+ *
+ * @param mixed $value
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($value)
+ {
+ return PdfType::ensureType(self::class, $value, 'Numeric value expected.');
+ }
+}
diff --git a/vendor/setasign/fpdi/src/PdfParser/Type/PdfStream.php b/vendor/setasign/fpdi/src/PdfParser/Type/PdfStream.php
new file mode 100644
index 0000000..6d4c5a8
--- /dev/null
+++ b/vendor/setasign/fpdi/src/PdfParser/Type/PdfStream.php
@@ -0,0 +1,326 @@
+<?php
+
+/**
+ * This file is part of FPDI
+ *
+ * @package setasign\Fpdi
+ * @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
+ * @license http://opensource.org/licenses/mit-license The MIT License
+ */
+
+namespace setasign\Fpdi\PdfParser\Type;
+
+use setasign\Fpdi\PdfParser\CrossReference\CrossReferenceException;
+use setasign\Fpdi\PdfParser\Filter\Ascii85;
+use setasign\Fpdi\PdfParser\Filter\AsciiHex;
+use setasign\Fpdi\PdfParser\Filter\FilterException;
+use setasign\Fpdi\PdfParser\Filter\Flate;
+use setasign\Fpdi\PdfParser\Filter\Lzw;
+use setasign\Fpdi\PdfParser\PdfParser;
+use setasign\Fpdi\PdfParser\PdfParserException;
+use setasign\Fpdi\PdfParser\StreamReader;
+use setasign\FpdiPdfParser\PdfParser\Filter\Predictor;
+
+/**
+ * Class representing a PDF stream object
+ */
+class PdfStream extends PdfType
+{
+ /**
+ * Parses a stream from a stream reader.
+ *
+ * @param PdfDictionary $dictionary
+ * @param StreamReader $reader
+ * @param PdfParser $parser Optional to keep backwards compatibility
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function parse(PdfDictionary $dictionary, StreamReader $reader, PdfParser $parser = null)
+ {
+ $v = new self();
+ $v->value = $dictionary;
+ $v->reader = $reader;
+ $v->parser = $parser;
+
+ $offset = $reader->getOffset();
+
+ // Find the first "newline"
+ while (($firstByte = $reader->getByte($offset)) !== false) {
+ if ($firstByte !== "\n" && $firstByte !== "\r") {
+ $offset++;
+ } else {
+ break;
+ }
+ }
+
+ if ($firstByte === false) {
+ throw new PdfTypeException(
+ 'Unable to parse stream data. No newline after the stream keyword found.',
+ PdfTypeException::NO_NEWLINE_AFTER_STREAM_KEYWORD
+ );
+ }
+
+ $sndByte = $reader->getByte($offset + 1);
+ if ($firstByte === "\n" || $firstByte === "\r") {
+ $offset++;
+ }
+
+ if ($sndByte === "\n" && $firstByte !== "\n") {
+ $offset++;
+ }
+
+ $reader->setOffset($offset);
+ // let's only save the byte-offset and read the stream only when needed
+ $v->stream = $reader->getPosition() + $reader->getOffset();
+
+ return $v;
+ }
+
+ /**
+ * Helper method to create an instance.
+ *
+ * @param PdfDictionary $dictionary
+ * @param string $stream
+ * @return self
+ */
+ public static function create(PdfDictionary $dictionary, $stream)
+ {
+ $v = new self();
+ $v->value = $dictionary;
+ $v->stream = (string) $stream;
+
+ return $v;
+ }
+
+ /**
+ * Ensures that the passed value is a PdfStream instance.
+ *
+ * @param mixed $stream
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($stream)
+ {
+ return PdfType::ensureType(self::class, $stream, 'Stream value expected.');
+ }
+
+ /**
+ * The stream or its byte-offset position.
+ *
+ * @var int|string
+ */
+ protected $stream;
+
+ /**
+ * The stream reader instance.
+ *
+ * @var StreamReader|null
+ */
+ protected $reader;
+
+ /**
+ * The PDF parser instance.
+ *
+ * @var PdfParser
+ */
+ protected $parser;
+
+ /**
+ * Get the stream data.
+ *
+ * @param bool $cache Whether cache the stream data or not.
+ * @return bool|string
+ * @throws PdfTypeException
+ * @throws CrossReferenceException
+ * @throws PdfParserException
+ */
+ public function getStream($cache = false)
+ {
+ if (\is_int($this->stream)) {
+ $length = PdfDictionary::get($this->value, 'Length');
+ if ($this->parser !== null) {
+ $length = PdfType::resolve($length, $this->parser);
+ }
+
+ if (!($length instanceof PdfNumeric) || $length->value === 0) {
+ $this->reader->reset($this->stream, 100000);
+ $buffer = $this->extractStream();
+ } else {
+ $this->reader->reset($this->stream, $length->value);
+ $buffer = $this->reader->getBuffer(false);
+ if ($this->parser !== null) {
+ $this->reader->reset($this->stream + strlen($buffer));
+ $this->parser->getTokenizer()->clearStack();
+ $token = $this->parser->readValue();
+ if ($token === false || !($token instanceof PdfToken) || $token->value !== 'endstream') {
+ $this->reader->reset($this->stream, 100000);
+ $buffer = $this->extractStream();
+ $this->reader->reset($this->stream + strlen($buffer));
+ }
+ }
+ }
+
+ if ($cache === false) {
+ return $buffer;
+ }
+
+ $this->stream = $buffer;
+ $this->reader = null;
+ }
+
+ return $this->stream;
+ }
+
+ /**
+ * Extract the stream "manually".
+ *
+ * @return string
+ * @throws PdfTypeException
+ */
+ protected function extractStream()
+ {
+ while (true) {
+ $buffer = $this->reader->getBuffer(false);
+ $length = \strpos($buffer, 'endstream');
+ if ($length === false) {
+ if (!$this->reader->increaseLength(100000)) {
+ throw new PdfTypeException('Cannot extract stream.');
+ }
+ continue;
+ }
+ break;
+ }
+
+ $buffer = \substr($buffer, 0, $length);
+ $lastByte = \substr($buffer, -1);
+
+ /* Check for EOL marker =
+ * CARRIAGE RETURN (\r) and a LINE FEED (\n) or just a LINE FEED (\n},
+ * and not by a CARRIAGE RETURN (\r) alone
+ */
+ if ($lastByte === "\n") {
+ $buffer = \substr($buffer, 0, -1);
+
+ $lastByte = \substr($buffer, -1);
+ if ($lastByte === "\r") {
+ $buffer = \substr($buffer, 0, -1);
+ }
+ }
+
+ // There are streams in the wild, which have only white signs in them but need to be parsed manually due
+ // to a problem encountered before (e.g. Length === 0). We should set them to empty streams to avoid problems
+ // in further processing (e.g. applying of filters).
+ if (trim($buffer) === '') {
+ $buffer = '';
+ }
+
+ return $buffer;
+ }
+
+ /**
+ * Get the unfiltered stream data.
+ *
+ * @return string
+ * @throws FilterException
+ * @throws PdfParserException
+ */
+ public function getUnfilteredStream()
+ {
+ $stream = $this->getStream();
+ $filters = PdfDictionary::get($this->value, 'Filter');
+ if ($filters instanceof PdfNull) {
+ return $stream;
+ }
+
+ if ($filters instanceof PdfArray) {
+ $filters = $filters->value;
+ } else {
+ $filters = [$filters];
+ }
+
+ $decodeParams = PdfDictionary::get($this->value, 'DecodeParms');
+ if ($decodeParams instanceof PdfArray) {
+ $decodeParams = $decodeParams->value;
+ } else {
+ $decodeParams = [$decodeParams];
+ }
+
+ foreach ($filters as $key => $filter) {
+ if (!($filter instanceof PdfName)) {
+ continue;
+ }
+
+ $decodeParam = null;
+ if (isset($decodeParams[$key])) {
+ $decodeParam = ($decodeParams[$key] instanceof PdfDictionary ? $decodeParams[$key] : null);
+ }
+
+ switch ($filter->value) {
+ case 'FlateDecode':
+ case 'Fl':
+ case 'LZWDecode':
+ case 'LZW':
+ if (\strpos($filter->value, 'LZW') === 0) {
+ $filterObject = new Lzw();
+ } else {
+ $filterObject = new Flate();
+ }
+
+ $stream = $filterObject->decode($stream);
+
+ if ($decodeParam instanceof PdfDictionary) {
+ $predictor = PdfDictionary::get($decodeParam, 'Predictor', PdfNumeric::create(1));
+ if ($predictor->value !== 1) {
+ if (!\class_exists(Predictor::class)) {
+ throw new PdfParserException(
+ 'This PDF document makes use of features which are only implemented in the ' .
+ 'commercial "FPDI PDF-Parser" add-on (see https://www.setasign.com/fpdi-pdf-' .
+ 'parser).',
+ PdfParserException::IMPLEMENTED_IN_FPDI_PDF_PARSER
+ );
+ }
+
+ $colors = PdfDictionary::get($decodeParam, 'Colors', PdfNumeric::create(1));
+ $bitsPerComponent = PdfDictionary::get(
+ $decodeParam,
+ 'BitsPerComponent',
+ PdfNumeric::create(8)
+ );
+
+ $columns = PdfDictionary::get($decodeParam, 'Columns', PdfNumeric::create(1));
+
+ $filterObject = new Predictor(
+ $predictor->value,
+ $colors->value,
+ $bitsPerComponent->value,
+ $columns->value
+ );
+
+ $stream = $filterObject->decode($stream);
+ }
+ }
+
+ break;
+ case 'ASCII85Decode':
+ case 'A85':
+ $filterObject = new Ascii85();
+ $stream = $filterObject->decode($stream);
+ break;
+
+ case 'ASCIIHexDecode':
+ case 'AHx':
+ $filterObject = new AsciiHex();
+ $stream = $filterObject->decode($stream);
+ break;
+
+ default:
+ throw new FilterException(
+ \sprintf('Unsupported filter "%s".', $filter->value),
+ FilterException::UNSUPPORTED_FILTER
+ );
+ }
+ }
+
+ return $stream;
+ }
+}
diff --git a/vendor/setasign/fpdi/src/PdfParser/Type/PdfString.php b/vendor/setasign/fpdi/src/PdfParser/Type/PdfString.php
new file mode 100644
index 0000000..1636e68
--- /dev/null
+++ b/vendor/setasign/fpdi/src/PdfParser/Type/PdfString.php
@@ -0,0 +1,172 @@
+<?php
+
+/**
+ * This file is part of FPDI
+ *
+ * @package setasign\Fpdi
+ * @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
+ * @license http://opensource.org/licenses/mit-license The MIT License
+ */
+
+namespace setasign\Fpdi\PdfParser\Type;
+
+use setasign\Fpdi\PdfParser\StreamReader;
+
+/**
+ * Class representing a PDF string object
+ */
+class PdfString extends PdfType
+{
+ /**
+ * Parses a string object from the stream reader.
+ *
+ * @param StreamReader $streamReader
+ * @return self
+ */
+ public static function parse(StreamReader $streamReader)
+ {
+ $pos = $startPos = $streamReader->getOffset();
+ $openBrackets = 1;
+ do {
+ $buffer = $streamReader->getBuffer(false);
+ for ($length = \strlen($buffer); $openBrackets !== 0 && $pos < $length; $pos++) {
+ switch ($buffer[$pos]) {
+ case '(':
+ $openBrackets++;
+ break;
+ case ')':
+ $openBrackets--;
+ break;
+ case '\\':
+ $pos++;
+ }
+ }
+ } while ($openBrackets !== 0 && $streamReader->increaseLength());
+
+ $result = \substr($buffer, $startPos, $openBrackets + $pos - $startPos - 1);
+ $streamReader->setOffset($pos);
+
+ $v = new self();
+ $v->value = $result;
+
+ return $v;
+ }
+
+ /**
+ * Helper method to create an instance.
+ *
+ * @param string $value The string needs to be escaped accordingly.
+ * @return self
+ */
+ public static function create($value)
+ {
+ $v = new self();
+ $v->value = $value;
+
+ return $v;
+ }
+
+ /**
+ * Ensures that the passed value is a PdfString instance.
+ *
+ * @param mixed $string
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($string)
+ {
+ return PdfType::ensureType(self::class, $string, 'String value expected.');
+ }
+
+ /**
+ * Unescapes escaped sequences in a PDF string according to the PDF specification.
+ *
+ * @param string $s
+ * @return string
+ */
+ public static function unescape($s)
+ {
+ $out = '';
+ /** @noinspection ForeachInvariantsInspection */
+ for ($count = 0, $n = \strlen($s); $count < $n; $count++) {
+ if ($s[$count] !== '\\') {
+ $out .= $s[$count];
+ } else {
+ // A backslash at the end of the string - ignore it
+ if ($count === ($n - 1)) {
+ break;
+ }
+
+ switch ($s[++$count]) {
+ case ')':
+ case '(':
+ case '\\':
+ $out .= $s[$count];
+ break;
+
+ case 'f':
+ $out .= "\x0C";
+ break;
+
+ case 'b':
+ $out .= "\x08";
+ break;
+
+ case 't':
+ $out .= "\x09";
+ break;
+
+ case 'r':
+ $out .= "\x0D";
+ break;
+
+ case 'n':
+ $out .= "\x0A";
+ break;
+
+ case "\r":
+ if ($count !== $n - 1 && $s[$count + 1] === "\n") {
+ $count++;
+ }
+ break;
+
+ case "\n":
+ break;
+
+ default:
+ $actualChar = \ord($s[$count]);
+ // ascii 48 = number 0
+ // ascii 57 = number 9
+ if ($actualChar >= 48 && $actualChar <= 57) {
+ $oct = '' . $s[$count];
+
+ /** @noinspection NotOptimalIfConditionsInspection */
+ if (
+ $count + 1 < $n
+ && \ord($s[$count + 1]) >= 48
+ && \ord($s[$count + 1]) <= 57
+ ) {
+ $count++;
+ $oct .= $s[$count];
+
+ /** @noinspection NotOptimalIfConditionsInspection */
+ if (
+ $count + 1 < $n
+ && \ord($s[$count + 1]) >= 48
+ && \ord($s[$count + 1]) <= 57
+ ) {
+ $oct .= $s[++$count];
+ }
+ }
+
+ $out .= \chr(\octdec($oct));
+ } else {
+ // If the character is not one of those defined, the backslash is ignored
+ $out .= $s[$count];
+ }
+ }
+ }
+ }
+ return $out;
+ }
+}
diff --git a/vendor/setasign/fpdi/src/PdfParser/Type/PdfToken.php b/vendor/setasign/fpdi/src/PdfParser/Type/PdfToken.php
new file mode 100644
index 0000000..012b9fd
--- /dev/null
+++ b/vendor/setasign/fpdi/src/PdfParser/Type/PdfToken.php
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * This file is part of FPDI
+ *
+ * @package setasign\Fpdi
+ * @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
+ * @license http://opensource.org/licenses/mit-license The MIT License
+ */
+
+namespace setasign\Fpdi\PdfParser\Type;
+
+/**
+ * Class representing PDF token object
+ */
+class PdfToken extends PdfType
+{
+ /**
+ * Helper method to create an instance.
+ *
+ * @param string $token
+ * @return self
+ */
+ public static function create($token)
+ {
+ $v = new self();
+ $v->value = $token;
+
+ return $v;
+ }
+
+ /**
+ * Ensures that the passed value is a PdfToken instance.
+ *
+ * @param mixed $token
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($token)
+ {
+ return PdfType::ensureType(self::class, $token, 'Token value expected.');
+ }
+}
diff --git a/vendor/setasign/fpdi/src/PdfParser/Type/PdfType.php b/vendor/setasign/fpdi/src/PdfParser/Type/PdfType.php
new file mode 100644
index 0000000..7672dcd
--- /dev/null
+++ b/vendor/setasign/fpdi/src/PdfParser/Type/PdfType.php
@@ -0,0 +1,78 @@
+<?php
+
+/**
+ * This file is part of FPDI
+ *
+ * @package setasign\Fpdi
+ * @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
+ * @license http://opensource.org/licenses/mit-license The MIT License
+ */
+
+namespace setasign\Fpdi\PdfParser\Type;
+
+use setasign\Fpdi\PdfParser\CrossReference\CrossReferenceException;
+use setasign\Fpdi\PdfParser\PdfParser;
+use setasign\Fpdi\PdfParser\PdfParserException;
+
+/**
+ * A class defining a PDF data type
+ */
+class PdfType
+{
+ /**
+ * Resolves a PdfType value to its value.
+ *
+ * This method is used to evaluate indirect and direct object references until a final value is reached.
+ *
+ * @param PdfType $value
+ * @param PdfParser $parser
+ * @param bool $stopAtIndirectObject
+ * @return PdfType
+ * @throws CrossReferenceException
+ * @throws PdfParserException
+ */
+ public static function resolve(PdfType $value, PdfParser $parser, $stopAtIndirectObject = false)
+ {
+ if ($value instanceof PdfIndirectObject) {
+ if ($stopAtIndirectObject === true) {
+ return $value;
+ }
+
+ return self::resolve($value->value, $parser, $stopAtIndirectObject);
+ }
+
+ if ($value instanceof PdfIndirectObjectReference) {
+ return self::resolve($parser->getIndirectObject($value->value), $parser, $stopAtIndirectObject);
+ }
+
+ return $value;
+ }
+
+ /**
+ * Ensure that a value is an instance of a specific PDF type.
+ *
+ * @param string $type
+ * @param PdfType $value
+ * @param string $errorMessage
+ * @return mixed
+ * @throws PdfTypeException
+ */
+ protected static function ensureType($type, $value, $errorMessage)
+ {
+ if (!($value instanceof $type)) {
+ throw new PdfTypeException(
+ $errorMessage,
+ PdfTypeException::INVALID_DATA_TYPE
+ );
+ }
+
+ return $value;
+ }
+
+ /**
+ * The value of the PDF type.
+ *
+ * @var mixed
+ */
+ public $value;
+}
diff --git a/vendor/setasign/fpdi/src/PdfParser/Type/PdfTypeException.php b/vendor/setasign/fpdi/src/PdfParser/Type/PdfTypeException.php
new file mode 100644
index 0000000..593d147
--- /dev/null
+++ b/vendor/setasign/fpdi/src/PdfParser/Type/PdfTypeException.php
@@ -0,0 +1,24 @@
+<?php
+
+/**
+ * This file is part of FPDI
+ *
+ * @package setasign\Fpdi
+ * @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
+ * @license http://opensource.org/licenses/mit-license The MIT License
+ */
+
+namespace setasign\Fpdi\PdfParser\Type;
+
+use setasign\Fpdi\PdfParser\PdfParserException;
+
+/**
+ * Exception class for pdf type classes
+ */
+class PdfTypeException extends PdfParserException
+{
+ /**
+ * @var int
+ */
+ const NO_NEWLINE_AFTER_STREAM_KEYWORD = 0x0601;
+}