X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fmedia%2FPNGMetadataExtractor.php;h=b9377be0af7954031012429ea3423a755266520a;hb=008c561245742cdff111d4821839c9242f75ecb0;hp=845d212ab5a8a558c6cf91c24890f3cdbc273ba8;hpb=667a6c3dee132d6e26a648a77983513cca1f56b2;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/media/PNGMetadataExtractor.php b/includes/media/PNGMetadataExtractor.php index 845d212ab5..b9377be0af 100644 --- a/includes/media/PNGMetadataExtractor.php +++ b/includes/media/PNGMetadataExtractor.php @@ -31,40 +31,45 @@ * @ingroup Media */ class PNGMetadataExtractor { - static $png_sig; - static $CRC_size; - static $text_chunks; + /** @var string */ + private static $pngSig; + + /** @var int */ + private static $crcSize; + + /** @var array */ + private static $textChunks; const VERSION = 1; const MAX_CHUNK_SIZE = 3145728; // 3 megabytes static function getMetadata( $filename ) { - self::$png_sig = pack( "C8", 137, 80, 78, 71, 13, 10, 26, 10 ); - self::$CRC_size = 4; + self::$pngSig = pack( "C8", 137, 80, 78, 71, 13, 10, 26, 10 ); + self::$crcSize = 4; /* based on list at http://owl.phy.queensu.ca/~phil/exiftool/TagNames/PNG.html#TextualData * and http://www.w3.org/TR/PNG/#11keywords */ - self::$text_chunks = array( + self::$textChunks = array( 'xml:com.adobe.xmp' => 'xmp', # Artist is unofficial. Author is the recommended # keyword in the PNG spec. However some people output # Artist so support both. - 'artist' => 'Artist', - 'model' => 'Model', - 'make' => 'Make', - 'author' => 'Artist', - 'comment' => 'PNGFileComment', + 'artist' => 'Artist', + 'model' => 'Model', + 'make' => 'Make', + 'author' => 'Artist', + 'comment' => 'PNGFileComment', 'description' => 'ImageDescription', - 'title' => 'ObjectName', - 'copyright' => 'Copyright', + 'title' => 'ObjectName', + 'copyright' => 'Copyright', # Source as in original device used to make image # not as in who gave you the image - 'source' => 'Model', - 'software' => 'Software', - 'disclaimer' => 'Disclaimer', - 'warning' => 'ContentWarning', - 'url' => 'Identifier', # Not sure if this is best mapping. Maybe WebStatement. - 'label' => 'Label', + 'source' => 'Model', + 'software' => 'Software', + 'disclaimer' => 'Disclaimer', + 'warning' => 'ContentWarning', + 'url' => 'Identifier', # Not sure if this is best mapping. Maybe WebStatement. + 'label' => 'Label', 'creation time' => 'DateTimeDigitized', /* Other potentially useful things - Document */ ); @@ -90,7 +95,7 @@ class PNGMetadataExtractor { // Check for the PNG header $buf = fread( $fh, 8 ); - if ( $buf != self::$png_sig ) { + if ( $buf != self::$pngSig ) { throw new Exception( __METHOD__ . ": Not a valid PNG file; header: $buf" ); } @@ -181,9 +186,9 @@ class PNGMetadataExtractor { // Theoretically should be case-sensitive, but in practise... $items[1] = strtolower( $items[1] ); - if ( !isset( self::$text_chunks[$items[1]] ) ) { + if ( !isset( self::$textChunks[$items[1]] ) ) { // Only extract textual chunks on our list. - fseek( $fh, self::$CRC_size, SEEK_CUR ); + fseek( $fh, self::$crcSize, SEEK_CUR ); continue; } @@ -203,26 +208,23 @@ class PNGMetadataExtractor { if ( $items[5] === false ) { // decompression failed wfDebug( __METHOD__ . ' Error decompressing iTxt chunk - ' . $items[1] . "\n" ); - fseek( $fh, self::$CRC_size, SEEK_CUR ); + fseek( $fh, self::$crcSize, SEEK_CUR ); continue; } - } else { wfDebug( __METHOD__ . ' Skipping compressed png iTXt chunk due to lack of zlib,' . " or potentially invalid compression method\n" ); - fseek( $fh, self::$CRC_size, SEEK_CUR ); + fseek( $fh, self::$crcSize, SEEK_CUR ); continue; } } - $finalKeyword = self::$text_chunks[$items[1]]; + $finalKeyword = self::$textChunks[$items[1]]; $text[$finalKeyword][$items[3]] = $items[5]; $text[$finalKeyword]['_type'] = 'lang'; - } else { // Error reading iTXt chunk throw new Exception( __METHOD__ . ": Read error on iTXt chunk" ); } - } elseif ( $chunk_type == 'tEXt' ) { $buf = self::read( $fh, $chunk_size ); @@ -238,9 +240,9 @@ class PNGMetadataExtractor { // Theoretically should be case-sensitive, but in practise... $keyword = strtolower( $keyword ); - if ( !isset( self::$text_chunks[ $keyword ] ) ) { + if ( !isset( self::$textChunks[$keyword] ) ) { // Don't recognize chunk, so skip. - fseek( $fh, self::$CRC_size, SEEK_CUR ); + fseek( $fh, self::$crcSize, SEEK_CUR ); continue; } wfSuppressWarnings(); @@ -251,10 +253,9 @@ class PNGMetadataExtractor { throw new Exception( __METHOD__ . ": Read error (error with iconv)" ); } - $finalKeyword = self::$text_chunks[$keyword]; + $finalKeyword = self::$textChunks[$keyword]; $text[$finalKeyword]['x-default'] = $content; $text[$finalKeyword]['_type'] = 'lang'; - } elseif ( $chunk_type == 'zTXt' ) { if ( function_exists( 'gzuncompress' ) ) { $buf = self::read( $fh, $chunk_size ); @@ -271,16 +272,16 @@ class PNGMetadataExtractor { // Theoretically should be case-sensitive, but in practise... $keyword = strtolower( $keyword ); - if ( !isset( self::$text_chunks[ $keyword ] ) ) { + if ( !isset( self::$textChunks[$keyword] ) ) { // Don't recognize chunk, so skip. - fseek( $fh, self::$CRC_size, SEEK_CUR ); + fseek( $fh, self::$crcSize, SEEK_CUR ); continue; } $compression = substr( $postKeyword, 0, 1 ); $content = substr( $postKeyword, 1 ); if ( $compression !== "\x00" ) { wfDebug( __METHOD__ . " Unrecognized compression method in zTXt ($keyword). Skipping.\n" ); - fseek( $fh, self::$CRC_size, SEEK_CUR ); + fseek( $fh, self::$crcSize, SEEK_CUR ); continue; } @@ -291,7 +292,7 @@ class PNGMetadataExtractor { if ( $content === false ) { // decompression failed wfDebug( __METHOD__ . ' Error decompressing zTXt chunk - ' . $keyword . "\n" ); - fseek( $fh, self::$CRC_size, SEEK_CUR ); + fseek( $fh, self::$crcSize, SEEK_CUR ); continue; } @@ -303,10 +304,9 @@ class PNGMetadataExtractor { throw new Exception( __METHOD__ . ": Read error (error with iconv)" ); } - $finalKeyword = self::$text_chunks[$keyword]; + $finalKeyword = self::$textChunks[$keyword]; $text[$finalKeyword]['x-default'] = $content; $text[$finalKeyword]['_type'] = 'lang'; - } else { wfDebug( __METHOD__ . " Cannot decompress zTXt chunk due to lack of zlib. Skipping.\n" ); fseek( $fh, $chunk_size, SEEK_CUR ); @@ -332,7 +332,6 @@ class PNGMetadataExtractor { if ( $exifTime ) { $text['DateTime'] = $exifTime; } - } elseif ( $chunk_type == 'pHYs' ) { // how big pixels are (dots per meter). if ( $chunk_size !== 9 ) { @@ -359,13 +358,12 @@ class PNGMetadataExtractor { // 3 = dots per cm (from Exif). } } - } elseif ( $chunk_type == "IEND" ) { break; } else { fseek( $fh, $chunk_size, SEEK_CUR ); } - fseek( $fh, self::$CRC_size, SEEK_CUR ); + fseek( $fh, self::$crcSize, SEEK_CUR ); } fclose( $fh ); @@ -399,6 +397,7 @@ class PNGMetadataExtractor { } } } + return array( 'frameCount' => $frameCount, 'loopCount' => $loopCount, @@ -407,8 +406,8 @@ class PNGMetadataExtractor { 'bitDepth' => $bitDepth, 'colorType' => $colorType, ); - } + /** * Read a chunk, checking to make sure its not too big. * @@ -422,6 +421,7 @@ class PNGMetadataExtractor { throw new Exception( __METHOD__ . ': Chunk size of ' . $size . ' too big. Max size is: ' . self::MAX_CHUNK_SIZE ); } + return fread( $fh, $size ); } }