!C99Shell v.2.1 [PHP 7 Update] [1.12.2019]!

Software: Apache/2.2.8 (Ubuntu) PHP/5.2.4-2ubuntu5.12 with Suhosin-Patch mod_ssl/2.2.8 OpenSSL/0.9.8g. PHP/5.2.4-2ubuntu5.12 

uname -a: Linux forum.circlefusion.com 2.6.24-19-server #1 SMP Wed Jun 18 15:18:00 UTC 2008 i686 

uid=33(www-data) gid=33(www-data) groups=33(www-data) 

Safe-mode: OFF (not secure)

/home/doku/axrepos/axess/old/wiki/inc/   drwxrwxr-x
Free 11.52 GB of 97.11 GB (11.87%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     JpegMeta.php (100.59 KB)      -rw-rw-r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
/**
 * JPEG metadata reader/writer
 *
 * @license    PHP license 2.0 (http://www.php.net/license/2_02.txt)
 * @link       http://www.zonageek.com/software/php/jpeg/index.php
 * @author     Sebastian Delmont <sdelmont@zonageek.com>
 * @author     Andreas Gohr <andi@splitbrain.org>
 * @todo       Add support for Maker Notes, Extend for GIF and PNG metadata
 */

// This class is a modified and enhanced version of the JPEG class by
// Sebastian Delmont. Original Copyright notice follows:
//
// +----------------------------------------------------------------------+
// | PHP version 4.0                                                      |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997, 1998, 1999, 2000, 2001 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: Sebastian Delmont <sdelmont@zonageek.com>                   |
// +----------------------------------------------------------------------+

class JpegMeta
{
    var 
$_fileName;
    var 
$_fp null;
    var 
$_type 'unknown';

    var 
$_markers;
    var 
$_info;


    
/**
     * Constructor
     *
     * @author Sebastian Delmont <sdelmont@zonageek.com>
     */
    
function JpegMeta($fileName)
    {

        
$this->_fileName $fileName;

        
$this->_fp null;
        
$this->_type 'unknown';

        unset(
$this->_info);
        unset(
$this->_markers);
    }

    
/**
     * Returns all gathered info as multidim array
     *
     * @author Sebastian Delmont <sdelmont@zonageek.com>
     */
    
function & getRawInfo()
    {
        
$this->_parseAll();

        if (
$this->_markers == null) {
            return 
false;
        }

        return 
$this->_info;
    }

    
/**
     * Returns basic image info
     *
     * @author Sebastian Delmont <sdelmont@zonageek.com>
     */
    
function & getBasicInfo()
    {
        
$this->_parseAll();

        
$info = array();

        if (
$this->_markers == null) {
            return 
false;
        }

        
$info['Name'] = $this->_info['file']['Name'];
        if (isset(
$this->_info['file']['Url'])) {
            
$info['Url'] = $this->_info['file']['Url'];
            
$info['NiceSize'] = "???KB";
        }
        else {
            
$info['Size'] = $this->_info['file']['Size'];
            
$info['NiceSize'] = $this->_info['file']['NiceSize'];
        }

        if (@isset(
$this->_info['sof']['Format'])) {
            
$info['Format'] = $this->_info['sof']['Format'] . " JPEG";
        }
        else {
            
$info['Format'] = $this->_info['sof']['Format'] . " JPEG";
        }

        if (@isset(
$this->_info['sof']['ColorChannels'])) {
            
$info['ColorMode'] = ($this->_info['sof']['ColorChannels'] > 1) ? "Color" "B&W";
        }

        
$info['Width'] = $this->getWidth();
        
$info['Height'] = $this->getHeight();
        
$info['DimStr'] = $this->getDimStr();

        
$dates $this->getDates();

        
$info['DateTime'] = $dates['EarliestTime'];
        
$info['DateTimeStr'] = $dates['EarliestTimeStr'];

        
$info['HasThumbnail'] = $this->hasThumbnail();

        return 
$info;
    }


    
/**
     * Convinience function to access nearly all available Data
     * through one function
     *
     * @author Andreas Gohr <andi@splitbrain.org>
     */
    
function getField($fields)
    {
        if(!
is_array($fields)) $fields = array($fields);
        
$info false;
        foreach(
$fields as $field){
            if(
strtolower(substr($field,0,5)) == 'iptc.'){
                
$info $this->getIPTCField(substr($field,5));
            }elseif(
strtolower(substr($field,0,5)) == 'exif.'){
                
$info $this->getExifField(substr($field,5));
            }elseif(
strtolower(substr($field,0,5)) == 'file.'){
                
$info $this->getFileField(substr($field,5));
            }elseif(
strtolower(substr($field,0,5)) == 'date.'){
                
$info $this->getDateField(substr($field,5));
            }elseif(
strtolower($field) == 'simple.camera'){
                
$info $this->getCamera();
            }elseif(
strtolower($field) == 'simple.raw'){
                return 
$this->getRawInfo();
            }elseif(
strtolower($field) == 'simple.title'){
                
$info $this->getTitle();
            }elseif(
strtolower($field) == 'simple.shutterspeed'){
                
$info $this->getShutterSpeed();
            }else{
                
$info $this->getExifField($field);
            }
            if(
$info != false) break;
        }

        if(
$info === false)  $info $alt;
        if(
is_array($info)){
            if(isset(
$info['val'])){
                
$info $info['val'];
            }else{
                
$info join(', ',$info);
            }
        }
        return 
trim($info);
    }

    
/**
     * Convinience function to set nearly all available Data
     * through one function
     *
     * @author Andreas Gohr <andi@splitbrain.org>
     */
    
function setField($field$value)
    {
        if(
strtolower(substr($field,0,5)) == 'iptc.'){
            return 
$this->setIPTCField(substr($field,5),$value);
        }elseif(
strtolower(substr($field,0,5)) == 'exif.'){
            return 
$this->setExifField(substr($field,5),$value);
        }else{
            return 
$this->setExifField($field,$value);
        }
    }

    
/**
     * Convinience function to delete nearly all available Data
     * through one function
     *
     * @author Andreas Gohr <andi@splitbrain.org>
     */
    
function deleteField($field)
    {
        if(
strtolower(substr($field,0,5)) == 'iptc.'){
            return 
$this->deleteIPTCField(substr($field,5));
        }elseif(
strtolower(substr($field,0,5)) == 'exif.'){
            return 
$this->deleteExifField(substr($field,5));
        }else{
            return 
$this->deleteExifField($field);
        }
    }

    
/**
     * Return a date field
     *
     * @author Andreas Gohr <andi@splitbrain.org>
     */
    
function getDateField($field)
    {
        if (!isset(
$this->_info['dates'])) {
            
$this->_info['dates'] = $this->getDates();
        }

        if (isset(
$this->_info['dates'][$field])) {
            return 
$this->_info['dates'][$field];
        }

        return 
false;
    }

    
/**
     * Return a file info field
     *
     * @author Andreas Gohr <andi@splitbrain.org>
     */
    
function getFileField($field)
    {
        if (!isset(
$this->_info['file'])) {
            
$this->_parseFileInfo();
        }

        if (isset(
$this->_info['file'][$field])) {
            return 
$this->_info['file'][$field];
        }

        return 
false;
    }

    
/**
     * Return the camera info (Maker and Model)
     *
     * @author Andreas Gohr <andi@splitbrain.org>
     * @todo   handle makernotes
     */
    
function getCamera(){
        
$make  $this->getField(array('Exif.Make','Exif.TIFFMake'));
        
$model $this->getField(array('Exif.Model','Exif.TIFFModel'));
        
$cam trim("$make $model");
        if(empty(
$cam)) return false;
        return 
$cam;
    }

    
/**
     * Return shutter speed as a ratio
     *
     * @author Joe Lapp <joe.lapp@pobox.com>
     */
    
function getShutterSpeed()
    {
        if (!isset(
$this->_info['exif'])) {
            
$this->_parseMarkerExif();
        }
        if(!isset(
$this->_info['exif']['ExposureTime'])){
            return 
'';
        }

        
$field $this->_info['exif']['ExposureTime'];
        if(
$field['den'] == 1) return $field['num'];
        return 
$field['num'].'/'.$field['den'];
    }

    
/**
     * Return an EXIF field
     *
     * @author Sebastian Delmont <sdelmont@zonageek.com>
     */
    
function getExifField($field)
    {
        if (!isset(
$this->_info['exif'])) {
            
$this->_parseMarkerExif();
        }

        if (
$this->_markers == null) {
            return 
false;
        }

        if (isset(
$this->_info['exif'][$field])) {
            return 
$this->_info['exif'][$field];
        }

        return 
false;
    }

    
/**
     * Return an Adobe Field
     *
     * @author Sebastian Delmont <sdelmont@zonageek.com>
     */
    
function getAdobeField($field)
    {
        if (!isset(
$this->_info['adobe'])) {
            
$this->_parseMarkerAdobe();
        }

        if (
$this->_markers == null) {
            return 
false;
        }

        if (isset(
$this->_info['adobe'][$field])) {
            return 
$this->_info['adobe'][$field];
        }

        return 
false;
    }

    
/**
     * Return an IPTC field
     *
     * @author Sebastian Delmont <sdelmont@zonageek.com>
     */
    
function getIPTCField($field)
    {
        if (!isset(
$this->_info['iptc'])) {
            
$this->_parseMarkerAdobe();
        }

        if (
$this->_markers == null) {
            return 
false;
        }

        if (isset(
$this->_info['iptc'][$field])) {
            return 
$this->_info['iptc'][$field];
        }

        return 
false;
    }

    
/**
     * Set an EXIF field
     *
     * @author Sebastian Delmont <sdelmont@zonageek.com>
     * @author Joe Lapp <joe.lapp@pobox.com>
     */
    
function setExifField($field$value)
    {
        if (!isset(
$this->_info['exif'])) {
            
$this->_parseMarkerExif();
        }

        if (
$this->_markers == null) {
            return 
false;
        }

        if (
$this->_info['exif'] == false) {
            
$this->_info['exif'] = array();
        }

        
// make sure datetimes are in correct format
        
if(strlen($field) >= && strtolower(substr($field08)) == 'datetime') {
            if(
strlen($value) < || $value{4} != ':' || $value{7} != ':') {
                
$value date('Y:m:d H:i:s'strtotime($value));
            }
        }

        
$this->_info['exif'][$field] = $value;

        return 
true;
    }

    
/**
     * Set an Adobe Field
     *
     * @author Sebastian Delmont <sdelmont@zonageek.com>
     */
    
function setAdobeField($field$value)
    {
        if (!isset(
$this->_info['adobe'])) {
            
$this->_parseMarkerAdobe();
        }

        if (
$this->_markers == null) {
            return 
false;
        }

        if (
$this->_info['adobe'] == false) {
            
$this->_info['adobe'] = array();
        }

        
$this->_info['adobe'][$field] = $value;

        return 
true;
    }

    
/**
     * Calculates the multiplier needed to resize the image to the given
     * dimensions
     *
     * @author Andreas Gohr <andi@splitbrain.org>
     */
    
function getResizeRatio($maxwidth,$maxheight=0){
        if(!
$maxheight$maxheight $maxwidth;

        
$w $this->getField('File.Width');
        
$h $this->getField('File.Height');

        
$ratio 1;
        if(
$w >= $h){
            if(
$w >= $maxwidth){
                
$ratio $maxwidth/$w;
            }elseif(
$h $maxheight){
                
$ratio $maxheight/$h;
            }
        }else{
            if(
$h >= $maxheight){
                
$ratio $maxheight/$h;
            }elseif(
$w $maxwidth){
                
$ratio $maxwidth/$w;
            }
        }
        return 
$ratio;
    }


    
/**
     * Set an IPTC field
     *
     * @author Sebastian Delmont <sdelmont@zonageek.com>
     */
    
function setIPTCField($field$value)
    {
        if (!isset(
$this->_info['iptc'])) {
            
$this->_parseMarkerAdobe();
        }

        if (
$this->_markers == null) {
            return 
false;
        }

        if (
$this->_info['iptc'] == false) {
            
$this->_info['iptc'] = array();
        }

        
$this->_info['iptc'][$field] = $value;

        return 
true;
    }

    
/**
     * Delete an EXIF field
     *
     * @author Sebastian Delmont <sdelmont@zonageek.com>
     */
    
function deleteExifField($field)
    {
        if (!isset(
$this->_info['exif'])) {
            
$this->_parseMarkerAdobe();
        }

        if (
$this->_markers == null) {
            return 
false;
        }

        if (
$this->_info['exif'] != false) {
            unset(
$this->_info['exif'][$field]);
        }

        return 
true;
    }

    
/**
     * Delete an Adobe field
     *
     * @author Sebastian Delmont <sdelmont@zonageek.com>
     */
    
function deleteAdobeField($field)
    {
        if (!isset(
$this->_info['adobe'])) {
            
$this->_parseMarkerAdobe();
        }

        if (
$this->_markers == null) {
            return 
false;
        }

        if (
$this->_info['adobe'] != false) {
            unset(
$this->_info['adobe'][$field]);
        }

        return 
true;
    }

    
/**
     * Delete an IPTC field
     *
     * @author Sebastian Delmont <sdelmont@zonageek.com>
     */
    
function deleteIPTCField($field)
    {
        if (!isset(
$this->_info['iptc'])) {
            
$this->_parseMarkerAdobe();
        }

        if (
$this->_markers == null) {
            return 
false;
        }

        if (
$this->_info['iptc'] != false) {
            unset(
$this->_info['iptc'][$field]);
        }

        return 
true;
    }

    
/**
     * Get the image's title, tries various fields
     *
     * @param int $max  maximum number chars (keeps words)
     * @author Andreas Gohr <andi@splitbrain.org>
     */
    
function getTitle($max=80){
        
$cap '';

        
// try various fields
        
$cap $this->getField(array('Iptc.Headline',
                                     
'Iptc.Caption',
                                     
'Exif.UserComment',
                                     
'Exif.TIFFUserComment',
                                     
'Exif.TIFFImageDescription',
                                     
'File.Name'));
        if (empty(
$cap)) return false;

        if(!
$max) return $cap;
        
// Shorten to 80 chars (keeping words)
        
$new preg_replace('/\n.+$/','',wordwrap($cap$max));
        if(
$new != $cap$new .= '...';

        return 
$new;
    }

    
/**
     * Gather various date fields
     *
     * @author Sebastian Delmont <sdelmont@zonageek.com>
     */
    
function getDates()
    {
        
$this->_parseAll();

        if (
$this->_markers == null) {
            return 
false;
        }

        
$dates = array();

        
$latestTime 0;
        
$latestTimeSource "";
        
$earliestTime time();
        
$earliestTimeSource "";

        if (@isset(
$this->_info['exif']['DateTime'])) {
            
$dates['ExifDateTime'] = $this->_info['exif']['DateTime'];

            
$aux $this->_info['exif']['DateTime'];
            
$aux{4} = "-";
            
$aux{7} = "-";
            
$t strtotime($aux);

            if (
$t $latestTime) {
                
$latestTime $t;
                
$latestTimeSource "ExifDateTime";
            }

            if (
$t $earliestTime) {
                
$earliestTime $t;
                
$earliestTimeSource "ExifDateTime";
            }
        }

        if (@isset(
$this->_info['exif']['DateTimeOriginal'])) {
            
$dates['ExifDateTimeOriginal'] = $this->_info['exif']['DateTime'];

            
$aux $this->_info['exif']['DateTimeOriginal'];
            
$aux{4} = "-";
            
$aux{7} = "-";
            
$t strtotime($aux);

            if (
$t $latestTime) {
                
$latestTime $t;
                
$latestTimeSource "ExifDateTimeOriginal";
            }

            if (
$t $earliestTime) {
                
$earliestTime $t;
                
$earliestTimeSource "ExifDateTimeOriginal";
            }
        }

        if (@isset(
$this->_info['exif']['DateTimeDigitized'])) {
            
$dates['ExifDateTimeDigitized'] = $this->_info['exif']['DateTime'];

            
$aux $this->_info['exif']['DateTimeDigitized'];
            
$aux{4} = "-";
            
$aux{7} = "-";
            
$t strtotime($aux);

            if (
$t $latestTime) {
                
$latestTime $t;
                
$latestTimeSource "ExifDateTimeDigitized";
            }

            if (
$t $earliestTime) {
                
$earliestTime $t;
                
$earliestTimeSource "ExifDateTimeDigitized";
            }
        }

        if (@isset(
$this->_info['iptc']['DateCreated'])) {
            
$dates['IPTCDateCreated'] = $this->_info['iptc']['DateCreated'];

            
$aux $this->_info['iptc']['DateCreated'];
            
$aux substr($aux04) . "-" substr($aux42) . "-" substr($aux62);
            
$t strtotime($aux);

            if (
$t $latestTime) {
                
$latestTime $t;
                
$latestTimeSource "IPTCDateCreated";
            }

            if (
$t $earliestTime) {
                
$earliestTime $t;
                
$earliestTimeSource "IPTCDateCreated";
            }
        }

        if (@isset(
$this->_info['file']['UnixTime'])) {
            
$dates['FileModified'] = $this->_info['file']['UnixTime'];

            
$t $this->_info['file']['UnixTime'];

            if (
$t $latestTime) {
                
$latestTime $t;
                
$latestTimeSource "FileModified";
            }

            if (
$t $earliestTime) {
                
$earliestTime $t;
                
$earliestTimeSource "FileModified";
            }
        }

        
$dates['Time'] = $earliestTime;
        
$dates['TimeSource'] = $earliestTimeSource;
        
$dates['TimeStr'] = date("Y-m-d H:i:s"$earliestTime);
        
$dates['EarliestTime'] = $earliestTime;
        
$dates['EarliestTimeSource'] = $earliestTimeSource;
        
$dates['EarliestTimeStr'] = date("Y-m-d H:i:s"$earliestTime);
        
$dates['LatestTime'] = $latestTime;
        
$dates['LatestTimeSource'] = $latestTimeSource;
        
$dates['LatestTimeStr'] = date("Y-m-d H:i:s"$latestTime);

        return 
$dates;
    }

    
/**
     * Get the image width, tries various fields
     *
     * @author Sebastian Delmont <sdelmont@zonageek.com>
     */
    
function getWidth()
    {
        if (!isset(
$this->_info['sof'])) {
            
$this->_parseMarkerSOF();
        }

        if (
$this->_markers == null) {
            return 
false;
        }

        if (isset(
$this->_info['sof']['ImageWidth'])) {
            return 
$this->_info['sof']['ImageWidth'];
        }

        if (!isset(
$this->_info['exif'])) {
            
$this->_parseMarkerExif();
        }

        if (isset(
$this->_info['exif']['PixelXDimension'])) {
            return 
$this->_info['exif']['PixelXDimension'];
        }

        return 
false;
    }

    
/**
     * Get the image height, tries various fields
     *
     * @author Sebastian Delmont <sdelmont@zonageek.com>
     */
    
function getHeight()
    {
        if (!isset(
$this->_info['sof'])) {
            
$this->_parseMarkerSOF();
        }

        if (
$this->_markers == null) {
            return 
false;
        }

        if (isset(
$this->_info['sof']['ImageHeight'])) {
            return 
$this->_info['sof']['ImageHeight'];
        }

        if (!isset(
$this->_info['exif'])) {
            
$this->_parseMarkerExif();
        }

        if (isset(
$this->_info['exif']['PixelYDimension'])) {
            return 
$this->_info['exif']['PixelYDimension'];
        }

        return 
false;
    }

    
/**
     * Get an dimension string for use in img tag
     *
     * @author Sebastian Delmont <sdelmont@zonageek.com>
     */
    
function getDimStr()
    {
        if (
$this->_markers == null) {
            return 
false;
        }

        
$w $this->getWidth();
        
$h $this->getHeight();

        return 
"width='" $w "' height='" $h "'";
    }

    
/**
     * Checks for an embedded thumbnail
     *
     * @author Sebastian Delmont <sdelmont@zonageek.com>
     */
    
function hasThumbnail($which 'any')
    {
        if ((
$which == 'any') || ($which == 'exif')) {
            if (!isset(
$this->_info['exif'])) {
                
$this->_parseMarkerExif();
            }

            if (
$this->_markers == null) {
                return 
false;
            }

            if (isset(
$this->_info['exif']) && is_array($this->_info['exif'])) {
                if (isset(
$this->_info['exif']['JFIFThumbnail'])) {
                    return 
'exif';
                }
            }
        }

        if (
$which == 'adobe') {
            if (!isset(
$this->_info['adobe'])) {
                
$this->_parseMarkerAdobe();
            }

            if (
$this->_markers == null) {
                return 
false;
            }

            if (isset(
$this->_info['adobe']) && is_array($this->_info['adobe'])) {
                if (isset(
$this->_info['adobe']['ThumbnailData'])) {
                    return 
'exif';
                }
            }
        }

        return 
false;
    }

    
/**
     * Send embedded thumbnail to browser
     *
     * @author Sebastian Delmont <sdelmont@zonageek.com>
     */
    
function sendThumbnail($which 'any')
    {
        
$data null;

        if ((
$which == 'any') || ($which == 'exif')) {
            if (!isset(
$this->_info['exif'])) {
                
$this->_parseMarkerExif();
            }

            if (
$this->_markers == null) {
                return 
false;
            }

            if (isset(
$this->_info['exif']) && is_array($this->_info['exif'])) {
                if (isset(
$this->_info['exif']['JFIFThumbnail'])) {
                    
$data =& $this->_info['exif']['JFIFThumbnail'];
                }
            }
        }

        if ((
$which == 'adobe') || ($data == null)){
            if (!isset(
$this->_info['adobe'])) {
                
$this->_parseMarkerAdobe();
            }

            if (
$this->_markers == null) {
                return 
false;
            }

            if (isset(
$this->_info['adobe']) && is_array($this->_info['adobe'])) {
                if (isset(
$this->_info['adobe']['ThumbnailData'])) {
                    
$data =& $this->_info['adobe']['ThumbnailData'];
                }
            }
        }

        if (
$data != null) {
            
header("Content-type: image/jpeg");
            echo 
$data;
            return 
true;
        }

        return 
false;
    }

    
/**
     * Save changed Metadata
     *
     * @author Sebastian Delmont <sdelmont@zonageek.com>
     * @author Andreas Gohr <andi@splitbrain.org>
     */
    
function save($fileName "") {
        if (
$fileName == "") {
            
$tmpName tempnam(dirname($this->_fileName),'_metatemp_');
            
$this->_writeJPEG($tmpName);
            if (@
file_exists($tmpName)) {
                return 
io_rename($tmpName$this->_fileName);
            }
        } else {
            return 
$this->_writeJPEG($fileName);
        }
        return 
false;
    }

    
/*************************************************************/
    /* PRIVATE FUNCTIONS (Internal Use Only!)                    */
    /*************************************************************/

    /*************************************************************/
    
function _dispose()
    {
        
$this->_fileName $fileName;

        
$this->_fp null;
        
$this->_type 'unknown';

        unset(
$this->_markers);
        unset(
$this->_info);
    }

    
/*************************************************************/
    
function _readJPEG()
    {
        unset(
$this->_markers);
        unset(
$this->_info);
        
$this->_markers = array();
        
$this->_info = array();

        
$this->_fp = @fopen($this->_fileName'rb');
        if (
$this->_fp) {
            if (
file_exists($this->_fileName)) {
                
$this->_type 'file';
            }
            else {
                
$this->_type 'url';
            }
        }
        else {
            
$this->_fp null;
            return 
false;  // ERROR: Can't open file
        
}

        
// Check for the JPEG signature
        
$c1 ord(fgetc($this->_fp));
        
$c2 ord(fgetc($this->_fp));

        if (
$c1 != 0xFF || $c2 != 0xD8) {   // (0xFF + SOI)
            
$this->_markers null;
            return 
false;  // ERROR: File is not a JPEG
        
}

        
$count 0;

        
$done false;
        
$ok true;

        while (!
$done) {
            
$capture false;

          
// First, skip any non 0xFF bytes
            
$discarded 0;
            
$c ord(fgetc($this->_fp));
            while (!
feof($this->_fp) && ($c != 0xFF)) {
                
$discarded++;
                
$c ord(fgetc($this->_fp));
            }
          
// Then skip all 0xFF until the marker byte
            
do {
                
$marker ord(fgetc($this->_fp));
            } while (!
feof($this->_fp) && ($marker == 0xFF));

            if (
feof($this->_fp)) {
                return 
false// ERROR: Unexpected EOF
            
}
            if (
$discarded != 0) {
                return 
false// ERROR: Extraneous data
            
}

            
$length ord(fgetc($this->_fp)) * 256 ord(fgetc($this->_fp));
            if (
feof($this->_fp)) {
                return 
false// ERROR: Unexpected EOF
            
}
            if (
$length 2) {
                return 
false// ERROR: Extraneous data
            
}
            
$length $length 2// The length we got counts itself

            
switch ($marker) {
            case 
0xC0:    // SOF0
            
case 0xC1:    // SOF1
            
case 0xC2:    // SOF2
            
case 0xC9:    // SOF9
            
case 0xE0:    // APP0: JFIF data
            
case 0xE1:    // APP1: EXIF data
            
case 0xED:    // APP13: IPTC / Photoshop data
                
$capture true;
                break;
            case 
0xDA:    // SOS: Start of scan... the image itself and the last block on the file
                
$capture false;
                
$length = -1;  // This field has no length... it includes all data until EOF
                
$done true;
                break;
            default:
                
$capture true;//false;
                
break;
            }

            
$this->_markers[$count] = array();
            
$this->_markers[$count]['marker'] = $marker;
            
$this->_markers[$count]['length'] = $length;

            if (
$capture) {
                
$this->_markers[$count]['data'] =& fread($this->_fp$length);
            }
            elseif (!
$done) {
                
$result = @fseek($this->_fp$lengthSEEK_CUR);
              
// fseek doesn't seem to like HTTP 'files', but fgetc has no problem
                
if (!($result === 0)) {
                    for (
$i 0$i $length$i++) {
                        
fgetc($this->_fp);
                    }
                }
            }
            
$count++;
        }

        if (
$this->_fp) {
            
fclose($this->_fp);
            
$this->_fp null;
        }

        return 
$ok;
    }

    
/*************************************************************/
    
function _parseAll()
    {
        if (!isset(
$this->_markers)) {
            
$this->_readJPEG();
        }

        if (
$this->_markers == null) {
            return 
false;
        }

        if (!isset(
$this->_info['jfif'])) {
            
$this->_parseMarkerJFIF();
        }
        if (!isset(
$this->_info['jpeg'])) {
            
$this->_parseMarkerSOF();
        }
        if (!isset(
$this->_info['exif'])) {
            
$this->_parseMarkerExif();
        }
        if (!isset(
$this->_info['adobe'])) {
            
$this->_parseMarkerAdobe();
        }
        if (!isset(
$this->_info['file'])) {
            
$this->_parseFileInfo();
        }
    }

    
/*************************************************************/
    
function _writeJPEG($outputName)
    {
        
$this->_parseAll();

        
$wroteEXIF false;
        
$wroteAdobe false;

        
$this->_fp = @fopen($this->_fileName'r');
        if (
$this->_fp) {
            if (
file_exists($this->_fileName)) {
                
$this->_type 'file';
            }
            else {
                
$this->_type 'url';
            }
        }
        else {
            
$this->_fp null;
            return 
false;  // ERROR: Can't open file
        
}

        
$this->_fpout fopen($outputName'wb');
        if (
$this->_fpout) {
        }
        else {
            
$this->_fpout null;
            
fclose($this->_fp);
            
$this->_fp null;
            return 
false;  // ERROR: Can't open output file
        
}

        
// Check for the JPEG signature
        
$c1 ord(fgetc($this->_fp));
        
$c2 ord(fgetc($this->_fp));

        if (
$c1 != 0xFF || $c2 != 0xD8) {   // (0xFF + SOI)
            
return false;  // ERROR: File is not a JPEG
        
}

        
fputs($this->_fpoutchr(0xFF), 1);
        
fputs($this->_fpoutchr(0xD8), 1); // (0xFF + SOI)

        
$count 0;

        
$done false;
        
$ok true;

        while (!
$done) {
          
// First, skip any non 0xFF bytes
            
$discarded 0;
            
$c ord(fgetc($this->_fp));
            while (!
feof($this->_fp) && ($c != 0xFF)) {
                
$discarded++;
                
$c ord(fgetc($this->_fp));
            }
          
// Then skip all 0xFF until the marker byte
            
do {
                
$marker ord(fgetc($this->_fp));
            } while (!
feof($this->_fp) && ($marker == 0xFF));

            if (
feof($this->_fp)) {
                
$ok false;
                break; 
// ERROR: Unexpected EOF
            
}
            if (
$discarded != 0) {
                
$ok false;
                break; 
// ERROR: Extraneous data
            
}

            
$length ord(fgetc($this->_fp)) * 256 ord(fgetc($this->_fp));
            if (
feof($this->_fp)) {
                
$ok false;
                break; 
// ERROR: Unexpected EOF
            
}
            if (
$length 2) {
                
$ok false;
                break; 
// ERROR: Extraneous data
            
}
            
$length $length 2// The length we got counts itself

            
unset($data);
            if (
$marker == 0xE1) { // APP1: EXIF data
                
$data =& $this->_createMarkerEXIF();
                
$wroteEXIF true;
            }
            elseif (
$marker == 0xED) { // APP13: IPTC / Photoshop data
                
$data =& $this->_createMarkerAdobe();
                
$wroteAdobe true;
            }
            elseif (
$marker == 0xDA) { // SOS: Start of scan... the image itself and the last block on the file
                
$done true;
            }

            if (!
$wroteEXIF && (($marker 0xE0) || ($marker 0xEF))) {
                if (isset(
$this->_info['exif']) && is_array($this->_info['exif'])) {
                    
$exif =& $this->_createMarkerEXIF();
                    
$this->_writeJPEGMarker(0xE1strlen($exif), $exif0);
                    unset(
$exif);
                }
                
$wroteEXIF true;
            }

            if (!
$wroteAdobe && (($marker 0xE0) || ($marker 0xEF))) {
                if ((isset(
$this->_info['adobe']) && is_array($this->_info['adobe']))
                || (isset(
$this->_info['iptc']) && is_array($this->_info['iptc']))) {
                    
$adobe =& $this->_createMarkerAdobe();
                    
$this->_writeJPEGMarker(0xEDstrlen($adobe), $adobe0);
                    unset(
$adobe);
                }
                
$wroteAdobe true;
            }

            
$origLength $length;
            if (isset(
$data)) {
                
$length strlen($data);
            }

            if (
$marker != -1) {
                
$this->_writeJPEGMarker($marker$length$data$origLength);
            }
        }

        if (
$this->_fp) {
            
fclose($this->_fp);
            
$this->_fp null;
        }

        if (
$this->_fpout) {
            
fclose($this->_fpout);
            
$this->_fpout null;
        }

        return 
$ok;
    }

    
/*************************************************************/
    
function _writeJPEGMarker($marker$length, &$data$origLength)
    {
        if (
$length <= 0) {
            return 
false;
        }

        
fputs($this->_fpoutchr(0xFF), 1);
        
fputs($this->_fpoutchr($marker), 1);
        
fputs($this->_fpoutchr((($length 2) & 0x0000FF00) >> 8), 1);
        
fputs($this->_fpoutchr((($length 2) & 0x000000FF) >> 0), 1);

        if (isset(
$data)) {
            
// Copy the generated data
            
fputs($this->_fpout$data$length);

            if (
$origLength 0) {   // Skip the original data
                
$result = @fseek($this->_fp$origLengthSEEK_CUR);
                
// fseek doesn't seem to like HTTP 'files', but fgetc has no problem
                
if ($result != 0) {
                    for (
$i 0$i $origLength$i++) {
                        
fgetc($this->_fp);
                    }
                }
            }
        }
        else {
            if (
$marker == 0xDA) {  // Copy until EOF
                
while (!feof($this->_fp)) {
                    
$data =& fread($this->_fp1024 16);
                    
fputs($this->_fpout$datastrlen($data));
                }
            }
            else { 
// Copy only $length bytes
                
$data =& fread($this->_fp$length);
                
fputs($this->_fpout$data$length);
            }
        }

        return 
true;
    }

    
/**
     * Gets basic info from the file - should work with non-JPEGs
     *
     * @author  Sebastian Delmont <sdelmont@zonageek.com>
     * @author  Andreas Gohr <andi@splitbrain.org>
     */
    
function _parseFileInfo()
    {
        if (
file_exists($this->_fileName)) {
            
$this->_info['file'] = array();
            
$this->_info['file']['Name'] = basename($this->_fileName);
            
$this->_info['file']['Path'] = fullpath($this->_fileName);
            
$this->_info['file']['Size'] = filesize($this->_fileName);
            if (
$this->_info['file']['Size'] < 1024) {
                
$this->_info['file']['NiceSize'] = $this->_info['file']['Size'] . 'B';
            }
            elseif (
$this->_info['file']['Size'] < (1024 1024)) {
                
$this->_info['file']['NiceSize'] = round($this->_info['file']['Size'] / 1024) . 'KB';
            }
            elseif (
$this->_info['file']['Size'] < (1024 1024 1024)) {
                
$this->_info['file']['NiceSize'] = round($this->_info['file']['Size'] / (1024*1024)) . 'MB';
            }
            else {
                
$this->_info['file']['NiceSize'] = $this->_info['file']['Size'] . 'B';
            }
            
$this->_info['file']['UnixTime'] = filemtime($this->_fileName);

            
// get image size directly from file
            
$size getimagesize($this->_fileName);
            
$this->_info['file']['Width']  = $size[0];
            
$this->_info['file']['Height'] = $size[1];
            
// set mime types and formats
            // http://www.php.net/manual/en/function.getimagesize.php
            // http://www.php.net/manual/en/function.image-type-to-mime-type.php
            
switch ($size[2]){
                case 
1:
                    
$this->_info['file']['Mime']   = 'image/gif';
                    
$this->_info['file']['Format'] = 'GIF';
                    break;
                case 
2:
                    
$this->_info['file']['Mime']   = 'image/jpeg';
                    
$this->_info['file']['Format'] = 'JPEG';
                    break;
                case 
3:
                    
$this->_info['file']['Mime']   = 'image/png';
                    
$this->_info['file']['Format'] = 'PNG';
                    break;
                case 
4:
                    
$this->_info['file']['Mime']   = 'application/x-shockwave-flash';
                    
$this->_info['file']['Format'] = 'SWF';
                    break;
                case 
5:
                    
$this->_info['file']['Mime']   = 'image/psd';
                    
$this->_info['file']['Format'] = 'PSD';
                    break;
                case 
6:
                    
$this->_info['file']['Mime']   = 'image/bmp';
                    
$this->_info['file']['Format'] = 'BMP';
                    break;
                case 
7:
                    
$this->_info['file']['Mime']   = 'image/tiff';
                    
$this->_info['file']['Format'] = 'TIFF (Intel)';
                    break;
                case 
8:
                    
$this->_info['file']['Mime']   = 'image/tiff';
                    
$this->_info['file']['Format'] = 'TIFF (Motorola)';
                    break;
                case 
9:
                    
$this->_info['file']['Mime']   = 'application/octet-stream';
                    
$this->_info['file']['Format'] = 'JPC';
                    break;
                case 
10:
                    
$this->_info['file']['Mime']   = 'image/jp2';
                    
$this->_info['file']['Format'] = 'JP2';
                    break;
                case 
11:
                    
$this->_info['file']['Mime']   = 'application/octet-stream';
                    
$this->_info['file']['Format'] = 'JPX';
                    break;
                case 
12:
                    
$this->_info['file']['Mime']   = 'application/octet-stream';
                    
$this->_info['file']['Format'] = 'JB2';
                    break;
                case 
13:
                    
$this->_info['file']['Mime']   = 'application/x-shockwave-flash';
                    
$this->_info['file']['Format'] = 'SWC';
                    break;
                case 
14:
                    
$this->_info['file']['Mime']   = 'image/iff';
                    
$this->_info['file']['Format'] = 'IFF';
                    break;
                case 
15:
                    
$this->_info['file']['Mime']   = 'image/vnd.wap.wbmp';
                    
$this->_info['file']['Format'] = 'WBMP';
                    break;
                case 
16:
                    
$this->_info['file']['Mime']   = 'image/xbm';
                    
$this->_info['file']['Format'] = 'XBM';
                    break;
                default:
                    
$this->_info['file']['Mime']   = 'image/unknown';
            }
        }
        else {
            
$this->_info['file'] = array();
            
$this->_info['file']['Name'] = basename($this->_fileName);
            
$this->_info['file']['Url'] = $this->_fileName;
        }

        return 
true;
    }

    
/*************************************************************/
    
function _parseMarkerJFIF()
    {
        if (!isset(
$this->_markers)) {
            
$this->_readJPEG();
        }

        if (
$this->_markers == null) {
            return 
false;
        }

        
$data null;
        
$count count($this->_markers);
        for (
$i 0$i $count$i++) {
            if (
$this->_markers[$i]['marker'] == 0xE0) {
                
$signature $this->_getFixedString($this->_markers[$i]['data'], 04);
                if (
$signature == 'JFIF') {
                    
$data =& $this->_markers[$i]['data'];
                    break;
                }
            }
        }

        if (
$data == null) {
            
$this->_info['jfif'] = false;
            return 
false;
        }

        
$pos 0;
        
$this->_info['jfif'] = array();


        
$vmaj $this->_getByte($data5);
        
$vmin $this->_getByte($data6);

        
$this->_info['jfif']['Version'] = sprintf('%d.%02d'$vmaj$vmin);

        
$units $this->_getByte($data7);
        switch (
$units) {
        case 
0:
            
$this->_info['jfif']['Units'] = 'pixels';
            break;
        case 
1:
            
$this->_info['jfif']['Units'] = 'dpi';
            break;
        case 
2:
            
$this->_info['jfif']['Units'] = 'dpcm';
            break;
        default:
            
$this->_info['jfif']['Units'] = 'unknown';
            break;
        }

        
$xdens $this->_getShort($data8);
        
$ydens $this->_getShort($data10);

        
$this->_info['jfif']['XDensity'] = $xdens;
        
$this->_info['jfif']['YDensity'] = $ydens;

        
$thumbx $this->_getByte($data12);
        
$thumby $this->_getByte($data13);

        
$this->_info['jfif']['ThumbnailWidth'] = $thumbx;
        
$this->_info['jfif']['ThumbnailHeight'] = $thumby;

        return 
true;
    }

    
/*************************************************************/
    
function _parseMarkerSOF()
    {
        if (!isset(
$this->_markers)) {
            
$this->_readJPEG();
        }

        if (
$this->_markers == null) {
            return 
false;
        }

        
$data null;
        
$count count($this->_markers);
        for (
$i 0$i $count$i++) {
            switch (
$this->_markers[$i]['marker']) {
            case 
0xC0// SOF0
            
case 0xC1// SOF1
            
case 0xC2// SOF2
            
case 0xC9// SOF9
                
$data =& $this->_markers[$i]['data'];
                
$marker $this->_markers[$i]['marker'];
                break;
            }
        }

        if (
$data == null) {
            
$this->_info['sof'] = false;
            return 
false;
        }

        
$pos 0;
        
$this->_info['sof'] = array();


        switch (
$marker) {
        case 
0xC0// SOF0
            
$format 'Baseline';
            break;
        case 
0xC1// SOF1
            
$format 'Progessive';
            break;
        case 
0xC2// SOF2
            
$format 'Non-baseline';
            break;
        case 
0xC9// SOF9
            
$format 'Arithmetic';
            break;
        default:
            return 
false;
            break;
        }


        
$this->_info['sof']['Format'] = $format;

        
$this->_info['sof']['SamplePrecision'] = $this->_getByte($data$pos 0);
        
$this->_info['sof']['ImageHeight'] = $this->_getShort($data$pos 1);
        
$this->_info['sof']['ImageWidth'] = $this->_getShort($data$pos 3);
        
$this->_info['sof']['ColorChannels'] = $this->_getByte($data$pos 5);

        return 
true;
    }

    
/*************************************************************/
    
function _parseMarkerExif()
    {
        if (!isset(
$this->_markers)) {
            
$this->_readJPEG();
        }

        if (
$this->_markers == null) {
            return 
false;
        }

        
$data null;
        
$count count($this->_markers);
        for (
$i 0$i $count$i++) {
            if (
$this->_markers[$i]['marker'] == 0xE1) {
                
$signature $this->_getFixedString($this->_markers[$i]['data'], 06);
                if (
$signature == "Exif\0\0") {
                    
$data =& $this->_markers[$i]['data'];
                    break;
                }
            }
        }

        if (
$data == null) {
            
$this->_info['exif'] = false;
            return 
false;
        }
        
$pos 6;
        
$this->_info['exif'] = array();

        
// We don't increment $pos after this because Exif uses offsets relative to this point

        
$byteAlign $this->_getShort($data$pos 0);

        if (
$byteAlign == 0x4949) { // "II"
            
$isBigEndian false;
        }
        elseif (
$byteAlign == 0x4D4D) { // "MM"
            
$isBigEndian true;
        }
        else {
            return 
false// Unexpected data
        
}

        
$alignCheck $this->_getShort($data$pos 2$isBigEndian);
        if (
$alignCheck != 0x002A// That's the expected value
            
return false// Unexpected data

        
if ($isBigEndian) {
            
$this->_info['exif']['ByteAlign'] = "Big Endian";
        }
        else {
            
$this->_info['exif']['ByteAlign'] = "Little Endian";
        }

        
$offsetIFD0 $this->_getLong($data$pos 4$isBigEndian);
        if (
$offsetIFD0 8)
            return 
false// Unexpected data

        
$offsetIFD1 $this->_readIFD($data$pos$offsetIFD0$isBigEndian'ifd0');
        if (
$offsetIFD1 != 0)
            
$this->_readIFD($data$pos$offsetIFD1$isBigEndian'ifd1');

        return 
true;
    }

    
/*************************************************************/
    
function _readIFD($data$base$offset$isBigEndian$mode)
    {
        
$EXIFTags $this->_exifTagNames($mode);

        
$numEntries $this->_getShort($data$base $offset$isBigEndian);
        
$offset += 2;

        
$exifTIFFOffset 0;
        
$exifTIFFLength 0;
        
$exifThumbnailOffset 0;
        
$exifThumbnailLength 0;

        for (
$i 0$i $numEntries$i++) {
            
$tag $this->_getShort($data$base $offset$isBigEndian);
            
$offset += 2;
            
$type $this->_getShort($data$base $offset$isBigEndian);
            
$offset += 2;
            
$count $this->_getLong($data$base $offset$isBigEndian);
            
$offset += 4;

            if ((
$type 1) || ($type 12))
                return 
false// Unexpected Type

            
$typeLengths = array( -111248112484);

            
$dataLength $typeLengths[$type] * $count;
            if (
$dataLength 4) {
                
$dataOffset $this->_getLong($data$base $offset$isBigEndian);
                
$rawValue $this->_getFixedString($data$base $dataOffset$dataLength);
            }
            else {
                
$rawValue $this->_getFixedString($data$base $offset$dataLength);
            }
            
$offset += 4;

            switch (
$type) {
            case 
1:    // UBYTE
                
if ($count == 1) {
                    
$value $this->_getByte($rawValue0);
                }
                else {
                    
$value = array();
                    for (
$j 0$j $count$j++)
                        
$value[$j] = $this->_getByte($rawValue$j);
                }
                break;
            case 
2:    // ASCII
                
$value $rawValue;
                break;
            case 
3:    // USHORT
                
if ($count == 1) {
                    
$value $this->_getShort($rawValue0$isBigEndian);
                }
                else {
                    
$value = array();
                    for (
$j 0$j $count$j++)
                        
$value[$j] = $this->_getShort($rawValue$j 2$isBigEndian);
                }
                break;
            case 
4:    // ULONG
                
if ($count == 1) {
                    
$value $this->_getLong($rawValue0$isBigEndian);
                }
                else {
                    
$value = array();
                    for (
$j 0$j $count$j++)
                        
$value[$j] = $this->_getLong($rawValue$j 4$isBigEndian);
                }
                break;
            case 
5:    // URATIONAL
                
if ($count == 1) {
                    
$a $this->_getLong($rawValue0$isBigEndian);
                    
$b $this->_getLong($rawValue4$isBigEndian);
                    
$value = array();
                    
$value['val'] = 0;
                    
$value['num'] = $a;
                    
$value['den'] = $b;
                    if ((
$a != 0) && ($b != 0)) {
                        
$value['val'] = $a $b;
                    }
                }
                else {
                    
$value = array();
                    for (
$j 0$j $count$j++) {
                        
$a $this->_getLong($rawValue$j 8$isBigEndian);
                        
$b $this->_getLong($rawValue, ($j 8) + 4$isBigEndian);
                        
$value = array();
                        
$value[$j]['val'] = 0;
                        
$value[$j]['num'] = $a;
                        
$value[$j]['den'] = $b;
                        if ((
$a != 0) && ($b != 0))
                            
$value[$j]['val'] = $a $b;
                    }
                }
                break;
            case 
6:    // SBYTE
                
if ($count == 1) {
                    
$value $this->_getByte($rawValue0);
                }
                else {
                    
$value = array();
                    for (
$j 0$j $count$j++)
                        
$value[$j] = $this->_getByte($rawValue$j);
                }
                break;
            case 
7:    // UNDEFINED
                
$value $rawValue;
                break;
            case 
8:    // SSHORT
                
if ($count == 1) {
                    
$value $this->_getShort($rawValue0$isBigEndian);
                }
                else {
                    
$value = array();
                    for (
$j 0$j $count$j++)
                        
$value[$j] = $this->_getShort($rawValue$j 2$isBigEndian);
                }
                break;
            case 
9:    // SLONG
                
if ($count == 1) {
                    
$value $this->_getLong($rawValue0$isBigEndian);
                }
                else {
                    
$value = array();
                    for (
$j 0$j $count$j++)
                        
$value[$j] = $this->_getLong($rawValue$j 4$isBigEndian);
                }
                break;
            case 
10:   // SRATIONAL
                
if ($count == 1) {
                    
$a $this->_getLong($rawValue0$isBigEndian);
                    
$b $this->_getLong($rawValue4$isBigEndian);
                    
$value = array();
                    
$value['val'] = 0;
                    
$value['num'] = $a;
                    
$value['den'] = $b;
                    if ((
$a != 0) && ($b != 0))
                        
$value['val'] = $a $b;
                }
                else {
                    
$value = array();
                    for (
$j 0$j $count$j++) {
                        
$a $this->_getLong($rawValue$j 8$isBigEndian);
                        
$b $this->_getLong($rawValue, ($j 8) + 4$isBigEndian);
                        
$value = array();
                        
$value[$j]['val'] = 0;
                        
$value[$j]['num'] = $a;
                        
$value[$j]['den'] = $b;
                        if ((
$a != 0) && ($b != 0))
                            
$value[$j]['val'] = $a $b;
                    }
                }
                break;
            case 
11:   // FLOAT
                
$value $rawValue;
                break;

            case 
12:   // DFLOAT
                
$value $rawValue;
                break;
            default:
                return 
false// Unexpected Type
            
}

            
$tagName '';
            if ((
$mode == 'ifd0') && ($tag == 0x8769)) {  // ExifIFDOffset
                
$this->_readIFD($data$base$value$isBigEndian'exif');
            }
            elseif ((
$mode == 'ifd0') && ($tag == 0x8825)) {  // GPSIFDOffset
                
$this->_readIFD($data$base$value$isBigEndian'gps');
            }
            elseif ((
$mode == 'ifd1') && ($tag == 0x0111)) {  // TIFFStripOffsets
                
$exifTIFFOffset $value;
            }
            elseif ((
$mode == 'ifd1') && ($tag == 0x0117)) {  // TIFFStripByteCounts
                
$exifTIFFLength $value;
            }
            elseif ((
$mode == 'ifd1') && ($tag == 0x0201)) {  // TIFFJFIFOffset
                
$exifThumbnailOffset $value;
            }
            elseif ((
$mode == 'ifd1') && ($tag == 0x0202)) {  // TIFFJFIFLength
                
$exifThumbnailLength $value;
            }
            elseif ((
$mode == 'exif') && ($tag == 0xA005)) {  // InteropIFDOffset
                
$this->_readIFD($data$base$value$isBigEndian'interop');
            }
            
// elseif (($mode == 'exif') && ($tag == 0x927C)) {  // MakerNote
            // }
            
else {
                if (isset(
$EXIFTags[$tag])) {
                    
$tagName $EXIFTags[$tag];
                    if (isset(
$this->_info['exif'][$tagName])) {
                        if (!
is_array($this->_info['exif'][$tagName])) {
                            
$aux = array();
                            
$aux[0] = $this->_info['exif'][$tagName];
                            
$this->_info['exif'][$tagName] = $aux;
                        }

                        
$this->_info['exif'][$tagName][count($this->_info['exif'][$tagName])] = $value;
                    }
                    else {
                        
$this->_info['exif'][$tagName] = $value;
                    }
                }
                else {
#echo sprintf("<h1>Unknown tag %02x (t: %d l: %d) %s in %s</h1>", $tag, $type, $count, $mode, $this->_fileName);
                    // Unknown Tags will be ignored!!!
                    // That's because the tag might be a pointer (like the Exif tag)
                    // and saving it without saving the data it points to might
                    // create an invalid file.
                
}
            }
        }

        if ((
$exifThumbnailOffset 0) && ($exifThumbnailLength 0)) {
            
$this->_info['exif']['JFIFThumbnail'] = $this->_getFixedString($data$base $exifThumbnailOffset$exifThumbnailLength);
        }

        if ((
$exifTIFFOffset 0) && ($exifTIFFLength 0)) {
            
$this->_info['exif']['TIFFStrips'] = $this->_getFixedString($data$base $exifTIFFOffset$exifTIFFLength);
        }

        
$nextOffset $this->_getLong($data$base $offset$isBigEndian);
        return 
$nextOffset;
    }

    
/*************************************************************/
    
function & _createMarkerExif()
    {
        
$data null;
        
$count count($this->_markers);
        for (
$i 0$i $count$i++) {
            if (
$this->_markers[$i]['marker'] == 0xE1) {
                
$signature $this->_getFixedString($this->_markers[$i]['data'], 06);
                if (
$signature == "Exif\0\0") {
                    
$data =& $this->_markers[$i]['data'];
                    break;
                }
            }
        }

        if (!isset(
$this->_info['exif'])) {
            return 
false;
        }

        
$data "Exif\0\0";
        
$pos 6;
        
$offsetBase 6;

        if (isset(
$this->_info['exif']['ByteAlign']) && ($this->_info['exif']['ByteAlign'] == "Big Endian")) {
            
$isBigEndian true;
            
$aux "MM";
            
$pos $this->_putString($data$pos$aux);
        }
        else {
            
$isBigEndian false;
            
$aux "II";
            
$pos $this->_putString($data$pos$aux);
        }
        
$pos $this->_putShort($data$pos0x002A$isBigEndian);
        
$pos $this->_putLong($data$pos0x00000008$isBigEndian); // IFD0 Offset is always 8

        
$ifd0 =& $this->_getIFDEntries($isBigEndian'ifd0');
        
$ifd1 =& $this->_getIFDEntries($isBigEndian'ifd1');

        
$pos $this->_writeIFD($data$pos$offsetBase$ifd0$isBigEndiantrue);
        
$pos $this->_writeIFD($data$pos$offsetBase$ifd1$isBigEndianfalse);

        return 
$data;
    }

    
/*************************************************************/
    
function _writeIFD(&$data$pos$offsetBase, &$entries$isBigEndian$hasNext)
    {
        
$tiffData null;
        
$tiffDataOffsetPos = -1;

        
$entryCount count($entries);

        
$dataPos $pos + ($entryCount 12) + 4;
        
$pos $this->_putShort($data$pos$entryCount$isBigEndian);

        for (
$i 0$i $entryCount$i++) {
            
$tag $entries[$i]['tag'];
            
$type $entries[$i]['type'];

            if (
$type == -99) { // SubIFD
                
$pos $this->_putShort($data$pos$tag$isBigEndian);
                
$pos $this->_putShort($data$pos0x04$isBigEndian); // LONG
                
$pos $this->_putLong($data$pos0x01$isBigEndian); // Count = 1
                
$pos $this->_putLong($data$pos$dataPos $offsetBase$isBigEndian);

                
$dataPos $this->_writeIFD($data$dataPos$offsetBase$entries[$i]['value'], $isBigEndianfalse);
            }
            elseif (
$type == -98) { // TIFF Data
                
$pos $this->_putShort($data$pos$tag$isBigEndian);
                
$pos $this->_putShort($data$pos0x04$isBigEndian); // LONG
                
$pos $this->_putLong($data$pos0x01$isBigEndian); // Count = 1
                
$tiffDataOffsetPos $pos;
                
$pos $this->_putLong($data$pos0x00$isBigEndian); // For Now
                
$tiffData =& $entries[$i]['value'] ;
            }
            else { 
// Regular Entry
                
$pos $this->_putShort($data$pos$tag$isBigEndian);
                
$pos $this->_putShort($data$pos$type$isBigEndian);
                
$pos $this->_putLong($data$pos$entries[$i]['count'], $isBigEndian);
                if (
strlen($entries[$i]['value']) > 4) {
                    
$pos $this->_putLong($data$pos$dataPos $offsetBase$isBigEndian);
                    
$dataPos $this->_putString($data$dataPos$entries[$i]['value']);
                }
                else {
                    
$val str_pad($entries[$i]['value'], 4"\0");
                    
$pos $this->_putString($data$pos$val);
                }
            }
        }

        if (
$tiffData != null) {
            
$this->_putLong($data$tiffDataOffsetPos$dataPos $offsetBase$isBigEndian);
            
$dataPos $this->_putString($data$dataPos$tiffData);
        }

        if (
$hasNext) {
            
$pos $this->_putLong($data$pos$dataPos $offsetBase$isBigEndian);
        }
        else {
            
$pos $this->_putLong($data$pos0$isBigEndian);
        }

        return 
$dataPos;
    }

    
/*************************************************************/
    
function & _getIFDEntries($isBigEndian$mode)
    {
        
$EXIFNames $this->_exifTagNames($mode);
        
$EXIFTags $this->_exifNameTags($mode);
        
$EXIFTypeInfo $this->_exifTagTypes($mode);

        
$ifdEntries = array();
        
$entryCount 0;

        
reset($EXIFNames);
        while (list(
$tag$name) = each($EXIFNames)) {
            
$type $EXIFTypeInfo[$tag][0];
            
$count $EXIFTypeInfo[$tag][1];
            
$value null;

            if ((
$mode == 'ifd0') && ($tag == 0x8769)) {  // ExifIFDOffset
                
if (isset($this->_info['exif']['EXIFVersion'])) {
                    
$value =& $this->_getIFDEntries($isBigEndian"exif");
                    
$type = -99;
                }
                else {
                    
$value null;
                }
            }
            elseif ((
$mode == 'ifd0') && ($tag == 0x8825)) {  // GPSIFDOffset
                
if (isset($this->_info['exif']['GPSVersionID'])) {
                    
$value =& $this->_getIFDEntries($isBigEndian"gps");
                    
$type = -99;
                }
                else {
                    
$value null;
                }
            }
            elseif ((
$mode == 'ifd1') && ($tag == 0x0111)) {  // TIFFStripOffsets
                
if (isset($this->_info['exif']['TIFFStrips'])) {
                    
$value =& $this->_info['exif']['TIFFStrips'];
                    
$type = -98;
                }
                else {
                    
$value null;
                }
            }
            elseif ((
$mode == 'ifd1') && ($tag == 0x0117)) {  // TIFFStripByteCounts
                
if (isset($this->_info['exif']['TIFFStrips'])) {
                    
$value strlen($this->_info['exif']['TIFFStrips']);
                }
                else {
                    
$value null;
                }
            }
            elseif ((
$mode == 'ifd1') && ($tag == 0x0201)) {  // TIFFJFIFOffset
                
if (isset($this->_info['exif']['JFIFThumbnail'])) {
                    
$value =& $this->_info['exif']['JFIFThumbnail'];
                    
$type = -98;
                }
                else {
                    
$value null;
                }
            }
            elseif ((
$mode == 'ifd1') && ($tag == 0x0202)) {  // TIFFJFIFLength
                
if (isset($this->_info['exif']['JFIFThumbnail'])) {
                    
$value strlen($this->_info['exif']['JFIFThumbnail']);
                }
                else {
                    
$value null;
                }
            }
            elseif ((
$mode == 'exif') && ($tag == 0xA005)) {  // InteropIFDOffset
                
if (isset($this->_info['exif']['InteroperabilityIndex'])) {
                    
$value =& $this->_getIFDEntries($isBigEndian"interop");
                    
$type = -99;
                }
                else {
                    
$value null;
                }
            }
            elseif (isset(
$this->_info['exif'][$name])) {
                
$origValue =& $this->_info['exif'][$name];

                
// This makes it easier to process variable size elements
                
if (!is_array($origValue) || isset($origValue['val'])) {
                    unset(
$origValue); // Break the reference
                    
$origValue = array($this->_info['exif'][$name]);
                }
                
$origCount count($origValue);

                if (
$origCount == ) {
                    
$type = -1;  // To ignore this field
                
}

                
$value " ";

                switch (
$type) {
                case 
1:    // UBYTE
                    
if ($count == 0) {
                        
$count $origCount;
                    }

                    
$j 0;
                    while ((
$j $count) && ($j $origCount)) {

                        
$this->_putByte($value$j$origValue[$j]);
                        
$j++;
                    }

                    while (
$j $count) {
                        
$this->_putByte($value$j0);
                        
$j++;
                    }
                    break;
                case 
2:    // ASCII
                    
$v strval($origValue[0]);
                    if ((
$count != 0) && (strlen($v) > $count)) {
                        
$v substr($v0$count);
                    }
                    elseif ((
$count 0) && (strlen($v) < $count)) {
                        
$v str_pad($v$count"\0");
                    }

                    
$count strlen($v);

                    
$this->_putString($value0$v);
                    break;
                case 
3:    // USHORT
                    
if ($count == 0) {
                        
$count $origCount;
                    }

                    
$j 0;
                    while ((
$j $count) && ($j $origCount)) {
                        
$this->_putShort($value$j 2$origValue[$j], $isBigEndian);
                        
$j++;
                    }

                    while (
$j $count) {
                        
$this->_putShort($value$j 20$isBigEndian);
                        
$j++;
                    }
                    break;
                case 
4:    // ULONG
                    
if ($count == 0) {
                        
$count $origCount;
                    }

                    
$j 0;
                    while ((
$j $count) && ($j $origCount)) {
                        
$this->_putLong($value$j 4$origValue[$j], $isBigEndian);
                        
$j++;
                    }

                    while (
$j $count) {
                        
$this->_putLong($value$j 40$isBigEndian);
                        
$j++;
                    }
                    break;
                case 
5:    // URATIONAL
                    
if ($count == 0) {
                        
$count $origCount;
                    }

                    
$j 0;
                    while ((
$j $count) && ($j $origCount)) {
                        
$v $origValue[$j];
                        if (
is_array($v)) {
                            
$a $v['num'];
                            
$b $v['den'];
                        }
                        else {
                            
$a 0;
                            
$b 0;
                            
// TODO: Allow other types and convert them
                        
}
                        
$this->_putLong($value$j 8$a$isBigEndian);
                        
$this->_putLong($value, ($j 8) + 4$b$isBigEndian);
                        
$j++;
                    }

                    while (
$j $count) {
                        
$this->_putLong($value$j 80$isBigEndian);
                        
$this->_putLong($value, ($j 8) + 40$isBigEndian);
                        
$j++;
                    }
                    break;
                case 
6:    // SBYTE
                    
if ($count == 0) {
                        
$count $origCount;
                    }

                    
$j 0;
                    while ((
$j $count) && ($j $origCount)) {
                        
$this->_putByte($value$j$origValue[$j]);
                        
$j++;
                    }

                    while (
$j $count) {
                        
$this->_putByte($value$j0);
                        
$j++;
                    }
                    break;
                case 
7:    // UNDEFINED
                    
$v strval($origValue[0]);
                    if ((
$count != 0) && (strlen($v) > $count)) {
                        
$v substr($v0$count);
                    }
                    elseif ((
$count 0) && (strlen($v) < $count)) {
                        
$v str_pad($v$count"\0");
                    }

                    
$count strlen($v);

                    
$this->_putString($value0$v);
                    break;
                case 
8:    // SSHORT
                    
if ($count == 0) {
                        
$count $origCount;
                    }

                    
$j 0;
                    while ((
$j $count) && ($j $origCount)) {
                        
$this->_putShort($value$j 2$origValue[$j], $isBigEndian);
                        
$j++;
                    }

                    while (
$j $count) {
                        
$this->_putShort($value$j 20$isBigEndian);
                        
$j++;
                    }
                    break;
                case 
9:    // SLONG
                    
if ($count == 0) {
                        
$count $origCount;
                    }

                    
$j 0;
                    while ((
$j $count) && ($j $origCount)) {
                        
$this->_putLong($value$j 4$origValue[$j], $isBigEndian);
                        
$j++;
                    }

                    while (
$j $count) {
                        
$this->_putLong($value$j 40$isBigEndian);
                        
$j++;
                    }
                    break;
                case 
10:   // SRATIONAL
                    
if ($count == 0) {
                        
$count $origCount;
                    }

                    
$j 0;
                    while ((
$j $count) && ($j $origCount)) {
                        
$v $origValue[$j];
                        if (
is_array($v)) {
                            
$a $v['num'];
                            
$b $v['den'];
                        }
                        else {
                            
$a 0;
                            
$b 0;
                            
// TODO: Allow other types and convert them
                        
}

                        
$this->_putLong($value$j 8$a$isBigEndian);
                        
$this->_putLong($value, ($j 8) + 4$b$isBigEndian);
                        
$j++;
                    }

                    while (
$j $count) {
                        
$this->_putLong($value$j 80$isBigEndian);
                        
$this->_putLong($value, ($j 8) + 40$isBigEndian);
                        
$j++;
                    }
                    break;
                case 
11:   // FLOAT
                    
if ($count == 0) {
                        
$count $origCount;
                    }

                    
$j 0;
                    while ((
$j $count) && ($j $origCount)) {
                        
$v strval($origValue[$j]);
                        if (
strlen($v) > 4) {
                            
$v substr($v04);
                        }
                        elseif (
strlen($v) < 4) {
                            
$v str_pad($v4"\0");
                        }
                        
$this->_putString($value$j 4$v);
                        
$j++;
                    }

                    while (
$j $count) {
                        
$this->_putString($value$j 4"\0\0\0\0");
                        
$j++;
                    }
                    break;
                case 
12:   // DFLOAT
                    
if ($count == 0) {
                        
$count $origCount;
                    }

                    
$j 0;
                    while ((
$j $count) && ($j $origCount)) {
                        
$v strval($origValue[$j]);
                        if (
strlen($v) > 8) {
                            
$v substr($v08);
                        }
                        elseif (
strlen($v) < 8) {
                            
$v str_pad($v8"\0");
                        }
                        
$this->_putString($value$j 8$v);
                        
$j++;
                    }

                    while (
$j $count) {
                        
$this->_putString($value$j 8"\0\0\0\0\0\0\0\0");
                        
$j++;
                    }
                    break;
                default:
                    
$value null;
                    break;
                }
            }

            if (
$value != null) {
                
$ifdEntries[$entryCount] = array();
                
$ifdEntries[$entryCount]['tag'] = $tag;
                
$ifdEntries[$entryCount]['type'] = $type;
                
$ifdEntries[$entryCount]['count'] = $count;
                
$ifdEntries[$entryCount]['value'] = $value;

                
$entryCount++;
            }
        }

        return 
$ifdEntries;
    }

    
/*************************************************************/
    
function _parseMarkerAdobe()
    {
        if (!isset(
$this->_markers)) {
            
$this->_readJPEG();
        }

        if (
$this->_markers == null) {
            return 
false;
        }

        
$data null;
        
$count count($this->_markers);
        for (
$i 0$i $count$i++) {
            if (
$this->_markers[$i]['marker'] == 0xED) {
                
$signature $this->_getFixedString($this->_markers[$i]['data'], 014);
                if (
$signature == "Photoshop 3.0\0") {
                    
$data =& $this->_markers[$i]['data'];
                    break;
                }
            }
        }

        if (
$data == null) {
            
$this->_info['adobe'] = false;
            
$this->_info['iptc'] = false;
            return 
false;
        }
        
$pos 14;
        
$this->_info['adobe'] = array();
        
$this->_info['adobe']['raw'] = array();
        
$this->_info['iptc'] = array();

        
$datasize strlen($data);

        while (
$pos $datasize) {
            
$signature $this->_getFixedString($data$pos4);
            if (
$signature != '8BIM')
                return 
false;
            
$pos += 4;

            
$type $this->_getShort($data$pos);
            
$pos += 2;

            
$strlen $this->_getByte($data$pos);
            
$pos += 1;
            
$header '';
            for (
$i 0$i $strlen$i++) {
                
$header .= $data{$pos $i};
            }
            
$pos += $strlen - ($strlen 2);  // The string is padded to even length, counting the length byte itself

            
$length $this->_getLong($data$pos);
            
$pos += 4;

            
$basePos $pos;

            switch (
$type) {
            case 
0x0404// Caption (IPTC Data)
                
$pos $this->_readIPTC($data$pos);
                if (
$pos == false)
                    return 
false;
                break;
            case 
0x040A// CopyrightFlag
                
$this->_info['adobe']['CopyrightFlag'] = $this->_getByte($data$pos);
                
$pos += $length;
                break;
            case 
0x040B// ImageURL
                
$this->_info['adobe']['ImageURL'] = $this->_getFixedString($data$pos$length);
                
$pos += $length;
                break;
            case 
0x040C// Thumbnail
                
$aux $this->_getLong($data$pos);
                
$pos += 4;
                if (
$aux == 1) {
                    
$this->_info['adobe']['ThumbnailWidth'] = $this->_getLong($data$pos);
                    
$pos += 4;
                    
$this->_info['adobe']['ThumbnailHeight'] = $this->_getLong($data$pos);
                    
$pos += 4;

                    
$pos += 16// Skip some data

                    
$this->_info['adobe']['ThumbnailData'] = $this->_getFixedString($data$pos$length 28);
                    
$pos += $length 28;
                }
                break;
            default:
                break;
            }

            
// We save all blocks, even those we recognized
            
$label sprintf('8BIM_0x%04x'$type);
            
$this->_info['adobe']['raw'][$label] = array();
            
$this->_info['adobe']['raw'][$label]['type'] = $type;
            
$this->_info['adobe']['raw'][$label]['header'] = $header;
            
$this->_info['adobe']['raw'][$label]['data'] =& $this->_getFixedString($data$basePos$length);

            
$pos $basePos $length + ($length 2); // Even padding
        
}

    }

    
/*************************************************************/
    
function _readIPTC(&$data$pos 0)
    {
        
$totalLength strlen($data);

        
$IPTCTags =& $this->_iptcTagNames();

        while (
$pos < ($totalLength 5)) {
            
$signature $this->_getShort($data$pos);
            if (
$signature != 0x1C02)
                return 
$pos;
            
$pos += 2;

            
$type $this->_getByte($data$pos);
            
$pos += 1;
            
$length $this->_getShort($data$pos);
            
$pos += 2;

            
$basePos $pos;
            
$label '';

            if (isset(
$IPTCTags[$type])) {
                
$label $IPTCTags[$type];
            }
            else {
                
$label sprintf('IPTC_0x%02x'$type);
            }

            if (
$label != '') {
                if (isset(
$this->_info['iptc'][$label])) {
                    if (!
is_array($this->_info['iptc'][$label])) {
                        
$aux = array();
                        
$aux[0] = $this->_info['iptc'][$label];
                        
$this->_info['iptc'][$label] = $aux;
                    }
                    
$this->_info['iptc'][$label][ count($this->_info['iptc'][$label]) ] = $this->_getFixedString($data$pos$length);
                }
                else {
                    
$this->_info['iptc'][$label] = $this->_getFixedString($data$pos$length);
                }
            }

            
$pos $basePos $length// No padding
        
}
        return 
$pos;
    }

    
/*************************************************************/
    
function & _createMarkerAdobe()
    {
        if (isset(
$this->_info['iptc'])) {
            if (!isset(
$this->_info['adobe'])) {
                
$this->_info['adobe'] = array();
            }
            if (!isset(
$this->_info['adobe']['raw'])) {
                
$this->_info['adobe']['raw'] = array();
            }
            if (!isset(
$this->_info['adobe']['raw']['8BIM_0x0404'])) {
                
$this->_info['adobe']['raw']['8BIM_0x0404'] = array();
            }
            
$this->_info['adobe']['raw']['8BIM_0x0404']['type'] = 0x0404;
            
$this->_info['adobe']['raw']['8BIM_0x0404']['header'] = "Caption";
            
$this->_info['adobe']['raw']['8BIM_0x0404']['data'] =& $this->_writeIPTC();
        }

        if (isset(
$this->_info['adobe']['raw']) && (count($this->_info['adobe']['raw']) > 0)) {
            
$data "Photoshop 3.0\0";
            
$pos 14;

            
reset($this->_info['adobe']['raw']);
            while (list(
$key) = each($this->_info['adobe']['raw'])) {
                
$pos $this->_write8BIM(
                            
$data,
                            
$pos,
                            
$this->_info['adobe']['raw'][$key]['type'],
                            
$this->_info['adobe']['raw'][$key]['header'],
                            
$this->_info['adobe']['raw'][$key]['data'] );
            }
        }

        return 
$data;
    }

    
/*************************************************************/
    
function _write8BIM(&$data$pos$type$header, &$value)
    {
        
$signature "8BIM";

        
$pos $this->_putString($data$pos$signature);
        
$pos $this->_putShort($data$pos$type);

        
$len strlen($header);

        
$pos $this->_putByte($data$pos$len);
        
$pos $this->_putString($data$pos$header);
        if ((
$len 2) == 0) {  // Even padding, including the length byte
            
$pos $this->_putByte($data$pos0);
        }

        
$len strlen($value);
        
$pos $this->_putLong($data$pos$len);
        
$pos $this->_putString($data$pos$value);
        if ((
$len 2) != 0) {  // Even padding
            
$pos $this->_putByte($data$pos0);
        }
        return 
$pos;
    }

    
/*************************************************************/
    
function & _writeIPTC()
    {
        
$data " ";
        
$pos 0;

        
$IPTCNames =& $this->_iptcNameTags();

        
reset($this->_info['iptc']);


        while (list(
$label) = each($this->_info['iptc'])) {
            
$value =& $this->_info['iptc'][$label];
            
$type = -1;

            if (isset(
$IPTCNames[$label])) {
                
$type $IPTCNames[$label];
            }
            elseif (
substr($label07) == "IPTC_0x") {
                
$type hexdec(substr($label72));
            }

            if (
$type != -1) {
                if (
is_array($value)) {
                    for (
$i 0$i count($value); $i++) {
                        
$pos $this->_writeIPTCEntry($data$pos$type$value[$i]);
                    }
                }
                else {
                    
$pos $this->_writeIPTCEntry($data$pos$type$value);
                }
            }
        }

        return 
$data;
    }

    
/*************************************************************/
    
function _writeIPTCEntry(&$data$pos$type, &$value)
    {
        
$pos $this->_putShort($data$pos0x1C02);
        
$pos $this->_putByte($data$pos$type);
        
$pos $this->_putShort($data$posstrlen($value));
        
$pos $this->_putString($data$pos$value);

        return 
$pos;
    }

    
/*************************************************************/
    
function _exifTagNames($mode)
    {
        
$tags = array();

        if (
$mode == 'ifd0') {
            
$tags[0x010E] = 'ImageDescription';
            
$tags[0x010F] = 'Make';
            
$tags[0x0110] = 'Model';
            
$tags[0x0112] = 'Orientation';
            
$tags[0x011A] = 'XResolution';
            
$tags[0x011B] = 'YResolution';
            
$tags[0x0128] = 'ResolutionUnit';
            
$tags[0x0131] = 'Software';
            
$tags[0x0132] = 'DateTime';
            
$tags[0x013B] = 'Artist';
            
$tags[0x013E] = 'WhitePoint';
            
$tags[0x013F] = 'PrimaryChromaticities';
            
$tags[0x0211] = 'YCbCrCoefficients';
            
$tags[0x0212] = 'YCbCrSubSampling';
            
$tags[0x0213] = 'YCbCrPositioning';
            
$tags[0x0214] = 'ReferenceBlackWhite';
            
$tags[0x8298] = 'Copyright';
            
$tags[0x8769] = 'ExifIFDOffset';
            
$tags[0x8825] = 'GPSIFDOffset';
        }
        if (
$mode == 'ifd1') {
            
$tags[0x00FE] = 'TIFFNewSubfileType';
            
$tags[0x00FF] = 'TIFFSubfileType';
            
$tags[0x0100] = 'TIFFImageWidth';
            
$tags[0x0101] = 'TIFFImageHeight';
            
$tags[0x0102] = 'TIFFBitsPerSample';
            
$tags[0x0103] = 'TIFFCompression';
            
$tags[0x0106] = 'TIFFPhotometricInterpretation';
            
$tags[0x0107] = 'TIFFThreshholding';
            
$tags[0x0108] = 'TIFFCellWidth';
            
$tags[0x0109] = 'TIFFCellLength';
            
$tags[0x010A] = 'TIFFFillOrder';
            
$tags[0x010E] = 'TIFFImageDescription';
            
$tags[0x010F] = 'TIFFMake';
            
$tags[0x0110] = 'TIFFModel';
            
$tags[0x0111] = 'TIFFStripOffsets';
            
$tags[0x0112] = 'TIFFOrientation';
            
$tags[0x0115] = 'TIFFSamplesPerPixel';
            
$tags[0x0116] = 'TIFFRowsPerStrip';
            
$tags[0x0117] = 'TIFFStripByteCounts';
            
$tags[0x0118] = 'TIFFMinSampleValue';
            
$tags[0x0119] = 'TIFFMaxSampleValue';
            
$tags[0x011A] = 'TIFFXResolution';
            
$tags[0x011B] = 'TIFFYResolution';
            
$tags[0x011C] = 'TIFFPlanarConfiguration';
            
$tags[0x0122] = 'TIFFGrayResponseUnit';
            
$tags[0x0123] = 'TIFFGrayResponseCurve';
            
$tags[0x0128] = 'TIFFResolutionUnit';
            
$tags[0x0131] = 'TIFFSoftware';
            
$tags[0x0132] = 'TIFFDateTime';
            
$tags[0x013B] = 'TIFFArtist';
            
$tags[0x013C] = 'TIFFHostComputer';
            
$tags[0x0140] = 'TIFFColorMap';
            
$tags[0x0152] = 'TIFFExtraSamples';
            
$tags[0x0201] = 'TIFFJFIFOffset';
            
$tags[0x0202] = 'TIFFJFIFLength';
            
$tags[0x0211] = 'TIFFYCbCrCoefficients';
            
$tags[0x0212] = 'TIFFYCbCrSubSampling';
            
$tags[0x0213] = 'TIFFYCbCrPositioning';
            
$tags[0x0214] = 'TIFFReferenceBlackWhite';
            
$tags[0x8298] = 'TIFFCopyright';
            
$tags[0x9286] = 'TIFFUserComment';
        }
        elseif (
$mode == 'exif') {
            
$tags[0x829A] = 'ExposureTime';
            
$tags[0x829D] = 'FNumber';
            
$tags[0x8822] = 'ExposureProgram';
            
$tags[0x8824] = 'SpectralSensitivity';
            
$tags[0x8827] = 'ISOSpeedRatings';
            
$tags[0x8828] = 'OECF';
            
$tags[0x9000] = 'EXIFVersion';
            
$tags[0x9003] = 'DatetimeOriginal';
            
$tags[0x9004] = 'DatetimeDigitized';
            
$tags[0x9101] = 'ComponentsConfiguration';
            
$tags[0x9102] = 'CompressedBitsPerPixel';
            
$tags[0x9201] = 'ShutterSpeedValue';
            
$tags[0x9202] = 'ApertureValue';
            
$tags[0x9203] = 'BrightnessValue';
            
$tags[0x9204] = 'ExposureBiasValue';
            
$tags[0x9205] = 'MaxApertureValue';
            
$tags[0x9206] = 'SubjectDistance';
            
$tags[0x9207] = 'MeteringMode';
            
$tags[0x9208] = 'LightSource';
            
$tags[0x9209] = 'Flash';
            
$tags[0x920A] = 'FocalLength';
            
$tags[0x927C] = 'MakerNote';
            
$tags[0x9286] = 'UserComment';
            
$tags[0x9290] = 'SubSecTime';
            
$tags[0x9291] = 'SubSecTimeOriginal';
            
$tags[0x9292] = 'SubSecTimeDigitized';
            
$tags[0xA000] = 'FlashPixVersion';
            
$tags[0xA001] = 'ColorSpace';
            
$tags[0xA002] = 'PixelXDimension';
            
$tags[0xA003] = 'PixelYDimension';
            
$tags[0xA004] = 'RelatedSoundFile';
            
$tags[0xA005] = 'InteropIFDOffset';
            
$tags[0xA20B] = 'FlashEnergy';
            
$tags[0xA20C] = 'SpatialFrequencyResponse';
            
$tags[0xA20E] = 'FocalPlaneXResolution';
            
$tags[0xA20F] = 'FocalPlaneYResolution';
            
$tags[0xA210] = 'FocalPlaneResolutionUnit';
            
$tags[0xA214] = 'SubjectLocation';
            
$tags[0xA215] = 'ExposureIndex';
            
$tags[0xA217] = 'SensingMethod';
            
$tags[0xA300] = 'FileSource';
            
$tags[0xA301] = 'SceneType';
            
$tags[0xA302] = 'CFAPattern';
        }
        elseif (
$mode == 'interop') {
            
$tags[0x0001] = 'InteroperabilityIndex';
            
$tags[0x0002] = 'InteroperabilityVersion';
            
$tags[0x1000] = 'RelatedImageFileFormat';
            
$tags[0x1001] = 'RelatedImageWidth';
            
$tags[0x1002] = 'RelatedImageLength';
        }
        elseif (
$mode == 'gps') {
            
$tags[0x0000] = 'GPSVersionID';
            
$tags[0x0001] = 'GPSLatitudeRef';
            
$tags[0x0002] = 'GPSLatitude';
            
$tags[0x0003] = 'GPSLongitudeRef';
            
$tags[0x0004] = 'GPSLongitude';
            
$tags[0x0005] = 'GPSAltitudeRef';
            
$tags[0x0006] = 'GPSAltitude';
            
$tags[0x0007] = 'GPSTimeStamp';
            
$tags[0x0008] = 'GPSSatellites';
            
$tags[0x0009] = 'GPSStatus';
            
$tags[0x000A] = 'GPSMeasureMode';
            
$tags[0x000B] = 'GPSDOP';
            
$tags[0x000C] = 'GPSSpeedRef';
            
$tags[0x000D] = 'GPSSpeed';
            
$tags[0x000E] = 'GPSTrackRef';
            
$tags[0x000F] = 'GPSTrack';
            
$tags[0x0010] = 'GPSImgDirectionRef';
            
$tags[0x0011] = 'GPSImgDirection';
            
$tags[0x0012] = 'GPSMapDatum';
            
$tags[0x0013] = 'GPSDestLatitudeRef';
            
$tags[0x0014] = 'GPSDestLatitude';
            
$tags[0x0015] = 'GPSDestLongitudeRef';
            
$tags[0x0016] = 'GPSDestLongitude';
            
$tags[0x0017] = 'GPSDestBearingRef';
            
$tags[0x0018] = 'GPSDestBearing';
            
$tags[0x0019] = 'GPSDestDistanceRef';
            
$tags[0x001A] = 'GPSDestDistance';
        }

        return 
$tags;
    }

    
/*************************************************************/
    
function _exifTagTypes($mode)
    {
        
$tags = array();

        if (
$mode == 'ifd0') {
            
$tags[0x010E] = array(20); // ImageDescription -> ASCII, Any
            
$tags[0x010F] = array(20); // Make -> ASCII, Any
            
$tags[0x0110] = array(20); // Model -> ASCII, Any
            
$tags[0x0112] = array(31); // Orientation -> SHORT, 1
            
$tags[0x011A] = array(51); // XResolution -> RATIONAL, 1
            
$tags[0x011B] = array(51); // YResolution -> RATIONAL, 1
            
$tags[0x0128] = array(31); // ResolutionUnit -> SHORT
            
$tags[0x0131] = array(20); // Software -> ASCII, Any
            
$tags[0x0132] = array(220); // DateTime -> ASCII, 20
            
$tags[0x013B] = array(20); // Artist -> ASCII, Any
            
$tags[0x013E] = array(52); // WhitePoint -> RATIONAL, 2
            
$tags[0x013F] = array(56); // PrimaryChromaticities -> RATIONAL, 6
            
$tags[0x0211] = array(53); // YCbCrCoefficients -> RATIONAL, 3
            
$tags[0x0212] = array(32); // YCbCrSubSampling -> SHORT, 2
            
$tags[0x0213] = array(31); // YCbCrPositioning -> SHORT, 1
            
$tags[0x0214] = array(56); // ReferenceBlackWhite -> RATIONAL, 6
            
$tags[0x8298] = array(20); // Copyright -> ASCII, Any
            
$tags[0x8769] = array(41); // ExifIFDOffset -> LONG, 1
            
$tags[0x8825] = array(41); // GPSIFDOffset -> LONG, 1
        
}
        if (
$mode == 'ifd1') {
            
$tags[0x00FE] = array(41); // TIFFNewSubfileType -> LONG, 1
            
$tags[0x00FF] = array(31); // TIFFSubfileType -> SHORT, 1
            
$tags[0x0100] = array(41); // TIFFImageWidth -> LONG (or SHORT), 1
            
$tags[0x0101] = array(41); // TIFFImageHeight -> LONG (or SHORT), 1
            
$tags[0x0102] = array(33); // TIFFBitsPerSample -> SHORT, 3
            
$tags[0x0103] = array(31); // TIFFCompression -> SHORT, 1
            
$tags[0x0106] = array(31); // TIFFPhotometricInterpretation -> SHORT, 1
            
$tags[0x0107] = array(31); // TIFFThreshholding -> SHORT, 1
            
$tags[0x0108] = array(31); // TIFFCellWidth -> SHORT, 1
            
$tags[0x0109] = array(31); // TIFFCellLength -> SHORT, 1
            
$tags[0x010A] = array(31); // TIFFFillOrder -> SHORT, 1
            
$tags[0x010E] = array(20); // TIFFImageDescription -> ASCII, Any
            
$tags[0x010F] = array(20); // TIFFMake -> ASCII, Any
            
$tags[0x0110] = array(20); // TIFFModel -> ASCII, Any
            
$tags[0x0111] = array(40); // TIFFStripOffsets -> LONG (or SHORT), Any (one per strip)
            
$tags[0x0112] = array(31); // TIFFOrientation -> SHORT, 1
            
$tags[0x0115] = array(31); // TIFFSamplesPerPixel -> SHORT, 1
            
$tags[0x0116] = array(41); // TIFFRowsPerStrip -> LONG (or SHORT), 1
            
$tags[0x0117] = array(40); // TIFFStripByteCounts -> LONG (or SHORT), Any (one per strip)
            
$tags[0x0118] = array(30); // TIFFMinSampleValue -> SHORT, Any (SamplesPerPixel)
            
$tags[0x0119] = array(30); // TIFFMaxSampleValue -> SHORT, Any (SamplesPerPixel)
            
$tags[0x011A] = array(51); // TIFFXResolution -> RATIONAL, 1
            
$tags[0x011B] = array(51); // TIFFYResolution -> RATIONAL, 1
            
$tags[0x011C] = array(31); // TIFFPlanarConfiguration -> SHORT, 1
            
$tags[0x0122] = array(31); // TIFFGrayResponseUnit -> SHORT, 1
            
$tags[0x0123] = array(30); // TIFFGrayResponseCurve -> SHORT, Any (2^BitsPerSample)
            
$tags[0x0128] = array(31); // TIFFResolutionUnit -> SHORT, 1
            
$tags[0x0131] = array(20); // TIFFSoftware -> ASCII, Any
            
$tags[0x0132] = array(220); // TIFFDateTime -> ASCII, 20
            
$tags[0x013B] = array(20); // TIFFArtist -> ASCII, Any
            
$tags[0x013C] = array(20); // TIFFHostComputer -> ASCII, Any
            
$tags[0x0140] = array(30); // TIFFColorMap -> SHORT, Any (3 * 2^BitsPerSample)
            
$tags[0x0152] = array(30); // TIFFExtraSamples -> SHORT, Any (SamplesPerPixel - 3)
            
$tags[0x0201] = array(41); // TIFFJFIFOffset -> LONG, 1
            
$tags[0x0202] = array(41); // TIFFJFIFLength -> LONG, 1
            
$tags[0x0211] = array(53); // TIFFYCbCrCoefficients -> RATIONAL, 3
            
$tags[0x0212] = array(32); // TIFFYCbCrSubSampling -> SHORT, 2
            
$tags[0x0213] = array(31); // TIFFYCbCrPositioning -> SHORT, 1
            
$tags[0x0214] = array(56); // TIFFReferenceBlackWhite -> RATIONAL, 6
            
$tags[0x8298] = array(20); // TIFFCopyright -> ASCII, Any
            
$tags[0x9286] = array(20); // TIFFUserComment -> ASCII, Any
        
}
        elseif (
$mode == 'exif') {
            
$tags[0x829A] = array(51); // ExposureTime -> RATIONAL, 1
            
$tags[0x829D] = array(51); // FNumber -> RATIONAL, 1
            
$tags[0x8822] = array(31); // ExposureProgram -> SHORT, 1
            
$tags[0x8824] = array(20); // SpectralSensitivity -> ASCII, Any
            
$tags[0x8827] = array(30); // ISOSpeedRatings -> SHORT, Any
            
$tags[0x8828] = array(70); // OECF -> UNDEFINED, Any
            
$tags[0x9000] = array(74); // EXIFVersion -> UNDEFINED, 4
            
$tags[0x9003] = array(220); // DatetimeOriginal -> ASCII, 20
            
$tags[0x9004] = array(220); // DatetimeDigitized -> ASCII, 20
            
$tags[0x9101] = array(74); // ComponentsConfiguration -> UNDEFINED, 4
            
$tags[0x9102] = array(51); // CompressedBitsPerPixel -> RATIONAL, 1
            
$tags[0x9201] = array(101); // ShutterSpeedValue -> SRATIONAL, 1
            
$tags[0x9202] = array(51); // ApertureValue -> RATIONAL, 1
            
$tags[0x9203] = array(101); // BrightnessValue -> SRATIONAL, 1
            
$tags[0x9204] = array(101); // ExposureBiasValue -> SRATIONAL, 1
            
$tags[0x9205] = array(51); // MaxApertureValue -> RATIONAL, 1
            
$tags[0x9206] = array(51); // SubjectDistance -> RATIONAL, 1
            
$tags[0x9207] = array(31); // MeteringMode -> SHORT, 1
            
$tags[0x9208] = array(31); // LightSource -> SHORT, 1
            
$tags[0x9209] = array(31); // Flash -> SHORT, 1
            
$tags[0x920A] = array(51); // FocalLength -> RATIONAL, 1
            
$tags[0x927C] = array(70); // MakerNote -> UNDEFINED, Any
            
$tags[0x9286] = array(70); // UserComment -> UNDEFINED, Any
            
$tags[0x9290] = array(20); // SubSecTime -> ASCII, Any
            
$tags[0x9291] = array(20); // SubSecTimeOriginal -> ASCII, Any
            
$tags[0x9292] = array(20); // SubSecTimeDigitized -> ASCII, Any
            
$tags[0xA000] = array(74); // FlashPixVersion -> UNDEFINED, 4
            
$tags[0xA001] = array(31); // ColorSpace -> SHORT, 1
            
$tags[0xA002] = array(41); // PixelXDimension -> LONG (or SHORT), 1
            
$tags[0xA003] = array(41); // PixelYDimension -> LONG (or SHORT), 1
            
$tags[0xA004] = array(213); // RelatedSoundFile -> ASCII, 13
            
$tags[0xA005] = array(41); // InteropIFDOffset -> LONG, 1
            
$tags[0xA20B] = array(51); // FlashEnergy -> RATIONAL, 1
            
$tags[0xA20C] = array(70); // SpatialFrequencyResponse -> UNDEFINED, Any
            
$tags[0xA20E] = array(51); // FocalPlaneXResolution -> RATIONAL, 1
            
$tags[0xA20F] = array(51); // FocalPlaneYResolution -> RATIONAL, 1
            
$tags[0xA210] = array(31); // FocalPlaneResolutionUnit -> SHORT, 1
            
$tags[0xA214] = array(32); // SubjectLocation -> SHORT, 2
            
$tags[0xA215] = array(51); // ExposureIndex -> RATIONAL, 1
            
$tags[0xA217] = array(31); // SensingMethod -> SHORT, 1
            
$tags[0xA300] = array(71); // FileSource -> UNDEFINED, 1
            
$tags[0xA301] = array(71); // SceneType -> UNDEFINED, 1
            
$tags[0xA302] = array(70); // CFAPattern -> UNDEFINED, Any
        
}
        elseif (
$mode == 'interop') {
            
$tags[0x0001] = array(20); // InteroperabilityIndex -> ASCII, Any
            
$tags[0x0002] = array(74); // InteroperabilityVersion -> UNKNOWN, 4
            
$tags[0x1000] = array(20); // RelatedImageFileFormat -> ASCII, Any
            
$tags[0x1001] = array(41); // RelatedImageWidth -> LONG (or SHORT), 1
            
$tags[0x1002] = array(41); // RelatedImageLength -> LONG (or SHORT), 1
        
}
        elseif (
$mode == 'gps') {
            
$tags[0x0000] = array(14); // GPSVersionID -> BYTE, 4
            
$tags[0x0001] = array(22); // GPSLatitudeRef -> ASCII, 2
            
$tags[0x0002] = array(53); // GPSLatitude -> RATIONAL, 3
            
$tags[0x0003] = array(22); // GPSLongitudeRef -> ASCII, 2
            
$tags[0x0004] = array(53); // GPSLongitude -> RATIONAL, 3
            
$tags[0x0005] = array(22); // GPSAltitudeRef -> ASCII, 2
            
$tags[0x0006] = array(51); // GPSAltitude -> RATIONAL, 1
            
$tags[0x0007] = array(53); // GPSTimeStamp -> RATIONAL, 3
            
$tags[0x0008] = array(20); // GPSSatellites -> ASCII, Any
            
$tags[0x0009] = array(22); // GPSStatus -> ASCII, 2
            
$tags[0x000A] = array(22); // GPSMeasureMode -> ASCII, 2
            
$tags[0x000B] = array(51); // GPSDOP -> RATIONAL, 1
            
$tags[0x000C] = array(22); // GPSSpeedRef -> ASCII, 2
            
$tags[0x000D] = array(51); // GPSSpeed -> RATIONAL, 1
            
$tags[0x000E] = array(22); // GPSTrackRef -> ASCII, 2
            
$tags[0x000F] = array(51); // GPSTrack -> RATIONAL, 1
            
$tags[0x0010] = array(22); // GPSImgDirectionRef -> ASCII, 2
            
$tags[0x0011] = array(51); // GPSImgDirection -> RATIONAL, 1
            
$tags[0x0012] = array(20); // GPSMapDatum -> ASCII, Any
            
$tags[0x0013] = array(22); // GPSDestLatitudeRef -> ASCII, 2
            
$tags[0x0014] = array(53); // GPSDestLatitude -> RATIONAL, 3
            
$tags[0x0015] = array(22); // GPSDestLongitudeRef -> ASCII, 2
            
$tags[0x0016] = array(53); // GPSDestLongitude -> RATIONAL, 3
            
$tags[0x0017] = array(22); // GPSDestBearingRef -> ASCII, 2
            
$tags[0x0018] = array(51); // GPSDestBearing -> RATIONAL, 1
            
$tags[0x0019] = array(22); // GPSDestDistanceRef -> ASCII, 2
            
$tags[0x001A] = array(51); // GPSDestDistance -> RATIONAL, 1
        
}

        return 
$tags;
    }

    
/*************************************************************/
    
function _exifNameTags($mode)
    {
        
$tags $this->_exifTagNames($mode);
        return 
$this->_names2Tags($tags);
    }

    
/*************************************************************/
    
function _iptcTagNames()
    {
        
$tags = array();
        
$tags[0x14] = 'SuplementalCategories';
        
$tags[0x19] = 'Keywords';
        
$tags[0x78] = 'Caption';
        
$tags[0x7A] = 'CaptionWriter';
        
$tags[0x69] = 'Headline';
        
$tags[0x28] = 'SpecialInstructions';
        
$tags[0x0F] = 'Category';
        
$tags[0x50] = 'Byline';
        
$tags[0x55] = 'BylineTitle';
        
$tags[0x6E] = 'Credit';
        
$tags[0x73] = 'Source';
        
$tags[0x74] = 'CopyrightNotice';
        
$tags[0x05] = 'ObjectName';
        
$tags[0x5A] = 'City';
        
$tags[0x5C] = 'Sublocation';
        
$tags[0x5F] = 'ProvinceState';
        
$tags[0x65] = 'CountryName';
        
$tags[0x67] = 'OriginalTransmissionReference';
        
$tags[0x37] = 'DateCreated';
        
$tags[0x0A] = 'CopyrightFlag';

        return 
$tags;
    }

    
/*************************************************************/
    
function & _iptcNameTags()
    {
        
$tags $this->_iptcTagNames();
        return 
$this->_names2Tags($tags);
    }

    
/*************************************************************/
    
function _names2Tags($tags2Names)
    {
        
$names2Tags = array();
        
reset($tags2Names);
        while (list(
$tag$name) = each($tags2Names)) {
            
$names2Tags[$name] = $tag;
        }

        return 
$names2Tags;
    }

    
/*************************************************************/
    
function _getByte(&$data$pos)
    {
        return 
ord($data{$pos});
    }

    
/*************************************************************/
    
function _putByte(&$data$pos$val)
    {
        
$val intval($val);

        
$data{$pos} = chr($val);

        return 
$pos 1;
    }

    
/*************************************************************/
    
function _getShort(&$data$pos$bigEndian true)
    {
        if (
$bigEndian) {
            return (
ord($data{$pos}) << 8)
                   + 
ord($data{$pos 1});
        }
        else {
            return 
ord($data{$pos})
                   + (
ord($data{$pos 1}) << 8);
        }
    }

    
/*************************************************************/
    
function _putShort(&$data$pos 0$val$bigEndian true)
    {
        
$val intval($val);

        if (
$bigEndian) {
            
$data{$pos 0} = chr(($val 0x0000FF00) >> 8);
            
$data{$pos 1} = chr(($val 0x000000FF) >> 0);
        }
        else {
            
$data{$pos 0} = chr(($val 0x00FF) >> 0);
            
$data{$pos 1} = chr(($val 0xFF00) >> 8);
        }

        return 
$pos 2;
    }

    
/*************************************************************/
    
function _getLong(&$data$pos$bigEndian true)
    {
        if (
$bigEndian) {
            return (
ord($data{$pos}) << 24)
                   + (
ord($data{$pos 1}) << 16)
                   + (
ord($data{$pos 2}) << 8)
                   + 
ord($data{$pos 3});
        }
        else {
            return 
ord($data{$pos})
                   + (
ord($data{$pos 1}) << 8)
                   + (
ord($data{$pos 2}) << 16)
                   + (
ord($data{$pos 3}) << 24);
        }
    }

    
/*************************************************************/
    
function _putLong(&$data$pos$val$bigEndian true)
    {
        
$val intval($val);

        if (
$bigEndian) {
            
$data{$pos 0} = chr(($val 0xFF000000) >> 24);
            
$data{$pos 1} = chr(($val 0x00FF0000) >> 16);
            
$data{$pos 2} = chr(($val 0x0000FF00) >> 8);
            
$data{$pos 3} = chr(($val 0x000000FF) >> 0);
        }
        else {
            
$data{$pos 0} = chr(($val 0x000000FF) >> 0);
            
$data{$pos 1} = chr(($val 0x0000FF00) >> 8);
            
$data{$pos 2} = chr(($val 0x00FF0000) >> 16);
            
$data{$pos 3} = chr(($val 0xFF000000) >> 24);
        }

        return 
$pos 4;
    }

    
/*************************************************************/
    
function & _getNullString(&$data$pos)
    {
        
$str '';
        
$max strlen($data);

        while (
$pos $max) {
            if (
ord($data{$pos}) == 0) {
                return 
$str;
            }
            else {
                
$str .= $data{$pos};
            }
            
$pos++;
        }

        return 
$str;
    }

    
/*************************************************************/
    
function & _getFixedString(&$data$pos$length = -1)
    {
        if (
$length == -1) {
            
$length strlen($data) - $pos;
        }

        return 
substr($data$pos$length);
    }

    
/*************************************************************/
    
function _putString(&$data$pos, &$str)
    {
        
$len strlen($str);
        for (
$i 0$i $len$i++) {
          
$data{$pos $i} = $str{$i};
        }

        return 
$pos $len;
    }

    
/*************************************************************/
    
function _hexDump(&$data$start 0$length = -1)
    {
        if ((
$length == -1) || (($length $start) > strlen($data))) {
            
$end strlen($data);
        }
        else {
            
$end $start $length;
        }

        
$ascii '';
        
$count 0;

        echo 
"<tt>\n";

        while (
$start $end) {
            if ((
$count 16) == 0) {
                echo 
sprintf('%04d'$count) . ': ';
            }

            
$c ord($data{$start});
            
$count++;
            
$start++;

            
$aux dechex($c);
            if (
strlen($aux) == 1)
                echo 
'0';
            echo 
$aux ' ';

            if (
$c == 60)
                
$ascii .= '&lt;';
            elseif (
$c == 62)
                
$ascii .= '&gt;';
            elseif (
$c == 32)
                
$ascii .= '&nbsp;';
            elseif (
$c 32)
                
$ascii .= chr($c);
            else
                
$ascii .= '.';

            if ((
$count 4) == 0) {
                echo 
' - ';
            }

            if ((
$count 16) == 0) {
                echo 
': ' $ascii "<br>\n";
                
$ascii '';
            }
        }

        if (
$ascii != '') {
            while ((
$count 16) != 0) {
                echo 
'-- ';
                
$count++;
                if ((
$count 4) == 0) {
                    echo 
' - ';
                }
            }
            echo 
': ' $ascii "<br>\n";
        }

        echo 
"</tt>\n";
    }

/*****************************************************************/
}

/* vim: set expandtab tabstop=4 shiftwidth=4: */


:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v.2.1 [PHP 7 Update] [1.12.2019] maintained by KaizenLouie and updated by cermmik | C99Shell Github (MySQL update) | Generation time: 0.0264 ]--