PluginProbe
PDF & Print by BestWebSoft – WordPress Posts and Pages PDF Generator Plugin / 1.5
PDF & Print by BestWebSoft – WordPress Posts and Pages PDF Generator Plugin v1.5
trunk 1.5 1.6 1.7 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 All 71 releases
← All changes | mpdf/classes/gif.php +700 -677 trunk1.5 View file →
@@ -1,677 +1,700 @@
1 -<?php
2 -
3 -///////////////////////////////////////////////////////////////////////////////////////////////////
4 -// 2009-12-22 Adapted for mPDF 4.2
5 -///////////////////////////////////////////////////////////////////////////////////////////////////
6 -// GIF Util - (C) 2003 Yamasoft (S/C)
7 -// http://www.yamasoft.com
8 -// All Rights Reserved
9 -// This file can be freely copied, distributed, modified, updated by anyone under the only
10 -// condition to leave the original address (Yamasoft, http://www.yamasoft.com) and this header.
11 -///////////////////////////////////////////////////////////////////////////////////////////////////
12 -///////////////////////////////////////////////////////////////////////////////////////////////////
13 -// 2009-12-22 Adapted INB
14 -// Functions calling functionname($x, $len = 0) were not working on PHP5.1.5 as pass by reference
15 -// All edited to $len = 0; then call function.
16 -///////////////////////////////////////////////////////////////////////////////////////////////////
17 -///////////////////////////////////////////////////////////////////////////////////////////////////
18 -
19 -class CGIFLZW
20 -{
21 -
22 - var $MAX_LZW_BITS;
23 -
24 - var $Fresh, $CodeSize, $SetCodeSize, $MaxCode, $MaxCodeSize, $FirstCode, $OldCode;
25 -
26 - var $ClearCode, $EndCode, $Next, $Vals, $Stack, $sp, $Buf, $CurBit, $LastBit, $Done, $LastByte;
27 -
28 - public function __construct()
29 - {
30 - $this->MAX_LZW_BITS = 12;
31 - unSet($this->Next);
32 - unSet($this->Vals);
33 - unSet($this->Stack);
34 - unSet($this->Buf);
35 -
36 - $this->Next = range(0, (1 << $this->MAX_LZW_BITS) - 1);
37 - $this->Vals = range(0, (1 << $this->MAX_LZW_BITS) - 1);
38 - $this->Stack = range(0, (1 << ($this->MAX_LZW_BITS + 1)) - 1);
39 - $this->Buf = range(0, 279);
40 - }
41 -
42 - function deCompress($data, &$datLen)
43 - {
44 - $stLen = strlen($data);
45 - $datLen = 0;
46 - $ret = "";
47 - $dp = 0; // data pointer
48 - // INITIALIZATION
49 - $this->LZWCommandInit($data, $dp);
50 -
51 - while (($iIndex = $this->LZWCommand($data, $dp)) >= 0) {
52 - $ret .= chr($iIndex);
53 - }
54 -
55 - $datLen = $dp;
56 -
57 - if ($iIndex != -2) {
58 - return false;
59 - }
60 -
61 - return $ret;
62 - }
63 -
64 - function LZWCommandInit(&$data, &$dp)
65 - {
66 - $this->SetCodeSize = ord($data[0]);
67 - $dp += 1;
68 -
69 - $this->CodeSize = $this->SetCodeSize + 1;
70 - $this->ClearCode = 1 << $this->SetCodeSize;
71 - $this->EndCode = $this->ClearCode + 1;
72 - $this->MaxCode = $this->ClearCode + 2;
73 - $this->MaxCodeSize = $this->ClearCode << 1;
74 -
75 - $this->GetCodeInit($data, $dp);
76 -
77 - $this->Fresh = 1;
78 - for ($i = 0; $i < $this->ClearCode; $i++) {
79 - $this->Next[$i] = 0;
80 - $this->Vals[$i] = $i;
81 - }
82 -
83 - for (; $i < (1 << $this->MAX_LZW_BITS); $i++) {
84 - $this->Next[$i] = 0;
85 - $this->Vals[$i] = 0;
86 - }
87 -
88 - $this->sp = 0;
89 - return 1;
90 - }
91 -
92 - function LZWCommand(&$data, &$dp)
93 - {
94 - if ($this->Fresh) {
95 - $this->Fresh = 0;
96 - do {
97 - $this->FirstCode = $this->GetCode($data, $dp);
98 - $this->OldCode = $this->FirstCode;
99 - } while ($this->FirstCode == $this->ClearCode);
100 -
101 - return $this->FirstCode;
102 - }
103 -
104 - if ($this->sp > 0) {
105 - $this->sp--;
106 - return $this->Stack[$this->sp];
107 - }
108 -
109 - while (($Code = $this->GetCode($data, $dp)) >= 0) {
110 - if ($Code == $this->ClearCode) {
111 - for ($i = 0; $i < $this->ClearCode; $i++) {
112 - $this->Next[$i] = 0;
113 - $this->Vals[$i] = $i;
114 - }
115 -
116 - for (; $i < (1 << $this->MAX_LZW_BITS); $i++) {
117 - $this->Next[$i] = 0;
118 - $this->Vals[$i] = 0;
119 - }
120 -
121 - $this->CodeSize = $this->SetCodeSize + 1;
122 - $this->MaxCodeSize = $this->ClearCode << 1;
123 - $this->MaxCode = $this->ClearCode + 2;
124 - $this->sp = 0;
125 - $this->FirstCode = $this->GetCode($data, $dp);
126 - $this->OldCode = $this->FirstCode;
127 -
128 - return $this->FirstCode;
129 - }
130 -
131 - if ($Code == $this->EndCode) {
132 - return -2;
133 - }
134 -
135 - $InCode = $Code;
136 - if ($Code >= $this->MaxCode) {
137 - $this->Stack[$this->sp++] = $this->FirstCode;
138 - $Code = $this->OldCode;
139 - }
140 -
141 - while ($Code >= $this->ClearCode) {
142 - $this->Stack[$this->sp++] = $this->Vals[$Code];
143 -
144 - if ($Code == $this->Next[$Code]) // Circular table entry, big GIF Error!
145 - return -1;
146 -
147 - $Code = $this->Next[$Code];
148 - }
149 -
150 - $this->FirstCode = $this->Vals[$Code];
151 - $this->Stack[$this->sp++] = $this->FirstCode;
152 -
153 - if (($Code = $this->MaxCode) < (1 << $this->MAX_LZW_BITS)) {
154 - $this->Next[$Code] = $this->OldCode;
155 - $this->Vals[$Code] = $this->FirstCode;
156 - $this->MaxCode++;
157 -
158 - if (($this->MaxCode >= $this->MaxCodeSize) && ($this->MaxCodeSize < (1 << $this->MAX_LZW_BITS))) {
159 - $this->MaxCodeSize *= 2;
160 - $this->CodeSize++;
161 - }
162 - }
163 -
164 - $this->OldCode = $InCode;
165 - if ($this->sp > 0) {
166 - $this->sp--;
167 - return $this->Stack[$this->sp];
168 - }
169 - }
170 -
171 - return $Code;
172 - }
173 -
174 - function GetCodeInit(&$data, &$dp)
175 - {
176 - $this->CurBit = 0;
177 - $this->LastBit = 0;
178 - $this->Done = 0;
179 - $this->LastByte = 2;
180 - return 1;
181 - }
182 -
183 - function GetCode(&$data, &$dp)
184 - {
185 - if (($this->CurBit + $this->CodeSize) >= $this->LastBit) {
186 - if ($this->Done) {
187 - if ($this->CurBit >= $this->LastBit) {
188 - // Ran off the end of my bits
189 - return 0;
190 - }
191 - return -1;
192 - }
193 -
194 - $this->Buf[0] = $this->Buf[$this->LastByte - 2];
195 - $this->Buf[1] = $this->Buf[$this->LastByte - 1];
196 -
197 - $Count = ord($data[$dp]);
198 - $dp += 1;
199 -
200 - if ($Count) {
201 - for ($i = 0; $i < $Count; $i++) {
202 - $this->Buf[2 + $i] = ord($data[$dp + $i]);
203 - }
204 - $dp += $Count;
205 - } else {
206 - $this->Done = 1;
207 - }
208 -
209 - $this->LastByte = 2 + $Count;
210 - $this->CurBit = ($this->CurBit - $this->LastBit) + 16;
211 - $this->LastBit = (2 + $Count) << 3;
212 - }
213 -
214 - $iRet = 0;
215 - for ($i = $this->CurBit, $j = 0; $j < $this->CodeSize; $i++, $j++) {
216 - $iRet |= (($this->Buf[intval($i / 8)] & (1 << ($i % 8))) != 0) << $j;
217 - }
218 -
219 - $this->CurBit += $this->CodeSize;
220 - return $iRet;
221 - }
222 -
223 -}
224 -
225 -class CGIFCOLORTABLE
226 -{
227 -
228 - var $m_nColors;
229 -
230 - var $m_arColors;
231 -
232 - public function __construct()
233 - {
234 - unSet($this->m_nColors);
235 - unSet($this->m_arColors);
236 - }
237 -
238 - function load($lpData, $num)
239 - {
240 - $this->m_nColors = 0;
241 - $this->m_arColors = array();
242 -
243 - for ($i = 0; $i < $num; $i++) {
244 - $rgb = substr($lpData, $i * 3, 3);
245 - if (strlen($rgb) < 3) {
246 - return false;
247 - }
248 -
249 - $this->m_arColors[] = (ord($rgb[2]) << 16) + (ord($rgb[1]) << 8) + ord($rgb[0]);
250 - $this->m_nColors++;
251 - }
252 -
253 - return true;
254 - }
255 -
256 - function toString()
257 - {
258 - $ret = "";
259 -
260 - for ($i = 0; $i < $this->m_nColors; $i++) {
261 - $ret .=
262 - chr(($this->m_arColors[$i] & 0x000000FF)) . // R
263 - chr(($this->m_arColors[$i] & 0x0000FF00) >> 8) . // G
264 - chr(($this->m_arColors[$i] & 0x00FF0000) >> 16); // B
265 - }
266 -
267 - return $ret;
268 - }
269 -
270 - function colorIndex($rgb)
271 - {
272 - $rgb = intval($rgb) & 0xFFFFFF;
273 - $r1 = ($rgb & 0x0000FF);
274 - $g1 = ($rgb & 0x00FF00) >> 8;
275 - $b1 = ($rgb & 0xFF0000) >> 16;
276 - $idx = -1;
277 -
278 - for ($i = 0; $i < $this->m_nColors; $i++) {
279 - $r2 = ($this->m_arColors[$i] & 0x000000FF);
280 - $g2 = ($this->m_arColors[$i] & 0x0000FF00) >> 8;
281 - $b2 = ($this->m_arColors[$i] & 0x00FF0000) >> 16;
282 - $d = abs($r2 - $r1) + abs($g2 - $g1) + abs($b2 - $b1);
283 -
284 - if (($idx == -1) || ($d < $dif)) {
285 - $idx = $i;
286 - $dif = $d;
287 - }
288 - }
289 -
290 - return $idx;
291 - }
292 -
293 -}
294 -
295 -class CGIFFILEHEADER
296 -{
297 -
298 - var $m_lpVer;
299 -
300 - var $m_nWidth;
301 -
302 - var $m_nHeight;
303 -
304 - var $m_bGlobalClr;
305 -
306 - var $m_nColorRes;
307 -
308 - var $m_bSorted;
309 -
310 - var $m_nTableSize;
311 -
312 - var $m_nBgColor;
313 -
314 - var $m_nPixelRatio;
315 -
316 - var $m_colorTable;
317 -
318 - public function __construct()
319 - {
320 - unSet($this->m_lpVer);
321 - unSet($this->m_nWidth);
322 - unSet($this->m_nHeight);
323 - unSet($this->m_bGlobalClr);
324 - unSet($this->m_nColorRes);
325 - unSet($this->m_bSorted);
326 - unSet($this->m_nTableSize);
327 - unSet($this->m_nBgColor);
328 - unSet($this->m_nPixelRatio);
329 - unSet($this->m_colorTable);
330 - }
331 -
332 - function load($lpData, &$hdrLen)
333 - {
334 - $hdrLen = 0;
335 -
336 - $this->m_lpVer = substr($lpData, 0, 6);
337 - if (($this->m_lpVer <> "GIF87a") && ($this->m_lpVer <> "GIF89a")) {
338 - return false;
339 - }
340 -
341 - $this->m_nWidth = $this->w2i(substr($lpData, 6, 2));
342 - $this->m_nHeight = $this->w2i(substr($lpData, 8, 2));
343 - if (!$this->m_nWidth || !$this->m_nHeight) {
344 - return false;
345 - }
346 -
347 - $b = ord(substr($lpData, 10, 1));
348 - $this->m_bGlobalClr = ($b & 0x80) ? true : false;
349 - $this->m_nColorRes = ($b & 0x70) >> 4;
350 - $this->m_bSorted = ($b & 0x08) ? true : false;
351 - $this->m_nTableSize = 2 << ($b & 0x07);
352 - $this->m_nBgColor = ord(substr($lpData, 11, 1));
353 - $this->m_nPixelRatio = ord(substr($lpData, 12, 1));
354 - $hdrLen = 13;
355 -
356 - if ($this->m_bGlobalClr) {
357 - $this->m_colorTable = new CGIFCOLORTABLE();
358 - if (!$this->m_colorTable->load(substr($lpData, $hdrLen), $this->m_nTableSize)) {
359 - return false;
360 - }
361 - $hdrLen += 3 * $this->m_nTableSize;
362 - }
363 -
364 - return true;
365 - }
366 -
367 - function w2i($str)
368 - {
369 - return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8);
370 - }
371 -
372 -}
373 -
374 -class CGIFIMAGEHEADER
375 -{
376 -
377 - var $m_nLeft;
378 -
379 - var $m_nTop;
380 -
381 - var $m_nWidth;
382 -
383 - var $m_nHeight;
384 -
385 - var $m_bLocalClr;
386 -
387 - var $m_bInterlace;
388 -
389 - var $m_bSorted;
390 -
391 - var $m_nTableSize;
392 -
393 - var $m_colorTable;
394 -
395 - public function __construct()
396 - {
397 - unSet($this->m_nLeft);
398 - unSet($this->m_nTop);
399 - unSet($this->m_nWidth);
400 - unSet($this->m_nHeight);
401 - unSet($this->m_bLocalClr);
402 - unSet($this->m_bInterlace);
403 - unSet($this->m_bSorted);
404 - unSet($this->m_nTableSize);
405 - unSet($this->m_colorTable);
406 - }
407 -
408 - function load($lpData, &$hdrLen)
409 - {
410 - $hdrLen = 0;
411 -
412 - $this->m_nLeft = $this->w2i(substr($lpData, 0, 2));
413 - $this->m_nTop = $this->w2i(substr($lpData, 2, 2));
414 - $this->m_nWidth = $this->w2i(substr($lpData, 4, 2));
415 - $this->m_nHeight = $this->w2i(substr($lpData, 6, 2));
416 -
417 - if (!$this->m_nWidth || !$this->m_nHeight) {
418 - return false;
419 - }
420 -
421 - $b = ord($lpData[8]);
422 - $this->m_bLocalClr = ($b & 0x80) ? true : false;
423 - $this->m_bInterlace = ($b & 0x40) ? true : false;
424 - $this->m_bSorted = ($b & 0x20) ? true : false;
425 - $this->m_nTableSize = 2 << ($b & 0x07);
426 - $hdrLen = 9;
427 -
428 - if ($this->m_bLocalClr) {
429 - $this->m_colorTable = new CGIFCOLORTABLE();
430 - if (!$this->m_colorTable->load(substr($lpData, $hdrLen), $this->m_nTableSize)) {
431 - return false;
432 - }
433 - $hdrLen += 3 * $this->m_nTableSize;
434 - }
435 -
436 - return true;
437 - }
438 -
439 - function w2i($str)
440 - {
441 - return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8);
442 - }
443 -
444 -}
445 -
446 -class CGIFIMAGE
447 -{
448 -
449 - var $m_disp;
450 -
451 - var $m_bUser;
452 -
453 - var $m_bTrans;
454 -
455 - var $m_nDelay;
456 -
457 - var $m_nTrans;
458 -
459 - var $m_lpComm;
460 -
461 - var $m_gih;
462 -
463 - var $m_data;
464 -
465 - var $m_lzw;
466 -
467 - public function __construct()
468 - {
469 - unSet($this->m_disp);
470 - unSet($this->m_bUser);
471 - unSet($this->m_bTrans);
472 - unSet($this->m_nDelay);
473 - unSet($this->m_nTrans);
474 - unSet($this->m_lpComm);
475 - unSet($this->m_data);
476 - $this->m_gih = new CGIFIMAGEHEADER();
477 - $this->m_lzw = new CGIFLZW();
478 - }
479 -
480 - function load($data, &$datLen)
481 - {
482 - $datLen = 0;
483 -
484 - while (true) {
485 - $b = ord($data[0]);
486 - $data = substr($data, 1);
487 - $datLen++;
488 -
489 - switch ($b) {
490 - case 0x21: // Extension
491 - $len = 0;
492 - if (!$this->skipExt($data, $len)) {
493 - return false;
494 - }
495 - $datLen += $len;
496 - break;
497 -
498 - case 0x2C: // Image
499 - // LOAD HEADER & COLOR TABLE
500 - $len = 0;
501 - if (!$this->m_gih->load($data, $len)) {
502 - return false;
503 - }
504 - $data = substr($data, $len);
505 - $datLen += $len;
506 -
507 - // ALLOC BUFFER
508 - $len = 0;
509 -
510 - if (!($this->m_data = $this->m_lzw->deCompress($data, $len))) {
511 - return false;
512 - }
513 -
514 - $data = substr($data, $len);
515 - $datLen += $len;
516 -
517 - if ($this->m_gih->m_bInterlace) {
518 - $this->deInterlace();
519 - }
520 -
521 - return true;
522 -
523 - case 0x3B: // EOF
524 - default:
525 - return false;
526 - }
527 - }
528 - return false;
529 - }
530 -
531 - function skipExt(&$data, &$extLen)
532 - {
533 - $extLen = 0;
534 -
535 - $b = ord($data[0]);
536 - $data = substr($data, 1);
537 - $extLen++;
538 -
539 - switch ($b) {
540 - case 0xF9: // Graphic Control
541 - $b = ord($data[1]);
542 - $this->m_disp = ($b & 0x1C) >> 2;
543 - $this->m_bUser = ($b & 0x02) ? true : false;
544 - $this->m_bTrans = ($b & 0x01) ? true : false;
545 - $this->m_nDelay = $this->w2i(substr($data, 2, 2));
546 - $this->m_nTrans = ord($data[4]);
547 - break;
548 -
549 - case 0xFE: // Comment
550 - $this->m_lpComm = substr($data, 1, ord($data[0]));
551 - break;
552 -
553 - case 0x01: // Plain text
554 - break;
555 -
556 - case 0xFF: // Application
557 - break;
558 - }
559 -
560 - // SKIP DEFAULT AS DEFS MAY CHANGE
561 - $b = ord($data[0]);
562 - $data = substr($data, 1);
563 - $extLen++;
564 - while ($b > 0) {
565 - $data = substr($data, $b);
566 - $extLen += $b;
567 - $b = ord($data[0]);
568 - $data = substr($data, 1);
569 - $extLen++;
570 - }
571 - return true;
572 - }
573 -
574 - function w2i($str)
575 - {
576 - return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8);
577 - }
578 -
579 - function deInterlace()
580 - {
581 - $data = $this->m_data;
582 -
583 - for ($i = 0; $i < 4; $i++) {
584 - switch ($i) {
585 - case 0:
586 - $s = 8;
587 - $y = 0;
588 - break;
589 -
590 - case 1:
591 - $s = 8;
592 - $y = 4;
593 - break;
594 -
595 - case 2:
596 - $s = 4;
597 - $y = 2;
598 - break;
599 -
600 - case 3:
601 - $s = 2;
602 - $y = 1;
603 - break;
604 - }
605 -
606 - for (; $y < $this->m_gih->m_nHeight; $y += $s) {
607 - $lne = substr($this->m_data, 0, $this->m_gih->m_nWidth);
608 - $this->m_data = substr($this->m_data, $this->m_gih->m_nWidth);
609 -
610 - $data = substr($data, 0, $y * $this->m_gih->m_nWidth) .
611 - $lne .
612 - substr($data, ($y + 1) * $this->m_gih->m_nWidth);
613 - }
614 - }
615 -
616 - $this->m_data = $data;
617 - }
618 -
619 -}
620 -
621 -class CGIF
622 -{
623 -
624 - var $m_gfh;
625 -
626 - var $m_lpData;
627 -
628 - var $m_img;
629 -
630 - var $m_bLoaded;
631 -
632 - public function __construct()
633 - {
634 - $this->m_gfh = new CGIFFILEHEADER();
635 - $this->m_img = new CGIFIMAGE();
636 - $this->m_lpData = "";
637 - $this->m_bLoaded = false;
638 - }
639 -
640 - function ClearData()
641 - {
642 - $this->m_lpData = '';
643 - unSet($this->m_img->m_data);
644 - unSet($this->m_img->m_lzw->Next);
645 - unSet($this->m_img->m_lzw->Vals);
646 - unSet($this->m_img->m_lzw->Stack);
647 - unSet($this->m_img->m_lzw->Buf);
648 - }
649 -
650 - function loadFile(&$data, $iIndex)
651 - {
652 - if ($iIndex < 0) {
653 - return false;
654 - }
655 - $this->m_lpData = $data;
656 -
657 - // GET FILE HEADER
658 - $len = 0;
659 - if (!$this->m_gfh->load($this->m_lpData, $len)) {
660 - return false;
661 - }
662 -
663 - $this->m_lpData = substr($this->m_lpData, $len);
664 -
665 - do {
666 - $imgLen = 0;
667 - if (!$this->m_img->load($this->m_lpData, $imgLen)) {
668 - return false;
669 - }
670 - $this->m_lpData = substr($this->m_lpData, $imgLen);
671 - } while ($iIndex-- > 0);
672 -
673 - $this->m_bLoaded = true;
674 - return true;
675 - }
676 -
677 -}
1 +<?php
2 +///////////////////////////////////////////////////////////////////////////////////////////////////
3 +// 2009-12-22 Adapted for mPDF 4.2
4 +///////////////////////////////////////////////////////////////////////////////////////////////////
5 +// GIF Util - (C) 2003 Yamasoft (S/C)
6 +// http://www.yamasoft.com
7 +// All Rights Reserved
8 +// This file can be freely copied, distributed, modified, updated by anyone under the only
9 +// condition to leave the original address (Yamasoft, http://www.yamasoft.com) and this header.
10 +///////////////////////////////////////////////////////////////////////////////////////////////////
11 +///////////////////////////////////////////////////////////////////////////////////////////////////
12 +// 2009-12-22 Adapted INB
13 +// Functions calling functionname($x, $len = 0) were not working on PHP5.1.5 as pass by reference
14 +// All edited to $len = 0; then call function.
15 +///////////////////////////////////////////////////////////////////////////////////////////////////
16 +
17 +
18 +///////////////////////////////////////////////////////////////////////////////////////////////////
19 +
20 +class CGIFLZW
21 +{
22 + var $MAX_LZW_BITS;
23 + var $Fresh, $CodeSize, $SetCodeSize, $MaxCode, $MaxCodeSize, $FirstCode, $OldCode;
24 + var $ClearCode, $EndCode, $Next, $Vals, $Stack, $sp, $Buf, $CurBit, $LastBit, $Done, $LastByte;
25 +
26 + ///////////////////////////////////////////////////////////////////////////
27 +
28 + // CONSTRUCTOR
29 + function CGIFLZW()
30 + {
31 + $this->MAX_LZW_BITS = 12;
32 + unSet($this->Next);
33 + unSet($this->Vals);
34 + unSet($this->Stack);
35 + unSet($this->Buf);
36 +
37 + $this->Next = range(0, (1 << $this->MAX_LZW_BITS) - 1);
38 + $this->Vals = range(0, (1 << $this->MAX_LZW_BITS) - 1);
39 + $this->Stack = range(0, (1 << ($this->MAX_LZW_BITS + 1)) - 1);
40 + $this->Buf = range(0, 279);
41 + }
42 +
43 + ///////////////////////////////////////////////////////////////////////////
44 +
45 + function deCompress($data, &$datLen)
46 + {
47 + $stLen = strlen($data);
48 + $datLen = 0;
49 + $ret = "";
50 + $dp = 0; // data pointer
51 +
52 + // INITIALIZATION
53 + $this->LZWCommandInit($data, $dp);
54 +
55 + while(($iIndex = $this->LZWCommand($data, $dp)) >= 0) {
56 + $ret .= chr($iIndex);
57 + }
58 +
59 + $datLen = $dp;
60 +
61 + if($iIndex != -2) {
62 + return false;
63 + }
64 +
65 + return $ret;
66 + }
67 +
68 + ///////////////////////////////////////////////////////////////////////////
69 + function LZWCommandInit(&$data, &$dp)
70 + {
71 + $this->SetCodeSize = ord($data[0]);
72 + $dp += 1;
73 +
74 + $this->CodeSize = $this->SetCodeSize + 1;
75 + $this->ClearCode = 1 << $this->SetCodeSize;
76 + $this->EndCode = $this->ClearCode + 1;
77 + $this->MaxCode = $this->ClearCode + 2;
78 + $this->MaxCodeSize = $this->ClearCode << 1;
79 +
80 + $this->GetCodeInit($data, $dp);
81 +
82 + $this->Fresh = 1;
83 + for($i = 0; $i < $this->ClearCode; $i++) {
84 + $this->Next[$i] = 0;
85 + $this->Vals[$i] = $i;
86 + }
87 +
88 + for(; $i < (1 << $this->MAX_LZW_BITS); $i++) {
89 + $this->Next[$i] = 0;
90 + $this->Vals[$i] = 0;
91 + }
92 +
93 + $this->sp = 0;
94 + return 1;
95 + }
96 +
97 + function LZWCommand(&$data, &$dp)
98 + {
99 + if($this->Fresh) {
100 + $this->Fresh = 0;
101 + do {
102 + $this->FirstCode = $this->GetCode($data, $dp);
103 + $this->OldCode = $this->FirstCode;
104 + }
105 + while($this->FirstCode == $this->ClearCode);
106 +
107 + return $this->FirstCode;
108 + }
109 +
110 + if($this->sp > 0) {
111 + $this->sp--;
112 + return $this->Stack[$this->sp];
113 + }
114 +
115 + while(($Code = $this->GetCode($data, $dp)) >= 0) {
116 + if($Code == $this->ClearCode) {
117 + for($i = 0; $i < $this->ClearCode; $i++) {
118 + $this->Next[$i] = 0;
119 + $this->Vals[$i] = $i;
120 + }
121 +
122 + for(; $i < (1 << $this->MAX_LZW_BITS); $i++) {
123 + $this->Next[$i] = 0;
124 + $this->Vals[$i] = 0;
125 + }
126 +
127 + $this->CodeSize = $this->SetCodeSize + 1;
128 + $this->MaxCodeSize = $this->ClearCode << 1;
129 + $this->MaxCode = $this->ClearCode + 2;
130 + $this->sp = 0;
131 + $this->FirstCode = $this->GetCode($data, $dp);
132 + $this->OldCode = $this->FirstCode;
133 +
134 + return $this->FirstCode;
135 + }
136 +
137 + if($Code == $this->EndCode) {
138 + return -2;
139 + }
140 +
141 + $InCode = $Code;
142 + if($Code >= $this->MaxCode) {
143 + $this->Stack[$this->sp++] = $this->FirstCode;
144 + $Code = $this->OldCode;
145 + }
146 +
147 + while($Code >= $this->ClearCode) {
148 + $this->Stack[$this->sp++] = $this->Vals[$Code];
149 +
150 + if($Code == $this->Next[$Code]) // Circular table entry, big GIF Error!
151 + return -1;
152 +
153 + $Code = $this->Next[$Code];
154 + }
155 +
156 + $this->FirstCode = $this->Vals[$Code];
157 + $this->Stack[$this->sp++] = $this->FirstCode;
158 +
159 + if(($Code = $this->MaxCode) < (1 << $this->MAX_LZW_BITS)) {
160 + $this->Next[$Code] = $this->OldCode;
161 + $this->Vals[$Code] = $this->FirstCode;
162 + $this->MaxCode++;
163 +
164 + if(($this->MaxCode >= $this->MaxCodeSize) && ($this->MaxCodeSize < (1 << $this->MAX_LZW_BITS))) {
165 + $this->MaxCodeSize *= 2;
166 + $this->CodeSize++;
167 + }
168 + }
169 +
170 + $this->OldCode = $InCode;
171 + if($this->sp > 0) {
172 + $this->sp--;
173 + return $this->Stack[$this->sp];
174 + }
175 + }
176 +
177 + return $Code;
178 + }
179 +
180 + ///////////////////////////////////////////////////////////////////////////
181 +
182 + function GetCodeInit(&$data, &$dp)
183 + {
184 + $this->CurBit = 0;
185 + $this->LastBit = 0;
186 + $this->Done = 0;
187 + $this->LastByte = 2;
188 + return 1;
189 + }
190 +
191 + function GetCode(&$data, &$dp)
192 + {
193 + if(($this->CurBit + $this->CodeSize) >= $this->LastBit) {
194 + if($this->Done) {
195 + if($this->CurBit >= $this->LastBit) {
196 + // Ran off the end of my bits
197 + return 0;
198 + }
199 + return -1;
200 + }
201 +
202 + $this->Buf[0] = $this->Buf[$this->LastByte - 2];
203 + $this->Buf[1] = $this->Buf[$this->LastByte - 1];
204 +
205 + $Count = ord($data[$dp]);
206 + $dp += 1;
207 +
208 + if($Count) {
209 + for($i = 0; $i < $Count; $i++) {
210 + $this->Buf[2 + $i] = ord($data[$dp+$i]);
211 + }
212 + $dp += $Count;
213 + }
214 + else {
215 + $this->Done = 1;
216 + }
217 +
218 + $this->LastByte = 2 + $Count;
219 + $this->CurBit = ($this->CurBit - $this->LastBit) + 16;
220 + $this->LastBit = (2 + $Count) << 3;
221 + }
222 +
223 + $iRet = 0;
224 + for($i = $this->CurBit, $j = 0; $j < $this->CodeSize; $i++, $j++) {
225 + $iRet |= (($this->Buf[intval($i / 8)] & (1 << ($i % 8))) != 0) << $j;
226 + }
227 +
228 + $this->CurBit += $this->CodeSize;
229 + return $iRet;
230 + }
231 +}
232 +
233 +///////////////////////////////////////////////////////////////////////////////////////////////////
234 +
235 +class CGIFCOLORTABLE
236 +{
237 + var $m_nColors;
238 + var $m_arColors;
239 +
240 + ///////////////////////////////////////////////////////////////////////////
241 +
242 + // CONSTRUCTOR
243 + function CGIFCOLORTABLE()
244 + {
245 + unSet($this->m_nColors);
246 + unSet($this->m_arColors);
247 + }
248 +
249 + ///////////////////////////////////////////////////////////////////////////
250 +
251 + function load($lpData, $num)
252 + {
253 + $this->m_nColors = 0;
254 + $this->m_arColors = array();
255 +
256 + for($i = 0; $i < $num; $i++) {
257 + $rgb = substr($lpData, $i * 3, 3);
258 + if(strlen($rgb) < 3) {
259 + return false;
260 + }
261 +
262 + $this->m_arColors[] = (ord($rgb[2]) << 16) + (ord($rgb[1]) << 8) + ord($rgb[0]);
263 + $this->m_nColors++;
264 + }
265 +
266 + return true;
267 + }
268 +
269 + ///////////////////////////////////////////////////////////////////////////
270 +
271 + function toString()
272 + {
273 + $ret = "";
274 +
275 + for($i = 0; $i < $this->m_nColors; $i++) {
276 + $ret .=
277 + chr(($this->m_arColors[$i] & 0x000000FF)) . // R
278 + chr(($this->m_arColors[$i] & 0x0000FF00) >> 8) . // G
279 + chr(($this->m_arColors[$i] & 0x00FF0000) >> 16); // B
280 + }
281 +
282 + return $ret;
283 + }
284 +
285 +
286 + ///////////////////////////////////////////////////////////////////////////
287 +
288 + function colorIndex($rgb)
289 + {
290 + $rgb = intval($rgb) & 0xFFFFFF;
291 + $r1 = ($rgb & 0x0000FF);
292 + $g1 = ($rgb & 0x00FF00) >> 8;
293 + $b1 = ($rgb & 0xFF0000) >> 16;
294 + $idx = -1;
295 +
296 + for($i = 0; $i < $this->m_nColors; $i++) {
297 + $r2 = ($this->m_arColors[$i] & 0x000000FF);
298 + $g2 = ($this->m_arColors[$i] & 0x0000FF00) >> 8;
299 + $b2 = ($this->m_arColors[$i] & 0x00FF0000) >> 16;
300 + $d = abs($r2 - $r1) + abs($g2 - $g1) + abs($b2 - $b1);
301 +
302 + if(($idx == -1) || ($d < $dif)) {
303 + $idx = $i;
304 + $dif = $d;
305 + }
306 + }
307 +
308 + return $idx;
309 + }
310 +}
311 +
312 +///////////////////////////////////////////////////////////////////////////////////////////////////
313 +
314 +class CGIFFILEHEADER
315 +{
316 + var $m_lpVer;
317 + var $m_nWidth;
318 + var $m_nHeight;
319 + var $m_bGlobalClr;
320 + var $m_nColorRes;
321 + var $m_bSorted;
322 + var $m_nTableSize;
323 + var $m_nBgColor;
324 + var $m_nPixelRatio;
325 + var $m_colorTable;
326 +
327 + ///////////////////////////////////////////////////////////////////////////
328 +
329 + // CONSTRUCTOR
330 + function CGIFFILEHEADER()
331 + {
332 + unSet($this->m_lpVer);
333 + unSet($this->m_nWidth);
334 + unSet($this->m_nHeight);
335 + unSet($this->m_bGlobalClr);
336 + unSet($this->m_nColorRes);
337 + unSet($this->m_bSorted);
338 + unSet($this->m_nTableSize);
339 + unSet($this->m_nBgColor);
340 + unSet($this->m_nPixelRatio);
341 + unSet($this->m_colorTable);
342 + }
343 +
344 + ///////////////////////////////////////////////////////////////////////////
345 +
346 + function load($lpData, &$hdrLen)
347 + {
348 + $hdrLen = 0;
349 +
350 + $this->m_lpVer = substr($lpData, 0, 6);
351 + if(($this->m_lpVer <> "GIF87a") && ($this->m_lpVer <> "GIF89a")) {
352 + return false;
353 + }
354 +
355 + $this->m_nWidth = $this->w2i(substr($lpData, 6, 2));
356 + $this->m_nHeight = $this->w2i(substr($lpData, 8, 2));
357 + if(!$this->m_nWidth || !$this->m_nHeight) {
358 + return false;
359 + }
360 +
361 + $b = ord(substr($lpData, 10, 1));
362 + $this->m_bGlobalClr = ($b & 0x80) ? true : false;
363 + $this->m_nColorRes = ($b & 0x70) >> 4;
364 + $this->m_bSorted = ($b & 0x08) ? true : false;
365 + $this->m_nTableSize = 2 << ($b & 0x07);
366 + $this->m_nBgColor = ord(substr($lpData, 11, 1));
367 + $this->m_nPixelRatio = ord(substr($lpData, 12, 1));
368 + $hdrLen = 13;
369 +
370 + if($this->m_bGlobalClr) {
371 + $this->m_colorTable = new CGIFCOLORTABLE();
372 + if(!$this->m_colorTable->load(substr($lpData, $hdrLen), $this->m_nTableSize)) {
373 + return false;
374 + }
375 + $hdrLen += 3 * $this->m_nTableSize;
376 + }
377 +
378 + return true;
379 + }
380 +
381 + ///////////////////////////////////////////////////////////////////////////
382 +
383 + function w2i($str)
384 + {
385 + return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8);
386 + }
387 +}
388 +
389 +///////////////////////////////////////////////////////////////////////////////////////////////////
390 +
391 +class CGIFIMAGEHEADER
392 +{
393 + var $m_nLeft;
394 + var $m_nTop;
395 + var $m_nWidth;
396 + var $m_nHeight;
397 + var $m_bLocalClr;
398 + var $m_bInterlace;
399 + var $m_bSorted;
400 + var $m_nTableSize;
401 + var $m_colorTable;
402 +
403 + ///////////////////////////////////////////////////////////////////////////
404 +
405 + // CONSTRUCTOR
406 + function CGIFIMAGEHEADER()
407 + {
408 + unSet($this->m_nLeft);
409 + unSet($this->m_nTop);
410 + unSet($this->m_nWidth);
411 + unSet($this->m_nHeight);
412 + unSet($this->m_bLocalClr);
413 + unSet($this->m_bInterlace);
414 + unSet($this->m_bSorted);
415 + unSet($this->m_nTableSize);
416 + unSet($this->m_colorTable);
417 + }
418 +
419 + ///////////////////////////////////////////////////////////////////////////
420 +
421 + function load($lpData, &$hdrLen)
422 + {
423 + $hdrLen = 0;
424 +
425 + $this->m_nLeft = $this->w2i(substr($lpData, 0, 2));
426 + $this->m_nTop = $this->w2i(substr($lpData, 2, 2));
427 + $this->m_nWidth = $this->w2i(substr($lpData, 4, 2));
428 + $this->m_nHeight = $this->w2i(substr($lpData, 6, 2));
429 +
430 + if(!$this->m_nWidth || !$this->m_nHeight) {
431 + return false;
432 + }
433 +
434 + $b = ord($lpData{8});
435 + $this->m_bLocalClr = ($b & 0x80) ? true : false;
436 + $this->m_bInterlace = ($b & 0x40) ? true : false;
437 + $this->m_bSorted = ($b & 0x20) ? true : false;
438 + $this->m_nTableSize = 2 << ($b & 0x07);
439 + $hdrLen = 9;
440 +
441 + if($this->m_bLocalClr) {
442 + $this->m_colorTable = new CGIFCOLORTABLE();
443 + if(!$this->m_colorTable->load(substr($lpData, $hdrLen), $this->m_nTableSize)) {
444 + return false;
445 + }
446 + $hdrLen += 3 * $this->m_nTableSize;
447 + }
448 +
449 + return true;
450 + }
451 +
452 + ///////////////////////////////////////////////////////////////////////////
453 +
454 + function w2i($str)
455 + {
456 + return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8);
457 + }
458 +}
459 +
460 +///////////////////////////////////////////////////////////////////////////////////////////////////
461 +
462 +class CGIFIMAGE
463 +{
464 + var $m_disp;
465 + var $m_bUser;
466 + var $m_bTrans;
467 + var $m_nDelay;
468 + var $m_nTrans;
469 + var $m_lpComm;
470 + var $m_gih;
471 + var $m_data;
472 + var $m_lzw;
473 +
474 + ///////////////////////////////////////////////////////////////////////////
475 +
476 + function CGIFIMAGE()
477 + {
478 + unSet($this->m_disp);
479 + unSet($this->m_bUser);
480 + unSet($this->m_bTrans);
481 + unSet($this->m_nDelay);
482 + unSet($this->m_nTrans);
483 + unSet($this->m_lpComm);
484 + unSet($this->m_data);
485 + $this->m_gih = new CGIFIMAGEHEADER();
486 + $this->m_lzw = new CGIFLZW();
487 + }
488 +
489 + ///////////////////////////////////////////////////////////////////////////
490 +
491 + function load($data, &$datLen)
492 + {
493 + $datLen = 0;
494 +
495 + while(true) {
496 + $b = ord($data[0]);
497 + $data = substr($data, 1);
498 + $datLen++;
499 +
500 + switch($b) {
501 + case 0x21: // Extension
502 + $len = 0;
503 + if(!$this->skipExt($data, $len)) {
504 + return false;
505 + }
506 + $datLen += $len;
507 + break;
508 +
509 + case 0x2C: // Image
510 + // LOAD HEADER & COLOR TABLE
511 + $len = 0;
512 + if(!$this->m_gih->load($data, $len)) {
513 + return false;
514 + }
515 + $data = substr($data, $len);
516 + $datLen += $len;
517 +
518 + // ALLOC BUFFER
519 + $len = 0;
520 +
521 + if(!($this->m_data = $this->m_lzw->deCompress($data, $len))) {
522 + return false;
523 + }
524 +
525 + $data = substr($data, $len);
526 + $datLen += $len;
527 +
528 + if($this->m_gih->m_bInterlace) {
529 + $this->deInterlace();
530 + }
531 +
532 + return true;
533 +
534 + case 0x3B: // EOF
535 + default:
536 + return false;
537 + }
538 + }
539 + return false;
540 + }
541 +
542 + ///////////////////////////////////////////////////////////////////////////
543 +
544 + function skipExt(&$data, &$extLen)
545 + {
546 + $extLen = 0;
547 +
548 + $b = ord($data[0]);
549 + $data = substr($data, 1);
550 + $extLen++;
551 +
552 + switch($b) {
553 + case 0xF9: // Graphic Control
554 + $b = ord($data[1]);
555 + $this->m_disp = ($b & 0x1C) >> 2;
556 + $this->m_bUser = ($b & 0x02) ? true : false;
557 + $this->m_bTrans = ($b & 0x01) ? true : false;
558 + $this->m_nDelay = $this->w2i(substr($data, 2, 2));
559 + $this->m_nTrans = ord($data[4]);
560 + break;
561 +
562 + case 0xFE: // Comment
563 + $this->m_lpComm = substr($data, 1, ord($data[0]));
564 + break;
565 +
566 + case 0x01: // Plain text
567 + break;
568 +
569 + case 0xFF: // Application
570 + break;
571 + }
572 +
573 + // SKIP DEFAULT AS DEFS MAY CHANGE
574 + $b = ord($data[0]);
575 + $data = substr($data, 1);
576 + $extLen++;
577 + while($b > 0) {
578 + $data = substr($data, $b);
579 + $extLen += $b;
580 + $b = ord($data[0]);
581 + $data = substr($data, 1);
582 + $extLen++;
583 + }
584 + return true;
585 + }
586 +
587 + ///////////////////////////////////////////////////////////////////////////
588 +
589 + function w2i($str)
590 + {
591 + return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8);
592 + }
593 +
594 + ///////////////////////////////////////////////////////////////////////////
595 +
596 + function deInterlace()
597 + {
598 + $data = $this->m_data;
599 +
600 + for($i = 0; $i < 4; $i++) {
601 + switch($i) {
602 + case 0:
603 + $s = 8;
604 + $y = 0;
605 + break;
606 +
607 + case 1:
608 + $s = 8;
609 + $y = 4;
610 + break;
611 +
612 + case 2:
613 + $s = 4;
614 + $y = 2;
615 + break;
616 +
617 + case 3:
618 + $s = 2;
619 + $y = 1;
620 + break;
621 + }
622 +
623 + for(; $y < $this->m_gih->m_nHeight; $y += $s) {
624 + $lne = substr($this->m_data, 0, $this->m_gih->m_nWidth);
625 + $this->m_data = substr($this->m_data, $this->m_gih->m_nWidth);
626 +
627 + $data =
628 + substr($data, 0, $y * $this->m_gih->m_nWidth) .
629 + $lne .
630 + substr($data, ($y + 1) * $this->m_gih->m_nWidth);
631 + }
632 + }
633 +
634 + $this->m_data = $data;
635 + }
636 +}
637 +
638 +///////////////////////////////////////////////////////////////////////////////////////////////////
639 +
640 +class CGIF
641 +{
642 + var $m_gfh;
643 + var $m_lpData;
644 + var $m_img;
645 + var $m_bLoaded;
646 +
647 + ///////////////////////////////////////////////////////////////////////////
648 +
649 + // CONSTRUCTOR
650 + function CGIF()
651 + {
652 + $this->m_gfh = new CGIFFILEHEADER();
653 + $this->m_img = new CGIFIMAGE();
654 + $this->m_lpData = "";
655 + $this->m_bLoaded = false;
656 + }
657 +
658 + ///////////////////////////////////////////////////////////////////////////
659 + function ClearData() {
660 + $this->m_lpData = '';
661 + unSet($this->m_img->m_data);
662 + unSet($this->m_img->m_lzw->Next);
663 + unSet($this->m_img->m_lzw->Vals);
664 + unSet($this->m_img->m_lzw->Stack);
665 + unSet($this->m_img->m_lzw->Buf);
666 + }
667 +
668 + function loadFile(&$data, $iIndex)
669 + {
670 + if($iIndex < 0) {
671 + return false;
672 + }
673 + $this->m_lpData = $data;
674 +
675 + // GET FILE HEADER
676 + $len = 0;
677 + if(!$this->m_gfh->load($this->m_lpData, $len)) {
678 + return false;
679 + }
680 +
681 + $this->m_lpData = substr($this->m_lpData, $len);
682 +
683 + do {
684 + $imgLen = 0;
685 + if(!$this->m_img->load($this->m_lpData, $imgLen)) {
686 + return false;
687 + }
688 + $this->m_lpData = substr($this->m_lpData, $imgLen);
689 + }
690 + while($iIndex-- > 0);
691 +
692 + $this->m_bLoaded = true;
693 + return true;
694 + }
695 +
696 +}
697 +
698 +///////////////////////////////////////////////////////////////////////////////////////////////////
699 +
700 +?>