Issues (1210)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

thumbs/phpthumb.bmp.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/////////////////////////////////////////////////////////////////
3
/// getID3() by James Heinrich <[email protected]>               //
4
//  available at http://getid3.sourceforge.net                 //
5
//            or http://www.getid3.org                         //
6
/////////////////////////////////////////////////////////////////
7
// See readme.txt for more details                             //
8
/////////////////////////////////////////////////////////////////
9
//                                                             //
10
// module.graphic.bmp.php                                      //
11
// module for analyzing BMP Image files                        //
12
// dependencies: NONE                                          //
13
//                                                            ///
14
/////////////////////////////////////////////////////////////////
15
//                                                             //
16
// Modified for use in phpThumb() - James Heinrich 2004.07.27  //
17
//                                                             //
18
/////////////////////////////////////////////////////////////////
19
20
/**
21
 * Class phpthumb_bmp
22
 */
23
class phpthumb_bmp
24
{
25
26
    // removed for XOOPS
27
    //function phpthumb_bmp() {
28
    //  return true;
29
    //}
30
31
    /**
32
     * @param                $BMPdata
33
     * @param  bool          $truecolor
34
     * @return bool|resource
35
     */
36
    public function phpthumb_bmp2gd(&$BMPdata, $truecolor = true)
37
    {
38
        $ThisFileInfo = array();
39
        if ($this->getid3_bmp($BMPdata, $ThisFileInfo, true, true)) {
40
            $gd = $this->PlotPixelsGD($ThisFileInfo['bmp'], $truecolor);
41
42
            return $gd;
43
        }
44
45
        return false;
46
    }
47
48
    /**
49
     * @param                $filename
50
     * @param  bool          $truecolor
51
     * @return bool|resource
52
     */
53
    public function phpthumb_bmpfile2gd($filename, $truecolor = true)
54
    {
55
        if ($fp = @fopen($filename, 'rb')) {
56
            $BMPdata = fread($fp, filesize($filename));
57
            fclose($fp);
58
59
            return $this->phpthumb_bmp2gd($BMPdata, $truecolor);
60
        }
61
62
        return false;
63
    }
64
65
    /**
66
     * @param $gd_image
67
     * @return string
68
     */
69
    public function GD2BMPstring(&$gd_image)
70
    {
71
        $imageX = imagesx($gd_image);
72
        $imageY = imagesy($gd_image);
73
74
        $BMP = '';
75
        for ($y = ($imageY - 1); $y >= 0; $y--) {
76
            $thisline = '';
77
            for ($x = 0; $x < $imageX; $x++) {
78
                $argb     = phpthumb_functions::GetPixelColor($gd_image, $x, $y);
79
                $thisline .= chr($argb['blue']) . chr($argb['green']) . chr($argb['red']);
80
            }
81
            while (strlen($thisline) % 4) {
82
                $thisline .= "\x00";
83
            }
84
            $BMP .= $thisline;
85
        }
86
87
        $bmpSize = strlen($BMP) + 14 + 40;
88
        // BITMAPFILEHEADER [14 bytes] - http://msdn.microsoft.com/library/en-us/gdi/bitmaps_62uq.asp
89
        $BITMAPFILEHEADER = 'BM';                                                           // WORD    bfType;
90
        $BITMAPFILEHEADER .= phpthumb_functions::LittleEndian2String($bmpSize, 4); // DWORD   bfSize;
91
        $BITMAPFILEHEADER .= phpthumb_functions::LittleEndian2String(0, 2); // WORD    bfReserved1;
92
        $BITMAPFILEHEADER .= phpthumb_functions::LittleEndian2String(0, 2); // WORD    bfReserved2;
93
        $BITMAPFILEHEADER .= phpthumb_functions::LittleEndian2String(54, 4); // DWORD   bfOffBits;
94
95
        // BITMAPINFOHEADER - [40 bytes] http://msdn.microsoft.com/library/en-us/gdi/bitmaps_1rw2.asp
96
        $BITMAPINFOHEADER = phpthumb_functions::LittleEndian2String(40, 4); // DWORD  biSize;
97
        $BITMAPINFOHEADER .= phpthumb_functions::LittleEndian2String($imageX, 4); // LONG   biWidth;
98
        $BITMAPINFOHEADER .= phpthumb_functions::LittleEndian2String($imageY, 4); // LONG   biHeight;
99
        $BITMAPINFOHEADER .= phpthumb_functions::LittleEndian2String(1, 2); // WORD   biPlanes;
100
        $BITMAPINFOHEADER .= phpthumb_functions::LittleEndian2String(24, 2); // WORD   biBitCount;
101
        $BITMAPINFOHEADER .= phpthumb_functions::LittleEndian2String(0, 4); // DWORD  biCompression;
102
        $BITMAPINFOHEADER .= phpthumb_functions::LittleEndian2String(0, 4); // DWORD  biSizeImage;
103
        $BITMAPINFOHEADER .= phpthumb_functions::LittleEndian2String(2835, 4); // LONG   biXPelsPerMeter;
104
        $BITMAPINFOHEADER .= phpthumb_functions::LittleEndian2String(2835, 4); // LONG   biYPelsPerMeter;
105
        $BITMAPINFOHEADER .= phpthumb_functions::LittleEndian2String(0, 4); // DWORD  biClrUsed;
106
        $BITMAPINFOHEADER .= phpthumb_functions::LittleEndian2String(0, 4); // DWORD  biClrImportant;
107
108
        return $BITMAPFILEHEADER . $BITMAPINFOHEADER . $BMP;
109
    }
110
111
    /**
112
     * @param       $BMPdata
113
     * @param       $ThisFileInfo
114
     * @param  bool $ExtractPalette
115
     * @param  bool $ExtractData
116
     * @return bool
117
     */
118
    public function getid3_bmp(&$BMPdata, &$ThisFileInfo, $ExtractPalette = false, $ExtractData = false)
119
    {
120
121
        // shortcuts
122
        $ThisFileInfo['bmp']['header']['raw'] = array();
123
        $thisfile_bmp                         = &$ThisFileInfo['bmp'];
124
        $thisfile_bmp_header                  = &$thisfile_bmp['header'];
125
        $thisfile_bmp_header_raw              = &$thisfile_bmp_header['raw'];
126
127
        // BITMAPFILEHEADER [14 bytes] - http://msdn.microsoft.com/library/en-us/gdi/bitmaps_62uq.asp
128
        // all versions
129
        // WORD    bfType;
130
        // DWORD   bfSize;
131
        // WORD    bfReserved1;
132
        // WORD    bfReserved2;
133
        // DWORD   bfOffBits;
134
135
        $offset        = 0;
136
        $overalloffset = 0;
137
        $BMPheader     = substr($BMPdata, $overalloffset, 14 + 40);
138
        $overalloffset += (14 + 40);
139
140
        $thisfile_bmp_header_raw['identifier'] = substr($BMPheader, $offset, 2);
141
        $offset                                += 2;
142
143
        if ($thisfile_bmp_header_raw['identifier'] != 'BM') {
144
            $ThisFileInfo['error'][] = 'Expecting "BM" at offset ' . (int)(@$ThisFileInfo['avdataoffset']) . ', found "' . $thisfile_bmp_header_raw['identifier'] . '"';
145
            unset($ThisFileInfo['fileformat']);
146
            unset($ThisFileInfo['bmp']);
147
148
            return false;
149
        }
150
151
        $thisfile_bmp_header_raw['filesize']    = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
152
        $offset                                 += 4;
153
        $thisfile_bmp_header_raw['reserved1']   = $this->LittleEndian2Int(substr($BMPheader, $offset, 2));
154
        $offset                                 += 2;
155
        $thisfile_bmp_header_raw['reserved2']   = $this->LittleEndian2Int(substr($BMPheader, $offset, 2));
156
        $offset                                 += 2;
157
        $thisfile_bmp_header_raw['data_offset'] = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
158
        $offset                                 += 4;
159
        $thisfile_bmp_header_raw['header_size'] = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
160
        $offset                                 += 4;
161
162
        // check if the hardcoded-to-1 "planes" is at offset 22 or 26
163
        $planes22 = $this->LittleEndian2Int(substr($BMPheader, 22, 2));
164
        $planes26 = $this->LittleEndian2Int(substr($BMPheader, 26, 2));
165
        if (($planes22 == 1) && ($planes26 != 1)) {
166
            $thisfile_bmp['type_os']      = 'OS/2';
167
            $thisfile_bmp['type_version'] = 1;
168
        } elseif (($planes26 == 1) && ($planes22 != 1)) {
169
            $thisfile_bmp['type_os']      = 'Windows';
170
            $thisfile_bmp['type_version'] = 1;
171 View Code Duplication
        } elseif ($thisfile_bmp_header_raw['header_size'] == 12) {
172
            $thisfile_bmp['type_os']      = 'OS/2';
173
            $thisfile_bmp['type_version'] = 1;
174
        } elseif ($thisfile_bmp_header_raw['header_size'] == 40) {
175
            $thisfile_bmp['type_os']      = 'Windows';
176
            $thisfile_bmp['type_version'] = 1;
177 View Code Duplication
        } elseif ($thisfile_bmp_header_raw['header_size'] == 84) {
178
            $thisfile_bmp['type_os']      = 'Windows';
179
            $thisfile_bmp['type_version'] = 4;
180
        } elseif ($thisfile_bmp_header_raw['header_size'] == 100) {
181
            $thisfile_bmp['type_os']      = 'Windows';
182
            $thisfile_bmp['type_version'] = 5;
183
        } else {
184
            $ThisFileInfo['error'][] = 'Unknown BMP subtype (or not a BMP file)';
185
            unset($ThisFileInfo['fileformat']);
186
            unset($ThisFileInfo['bmp']);
187
188
            return false;
189
        }
190
191
        $ThisFileInfo['fileformat']                  = 'bmp';
192
        $ThisFileInfo['video']['dataformat']         = 'bmp';
193
        $ThisFileInfo['video']['lossless']           = true;
194
        $ThisFileInfo['video']['pixel_aspect_ratio'] = (float)1;
195
196
        if ($thisfile_bmp['type_os'] == 'OS/2') {
197
198
            // OS/2-format BMP
199
            // http://netghost.narod.ru/gff/graphics/summary/os2bmp.htm
200
201
            // DWORD  Size;             /* Size of this structure in bytes */
202
            // DWORD  Width;            /* Bitmap width in pixels */
203
            // DWORD  Height;           /* Bitmap height in pixel */
204
            // WORD   NumPlanes;        /* Number of bit planes (color depth) */
205
            // WORD   BitsPerPixel;     /* Number of bits per pixel per plane */
206
207
            $thisfile_bmp_header_raw['width']          = $this->LittleEndian2Int(substr($BMPheader, $offset, 2));
208
            $offset                                    += 2;
209
            $thisfile_bmp_header_raw['height']         = $this->LittleEndian2Int(substr($BMPheader, $offset, 2));
210
            $offset                                    += 2;
211
            $thisfile_bmp_header_raw['planes']         = $this->LittleEndian2Int(substr($BMPheader, $offset, 2));
212
            $offset                                    += 2;
213
            $thisfile_bmp_header_raw['bits_per_pixel'] = $this->LittleEndian2Int(substr($BMPheader, $offset, 2));
214
            $offset                                    += 2;
215
216
            $ThisFileInfo['video']['resolution_x']    = $thisfile_bmp_header_raw['width'];
217
            $ThisFileInfo['video']['resolution_y']    = $thisfile_bmp_header_raw['height'];
218
            $ThisFileInfo['video']['codec']           = 'BI_RGB ' . $thisfile_bmp_header_raw['bits_per_pixel'] . '-bit';
219
            $ThisFileInfo['video']['bits_per_sample'] = $thisfile_bmp_header_raw['bits_per_pixel'];
220
221
            if ($thisfile_bmp['type_version'] >= 2) {
222
                // DWORD  Compression;      /* Bitmap compression scheme */
223
                // DWORD  ImageDataSize;    /* Size of bitmap data in bytes */
224
                // DWORD  XResolution;      /* X resolution of display device */
225
                // DWORD  YResolution;      /* Y resolution of display device */
226
                // DWORD  ColorsUsed;       /* Number of color table indices used */
227
                // DWORD  ColorsImportant;  /* Number of important color indices */
228
                // WORD   Units;            /* Type of units used to measure resolution */
229
                // WORD   Reserved;         /* Pad structure to 4-byte boundary */
230
                // WORD   Recording;        /* Recording algorithm */
231
                // WORD   Rendering;        /* Halftoning algorithm used */
232
                // DWORD  Size1;            /* Reserved for halftoning algorithm use */
233
                // DWORD  Size2;            /* Reserved for halftoning algorithm use */
234
                // DWORD  ColorEncoding;    /* Color model used in bitmap */
235
                // DWORD  Identifier;       /* Reserved for application use */
236
237
                $thisfile_bmp_header_raw['compression']      = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
238
                $offset                                      += 4;
239
                $thisfile_bmp_header_raw['bmp_data_size']    = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
240
                $offset                                      += 4;
241
                $thisfile_bmp_header_raw['resolution_h']     = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
242
                $offset                                      += 4;
243
                $thisfile_bmp_header_raw['resolution_v']     = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
244
                $offset                                      += 4;
245
                $thisfile_bmp_header_raw['colors_used']      = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
246
                $offset                                      += 4;
247
                $thisfile_bmp_header_raw['colors_important'] = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
248
                $offset                                      += 4;
249
                $thisfile_bmp_header_raw['resolution_units'] = $this->LittleEndian2Int(substr($BMPheader, $offset, 2));
250
                $offset                                      += 2;
251
                $thisfile_bmp_header_raw['reserved1']        = $this->LittleEndian2Int(substr($BMPheader, $offset, 2));
252
                $offset                                      += 2;
253
                $thisfile_bmp_header_raw['recording']        = $this->LittleEndian2Int(substr($BMPheader, $offset, 2));
254
                $offset                                      += 2;
255
                $thisfile_bmp_header_raw['rendering']        = $this->LittleEndian2Int(substr($BMPheader, $offset, 2));
256
                $offset                                      += 2;
257
                $thisfile_bmp_header_raw['size1']            = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
258
                $offset                                      += 4;
259
                $thisfile_bmp_header_raw['size2']            = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
260
                $offset                                      += 4;
261
                $thisfile_bmp_header_raw['color_encoding']   = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
262
                $offset                                      += 4;
263
                $thisfile_bmp_header_raw['identifier']       = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
264
                $offset                                      += 4;
265
266
                $thisfile_bmp_header['compression'] = $this->BMPcompressionOS2Lookup($thisfile_bmp_header_raw['compression']);
267
268
                $ThisFileInfo['video']['codec'] = $thisfile_bmp_header['compression'] . ' ' . $thisfile_bmp_header_raw['bits_per_pixel'] . '-bit';
269
            }
270
        } elseif ($thisfile_bmp['type_os'] == 'Windows') {
271
272
            // Windows-format BMP
273
274
            // BITMAPINFOHEADER - [40 bytes] http://msdn.microsoft.com/library/en-us/gdi/bitmaps_1rw2.asp
275
            // all versions
276
            // DWORD  biSize;
277
            // LONG   biWidth;
278
            // LONG   biHeight;
279
            // WORD   biPlanes;
280
            // WORD   biBitCount;
281
            // DWORD  biCompression;
282
            // DWORD  biSizeImage;
283
            // LONG   biXPelsPerMeter;
284
            // LONG   biYPelsPerMeter;
285
            // DWORD  biClrUsed;
286
            // DWORD  biClrImportant;
287
288
            $thisfile_bmp_header_raw['width']            = $this->LittleEndian2Int(substr($BMPheader, $offset, 4), true);
289
            $offset                                      += 4;
290
            $thisfile_bmp_header_raw['height']           = $this->LittleEndian2Int(substr($BMPheader, $offset, 4), true);
291
            $offset                                      += 4;
292
            $thisfile_bmp_header_raw['planes']           = $this->LittleEndian2Int(substr($BMPheader, $offset, 2));
293
            $offset                                      += 2;
294
            $thisfile_bmp_header_raw['bits_per_pixel']   = $this->LittleEndian2Int(substr($BMPheader, $offset, 2));
295
            $offset                                      += 2;
296
            $thisfile_bmp_header_raw['compression']      = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
297
            $offset                                      += 4;
298
            $thisfile_bmp_header_raw['bmp_data_size']    = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
299
            $offset                                      += 4;
300
            $thisfile_bmp_header_raw['resolution_h']     = $this->LittleEndian2Int(substr($BMPheader, $offset, 4), true);
301
            $offset                                      += 4;
302
            $thisfile_bmp_header_raw['resolution_v']     = $this->LittleEndian2Int(substr($BMPheader, $offset, 4), true);
303
            $offset                                      += 4;
304
            $thisfile_bmp_header_raw['colors_used']      = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
305
            $offset                                      += 4;
306
            $thisfile_bmp_header_raw['colors_important'] = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
307
            $offset                                      += 4;
308
309
            $thisfile_bmp_header['compression']       = $this->BMPcompressionWindowsLookup($thisfile_bmp_header_raw['compression']);
310
            $ThisFileInfo['video']['resolution_x']    = $thisfile_bmp_header_raw['width'];
311
            $ThisFileInfo['video']['resolution_y']    = $thisfile_bmp_header_raw['height'];
312
            $ThisFileInfo['video']['codec']           = $thisfile_bmp_header['compression'] . ' ' . $thisfile_bmp_header_raw['bits_per_pixel'] . '-bit';
313
            $ThisFileInfo['video']['bits_per_sample'] = $thisfile_bmp_header_raw['bits_per_pixel'];
314
315
            if (($thisfile_bmp['type_version'] >= 4) || ($thisfile_bmp_header_raw['compression'] == 3)) {
316
                // should only be v4+, but BMPs with type_version==1 and BI_BITFIELDS compression have been seen
317
                $BMPheader     .= substr($BMPdata, $overalloffset, 44);
318
                $overalloffset += 44;
319
320
                // BITMAPV4HEADER - [44 bytes] - http://msdn.microsoft.com/library/en-us/gdi/bitmaps_2k1e.asp
321
                // Win95+, WinNT4.0+
322
                // DWORD        bV4RedMask;
323
                // DWORD        bV4GreenMask;
324
                // DWORD        bV4BlueMask;
325
                // DWORD        bV4AlphaMask;
326
                // DWORD        bV4CSType;
327
                // CIEXYZTRIPLE bV4Endpoints;
328
                // DWORD        bV4GammaRed;
329
                // DWORD        bV4GammaGreen;
330
                // DWORD        bV4GammaBlue;
331
                $thisfile_bmp_header_raw['red_mask']     = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
332
                $offset                                  += 4;
333
                $thisfile_bmp_header_raw['green_mask']   = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
334
                $offset                                  += 4;
335
                $thisfile_bmp_header_raw['blue_mask']    = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
336
                $offset                                  += 4;
337
                $thisfile_bmp_header_raw['alpha_mask']   = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
338
                $offset                                  += 4;
339
                $thisfile_bmp_header_raw['cs_type']      = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
340
                $offset                                  += 4;
341
                $thisfile_bmp_header_raw['ciexyz_red']   = substr($BMPheader, $offset, 4);
342
                $offset                                  += 4;
343
                $thisfile_bmp_header_raw['ciexyz_green'] = substr($BMPheader, $offset, 4);
344
                $offset                                  += 4;
345
                $thisfile_bmp_header_raw['ciexyz_blue']  = substr($BMPheader, $offset, 4);
346
                $offset                                  += 4;
347
                $thisfile_bmp_header_raw['gamma_red']    = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
348
                $offset                                  += 4;
349
                $thisfile_bmp_header_raw['gamma_green']  = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
350
                $offset                                  += 4;
351
                $thisfile_bmp_header_raw['gamma_blue']   = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
352
                $offset                                  += 4;
353
354
                $thisfile_bmp_header['ciexyz_red']   = $this->FixedPoint2_30(strrev($thisfile_bmp_header_raw['ciexyz_red']));
355
                $thisfile_bmp_header['ciexyz_green'] = $this->FixedPoint2_30(strrev($thisfile_bmp_header_raw['ciexyz_green']));
356
                $thisfile_bmp_header['ciexyz_blue']  = $this->FixedPoint2_30(strrev($thisfile_bmp_header_raw['ciexyz_blue']));
357
            }
358
359
            if ($thisfile_bmp['type_version'] >= 5) {
360
                $BMPheader     .= substr($BMPdata, $overalloffset, 16);
361
                $overalloffset += 16;
362
363
                // BITMAPV5HEADER - [16 bytes] - http://msdn.microsoft.com/library/en-us/gdi/bitmaps_7c36.asp
364
                // Win98+, Win2000+
365
                // DWORD        bV5Intent;
366
                // DWORD        bV5ProfileData;
367
                // DWORD        bV5ProfileSize;
368
                // DWORD        bV5Reserved;
369
                $thisfile_bmp_header_raw['intent']              = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
370
                $offset                                         += 4;
371
                $thisfile_bmp_header_raw['profile_data_offset'] = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
372
                $offset                                         += 4;
373
                $thisfile_bmp_header_raw['profile_data_size']   = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
374
                $offset                                         += 4;
375
                $thisfile_bmp_header_raw['reserved3']           = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
376
                $offset                                         += 4;
377
            }
378
        } else {
379
            $ThisFileInfo['error'][] = 'Unknown BMP format in header.';
380
381
            return false;
382
        }
383
384
        if ($ExtractPalette || $ExtractData) {
385
            $PaletteEntries = 0;
386
            if ($thisfile_bmp_header_raw['bits_per_pixel'] < 16) {
387
                $PaletteEntries = pow(2, $thisfile_bmp_header_raw['bits_per_pixel']);
388
            } elseif (isset($thisfile_bmp_header_raw['colors_used']) && ($thisfile_bmp_header_raw['colors_used'] > 0)
389
                      && ($thisfile_bmp_header_raw['colors_used'] <= 256)
390
            ) {
391
                $PaletteEntries = $thisfile_bmp_header_raw['colors_used'];
392
            }
393
            if ($PaletteEntries > 0) {
394
                $BMPpalette    = substr($BMPdata, $overalloffset, 4 * $PaletteEntries);
395
                $overalloffset += 4 * $PaletteEntries;
396
397
                $paletteoffset = 0;
398
                for ($i = 0; $i < $PaletteEntries; $i++) {
399
                    // RGBQUAD          - http://msdn.microsoft.com/library/en-us/gdi/bitmaps_5f8y.asp
400
                    // BYTE    rgbBlue;
401
                    // BYTE    rgbGreen;
402
                    // BYTE    rgbRed;
403
                    // BYTE    rgbReserved;
404
                    $blue  = $this->LittleEndian2Int(substr($BMPpalette, $paletteoffset++, 1));
405
                    $green = $this->LittleEndian2Int(substr($BMPpalette, $paletteoffset++, 1));
406
                    $red   = $this->LittleEndian2Int(substr($BMPpalette, $paletteoffset++, 1));
407
                    if (($thisfile_bmp['type_os'] == 'OS/2') && ($thisfile_bmp['type_version'] == 1)) {
408
                        // no padding byte
409
                    } else {
410
                        $paletteoffset++; // padding byte
411
                    }
412
                    $thisfile_bmp['palette'][$i] = (($red << 16) | ($green << 8) | $blue);
413
                }
414
            }
415
        }
416
417
        if ($ExtractData) {
418
            $RowByteLength = ceil(($thisfile_bmp_header_raw['width'] * ($thisfile_bmp_header_raw['bits_per_pixel'] / 8)) / 4) * 4; // round up to nearest DWORD boundry
419
420
            $BMPpixelData  = substr($BMPdata, $thisfile_bmp_header_raw['data_offset'], $thisfile_bmp_header_raw['height'] * $RowByteLength);
421
            $overalloffset = $thisfile_bmp_header_raw['data_offset'] + ($thisfile_bmp_header_raw['height'] * $RowByteLength);
422
423
            $pixeldataoffset = 0;
424
            switch (@$thisfile_bmp_header_raw['compression']) {
425
426
                case 0: // BI_RGB
427
                    switch ($thisfile_bmp_header_raw['bits_per_pixel']) {
428 View Code Duplication
                        case 1:
429
                            for ($row = ($thisfile_bmp_header_raw['height'] - 1); $row >= 0; $row--) {
430
                                for ($col = 0; $col < $thisfile_bmp_header_raw['width']; $col = $col) {
431
                                    $paletteindexbyte = ord($BMPpixelData{$pixeldataoffset++});
432
                                    for ($i = 7; $i >= 0; $i--) {
433
                                        $paletteindex                     = ($paletteindexbyte & (0x01 << $i)) >> $i;
434
                                        $thisfile_bmp['data'][$row][$col] = $thisfile_bmp['palette'][$paletteindex];
435
                                        $col++;
436
                                    }
437
                                }
438
                                while (($pixeldataoffset % 4) != 0) {
439
                                    // lines are padded to nearest DWORD
440
                                    $pixeldataoffset++;
441
                                }
442
                            }
443
                            break;
444
445 View Code Duplication
                        case 4:
446
                            for ($row = ($thisfile_bmp_header_raw['height'] - 1); $row >= 0; $row--) {
447
                                for ($col = 0; $col < $thisfile_bmp_header_raw['width']; $col = $col) {
448
                                    $paletteindexbyte = ord($BMPpixelData{$pixeldataoffset++});
449
                                    for ($i = 1; $i >= 0; $i--) {
450
                                        $paletteindex                     = ($paletteindexbyte & (0x0F << (4 * $i))) >> (4 * $i);
451
                                        $thisfile_bmp['data'][$row][$col] = $thisfile_bmp['palette'][$paletteindex];
452
                                        $col++;
453
                                    }
454
                                }
455
                                while (($pixeldataoffset % 4) != 0) {
456
                                    // lines are padded to nearest DWORD
457
                                    $pixeldataoffset++;
458
                                }
459
                            }
460
                            break;
461
462
                        case 8:
463
                            for ($row = ($thisfile_bmp_header_raw['height'] - 1); $row >= 0; $row--) {
464
                                for ($col = 0; $col < $thisfile_bmp_header_raw['width']; $col++) {
465
                                    $paletteindex                     = ord($BMPpixelData{$pixeldataoffset++});
466
                                    $thisfile_bmp['data'][$row][$col] = $thisfile_bmp['palette'][$paletteindex];
467
                                }
468
                                while (($pixeldataoffset % 4) != 0) {
469
                                    // lines are padded to nearest DWORD
470
                                    $pixeldataoffset++;
471
                                }
472
                            }
473
                            break;
474
475
                        case 24:
476
                            for ($row = ($thisfile_bmp_header_raw['height'] - 1); $row >= 0; $row--) {
477
                                for ($col = 0; $col < $thisfile_bmp_header_raw['width']; $col++) {
478
                                    $thisfile_bmp['data'][$row][$col] = (ord($BMPpixelData{$pixeldataoffset + 2}) << 16)
479
                                                                        | (ord($BMPpixelData{$pixeldataoffset + 1}) << 8)
480
                                                                        | ord($BMPpixelData{$pixeldataoffset});
481
                                    $pixeldataoffset                  += 3;
482
                                }
483
                                while (($pixeldataoffset % 4) != 0) {
484
                                    // lines are padded to nearest DWORD
485
                                    $pixeldataoffset++;
486
                                }
487
                            }
488
                            break;
489
490
                        case 32:
491
                            for ($row = ($thisfile_bmp_header_raw['height'] - 1); $row >= 0; $row--) {
492
                                for ($col = 0; $col < $thisfile_bmp_header_raw['width']; $col++) {
493
                                    $thisfile_bmp['data'][$row][$col] = (ord($BMPpixelData{$pixeldataoffset + 3}) << 24)
494
                                                                        | (ord($BMPpixelData{$pixeldataoffset + 2}) << 16)
495
                                                                        | (ord($BMPpixelData{$pixeldataoffset + 1}) << 8)
496
                                                                        | ord($BMPpixelData{$pixeldataoffset});
497
                                    $pixeldataoffset                  += 4;
498
                                }
499
                                while (($pixeldataoffset % 4) != 0) {
500
                                    // lines are padded to nearest DWORD
501
                                    $pixeldataoffset++;
502
                                }
503
                            }
504
                            break;
505
506
                        case 16:
507
                            // ?
508
                            break;
509
510
                        default:
511
                            $ThisFileInfo['error'][] = 'Unknown bits-per-pixel value (' . $thisfile_bmp_header_raw['bits_per_pixel'] . ') - cannot read pixel data';
512
                            break;
513
                    }
514
                    break;
515
516
                case 1: // BI_RLE8 - http://msdn.microsoft.com/library/en-us/gdi/bitmaps_6x0u.asp
517
                    switch ($thisfile_bmp_header_raw['bits_per_pixel']) {
518
                        case 8:
519
                            $pixelcounter = 0;
520
                            while ($pixeldataoffset < strlen($BMPpixelData)) {
521
                                $firstbyte  = $this->LittleEndian2Int(substr($BMPpixelData, $pixeldataoffset++, 1));
522
                                $secondbyte = $this->LittleEndian2Int(substr($BMPpixelData, $pixeldataoffset++, 1));
523
                                if ($firstbyte == 0) {
524
525
                                    // escaped/absolute mode - the first byte of the pair can be set to zero to
526
                                    // indicate an escape character that denotes the end of a line, the end of
527
                                    // a bitmap, or a delta, depending on the value of the second byte.
528
                                    switch ($secondbyte) {
529
                                        case 0:
530
                                            // end of line
531
                                            // no need for special processing, just ignore
532
                                            break;
533
534
                                        case 1:
535
                                            // end of bitmap
536
                                            $pixeldataoffset = strlen($BMPpixelData); // force to exit loop just in case
537
                                            break;
538
539 View Code Duplication
                                        case 2:
540
                                            // delta - The 2 bytes following the escape contain unsigned values
541
                                            // indicating the horizontal and vertical offsets of the next pixel
542
                                            // from the current position.
543
                                            $colincrement = $this->LittleEndian2Int(substr($BMPpixelData, $pixeldataoffset++, 1));
544
                                            $rowincrement = $this->LittleEndian2Int(substr($BMPpixelData, $pixeldataoffset++, 1));
545
                                            $col          = ($pixelcounter % $thisfile_bmp_header_raw['width']) + $colincrement;
546
                                            $row          = ($thisfile_bmp_header_raw['height'] - 1 - (($pixelcounter - $col) / $thisfile_bmp_header_raw['width'])) - $rowincrement;
547
                                            $pixelcounter = ($row * $thisfile_bmp_header_raw['width']) + $col;
548
                                            break;
549
550
                                        default:
551
                                            // In absolute mode, the first byte is zero and the second byte is a
552
                                            // value in the range 03H through FFH. The second byte represents the
553
                                            // number of bytes that follow, each of which contains the color index
554
                                            // of a single pixel. Each run must be aligned on a word boundary.
555
                                            for ($i = 0; $i < $secondbyte; $i++) {
556
                                                $paletteindex                     = $this->LittleEndian2Int(substr($BMPpixelData, $pixeldataoffset++, 1));
557
                                                $col                              = $pixelcounter % $thisfile_bmp_header_raw['width'];
558
                                                $row                              = $thisfile_bmp_header_raw['height'] - 1 - (($pixelcounter - $col) / $thisfile_bmp_header_raw['width']);
559
                                                $thisfile_bmp['data'][$row][$col] = $thisfile_bmp['palette'][$paletteindex];
560
                                                $pixelcounter++;
561
                                            }
562
                                            while (($pixeldataoffset % 2) != 0) {
563
                                                // Each run must be aligned on a word boundary.
564
                                                $pixeldataoffset++;
565
                                            }
566
                                            break;
567
                                    }
568
                                } else {
569
570
                                    // encoded mode - the first byte specifies the number of consecutive pixels
571
                                    // to be drawn using the color index contained in the second byte.
572 View Code Duplication
                                    for ($i = 0; $i < $firstbyte; $i++) {
573
                                        $col                              = $pixelcounter % $thisfile_bmp_header_raw['width'];
574
                                        $row                              = $thisfile_bmp_header_raw['height'] - 1 - (($pixelcounter - $col) / $thisfile_bmp_header_raw['width']);
575
                                        $thisfile_bmp['data'][$row][$col] = $thisfile_bmp['palette'][$secondbyte];
576
                                        $pixelcounter++;
577
                                    }
578
                                }
579
                            }
580
                            break;
581
582
                        default:
583
                            $ThisFileInfo['error'][] = 'Unknown bits-per-pixel value (' . $thisfile_bmp_header_raw['bits_per_pixel'] . ') - cannot read pixel data';
584
                            break;
585
                    }
586
                    break;
587
588
                case 2: // BI_RLE4 - http://msdn.microsoft.com/library/en-us/gdi/bitmaps_6x0u.asp
589
                    switch ($thisfile_bmp_header_raw['bits_per_pixel']) {
590
                        case 4:
591
                            $pixelcounter = 0;
592
                            while ($pixeldataoffset < strlen($BMPpixelData)) {
593
                                $firstbyte  = $this->LittleEndian2Int(substr($BMPpixelData, $pixeldataoffset++, 1));
594
                                $secondbyte = $this->LittleEndian2Int(substr($BMPpixelData, $pixeldataoffset++, 1));
595
                                if ($firstbyte == 0) {
596
597
                                    // escaped/absolute mode - the first byte of the pair can be set to zero to
598
                                    // indicate an escape character that denotes the end of a line, the end of
599
                                    // a bitmap, or a delta, depending on the value of the second byte.
600
                                    switch ($secondbyte) {
601
                                        case 0:
602
                                            // end of line
603
                                            // no need for special processing, just ignore
604
                                            break;
605
606
                                        case 1:
607
                                            // end of bitmap
608
                                            $pixeldataoffset = strlen($BMPpixelData); // force to exit loop just in case
609
                                            break;
610
611 View Code Duplication
                                        case 2:
612
                                            // delta - The 2 bytes following the escape contain unsigned values
613
                                            // indicating the horizontal and vertical offsets of the next pixel
614
                                            // from the current position.
615
                                            $colincrement = $this->LittleEndian2Int(substr($BMPpixelData, $pixeldataoffset++, 1));
616
                                            $rowincrement = $this->LittleEndian2Int(substr($BMPpixelData, $pixeldataoffset++, 1));
617
                                            $col          = ($pixelcounter % $thisfile_bmp_header_raw['width']) + $colincrement;
618
                                            $row          = ($thisfile_bmp_header_raw['height'] - 1 - (($pixelcounter - $col) / $thisfile_bmp_header_raw['width'])) - $rowincrement;
619
                                            $pixelcounter = ($row * $thisfile_bmp_header_raw['width']) + $col;
620
                                            break;
621
622
                                        default:
623
                                            // In absolute mode, the first byte is zero. The second byte contains the number
624
                                            // of color indexes that follow. Subsequent bytes contain color indexes in their
625
                                            // high- and low-order 4 bits, one color index for each pixel. In absolute mode,
626
                                            // each run must be aligned on a word boundary.
627
                                            unset($paletteindexes);
628
                                            for ($i = 0; $i < ceil($secondbyte / 2); $i++) {
629
                                                $paletteindexbyte = $this->LittleEndian2Int(substr($BMPpixelData, $pixeldataoffset++, 1));
630
                                                $paletteindexes[] = ($paletteindexbyte & 0xF0) >> 4;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$paletteindexes was never initialized. Although not strictly required by PHP, it is generally a good practice to add $paletteindexes = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
631
                                                $paletteindexes[] = ($paletteindexbyte & 0x0F);
632
                                            }
633
                                            while (($pixeldataoffset % 2) != 0) {
634
                                                // Each run must be aligned on a word boundary.
635
                                                $pixeldataoffset++;
636
                                            }
637
638
                                            foreach ($paletteindexes as $dummy => $paletteindex) {
639
                                                $col                              = $pixelcounter % $thisfile_bmp_header_raw['width'];
640
                                                $row                              = $thisfile_bmp_header_raw['height'] - 1 - (($pixelcounter - $col) / $thisfile_bmp_header_raw['width']);
641
                                                $thisfile_bmp['data'][$row][$col] = $thisfile_bmp['palette'][$paletteindex];
642
                                                $pixelcounter++;
643
                                            }
644
                                            break;
645
                                    }
646
                                } else {
647
648
                                    // encoded mode - the first byte of the pair contains the number of pixels to be
649
                                    // drawn using the color indexes in the second byte. The second byte contains two
650
                                    // color indexes, one in its high-order 4 bits and one in its low-order 4 bits.
651
                                    // The first of the pixels is drawn using the color specified by the high-order
652
                                    // 4 bits, the second is drawn using the color in the low-order 4 bits, the third
653
                                    // is drawn using the color in the high-order 4 bits, and so on, until all the
654
                                    // pixels specified by the first byte have been drawn.
655
                                    $paletteindexes[0] = ($secondbyte & 0xF0) >> 4;
656
                                    $paletteindexes[1] = ($secondbyte & 0x0F);
657 View Code Duplication
                                    for ($i = 0; $i < $firstbyte; $i++) {
658
                                        $col                              = $pixelcounter % $thisfile_bmp_header_raw['width'];
659
                                        $row                              = $thisfile_bmp_header_raw['height'] - 1 - (($pixelcounter - $col) / $thisfile_bmp_header_raw['width']);
660
                                        $thisfile_bmp['data'][$row][$col] = $thisfile_bmp['palette'][$paletteindexes[$i % 2]];
661
                                        $pixelcounter++;
662
                                    }
663
                                }
664
                            }
665
                            break;
666
667
                        default:
668
                            $ThisFileInfo['error'][] = 'Unknown bits-per-pixel value (' . $thisfile_bmp_header_raw['bits_per_pixel'] . ') - cannot read pixel data';
669
                            break;
670
                    }
671
                    break;
672
673
                case 3: // BI_BITFIELDS
674
                    switch ($thisfile_bmp_header_raw['bits_per_pixel']) {
675
                        case 16:
676
                        case 32:
677
                            $redshift   = 0;
678
                            $greenshift = 0;
679
                            $blueshift  = 0;
680
                            if (!$thisfile_bmp_header_raw['red_mask'] || !$thisfile_bmp_header_raw['green_mask']
681
                                || !$thisfile_bmp_header_raw['blue_mask']
682
                            ) {
683
                                $ThisFileInfo['error'][] = 'missing $thisfile_bmp_header_raw[(red|green|blue)_mask]';
684
685
                                return false;
686
                            }
687
                            while ((($thisfile_bmp_header_raw['red_mask'] >> $redshift) & 0x01) == 0) {
688
                                $redshift++;
689
                            }
690
                            while ((($thisfile_bmp_header_raw['green_mask'] >> $greenshift) & 0x01) == 0) {
691
                                $greenshift++;
692
                            }
693
                            while ((($thisfile_bmp_header_raw['blue_mask'] >> $blueshift) & 0x01) == 0) {
694
                                $blueshift++;
695
                            }
696
                            for ($row = ($thisfile_bmp_header_raw['height'] - 1); $row >= 0; $row--) {
697
                                for ($col = 0; $col < $thisfile_bmp_header_raw['width']; $col++) {
698
                                    $pixelvalue      = $this->LittleEndian2Int(substr($BMPpixelData, $pixeldataoffset, $thisfile_bmp_header_raw['bits_per_pixel'] / 8));
699
                                    $pixeldataoffset += $thisfile_bmp_header_raw['bits_per_pixel'] / 8;
700
701
                                    $red                              = (int)round(((($pixelvalue & $thisfile_bmp_header_raw['red_mask']) >> $redshift) / ($thisfile_bmp_header_raw['red_mask']
702
                                                                                                                                                           >> $redshift)) * 255);
703
                                    $green                            = (int)round(((($pixelvalue & $thisfile_bmp_header_raw['green_mask']) >> $greenshift) / ($thisfile_bmp_header_raw['green_mask']
704
                                                                                                                                                               >> $greenshift)) * 255);
705
                                    $blue                             = (int)round(((($pixelvalue & $thisfile_bmp_header_raw['blue_mask']) >> $blueshift) / ($thisfile_bmp_header_raw['blue_mask']
706
                                                                                                                                                             >> $blueshift)) * 255);
707
                                    $thisfile_bmp['data'][$row][$col] = (($red << 16) | ($green << 8) | $blue);
708
                                }
709
                                while (($pixeldataoffset % 4) != 0) {
710
                                    // lines are padded to nearest DWORD
711
                                    $pixeldataoffset++;
712
                                }
713
                            }
714
                            break;
715
716
                        default:
717
                            $ThisFileInfo['error'][] = 'Unknown bits-per-pixel value (' . $thisfile_bmp_header_raw['bits_per_pixel'] . ') - cannot read pixel data';
718
                            break;
719
                    }
720
                    break;
721
722
                default: // unhandled compression type
723
                    $ThisFileInfo['error'][] = 'Unknown/unhandled compression type value (' . $thisfile_bmp_header_raw['compression'] . ') - cannot decompress pixel data';
724
                    break;
725
            }
726
        }
727
728
        return true;
729
    }
730
731
    /**
732
     * @param $color
733
     * @return array
734
     */
735
    public function IntColor2RGB($color)
736
    {
737
        $red   = ($color & 0x00FF0000) >> 16;
738
        $green = ($color & 0x0000FF00) >> 8;
739
        $blue  = ($color & 0x000000FF);
740
741
        return array($red, $green, $blue);
742
    }
743
744
    /**
745
     * @param                $BMPdata
746
     * @param  bool          $truecolor
747
     * @return bool|resource
748
     */
749
    public function PlotPixelsGD(&$BMPdata, $truecolor = true)
750
    {
751
        $imagewidth  = $BMPdata['header']['raw']['width'];
752
        $imageheight = $BMPdata['header']['raw']['height'];
753
754
        if ($truecolor) {
755
            $gd = @imagecreatetruecolor($imagewidth, $imageheight);
756
        } else {
757
            $gd = @imagecreate($imagewidth, $imageheight);
758
            if (!empty($BMPdata['palette'])) {
759
                // create GD palette from BMP palette
760
                foreach ($BMPdata['palette'] as $dummy => $color) {
761
                    list($r, $g, $b) = $this->IntColor2RGB($color);
762
                    imagecolorallocate($gd, $r, $g, $b);
763
                }
764
            } else {
765
                // create 216-color websafe palette
766
                for ($r = 0x00; $r <= 0xFF; $r += 0x33) {
767
                    for ($g = 0x00; $g <= 0xFF; $g += 0x33) {
768
                        for ($b = 0x00; $b <= 0xFF; $b += 0x33) {
769
                            imagecolorallocate($gd, $r, $g, $b);
770
                        }
771
                    }
772
                }
773
            }
774
        }
775
        if (!is_resource($gd)) {
776
            return false;
777
        }
778
779
        foreach ($BMPdata['data'] as $row => $colarray) {
780
            if (!phpthumb_functions::FunctionIsDisabled('set_time_limit')) {
781
                set_time_limit(30);
782
            }
783
            foreach ($colarray as $col => $color) {
784
                list($red, $green, $blue) = $this->IntColor2RGB($color);
785
                if ($truecolor) {
786
                    $pixelcolor = imagecolorallocate($gd, $red, $green, $blue);
787
                } else {
788
                    $pixelcolor = imagecolorclosest($gd, $red, $green, $blue);
789
                }
790
                imagesetpixel($gd, $col, $row, $pixelcolor);
791
            }
792
        }
793
794
        return $gd;
795
    }
796
797
    /**
798
     * @param $BMPinfo
799
     * @return bool
800
     */
801
    public function PlotBMP(&$BMPinfo)
802
    {
803
        $starttime = time();
804
        if (!isset($BMPinfo['bmp']['data']) || !is_array($BMPinfo['bmp']['data'])) {
805
            echo 'ERROR: no pixel data<br>';
806
807
            return false;
808
        }
809
        if (!phpthumb_functions::FunctionIsDisabled('set_time_limit')) {
810
            set_time_limit((int)round($BMPinfo['resolution_x'] * $BMPinfo['resolution_y'] / 10000));
811
        }
812
        $im = $this->PlotPixelsGD($BMPinfo['bmp']);
813
        if (headers_sent()) {
814
            echo 'plotted ' . ($BMPinfo['resolution_x'] * $BMPinfo['resolution_y']) . ' pixels in ' . (time() - $starttime) . ' seconds<br>';
815
            imagedestroy($im);
816
            exit;
817
        } else {
818
            header('Content-Type: image/png');
819
            imagepng($im);
820
            imagedestroy($im);
821
822
            return true;
823
        }
824
825
        return false;
826
    }
827
828
    /**
829
     * @param $compressionid
830
     * @return mixed|string
831
     */
832 View Code Duplication
    public function BMPcompressionWindowsLookup($compressionid)
833
    {
834
        static $BMPcompressionWindowsLookup = array(
835
            0 => 'BI_RGB',
836
            1 => 'BI_RLE8',
837
            2 => 'BI_RLE4',
838
            3 => 'BI_BITFIELDS',
839
            4 => 'BI_JPEG',
840
            5 => 'BI_PNG'
841
        );
842
843
        return (isset($BMPcompressionWindowsLookup[$compressionid]) ? $BMPcompressionWindowsLookup[$compressionid] : 'invalid');
844
    }
845
846
    /**
847
     * @param $compressionid
848
     * @return mixed|string
849
     */
850 View Code Duplication
    public function BMPcompressionOS2Lookup($compressionid)
851
    {
852
        static $BMPcompressionOS2Lookup = array(
853
            0 => 'BI_RGB',
854
            1 => 'BI_RLE8',
855
            2 => 'BI_RLE4',
856
            3 => 'Huffman 1D',
857
            4 => 'BI_RLE24'
858
        );
859
860
        return (isset($BMPcompressionOS2Lookup[$compressionid]) ? $BMPcompressionOS2Lookup[$compressionid] : 'invalid');
861
    }
862
863
    // from getid3.lib.php
864
865
    /**
866
     * @param $floatnumber
867
     * @return float|int
868
     */
869
    public function trunc($floatnumber)
870
    {
871
        // truncates a floating-point number at the decimal point
872
        // returns int (if possible, otherwise float)
873
        if ($floatnumber >= 1) {
874
            $truncatednumber = floor($floatnumber);
875
        } elseif ($floatnumber <= -1) {
876
            $truncatednumber = ceil($floatnumber);
877
        } else {
878
            $truncatednumber = 0;
879
        }
880
        if ($truncatednumber <= 1073741824) { // 2^30
881
            $truncatednumber = (int)$truncatednumber;
882
        }
883
884
        return $truncatednumber;
885
    }
886
887
    /**
888
     * @param $byteword
889
     * @return int
890
     */
891
    public function LittleEndian2Int($byteword)
892
    {
893
        $intvalue    = 0;
894
        $byteword    = strrev($byteword);
895
        $bytewordlen = strlen($byteword);
896
        for ($i = 0; $i < $bytewordlen; $i++) {
897
            $intvalue += ord($byteword{$i}) * pow(256, $bytewordlen - 1 - $i);
898
        }
899
900
        return $intvalue;
901
    }
902
903
    /**
904
     * @param $byteword
905
     * @return int
906
     */
907
    public function BigEndian2Int($byteword)
908
    {
909
        return $this->LittleEndian2Int(strrev($byteword));
910
    }
911
912
    /**
913
     * @param $byteword
914
     * @return string
915
     */
916 View Code Duplication
    public function BigEndian2Bin($byteword)
917
    {
918
        $binvalue    = '';
919
        $bytewordlen = strlen($byteword);
920
        for ($i = 0; $i < $bytewordlen; $i++) {
921
            $binvalue .= str_pad(decbin(ord($byteword{$i})), 8, '0', STR_PAD_LEFT);
922
        }
923
924
        return $binvalue;
925
    }
926
927
    /**
928
     * @param $rawdata
929
     * @return float|int
930
     */
931
    public function FixedPoint2_30($rawdata)
932
    {
933
        $binarystring = $this->BigEndian2Bin($rawdata);
934
935
        return $this->Bin2Dec(substr($binarystring, 0, 2)) + (float)($this->Bin2Dec(substr($binarystring, 2, 30)) / 1073741824);
936
    }
937
938
    /**
939
     * @param            $binstring
940
     * @param  bool      $signed
941
     * @return float|int
942
     */
943
    public function Bin2Dec($binstring, $signed = false)
944
    {
945
        $signmult = 1;
946
        if ($signed) {
947
            if ($binstring{0} == '1') {
948
                $signmult = -1;
949
            }
950
            $binstring = substr($binstring, 1);
951
        }
952
        $decvalue = 0;
953
        for ($i = 0, $iMax = strlen($binstring); $i < $iMax; $i++) {
954
            $decvalue += ((int)substr($binstring, strlen($binstring) - $i - 1, 1)) * pow(2, $i);
955
        }
956
957
        return $this->CastAsInt($decvalue * $signmult);
958
    }
959
960
    /**
961
     * @param $floatnum
962
     * @return float|int
963
     */
964
    public function CastAsInt($floatnum)
965
    {
966
        // convert to float if not already
967
        $floatnum = (float)$floatnum;
968
969
        // convert a float to type int, only if possible
970
        if ($this->trunc($floatnum) == $floatnum) {
971
            // it's not floating point
972
            if ($floatnum <= 1073741824) { // 2^30
973
                // it's within int range
974
                $floatnum = (int)$floatnum;
975
            }
976
        }
977
978
        return $floatnum;
979
    }
980
}
981