LZWDecode.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. //
  3. // FPDI - Version 1.2
  4. //
  5. // Copyright 2004-2007 Setasign - Jan Slabon
  6. //
  7. // Licensed under the Apache License, Version 2.0 (the "License");
  8. // you may not use this file except in compliance with the License.
  9. // You may obtain a copy of the License at
  10. //
  11. // http://www.apache.org/licenses/LICENSE-2.0
  12. //
  13. // Unless required by applicable law or agreed to in writing, software
  14. // distributed under the License is distributed on an "AS IS" BASIS,
  15. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. // See the License for the specific language governing permissions and
  17. // limitations under the License.
  18. //
  19. class LZWDecode {
  20. var $sTable = array();
  21. var $data = null;
  22. var $tIdx;
  23. var $bitsToGet = 9;
  24. var $bytePointer;
  25. var $bitPointer;
  26. var $nextData = 0;
  27. var $nextBits = 0;
  28. var $andTable = array(511, 1023, 2047, 4095);
  29. function LZWDecode(&$fpdi) {
  30. $this->fpdi =& $fpdi;
  31. }
  32. /**
  33. * Method to decode LZW compressed data.
  34. *
  35. * @param string data The compressed data.
  36. */
  37. function decode(&$data) {
  38. if($data[0] == 0x00 && $data[1] == 0x01) {
  39. $this->fpdi->error("LZW flavour not supported.");
  40. }
  41. $this->initsTable();
  42. $this->data =& $data;
  43. // Initialize pointers
  44. $this->bytePointer = 0;
  45. $this->bitPointer = 0;
  46. $this->nextData = 0;
  47. $this->nextBits = 0;
  48. $oldCode = 0;
  49. $string = "";
  50. $uncompData = "";
  51. while (($code = $this->getNextCode()) != 257) {
  52. if ($code == 256) {
  53. $this->initsTable();
  54. $code = $this->getNextCode();
  55. if ($code == 257) {
  56. break;
  57. }
  58. $uncompData .= $this->sTable[$code];
  59. $oldCode = $code;
  60. } else {
  61. if ($code < $this->tIdx) {
  62. $string = $this->sTable[$code];
  63. $uncompData .= $string;
  64. $this->addStringToTable($this->sTable[$oldCode], $string[0]);
  65. $oldCode = $code;
  66. } else {
  67. $string = $this->sTable[$oldCode];
  68. $string = $string.$string[0];
  69. $uncompData .= $string;
  70. $this->addStringToTable($string);
  71. $oldCode = $code;
  72. }
  73. }
  74. }
  75. return $uncompData;
  76. }
  77. /**
  78. * Initialize the string table.
  79. */
  80. function initsTable() {
  81. $this->sTable = array();
  82. for ($i = 0; $i < 256; $i++)
  83. $this->sTable[$i] = chr($i);
  84. $this->tIdx = 258;
  85. $this->bitsToGet = 9;
  86. }
  87. /**
  88. * Add a new string to the string table.
  89. */
  90. function addStringToTable ($oldString, $newString="") {
  91. $string = $oldString.$newString;
  92. // Add this new String to the table
  93. $this->sTable[$this->tIdx++] = $string;
  94. if ($this->tIdx == 511) {
  95. $this->bitsToGet = 10;
  96. } else if ($this->tIdx == 1023) {
  97. $this->bitsToGet = 11;
  98. } else if ($this->tIdx == 2047) {
  99. $this->bitsToGet = 12;
  100. }
  101. }
  102. // Returns the next 9, 10, 11 or 12 bits
  103. function getNextCode() {
  104. if ($this->bytePointer == strlen($this->data))
  105. return 257;
  106. $this->nextData = ($this->nextData << 8) | (ord($this->data[$this->bytePointer++]) & 0xff);
  107. $this->nextBits += 8;
  108. if ($this->nextBits < $this->bitsToGet) {
  109. $this->nextData = ($this->nextData << 8) | (ord($this->data[$this->bytePointer++]) & 0xff);
  110. $this->nextBits += 8;
  111. }
  112. $code = ($this->nextData >> ($this->nextBits - $this->bitsToGet)) & $this->andTable[$this->bitsToGet-9];
  113. $this->nextBits -= $this->bitsToGet;
  114. return $code;
  115. }
  116. }
  117. ?>