Exemple #1
0
 /**
  * Retrieves what you really want to know about an image file, PDFs included,
  * before making calls such as the above based on good information.
  * Returns as follows:
  * array('format' => 'file extension: gif, jpg, png or pdf', 'width' => width in pixels, 'height' => height in pixels);
  * $format is the recommended file extension based on the actual file type, not the user's (possibly totally false or absent)
  * claimed file extension.
  * If the file does not have a valid header identifying it as one of these types, false is returned.
  * If the 'format-only' option is true, only the format field is returned. This is much faster if the
  * file is a PDF.
  * @param mixed $file
  * @param mixed $options
  * @return mixed
  */
 public static function getInfo($file, $options = array())
 {
     $formatOnly = isset($options['format-only']) && $options['format-only'];
     $result = array();
     $in = fopen($file, "rb");
     $data = fread($in, 4);
     fclose($in);
     if ($data === '%PDF') {
         // format-only
         if ($formatOnly || !aImageConverter::supportsInput('pdf')) {
             // All we can do is confirm the format and allow
             // download of the original (which, for PDF, is
             // usually fine)
             return array('format' => 'pdf');
         }
         $result['format'] = 'pdf';
         $path = sfConfig::get("app_aimageconverter_path", "");
         if (strlen($path)) {
             if (!preg_match("/\\/\$/", $path)) {
                 $path .= "/";
             }
         }
         // Bounding box goes to stderr, not stdout! Charming
         // 5 second timeout for reading dimensions. Keeps us from getting stuck on
         // PDFs that just barely work in Adobe but are noncompliant and hang ghostscript.
         // Read the output one line at a time so we can catch the happy
         // bounding box message without hanging
         // Problem: this doesn't work. We regain control but the process won't die for some reason. It helps
         // with import but for now go with the simpler standard invocation and hope they fix gs
         // $cmd = "(PATH=$path:\$PATH; export PATH; gs -sDEVICE=bbox -dNOPAUSE -dFirstPage=1 -dLastPage=1 -r100 -q " . escapeshellarg($file) . " -c quit ) 2>&1";
         $cmd = "( PATH={$path}:\$PATH; export PATH; gs -sDEVICE=bbox -dNOPAUSE -dFirstPage=1 -dLastPage=1 -r100 -q " . escapeshellarg($file) . " -c quit & GS=\$!; ( sleep 5; kill \$GS ) & TIMEOUT=\$!; wait \$GS; kill \$TIMEOUT ) 2>&1";
         // For some reason system() does not get the same result when killing subshells as I get when executing
         // $cmd directly. I don't know why this is this the case but it's easily reproduced
         $script = aFiles::getTemporaryFilename() . '.sh';
         file_put_contents($script, $cmd);
         $cmd = "/bin/sh " . escapeshellarg($script);
         $in = popen($cmd, "r");
         $data = stream_get_contents($in);
         pclose($in);
         // Actual nonfatal errors in the bbox output mean it's not safe to just
         // read this naively with fscanf, look for the good part
         if (preg_match("/%%BoundingBox: \\d+ \\d+ (\\d+) (\\d+)/", $data, $matches)) {
             $result['width'] = $matches[1];
             $result['height'] = $matches[2];
         }
         if (!isset($result['width'])) {
             // Bad PDF
             return false;
         }
         return $result;
     } else {
         $formats = array(IMAGETYPE_JPEG => "jpg", IMAGETYPE_PNG => "png", IMAGETYPE_GIF => "gif");
         $data = getimagesize($file);
         if (count($data) < 3) {
             return false;
         }
         if (!isset($formats[$data[2]])) {
             return false;
         }
         $format = $formats[$data[2]];
         $result['format'] = $format;
         if ($formatOnly) {
             return $result;
         }
         $result['width'] = $data[0];
         $result['height'] = $data[1];
         if ($format === 'jpg') {
             // Some EXIF orientations swap width and height
             switch (aImageConverter::getRotation($file, $data)) {
                 case 5:
                     // vertical flip + 90 rotate right
                 // vertical flip + 90 rotate right
                 case 6:
                     // 90 rotate right
                 // 90 rotate right
                 case 7:
                     // horizontal flip + 90 rotate right
                 // horizontal flip + 90 rotate right
                 case 8:
                     // 90 rotate left
                     $result['width'] = $data[1];
                     $result['height'] = $data[0];
                     break;
             }
         }
         return $result;
     }
 }