c2ephp
|
00001 <?php 00002 require_once(dirname(__FILE__).'/SpriteFrame.php'); 00003 require_once(dirname(__FILE__).'/../support/IReader.php'); 00005 00008 class C16Frame extends SpriteFrame 00009 { 00011 00012 private $encoding; 00013 00014 private $lineOffset = array(); 00015 00016 private $reader; 00017 private $offset; 00018 00020 00021 00023 00028 public function C16Frame($reader,$encoding='565') 00029 { 00030 if($reader instanceof IReader) { 00031 $this->reader = $reader; 00032 $this->encoding = $encoding; 00033 $this->offset = $this->reader->ReadInt(4); 00034 00035 $width = $this->reader->ReadInt(2); 00036 $height = $this->reader->ReadInt(2); 00037 00038 parent::SpriteFrame($width,$height); 00039 00040 for($x = 0; $x < ($height - 1); $x++) 00041 { 00042 $this->lineOffset[$x] = $this->reader->ReadInt(4); 00043 } 00044 } else if(is_resource($reader)) { 00045 if(get_resource_type($reader) == 'gd') { 00046 00047 $this->encoding = ($encoding=='555')?'555':'565'; 00048 parent::SpriteFrame(imagesx($reader),imagesy($reader),true); 00049 $this->gdImage = $reader; 00050 } 00051 } else { 00052 throw new Exception('$reader must be an IReader or gd image resource.'); 00053 } 00054 } 00055 00056 // @brief Sets the encoding to use when compiling 00057 public function SetEncoding($encoding) { 00058 $this->EnsureDecoded(); 00059 $this->encoding = $encoding; 00060 } 00061 00063 00065 00068 protected function Decode() 00069 { 00070 $image = imagecreatetruecolor($this->GetWidth(), 00071 $this->GetHeight()); 00072 $this->reader->Seek($this->offset); 00073 for($y = 0; $y < $this->GetHeight(); $y++) 00074 { 00075 for($x = 0; $x < $this->GetWidth();) 00076 { 00077 $run = $this->reader->ReadInt(2); 00078 if(($run & 0x0001) > 0) 00079 $run_type = "colour"; 00080 else 00081 $run_type = "black"; 00082 $run_length = ($run & 0x7FFF) >> 1; 00083 if($run_type == "black") 00084 { 00085 $z = $x + $run_length; 00086 for(;$x < $z; $x++) 00087 { 00088 imagesetpixel($image, $x, $y, imagecolorallocate($image, 0, 0, 0)); 00089 } 00090 } 00091 else //colour run 00092 { 00093 $z = $x + $run_length; 00094 for(;$x < $z; $x++) 00095 { 00096 $pixel = $this->reader->ReadInt(2); 00097 if($this->encoding == "565") 00098 { 00099 $red = ($pixel & 0xF800) >> 8; 00100 $green = ($pixel & 0x07E0) >> 3; 00101 $blue = ($pixel & 0x001F) << 3; 00102 } 00103 else if($this->encoding == "555") 00104 { 00105 $red = ($pixel & 0x7C00) >> 7; 00106 $green = ($pixel & 0x03E0) >> 2; 00107 $blue = ($pixel & 0x001F) << 3; 00108 } 00109 $colour = imagecolorallocate($image, $red, $green, $blue); 00110 imagesetpixel($image, $x, $y, $colour); 00111 } 00112 } 00113 if($x == $this->GetWidth()) 00114 $this->reader->Skip(2); 00115 } 00116 } 00117 $this->gdImage = $image; 00118 return $image; 00119 } 00121 00123 00127 public function Encode() { 00128 $data = ''; 00129 $lineOffsets = array(); 00130 for($y = 0; $y < $this->GetHeight(); $y++) { 00131 $wasblack = 0; 00132 $runlength = 0; 00133 if($y > 0) { 00134 $lineOffsets[] = strlen($data); 00135 } 00136 $colourRunData = ''; 00137 for($x = 0; $x < $this->GetWidth(); $x++) { 00138 00139 $pixel = $this->GetPixel($x,$y); 00140 if($pixel['red'] > 255 || $pixel['green'] > 255 || $pixel['blue'] > 255) { 00141 throw new Exception('Pixel colour out of range.'); 00142 } 00143 $newpixel = 0; 00144 if($this->encoding == '555') { 00145 $newpixel = (($pixel['red'] << 7) & 0xF800) | (($pixel['green'] << 2) & 0x03E0) | (($pixel['blue'] >> 3) & 0x001F); 00146 } else { 00147 $newpixel = (($pixel['red'] << 8) & 0xF800) | (($pixel['green'] << 3) & 0x07E0) | (($pixel['blue'] >> 3) & 0x001F); 00148 } 00149 00150 00151 // if isblack !== wasblack 00152 if(($newpixel == 0) !== $wasblack || $runlength > 32766) { 00153 //end the run if this isn't the first run 00154 if($wasblack !== 0) { 00155 00156 //output data. 00157 $run = $runlength << 1; 00158 if($wasblack) { 00159 $data .= pack('v',$run); 00160 00161 } else { 00162 $run = $run | 1; 00163 $data .= pack('v',$run); 00164 $data .= $colourRunData; 00165 $colourRunData = ''; 00166 } 00167 } 00168 //start a new run 00169 if($newpixel == 0) { 00170 $wasblack = true; 00171 $colourRunData = ''; 00172 } else { 00173 $wasblack = false; 00174 $colourRunData = pack('v',$newpixel); 00175 } 00176 $runlength = 1; 00177 00178 } else { 00179 if(!$wasblack) { 00180 $colourRunData .= pack('v',$newpixel); 00181 } 00182 $runlength++; 00183 } 00184 00185 if($x == ($this->GetWidth()-1)) { 00186 //end run and output data. 00187 $run = $runlength << 1; 00188 if($wasblack) { 00189 $data .= pack('v',$run); 00190 00191 } else { 00192 $run = $run | 1; 00193 $data .= pack('v',$run); 00194 $data .= $colourRunData; 00195 $colourRunData = ''; 00196 } 00197 } 00198 } 00199 //line terminating zero tag. 00200 $data .= pack('xx'); 00201 } 00202 //image terminating zero tag 00203 $data .= pack('xx'); 00204 return array('lineoffsets' => $lineOffsets, 'data' => $data); 00205 } 00206 } 00207 ?>