function SourceImageToGD() { if (is_resource($this->gdimg_source)) { $this->source_width = ImageSX($this->gdimg_source); $this->source_height = ImageSY($this->gdimg_source); $this->DebugMessage('skipping SourceImageToGD() because $this->gdimg_source is already a resource (' . $this->source_width . 'x' . $this->source_height . ')', __FILE__, __LINE__); return true; } $this->DebugMessage('starting SourceImageToGD()', __FILE__, __LINE__); if ($this->config_prefer_imagemagick) { if (empty($this->sourceFilename) && !empty($this->rawImageData)) { $this->DebugMessage('Copying raw image data to temp file and trying again with ImageMagick', __FILE__, __LINE__); if ($tempnam = $this->phpThumb_tempnam()) { if (file_put_contents($tempnam, $this->rawImageData)) { $this->sourceFilename = $tempnam; if ($this->ImageMagickThumbnailToGD()) { // excellent, we have a thumbnailed source image $this->DebugMessage('ImageMagickThumbnailToGD() succeeded', __FILE__, __LINE__); } else { $this->DebugMessage('ImageMagickThumbnailToGD() failed', __FILE__, __LINE__); } } else { $this->DebugMessage('failed to put $this->rawImageData into temp file "' . $tempnam . '"', __FILE__, __LINE__); } } else { $this->DebugMessage('failed to generate temp file name', __FILE__, __LINE__); } } } if (!$this->gdimg_source && $this->rawImageData) { if ($this->SourceImageIsTooLarge($this->source_width, $this->source_height)) { $memory_get_usage = function_exists('memory_get_usage') ? memory_get_usage() : 0; return $this->ErrorImage('Source image is too large (' . $this->source_width . 'x' . $this->source_height . ' = ' . number_format($this->source_width * $this->source_height / 1000000, 1) . 'Mpx, max=' . number_format($this->config_max_source_pixels / 1000000, 1) . 'Mpx) for GD creation (either install ImageMagick or increase PHP memory_limit to at least ' . ceil(($memory_get_usage + 5 * $this->source_width * $this->source_height) / 1048576) . 'M).'); } if ($this->md5s && $this->md5s != md5($this->rawImageData)) { return $this->ErrorImage('$this->md5s != md5($this->rawImageData)' . "\n" . '"' . $this->md5s . '" != ' . "\n" . '"' . md5($this->rawImageData) . '"'); } //if ($this->issafemode) { // return $this->ErrorImage('Cannot generate thumbnails from raw image data when PHP SAFE_MODE enabled'); //} $this->gdimg_source = $this->ImageCreateFromStringReplacement($this->rawImageData); if (!$this->gdimg_source) { if (substr($this->rawImageData, 0, 2) === 'BM') { $this->getimagesizeinfo[2] = 6; // BMP } elseif (substr($this->rawImageData, 0, 4) === 'II' . "*") { $this->getimagesizeinfo[2] = 7; // TIFF (littlendian) } elseif (substr($this->rawImageData, 0, 4) === 'MM' . "*") { $this->getimagesizeinfo[2] = 8; // TIFF (bigendian) } $this->DebugMessage('SourceImageToGD.ImageCreateFromStringReplacement() failed with unknown image type "' . substr($this->rawImageData, 0, 4) . '" (' . phpthumb_functions::HexCharDisplay(substr($this->rawImageData, 0, 4)) . ')', __FILE__, __LINE__); // return $this->ErrorImage('Unknown image type identified by "'.substr($this->rawImageData, 0, 4).'" ('.phpthumb_functions::HexCharDisplay(substr($this->rawImageData, 0, 4)).') in SourceImageToGD()['.__LINE__.']'); } } elseif (!$this->gdimg_source && $this->sourceFilename) { if ($this->md5s && $this->md5s != phpthumb_functions::md5_file_safe($this->sourceFilename)) { return $this->ErrorImage('$this->md5s != md5(sourceFilename)' . "\n" . '"' . $this->md5s . '" != ' . "\n" . '"' . phpthumb_functions::md5_file_safe($this->sourceFilename) . '"'); } switch (@$this->getimagesizeinfo[2]) { case 1: case 3: // GIF or PNG input file may have transparency $this->is_alpha = true; break; } if (!$this->SourceImageIsTooLarge($this->source_width, $this->source_height)) { $this->gdimg_source = $this->ImageCreateFromFilename($this->sourceFilename); } } while (true) { if ($this->gdimg_source) { $this->DebugMessage('Not using EXIF thumbnail data because $this->gdimg_source is already set', __FILE__, __LINE__); break; } if (!$this->exif_thumbnail_data) { $this->DebugMessage('Not using EXIF thumbnail data because $this->exif_thumbnail_data is empty', __FILE__, __LINE__); break; } if (ini_get('safe_mode')) { if (!$this->SourceImageIsTooLarge($this->source_width, $this->source_height)) { $this->DebugMessage('Using EXIF thumbnail data because source image too large and safe_mode enabled', __FILE__, __LINE__); $this->aoe = true; } else { break; } } else { if (!$this->config_use_exif_thumbnail_for_speed) { $this->DebugMessage('Not using EXIF thumbnail data because $this->config_use_exif_thumbnail_for_speed is FALSE', __FILE__, __LINE__); break; } if ($this->thumbnailCropX != 0 || $this->thumbnailCropY != 0) { $this->DebugMessage('Not using EXIF thumbnail data because source cropping is enabled (' . $this->thumbnailCropX . ',' . $this->thumbnailCropY . ')', __FILE__, __LINE__); break; } if ($this->w > $this->exif_thumbnail_width || $this->h > $this->exif_thumbnail_height) { $this->DebugMessage('Not using EXIF thumbnail data because EXIF thumbnail is too small (' . $this->exif_thumbnail_width . 'x' . $this->exif_thumbnail_height . ' vs ' . $this->w . 'x' . $this->h . ')', __FILE__, __LINE__); break; } $source_ar = $this->source_width / $this->source_height; $exif_ar = $this->exif_thumbnail_width / $this->exif_thumbnail_height; if (number_format($source_ar, 2) != number_format($exif_ar, 2)) { $this->DebugMessage('not using EXIF thumbnail because $source_ar != $exif_ar (' . $source_ar . ' != ' . $exif_ar . ')', __FILE__, __LINE__); break; } } // EXIF thumbnail exists, and is equal to or larger than destination thumbnail, and will be use as source image $this->DebugMessage('Trying to use EXIF thumbnail as source image', __FILE__, __LINE__); if ($gdimg_exif_temp = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false)) { $this->DebugMessage('Successfully using EXIF thumbnail as source image', __FILE__, __LINE__); $this->gdimg_source = $gdimg_exif_temp; $this->source_width = $this->exif_thumbnail_width; $this->source_height = $this->exif_thumbnail_height; $this->thumbnailCropW = $this->source_width; $this->thumbnailCropH = $this->source_height; return true; } else { $this->DebugMessage('$this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false) failed', __FILE__, __LINE__); } break; } if (!$this->gdimg_source) { $this->DebugMessage('$this->gdimg_source is still empty', __FILE__, __LINE__); $this->DebugMessage('ImageMagickThumbnailToGD() failed', __FILE__, __LINE__); $imageHeader = ''; $gd_info = gd_info(); $GDreadSupport = false; switch (@$this->getimagesizeinfo[2]) { case 1: $imageHeader = 'Content-Type: image/gif'; $GDreadSupport = (bool) @$gd_info['GIF Read Support']; break; case 2: $imageHeader = 'Content-Type: image/jpeg'; $GDreadSupport = (bool) @$gd_info['JPG Support']; break; case 3: $imageHeader = 'Content-Type: image/png'; $GDreadSupport = (bool) @$gd_info['PNG Support']; break; } if ($imageHeader) { // cannot create image for whatever reason (maybe ImageCreateFromJPEG et al are not available?) // and ImageMagick is not available either, no choice but to output original (not resized/modified) data and exit if ($this->config_error_die_on_source_failure) { $errormessages = array(); $errormessages[] = 'All attempts to create GD image source failed.'; if ($this->fatalerror) { $errormessages[] = $this->fatalerror; } if ($this->issafemode) { $errormessages[] = 'Safe Mode enabled, therefore ImageMagick is unavailable. (disable Safe Mode if possible)'; } elseif (!$this->ImageMagickVersion()) { $errormessages[] = 'ImageMagick is not installed (it is highly recommended that you install it).'; } if ($this->SourceImageIsTooLarge($this->getimagesizeinfo[0], $this->getimagesizeinfo[1])) { $memory_get_usage = function_exists('memory_get_usage') ? memory_get_usage() : 0; $errormessages[] = 'Source image is too large (' . $this->getimagesizeinfo[0] . 'x' . $this->getimagesizeinfo[1] . ' = ' . number_format($this->getimagesizeinfo[0] * $this->getimagesizeinfo[1] / 1000000, 1) . 'Mpx, max=' . number_format($this->config_max_source_pixels / 1000000, 1) . 'Mpx) for GD creation (either install ImageMagick or increase PHP memory_limit to at least ' . ceil(($memory_get_usage + 5 * $this->getimagesizeinfo[0] * $this->getimagesizeinfo[1]) / 1048576) . 'M).'; } elseif (!$GDreadSupport) { $errormessages[] = 'GD does not have read support for "' . $imageHeader . '".'; } else { $errormessages[] = 'Source image probably corrupt.'; } $this->ErrorImage(implode("\n", $errormessages)); } else { $this->DebugMessage('All attempts to create GD image source failed (' . (ini_get('safe_mode') ? 'Safe Mode enabled, ImageMagick unavailable and source image probably too large for GD' : ($GDreadSupport ? 'source image probably corrupt' : 'GD does not have read support for "' . $imageHeader . '"')) . '), cannot generate thumbnail'); //$this->DebugMessage('All attempts to create GD image source failed ('.($GDreadSupport ? 'source image probably corrupt' : 'GD does not have read support for "'.$imageHeader.'"').'), outputing raw image', __FILE__, __LINE__); //if (!$this->phpThumbDebug) { // header($imageHeader); // echo $this->rawImageData; // exit; //} return false; } } //switch (substr($this->rawImageData, 0, 2)) { // case 'BM': switch (@$this->getimagesizeinfo[2]) { case 6: ob_start(); if (!@(include_once dirname(__FILE__) . '/phpthumb.bmp.php')) { ob_end_clean(); return $this->ErrorImage('include_once(' . dirname(__FILE__) . '/phpthumb.bmp.php) failed'); } ob_end_clean(); if ($fp = @fopen($this->sourceFilename, 'rb')) { $this->rawImageData = ''; while (!feof($fp)) { $this->rawImageData .= fread($fp, 32768); } fclose($fp); } $phpthumb_bmp = new phpthumb_bmp(); $this->gdimg_source = $phpthumb_bmp->phpthumb_bmp2gd($this->rawImageData, phpthumb_functions::gd_version() >= 2.0); unset($phpthumb_bmp); if ($this->gdimg_source) { $this->DebugMessage('$phpthumb_bmp->phpthumb_bmp2gd() succeeded', __FILE__, __LINE__); } else { return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on BMP source conversion' : 'phpthumb_bmp2gd() failed'); } break; //} //switch (substr($this->rawImageData, 0, 4)) { // case 'II'."\x2A\x00": // case 'MM'."\x00\x2A": //} //switch (substr($this->rawImageData, 0, 4)) { // case 'II'."\x2A\x00": // case 'MM'."\x00\x2A": case 7: case 8: return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on TIFF source conversion' : 'ImageMagick is unavailable and phpThumb() does not support TIFF source images without it'); break; //case "\xD7\xCD\xC6\x9A": // return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on WMF source conversion' : 'ImageMagick is unavailable and phpThumb() does not support WMF source images without it'); // break; } if (!$this->gdimg_source) { $HeaderFourBytes = ''; if ($this->rawImageData) { $HeaderFourBytes = substr($this->rawImageData, 0, 4); } elseif ($this->sourceFilename) { if ($fp = @fopen($this->sourceFilename, 'rb')) { $HeaderFourBytes = fread($fp, 4); fclose($fp); } else { return $this->ErrorImage('failed to open "' . $this->sourceFilename . '" SourceImageToGD() [' . __LINE__ . ']'); } } else { return $this->ErrorImage('Unable to create image, neither filename nor image data suppplied in SourceImageToGD() [' . __LINE__ . ']'); } if (!$this->ImageMagickVersion() && !phpthumb_functions::gd_version()) { return $this->ErrorImage('Neither GD nor ImageMagick seem to be installed on this server. At least one (preferably GD), or better both, MUST be installed for phpThumb to work.'); } elseif ($HeaderFourBytes == "×ÍÆš") { // WMF return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on WMF source conversion' : 'ImageMagick is unavailable and phpThumb() does not support WMF source images without it'); } elseif ($HeaderFourBytes == '%PDF') { // "%PDF" return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick and GhostScript are both required for PDF source images; GhostScript may not be properly configured' : 'ImageMagick and/or GhostScript are unavailable and phpThumb() does not support PDF source images without them'); } elseif (substr($HeaderFourBytes, 0, 3) == "ÿØÿ") { // JPEG return $this->ErrorImage('Image (JPEG) is too large for PHP-GD memory_limit, please install ImageMagick or increase php.ini memory_limit setting'); } elseif ($HeaderFourBytes == '%PNG') { // "%PNG" return $this->ErrorImage('Image (PNG) is too large for PHP-GD memory_limit, please install ImageMagick or increase php.ini memory_limit setting'); } elseif (substr($HeaderFourBytes, 0, 3) == 'GIF') { // GIF return $this->ErrorImage('Image (GIF) is too large for PHP-GD memory_limit, please install ImageMagick or increase php.ini memory_limit setting'); } return $this->ErrorImage('Unknown image type identified by "' . $HeaderFourBytes . '" (' . phpthumb_functions::HexCharDisplay($HeaderFourBytes) . ') in SourceImageToGD() [' . __LINE__ . ']'); } } if (!$this->gdimg_source) { if ($gdimg_exif_temp = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false)) { $this->DebugMessage('All other attempts failed, but successfully using EXIF thumbnail as source image', __FILE__, __LINE__); $this->gdimg_source = $gdimg_exif_temp; // override allow-enlarging setting if EXIF thumbnail is the only source available // otherwise thumbnails larger than the EXIF thumbnail will be created at EXIF size $this->aoe = true; return true; } return false; } $this->source_width = ImageSX($this->gdimg_source); $this->source_height = ImageSY($this->gdimg_source); return true; }
function SourceImageToGD() { if (is_resource($this->gdimg_source)) { $this->source_width = ImageSX($this->gdimg_source); $this->source_height = ImageSY($this->gdimg_source); $this->DebugMessage('skipping SourceImageToGD() because $this->gdimg_source is already a resource (' . $this->source_width . 'x' . $this->source_height . ')', __FILE__, __LINE__); return true; } $this->DebugMessage('starting SourceImageToGD()', __FILE__, __LINE__); while (true) { if (!$this->exif_thumbnail_data) { $this->DebugMessage('Not using EXIF thumbnail data because $this->exif_thumbnail_data is empty', __FILE__, __LINE__); break; } if (ini_get('safe_mode')) { if ($this->config_max_source_pixels > 0 && $this->source_width * $this->source_height > $this->config_max_source_pixels) { $this->DebugMessage('Using EXIF thumbnail data because source image too large and safe_mode enabled', __FILE__, __LINE__); $this->aoe = true; } else { break; } } else { if (!$this->config_use_exif_thumbnail_for_speed) { $this->DebugMessage('Not using EXIF thumbnail data because $this->config_use_exif_thumbnail_for_speed is FALSE', __FILE__, __LINE__); break; } if ($this->thumbnailCropX != 0 || $this->thumbnailCropY != 0) { $this->DebugMessage('Not using EXIF thumbnail data because source cropping is enabled (' . $this->thumbnailCropX . ',' . $this->thumbnailCropY . ')', __FILE__, __LINE__); break; } if ($this->w > $this->exif_thumbnail_width || $this->h > $this->exif_thumbnail_height) { $this->DebugMessage('Not using EXIF thumbnail data because EXIF thumbnail is too small (' . $this->exif_thumbnail_width . 'x' . $this->exif_thumbnail_height . ' vs ' . $this->w . 'x' . $this->h . ')', __FILE__, __LINE__); break; } $source_ar = $this->source_width / $this->source_height; $exif_ar = $this->exif_thumbnail_width / $this->exif_thumbnail_height; if (number_format($source_ar, 2) != number_format($exif_ar, 2)) { $this->DebugMessage('not using EXIF thumbnail because $source_ar != $exif_ar (' . $source_ar . ' != ' . $exif_ar . ')', __FILE__, __LINE__); break; } } // EXIF thumbnail exists, and is equal to or larger than destination thumbnail, and will be use as source image $this->DebugMessage('Trying to use EXIF thumbnail as source image', __FILE__, __LINE__); if ($gdimg_exif_temp = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false)) { $this->DebugMessage('Successfully using EXIF thumbnail as source image', __FILE__, __LINE__); $this->gdimg_source = $gdimg_exif_temp; $this->source_width = $this->exif_thumbnail_width; $this->source_height = $this->exif_thumbnail_height; $this->thumbnailCropW = $this->source_width; $this->thumbnailCropH = $this->source_height; return true; } else { $this->DebugMessage('$this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false) failed', __FILE__, __LINE__); } break; } if (!$this->gdimg_source) { if ($this->md5s && $this->md5s != phpthumb_functions::md5_file_safe($this->sourceFilename)) { return $this->ErrorImage('$this->md5s != md5($rawimagedata)' . "\n" . '"' . $this->md5s . '" != ' . "\n" . '"' . phpthumb_functions::md5_file_safe($this->sourceFilename) . '"'); } switch (@$this->getimagesizeinfo[2]) { case 1: case 3: // GIF or PNG input file may have transparency $this->is_alpha = true; break; } //$this->gdimg_source = $this->ImageCreateFromFilename($this->sourceFilename, $this->rawImageData); $this->gdimg_source = $this->ImageCreateFromFilename($this->sourceFilename); //if ($this->md5s && ($this->md5s != md5($this->rawImageData))) { // return $this->ErrorImage('$this->md5s != md5($this->rawImageData)'."\n".'"'.$this->md5s.'" != '."\n".'"'.md5($this->rawImageData).'"'); //} if (!$this->gdimg_source) { $this->DebugMessage('$this->gdimg_source is still empty', __FILE__, __LINE__); if ($this->ImageMagickThumbnailToGD()) { // excellent, we have a thumbnailed source image $this->DebugMessage('ImageMagickThumbnailToGD() succeeded', __FILE__, __LINE__); } else { $this->DebugMessage('ImageMagickThumbnailToGD() failed', __FILE__, __LINE__); $imageHeader = ''; $gd_info = gd_info(); $GDreadSupport = false; //switch (substr($this->rawImageData, 0, 3)) { // case 'GIF': // $imageHeader = 'Content-Type: image/gif'; // $GDreadSupport = (bool) @$gd_info['GIF Read Support']; // break; // case "\xFF\xD8\xFF": // $imageHeader = 'Content-Type: image/jpeg'; // $GDreadSupport = (bool) @$gd_info['JPG Support']; // break; // case "\x89".'PN': // $imageHeader = 'Content-Type: image/png'; // $GDreadSupport = (bool) @$gd_info['PNG Support']; // break; //} switch (@$this->getimagesizeinfo[2]) { case 1: $imageHeader = 'Content-Type: image/gif'; $GDreadSupport = (bool) @$gd_info['GIF Read Support']; break; case 2: $imageHeader = 'Content-Type: image/jpeg'; $GDreadSupport = (bool) @$gd_info['JPG Support']; break; case 3: $imageHeader = 'Content-Type: image/png'; $GDreadSupport = (bool) @$gd_info['PNG Support']; break; } if ($imageHeader) { // cannot create image for whatever reason (maybe ImageCreateFromJPEG et al are not available?) // and ImageMagick is not available either, no choice but to output original (not resized/modified) data and exit if ($this->config_error_die_on_source_failure) { $this->ErrorImage('All attempts to create GD image source failed (' . (ini_get('safe_mode') ? 'Safe Mode enabled, ImageMagick unavailable and source image probably too large for GD' : ($GDreadSupport ? 'source image probably corrupt' : 'GD does not have read support for "' . $imageHeader . '"')) . '), cannot generate thumbnail'); } else { //$this->DebugMessage('All attempts to create GD image source failed ('.($GDreadSupport ? 'source image probably corrupt' : 'GD does not have read support for "'.$imageHeader.'"').'), outputing raw image', __FILE__, __LINE__); //if (!$this->phpThumbDebug) { // header($imageHeader); // echo $this->rawImageData; // exit; //} return false; } } //switch (substr($this->rawImageData, 0, 2)) { // case 'BM': switch (@$this->getimagesizeinfo[2]) { case 6: ob_start(); if (!@(include_once dirname(__FILE__) . '/phpthumb.bmp.php')) { ob_end_clean(); return $this->ErrorImage('include_once(' . dirname(__FILE__) . '/phpthumb.bmp.php) failed'); } ob_end_clean(); if ($fp = @fopen($this->sourceFilename, 'rb')) { $this->rawImageData = ''; while (!feof($fp)) { $this->rawImageData .= fread($fp, 32768); } fclose($fp); } $phpthumb_bmp = new phpthumb_bmp(); if ($this->gdimg_source = $phpthumb_bmp->phpthumb_bmp2gd($this->rawImageData, phpthumb_functions::gd_version() >= 2.0)) { $this->DebugMessage('$phpthumb_bmp->phpthumb_bmp2gd() succeeded', __FILE__, __LINE__); break; } return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on BMP source conversion' : 'phpthumb_bmp2gd() failed'); break; //} //switch (substr($this->rawImageData, 0, 4)) { // case 'II'."\x2A\x00": // case 'MM'."\x00\x2A": //} //switch (substr($this->rawImageData, 0, 4)) { // case 'II'."\x2A\x00": // case 'MM'."\x00\x2A": case 7: case 8: return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on TIFF source conversion' : 'ImageMagick is unavailable and phpThumb() does not support TIFF source images without it'); break; //case "\xD7\xCD\xC6\x9A": // return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on WMF source conversion' : 'ImageMagick is unavailable and phpThumb() does not support WMF source images without it'); // break; } if (!$this->gdimg_source) { $HeaderFourBytes = ''; if ($fp = @fopen($this->sourceFilename, 'rb')) { $HeaderFourBytes = fread($fp, 4); fclose($fp); } if ($HeaderFourBytes == "×ÍÆš") { return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on WMF source conversion' : 'ImageMagick is unavailable and phpThumb() does not support WMF source images without it'); } return $this->ErrorImage('Unknown image type identified by "' . substr($HeaderFourBytes, 0, 4) . '" (' . phpthumb_functions::HexCharDisplay(substr($this->rawImageData, 0, 4)) . ') in SourceImageToGD()'); } } } } if (!$this->gdimg_source) { if ($gdimg_exif_temp = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false)) { $this->DebugMessage('All other attempts failed, but successfully using EXIF thumbnail as source image', __FILE__, __LINE__); $this->gdimg_source = $gdimg_exif_temp; // override allow-enlarging setting if EXIF thumbnail is the only source available // otherwise thumbnails larger than the EXIF thumbnail will be created at EXIF size $this->aoe = true; return true; } return false; } $this->source_width = ImageSX($this->gdimg_source); $this->source_height = ImageSY($this->gdimg_source); return true; }
function SourceImageToGD() { if (is_resource($this->gdimg_source)) { $this->DebugMessage('skipping SourceImageToGD() because $this->gdimg_source is already a resource', __FILE__, __LINE__); return true; } $this->DebugMessage('starting SourceImageToGD()', __FILE__, __LINE__); while (true) { if (!$this->config_use_exif_thumbnail_for_speed) { $this->DebugMessage('Not using EXIF thumbnail data because $this->config_use_exif_thumbnail_for_speed is FALSE', __FILE__, __LINE__); break; } if (!$this->exif_thumbnail_data) { $this->DebugMessage('Not using EXIF thumbnail data because $this->exif_thumbnail_data is empty', __FILE__, __LINE__); break; } if ($this->thumbnailCropX != 0 || $this->thumbnailCropY != 0) { $this->DebugMessage('Not using EXIF thumbnail data because source cropping is enabled (' . $this->thumbnailCropX . ',' . $this->thumbnailCropY . ')', __FILE__, __LINE__); break; } if ($this->w > $this->exif_thumbnail_width || $this->h > $this->exif_thumbnail_height) { $this->DebugMessage('Not using EXIF thumbnail data because EXIF thumbnail is too small (' . $this->exif_thumbnail_width . 'x' . $this->exif_thumbnail_height . ' vs ' . $this->w . 'x' . $this->h . ')', __FILE__, __LINE__); break; } $source_ar = $this->source_width / $this->source_height; $exif_ar = $this->exif_thumbnail_width / $this->exif_thumbnail_height; if (number_format($source_ar, 2) != number_format($exif_ar, 2)) { $this->DebugMessage('not using EXIF thumbnail because $source_ar != $exif_ar (' . $source_ar . ' != ' . $exif_ar . ')', __FILE__, __LINE__); } // EXIF thumbnail exists, and is equal to or larger than destination thumbnail, and will be use as source image $this->DebugMessage('Trying to use EXIF thumbnail as source image', __FILE__, __LINE__); if ($gdimg_exif_temp = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false)) { $this->DebugMessage('Successfully using EXIF thumbnail as source image', __FILE__, __LINE__); $this->gdimg_source = $gdimg_exif_temp; $this->source_width = $this->exif_thumbnail_width; $this->source_height = $this->exif_thumbnail_height; $this->thumbnailCropW = $this->source_width; $this->thumbnailCropH = $this->source_height; return true; } else { $this->DebugMessage('$this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false) failed', __FILE__, __LINE__); } break; } if (!$this->gdimg_source) { // try to create GD image source directly via GD, if possible, // rather than buffering to memory and creating with ImageCreateFromString $ImageCreateWasAttempted = false; $ImageCreateFromFunction = array(1 => 'ImageCreateFromGIF', 2 => 'ImageCreateFromJPEG', 3 => 'ImageCreateFromPNG', 15 => 'ImageCreateFromWBMP'); switch (@$this->getimagesizeinfo[2]) { case 1: // GIF // GIF case 2: // JPEG // JPEG case 3: // PNG // PNG case 15: // WBMP if ($this->md5s && $this->md5s != phpthumb_functions::md5_file_safe($this->sourceFilename)) { return $this->ErrorImage('$this->md5s != md5($this->rawImageData)' . "\n" . '"' . $this->md5s . '" != ' . "\n" . '"' . phpthumb_functions::md5_file_safe($this->sourceFilename) . '"'); } $ImageCreateFromFunctionName = $ImageCreateFromFunction[$this->getimagesizeinfo[2]]; if (function_exists($ImageCreateFromFunctionName)) { $this->DebugMessage('Calling ' . $ImageCreateFromFunctionName . '(' . $this->sourceFilename . ')', __FILE__, __LINE__); $ImageCreateWasAttempted = true; $this->gdimg_source = @$ImageCreateFromFunctionName($this->sourceFilename); switch ($this->getimagesizeinfo[2]) { case 1: case 3: // GIF or PNG input file may have transparency $this->is_alpha = true; break; } } else { $this->DebugMessage('NOT calling ' . $ImageCreateFromFunctionName . '(' . $this->sourceFilename . ') because !function_exists(' . $ImageCreateFromFunctionName . ')', __FILE__, __LINE__); } break; case 4: // SWF // SWF case 5: // PSD // PSD case 6: // BMP // BMP case 7: // TIFF (LE) // TIFF (LE) case 8: // TIFF (BE) // TIFF (BE) case 9: // JPC // JPC case 10: // JP2 // JP2 case 11: // JPX // JPX case 12: // JB2 // JB2 case 13: // SWC // SWC case 14: // IFF // IFF case 16: // XBM $this->DebugMessage('No built-in image creation function for image type "' . @$this->getimagesizeinfo[2] . '" ($this->getimagesizeinfo[2])', __FILE__, __LINE__); break; case '': // no source file, source image was probably set by setSourceData() break; default: $this->DebugMessage('Unknown value for $this->getimagesizeinfo[2]: "' . @$this->getimagesizeinfo[2] . '"', __FILE__, __LINE__); break; } if (!$this->gdimg_source) { // cannot create from filename, attempt to create source image with ImageCreateFromString, if possible if ($ImageCreateWasAttempted) { $this->DebugMessage(@$ImageCreateFromFunctionName . '() was attempted but FAILED', __FILE__, __LINE__); } if (!$this->rawImageData) { $this->DebugMessage('Populating $this->rawImageData and attempting ImageCreateFromStringReplacement()', __FILE__, __LINE__); if ($fp = @fopen($this->sourceFilename, 'rb')) { $this->rawImageData = ''; $filesize = filesize($this->sourceFilename); $blocksize = 16384; $blockreads = ceil($filesize / $blocksize); for ($i = 0; $i < $blockreads; $i++) { $this->rawImageData .= fread($fp, $blocksize); } fclose($fp); } else { return $this->ErrorImage('cannot fopen("' . $this->sourceFilename . '") on line ' . __LINE__ . ' of ' . __FILE__); } } if ($this->md5s && $this->md5s != md5($this->rawImageData)) { return $this->ErrorImage('$this->md5s != md5($this->rawImageData)' . "\n" . '"' . $this->md5s . '" != ' . "\n" . '"' . md5($this->rawImageData) . '"'); } $this->gdimg_source = $this->ImageCreateFromStringReplacement($this->rawImageData, true); } if (!$this->gdimg_source) { $this->DebugMessage('$this->gdimg_source is still empty', __FILE__, __LINE__); if ($this->ImageMagickThumbnailToGD()) { // excellent, we have a thumbnailed source image $this->DebugMessage('ImageMagickThumbnailToGD() succeeded', __FILE__, __LINE__); } else { $this->DebugMessage('ImageMagickThumbnailToGD() failed', __FILE__, __LINE__); $imageHeader = ''; $gd_info = phpthumb_functions::gd_info(); $GDreadSupport = false; switch (substr($this->rawImageData, 0, 3)) { case 'GIF': $imageHeader = 'Content-Type: image/gif'; $GDreadSupport = (bool) @$gd_info['GIF Read Support']; break; case "ÿØÿ": $imageHeader = 'Content-Type: image/jpeg'; $GDreadSupport = (bool) @$gd_info['JPG Support']; break; case "‰" . 'PN': $imageHeader = 'Content-Type: image/png'; $GDreadSupport = (bool) @$gd_info['PNG Support']; break; } if ($imageHeader) { // cannot create image for whatever reason (maybe ImageCreateFromJPEG et al are not available?) // and ImageMagick is not available either, no choice but to output original (not resized/modified) data and exit if ($this->config_error_die_on_source_failure && !$this->phpThumbDebug) { $this->ErrorImage('All attempts to create GD image source failed (' . ($GDreadSupport ? 'source image probably corrupt' : 'GD does not have read support for "' . $imageHeader . '"') . '), cannot generate thumbnail'); } else { //$this->DebugMessage('All attempts to create GD image source failed ('.($GDreadSupport ? 'source image probably corrupt' : 'GD does not have read support for "'.$imageHeader.'"').'), outputing raw image', __FILE__, __LINE__); //if (!$this->phpThumbDebug) { // header($imageHeader); // echo $this->rawImageData; // exit; //} return false; } } switch (substr($this->rawImageData, 0, 2)) { case 'BM': ob_start(); if (!@(include_once dirname(__FILE__) . '/phpthumb.bmp.php')) { ob_end_clean(); if ($this->phpThumbDebug) { $this->DebugMessage('include_once(' . dirname(__FILE__) . '/phpthumb.bmp.php) failed', __FILE__, __LINE__); return false; } return $this->ErrorImage('include_once(' . dirname(__FILE__) . '/phpthumb.bmp.php) failed'); } ob_end_clean(); $phpthumb_bmp = new phpthumb_bmp(); if ($this->gdimg_source = $phpthumb_bmp->phpthumb_bmp2gd($this->rawImageData, phpthumb_functions::gd_version() >= 2.0)) { $this->DebugMessage('$phpthumb_bmp->phpthumb_bmp2gd() succeeded', __FILE__, __LINE__); break; } elseif ($this->phpThumbDebug) { $this->DebugMessage('phpthumb_bmp2db failed', __FILE__, __LINE__); return false; } return $this->ErrorImage('ImageMagick is unavailable and phpThumb() does not support BMP source images without it'); break; } switch (substr($this->rawImageData, 0, 4)) { case 'II' . "*": case 'MM' . "*": if ($this->phpThumbDebug) { $this->DebugMessage('ImageMagick is unavailable and phpThumb() does not support TIFF source images without it', __FILE__, __LINE__); return false; } return $this->ErrorImage('ImageMagick is unavailable and phpThumb() does not support TIFF source images without it'); break; case "×ÍÆš": if ($this->phpThumbDebug) { $this->DebugMessage('ImageMagick is unavailable and phpThumb() does not support WMF source images without it', __FILE__, __LINE__); return false; } return $this->ErrorImage('ImageMagick is unavailable and phpThumb() does not support WMF source images without it'); break; } if (!$this->gdimg_source) { if ($this->phpThumbDebug) { $this->DebugMessage('Unknown image type identified by "' . substr($this->rawImageData, 0, 4) . '" (' . phpthumb_functions::HexCharDisplay(substr($this->rawImageData, 0, 4)) . ') in SourceImageToGD()', __FILE__, __LINE__); return false; } return $this->ErrorImage('Unknown image type identified by "' . substr($this->rawImageData, 0, 4) . '" (' . phpthumb_functions::HexCharDisplay(substr($this->rawImageData, 0, 4)) . ') in SourceImageToGD()'); } } } } if (!$this->gdimg_source) { if ($gdimg_exif_temp = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false)) { $this->DebugMessage('All other attempts failed, but successfully using EXIF thumbnail as source image', __FILE__, __LINE__); $this->gdimg_source = $gdimg_exif_temp; // override allow-enlarging setting if EXIF thumbnail is the only source available // otherwise thumbnails larger than the EXIF thumbnail will be created at EXIF size $this->aoe = true; return true; } return false; } $this->source_width = ImageSX($this->gdimg_source); $this->source_height = ImageSY($this->gdimg_source); return true; }
function SourceImageToGD() { if (is_resource($this->gdimg_source)) { $this->DebugMessage('skipping SourceImageToGD() because $this->gdimg_source is already a resource', __FILE__, __LINE__); return true; } $this->DebugMessage('starting SourceImageToGD()', __FILE__, __LINE__); if ($this->config_use_exif_thumbnail_for_speed && !empty($this->exif_thumbnail_data)) { if ($this->exif_thumbnail_width >= $this->thumbnail_image_width && $this->exif_thumbnail_height >= $this->thumbnail_image_height && $this->thumbnailCropX == 0 && $this->thumbnailCropY == 0 && $this->thumbnailCropW > 0 && $this->thumbnailCropH > 0 && $this->source_width >= $this->thumbnailCropW && $this->source_height >= $this->thumbnailCropH) { // EXIF thumbnail exists, and is equal to or larger than destination thumbnail, and will be use as source image // Only benefit here is greater speed, not lower memory usage $this->DebugMessage('Trying to use EXIF thumbnail as source image', __FILE__, __LINE__); if ($gdimg_exif_temp = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false)) { $this->DebugMessage('Successfully using EXIF thumbnail as source image', __FILE__, __LINE__); $this->gdimg_source = $gdimg_exif_temp; $this->source_width = $this->exif_thumbnail_width; $this->source_height = $this->exif_thumbnail_height; $this->thumbnailCropW = $this->source_width; $this->thumbnailCropH = $this->source_height; return true; } else { $this->DebugMessage('$this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false) failed', __FILE__, __LINE__); } } else { $this->DebugMessage('Not using EXIF thumbnail data because EXIF thumbnail is too small', __FILE__, __LINE__); } } else { if (!$this->config_use_exif_thumbnail_for_speed) { $this->DebugMessage('Not using EXIF thumbnail data because $this->config_use_exif_thumbnail_for_speed is FALSE', __FILE__, __LINE__); } elseif ($this->getimagesizeinfo[2] == 2) { $this->DebugMessage('Not using EXIF thumbnail data because EXIF thumbnail is unavailable', __FILE__, __LINE__); } elseif (is_array($this->getimagesizeinfo)) { $this->DebugMessage('Not using EXIF thumbnail data because source image is not JPEG, therefore no EXIF thumbnail available', __FILE__, __LINE__); //} else { // $this->DebugMessage('Not using EXIF thumbnail data because GetImageSize failed on source image', __FILE__, __LINE__); } } if (empty($this->gdimg_source)) { // try to create GD image source directly via GD, if possible, // rather than buffering to memory and creating with ImageCreateFromString $ImageCreateWasAttempted = false; if (!empty($this->rawImageData)) { // fine } elseif ($this->iswindows && (substr($this->sourceFilename, 0, 2) == '//' || substr($this->sourceFilename, 0, 2) == '\\\\')) { // Windows \\share\filename.ext } elseif (eregi('^(f|ht)tp[s]?://', $this->sourceFilename)) { // URL } elseif (!file_exists($this->sourceFilename)) { return $this->ErrorImage('"' . $this->sourceFilename . '" does not exist'); } elseif (!is_file($this->sourceFilename)) { return $this->ErrorImage('"' . $this->sourceFilename . '" is not a file'); } $ImageCreateFromFunction = array(1 => 'ImageCreateFromGIF', 2 => 'ImageCreateFromJPEG', 3 => 'ImageCreateFromPNG', 15 => 'ImageCreateFromWBMP'); switch (@$this->getimagesizeinfo[2]) { case 1: // GIF // GIF case 2: // JPEG // JPEG case 3: // PNG // PNG case 15: // WBMP $ImageCreateFromFunctionName = $ImageCreateFromFunction[$this->getimagesizeinfo[2]]; if (function_exists($ImageCreateFromFunctionName)) { $this->DebugMessage('Calling ' . $ImageCreateFromFunctionName . '(' . $this->sourceFilename . ')', __FILE__, __LINE__); $ImageCreateWasAttempted = true; $this->gdimg_source = @$ImageCreateFromFunctionName($this->sourceFilename); switch ($this->getimagesizeinfo[2]) { case 1: case 3: // GIF or PNG input file may have transparency $this->is_alpha = true; break; } } else { $this->DebugMessage('NOT calling ' . $ImageCreateFromFunctionName . '(' . $this->sourceFilename . ') because !function_exists(' . $ImageCreateFromFunctionName . ')', __FILE__, __LINE__); } break; case 4: // SWF // SWF case 5: // PSD // PSD case 6: // BMP // BMP case 7: // TIFF (LE) // TIFF (LE) case 8: // TIFF (BE) // TIFF (BE) case 9: // JPC // JPC case 10: // JP2 // JP2 case 11: // JPX // JPX case 12: // JB2 // JB2 case 13: // SWC // SWC case 14: // IFF // IFF case 16: // XBM $this->DebugMessage('No built-in image creation function for image type "' . @$this->getimagesizeinfo[2] . '" ($this->getimagesizeinfo[2])', __FILE__, __LINE__); break; case '': // no source file, source image was probably set by setSourceData() break; default: $this->DebugMessage('Unknown value for $this->getimagesizeinfo[2]: "' . @$this->getimagesizeinfo[2] . '"', __FILE__, __LINE__); break; } if (empty($this->gdimg_source)) { // cannot create from filename, attempt to create source image with ImageCreateFromString, if possible if ($ImageCreateWasAttempted) { $this->DebugMessage(@$ImageCreateFromFunctionName . '() was attempted but FAILED', __FILE__, __LINE__); } if (empty($this->rawImageData)) { $this->DebugMessage('Populating $this->rawImageData and attempting ImageCreateFromStringReplacement()', __FILE__, __LINE__); if ($fp = @fopen($this->sourceFilename, 'rb')) { $this->rawImageData = ''; $filesize = filesize($this->sourceFilename); $blocksize = 16384; $blockreads = ceil($filesize / $blocksize); for ($i = 0; $i < $blockreads; $i++) { $this->rawImageData .= fread($fp, $blocksize); } fclose($fp); } else { return $this->ErrorImage('cannot fopen("' . $this->sourceFilename . '") on line ' . __LINE__ . ' of ' . __FILE__); } } $this->gdimg_source = $this->ImageCreateFromStringReplacement($this->rawImageData, true); } if (empty($this->gdimg_source)) { $this->DebugMessage('$this->gdimg_source is still empty', __FILE__, __LINE__); if ($this->ImageMagickThumbnailToGD()) { // excellent, we have a thumbnailed source image $this->DebugMessage('ImageMagickThumbnailToGD() succeeded', __FILE__, __LINE__); } else { $this->DebugMessage('ImageMagickThumbnailToGD() failed', __FILE__, __LINE__); $imageHeader = ''; switch (substr($this->rawImageData, 0, 3)) { case 'GIF': $imageHeader = 'Content-type: image/gif'; break; case "ÿØÿ": $imageHeader = 'Content-type: image/jpeg'; break; case "‰" . 'PN': $imageHeader = 'Content-type: image/png'; break; } if ($imageHeader) { // cannot create image for whatever reason (maybe ImageCreateFromJPEG et al are not available?) // and ImageMagick is not available either, no choice but to output original (not resized/modified) data and exit if ($this->config_error_die_on_source_failure) { $this->ErrorImage('All attempts to create GD image source failed (source image probably corrupt), cannot generate thumbnail'); } else { $this->DebugMessage('All attempts to create GD image source failed, outputing raw image', __FILE__, __LINE__); header($imageHeader); echo $this->rawImageData; exit; } } switch (substr($this->rawImageData, 0, 2)) { case 'BM': if (@(include_once 'phpthumb.bmp.php')) { $phpthumb_bmp = new phpthumb_bmp(); if ($this->gdimg_source = $phpthumb_bmp->phpthumb_bmp2gd($this->rawImageData, phpthumb_functions::gd_version() >= 2.0)) { $this->DebugMessage('$phpthumb_bmp->phpthumb_bmp2gd() succeeded', __FILE__, __LINE__); break; } else { return $this->ErrorImage('phpthumb_bmp2db failed'); } } else { return $this->ErrorImage('include_once(phpthumb.bmp.php) failed'); } return $this->ErrorImage('ImageMagick is unavailable and phpThumb() does not support BMP source images without it'); break; } switch (substr($this->rawImageData, 0, 4)) { case 'II' . "*": case 'MM' . "*": return $this->ErrorImage('ImageMagick is unavailable and phpThumb() does not support TIFF source images without it'); break; case "×ÍÆš": return $this->ErrorImage('ImageMagick is unavailable and phpThumb() does not support WMF source images without it'); break; } if (empty($this->gdimg_source)) { return $this->ErrorImage('Unknown image type identified by "' . substr($this->rawImageData, 0, 4) . '" (' . phpthumb_functions::HexCharDisplay(substr($this->rawImageData, 0, 4)) . ') in SourceImageToGD()'); } } } } $this->source_width = ImageSX($this->gdimg_source); $this->source_height = ImageSY($this->gdimg_source); return true; }