/** * Turn this entry into a string. * * @return string a string representation of this entry. This is * mostly for debugging. */ function __toString() { $str = Pel::fmt(" Tag: 0x%04X (%s)\n", $this->tag, PelTag::getName($this->ifd_type, $this->tag)); $str .= Pel::fmt(" Format : %d (%s)\n", $this->format, PelFormat::getName($this->format)); $str .= Pel::fmt(" Components: %d\n", $this->components); if ($this->getTag() != PelTag::MAKER_NOTE && $this->getTag() != PelTag::PRINT_IM) { $str .= Pel::fmt(" Value : %s\n", print_r($this->getValue(), true)); } $str .= Pel::fmt(" Text : %s\n", $this->getText()); return $str; }
/** * Make a new entry from a bunch of bytes. * * This method will create the proper subclass of {@link PelEntry} * corresponding to the {@link PelTag} and {@link PelFormat} given. * The entry will be initialized with the data given. * * Please note that the data you pass to this method should come * from an image, that is, it should be raw bytes. If instead you * want to create an entry for holding, say, an short integer, then * create a {@link PelEntryShort} object directly and load the data * into it. * * A {@link PelUnexpectedFormatException} is thrown if a mismatch is * discovered between the tag and format, and likewise a {@link * PelWrongComponentCountException} is thrown if the number of * components does not match the requirements of the tag. The * requirements for a given tag (if any) can be found in the * documentation for {@link PelTag}. * * @param PelTag the tag of the entry. * * @param PelFormat the format of the entry. * * @param int the components in the entry. * * @param PelDataWindow the data which will be used to construct the * entry. * * @return PelEntry a newly created entry, holding the data given. */ function newEntryFromData($tag, $format, $components, PelDataWindow $data) { /* First handle tags for which we have a specific PelEntryXXX * class. */ switch ($this->type) { case self::IFD0: case self::IFD1: case self::EXIF: case self::INTEROPERABILITY: switch ($tag) { case PelTag::DATE_TIME: case PelTag::DATE_TIME_ORIGINAL: case PelTag::DATE_TIME_DIGITIZED: if ($format != PelFormat::ASCII) { throw new PelUnexpectedFormatException($this->type, $tag, $format, PelFormat::ASCII); } if ($components != 20) { throw new PelWrongComponentCountException($this->type, $tag, $components, 20); } // TODO: handle timezones. return new PelEntryTime($tag, $data->getBytes(0, -1), PelEntryTime::EXIF_STRING); case PelTag::COPYRIGHT: if ($format != PelFormat::ASCII) { throw new PelUnexpectedFormatException($this->type, $tag, $format, PelFormat::ASCII); } $v = explode("", trim($data->getBytes(), ' ')); return new PelEntryCopyright($v[0], $v[1]); case PelTag::EXIF_VERSION: case PelTag::FLASH_PIX_VERSION: case PelTag::INTEROPERABILITY_VERSION: if ($format != PelFormat::UNDEFINED) { throw new PelUnexpectedFormatException($this->type, $tag, $format, PelFormat::UNDEFINED); } return new PelEntryVersion($tag, $data->getBytes() / 100); case PelTag::USER_COMMENT: if ($format != PelFormat::UNDEFINED) { throw new PelUnexpectedFormatException($this->type, $tag, $format, PelFormat::UNDEFINED); } if ($data->getSize() < 8) { return new PelEntryUserComment(); } else { return new PelEntryUserComment($data->getBytes(8), rtrim($data->getBytes(0, 8))); } case PelTag::XP_TITLE: case PelTag::XP_COMMENT: case PelTag::XP_AUTHOR: case PelTag::XP_KEYWORDS: case PelTag::XP_SUBJECT: if ($format != PelFormat::BYTE) { throw new PelUnexpectedFormatException($this->type, $tag, $format, PelFormat::BYTE); } $v = ''; for ($i = 0; $i < $components; $i++) { $b = $data->getByte($i); /* Convert the byte to a character if it is non-null --- * information about the character encoding of these entries * would be very nice to have! So far my tests have shown * that characters in the Latin-1 character set are stored in * a single byte followed by a NULL byte. */ if ($b != 0) { $v .= chr($b); } } return new PelEntryWindowsString($tag, $v); } case self::GPS: default: /* Then handle the basic formats. */ switch ($format) { case PelFormat::BYTE: $v = new PelEntryByte($tag); for ($i = 0; $i < $components; $i++) { $v->addNumber($data->getByte($i)); } return $v; case PelFormat::SBYTE: $v = new PelEntrySByte($tag); for ($i = 0; $i < $components; $i++) { $v->addNumber($data->getSByte($i)); } return $v; case PelFormat::ASCII: return new PelEntryAscii($tag, $data->getBytes(0, -1)); case PelFormat::SHORT: $v = new PelEntryShort($tag); for ($i = 0; $i < $components; $i++) { $v->addNumber($data->getShort($i * 2)); } return $v; case PelFormat::SSHORT: $v = new PelEntrySShort($tag); for ($i = 0; $i < $components; $i++) { $v->addNumber($data->getSShort($i * 2)); } return $v; case PelFormat::LONG: $v = new PelEntryLong($tag); for ($i = 0; $i < $components; $i++) { $v->addNumber($data->getLong($i * 4)); } return $v; case PelFormat::SLONG: $v = new PelEntrySLong($tag); for ($i = 0; $i < $components; $i++) { $v->addNumber($data->getSLong($i * 4)); } return $v; case PelFormat::RATIONAL: $v = new PelEntryRational($tag); for ($i = 0; $i < $components; $i++) { $v->addNumber($data->getRational($i * 8)); } return $v; case PelFormat::SRATIONAL: $v = new PelEntrySRational($tag); for ($i = 0; $i < $components; $i++) { $v->addNumber($data->getSRational($i * 8)); } return $v; case PelFormat::UNDEFINED: return new PelEntryUndefined($tag, $data->getBytes()); default: throw new PelException('Unsupported format: %s', PelFormat::getName($format)); } } }
/** * Construct a new exception indicating an invalid format. * * @param int $type * the type of IFD. * * @param PelTag $tag * the tag for which the violation was found. * * @param PelFormat $found * the format found. * * @param PelFormat $expected * the expected format. */ public function __construct($type, $tag, $found, $expected) { parent::__construct('Unexpected format found for %s tag: PelFormat::%s. ' . 'Expected PelFormat::%s instead.', PelTag::getName($type, $tag), strtoupper(PelFormat::getName($found)), strtoupper(PelFormat::getName($expected))); $this->tag = $tag; $this->type = $type; }