Example #1
0
 /**
  * Turn this object into bytes.
  *
  * TIFF images can have {@link PelConvert::LITTLE_ENDIAN
  * little-endian} or {@link PelConvert::BIG_ENDIAN big-endian} byte
  * order, and so this method takes an argument specifying that.
  *
  * @param PelByteOrder $order
  *            the desired byte order of the TIFF data.
  *            This should be one of {@link PelConvert::LITTLE_ENDIAN} or {@link
  *            PelConvert::BIG_ENDIAN}.
  *
  * @return string the bytes representing this object.
  */
 public function getBytes($order = PelConvert::LITTLE_ENDIAN)
 {
     if ($order == PelConvert::LITTLE_ENDIAN) {
         $bytes = 'II';
     } else {
         $bytes = 'MM';
     }
     /* TIFF magic number --- fixed value. */
     $bytes .= PelConvert::shortToBytes(self::TIFF_HEADER, $order);
     if ($this->ifd != null) {
         /*
          * IFD 0 offset. We will always start IDF 0 at an offset of 8
          * bytes (2 bytes for byte order, another 2 bytes for the TIFF
          * header, and 4 bytes for the IFD 0 offset make 8 bytes
          * together).
          */
         $bytes .= PelConvert::longToBytes(8, $order);
         /*
          * The argument specifies the offset of this IFD. The IFD will
          * use this to calculate offsets from the entries to their data,
          * all those offsets are absolute offsets counted from the
          * beginning of the data.
          */
         $bytes .= $this->ifd->getBytes(8, $order);
     } else {
         $bytes .= PelConvert::longToBytes(0, $order);
     }
     return $bytes;
 }
Example #2
0
 /**
  * Turn this directory into bytes.
  *
  * This directory will be turned into a byte string, with the
  * specified byte order.  The offsets will be calculated from the
  * offset given.
  *
  * @param int the offset of the first byte of this directory.
  *
  * @param PelByteOrder the byte order that should be used when
  * turning integers into bytes.  This should be one of {@link
  * PelConvert::LITTLE_ENDIAN} and {@link PelConvert::BIG_ENDIAN}.
  */
 function getBytes($offset, $order)
 {
     $bytes = '';
     $extra_bytes = '';
     Pel::debug('Bytes from IDF will start at offset %d within Exif data', $offset);
     $n = count($this->entries) + count($this->sub);
     if ($this->thumb_data != null) {
         /* We need two extra entries for the thumbnail offset and
          * length. */
         $n += 2;
     }
     $bytes .= PelConvert::shortToBytes($n, $order);
     /* Initialize offset of extra data.  This included the bytes
      * preceding this IFD, the bytes needed for the count of entries,
      * the entries themselves (and sub entries), the extra data in the
      * entries, and the IFD link.
      */
     $end = $offset + 2 + 12 * $n + 4;
     foreach ($this->entries as $tag => $entry) {
         /* Each entry is 12 bytes long. */
         $bytes .= PelConvert::shortToBytes($entry->getTag(), $order);
         $bytes .= PelConvert::shortToBytes($entry->getFormat(), $order);
         $bytes .= PelConvert::longToBytes($entry->getComponents(), $order);
         /*
          * Size? If bigger than 4 bytes, the actual data is not in
          * the entry but somewhere else.
          */
         $data = $entry->getBytes($order);
         $s = strlen($data);
         if ($s > 4) {
             Pel::debug('Data size %d too big, storing at offset %d instead.', $s, $end);
             $bytes .= PelConvert::longToBytes($end, $order);
             $extra_bytes .= $data;
             $end += $s;
         } else {
             Pel::debug('Data size %d fits.', $s);
             /* Copy data directly, pad with NULL bytes as necessary to
              * fill out the four bytes available.*/
             $bytes .= $data . str_repeat(chr(0), 4 - $s);
         }
     }
     if ($this->thumb_data != null) {
         Pel::debug('Appending %d bytes of thumbnail data at %d', $this->thumb_data->getSize(), $end);
         // TODO: make PelEntry a class that can be constructed with
         // arguments corresponding to the newt four lines.
         $bytes .= PelConvert::shortToBytes(PelTag::JPEG_INTERCHANGE_FORMAT_LENGTH, $order);
         $bytes .= PelConvert::shortToBytes(PelFormat::LONG, $order);
         $bytes .= PelConvert::longToBytes(1, $order);
         $bytes .= PelConvert::longToBytes($this->thumb_data->getSize(), $order);
         $bytes .= PelConvert::shortToBytes(PelTag::JPEG_INTERCHANGE_FORMAT, $order);
         $bytes .= PelConvert::shortToBytes(PelFormat::LONG, $order);
         $bytes .= PelConvert::longToBytes(1, $order);
         $bytes .= PelConvert::longToBytes($end, $order);
         $extra_bytes .= $this->thumb_data->getBytes();
         $end += $this->thumb_data->getSize();
     }
     /* Find bytes from sub IFDs. */
     $sub_bytes = '';
     foreach ($this->sub as $type => $sub) {
         if ($type == PelIfd::EXIF) {
             $tag = PelTag::EXIF_IFD_POINTER;
         } elseif ($type == PelIfd::GPS) {
             $tag = PelTag::GPS_INFO_IFD_POINTER;
         } elseif ($type == PelIfd::INTEROPERABILITY) {
             $tag = PelTag::INTEROPERABILITY_IFD_POINTER;
         }
         /* Make an aditional entry with the pointer. */
         $bytes .= PelConvert::shortToBytes($tag, $order);
         /* Next the format, which is always unsigned long. */
         $bytes .= PelConvert::shortToBytes(PelFormat::LONG, $order);
         /* There is only one component. */
         $bytes .= PelConvert::longToBytes(1, $order);
         $data = $sub->getBytes($end, $order);
         $s = strlen($data);
         $sub_bytes .= $data;
         $bytes .= PelConvert::longToBytes($end, $order);
         $end += $s;
     }
     /* Make link to next IFD, if any*/
     if ($this->isLastIFD()) {
         $link = 0;
     } else {
         $link = $end;
     }
     Pel::debug('Link to next IFD: %d', $link);
     $bytes .= PelConvert::longtoBytes($link, $order);
     $bytes .= $extra_bytes . $sub_bytes;
     if (!$this->isLastIfd()) {
         $bytes .= $this->next->getBytes($end, $order);
     }
     return $bytes;
 }
 /**
  * Convert a number into bytes.
  *
  * @param int the number that should be converted.
  *
  * @param PelByteOrder one of {@link PelConvert::LITTLE_ENDIAN} and
  * {@link PelConvert::BIG_ENDIAN}, specifying the target byte order.
  *
  * @return string bytes representing the number given.
  */
 function numberToBytes($number, $order)
 {
     return PelConvert::longToBytes($number, $order);
 }