view e2gallerypro/e2upload/Backend/Assets/getid3/module.graphic.bmp.php @ 11:ed6ee381b8fd judyates

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