Example #1
0
 /**
  * Extract data from a JPEG image
  *
  * @param string $data Image raw data
  *
  * @return array Image raw data array
  */
 public function getData($data)
 {
     $data['filter'] = 'DCTDecode';
     $data['data'] = $data['raw'];
     $byte = new Byte($data['raw']);
     // extract embedded ICC profile (if any)
     $icc = array();
     $offset = 0;
     while (($pos = strpos($data['raw'], 'ICC_PROFILE' . "", $offset)) !== false) {
         // get ICC sequence length
         $length = $byte->getUShort($pos - 2) - 16;
         // marker sequence number
         $msn = max(1, ord($data['raw'][$pos + 12]));
         // number of markers (total of APP2 used)
         //$nom = max(1, ord($data['raw'][($pos + 13)]));
         // get sequence segment
         $icc[$msn - 1] = substr($data['raw'], $pos + 14, $length);
         // move forward to next sequence
         $offset = $pos + 14 + $length;
     }
     // order and compact ICC segments
     if (count($icc) > 0) {
         ksort($icc);
         $icc = implode('', $icc);
         if (substr($icc, 36, 4) == 'acsp') {
             // valid ICC profile
             $data['icc'] = $icc;
         }
     }
     return $data;
 }
Example #2
0
 /**
  * Get font widths
  */
 protected function getWidths()
 {
     // create widths array
     $chw = array();
     $this->offset = $this->fdt['table']['hmtx']['offset'];
     for ($i = 0; $i < $this->fdt['numHMetrics']; ++$i) {
         $chw[$i] = round($this->fbyte->getUFWord($this->offset) * $this->fdt['urk']);
         $this->offset += 4;
         // skip lsb
     }
     if ($this->fdt['numHMetrics'] < $this->fdt['numGlyphs']) {
         // fill missing widths with the last value
         $chw = array_pad($chw, $this->fdt['numGlyphs'], $chw[$this->fdt['numHMetrics'] - 1]);
     }
     $this->fdt['MissingWidth'] = $chw[0];
     $this->fdt['cw'] = '';
     $this->fdt['cbbox'] = '';
     for ($cid = 0; $cid <= 65535; ++$cid) {
         if (isset($this->fdt['ctgdata'][$cid])) {
             if ($cid >= 0 && isset($chw[$this->fdt['ctgdata'][$cid]])) {
                 $this->fdt['cw'] .= ',"' . $cid . '":' . $chw[$this->fdt['ctgdata'][$cid]];
             }
             if (isset($this->fdt['indexToLoc'][$this->fdt['ctgdata'][$cid]])) {
                 $this->offset = $this->fdt['table']['glyf']['offset'] + $this->fdt['indexToLoc'][$this->fdt['ctgdata'][$cid]];
                 $xMin = round($this->fbyte->getFWord($this->offset + 2) * $this->fdt['urk']);
                 $yMin = round($this->fbyte->getFWord($this->offset + 4) * $this->fdt['urk']);
                 $xMax = round($this->fbyte->getFWord($this->offset + 6) * $this->fdt['urk']);
                 $yMax = round($this->fbyte->getFWord($this->offset + 8) * $this->fdt['urk']);
                 $this->fdt['cbbox'] .= ',"' . $cid . '":[' . $xMin . ',' . $yMin . ',' . $xMax . ',' . $yMax . ']';
             }
         }
     }
 }
Example #3
0
 /**
  * Add composite glyphs
  *
  * @param array $new_sga
  * @param int   $key
  *
  * @return array
  */
 protected function findCompositeGlyphs($new_sga, $key)
 {
     if (isset($this->fdt['indexToLoc'][$key])) {
         $this->offset = $this->fdt['table']['glyf']['offset'] + $this->fdt['indexToLoc'][$key];
         $numberOfContours = $this->fbyte->getShort($this->offset);
         $this->offset += 2;
         if ($numberOfContours < 0) {
             // composite glyph
             $this->offset += 8;
             // skip xMin, yMin, xMax, yMax
             do {
                 $flags = $this->fbyte->getUShort($this->offset);
                 $this->offset += 2;
                 $glyphIndex = $this->fbyte->getUShort($this->offset);
                 $this->offset += 2;
                 if (!isset($this->subglyphs[$glyphIndex])) {
                     // add missing glyphs
                     $new_sga[$glyphIndex] = true;
                 }
                 // skip some bytes by case
                 if ($flags & 1) {
                     $this->offset += 4;
                 } else {
                     $this->offset += 2;
                 }
                 if ($flags & 8) {
                     $this->offset += 2;
                 } elseif ($flags & 64) {
                     $this->offset += 4;
                 } elseif ($flags & 128) {
                     $this->offset += 8;
                 }
             } while ($flags & 32);
         }
     }
     return $new_sga;
 }
 /**
  * Get the font type
  *
  * @param string $font_type      Font type. Leave empty for autodetect mode.
  *
  * @return string
  */
 protected function getFontType($font_type)
 {
     // autodetect font type
     if (empty($font_type)) {
         if (substr($this->font, 0, 16) == 'StartFontMetrics') {
             // AFM type - we use this type only for the 14 Core fonts
             return 'Core';
         }
         if (substr($this->font, 0, 4) == 'OTTO') {
             throw new FontException('Unsupported font format: OpenType with CFF data');
         }
         if ($this->fbyte->getULong(0) == 0x10000) {
             return 'TrueTypeUnicode';
         }
         return 'Type1';
     }
     if (strpos($font_type, 'CID0') === 0) {
         return 'cidfont0';
     }
     if (in_array($font_type, array('Core', 'Type1', 'TrueType', 'TrueTypeUnicode'))) {
         return $font_type;
     }
     throw new FontException('unknown or unsupported font type: ' . $font_type);
 }
Example #5
0
 /**
  * Extract the iCCP chunk data
  *
  * @param Byte   $byte   Byte class object
  * @param string $data   Image raw data
  * @param int    $offset Current byte offset
  * @param int    $len    NUmber of bytes in this chunk
  *
  * @return array Image raw data array
  */
 protected function getIccpChunk($byte, $data, &$offset, $len)
 {
     // skip profile name
     $pos = 0;
     while ($byte->getByte($offset++) != 0 && $pos < 80) {
         ++$pos;
     }
     // get compression method
     if ($byte->getByte($offset++) != 0) {
         // @codeCoverageIgnoreStart
         throw new ImageException('Unknown filter method');
         // @codeCoverageIgnoreEnd
     }
     // read ICC Color Profile
     $len -= $pos + 2;
     $data['icc'] = gzuncompress(substr($data['raw'], $offset, $len));
     $offset += $len;
     $offset += 4;
     return $data;
 }