c2ephp

sprites/C16Frame.php

Go to the documentation of this file.
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 ?>
 All Classes Files Functions Variables Enumerations