Subversion Repositories cheapmusic

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
103 - 1
<?php
2
 
3
class bmp {
4
 
5
var $mpdf = null;
6
 
7
function bmp(&$mpdf) {
8
	$this->mpdf = $mpdf;
9
}
10
 
11
 
12
function _getBMPimage($data, $file) {
13
	$info = array();
14
		// Adapted from script by Valentin Schmidt
15
		// http://staff.dasdeck.de/valentin/fpdf/fpdf_bmp/
16
		$bfOffBits=$this->_fourbytes2int_le(substr($data,10,4));
17
		$width=$this->_fourbytes2int_le(substr($data,18,4));
18
		$height=$this->_fourbytes2int_le(substr($data,22,4));
19
		$flip = ($height<0);
20
		if ($flip) $height =-$height;
21
		$biBitCount=$this->_twobytes2int_le(substr($data,28,2));
22
		$biCompression=$this->_fourbytes2int_le(substr($data,30,4));
23
		$info = array('w'=>$width, 'h'=>$height);
24
		if ($biBitCount<16){
25
			$info['cs'] = 'Indexed';
26
			$info['bpc'] = $biBitCount;
27
			$palStr = substr($data,54,($bfOffBits-54));
28
			$pal = '';
29
			$cnt = strlen($palStr)/4;
30
			for ($i=0;$i<$cnt;$i++){
31
				$n = 4*$i;
32
				$pal .= $palStr[$n+2].$palStr[$n+1].$palStr[$n];
33
			}
34
			$info['pal'] = $pal;
35
		}
36
		else{
37
			$info['cs'] = 'DeviceRGB';
38
			$info['bpc'] = 8;
39
		}
40
 
41
		if ($this->mpdf->restrictColorSpace==1 || $this->mpdf->PDFX || $this->mpdf->restrictColorSpace==3) {
42
			if (($this->mpdf->PDFA && !$this->mpdf->PDFAauto) || ($this->mpdf->PDFX && !$this->mpdf->PDFXauto)) { $this->mpdf->PDFAXwarnings[] = "Image cannot be converted to suitable colour space for PDFA or PDFX file - ".$file." - (Image replaced by 'no-image'.)"; }
43
			return array('error' => "BMP Image cannot be converted to suitable colour space - ".$file." - (Image replaced by 'no-image'.)");
44
		}
45
 
46
		$biXPelsPerMeter=$this->_fourbytes2int_le(substr($data,38,4));	// horizontal pixels per meter, usually set to zero
47
		//$biYPelsPerMeter=$this->_fourbytes2int_le(substr($data,42,4));	// vertical pixels per meter, usually set to zero
48
		$biXPelsPerMeter=round($biXPelsPerMeter/1000 *25.4);
49
		//$biYPelsPerMeter=round($biYPelsPerMeter/1000 *25.4);
50
		$info['set-dpi'] = $biXPelsPerMeter;
51
 
52
		switch ($biCompression){
53
		  case 0:
54
			$str = substr($data,$bfOffBits);
55
			break;
56
		  case 1: # BI_RLE8
57
			$str = $this->rle8_decode(substr($data,$bfOffBits), $width);
58
			break;
59
		  case 2: # BI_RLE4
60
			$str = $this->rle4_decode(substr($data,$bfOffBits), $width);
61
			break;
62
		}
63
		$bmpdata = '';
64
		$padCnt = (4-ceil(($width/(8/$biBitCount)))%4)%4;
65
		switch ($biBitCount){
66
		  case 1:
67
		  case 4:
68
		  case 8:
69
			$w = floor($width/(8/$biBitCount)) + ($width%(8/$biBitCount)?1:0);
70
			$w_row = $w + $padCnt;
71
			if ($flip){
72
				for ($y=0;$y<$height;$y++){
73
					$y0 = $y*$w_row;
74
					for ($x=0;$x<$w;$x++)
75
						$bmpdata .= $str[$y0+$x];
76
				}
77
			}else{
78
				for ($y=$height-1;$y>=0;$y--){
79
					$y0 = $y*$w_row;
80
					for ($x=0;$x<$w;$x++)
81
						$bmpdata .= $str[$y0+$x];
82
				}
83
			}
84
			break;
85
 
86
		  case 16:
87
			$w_row = $width*2 + $padCnt;
88
			if ($flip){
89
				for ($y=0;$y<$height;$y++){
90
					$y0 = $y*$w_row;
91
					for ($x=0;$x<$width;$x++){
92
						$n = (ord( $str[$y0 + 2*$x + 1])*256 +    ord( $str[$y0 + 2*$x]));
93
						$b = ($n & 31)<<3; $g = ($n & 992)>>2; $r = ($n & 31744)>>7128;
94
						$bmpdata .= chr($r) . chr($g) . chr($b);
95
					}
96
				}
97
			}else{
98
				for ($y=$height-1;$y>=0;$y--){
99
					$y0 = $y*$w_row;
100
					for ($x=0;$x<$width;$x++){
101
						$n = (ord( $str[$y0 + 2*$x + 1])*256 +    ord( $str[$y0 + 2*$x]));
102
						$b = ($n & 31)<<3; $g = ($n & 992)>>2; $r = ($n & 31744)>>7;
103
						$bmpdata .= chr($r) . chr($g) . chr($b);
104
					}
105
				}
106
			}
107
			break;
108
 
109
		  case 24:
110
		  case 32:
111
			$byteCnt = $biBitCount/8;
112
			$w_row = $width*$byteCnt + $padCnt;
113
 
114
			if ($flip){
115
				for ($y=0;$y<$height;$y++){
116
					$y0 = $y*$w_row;
117
					for ($x=0;$x<$width;$x++){
118
						$i = $y0 + $x*$byteCnt ; # + 1
119
						$bmpdata .= $str[$i+2].$str[$i+1].$str[$i];
120
					}
121
				}
122
			}else{
123
				for ($y=$height-1;$y>=0;$y--){
124
					$y0 = $y*$w_row;
125
					for ($x=0;$x<$width;$x++){
126
						$i = $y0 + $x*$byteCnt ; # + 1
127
						$bmpdata .= $str[$i+2].$str[$i+1].$str[$i];
128
					}
129
				}
130
			}
131
			break;
132
 
133
		  default:
134
			return array('error' => 'Error parsing BMP image - Unsupported image biBitCount');
135
		}
136
		if ($this->mpdf->compress) {
137
			$bmpdata=gzcompress($bmpdata);
138
			$info['f']='FlateDecode';
139
		}
140
		$info['data']=$bmpdata;
141
		$info['type']='bmp';
142
		return $info;
143
}
144
 
145
function _fourbytes2int_le($s) {
146
	//Read a 4-byte integer from string
147
	return (ord($s[3])<<24) + (ord($s[2])<<16) + (ord($s[1])<<8) + ord($s[0]);
148
}
149
 
150
function _twobytes2int_le($s) {
151
	//Read a 2-byte integer from string
152
	return (ord(substr($s, 1, 1))<<8) + ord(substr($s, 0, 1));
153
}
154
 
155
 
156
# Decoder for RLE8 compression in windows bitmaps
157
# see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6x0u.asp
158
function rle8_decode ($str, $width){
159
    $lineWidth = $width + (3 - ($width-1) % 4);
160
    $out = '';
161
    $cnt = strlen($str);
162
    for ($i=0;$i<$cnt;$i++){
163
        $o = ord($str[$i]);
164
        switch ($o){
165
            case 0: # ESCAPE
166
                $i++;
167
                switch (ord($str[$i])){
168
                    case 0: # NEW LINE
169
                         $padCnt = $lineWidth - strlen($out)%$lineWidth;
170
                        if ($padCnt<$lineWidth) $out .= str_repeat(chr(0), $padCnt); # pad line
171
                        break;
172
                    case 1: # END OF FILE
173
                        $padCnt = $lineWidth - strlen($out)%$lineWidth;
174
                        if ($padCnt<$lineWidth) $out .= str_repeat(chr(0), $padCnt); # pad line
175
                         break 3;
176
                    case 2: # DELTA
177
                        $i += 2;
178
                        break;
179
                    default: # ABSOLUTE MODE
180
                        $num = ord($str[$i]);
181
                        for ($j=0;$j<$num;$j++)
182
                            $out .= $str[++$i];
183
                        if ($num % 2) $i++;
184
             }
185
                break;
186
            default:
187
                $out .= str_repeat($str[++$i], $o);
188
        }
189
    }
190
    return $out;
191
}
192
 
193
# Decoder for RLE4 compression in windows bitmaps
194
# see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6x0u.asp
195
function rle4_decode ($str, $width){
196
    $w = floor($width/2) + ($width % 2);
197
    $lineWidth = $w + (3 - ( ($width-1) / 2) % 4);
198
    $pixels = array();
199
    $cnt = strlen($str);
200
    for ($i=0;$i<$cnt;$i++){
201
        $o = ord($str[$i]);
202
        switch ($o){
203
            case 0: # ESCAPE
204
                $i++;
205
                switch (ord($str[$i])){
206
                    case 0: # NEW LINE
207
                        while (count($pixels)%$lineWidth!=0)
208
                            $pixels[]=0;
209
                        break;
210
                    case 1: # END OF FILE
211
                        while (count($pixels)%$lineWidth!=0)
212
                            $pixels[]=0;
213
                        break 3;
214
                    case 2: # DELTA
215
                        $i += 2;
216
                        break;
217
                    default: # ABSOLUTE MODE
218
                        $num = ord($str[$i]);
219
                        for ($j=0;$j<$num;$j++){
220
                            if ($j%2==0){
221
                                $c = ord($str[++$i]);
222
                              $pixels[] = ($c & 240)>>4;
223
                             } else
224
                              $pixels[] = $c & 15;
225
                        }
226
                        if ($num % 2) $i++;
227
             }
228
                break;
229
            default:
230
                $c = ord($str[++$i]);
231
                for ($j=0;$j<$o;$j++)
232
                    $pixels[] = ($j%2==0 ? ($c & 240)>>4 : $c & 15);
233
        }
234
    }
235
 
236
    $out = '';
237
    if (count($pixels)%2) $pixels[]=0;
238
    $cnt = count($pixels)/2;
239
    for ($i=0;$i<$cnt;$i++)
240
        $out .= chr(16*$pixels[2*$i] + $pixels[2*$i+1]);
241
    return $out;
242
}
243
 
244
 
245
 
246
}
247
 
248
?>