Ascii85.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. <?php
  2. /**
  3. * This file is part of FPDI
  4. *
  5. * @package Fpdi
  6. * @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
  7. * @license http://opensource.org/licenses/mit-license The MIT License
  8. */
  9. namespace Fpdi\PdfParser\Filter;
  10. /**
  11. * Class for handling ASCII base-85 encoded data
  12. */
  13. class Ascii85 implements FilterInterface
  14. {
  15. /**
  16. * Decode ASCII85 encoded string.
  17. *
  18. * @param string $data The input string
  19. * @return string
  20. * @throws Ascii85Exception
  21. */
  22. public function decode($data)
  23. {
  24. $out = '';
  25. $state = 0;
  26. $chn = null;
  27. $data = \preg_replace('/\s/', '', $data);
  28. $l = \strlen($data);
  29. /** @noinspection ForeachInvariantsInspection */
  30. for ($k = 0; $k < $l; ++$k) {
  31. $ch = \ord($data[$k]) & 0xff;
  32. //Start <~
  33. if ($k === 0 && $ch === 60 && isset($data[$k + 1]) && (\ord($data[$k + 1]) & 0xFF) === 126) {
  34. $k++;
  35. continue;
  36. }
  37. //End ~>
  38. if ($ch === 126 && isset($data[$k + 1]) && (\ord($data[$k + 1]) & 0xFF) === 62) {
  39. break;
  40. }
  41. if ($ch === 122 /* z */ && $state === 0) {
  42. $out .= \chr(0) . \chr(0) . \chr(0) . \chr(0);
  43. continue;
  44. }
  45. if ($ch < 33 /* ! */ || $ch > 117 /* u */) {
  46. throw new Ascii85Exception(
  47. 'Illegal character found while ASCII85 decode.',
  48. Ascii85Exception::ILLEGAL_CHAR_FOUND
  49. );
  50. }
  51. $chn[$state] = $ch - 33;/* ! */
  52. $state++;
  53. if ($state === 5) {
  54. $state = 0;
  55. $r = 0;
  56. for ($j = 0; $j < 5; ++$j) {
  57. /** @noinspection UnnecessaryCastingInspection */
  58. $r = (int)($r * 85 + $chn[$j]);
  59. }
  60. $out .= \chr($r >> 24)
  61. . \chr($r >> 16)
  62. . \chr($r >> 8)
  63. . \chr($r);
  64. }
  65. }
  66. if ($state === 1) {
  67. throw new Ascii85Exception(
  68. 'Illegal length while ASCII85 decode.',
  69. Ascii85Exception::ILLEGAL_LENGTH
  70. );
  71. }
  72. if ($state === 2) {
  73. $r = $chn[0] * 85 * 85 * 85 * 85 + ($chn[1] + 1) * 85 * 85 * 85;
  74. $out .= \chr($r >> 24);
  75. } elseif ($state === 3) {
  76. $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + ($chn[2] + 1) * 85 * 85;
  77. $out .= \chr($r >> 24);
  78. $out .= \chr($r >> 16);
  79. } elseif ($state === 4) {
  80. $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + $chn[2] * 85 * 85 + ($chn[3] + 1) * 85;
  81. $out .= \chr($r >> 24);
  82. $out .= \chr($r >> 16);
  83. $out .= \chr($r >> 8);
  84. }
  85. return $out;
  86. }
  87. }