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