cvs: php4 /pear/Image Remote.php

From: Date: Sat, 06 Jan 2001 23:13:19 +0000
Subject: cvs: php4 /pear/Image Remote.php
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-3405@lists.php.net to get a copy of this message
tuupola Sat Jan 6 15:13:19 2001 EDT Added files: /php4/pear/Image Remote.php Log: Initial commit.

Index: php4/pear/Image/Remote.php +++ php4/pear/Image/Remote.php <?php /* vim: set ts=4 sw=4: */ // +----------------------------------------------------------------------+ // | PHP version 4.0 | // +----------------------------------------------------------------------+ // | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group | // +----------------------------------------------------------------------+ // | This source file is subject to version 2.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | // | available at through the world-wide-web at | // | http://www.php.net/license/2_02.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | // +----------------------------------------------------------------------+ // | Authors: Mika Tuupola <tuupola@appelsiini.net> | // +----------------------------------------------------------------------+ // // $Id: Remote.php,v 1.1 2001/01/06 23:13:19 tuupola Exp $ define("GIF_SIGNATURE_LENGTH", 3); define("GIF_VERSION_LENGTH", 3); define("GIF_LSW_LENGTH", 2); define("GIF_LSH_LENGTH", 2); define("PNG_SIGNATURE_LENGTH", 8); define("PNG_IHDR_LENGTH_LENGTH", 4); define("PNG_IHDR_CHUNKTYPE_LENGTH", 4); define("PNG_IHDR_IMW_LENGTH", 4); define("PNG_IHDR_IMH_LENGTH", 4); define("JPG_PARAM_LENGTH_LENGTH", 2); define("JPG_DATA_PRECISION_LENGTH", 1); define("JPG_IMW_LENGTH_LENGTH", 2); define("JPG_IMH_LENGTH_LENGTH", 2); define("JPG_NUM_COMPONENTS_LENGTH", 1); // The following jpeg defines were taken from rdjpgcom.c, which is part // of the Independent JPEG Group's software. // Copyright (C) 1994-1997, Thomas G. Lane. // // ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz define("M_SOF0", 0xC0); /* Start Of Frame N */ define("M_SOF1", 0xC1); /* N indicates which compression process */ define("M_SOF2", 0xC2); /* Only SOF0-SOF2 are now in common use */ define("M_SOF3", 0xC3); define("M_SOF5", 0xC5); /* NB: codes C4 and CC are NOT SOF markers */ define("M_SOF6", 0xC6); define("M_SOF7", 0xC7); define("M_SOF9", 0xC9); define("M_SOF10", 0xCA); define("M_SOF11", 0xCB); define("M_SOF13", 0xCD); define("M_SOF14", 0xCE); define("M_SOF15", 0xCF); define("M_SOI", 0xD8); /* Start Of Image (beginning of datastream) */ define("M_EOI", 0xD9); /* End Of Image (end of datastream) */ define("M_SOS", 0xDA); /* Start Of Scan (begins compressed data) */ define("M_APP0", 0xE0); /* Application-specific marker, type N */ define("M_APP12", 0xEC); /* (we don't bother to list all 16 APPn's) */ define("M_COM", 0xFE); /* COMment */ class Image_Remote { var $url; // the url we should be handling var $purl; // parsed url var $filesize; // filesize of the remote file var $mimetype; // mimetype of the remote url var $imagetype; // imagetype var $width; // image width var $height; // image height var $extra; // some useless extrainfo var $errstr; // error of the last method call /** * Image_Remote is a class to retrieve information on remote * imagefiles without actually downloading the whole image. * It mimics the GetImageSize() PHP function but works on * remote images. Gif, jpeg and png currently supported. * * Usage: * * $i = new Image_Remote("http://www.example.com/test.png"); * $data = $i->getImageSize(); * * @param string $input URL of the remote image. Currently supports * only http. * * @author Mika Tuupola <tuupola@appelsiini.net> * @version $Revision: 1.1 $ */ function Image_Remote($input) { $this->purl = parse_url($input); if ($this->purl[scheme] == 'http') { $this->url = $input; // assign default port if not given if (!($this->purl[port])) { $this->purl[port] = 80; } $this->errstr = ""; // actually fetch the info Image_Remote::_fetchImageInfo(); } else { $this->errstr = "Only http supported."; } } // constructor /** * Gets information on the remote image. Imitates PHP's native * GetImageSize. * * http://www.php.net/manual/function.getimagesize.php * * @return array where array[0] contains the width of the image, * array[1] contains the height of the image, array[2] contains * an integer indicating type of the image. 1 = GIF, 2 = JPG, * 3 = PNG. array[3] contains a string in WIDTH="X" HEIGHT="X" * format. */ function getImageSize() { $retval = array(0,0,0,""); $retval[0] = $this->width; $retval[1] = $this->height; $retval[2] = $this->imagetype; $retval[3] = "WIDTH=\"$retval[0]\" HEIGHT=\"$retval[1]\""; return($retval); } /** * Gets the URL of the remote image. This is actually the same URL * which was given to the constructor. However it sometimes comes * handy to be able to retrieve the URL again from the object. * * @return string URL */ function getImageURL() { $retval = $this->url; return($retval); } function _fetchImageInfo() { // default to success. $retval = 1; // Open the connection and get the headers $fp = fsockopen ($this->purl[host], $this->purl[port], &$errno, &$errstr, 30); if (!$fp) { $this->errstr = "Could not open socket $errstr ($errno)\n"; $retval = 0; } else { // get the headers. fputs ($fp, "GET " . $this->purl[path] . $this->purl[query] . " HTTP/1.1\r\n"); fputs ($fp, "Host: " . $this->purl[host] . "\r\n"); fputs ($fp, "User-Agent: Image_Remote PHP Class\r\n"); fputs ($fp, "Connection: close\r\n\r\n"); $line = trim(fgets($fp,128)); while ($line) { // Extract redirection if (preg_match("/^HTTP\/1\.[0-1] (3[0-9][0-9] .*)/", $line, $matches)) { $this->errstr = $matches[1] . " not implemented yet!"; $retval = 0; } // Extract client error if (preg_match("/^HTTP\/1\.[0-1] (4[0-9][0-9] .*)/", $line, $matches)) { $this->errstr = $matches[1]; $retval = 0; } // Extract server error if (preg_match("/^HTTP\/1\.[0-1] (5[0-9][0-9] .*)/", $line, $matches)) { $this->errstr = $matches[1]; $retval = 0; } // Extract mime type if (preg_match("/Content-Type: (.*)/", $line, $matches)) { $tempmime = chop($matches[1]); } // Extract filesize if (preg_match("/Content-Length: ([0-9]*)/", $line, $matches)) { $tempfilesize = $matches[1]; } $line = trim(fgets($fp,128)); } // If we got correct mimetype etc (we trust what the webserver says), // continue to fetch the actual data. // if no error yet if ($retval) { // if correct mimetype if (preg_match("/image\/(gif|jpeg|x-jpeg|x-png|png)/", $tempmime)) { $this->mimetype = $tempmime; $this->filesize = $tempfilesize; SWITCH ($tempmime) { case 'image/gif': Image_Remote::_fetchAndParseGIFHeader($fp); $this->imagetype = 1; break; case 'image/png': case 'image/x-png': Image_Remote::_fetchAndParsePNGHeader($fp); $this->imagetype = 3; break; case 'image/jpeg': case 'image/x-jpeg': Image_Remote::_fetchAndParseJPGHeader($fp); $this->imagetype = 2; break; } } else { $this->errstr = "Unsupported mimetype $tempmime."; $retval = 0; } } fclose($fp); } return($retval); } // _fetchImageInfo function _fetchAndParseGIFHeader($fd) { if (!$fd) { $this->errstr = "No socket."; } else { $signature = fread($fd, GIF_SIGNATURE_LENGTH); $version = fread($fd, GIF_VERSION_LENGTH); $wbytes = fread($fd, GIF_LSW_LENGTH); $hbytes = fread($fd, GIF_LSH_LENGTH); // Host Byte Order $this->width = Image_Remote::_htodecs($wbytes); $this->height = Image_Remote::_htodecs($hbytes); $this->extra = $signature . $version; } } function _fetchAndParsePNGHeader($fd) { if (!$fd) { $this->errstr = "No socket."; } else { $signature = fread($fd, PNG_SIGNATURE_LENGTH); $ihdrl = fread($fd, PNG_IHDR_LENGTH_LENGTH); $ihdrct = fread($fd, PNG_IHDR_CHUNKTYPE_LENGTH); $wbytes = fread($fd, PNG_IHDR_IMW_LENGTH); $hbytes = fread($fd, PNG_IHDR_IMH_LENGTH); // Network Byte Order $this->width = Image_Remote::_ntodecl($wbytes); $this->height = Image_Remote::_ntodecl($hbytes); $this->extra = $signature; } } // The jpeg parser is basically port of code found from rdjpgcom.c, // which is part of the Independent JPEG Group's software. // Copyright (C) 1994-1997, Thomas G. Lane. // // ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz // // Similar port can be found in elqGetImageFormat() by Oyvind Hallsteinsen // // ftp://ftp.elq.org/pub/php3/elqGetImageFormat/elqGetImageFormat.php3 function _fetchAndParseJPGHeader($fd) { if (!$fd) { $this->errstr = "No socket."; } else { $done = 0; // first marker $c1 = ord(fread($fd, 1)); $c2 = ord(fread($fd, 1)); if ($c1 != 0xFF || $c2 != M_SOI) { $this->errstr="Not a jpeg file?"; } else { while (!($done)) { // find next marker $marker = ord(fread($fd, 1)); while ($marker != 0xFF) { $marker = ord(fread($fd, 1)); } do { $marker = ord(fread($fd, 1)); } while ($marker == 0xFF); SWITCH ($marker) { case M_SOF0: case M_SOF1: case M_SOF2: case M_SOF3: case M_SOF5: case M_SOF6: case M_SOF7: case M_SOF9: case M_SOF10: case M_SOF11: case M_SOF13: case M_SOF14: case M_SOF15: $length = fread($fd, JPG_PARAM_LENGTH_LENGTH); $precision = fread($fd, JPG_DATA_PRECISION_LENGTH); $hbytes = fread($fd, JPG_IMH_LENGTH_LENGTH); $wbytes = fread($fd, JPG_IMW_LENGTH_LENGTH); $components= fread($fd, JPG_NUM_COMPONENTS_LENGTH); // Network Byte Order $this->width = Image_Remote::_ntodecs($wbytes); $this->height = Image_Remote::_ntodecs($hbytes); $this->extra = ""; $done = 1; break; case M_SOS: $done = 1; break; // By default we skip over unwanted markers and avoid // being fooled by 0xFF bytes in parameter segment. default: $lbytes = fread($fd, JPG_PARAM_LENGTH_LENGTH); $length = Image_Remote::_ntodecs($lbytes); if ($length < JPG_PARAM_LENGTH_LENGTH) { $this->errstr="Erronous parameter length."; $done = 1; } // the length is included in param length and // allready read $length -= JPG_PARAM_LENGTH_LENGTH; fread($fd, $length); break; } } } } } function _htodecl($bytes) { $b1 = ord($bytes[0]); $b2 = (ord($bytes[1])<<8); $b3 = (ord($bytes[2])<<16); $b4 = (ord($bytes[3])<<24); return($b1 + $b2 + $b3 + $b4); } function _htodecs($bytes) { $b1 = ord($bytes[0]); $b2 = (ord($bytes[1]) << 8); return($b1 + $b2); } function _ntodecl($bytes) { $b1 = ord($bytes[3]); $b2 = (ord($bytes[2]) << 8); $b3 = (ord($bytes[1]) << 16); $b4 = (ord($bytes[0]) << 24); return($b1 + $b2 + $b3 + $b4); } function _ntodecs($bytes) { $b1 = ord($bytes[1]); $b2 = (ord($bytes[0]) << 8 ); return($b1 + $b2); } } // class ?>
« previous php.cvs (#3405) next »