annotate e2gallerypro/e2upload/Backend/Assets/getid3/module.graphic.bmp.php @ 25:6a3d04638a89 judyates

mailto links.
author Robert McIntyre <rlm@mit.edu>
date Sat, 19 Jul 2014 14:35:52 -0400
parents 3f6b44aa6b35
children
rev   line source
rlm@3 1 <?php
rlm@3 2 // +----------------------------------------------------------------------+
rlm@3 3 // | PHP version 5 |
rlm@3 4 // +----------------------------------------------------------------------+
rlm@3 5 // | Copyright (c) 2002-2006 James Heinrich, Allan Hansen |
rlm@3 6 // +----------------------------------------------------------------------+
rlm@3 7 // | This source file is subject to version 2 of the GPL license, |
rlm@3 8 // | that is bundled with this package in the file license.txt and is |
rlm@3 9 // | available through the world-wide-web at the following url: |
rlm@3 10 // | http://www.gnu.org/copyleft/gpl.html |
rlm@3 11 // +----------------------------------------------------------------------+
rlm@3 12 // | getID3() - http://getid3.sourceforge.net or http://www.getid3.org |
rlm@3 13 // +----------------------------------------------------------------------+
rlm@3 14 // | Authors: James Heinrich <infoØgetid3*org> |
rlm@3 15 // | Allan Hansen <ahØartemis*dk> |
rlm@3 16 // +----------------------------------------------------------------------+
rlm@3 17 // | module.graphic.bmp.php |
rlm@3 18 // | Module for analyzing BMP graphic files. |
rlm@3 19 // | dependencies: NONE |
rlm@3 20 // +----------------------------------------------------------------------+
rlm@3 21 //
rlm@3 22 // $Id: module.graphic.bmp.php,v 1.4 2006/11/02 10:48:02 ah Exp $
rlm@3 23
rlm@3 24
rlm@3 25
rlm@3 26 class getid3_bmp extends getid3_handler
rlm@3 27 {
rlm@3 28
rlm@3 29
rlm@3 30 public function Analyze() {
rlm@3 31
rlm@3 32 $getid3 = $this->getid3;
rlm@3 33
rlm@3 34 // BITMAPFILEHEADER [14 bytes] - http://msdn.microsoft.com/library/en-us/gdi/bitmaps_62uq.asp
rlm@3 35 // all versions
rlm@3 36 // WORD bfType;
rlm@3 37 // DWORD bfSize;
rlm@3 38 // WORD bfReserved1;
rlm@3 39 // WORD bfReserved2;
rlm@3 40 // DWORD bfOffBits;
rlm@3 41
rlm@3 42 // shortcuts
rlm@3 43 $getid3->info['bmp']['header']['raw'] = array ();
rlm@3 44 $info_bmp = &$getid3->info['bmp'];
rlm@3 45 $info_bmp_header = &$info_bmp['header'];
rlm@3 46 $info_bmp_header_raw = &$info_bmp_header['raw'];
rlm@3 47
rlm@3 48 fseek($getid3->fp, $getid3->info['avdataoffset'], SEEK_SET);
rlm@3 49 $bmp_header = fread($getid3->fp, 14 + 40);
rlm@3 50
rlm@3 51 // Magic bytes
rlm@3 52 $info_bmp_header_raw['identifier'] = 'BM';
rlm@3 53
rlm@3 54 getid3_lib::ReadSequence('LittleEndian2Int', $info_bmp_header_raw, $bmp_header, 2,
rlm@3 55 array (
rlm@3 56 'filesize' => 4,
rlm@3 57 'reserved1' => 2,
rlm@3 58 'reserved2' => 2,
rlm@3 59 'data_offset' => 4,
rlm@3 60 'header_size' => 4
rlm@3 61 )
rlm@3 62 );
rlm@3 63
rlm@3 64 // Check if the hardcoded-to-1 "planes" is at offset 22 or 26
rlm@3 65 $planes22 = getid3_lib::LittleEndian2Int(substr($bmp_header, 22, 2));
rlm@3 66 $planes26 = getid3_lib::LittleEndian2Int(substr($bmp_header, 26, 2));
rlm@3 67 if (($planes22 == 1) && ($planes26 != 1)) {
rlm@3 68 $info_bmp['type_os'] = 'OS/2';
rlm@3 69 $info_bmp['type_version'] = 1;
rlm@3 70 }
rlm@3 71 elseif (($planes26 == 1) && ($planes22 != 1)) {
rlm@3 72 $info_bmp['type_os'] = 'Windows';
rlm@3 73 $info_bmp['type_version'] = 1;
rlm@3 74 }
rlm@3 75 elseif ($info_bmp_header_raw['header_size'] == 12) {
rlm@3 76 $info_bmp['type_os'] = 'OS/2';
rlm@3 77 $info_bmp['type_version'] = 1;
rlm@3 78 }
rlm@3 79 elseif ($info_bmp_header_raw['header_size'] == 40) {
rlm@3 80 $info_bmp['type_os'] = 'Windows';
rlm@3 81 $info_bmp['type_version'] = 1;
rlm@3 82 }
rlm@3 83 elseif ($info_bmp_header_raw['header_size'] == 84) {
rlm@3 84 $info_bmp['type_os'] = 'Windows';
rlm@3 85 $info_bmp['type_version'] = 4;
rlm@3 86 }
rlm@3 87 elseif ($info_bmp_header_raw['header_size'] == 100) {
rlm@3 88 $info_bmp['type_os'] = 'Windows';
rlm@3 89 $info_bmp['type_version'] = 5;
rlm@3 90 }
rlm@3 91 else {
rlm@3 92 throw new getid3_exception('Unknown BMP subtype (or not a BMP file)');
rlm@3 93 }
rlm@3 94
rlm@3 95 $getid3->info['fileformat'] = 'bmp';
rlm@3 96 $getid3->info['video']['dataformat'] = 'bmp';
rlm@3 97 $getid3->info['video']['lossless'] = true;
rlm@3 98 $getid3->info['video']['pixel_aspect_ratio'] = (float)1;
rlm@3 99
rlm@3 100 if ($info_bmp['type_os'] == 'OS/2') {
rlm@3 101
rlm@3 102 // OS/2-format BMP
rlm@3 103 // http://netghost.narod.ru/gff/graphics/summary/os2bmp.htm
rlm@3 104
rlm@3 105 // DWORD Size; /* Size of this structure in bytes */
rlm@3 106 // DWORD Width; /* Bitmap width in pixels */
rlm@3 107 // DWORD Height; /* Bitmap height in pixel */
rlm@3 108 // WORD NumPlanes; /* Number of bit planes (color depth) */
rlm@3 109 // WORD BitsPerPixel; /* Number of bits per pixel per plane */
rlm@3 110
rlm@3 111 getid3_lib::ReadSequence('LittleEndian2Int', $info_bmp_header_raw, $bmp_header, 18,
rlm@3 112 array (
rlm@3 113 'width' => 2,
rlm@3 114 'height' => 2,
rlm@3 115 'planes' => 2,
rlm@3 116 'bits_per_pixel' => 2
rlm@3 117 )
rlm@3 118 );
rlm@3 119
rlm@3 120 $getid3->info['video']['resolution_x'] = $info_bmp_header_raw['width'];
rlm@3 121 $getid3->info['video']['resolution_y'] = $info_bmp_header_raw['height'];
rlm@3 122 $getid3->info['video']['codec'] = 'BI_RGB '.$info_bmp_header_raw['bits_per_pixel'].'-bit';
rlm@3 123 $getid3->info['video']['bits_per_sample'] = $info_bmp_header_raw['bits_per_pixel'];
rlm@3 124
rlm@3 125 if ($info_bmp['type_version'] >= 2) {
rlm@3 126 // DWORD Compression; /* Bitmap compression scheme */
rlm@3 127 // DWORD ImageDataSize; /* Size of bitmap data in bytes */
rlm@3 128 // DWORD XResolution; /* X resolution of display device */
rlm@3 129 // DWORD YResolution; /* Y resolution of display device */
rlm@3 130 // DWORD ColorsUsed; /* Number of color table indices used */
rlm@3 131 // DWORD ColorsImportant; /* Number of important color indices */
rlm@3 132 // WORD Units; /* Type of units used to measure resolution */
rlm@3 133 // WORD Reserved; /* Pad structure to 4-byte boundary */
rlm@3 134 // WORD Recording; /* Recording algorithm */
rlm@3 135 // WORD Rendering; /* Halftoning algorithm used */
rlm@3 136 // DWORD Size1; /* Reserved for halftoning algorithm use */
rlm@3 137 // DWORD Size2; /* Reserved for halftoning algorithm use */
rlm@3 138 // DWORD ColorEncoding; /* Color model used in bitmap */
rlm@3 139 // DWORD Identifier; /* Reserved for application use */
rlm@3 140
rlm@3 141 getid3_lib::ReadSequence('LittleEndian2Int', $info_bmp_header_raw, $bmp_header, 26,
rlm@3 142 array (
rlm@3 143 'compression' => 4,
rlm@3 144 'bmp_data_size' => 4,
rlm@3 145 'resolution_h' => 4,
rlm@3 146 'resolution_v' => 4,
rlm@3 147 'colors_used' => 4,
rlm@3 148 'colors_important' => 4,
rlm@3 149 'resolution_units' => 2,
rlm@3 150 'reserved1' => 2,
rlm@3 151 'recording' => 2,
rlm@3 152 'rendering' => 2,
rlm@3 153 'size1' => 4,
rlm@3 154 'size2' => 4,
rlm@3 155 'color_encoding' => 4,
rlm@3 156 'identifier' => 4
rlm@3 157 )
rlm@3 158 );
rlm@3 159
rlm@3 160 $info_bmp_header['compression'] = getid3_bmp::BMPcompressionOS2Lookup($info_bmp_header_raw['compression']);
rlm@3 161 $getid3->info['video']['codec'] = $info_bmp_header['compression'].' '.$info_bmp_header_raw['bits_per_pixel'].'-bit';
rlm@3 162 }
rlm@3 163
rlm@3 164 return true;
rlm@3 165 }
rlm@3 166
rlm@3 167
rlm@3 168 if ($info_bmp['type_os'] == 'Windows') {
rlm@3 169
rlm@3 170 // Windows-format BMP
rlm@3 171
rlm@3 172 // BITMAPINFOHEADER - [40 bytes] http://msdn.microsoft.com/library/en-us/gdi/bitmaps_1rw2.asp
rlm@3 173 // all versions
rlm@3 174 // DWORD biSize;
rlm@3 175 // LONG biWidth;
rlm@3 176 // LONG biHeight;
rlm@3 177 // WORD biPlanes;
rlm@3 178 // WORD biBitCount;
rlm@3 179 // DWORD biCompression;
rlm@3 180 // DWORD biSizeImage;
rlm@3 181 // LONG biXPelsPerMeter;
rlm@3 182 // LONG biYPelsPerMeter;
rlm@3 183 // DWORD biClrUsed;
rlm@3 184 // DWORD biClrImportant;
rlm@3 185
rlm@3 186 getid3_lib::ReadSequence('LittleEndian2Int', $info_bmp_header_raw, $bmp_header, 18,
rlm@3 187 array (
rlm@3 188 'width' => -4, //signed
rlm@3 189 'height' => -4, //signed
rlm@3 190 'planes' => 2,
rlm@3 191 'bits_per_pixel' => 2,
rlm@3 192 'compression' => 4,
rlm@3 193 'bmp_data_size' => 4,
rlm@3 194 'resolution_h' => -4, //signed
rlm@3 195 'resolution_v' => -4, //signed
rlm@3 196 'colors_used' => 4,
rlm@3 197 'colors_important' => 4
rlm@3 198 )
rlm@3 199 );
rlm@3 200 foreach (array ('width', 'height', 'resolution_h', 'resolution_v') as $key) {
rlm@3 201 $info_bmp_header_raw[$key] = getid3_lib::LittleEndian2Int($info_bmp_header_raw[$key], true);
rlm@3 202 }
rlm@3 203
rlm@3 204 $info_bmp_header['compression'] = getid3_bmp::BMPcompressionWindowsLookup($info_bmp_header_raw['compression']);
rlm@3 205 $getid3->info['video']['resolution_x'] = $info_bmp_header_raw['width'];
rlm@3 206 $getid3->info['video']['resolution_y'] = $info_bmp_header_raw['height'];
rlm@3 207 $getid3->info['video']['codec'] = $info_bmp_header['compression'].' '.$info_bmp_header_raw['bits_per_pixel'].'-bit';
rlm@3 208 $getid3->info['video']['bits_per_sample'] = $info_bmp_header_raw['bits_per_pixel'];
rlm@3 209
rlm@3 210 // should only be v4+, but BMPs with type_version==1 and BI_BITFIELDS compression have been seen
rlm@3 211 if (($info_bmp['type_version'] >= 4) || ($info_bmp_header_raw['compression'] == 3)) {
rlm@3 212
rlm@3 213
rlm@3 214 $bmp_header .= fread($getid3->fp, 44);
rlm@3 215
rlm@3 216 // BITMAPV4HEADER - [44 bytes] - http://msdn.microsoft.com/library/en-us/gdi/bitmaps_2k1e.asp
rlm@3 217 // Win95+, WinNT4.0+
rlm@3 218 // DWORD bV4RedMask;
rlm@3 219 // DWORD bV4GreenMask;
rlm@3 220 // DWORD bV4BlueMask;
rlm@3 221 // DWORD bV4AlphaMask;
rlm@3 222 // DWORD bV4CSType;
rlm@3 223 // CIEXYZTRIPLE bV4Endpoints;
rlm@3 224 // DWORD bV4GammaRed;
rlm@3 225 // DWORD bV4GammaGreen;
rlm@3 226 // DWORD bV4GammaBlue;
rlm@3 227
rlm@3 228 getid3_lib::ReadSequence('LittleEndian2Int', $info_bmp_header_raw, $bmp_header, 54,
rlm@3 229 array (
rlm@3 230 'red_mask' => 4,
rlm@3 231 'green_mask' => 4,
rlm@3 232 'blue_mask' => 4,
rlm@3 233 'alpha_mask' => 4,
rlm@3 234 'cs_type' => 4,
rlm@3 235 'ciexyz_red' => -4, //string
rlm@3 236 'ciexyz_green' => -4, //string
rlm@3 237 'ciexyz_blue' => -4, //string
rlm@3 238 'gamma_red' => 4,
rlm@3 239 'gamma_green' => 4,
rlm@3 240 'gamma_blue' => 4
rlm@3 241 )
rlm@3 242 );
rlm@3 243
rlm@3 244 $info_bmp_header['ciexyz_red'] = getid3_bmp::FixedPoint2_30(strrev($info_bmp_header_raw['ciexyz_red']));
rlm@3 245 $info_bmp_header['ciexyz_green'] = getid3_bmp::FixedPoint2_30(strrev($info_bmp_header_raw['ciexyz_green']));
rlm@3 246 $info_bmp_header['ciexyz_blue'] = getid3_bmp::FixedPoint2_30(strrev($info_bmp_header_raw['ciexyz_blue']));
rlm@3 247
rlm@3 248
rlm@3 249 if ($info_bmp['type_version'] >= 5) {
rlm@3 250 $bmp_header .= fread($getid3->fp, 16);
rlm@3 251
rlm@3 252 // BITMAPV5HEADER - [16 bytes] - http://msdn.microsoft.com/library/en-us/gdi/bitmaps_7c36.asp
rlm@3 253 // Win98+, Win2000+
rlm@3 254 // DWORD bV5Intent;
rlm@3 255 // DWORD bV5ProfileData;
rlm@3 256 // DWORD bV5ProfileSize;
rlm@3 257 // DWORD bV5Reserved;
rlm@3 258
rlm@3 259 getid3_lib::ReadSequence('LittleEndian2Int', $info_bmp_header_raw, $bmp_header, 98,
rlm@3 260 array (
rlm@3 261 'intent' => 4,
rlm@3 262 'profile_data_offset' => 4,
rlm@3 263 'profile_data_size' => 4,
rlm@3 264 'reserved3' => 4
rlm@3 265 )
rlm@3 266 );
rlm@3 267
rlm@3 268 }
rlm@3 269 }
rlm@3 270
rlm@3 271 return true;
rlm@3 272 }
rlm@3 273
rlm@3 274
rlm@3 275 throw new getid3_exception('Unknown BMP format in header.');
rlm@3 276
rlm@3 277 }
rlm@3 278
rlm@3 279
rlm@3 280
rlm@3 281 public static function BMPcompressionWindowsLookup($compression_id) {
rlm@3 282
rlm@3 283 static $lookup = array (
rlm@3 284 0 => 'BI_RGB',
rlm@3 285 1 => 'BI_RLE8',
rlm@3 286 2 => 'BI_RLE4',
rlm@3 287 3 => 'BI_BITFIELDS',
rlm@3 288 4 => 'BI_JPEG',
rlm@3 289 5 => 'BI_PNG'
rlm@3 290 );
rlm@3 291 return (isset($lookup[$compression_id]) ? $lookup[$compression_id] : 'invalid');
rlm@3 292 }
rlm@3 293
rlm@3 294
rlm@3 295
rlm@3 296 public static function BMPcompressionOS2Lookup($compression_id) {
rlm@3 297
rlm@3 298 static $lookup = array (
rlm@3 299 0 => 'BI_RGB',
rlm@3 300 1 => 'BI_RLE8',
rlm@3 301 2 => 'BI_RLE4',
rlm@3 302 3 => 'Huffman 1D',
rlm@3 303 4 => 'BI_RLE24',
rlm@3 304 );
rlm@3 305 return (isset($lookup[$compression_id]) ? $lookup[$compression_id] : 'invalid');
rlm@3 306 }
rlm@3 307
rlm@3 308
rlm@3 309 public static function FixedPoint2_30($raw_data) {
rlm@3 310
rlm@3 311 $binary_string = getid3_lib::BigEndian2Bin($raw_data);
rlm@3 312 return bindec(substr($binary_string, 0, 2)) + (float)(bindec(substr($binary_string, 2, 30)) / 1073741824); // pow(2, 30) = 1073741824
rlm@3 313 }
rlm@3 314
rlm@3 315
rlm@3 316 }
rlm@3 317
rlm@3 318
rlm@3 319 ?>