15 public function __construct(Mpdf
$mpdf)
20 public function _getBMPimage($data, $file)
22 // Adapted from script by Valentin Schmidt
23 // http://staff.dasdeck.de/valentin/fpdf/fpdf_bmp/
24 $bfOffBits = $this->_fourbytes2int_le(substr($data, 10, 4));
25 $width = $this->_fourbytes2int_le(substr($data, 18, 4));
26 $height = $this->_fourbytes2int_le(substr($data, 22, 4));
27 $flip = ($height < 0);
31 $biBitCount = $this->_twobytes2int_le(substr($data, 28, 2));
32 $biCompression = $this->_fourbytes2int_le(substr($data, 30, 4));
33 $info = ['w' => $width, 'h' => $height];
34 if ($biBitCount < 16) {
35 $info['cs'] = 'Indexed';
36 $info['bpc'] = $biBitCount;
37 $palStr = substr($data, 54, $bfOffBits - 54);
39 $cnt = strlen($palStr) / 4;
40 for ($i = 0; $i < $cnt; $i++
) {
42 $pal .= $palStr[$n +
2] . $palStr[$n +
1] . $palStr[$n];
46 $info['cs'] = 'DeviceRGB';
50 if ($this->mpdf
->restrictColorSpace
== 1 ||
$this->mpdf
->PDFX ||
$this->mpdf
->restrictColorSpace
== 3) {
51 if (($this->mpdf
->PDFA
&& !$this->mpdf
->PDFAauto
) ||
($this->mpdf
->PDFX
&& !$this->mpdf
->PDFXauto
)) {
52 $this->mpdf
->PDFAXwarnings
[] = "Image cannot be converted to suitable colour space for PDFA or PDFX file - $file - (Image replaced by 'no-image'.)";
54 return ['error' => "BMP Image cannot be converted to suitable colour space - $file - (Image replaced by 'no-image'.)"];
57 $biXPelsPerMeter = $this->_fourbytes2int_le(substr($data, 38, 4)); // horizontal pixels per meter, usually set to zero
58 //$biYPelsPerMeter=$this->_fourbytes2int_le(substr($data,42,4)); // vertical pixels per meter, usually set to zero
59 $biXPelsPerMeter = round($biXPelsPerMeter / 1000 * 25.4);
60 //$biYPelsPerMeter=round($biYPelsPerMeter/1000 *25.4);
61 $info['set-dpi'] = $biXPelsPerMeter;
63 switch ($biCompression) {
65 $str = substr($data, $bfOffBits);
68 $str = $this->rle8_decode(substr($data, $bfOffBits), $width);
71 $str = $this->rle4_decode(substr($data, $bfOffBits), $width);
75 $padCnt = (4 - ceil($width / (8 / $biBitCount)) %
4) %
4;
76 switch ($biBitCount) {
80 $w = floor($width / (8 / $biBitCount)) +
($width %
(8 / $biBitCount) ?
1 : 0);
81 $w_row = $w +
$padCnt;
83 for ($y = 0; $y < $height; $y++
) {
85 for ($x = 0; $x < $w; $x++
) {
86 $bmpdata .= $str[$y0 +
$x];
90 for ($y = $height - 1; $y >= 0; $y--) {
92 for ($x = 0; $x < $w; $x++
) {
93 $bmpdata .= $str[$y0 +
$x];
100 $w_row = $width * 2 +
$padCnt;
102 for ($y = 0; $y < $height; $y++
) {
104 for ($x = 0; $x < $width; $x++
) {
105 $n = (ord($str[$y0 +
2 * $x +
1]) * 256 +
ord($str[$y0 +
2 * $x]));
107 $g = ($n & 992) >> 2;
108 $r = ($n & 31744) >> 7;
109 $bmpdata .= chr($r) . chr($g) . chr($b);
113 for ($y = $height - 1; $y >= 0; $y--) {
115 for ($x = 0; $x < $width; $x++
) {
116 $n = (ord($str[$y0 +
2 * $x +
1]) * 256 +
ord($str[$y0 +
2 * $x]));
118 $g = ($n & 992) >> 2;
119 $r = ($n & 31744) >> 7;
120 $bmpdata .= chr($r) . chr($g) . chr($b);
128 $byteCnt = $biBitCount / 8;
129 $w_row = $width * $byteCnt +
$padCnt;
132 for ($y = 0; $y < $height; $y++
) {
134 for ($x = 0; $x < $width; $x++
) {
135 $i = $y0 +
$x * $byteCnt; # + 1
136 $bmpdata .= $str[$i +
2] . $str[$i +
1] . $str[$i];
140 for ($y = $height - 1; $y >= 0; $y--) {
142 for ($x = 0; $x < $width; $x++
) {
143 $i = $y0 +
$x * $byteCnt; # + 1
144 $bmpdata .= $str[$i +
2] . $str[$i +
1] . $str[$i];
151 return ['error' => 'Error parsing BMP image - Unsupported image biBitCount'];
153 if ($this->mpdf
->compress
) {
154 $bmpdata = gzcompress($bmpdata);
155 $info['f'] = 'FlateDecode';
157 $info['data'] = $bmpdata;
158 $info['type'] = 'bmp';
163 * Read a 4-byte integer from string
168 private function _fourbytes2int_le($s)
170 return (ord($s[3]) << 24) +
(ord($s[2]) << 16) +
(ord($s[1]) << 8) +
ord($s[0]);
174 * Read a 2-byte integer from string
179 private function _twobytes2int_le($s)
181 return (ord(substr($s, 1, 1)) << 8) +
ord(substr($s, 0, 1));
185 * Decoder for RLE8 compression in windows bitmaps
187 * @see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6x0u.asp
192 private function rle8_decode($str, $width)
194 $lineWidth = $width +
(3 - ($width - 1) %
4);
197 for ($i = 0; $i < $cnt; $i++
) {
199 if ($o === 0) { # ESCAPE
201 switch (ord($str[$i])) {
203 $padCnt = $lineWidth - strlen($out) %
$lineWidth;
204 if ($padCnt < $lineWidth) {
205 $out .= str_repeat(chr(0), $padCnt);# pad line
208 case 1: # END OF FILE
209 $padCnt = $lineWidth - strlen($out) %
$lineWidth;
210 if ($padCnt < $lineWidth) {
211 $out .= str_repeat(chr(0), $padCnt);# pad line
217 default: # ABSOLUTE MODE
218 $num = ord($str[$i]);
219 for ($j = 0; $j < $num; $j++
) {
227 $out .= str_repeat($str[++
$i], $o);
234 * Decoder for RLE4 compression in windows bitmaps
236 * @see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6x0u.asp
241 private function rle4_decode($str, $width)
243 $w = floor($width / 2) +
($width %
2);
244 $lineWidth = $w +
(3 - ( ($width - 1) / 2) %
4);
247 for ($i = 0; $i < $cnt; $i++
) {
249 if ($o === 0) { # ESCAPE
251 switch (ord($str[$i])) {
253 while (count($pixels) %
$lineWidth !== 0) {
257 case 1: # END OF FILE
258 while (count($pixels) %
$lineWidth !== 0) {
265 default: # ABSOLUTE MODE
266 $num = ord($str[$i]);
267 for ($j = 0; $j < $num; $j++
) {
269 $c = ord($str[++
$i]);
270 $pixels[] = ($c & 240) >> 4;
272 $pixels[] = $c & 15; //FIXME: undefined var
280 $c = ord($str[++
$i]);
281 for ($j = 0; $j < $o; $j++
) {
282 $pixels[] = ($j %
2 === 0 ?
($c & 240) >> 4 : $c & 15);
288 if (count($pixels) %
2) {
291 $cnt = count($pixels) / 2;
292 for ($i = 0; $i < $cnt; $i++
) {
293 $out .= chr(16 * $pixels[2 * $i] +
$pixels[2 * $i +
1]);