source: trunk/www.guidonia.net/wp/wp-content/plugins/ferdinand-wordbook/phpthumb/phpthumb.gif.php@ 44

Last change on this file since 44 was 44, checked in by luciano, 14 years ago
File size: 29.2 KB
Line 
1<?php
2///////////////////////////////////////////////////////////////////////////////////////////////////
3// GIF Util - (C) 2003 Yamasoft (S/C)
4// http://www.yamasoft.com
5// All Rights Reserved
6// This file can be freely copied, distributed, modified, updated by anyone under the only
7// condition to leave the original address (Yamasoft, http://www.yamasoft.com) and this header.
8///////////////////////////////////////////////////////////////////////////////////////////////////
9// <gif> = gif_loadFile(filename, [index])
10// <bool> = gif_getSize(<gif> or filename, &width, &height)
11// <bool> = gif_outputAsPng(<gif>, filename, [bgColor])
12// <bool> = gif_outputAsBmp(<gif>, filename, [bgcolor])
13// <bool> = gif_outputAsJpeg(<gif>, filename, [bgcolor]) - use cjpeg if available otherwise uses GD
14///////////////////////////////////////////////////////////////////////////////////////////////////
15// Original code by Fabien Ezber
16// Modified by James Heinrich <info@silisoftware.com> for use in phpThumb() - December 10, 2003
17// * Added function gif_loadFileToGDimageResource() - this returns a GD image resource
18// * Modified gif_outputAsJpeg() to check if it's running under Windows, or if cjpeg is not
19// available, in which case it will attempt to output JPEG using GD functions
20// * added @ error-suppression to two lines where it checks: if ($this->m_img->m_bTrans)
21// otherwise warnings are generated if error_reporting == E_ALL
22///////////////////////////////////////////////////////////////////////////////////////////////////
23
24function gif_loadFile($lpszFileName, $iIndex = 0)
25{
26 $gif = new CGIF();
27 if ($gif->loadFile($lpszFileName, $iIndex)) {
28 return $gif;
29 }
30 return false;
31}
32
33///////////////////////////////////////////////////////////////////////////////////////////////////
34
35// Added by James Heinrich <info@silisoftware.com> - December 10, 2003
36function gif_loadFileToGDimageResource($gifFilename, $bgColor = -1)
37{
38 if ($gif = gif_loadFile($gifFilename)) {
39
40 if (!phpthumb_functions::FunctionIsDisabled('set_time_limit')) {
41 // shouldn't take nearly this long
42 set_time_limit(120);
43 }
44 // general strategy: convert raw data to PNG then convert PNG data to GD image resource
45 $PNGdata = $gif->getPng($bgColor);
46 if ($img = @ImageCreateFromString($PNGdata)) {
47
48 // excellent - PNG image data successfully converted to GD image
49 return $img;
50
51 } elseif ($img = $gif->getGD_PixelPlotterVersion()) {
52
53 // problem: ImageCreateFromString() didn't like the PNG image data.
54 // This has been known to happen in PHP v4.0.6
55 // solution: take the raw image data and create a new GD image and plot
56 // pixel-by-pixel on the GD image. This is extremely slow, but it does
57 // work and a slow solution is better than no solution, right? :)
58 return $img;
59
60 }
61 }
62 return false;
63}
64
65///////////////////////////////////////////////////////////////////////////////////////////////////
66
67function gif_outputAsBmp($gif, $lpszFileName, $bgColor = -1)
68{
69 if (!isSet($gif) || (@get_class($gif) <> 'cgif') || !$gif->loaded() || ($lpszFileName == '')) {
70 return false;
71 }
72
73 $fd = $gif->getBmp($bgColor);
74 if (strlen($fd) <= 0) {
75 return false;
76 }
77
78 if (!($fh = @fopen($lpszFileName, 'wb'))) {
79 return false;
80 }
81 @fwrite($fh, $fd, strlen($fd));
82 @fflush($fh);
83 @fclose($fh);
84 return true;
85}
86
87///////////////////////////////////////////////////////////////////////////////////////////////////
88
89function gif_outputAsPng($gif, $lpszFileName, $bgColor = -1)
90{
91 if (!isSet($gif) || (@get_class($gif) <> 'cgif') || !$gif->loaded() || ($lpszFileName == '')) {
92 return false;
93 }
94
95 $fd = $gif->getPng($bgColor);
96 if (strlen($fd) <= 0) {
97 return false;
98 }
99
100 if (!($fh = @fopen($lpszFileName, 'wb'))) {
101 return false;
102 }
103 @fwrite($fh, $fd, strlen($fd));
104 @fflush($fh);
105 @fclose($fh);
106 return true;
107}
108
109///////////////////////////////////////////////////////////////////////////////////////////////////
110
111function gif_outputAsJpeg($gif, $lpszFileName, $bgColor = -1)
112{
113 // JPEG output that does not require cjpeg added by James Heinrich <info@silisoftware.com> - December 10, 2003
114 if ((strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') && (file_exists('/usr/local/bin/cjpeg') || `which cjpeg`)) {
115
116 if (gif_outputAsBmp($gif, $lpszFileName.'.bmp', $bgColor)) {
117 exec('cjpeg '.$lpszFileName.'.bmp >'.$lpszFileName.' 2>/dev/null');
118 @unLink($lpszFileName.'.bmp');
119
120 if (@file_exists($lpszFileName)) {
121 if (@fileSize($lpszFileName) > 0) {
122 return true;
123 }
124
125 @unLink($lpszFileName);
126 }
127 }
128
129 } else {
130
131 // either Windows, or cjpeg not found in path
132 if ($img = @ImageCreateFromString($gif->getPng($bgColor))) {
133 if (@ImageJPEG($img, $lpszFileName)) {
134 return true;
135 }
136 }
137
138 }
139
140 return false;
141}
142
143///////////////////////////////////////////////////////////////////////////////////////////////////
144
145function gif_getSize($gif, &$width, &$height)
146{
147 if (isSet($gif) && (@get_class($gif) == 'cgif') && $gif->loaded()) {
148 $width = $gif->width();
149 $height = $gif->height();
150 } elseif (@file_exists($gif)) {
151 $myGIF = new CGIF();
152 if (!$myGIF->getSize($gif, $width, $height)) {
153 return false;
154 }
155 } else {
156 return false;
157 }
158
159 return true;
160}
161
162///////////////////////////////////////////////////////////////////////////////////////////////////
163
164class CGIFLZW
165{
166 var $MAX_LZW_BITS;
167 var $Fresh, $CodeSize, $SetCodeSize, $MaxCode, $MaxCodeSize, $FirstCode, $OldCode;
168 var $ClearCode, $EndCode, $Next, $Vals, $Stack, $sp, $Buf, $CurBit, $LastBit, $Done, $LastByte;
169
170 ///////////////////////////////////////////////////////////////////////////
171
172 // CONSTRUCTOR
173 function CGIFLZW()
174 {
175 $this->MAX_LZW_BITS = 12;
176 unSet($this->Next);
177 unSet($this->Vals);
178 unSet($this->Stack);
179 unSet($this->Buf);
180
181 $this->Next = range(0, (1 << $this->MAX_LZW_BITS) - 1);
182 $this->Vals = range(0, (1 << $this->MAX_LZW_BITS) - 1);
183 $this->Stack = range(0, (1 << ($this->MAX_LZW_BITS + 1)) - 1);
184 $this->Buf = range(0, 279);
185 }
186
187 ///////////////////////////////////////////////////////////////////////////
188
189 function deCompress($data, &$datLen)
190 {
191 $stLen = strlen($data);
192 $datLen = 0;
193 $ret = '';
194
195 // INITIALIZATION
196 $this->LZWCommand($data, true);
197
198 while (($iIndex = $this->LZWCommand($data, false)) >= 0) {
199 $ret .= chr($iIndex);
200 }
201
202 $datLen = $stLen - strlen($data);
203
204 if ($iIndex != -2) {
205 return false;
206 }
207
208 return $ret;
209 }
210
211 ///////////////////////////////////////////////////////////////////////////
212
213 function LZWCommand(&$data, $bInit)
214 {
215 if ($bInit) {
216 $this->SetCodeSize = ord($data{0});
217 $data = substr($data, 1);
218
219 $this->CodeSize = $this->SetCodeSize + 1;
220 $this->ClearCode = 1 << $this->SetCodeSize;
221 $this->EndCode = $this->ClearCode + 1;
222 $this->MaxCode = $this->ClearCode + 2;
223 $this->MaxCodeSize = $this->ClearCode << 1;
224
225 $this->GetCode($data, $bInit);
226
227 $this->Fresh = 1;
228 for ($i = 0; $i < $this->ClearCode; $i++) {
229 $this->Next[$i] = 0;
230 $this->Vals[$i] = $i;
231 }
232
233 for (; $i < (1 << $this->MAX_LZW_BITS); $i++) {
234 $this->Next[$i] = 0;
235 $this->Vals[$i] = 0;
236 }
237
238 $this->sp = 0;
239 return 1;
240 }
241
242 if ($this->Fresh) {
243 $this->Fresh = 0;
244 do {
245 $this->FirstCode = $this->GetCode($data, $bInit);
246 $this->OldCode = $this->FirstCode;
247 }
248 while ($this->FirstCode == $this->ClearCode);
249
250 return $this->FirstCode;
251 }
252
253 if ($this->sp > 0) {
254 $this->sp--;
255 return $this->Stack[$this->sp];
256 }
257
258 while (($Code = $this->GetCode($data, $bInit)) >= 0) {
259 if ($Code == $this->ClearCode) {
260 for ($i = 0; $i < $this->ClearCode; $i++) {
261 $this->Next[$i] = 0;
262 $this->Vals[$i] = $i;
263 }
264
265 for (; $i < (1 << $this->MAX_LZW_BITS); $i++) {
266 $this->Next[$i] = 0;
267 $this->Vals[$i] = 0;
268 }
269
270 $this->CodeSize = $this->SetCodeSize + 1;
271 $this->MaxCodeSize = $this->ClearCode << 1;
272 $this->MaxCode = $this->ClearCode + 2;
273 $this->sp = 0;
274 $this->FirstCode = $this->GetCode($data, $bInit);
275 $this->OldCode = $this->FirstCode;
276
277 return $this->FirstCode;
278 }
279
280 if ($Code == $this->EndCode) {
281 return -2;
282 }
283
284 $InCode = $Code;
285 if ($Code >= $this->MaxCode) {
286 $this->Stack[$this->sp] = $this->FirstCode;
287 $this->sp++;
288 $Code = $this->OldCode;
289 }
290
291 while ($Code >= $this->ClearCode) {
292 $this->Stack[$this->sp] = $this->Vals[$Code];
293 $this->sp++;
294
295 if ($Code == $this->Next[$Code]) // Circular table entry, big GIF Error!
296 return -1;
297
298 $Code = $this->Next[$Code];
299 }
300
301 $this->FirstCode = $this->Vals[$Code];
302 $this->Stack[$this->sp] = $this->FirstCode;
303 $this->sp++;
304
305 if (($Code = $this->MaxCode) < (1 << $this->MAX_LZW_BITS)) {
306 $this->Next[$Code] = $this->OldCode;
307 $this->Vals[$Code] = $this->FirstCode;
308 $this->MaxCode++;
309
310 if (($this->MaxCode >= $this->MaxCodeSize) && ($this->MaxCodeSize < (1 << $this->MAX_LZW_BITS))) {
311 $this->MaxCodeSize *= 2;
312 $this->CodeSize++;
313 }
314 }
315
316 $this->OldCode = $InCode;
317 if ($this->sp > 0) {
318 $this->sp--;
319 return $this->Stack[$this->sp];
320 }
321 }
322
323 return $Code;
324 }
325
326 ///////////////////////////////////////////////////////////////////////////
327
328 function GetCode(&$data, $bInit)
329 {
330 if ($bInit) {
331 $this->CurBit = 0;
332 $this->LastBit = 0;
333 $this->Done = 0;
334 $this->LastByte = 2;
335 return 1;
336 }
337
338 if (($this->CurBit + $this->CodeSize) >= $this->LastBit) {
339 if ($this->Done) {
340 if ($this->CurBit >= $this->LastBit) {
341 // Ran off the end of my bits
342 return 0;
343 }
344 return -1;
345 }
346
347 $this->Buf[0] = $this->Buf[$this->LastByte - 2];
348 $this->Buf[1] = $this->Buf[$this->LastByte - 1];
349
350 $Count = ord($data{0});
351 $data = substr($data, 1);
352
353 if ($Count) {
354 for ($i = 0; $i < $Count; $i++) {
355 $this->Buf[2 + $i] = ord($data{$i});
356 }
357 $data = substr($data, $Count);
358 } else {
359 $this->Done = 1;
360 }
361
362 $this->LastByte = 2 + $Count;
363 $this->CurBit = ($this->CurBit - $this->LastBit) + 16;
364 $this->LastBit = (2 + $Count) << 3;
365 }
366
367 $iRet = 0;
368 for ($i = $this->CurBit, $j = 0; $j < $this->CodeSize; $i++, $j++) {
369 $iRet |= (($this->Buf[intval($i / 8)] & (1 << ($i % 8))) != 0) << $j;
370 }
371
372 $this->CurBit += $this->CodeSize;
373 return $iRet;
374 }
375}
376
377///////////////////////////////////////////////////////////////////////////////////////////////////
378
379class CGIFCOLORTABLE
380{
381 var $m_nColors;
382 var $m_arColors;
383
384 ///////////////////////////////////////////////////////////////////////////
385
386 // CONSTRUCTOR
387 function CGIFCOLORTABLE()
388 {
389 unSet($this->m_nColors);
390 unSet($this->m_arColors);
391 }
392
393 ///////////////////////////////////////////////////////////////////////////
394
395 function load($lpData, $num)
396 {
397 $this->m_nColors = 0;
398 $this->m_arColors = array();
399
400 for ($i = 0; $i < $num; $i++) {
401 $rgb = substr($lpData, $i * 3, 3);
402 if (strlen($rgb) < 3) {
403 return false;
404 }
405
406 $this->m_arColors[] = (ord($rgb{2}) << 16) + (ord($rgb{1}) << 8) + ord($rgb{0});
407 $this->m_nColors++;
408 }
409
410 return true;
411 }
412
413 ///////////////////////////////////////////////////////////////////////////
414
415 function toString()
416 {
417 $ret = '';
418
419 for ($i = 0; $i < $this->m_nColors; $i++) {
420 $ret .=
421 chr(($this->m_arColors[$i] & 0x000000FF)) . // R
422 chr(($this->m_arColors[$i] & 0x0000FF00) >> 8) . // G
423 chr(($this->m_arColors[$i] & 0x00FF0000) >> 16); // B
424 }
425
426 return $ret;
427 }
428
429 ///////////////////////////////////////////////////////////////////////////
430
431 function toRGBQuad()
432 {
433 $ret = '';
434
435 for ($i = 0; $i < $this->m_nColors; $i++) {
436 $ret .=
437 chr(($this->m_arColors[$i] & 0x00FF0000) >> 16) . // B
438 chr(($this->m_arColors[$i] & 0x0000FF00) >> 8) . // G
439 chr(($this->m_arColors[$i] & 0x000000FF)) . // R
440 "\x00";
441 }
442
443 return $ret;
444 }
445
446 ///////////////////////////////////////////////////////////////////////////
447
448 function colorIndex($rgb)
449 {
450 $rgb = intval($rgb) & 0xFFFFFF;
451 $r1 = ($rgb & 0x0000FF);
452 $g1 = ($rgb & 0x00FF00) >> 8;
453 $b1 = ($rgb & 0xFF0000) >> 16;
454 $idx = -1;
455
456 for ($i = 0; $i < $this->m_nColors; $i++) {
457 $r2 = ($this->m_arColors[$i] & 0x000000FF);
458 $g2 = ($this->m_arColors[$i] & 0x0000FF00) >> 8;
459 $b2 = ($this->m_arColors[$i] & 0x00FF0000) >> 16;
460 $d = abs($r2 - $r1) + abs($g2 - $g1) + abs($b2 - $b1);
461
462 if (($idx == -1) || ($d < $dif)) {
463 $idx = $i;
464 $dif = $d;
465 }
466 }
467
468 return $idx;
469 }
470}
471
472///////////////////////////////////////////////////////////////////////////////////////////////////
473
474class CGIFFILEHEADER
475{
476 var $m_lpVer;
477 var $m_nWidth;
478 var $m_nHeight;
479 var $m_bGlobalClr;
480 var $m_nColorRes;
481 var $m_bSorted;
482 var $m_nTableSize;
483 var $m_nBgColor;
484 var $m_nPixelRatio;
485 var $m_colorTable;
486
487 ///////////////////////////////////////////////////////////////////////////
488
489 // CONSTRUCTOR
490 function CGIFFILEHEADER()
491 {
492 unSet($this->m_lpVer);
493 unSet($this->m_nWidth);
494 unSet($this->m_nHeight);
495 unSet($this->m_bGlobalClr);
496 unSet($this->m_nColorRes);
497 unSet($this->m_bSorted);
498 unSet($this->m_nTableSize);
499 unSet($this->m_nBgColor);
500 unSet($this->m_nPixelRatio);
501 unSet($this->m_colorTable);
502 }
503
504 ///////////////////////////////////////////////////////////////////////////
505
506 function load($lpData, &$hdrLen)
507 {
508 $hdrLen = 0;
509
510 $this->m_lpVer = substr($lpData, 0, 6);
511 if (($this->m_lpVer <> 'GIF87a') && ($this->m_lpVer <> 'GIF89a')) {
512 return false;
513 }
514
515 $this->m_nWidth = $this->w2i(substr($lpData, 6, 2));
516 $this->m_nHeight = $this->w2i(substr($lpData, 8, 2));
517 if (!$this->m_nWidth || !$this->m_nHeight) {
518 return false;
519 }
520
521 $b = ord(substr($lpData, 10, 1));
522 $this->m_bGlobalClr = ($b & 0x80) ? true : false;
523 $this->m_nColorRes = ($b & 0x70) >> 4;
524 $this->m_bSorted = ($b & 0x08) ? true : false;
525 $this->m_nTableSize = 2 << ($b & 0x07);
526 $this->m_nBgColor = ord(substr($lpData, 11, 1));
527 $this->m_nPixelRatio = ord(substr($lpData, 12, 1));
528 $hdrLen = 13;
529
530 if ($this->m_bGlobalClr) {
531 $this->m_colorTable = new CGIFCOLORTABLE();
532 if (!$this->m_colorTable->load(substr($lpData, $hdrLen), $this->m_nTableSize)) {
533 return false;
534 }
535 $hdrLen += 3 * $this->m_nTableSize;
536 }
537
538 return true;
539 }
540
541 ///////////////////////////////////////////////////////////////////////////
542
543 function w2i($str)
544 {
545 return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8);
546 }
547}
548
549///////////////////////////////////////////////////////////////////////////////////////////////////
550
551class CGIFIMAGEHEADER
552{
553 var $m_nLeft;
554 var $m_nTop;
555 var $m_nWidth;
556 var $m_nHeight;
557 var $m_bLocalClr;
558 var $m_bInterlace;
559 var $m_bSorted;
560 var $m_nTableSize;
561 var $m_colorTable;
562
563 ///////////////////////////////////////////////////////////////////////////
564
565 // CONSTRUCTOR
566 function CGIFIMAGEHEADER()
567 {
568 unSet($this->m_nLeft);
569 unSet($this->m_nTop);
570 unSet($this->m_nWidth);
571 unSet($this->m_nHeight);
572 unSet($this->m_bLocalClr);
573 unSet($this->m_bInterlace);
574 unSet($this->m_bSorted);
575 unSet($this->m_nTableSize);
576 unSet($this->m_colorTable);
577 }
578
579 ///////////////////////////////////////////////////////////////////////////
580
581 function load($lpData, &$hdrLen)
582 {
583 $hdrLen = 0;
584
585 $this->m_nLeft = $this->w2i(substr($lpData, 0, 2));
586 $this->m_nTop = $this->w2i(substr($lpData, 2, 2));
587 $this->m_nWidth = $this->w2i(substr($lpData, 4, 2));
588 $this->m_nHeight = $this->w2i(substr($lpData, 6, 2));
589
590 if (!$this->m_nWidth || !$this->m_nHeight) {
591 return false;
592 }
593
594 $b = ord($lpData{8});
595 $this->m_bLocalClr = ($b & 0x80) ? true : false;
596 $this->m_bInterlace = ($b & 0x40) ? true : false;
597 $this->m_bSorted = ($b & 0x20) ? true : false;
598 $this->m_nTableSize = 2 << ($b & 0x07);
599 $hdrLen = 9;
600
601 if ($this->m_bLocalClr) {
602 $this->m_colorTable = new CGIFCOLORTABLE();
603 if (!$this->m_colorTable->load(substr($lpData, $hdrLen), $this->m_nTableSize)) {
604 return false;
605 }
606 $hdrLen += 3 * $this->m_nTableSize;
607 }
608
609 return true;
610 }
611
612 ///////////////////////////////////////////////////////////////////////////
613
614 function w2i($str)
615 {
616 return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8);
617 }
618}
619
620///////////////////////////////////////////////////////////////////////////////////////////////////
621
622class CGIFIMAGE
623{
624 var $m_disp;
625 var $m_bUser;
626 var $m_bTrans;
627 var $m_nDelay;
628 var $m_nTrans;
629 var $m_lpComm;
630 var $m_gih;
631 var $m_data;
632 var $m_lzw;
633
634 ///////////////////////////////////////////////////////////////////////////
635
636 function CGIFIMAGE()
637 {
638 unSet($this->m_disp);
639 unSet($this->m_bUser);
640 unSet($this->m_bTrans);
641 unSet($this->m_nDelay);
642 unSet($this->m_nTrans);
643 unSet($this->m_lpComm);
644 unSet($this->m_data);
645 $this->m_gih = new CGIFIMAGEHEADER();
646 $this->m_lzw = new CGIFLZW();
647 }
648
649 ///////////////////////////////////////////////////////////////////////////
650
651 function load($data, &$datLen)
652 {
653 $datLen = 0;
654
655 while (true) {
656 $b = ord($data{0});
657 $data = substr($data, 1);
658 $datLen++;
659
660 switch($b) {
661 case 0x21: // Extension
662 if (!$this->skipExt($data, $len = 0)) {
663 return false;
664 }
665 $datLen += $len;
666 break;
667
668 case 0x2C: // Image
669 // LOAD HEADER & COLOR TABLE
670 if (!$this->m_gih->load($data, $len = 0)) {
671 return false;
672 }
673 $data = substr($data, $len);
674 $datLen += $len;
675
676 // ALLOC BUFFER
677 if (!($this->m_data = $this->m_lzw->deCompress($data, $len = 0))) {
678 return false;
679 }
680 $data = substr($data, $len);
681 $datLen += $len;
682
683 if ($this->m_gih->m_bInterlace) {
684 $this->deInterlace();
685 }
686 return true;
687
688 case 0x3B: // EOF
689 default:
690 return false;
691 }
692 }
693 return false;
694 }
695
696 ///////////////////////////////////////////////////////////////////////////
697
698 function skipExt(&$data, &$extLen)
699 {
700 $extLen = 0;
701
702 $b = ord($data{0});
703 $data = substr($data, 1);
704 $extLen++;
705
706 switch($b) {
707 case 0xF9: // Graphic Control
708 $b = ord($data{1});
709 $this->m_disp = ($b & 0x1C) >> 2;
710 $this->m_bUser = ($b & 0x02) ? true : false;
711 $this->m_bTrans = ($b & 0x01) ? true : false;
712 $this->m_nDelay = $this->w2i(substr($data, 2, 2));
713 $this->m_nTrans = ord($data{4});
714 break;
715
716 case 0xFE: // Comment
717 $this->m_lpComm = substr($data, 1, ord($data{0}));
718 break;
719
720 case 0x01: // Plain text
721 break;
722
723 case 0xFF: // Application
724 break;
725 }
726
727 // SKIP DEFAULT AS DEFS MAY CHANGE
728 $b = ord($data{0});
729 $data = substr($data, 1);
730 $extLen++;
731 while ($b > 0) {
732 $data = substr($data, $b);
733 $extLen += $b;
734 $b = ord($data{0});
735 $data = substr($data, 1);
736 $extLen++;
737 }
738 return true;
739 }
740
741 ///////////////////////////////////////////////////////////////////////////
742
743 function w2i($str)
744 {
745 return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8);
746 }
747
748 ///////////////////////////////////////////////////////////////////////////
749
750 function deInterlace()
751 {
752 $data = $this->m_data;
753
754 for ($i = 0; $i < 4; $i++) {
755 switch($i) {
756 case 0:
757 $s = 8;
758 $y = 0;
759 break;
760
761 case 1:
762 $s = 8;
763 $y = 4;
764 break;
765
766 case 2:
767 $s = 4;
768 $y = 2;
769 break;
770
771 case 3:
772 $s = 2;
773 $y = 1;
774 break;
775 }
776
777 for (; $y < $this->m_gih->m_nHeight; $y += $s) {
778 $lne = substr($this->m_data, 0, $this->m_gih->m_nWidth);
779 $this->m_data = substr($this->m_data, $this->m_gih->m_nWidth);
780
781 $data =
782 substr($data, 0, $y * $this->m_gih->m_nWidth) .
783 $lne .
784 substr($data, ($y + 1) * $this->m_gih->m_nWidth);
785 }
786 }
787
788 $this->m_data = $data;
789 }
790}
791
792///////////////////////////////////////////////////////////////////////////////////////////////////
793
794class CGIF
795{
796 var $m_gfh;
797 var $m_lpData;
798 var $m_img;
799 var $m_bLoaded;
800
801 ///////////////////////////////////////////////////////////////////////////
802
803 // CONSTRUCTOR
804 function CGIF()
805 {
806 $this->m_gfh = new CGIFFILEHEADER();
807 $this->m_img = new CGIFIMAGE();
808 $this->m_lpData = '';
809 $this->m_bLoaded = false;
810 }
811
812 ///////////////////////////////////////////////////////////////////////////
813
814 function loadFile($lpszFileName, $iIndex)
815 {
816 if ($iIndex < 0) {
817 return false;
818 }
819
820 // READ FILE
821 if (!($fh = @fopen($lpszFileName, 'rb'))) {
822 return false;
823 }
824 $this->m_lpData = @fRead($fh, @fileSize($lpszFileName));
825 fclose($fh);
826
827 // GET FILE HEADER
828 if (!$this->m_gfh->load($this->m_lpData, $len = 0)) {
829 return false;
830 }
831 $this->m_lpData = substr($this->m_lpData, $len);
832
833 do {
834 if (!$this->m_img->load($this->m_lpData, $imgLen = 0)) {
835 return false;
836 }
837 $this->m_lpData = substr($this->m_lpData, $imgLen);
838 }
839 while ($iIndex-- > 0);
840
841 $this->m_bLoaded = true;
842 return true;
843 }
844
845 ///////////////////////////////////////////////////////////////////////////
846
847 function getSize($lpszFileName, &$width, &$height)
848 {
849 if (!($fh = @fopen($lpszFileName, 'rb'))) {
850 return false;
851 }
852 $data = @fRead($fh, @fileSize($lpszFileName));
853 @fclose($fh);
854
855 $gfh = new CGIFFILEHEADER();
856 if (!$gfh->load($data, $len = 0)) {
857 return false;
858 }
859
860 $width = $gfh->m_nWidth;
861 $height = $gfh->m_nHeight;
862 return true;
863 }
864
865 ///////////////////////////////////////////////////////////////////////////
866
867 function getBmp($bgColor)
868 {
869 $out = '';
870
871 if (!$this->m_bLoaded) {
872 return false;
873 }
874
875 // PREPARE COLOR TABLE (RGBQUADs)
876 if ($this->m_img->m_gih->m_bLocalClr) {
877 $nColors = $this->m_img->m_gih->m_nTableSize;
878 $rgbq = $this->m_img->m_gih->m_colorTable->toRGBQuad();
879 if ($bgColor != -1) {
880 $bgColor = $this->m_img->m_gih->m_colorTable->colorIndex($bgColor);
881 }
882 } elseif ($this->m_gfh->m_bGlobalClr) {
883 $nColors = $this->m_gfh->m_nTableSize;
884 $rgbq = $this->m_gfh->m_colorTable->toRGBQuad();
885 if ($bgColor != -1) {
886 $bgColor = $this->m_gfh->m_colorTable->colorIndex($bgColor);
887 }
888 } else {
889 $nColors = 0;
890 $bgColor = -1;
891 }
892
893 // PREPARE BITMAP BITS
894 $data = $this->m_img->m_data;
895 $nPxl = ($this->m_gfh->m_nHeight - 1) * $this->m_gfh->m_nWidth;
896 $bmp = '';
897 $nPad = ($this->m_gfh->m_nWidth % 4) ? 4 - ($this->m_gfh->m_nWidth % 4) : 0;
898 for ($y = 0; $y < $this->m_gfh->m_nHeight; $y++) {
899 for ($x = 0; $x < $this->m_gfh->m_nWidth; $x++, $nPxl++) {
900 if (
901 ($x >= $this->m_img->m_gih->m_nLeft) &&
902 ($y >= $this->m_img->m_gih->m_nTop) &&
903 ($x < ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) &&
904 ($y < ($this->m_img->m_gih->m_nTop + $this->m_img->m_gih->m_nHeight))) {
905 // PART OF IMAGE
906 if (@$this->m_img->m_bTrans && (ord($data{$nPxl}) == $this->m_img->m_nTrans)) {
907 // TRANSPARENT -> BACKGROUND
908 if ($bgColor == -1) {
909 $bmp .= chr($this->m_gfh->m_nBgColor);
910 } else {
911 $bmp .= chr($bgColor);
912 }
913 } else {
914 $bmp .= $data{$nPxl};
915 }
916 } else {
917 // BACKGROUND
918 if ($bgColor == -1) {
919 $bmp .= chr($this->m_gfh->m_nBgColor);
920 } else {
921 $bmp .= chr($bgColor);
922 }
923 }
924 }
925 $nPxl -= $this->m_gfh->m_nWidth << 1;
926
927 // ADD PADDING
928 for ($x = 0; $x < $nPad; $x++) {
929 $bmp .= "\x00";
930 }
931 }
932
933 // BITMAPFILEHEADER
934 $out .= 'BM';
935 $out .= $this->dword(14 + 40 + ($nColors << 2) + strlen($bmp));
936 $out .= "\x00\x00";
937 $out .= "\x00\x00";
938 $out .= $this->dword(14 + 40 + ($nColors << 2));
939
940 // BITMAPINFOHEADER
941 $out .= $this->dword(40);
942 $out .= $this->dword($this->m_gfh->m_nWidth);
943 $out .= $this->dword($this->m_gfh->m_nHeight);
944 $out .= "\x01\x00";
945 $out .= "\x08\x00";
946 $out .= "\x00\x00\x00\x00";
947 $out .= "\x00\x00\x00\x00";
948 $out .= "\x12\x0B\x00\x00";
949 $out .= "\x12\x0B\x00\x00";
950 $out .= $this->dword($nColors % 256);
951 $out .= "\x00\x00\x00\x00";
952
953 // COLOR TABLE
954 if ($nColors > 0) {
955 $out .= $rgbq;
956 }
957
958 // DATA
959 $out .= $bmp;
960
961 return $out;
962 }
963
964 ///////////////////////////////////////////////////////////////////////////
965
966 function getPng($bgColor)
967 {
968 $out = '';
969
970 if (!$this->m_bLoaded) {
971 return false;
972 }
973
974 // PREPARE COLOR TABLE (RGBQUADs)
975 if ($this->m_img->m_gih->m_bLocalClr) {
976 $nColors = $this->m_img->m_gih->m_nTableSize;
977 $pal = $this->m_img->m_gih->m_colorTable->toString();
978 if ($bgColor != -1) {
979 $bgColor = $this->m_img->m_gih->m_colorTable->colorIndex($bgColor);
980 }
981 } elseif ($this->m_gfh->m_bGlobalClr) {
982 $nColors = $this->m_gfh->m_nTableSize;
983 $pal = $this->m_gfh->m_colorTable->toString();
984 if ($bgColor != -1) {
985 $bgColor = $this->m_gfh->m_colorTable->colorIndex($bgColor);
986 }
987 } else {
988 $nColors = 0;
989 $bgColor = -1;
990 }
991
992 // PREPARE BITMAP BITS
993 $data = $this->m_img->m_data;
994 $nPxl = 0;
995 $bmp = '';
996 for ($y = 0; $y < $this->m_gfh->m_nHeight; $y++) {
997 $bmp .= "\x00";
998 for ($x = 0; $x < $this->m_gfh->m_nWidth; $x++, $nPxl++) {
999 if (
1000 ($x >= $this->m_img->m_gih->m_nLeft) &&
1001 ($y >= $this->m_img->m_gih->m_nTop) &&
1002 ($x < ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) &&
1003 ($y < ($this->m_img->m_gih->m_nTop + $this->m_img->m_gih->m_nHeight))) {
1004 // PART OF IMAGE
1005 $bmp .= $data{$nPxl};
1006 } else {
1007 // BACKGROUND
1008 if ($bgColor == -1) {
1009 $bmp .= chr($this->m_gfh->m_nBgColor);
1010 } else {
1011 $bmp .= chr($bgColor);
1012 }
1013 }
1014 }
1015 }
1016 $bmp = gzcompress($bmp, 9);
1017
1018 ///////////////////////////////////////////////////////////////////////
1019 // SIGNATURE
1020 $out .= "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A";
1021 ///////////////////////////////////////////////////////////////////////
1022 // HEADER
1023 $out .= "\x00\x00\x00\x0D";
1024 $tmp = 'IHDR';
1025 $tmp .= $this->ndword($this->m_gfh->m_nWidth);
1026 $tmp .= $this->ndword($this->m_gfh->m_nHeight);
1027 $tmp .= "\x08\x03\x00\x00\x00";
1028 $out .= $tmp;
1029 $out .= $this->ndword(crc32($tmp));
1030 ///////////////////////////////////////////////////////////////////////
1031 // PALETTE
1032 if ($nColors > 0) {
1033 $out .= $this->ndword($nColors * 3);
1034 $tmp = 'PLTE';
1035 $tmp .= $pal;
1036 $out .= $tmp;
1037 $out .= $this->ndword(crc32($tmp));
1038 }
1039 ///////////////////////////////////////////////////////////////////////
1040 // TRANSPARENCY
1041 if (@$this->m_img->m_bTrans && ($nColors > 0)) {
1042 $out .= $this->ndword($nColors);
1043 $tmp = 'tRNS';
1044 for ($i = 0; $i < $nColors; $i++) {
1045 $tmp .= ($i == $this->m_img->m_nTrans) ? "\x00" : "\xFF";
1046 }
1047 $out .= $tmp;
1048 $out .= $this->ndword(crc32($tmp));
1049 }
1050 ///////////////////////////////////////////////////////////////////////
1051 // DATA BITS
1052 $out .= $this->ndword(strlen($bmp));
1053 $tmp = 'IDAT';
1054 $tmp .= $bmp;
1055 $out .= $tmp;
1056 $out .= $this->ndword(crc32($tmp));
1057 ///////////////////////////////////////////////////////////////////////
1058 // END OF FILE
1059 $out .= "\x00\x00\x00\x00IEND\xAE\x42\x60\x82";
1060
1061 return $out;
1062 }
1063
1064 ///////////////////////////////////////////////////////////////////////////
1065
1066 // Added by James Heinrich <info@silisoftware.com> - January 5, 2003
1067
1068 // Takes raw image data and plots it pixel-by-pixel on a new GD image and returns that
1069 // It's extremely slow, but the only solution when ImageCreateFromString() fails
1070 function getGD_PixelPlotterVersion()
1071 {
1072 if (!$this->m_bLoaded) {
1073 return false;
1074 }
1075
1076 // PREPARE COLOR TABLE (RGBQUADs)
1077 if ($this->m_img->m_gih->m_bLocalClr) {
1078 $pal = $this->m_img->m_gih->m_colorTable->toString();
1079 } elseif ($this->m_gfh->m_bGlobalClr) {
1080 $pal = $this->m_gfh->m_colorTable->toString();
1081 } else {
1082 die('No color table available in getGD_PixelPlotterVersion()');
1083 }
1084
1085 $PlottingIMG = ImageCreate($this->m_gfh->m_nWidth, $this->m_gfh->m_nHeight);
1086 $NumColorsInPal = floor(strlen($pal) / 3);
1087 for ($i = 0; $i < $NumColorsInPal; $i++) {
1088 $ThisImageColor[$i] = ImageColorAllocate(
1089 $PlottingIMG,
1090 ord($pal{(($i * 3) + 0)}),
1091 ord($pal{(($i * 3) + 1)}),
1092 ord($pal{(($i * 3) + 2)}));
1093 }
1094
1095 // PREPARE BITMAP BITS
1096 $data = $this->m_img->m_data;
1097 $nPxl = ($this->m_gfh->m_nHeight - 1) * $this->m_gfh->m_nWidth;
1098 for ($y = 0; $y < $this->m_gfh->m_nHeight; $y++) {
1099 if (!phpthumb_functions::FunctionIsDisabled('set_time_limit')) {
1100 set_time_limit(30);
1101 }
1102 for ($x = 0; $x < $this->m_gfh->m_nWidth; $x++, $nPxl++) {
1103 if (
1104 ($x >= $this->m_img->m_gih->m_nLeft) &&
1105 ($y >= $this->m_img->m_gih->m_nTop) &&
1106 ($x < ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) &&
1107 ($y < ($this->m_img->m_gih->m_nTop + $this->m_img->m_gih->m_nHeight))) {
1108 // PART OF IMAGE
1109 if (@$this->m_img->m_bTrans && (ord($data{$nPxl}) == $this->m_img->m_nTrans)) {
1110 ImageSetPixel($PlottingIMG, $x, $this->m_gfh->m_nHeight - $y - 1, $ThisImageColor[$this->m_gfh->m_nBgColor]);
1111 } else {
1112 ImageSetPixel($PlottingIMG, $x, $this->m_gfh->m_nHeight - $y - 1, $ThisImageColor[ord($data{$nPxl})]);
1113 }
1114 } else {
1115 // BACKGROUND
1116 ImageSetPixel($PlottingIMG, $x, $this->m_gfh->m_nHeight - $y - 1, $ThisImageColor[$this->m_gfh->m_nBgColor]);
1117 }
1118 }
1119 $nPxl -= $this->m_gfh->m_nWidth << 1;
1120
1121 }
1122
1123 return $PlottingIMG;
1124 }
1125
1126 ///////////////////////////////////////////////////////////////////////////
1127
1128 function dword($val)
1129 {
1130 $val = intval($val);
1131 return chr($val & 0xFF).chr(($val & 0xFF00) >> 8).chr(($val & 0xFF0000) >> 16).chr(($val & 0xFF000000) >> 24);
1132 }
1133
1134 ///////////////////////////////////////////////////////////////////////////
1135
1136 function ndword($val)
1137 {
1138 $val = intval($val);
1139 return chr(($val & 0xFF000000) >> 24).chr(($val & 0xFF0000) >> 16).chr(($val & 0xFF00) >> 8).chr($val & 0xFF);
1140 }
1141
1142 ///////////////////////////////////////////////////////////////////////////
1143
1144 function width()
1145 {
1146 return $this->m_gfh->m_nWidth;
1147 }
1148
1149 ///////////////////////////////////////////////////////////////////////////
1150
1151 function height()
1152 {
1153 return $this->m_gfh->m_nHeight;
1154 }
1155
1156 ///////////////////////////////////////////////////////////////////////////
1157
1158 function comment()
1159 {
1160 return $this->m_img->m_lpComm;
1161 }
1162
1163 ///////////////////////////////////////////////////////////////////////////
1164
1165 function loaded()
1166 {
1167 return $this->m_bLoaded;
1168 }
1169}
1170
1171///////////////////////////////////////////////////////////////////////////////////////////////////
1172
1173?>
Note: See TracBrowser for help on using the repository browser.