Source for file PelEntryAscii.php

Documentation is available at PelEntryAscii.php

  1. <?php
  2.  
  3. /*  PEL: PHP Exif Library.  A library with support for reading and
  4.  *  writing all Exif headers in JPEG and TIFF images using PHP.
  5.  *
  6.  *  Copyright (C) 2004, 2005, 2006  Martin Geisler.
  7.  *
  8.  *  This program is free software; you can redistribute it and/or modify
  9.  *  it under the terms of the GNU General Public License as published by
  10.  *  the Free Software Foundation; either version 2 of the License, or
  11.  *  (at your option) any later version.
  12.  *
  13.  *  This program is distributed in the hope that it will be useful,
  14.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  *  GNU General Public License for more details.
  17.  *
  18.  *  You should have received a copy of the GNU General Public License
  19.  *  along with this program in the file COPYING; if not, write to the
  20.  *  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
  21.  *  Boston, MA 02110-1301 USA
  22.  */
  23.  
  24. /* $Id: PelEntryAscii.php 443 2006-09-17 18:32:04Z mgeisler $ */
  25.  
  26.  
  27. /**
  28.  * Classes used to hold ASCII strings.
  29.  *
  30.  * The classes defined here are to be used for Exif entries holding
  31.  * ASCII strings, such as {@link PelTag::MAKE}{@link }
  32.  * PelTag::SOFTWARE}, and {@link PelTag::DATE_TIME}.  For
  33.  * entries holding normal textual ASCII strings the class {@link }
  34.  * PelEntryAscii} should be used, but for entries holding
  35.  * timestamps the class {@link PelEntryTime} would be more
  36.  * convenient instead.  Copyright information is handled by the {@link }
  37.  * PelEntryCopyright} class.
  38.  *
  39.  * @author Martin Geisler <mgeisler@users.sourceforge.net>
  40.  * @version $Revision: 443 $
  41.  * @date $Date: 2006-09-17 20:32:04 +0200 (Sun, 17 Sep 2006) $
  42.  * @license http://www.gnu.org/licenses/gpl.html GNU General Public
  43.  *  License (GPL)
  44.  * @package PEL
  45.  */
  46.  
  47. /**#@+ Required class definitions. */
  48. require_once('PelEntry.php');
  49. /**#@-*/
  50.  
  51.  
  52.  * Class for holding a plain ASCII string.
  53.  *
  54.  * This class can hold a single ASCII string, and it will be used as in
  55.  * <code>
  56.  * $entry = $ifd->getEntry(PelTag::IMAGE_DESCRIPTION);
  57.  * print($entry->getValue());
  58.  * $entry->setValue('This is my image.  I like it.');
  59.  * </code>
  60.  *
  61.  * @author Martin Geisler <mgeisler@users.sourceforge.net>
  62.  * @package PEL
  63.  */
  64. class PelEntryAscii extends PelEntry {
  65.  
  66.   /**
  67.    * The string hold by this entry.
  68.    *
  69.    * This is the string that was given to the {@link __construct}
  70.    * constructor} or later to {@link setValue}, without any final NULL
  71.    * character.
  72.    *
  73.    * @var string 
  74.    */
  75.   private $str;
  76.  
  77.  
  78.   /**
  79.    * Make a new PelEntry that can hold an ASCII string.
  80.    *
  81.    * @param int the tag which this entry represents.  This should be
  82.    *  one of the constants defined in {@link PelTag}, e.g., {@link }
  83.    *  PelTag::IMAGE_DESCRIPTION}, {@link PelTag::MODEL}, or any other
  84.    *  tag with format {@link PelFormat::ASCII}.
  85.    *
  86.    * @param string the string that this entry will represent.  The
  87.    *  string must obey the same rules as the string argument to {@link }
  88.    *  setValue}, namely that it should be given without any trailing
  89.    *  NULL character and that it must be plain 7-bit ASCII.
  90.    */
  91.   function __construct($tag$str ''{
  92.     $this->tag    = $tag;
  93.     $this->format = PelFormat::ASCII;
  94.     $this->setValue($str);
  95.   }
  96.  
  97.  
  98.   /**
  99.    * Give the entry a new ASCII value.
  100.    *
  101.    * This will overwrite the previous value.  The value can be
  102.    * retrieved later with the {@link getValue} method.
  103.    *
  104.    * @param string the new value of the entry.  This should be given
  105.    *  without any trailing NULL character.  The string must be plain
  106.    *  7-bit ASCII, the string should contain no high bytes.
  107.    *
  108.    * @todo Implement check for high bytes?
  109.    */
  110.   function setValue($str{
  111.     $this->components = strlen($str)+1;
  112.     $this->str        $str;
  113.     $this->bytes      = $str chr(0x00);
  114.   }
  115.  
  116.  
  117.   /**
  118.    * Return the ASCII string of the entry.
  119.    *
  120.    * @return string the string held, without any final NULL character.
  121.    *  The string will be the same as the one given to {@link setValue}
  122.    *  or to the {@link __construct constructor}.
  123.    */
  124.   function getValue({
  125.     return $this->str;
  126.   }
  127.  
  128.  
  129.   /**
  130.    * Return the ASCII string of the entry.
  131.    *
  132.    * This methods returns the same as {@link getValue}.
  133.    *
  134.    * @param boolean not used with ASCII entries.
  135.    *
  136.    * @return string the string held, without any final NULL character.
  137.    *  The string will be the same as the one given to {@link setValue}
  138.    *  or to the {@link __construct constructor}.
  139.    */
  140.   function getText($brief false{
  141.     return $this->str;      
  142.   }
  143.  
  144. }
  145.  
  146.  
  147. /**
  148.  * Class for holding a date and time.
  149.  *
  150.  * This class can hold a timestamp, and it will be used as
  151.  * in this example where the time is advanced by one week:
  152.  * <code>
  153.  * $entry = $ifd->getEntry(PelTag::DATE_TIME_ORIGINAL);
  154.  * $time = $entry->getValue();
  155.  * print('The image was taken on the ' . date($time, 'jS'));
  156.  * $entry->setValue($time + 7 * 24 * 3600);
  157.  * </code>
  158.  *
  159.  * The example used a standard UNIX timestamp, which is the default
  160.  * for this class.
  161.  *
  162.  * But the Exif format defines dates outside the range of a UNIX
  163.  * timestamp (about 1970 to 2038) and so you can also get access to
  164.  * the timestamp in two other formats: a simple string or a Julian Day
  165.  * Count. Please see the Calendar extension in the PHP Manual for more
  166.  * information about the Julian Day Count.
  167.  *
  168.  * @author Martin Geisler <mgeisler@users.sourceforge.net>
  169.  * @package PEL
  170.  */
  171. class PelEntryTime extends PelEntryAscii {
  172.  
  173.   /**
  174.    * Constant denoting a UNIX timestamp.
  175.    */
  176.   const UNIX_TIMESTAMP   = 1;
  177.   /**
  178.    * Constant denoting a Exif string.
  179.    */
  180.   const EXIF_STRING      = 2;
  181.   /**
  182.    * Constant denoting a Julian Day Count.
  183.    */
  184.   const JULIAN_DAY_COUNT = 3;
  185.  
  186.   /**
  187.    * The Julian Day Count of the timestamp held by this entry.
  188.    *
  189.    * This is an integer counting the number of whole days since
  190.    * January 1st, 4713 B.C. The fractional part of the timestamp held
  191.    * by this entry is stored in {@link $seconds}.
  192.    *
  193.    * @var int 
  194.    */
  195.   private $day_count;
  196.  
  197.   /**
  198.    * The number of seconds into the day of the timestamp held by this
  199.    * entry.
  200.    *
  201.    * The number of whole days is stored in {@link $day_count} and the
  202.    * number of seconds left-over is stored here.
  203.    *
  204.    * @var int 
  205.    */
  206.   private $seconds;
  207.  
  208.  
  209.   /**
  210.    * Make a new entry for holding a timestamp.
  211.    *
  212.    * @param int the Exif tag which this entry represents.  There are
  213.    *  only three standard tags which hold timestamp, so this should be
  214.    *  one of the constants {@link PelTag::DATE_TIME}{@link }
  215.    *  PelTag::DATE_TIME_ORIGINAL}, or {@link }
  216.    *  PelTag::DATE_TIME_DIGITIZED}.
  217.    *
  218.    * @param int the timestamp held by this entry in the correct form
  219.    *  as indicated by the third argument. For {@link UNIX_TIMESTAMP}
  220.    *  this is an integer counting the number of seconds since January
  221.    *  1st 1970, for {@link EXIF_STRING} this is a string of the form
  222.    *  'YYYY:MM:DD hh:mm:ss', and for {@link JULIAN_DAY_COUNT} this is a
  223.    *  floating point number where the integer part denotes the day
  224.    *  count and the fractional part denotes the time of day (0.25 means
  225.    *  6:00, 0.75 means 18:00).
  226.    *
  227.    * @param int the type of the timestamp. This must be one of
  228.    *  {@link UNIX_TIMESTAMP}{@link EXIF_STRING}, or
  229.    *  {@link JULIAN_DAY_COUNT}.
  230.    */
  231.   function __construct($tag$timestamp$type self::UNIX_TIMESTAMP{
  232.     parent::__construct($tag);
  233.     $this->setValue($timestamp$type);
  234.   }
  235.  
  236.   
  237.   /**
  238.    * Return the timestamp of the entry.
  239.    *
  240.    * The timestamp held by this entry is returned in one of three
  241.    * formats: as a standard UNIX timestamp (default), as a fractional
  242.    * Julian Day Count, or as a string.
  243.    *
  244.    * @param int the type of the timestamp. This must be one of
  245.    *  {@link UNIX_TIMESTAMP}{@link EXIF_STRING}, or
  246.    *  {@link JULIAN_DAY_COUNT}.
  247.    *
  248.    * @return int the timestamp held by this entry in the correct form
  249.    *  as indicated by the type argument. For {@link UNIX_TIMESTAMP}
  250.    *  this is an integer counting the number of seconds since January
  251.    *  1st 1970, for {@link EXIF_STRING} this is a string of the form
  252.    *  'YYYY:MM:DD hh:mm:ss', and for {@link JULIAN_DAY_COUNT} this is a
  253.    *  floating point number where the integer part denotes the day
  254.    *  count and the fractional part denotes the time of day (0.25 means
  255.    *  6:00, 0.75 means 18:00).
  256.    */
  257.   function getValue($type self::UNIX_TIMESTAMP{
  258.     switch ($type{
  259.     case self::UNIX_TIMESTAMP:
  260.       $seconds jdtounix($this->day_count);
  261.       if ($seconds === false)
  262.         /* jdtounix() return false if the Julian Day Count is outside
  263.          * the range of a UNIX timestamp. */ 
  264.         return false;
  265.       else
  266.         return $seconds $this->seconds;
  267.  
  268.     case self::EXIF_STRING:
  269.       list($month$day$yearexplode('/'jdtogregorian($this->day_count));
  270.       $hours   = (int)($this->seconds 3600);
  271.       $minutes = (int)($this->seconds 3600 60);
  272.       $seconds $this->seconds 60;
  273.       return sprintf('%04d:%02d:%02d %02d:%02d:%02d',
  274.                      $year$month$day$hours$minutes$seconds);
  275.     case self::JULIAN_DAY_COUNT:
  276.       return $this->day_count $this->seconds 86400;
  277.     default:
  278.       throw new PelInvalidArgumentException('Expected UNIX_TIMESTAMP (%d), ' .
  279.                                             'EXIF_STRING (%d), or ' .
  280.                                             'JULIAN_DAY_COUNT (%d) for $type, '.
  281.                                             'got %d.',
  282.                                             self::UNIX_TIMESTAMP,
  283.                                             self::EXIF_STRING,
  284.                                             self::JULIAN_DAY_COUNT,
  285.                                             $type);
  286.         }
  287.   }
  288.  
  289.  
  290.   /**
  291.    * Update the timestamp held by this entry.
  292.    *
  293.    * @param int the timestamp held by this entry in the correct form
  294.    *  as indicated by the third argument. For {@link UNIX_TIMESTAMP}
  295.    *  this is an integer counting the number of seconds since January
  296.    *  1st 1970, for {@link EXIF_STRING} this is a string of the form
  297.    *  'YYYY:MM:DD hh:mm:ss', and for {@link JULIAN_DAY_COUNT} this is a
  298.    *  floating point number where the integer part denotes the day
  299.    *  count and the fractional part denotes the time of day (0.25 means
  300.    *  6:00, 0.75 means 18:00).
  301.    *
  302.    * @param int the type of the timestamp. This must be one of
  303.    *  {@link UNIX_TIMESTAMP}{@link EXIF_STRING}, or
  304.    *  {@link JULIAN_DAY_COUNT}.
  305.    *
  306.    * @todo How to deal with timezones? Use the TimeZoneOffset tag
  307.    *  0x882A?
  308.    */
  309.   function setValue($timestamp$type self::UNIX_TIMESTAMP{
  310.     switch ($type{
  311.     case self::UNIX_TIMESTAMP:
  312.       $this->day_count unixtojd($timestamp);
  313.       $this->seconds   $timestamp 86400;
  314.       break;
  315.  
  316.     case self::EXIF_STRING:
  317.       /* Clean the timestamp: some timestamps are broken other
  318.        * separators than ':' and ' '. */
  319.       $d split('[^0-9]+'$timestamp);
  320.       $this->day_count gregoriantojd($d[1]$d[2]$d[0]);
  321.       $this->seconds   $d[3]*3600 $d[4]*60 $d[5];
  322.       break;
  323.  
  324.     case self::JULIAN_DAY_COUNT:
  325.       $this->day_count = (int)floor($timestamp);
  326.       $this->seconds = (int)(86400 ($timestamp floor($timestamp)));
  327.       break;
  328.  
  329.     default:
  330.       throw new PelInvalidArgumentException('Expected UNIX_TIMESTAMP (%d), ' .
  331.                                             'EXIF_STRING (%d), or ' .
  332.                                             'JULIAN_DAY_COUNT (%d) for $type, '.
  333.                                             'got %d.',
  334.                                             self::UNIX_TIMESTAMP,
  335.                                             self::EXIF_STRING,
  336.                                             self::JULIAN_DAY_COUNT,
  337.                                             $type);
  338.     }
  339.  
  340.     /* Now finally update the string which will be used when this is
  341.      * turned into bytes. */
  342.     parent::setValue($this->getValue(self::EXIF_STRING));
  343.   }
  344. }
  345.  
  346.  
  347. /**
  348.  * Class for holding copyright information.
  349.  *
  350.  * The Exif standard specifies a certain format for copyright
  351.  * information where the one {@link PelTag::COPYRIGHT copyright}
  352.  * tag} holds both the photographer and editor copyrights, separated
  353.  * by a NULL character.
  354.  *
  355.  * This class is used to manipulate that tag so that the format is
  356.  * kept to the standard.  A common use would be to add a new copyright
  357.  * tag to an image, since most cameras do not add this tag themselves.
  358.  * This would be done like this:
  359.  *
  360.  * <code>
  361.  * $entry = new PelEntryCopyright('Copyright, Martin Geisler, 2004');
  362.  * $ifd0->addEntry($entry);
  363.  * </code>
  364.  *
  365.  * Here we only set the photographer copyright, use the optional
  366.  * second argument to specify the editor copyright.  If there is only
  367.  * an editor copyright, then let the first argument be the empty
  368.  * string.
  369.  *
  370.  * @author Martin Geisler <mgeisler@users.sourceforge.net>
  371.  * @package PEL
  372.  */
  373. class PelEntryCopyright extends PelEntryAscii {
  374.  
  375.   /**
  376.    * The photographer copyright.
  377.    *
  378.    * @var string 
  379.    */
  380.   private $photographer;
  381.  
  382.   /**
  383.    * The editor copyright.
  384.    *
  385.    * @var string 
  386.    */
  387.   private $editor;
  388.  
  389.  
  390.   /**
  391.    * Make a new entry for holding copyright information.
  392.    *
  393.    * @param string the photographer copyright.  Use the empty string
  394.    *  if there is no photographer copyright.
  395.    *
  396.    * @param string the editor copyright.  Use the empty string if
  397.    *  there is no editor copyright.
  398.    */
  399.   function __construct($photographer ''$editor ''{
  400.     parent::__construct(PelTag::COPYRIGHT);
  401.     $this->setValue($photographer$editor);
  402.   }
  403.   
  404.  
  405.   /**
  406.    * Update the copyright information.
  407.    *
  408.    * @param string the photographer copyright.  Use the empty string
  409.    *  if there is no photographer copyright.
  410.    *
  411.    * @param string the editor copyright.  Use the empty string if
  412.    *  there is no editor copyright.
  413.    */
  414.   function setValue($photographer ''$editor ''{
  415.     $this->photographer $photographer;
  416.     $this->editor       $editor;
  417.  
  418.     if ($photographer == '' && $editor != '')
  419.       $photographer ' ';
  420.  
  421.     if ($editor == '')
  422.       parent::setValue($photographer);
  423.     else
  424.       parent::setValue($photographer chr(0x00$editor);
  425.   }
  426.  
  427.  
  428.   /**
  429.    * Retrive the copyright information.
  430.    *
  431.    * The strings returned will be the same as the one used previously
  432.    * with either {@link __construct the constructor} or with {@link }
  433.    * setValue}.
  434.    *
  435.    * @return array an array with two strings, the photographer and
  436.    *  editor copyrights.  The two fields will be returned in that
  437.    *  order, so that the first array index will be the photographer
  438.    *  copyright, and the second will be the editor copyright.
  439.    */
  440.   function getValue({
  441.     return array($this->photographer$this->editor);
  442.   }
  443.  
  444.  
  445.   /**
  446.    * Return a text string with the copyright information.
  447.    *
  448.    * The photographer and editor copyright fields will be returned
  449.    * with a '-' in between if both copyright fields are present,
  450.    * otherwise only one of them will be returned.
  451.    *
  452.    * @param boolean if false, then the strings '(Photographer)' and
  453.    *  '(Editor)' will be appended to the photographer and editor
  454.    *  copyright fields (if present), otherwise the fields will be
  455.    *  returned as is.
  456.    *
  457.    * @return string the copyright information in a string.
  458.    */
  459.   function getText($brief false{
  460.     if ($brief{
  461.       $p '';
  462.       $e '';
  463.     else {
  464.       $p ' ' Pel::tra('(Photographer)');
  465.       $e ' ' Pel::tra('(Editor)');
  466.     }
  467.  
  468.     if ($this->photographer != '' && $this->editor != '')
  469.       return $this->photographer $p ' - ' $this->editor $e;
  470.     
  471.     if ($this->photographer != '')
  472.       return $this->photographer $p;
  473.  
  474.     if ($this->editor != '')
  475.       return $this->editor $e;
  476.  
  477.     return '';
  478.   }
  479. }
  480.  
  481. ?>

Documentation generated on Tue, 19 Dec 2006 01:08:19 +0100 by phpDocumentor 1.3.0 SourceForge.net Logo