예제 #1
0
 /**
  * @param File $image
  * @param string $filename
  * @throws MWException
  * @return string
  */
 function getMetadata($image, $filename)
 {
     global $wgShowEXIF;
     if ($wgShowEXIF) {
         try {
             $meta = BitmapMetadataHandler::Tiff($filename);
             if (!is_array($meta)) {
                 // This should never happen, but doesn't hurt to be paranoid.
                 throw new MWException('Metadata array is not an array');
             }
             $meta['MEDIAWIKI_EXIF_VERSION'] = Exif::version();
             return serialize($meta);
         } catch (Exception $e) {
             // BitmapMetadataHandler throws an exception in certain exceptional
             // cases like if file does not exist.
             wfDebug(__METHOD__ . ': ' . $e->getMessage() . "\n");
             return ExifBitmapHandler::BROKEN_FILE;
         }
     } else {
         return '';
     }
 }
	/**
	 * Reads metadata of the tiff file via shell command and returns an associative array.
	 * layout:
	 * meta['page_count'] = number of pages
	 * meta['first_page'] = number of first page
	 * meta['last_page'] = number of last page
	 * meta['page_data'] = metadata per page
	 * meta['exif']  = Exif, XMP and IPTC
	 * meta['errors'] = identify-errors
	 * meta['warnings'] = identify-warnings
	 */
	public function retrieveMetaData() {
		global $wgImageMagickIdentifyCommand, $wgExiv2Command, $wgTiffUseExiv;
		global $wgTiffUseTiffinfo, $wgTiffTiffinfoCommand;
		global $wgShowEXIF;

		if ( $this->_meta === null ) {
			wfProfileIn( 'PagedTiffImage::retrieveMetaData' );

			//fetch base info: number of pages, size and alpha for each page.
			//run hooks first, then optionally tiffinfo or, per default, ImageMagic's identify command
			if ( !wfRunHooks( 'PagedTiffHandlerTiffData', array( $this->mFilename, &$this->_meta ) ) ) {
				wfDebug( __METHOD__ . ": hook PagedTiffHandlerTiffData overrides TIFF data extraction\n" );
			} elseif ( $wgTiffUseTiffinfo ) {
				// read TIFF directories using libtiff's tiffinfo, see
				// http://www.libtiff.org/man/tiffinfo.1.html
				$cmd = wfEscapeShellArg( $wgTiffTiffinfoCommand ) .
					' ' . wfEscapeShellArg( $this->mFilename ) . ' 2>&1';

				wfProfileIn( 'tiffinfo' );
				wfDebug( __METHOD__ . ": $cmd\n" );
				$retval = '';
				$dump = wfShellExec( $cmd, $retval );
				wfProfileOut( 'tiffinfo' );

				if ( $retval ) {
					$data['errors'][] = "tiffinfo command failed: $cmd";
					wfDebug( __METHOD__ . ": tiffinfo command failed: $cmd\n" );
					return $data; // fail. we *need* that info
				}

				$this->_meta = $this->parseTiffinfoOutput( $dump );
			} else {
				$cmd = wfEscapeShellArg( $wgImageMagickIdentifyCommand ) .
					' -format "[BEGIN]page=%p\nalpha=%A\nalpha2=%r\nheight=%h\nwidth=%w\ndepth=%z[END]" ' .
					wfEscapeShellArg( $this->mFilename ) . ' 2>&1';

				wfProfileIn( 'identify' );
				wfDebug( __METHOD__ . ": $cmd\n" );
				$retval = '';
				$dump = wfShellExec( $cmd, $retval );
				wfProfileOut( 'identify' );

				if ( $retval ) {
					$data['errors'][] = "identify command failed: $cmd";
					wfDebug( __METHOD__ . ": identify command failed: $cmd\n" );
					return $data; // fail. we *need* that info
				}

				$this->_meta = $this->parseIdentifyOutput( $dump );
			}

			$this->_meta['exif'] = array();

			//fetch extended info: EXIF/IPTC/XMP
			//run hooks first, then optionally Exiv2 or, per default, the internal EXIF class
			if ( !empty( $this->_meta['errors'] ) ) {
				wfDebug( __METHOD__ . ": found errors, skipping EXIF extraction\n" );
			} elseif ( !wfRunHooks( 'PagedTiffHandlerExifData', array( $this->mFilename, &$this->_meta['exif'] ) ) ) {
				wfDebug( __METHOD__ . ": hook PagedTiffHandlerExifData overrides EXIF extraction\n" );
			} elseif ( $wgTiffUseExiv ) {
				// read EXIF, XMP, IPTC as name-tag => interpreted data
				// -ignore unknown fields
				// see exiv2-doc @link http://www.exiv2.org/sample.html
				// NOTE: the linux version of exiv2 has a bug: it can only
				// read one type of meta-data at a time, not all at once.
				$cmd = wfEscapeShellArg( $wgExiv2Command ) .
					' -u -psix -Pnt ' . wfEscapeShellArg( $this->mFilename ) . ' 2>&1';

				wfProfileIn( 'exiv2' );
				wfDebug( __METHOD__ . ": $cmd\n" );
				$retval = '';
				$dump = wfShellExec( $cmd, $retval );
				wfProfileOut( 'exiv2' );

				if ( $retval ) {
					$data['errors'][] = "exiv command failed: $cmd";
					wfDebug( __METHOD__ . ": exiv command failed: $cmd\n" );
					// don't fail - we are missing info, just report
				}

				$data = $this->parseExiv2Output( $dump );

				$this->_meta['exif'] = $data;
			} elseif ( $wgShowEXIF ) {
				wfDebug( __METHOD__ . ": using internal Exif( {$this->mFilename} )\n" );
				if ( method_exists( 'BitmapMetadataHandler', 'Tiff' ) ) {
					$data = BitmapMetadataHandler::Tiff( $this->mFilename );
				} else {
					// old method for back compat.
					$exif = new Exif( $this->mFilename );
					$data = $exif->getFilteredData();
				}

				if ( $data ) {
					$data['MEDIAWIKI_EXIF_VERSION'] = Exif::version();
					$this->_meta['exif'] = $data;
				}
			}

			unset( $this->_meta['exif']['Image'] );
			unset( $this->_meta['exif']['filename'] );
			unset( $this->_meta['exif']['Base filename'] );
			unset( $this->_meta['exif']['XMLPacket'] );
			unset( $this->_meta['exif']['ImageResources'] );

			$this->_meta['TIFF_METADATA_VERSION'] = TIFF_METADATA_VERSION;

			wfProfileOut( 'PagedTiffImage::retrieveMetaData' );
		}

		return $this->_meta;
	}