<?php
// Read & Save 24bit BMP files

// Author: de77
// Licence: MIT
// Webpage: de77.com
// Version: 07.02.2010

//no for directly open
if (!defined('IN_COMMON'))
{
	exit();
}

class BMP
{
	public static function imagebmp(&$img, $filename = false)
	{
		return imagebmp($img, $filename);
	}
	
	public static function imagecreatefrombmp($filename)
	{
		return imagecreatefrombmp($filename);
	}
}

function imagebmp(&$img, $filename = false)
{
	$wid = imagesx($img);
	$hei = imagesy($img);
	$wid_pad = str_pad('', $wid % 4, "\0");
	
	$size = 54 + ($wid + $wid_pad) * $hei;
	
	//prepare & save header
	$header['identifier']		= 'BM';
	$header['file_size']		= dword($size);
	$header['reserved']			= dword(0);
	$header['bitmap_data']		= dword(54);
	$header['header_size']		= dword(40);
	$header['width']			= dword($wid);
	$header['height']			= dword($hei);
	$header['planes']			= word(1);
	$header['bits_per_pixel']	= word(24);
	$header['compression']		= dword(0);
	$header['data_size']		= dword(0);
	$header['h_resolution']		= dword(0);
	$header['v_resolution']		= dword(0);
	$header['colors']			= dword(0);
	$header['important_colors']	= dword(0);

	if ($filename)
	{
	    $f = fopen($filename, "wb");
	    foreach ($header AS $h)
	    {
	    	fwrite($f, $h);
	    }
	    
		//save pixels
		for ($y=$hei-1; $y>=0; $y--)
		{
			for ($x=0; $x<$wid; $x++)
			{
				$rgb = imagecolorat($img, $x, $y);
				fwrite($f, byte3($rgb));
			}
			fwrite($f, $wid_pad);
		}
		fclose($f);

	    return true;
	}
	else
	{
	    foreach ($header AS $h)
	    {
	    	echo $h;
	    }
	    
		//save pixels
		for ($y=$hei-1; $y>=0; $y--)
		{
			for ($x=0; $x<$wid; $x++)
			{
				$rgb = imagecolorat($img, $x, $y);
				echo byte3($rgb);
			}
			echo $wid_pad;
		}

		return false;
	}
}

function imagecreatefrombmp($filename)
{
    $f = fopen($filename, "rb");

	//read header    
    $header = fread($f, 54);
    $header = unpack(	'c2identifier/Vfile_size/Vreserved/Vbitmap_data/Vheader_size/' .
						'Vwidth/Vheight/vplanes/vbits_per_pixel/Vcompression/Vdata_size/'.
						'Vh_resolution/Vv_resolution/Vcolors/Vimportant_colors', $header);

    if ($header['identifier1'] != 66 or $header['identifier2'] != 77)
    {
    	//die('Not a valid bmp file');
    	return false;
    }
    
    if ($header['bits_per_pixel'] != 24)
    {
    	//die('Only 24bit BMP images are supported');
    	return false;
    }
    
    $wid2 = ceil((3*$header['width']) / 4) * 4;
	
    $wid = $header['width'];
    $hei = $header['height'];

    $img = imagecreatetruecolor($header['width'], $header['height']);

	//read pixels    
    for ($y=$hei-1; $y>=0; $y--)
    {
		$row = fread($f, $wid2);
		$pixels = str_split($row, 3);
    	for ($x=0; $x<$wid; $x++)
    	{
    		imagesetpixel($img, $x, $y, dwordize($pixels[$x]));
    	}
    }
	fclose($f);    	    
	
	return $img;
}	

function dwordize($str)
{
	$a = ord($str[0]);
	$b = ord($str[1]);
	$c = ord($str[2]);
	return $c*256*256 + $b*256 + $a;
}

function byte3($n)
{
	return chr($n & 255) . chr(($n >> 8) & 255) . chr(($n >> 16) & 255);	
}
function dword($n)
{
	return pack("V", $n);
}
function word($n)
{
	return pack("v", $n);
}
