mirror of
https://github.com/Yetangitu/ampache
synced 2025-10-05 10:49:37 +02:00
319 lines
No EOL
14 KiB
PHP
319 lines
No EOL
14 KiB
PHP
<?php
|
|
// +----------------------------------------------------------------------+
|
|
// | PHP version 5 |
|
|
// +----------------------------------------------------------------------+
|
|
// | Copyright (c) 2002-2006 James Heinrich, Allan Hansen |
|
|
// +----------------------------------------------------------------------+
|
|
// | This source file is subject to version 2 of the GPL license, |
|
|
// | that is bundled with this package in the file license.txt and is |
|
|
// | available through the world-wide-web at the following url: |
|
|
// | http://www.gnu.org/copyleft/gpl.html |
|
|
// +----------------------------------------------------------------------+
|
|
// | getID3() - http://getid3.sourceforge.net or http://www.getid3.org |
|
|
// +----------------------------------------------------------------------+
|
|
// | Authors: James Heinrich <infoØgetid3*org> |
|
|
// | Allan Hansen <ahØartemis*dk> |
|
|
// +----------------------------------------------------------------------+
|
|
// | module.graphic.bmp.php |
|
|
// | Module for analyzing BMP graphic files. |
|
|
// | dependencies: NONE |
|
|
// +----------------------------------------------------------------------+
|
|
//
|
|
// $Id: module.graphic.bmp.php,v 1.4 2006/11/02 10:48:02 ah Exp $
|
|
|
|
|
|
|
|
class getid3_bmp extends getid3_handler
|
|
{
|
|
|
|
|
|
public function Analyze() {
|
|
|
|
$getid3 = $this->getid3;
|
|
|
|
// BITMAPFILEHEADER [14 bytes] - http://msdn.microsoft.com/library/en-us/gdi/bitmaps_62uq.asp
|
|
// all versions
|
|
// WORD bfType;
|
|
// DWORD bfSize;
|
|
// WORD bfReserved1;
|
|
// WORD bfReserved2;
|
|
// DWORD bfOffBits;
|
|
|
|
// shortcuts
|
|
$getid3->info['bmp']['header']['raw'] = array ();
|
|
$info_bmp = &$getid3->info['bmp'];
|
|
$info_bmp_header = &$info_bmp['header'];
|
|
$info_bmp_header_raw = &$info_bmp_header['raw'];
|
|
|
|
fseek($getid3->fp, $getid3->info['avdataoffset'], SEEK_SET);
|
|
$bmp_header = fread($getid3->fp, 14 + 40);
|
|
|
|
// Magic bytes
|
|
$info_bmp_header_raw['identifier'] = 'BM';
|
|
|
|
getid3_lib::ReadSequence('LittleEndian2Int', $info_bmp_header_raw, $bmp_header, 2,
|
|
array (
|
|
'filesize' => 4,
|
|
'reserved1' => 2,
|
|
'reserved2' => 2,
|
|
'data_offset' => 4,
|
|
'header_size' => 4
|
|
)
|
|
);
|
|
|
|
// Check if the hardcoded-to-1 "planes" is at offset 22 or 26
|
|
$planes22 = getid3_lib::LittleEndian2Int(substr($bmp_header, 22, 2));
|
|
$planes26 = getid3_lib::LittleEndian2Int(substr($bmp_header, 26, 2));
|
|
if (($planes22 == 1) && ($planes26 != 1)) {
|
|
$info_bmp['type_os'] = 'OS/2';
|
|
$info_bmp['type_version'] = 1;
|
|
}
|
|
elseif (($planes26 == 1) && ($planes22 != 1)) {
|
|
$info_bmp['type_os'] = 'Windows';
|
|
$info_bmp['type_version'] = 1;
|
|
}
|
|
elseif ($info_bmp_header_raw['header_size'] == 12) {
|
|
$info_bmp['type_os'] = 'OS/2';
|
|
$info_bmp['type_version'] = 1;
|
|
}
|
|
elseif ($info_bmp_header_raw['header_size'] == 40) {
|
|
$info_bmp['type_os'] = 'Windows';
|
|
$info_bmp['type_version'] = 1;
|
|
}
|
|
elseif ($info_bmp_header_raw['header_size'] == 84) {
|
|
$info_bmp['type_os'] = 'Windows';
|
|
$info_bmp['type_version'] = 4;
|
|
}
|
|
elseif ($info_bmp_header_raw['header_size'] == 100) {
|
|
$info_bmp['type_os'] = 'Windows';
|
|
$info_bmp['type_version'] = 5;
|
|
}
|
|
else {
|
|
throw new getid3_exception('Unknown BMP subtype (or not a BMP file)');
|
|
}
|
|
|
|
$getid3->info['fileformat'] = 'bmp';
|
|
$getid3->info['video']['dataformat'] = 'bmp';
|
|
$getid3->info['video']['lossless'] = true;
|
|
$getid3->info['video']['pixel_aspect_ratio'] = (float)1;
|
|
|
|
if ($info_bmp['type_os'] == 'OS/2') {
|
|
|
|
// OS/2-format BMP
|
|
// http://netghost.narod.ru/gff/graphics/summary/os2bmp.htm
|
|
|
|
// DWORD Size; /* Size of this structure in bytes */
|
|
// DWORD Width; /* Bitmap width in pixels */
|
|
// DWORD Height; /* Bitmap height in pixel */
|
|
// WORD NumPlanes; /* Number of bit planes (color depth) */
|
|
// WORD BitsPerPixel; /* Number of bits per pixel per plane */
|
|
|
|
getid3_lib::ReadSequence('LittleEndian2Int', $info_bmp_header_raw, $bmp_header, 18,
|
|
array (
|
|
'width' => 2,
|
|
'height' => 2,
|
|
'planes' => 2,
|
|
'bits_per_pixel' => 2
|
|
)
|
|
);
|
|
|
|
$getid3->info['video']['resolution_x'] = $info_bmp_header_raw['width'];
|
|
$getid3->info['video']['resolution_y'] = $info_bmp_header_raw['height'];
|
|
$getid3->info['video']['codec'] = 'BI_RGB '.$info_bmp_header_raw['bits_per_pixel'].'-bit';
|
|
$getid3->info['video']['bits_per_sample'] = $info_bmp_header_raw['bits_per_pixel'];
|
|
|
|
if ($info_bmp['type_version'] >= 2) {
|
|
// DWORD Compression; /* Bitmap compression scheme */
|
|
// DWORD ImageDataSize; /* Size of bitmap data in bytes */
|
|
// DWORD XResolution; /* X resolution of display device */
|
|
// DWORD YResolution; /* Y resolution of display device */
|
|
// DWORD ColorsUsed; /* Number of color table indices used */
|
|
// DWORD ColorsImportant; /* Number of important color indices */
|
|
// WORD Units; /* Type of units used to measure resolution */
|
|
// WORD Reserved; /* Pad structure to 4-byte boundary */
|
|
// WORD Recording; /* Recording algorithm */
|
|
// WORD Rendering; /* Halftoning algorithm used */
|
|
// DWORD Size1; /* Reserved for halftoning algorithm use */
|
|
// DWORD Size2; /* Reserved for halftoning algorithm use */
|
|
// DWORD ColorEncoding; /* Color model used in bitmap */
|
|
// DWORD Identifier; /* Reserved for application use */
|
|
|
|
getid3_lib::ReadSequence('LittleEndian2Int', $info_bmp_header_raw, $bmp_header, 26,
|
|
array (
|
|
'compression' => 4,
|
|
'bmp_data_size' => 4,
|
|
'resolution_h' => 4,
|
|
'resolution_v' => 4,
|
|
'colors_used' => 4,
|
|
'colors_important' => 4,
|
|
'resolution_units' => 2,
|
|
'reserved1' => 2,
|
|
'recording' => 2,
|
|
'rendering' => 2,
|
|
'size1' => 4,
|
|
'size2' => 4,
|
|
'color_encoding' => 4,
|
|
'identifier' => 4
|
|
)
|
|
);
|
|
|
|
$info_bmp_header['compression'] = getid3_bmp::BMPcompressionOS2Lookup($info_bmp_header_raw['compression']);
|
|
$getid3->info['video']['codec'] = $info_bmp_header['compression'].' '.$info_bmp_header_raw['bits_per_pixel'].'-bit';
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
if ($info_bmp['type_os'] == 'Windows') {
|
|
|
|
// Windows-format BMP
|
|
|
|
// BITMAPINFOHEADER - [40 bytes] http://msdn.microsoft.com/library/en-us/gdi/bitmaps_1rw2.asp
|
|
// all versions
|
|
// DWORD biSize;
|
|
// LONG biWidth;
|
|
// LONG biHeight;
|
|
// WORD biPlanes;
|
|
// WORD biBitCount;
|
|
// DWORD biCompression;
|
|
// DWORD biSizeImage;
|
|
// LONG biXPelsPerMeter;
|
|
// LONG biYPelsPerMeter;
|
|
// DWORD biClrUsed;
|
|
// DWORD biClrImportant;
|
|
|
|
getid3_lib::ReadSequence('LittleEndian2Int', $info_bmp_header_raw, $bmp_header, 18,
|
|
array (
|
|
'width' => -4, //signed
|
|
'height' => -4, //signed
|
|
'planes' => 2,
|
|
'bits_per_pixel' => 2,
|
|
'compression' => 4,
|
|
'bmp_data_size' => 4,
|
|
'resolution_h' => -4, //signed
|
|
'resolution_v' => -4, //signed
|
|
'colors_used' => 4,
|
|
'colors_important' => 4
|
|
)
|
|
);
|
|
foreach (array ('width', 'height', 'resolution_h', 'resolution_v') as $key) {
|
|
$info_bmp_header_raw[$key] = getid3_lib::LittleEndian2Int($info_bmp_header_raw[$key], true);
|
|
}
|
|
|
|
$info_bmp_header['compression'] = getid3_bmp::BMPcompressionWindowsLookup($info_bmp_header_raw['compression']);
|
|
$getid3->info['video']['resolution_x'] = $info_bmp_header_raw['width'];
|
|
$getid3->info['video']['resolution_y'] = $info_bmp_header_raw['height'];
|
|
$getid3->info['video']['codec'] = $info_bmp_header['compression'].' '.$info_bmp_header_raw['bits_per_pixel'].'-bit';
|
|
$getid3->info['video']['bits_per_sample'] = $info_bmp_header_raw['bits_per_pixel'];
|
|
|
|
// should only be v4+, but BMPs with type_version==1 and BI_BITFIELDS compression have been seen
|
|
if (($info_bmp['type_version'] >= 4) || ($info_bmp_header_raw['compression'] == 3)) {
|
|
|
|
|
|
$bmp_header .= fread($getid3->fp, 44);
|
|
|
|
// BITMAPV4HEADER - [44 bytes] - http://msdn.microsoft.com/library/en-us/gdi/bitmaps_2k1e.asp
|
|
// Win95+, WinNT4.0+
|
|
// DWORD bV4RedMask;
|
|
// DWORD bV4GreenMask;
|
|
// DWORD bV4BlueMask;
|
|
// DWORD bV4AlphaMask;
|
|
// DWORD bV4CSType;
|
|
// CIEXYZTRIPLE bV4Endpoints;
|
|
// DWORD bV4GammaRed;
|
|
// DWORD bV4GammaGreen;
|
|
// DWORD bV4GammaBlue;
|
|
|
|
getid3_lib::ReadSequence('LittleEndian2Int', $info_bmp_header_raw, $bmp_header, 54,
|
|
array (
|
|
'red_mask' => 4,
|
|
'green_mask' => 4,
|
|
'blue_mask' => 4,
|
|
'alpha_mask' => 4,
|
|
'cs_type' => 4,
|
|
'ciexyz_red' => -4, //string
|
|
'ciexyz_green' => -4, //string
|
|
'ciexyz_blue' => -4, //string
|
|
'gamma_red' => 4,
|
|
'gamma_green' => 4,
|
|
'gamma_blue' => 4
|
|
)
|
|
);
|
|
|
|
$info_bmp_header['ciexyz_red'] = getid3_bmp::FixedPoint2_30(strrev($info_bmp_header_raw['ciexyz_red']));
|
|
$info_bmp_header['ciexyz_green'] = getid3_bmp::FixedPoint2_30(strrev($info_bmp_header_raw['ciexyz_green']));
|
|
$info_bmp_header['ciexyz_blue'] = getid3_bmp::FixedPoint2_30(strrev($info_bmp_header_raw['ciexyz_blue']));
|
|
|
|
|
|
if ($info_bmp['type_version'] >= 5) {
|
|
$bmp_header .= fread($getid3->fp, 16);
|
|
|
|
// BITMAPV5HEADER - [16 bytes] - http://msdn.microsoft.com/library/en-us/gdi/bitmaps_7c36.asp
|
|
// Win98+, Win2000+
|
|
// DWORD bV5Intent;
|
|
// DWORD bV5ProfileData;
|
|
// DWORD bV5ProfileSize;
|
|
// DWORD bV5Reserved;
|
|
|
|
getid3_lib::ReadSequence('LittleEndian2Int', $info_bmp_header_raw, $bmp_header, 98,
|
|
array (
|
|
'intent' => 4,
|
|
'profile_data_offset' => 4,
|
|
'profile_data_size' => 4,
|
|
'reserved3' => 4
|
|
)
|
|
);
|
|
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
throw new getid3_exception('Unknown BMP format in header.');
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function BMPcompressionWindowsLookup($compression_id) {
|
|
|
|
static $lookup = array (
|
|
0 => 'BI_RGB',
|
|
1 => 'BI_RLE8',
|
|
2 => 'BI_RLE4',
|
|
3 => 'BI_BITFIELDS',
|
|
4 => 'BI_JPEG',
|
|
5 => 'BI_PNG'
|
|
);
|
|
return (isset($lookup[$compression_id]) ? $lookup[$compression_id] : 'invalid');
|
|
}
|
|
|
|
|
|
|
|
public static function BMPcompressionOS2Lookup($compression_id) {
|
|
|
|
static $lookup = array (
|
|
0 => 'BI_RGB',
|
|
1 => 'BI_RLE8',
|
|
2 => 'BI_RLE4',
|
|
3 => 'Huffman 1D',
|
|
4 => 'BI_RLE24',
|
|
);
|
|
return (isset($lookup[$compression_id]) ? $lookup[$compression_id] : 'invalid');
|
|
}
|
|
|
|
|
|
public static function FixedPoint2_30($raw_data) {
|
|
|
|
$binary_string = getid3_lib::BigEndian2Bin($raw_data);
|
|
return bindec(substr($binary_string, 0, 2)) + (float)(bindec(substr($binary_string, 2, 30)) / 1073741824); // pow(2, 30) = 1073741824
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
?>
|