| [ Index ] |
PHP Cross Reference of Limb3 |
[Summary view] [Print] [Text view]
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 24 function 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 36 function gif_loadFileToGDimageResource($gifFilename, $bgColor = -1) 37 { 38 if ($gif = gif_loadFile($gifFilename)) { 39 40 @set_time_limit(300); 41 // general strategy: convert raw data to PNG then convert PNG data to GD image resource 42 $PNGdata = $gif->getPng($bgColor); 43 if ($img = @ImageCreateFromString($PNGdata)) { 44 45 // excellent - PNG image data successfully converted to GD image 46 return $img; 47 48 } elseif ($img = $gif->getGD_PixelPlotterVersion()) { 49 50 // problem: ImageCreateFromString() didn't like the PNG image data. 51 // This has been known to happen in PHP v4.0.6 52 // solution: take the raw image data and create a new GD image and plot 53 // pixel-by-pixel on the GD image. This is extremely slow, but it does 54 // work and a slow solution is better than no solution, right? :) 55 return $img; 56 57 } 58 } 59 return false; 60 } 61 62 /////////////////////////////////////////////////////////////////////////////////////////////////// 63 64 function gif_outputAsBmp($gif, $lpszFileName, $bgColor = -1) 65 { 66 if (!isSet($gif) || (@get_class($gif) <> 'cgif') || !$gif->loaded() || ($lpszFileName == '')) { 67 return false; 68 } 69 70 $fd = $gif->getBmp($bgColor); 71 if (strlen($fd) <= 0) { 72 return false; 73 } 74 75 if (!($fh = @fopen($lpszFileName, 'wb'))) { 76 return false; 77 } 78 @fwrite($fh, $fd, strlen($fd)); 79 @fflush($fh); 80 @fclose($fh); 81 return true; 82 } 83 84 /////////////////////////////////////////////////////////////////////////////////////////////////// 85 86 function gif_outputAsPng($gif, $lpszFileName, $bgColor = -1) 87 { 88 if (!isSet($gif) || (@get_class($gif) <> 'cgif') || !$gif->loaded() || ($lpszFileName == '')) { 89 return false; 90 } 91 92 $fd = $gif->getPng($bgColor); 93 if (strlen($fd) <= 0) { 94 return false; 95 } 96 97 if (!($fh = @fopen($lpszFileName, 'wb'))) { 98 return false; 99 } 100 @fwrite($fh, $fd, strlen($fd)); 101 @fflush($fh); 102 @fclose($fh); 103 return true; 104 } 105 106 /////////////////////////////////////////////////////////////////////////////////////////////////// 107 108 function gif_outputAsJpeg($gif, $lpszFileName, $bgColor = -1) 109 { 110 // JPEG output that does not require cjpeg added by James Heinrich <info@silisoftware.com> - December 10, 2003 111 if ((strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') && (file_exists('/usr/local/bin/cjpeg') || `which cjpeg`)) { 112 113 if (gif_outputAsBmp($gif, $lpszFileName.'.bmp', $bgColor)) { 114 exec('cjpeg '.$lpszFileName.'.bmp >'.$lpszFileName.' 2>/dev/null'); 115 @unLink($lpszFileName.'.bmp'); 116 117 if (@file_exists($lpszFileName)) { 118 if (@fileSize($lpszFileName) > 0) { 119 return true; 120 } 121 122 @unLink($lpszFileName); 123 } 124 } 125 126 } else { 127 128 // either Windows, or cjpeg not found in path 129 if ($img = @ImageCreateFromString($gif->getPng($bgColor))) { 130 if (@ImageJPEG($img, $lpszFileName)) { 131 return true; 132 } 133 } 134 135 } 136 137 return false; 138 } 139 140 /////////////////////////////////////////////////////////////////////////////////////////////////// 141 142 function gif_getSize($gif, &$width, &$height) 143 { 144 if (isSet($gif) && (@get_class($gif) == 'cgif') && $gif->loaded()) { 145 $width = $gif->width(); 146 $height = $gif->height(); 147 } elseif (@file_exists($gif)) { 148 $myGIF = new CGIF(); 149 if (!$myGIF->getSize($gif, $width, $height)) { 150 return false; 151 } 152 } else { 153 return false; 154 } 155 156 return true; 157 } 158 159 /////////////////////////////////////////////////////////////////////////////////////////////////// 160 161 class CGIFLZW 162 { 163 var $MAX_LZW_BITS; 164 var $Fresh, $CodeSize, $SetCodeSize, $MaxCode, $MaxCodeSize, $FirstCode, $OldCode; 165 var $ClearCode, $EndCode, $Next, $Vals, $Stack, $sp, $Buf, $CurBit, $LastBit, $Done, $LastByte; 166 167 /////////////////////////////////////////////////////////////////////////// 168 169 // CONSTRUCTOR 170 function CGIFLZW() 171 { 172 $this->MAX_LZW_BITS = 12; 173 unSet($this->Next); 174 unSet($this->Vals); 175 unSet($this->Stack); 176 unSet($this->Buf); 177 178 $this->Next = range(0, (1 << $this->MAX_LZW_BITS) - 1); 179 $this->Vals = range(0, (1 << $this->MAX_LZW_BITS) - 1); 180 $this->Stack = range(0, (1 << ($this->MAX_LZW_BITS + 1)) - 1); 181 $this->Buf = range(0, 279); 182 } 183 184 /////////////////////////////////////////////////////////////////////////// 185 186 function deCompress($data, &$datLen) 187 { 188 $stLen = strlen($data); 189 $datLen = 0; 190 $ret = ''; 191 192 // INITIALIZATION 193 $this->LZWCommand($data, true); 194 195 while (($iIndex = $this->LZWCommand($data, false)) >= 0) { 196 $ret .= chr($iIndex); 197 } 198 199 $datLen = $stLen - strlen($data); 200 201 if ($iIndex != -2) { 202 return false; 203 } 204 205 return $ret; 206 } 207 208 /////////////////////////////////////////////////////////////////////////// 209 210 function LZWCommand(&$data, $bInit) 211 { 212 if ($bInit) { 213 $this->SetCodeSize = ord($data{0}); 214 $data = substr($data, 1); 215 216 $this->CodeSize = $this->SetCodeSize + 1; 217 $this->ClearCode = 1 << $this->SetCodeSize; 218 $this->EndCode = $this->ClearCode + 1; 219 $this->MaxCode = $this->ClearCode + 2; 220 $this->MaxCodeSize = $this->ClearCode << 1; 221 222 $this->GetCode($data, $bInit); 223 224 $this->Fresh = 1; 225 for ($i = 0; $i < $this->ClearCode; $i++) { 226 $this->Next[$i] = 0; 227 $this->Vals[$i] = $i; 228 } 229 230 for (; $i < (1 << $this->MAX_LZW_BITS); $i++) { 231 $this->Next[$i] = 0; 232 $this->Vals[$i] = 0; 233 } 234 235 $this->sp = 0; 236 return 1; 237 } 238 239 if ($this->Fresh) { 240 $this->Fresh = 0; 241 do { 242 $this->FirstCode = $this->GetCode($data, $bInit); 243 $this->OldCode = $this->FirstCode; 244 } 245 while ($this->FirstCode == $this->ClearCode); 246 247 return $this->FirstCode; 248 } 249 250 if ($this->sp > 0) { 251 $this->sp--; 252 return $this->Stack[$this->sp]; 253 } 254 255 while (($Code = $this->GetCode($data, $bInit)) >= 0) { 256 if ($Code == $this->ClearCode) { 257 for ($i = 0; $i < $this->ClearCode; $i++) { 258 $this->Next[$i] = 0; 259 $this->Vals[$i] = $i; 260 } 261 262 for (; $i < (1 << $this->MAX_LZW_BITS); $i++) { 263 $this->Next[$i] = 0; 264 $this->Vals[$i] = 0; 265 } 266 267 $this->CodeSize = $this->SetCodeSize + 1; 268 $this->MaxCodeSize = $this->ClearCode << 1; 269 $this->MaxCode = $this->ClearCode + 2; 270 $this->sp = 0; 271 $this->FirstCode = $this->GetCode($data, $bInit); 272 $this->OldCode = $this->FirstCode; 273 274 return $this->FirstCode; 275 } 276 277 if ($Code == $this->EndCode) { 278 return -2; 279 } 280 281 $InCode = $Code; 282 if ($Code >= $this->MaxCode) { 283 $this->Stack[$this->sp] = $this->FirstCode; 284 $this->sp++; 285 $Code = $this->OldCode; 286 } 287 288 while ($Code >= $this->ClearCode) { 289 $this->Stack[$this->sp] = $this->Vals[$Code]; 290 $this->sp++; 291 292 if ($Code == $this->Next[$Code]) // Circular table entry, big GIF Error! 293 return -1; 294 295 $Code = $this->Next[$Code]; 296 } 297 298 $this->FirstCode = $this->Vals[$Code]; 299 $this->Stack[$this->sp] = $this->FirstCode; 300 $this->sp++; 301 302 if (($Code = $this->MaxCode) < (1 << $this->MAX_LZW_BITS)) { 303 $this->Next[$Code] = $this->OldCode; 304 $this->Vals[$Code] = $this->FirstCode; 305 $this->MaxCode++; 306 307 if (($this->MaxCode >= $this->MaxCodeSize) && ($this->MaxCodeSize < (1 << $this->MAX_LZW_BITS))) { 308 $this->MaxCodeSize *= 2; 309 $this->CodeSize++; 310 } 311 } 312 313 $this->OldCode = $InCode; 314 if ($this->sp > 0) { 315 $this->sp--; 316 return $this->Stack[$this->sp]; 317 } 318 } 319 320 return $Code; 321 } 322 323 /////////////////////////////////////////////////////////////////////////// 324 325 function GetCode(&$data, $bInit) 326 { 327 if ($bInit) { 328 $this->CurBit = 0; 329 $this->LastBit = 0; 330 $this->Done = 0; 331 $this->LastByte = 2; 332 return 1; 333 } 334 335 if (($this->CurBit + $this->CodeSize) >= $this->LastBit) { 336 if ($this->Done) { 337 if ($this->CurBit >= $this->LastBit) { 338 // Ran off the end of my bits 339 return 0; 340 } 341 return -1; 342 } 343 344 $this->Buf[0] = $this->Buf[$this->LastByte - 2]; 345 $this->Buf[1] = $this->Buf[$this->LastByte - 1]; 346 347 $Count = ord($data{0}); 348 $data = substr($data, 1); 349 350 if ($Count) { 351 for ($i = 0; $i < $Count; $i++) { 352 $this->Buf[2 + $i] = ord($data{$i}); 353 } 354 $data = substr($data, $Count); 355 } else { 356 $this->Done = 1; 357 } 358 359 $this->LastByte = 2 + $Count; 360 $this->CurBit = ($this->CurBit - $this->LastBit) + 16; 361 $this->LastBit = (2 + $Count) << 3; 362 } 363 364 $iRet = 0; 365 for ($i = $this->CurBit, $j = 0; $j < $this->CodeSize; $i++, $j++) { 366 $iRet |= (($this->Buf[intval($i / 8)] & (1 << ($i % 8))) != 0) << $j; 367 } 368 369 $this->CurBit += $this->CodeSize; 370 return $iRet; 371 } 372 } 373 374 /////////////////////////////////////////////////////////////////////////////////////////////////// 375 376 class CGIFCOLORTABLE 377 { 378 var $m_nColors; 379 var $m_arColors; 380 381 /////////////////////////////////////////////////////////////////////////// 382 383 // CONSTRUCTOR 384 function CGIFCOLORTABLE() 385 { 386 unSet($this->m_nColors); 387 unSet($this->m_arColors); 388 } 389 390 /////////////////////////////////////////////////////////////////////////// 391 392 function load($lpData, $num) 393 { 394 $this->m_nColors = 0; 395 $this->m_arColors = array(); 396 397 for ($i = 0; $i < $num; $i++) { 398 $rgb = substr(