예제 #1
0
파일: PelIfd.php 프로젝트: adjaika/J3Base
 /**
  * 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;
 }