Advertisement
cyla

TGA parser

Apr 5th, 2011
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 6.51 KB | None | 0 0
  1. <?php
  2.  
  3. /****************************************************************************
  4.  * based on:                                                                *
  5.  * http://tfcduke.developpez.com/tutoriel/format/tga/fichiers/tga_specs.pdf *
  6.  ****************************************************************************/
  7.  
  8. define( "TGA_COLOR_MAP_TYPE_NO_COLOR_MAP", 0 );
  9. define( "TGA_COLOR_MAP_TYPE_COLOR_MAP", 1 );
  10.  
  11. define( "TGA_IMAGE_TYPE_NONE_DATA", 0 );
  12. define( "TGA_IMAGE_TYPE_COLOR_MAPPED", 1 );
  13. define( "TGA_IMAGE_TYPE_TRUE_COLOR", 2 );
  14. define( "TGA_IMAGE_TYPE_BLACK_AND_WHITE", 3 );
  15. define( "TGA_IMAGE_TYPE_ENCODED_COLOR_MAPPED", 9 );
  16. define( "TGA_IMAGE_TYPE_ENCODED_TRUE_COLOR", 10 );
  17. define( "TGA_IMAGE_TYPE_ENCODED_BLACK_AND_WHITE", 11 );
  18.  
  19. define( "TGA_IMAGE_ORIGIN_BOTTOM_LEFT", 0x0 );
  20. define( "TGA_IMAGE_ORIGIN_BOTTOM_RIGHT", 0x10 );
  21. define( "TGA_IMAGE_ORIGIN_TOP_LEFT", 0x20 );
  22. define( "TGA_IMAGE_ORIGIN_TOP_RIGHT", 0x30 );
  23.  
  24. class TGA {
  25.     private $imageHandle;
  26.     private $width;
  27.     private $height;
  28.     private $imageHeader;
  29.     private $imageId;
  30.     private $colorMap;
  31.     private $imageData;
  32.     private $imageFooter;
  33.  
  34.     public function __construct( $imageHandle, $width = -1, $height = -1 ) {
  35.         $this->imageHandle = $imageHandle;
  36.         $this->width = $width;
  37.         $this->height = $height;
  38.     }
  39.  
  40.     public function parse() {
  41.         fseek( $this->imageHandle, 0 );
  42.  
  43.         $this->imageHeader["IdentSize"] = implode( unpack( "C", fread( $this->imageHandle, 1 ) ) );
  44.         $this->imageHeader["ColorMapType"] = implode( unpack( "C", fread( $this->imageHandle, 1 ) ) );
  45.         $this->imageHeader["ImageType"] = implode( unpack( "C", fread( $this->imageHandle, 1 ) ) );
  46.  
  47.         $this->imageHeader["ColorMapStart"] = implode( unpack( "S", fread( $this->imageHandle, 2 ) ) );
  48.         $this->imageHeader["ColorMapLength"] = implode( unpack( "S", fread( $this->imageHandle, 2 ) ) );
  49.         $this->imageHeader["ColorMapBits"] = implode( unpack( "C", fread( $this->imageHandle, 1 ) ) );
  50.  
  51.         $this->imageHeader["XStart"] = implode( unpack( "S", fread( $this->imageHandle, 2 ) ) );
  52.         $this->imageHeader["YStart"] = implode( unpack( "S", fread( $this->imageHandle, 2 ) ) );
  53.         $this->imageHeader["Width"] = implode( unpack( "S", fread( $this->imageHandle, 2 ) ) );
  54.         $this->imageHeader["Height"] = implode( unpack( "S", fread( $this->imageHandle, 2 ) ) );
  55.         $this->imageHeader["Bits"] = implode( unpack( "C", fread( $this->imageHandle, 1 ) ) );
  56.         $this->imageHeader["Descriptor"] = implode( unpack( "C", fread( $this->imageHandle, 1 ) ) );
  57.  
  58.         $this->imageHeader["ImageOrigin"] = $this->imageHeader["Descriptor"] & 0x30;
  59.         $this->imageHeader["AttributeBits"] = $this->imageHeader["Descriptor"] & 0x0f;
  60.  
  61.         if ( $this->imageHeader["IdentSize"] > 0 ) {
  62.             $this->imageId = implode( unpack( "a{$this->imageHeader["IdentSize"]}", fread( $this->imageHandle, $this->imageHeader["IdentSize"] ) ) );
  63.         }
  64.  
  65.         if ( $this->imageHeader["ColorMapType"] != 0 ) {
  66.             throw new Exception( "tga_not_implemented_colormap", $this->imageHeader["ColorMapType"] );
  67.         }
  68.  
  69.         fseek( $this->imageHandle, -26, SEEK_END );
  70.        
  71.         $this->parseFooter();
  72.  
  73.         fseek( $this->imageHandle, 18 + $this->imageHeader["IdentSize"] );
  74.  
  75.         switch ( $this->imageHeader["ImageType"] ) {
  76.             case TGA_IMAGE_TYPE_TRUE_COLOR : {
  77.                 $this->createImageTrueColor();
  78.  
  79.                 break;
  80.             }
  81.             default : {
  82.                 throw new Exception( "tga_not_implemented_image_type", $this->imageHeader["ImageType"] );
  83.             }
  84.         }
  85.     }
  86.  
  87.     public function close() {
  88.         fclose( $this->imageHandle );
  89.     }
  90.  
  91.     public function getHeader() {
  92.         return $this->imageHeader;
  93.     }
  94.  
  95.     public function getFooter() {
  96.         return $this->imageFooter;
  97.     }
  98.  
  99.     private function parseFooter() {
  100.         $this->imageFooter = array();
  101.         $this->imageFooter["extensionOffset"] = implode( unpack( "L", fread( $this->imageHandle, 4 ) ) );
  102.         $this->imageFooter["developerOffset"] = implode( unpack( "L", fread( $this->imageHandle, 4 ) ) );
  103.         $this->imageFooter["signature"] = implode( unpack( "a16", fread( $this->imageHandle, 16 ) ) );
  104.         $this->imageFooter["dot"] = implode( unpack( "C", fread( $this->imageHandle, 1 ) ) );
  105.         $this->imageFooter["null"] = implode( unpack( "C", fread( $this->imageHandle, 1 ) ) );
  106.     }
  107.  
  108.     private function createImageTrueColor() {
  109.         if ( $this->width != -1 ) {
  110.             $width = $this->width;
  111.         } else {
  112.             $width = $this->imageHeader["Width"];
  113.         }
  114.  
  115.         if ( $this->height != -1 ) {
  116.             $height = $this->height;
  117.         } else {
  118.             $height = $this->imageHeader["Height"];
  119.         }
  120.  
  121.         $this->imageData = imagecreatetruecolor( $width, $height );
  122.  
  123.         switch ( $this->imageHeader["Bits"] ) {
  124.             case 24 : {
  125.                 $pixelDataBytes = $this->imageHeader["Width"] * $this->imageHeader["Height"] * 3;
  126.                 $pixelData = unpack( "C{$pixelDataBytes}", fread( $this->imageHandle, $pixelDataBytes ) );
  127.                
  128.                 break;
  129.             }
  130.             default : {
  131.                 throw new Exception( "tga_not_implemented_color_depth", $this->imageHeader["Bits"] );
  132.             }
  133.         }
  134.  
  135.         $horizontalBorder = floor( ( $this->imageHeader["Width"] - $width ) / 2 );
  136.         $verticalBorder = floor( ( $this->imageHeader["Height"] - $height ) / 2 );
  137.  
  138.         for ( $y = $verticalBorder; $y < $this->imageHeader["Height"] - $verticalBorder; $y++ ) {
  139.             for ( $x = $horizontalBorder; $x < $this->imageHeader["Width"] - $horizontalBorder; $x++ ) {
  140.                 $pixelRed = $pixelData[( $y * $this->imageHeader["Width"] + $x ) * 3 + 3];
  141.                 $pixelGreen = $pixelData[( $y * $this->imageHeader["Width"] + $x ) * 3 + 2];
  142.                 $pixelBlue = $pixelData[( $y * $this->imageHeader["Width"] + $x ) * 3 + 1];
  143.  
  144.                 if ( ( $pixelRed != 0 ) && ( $pixelGreen != 0 ) && ( $pixelBlue != 0 ) ) {
  145.                     $color = imagecolorallocate ( $this->imageData, $pixelRed, $pixelGreen, $pixelBlue );
  146.  
  147.                     switch ( $this->imageHeader["ImageOrigin"] ) {
  148.                         case TGA_IMAGE_ORIGIN_BOTTOM_LEFT : {
  149.                             imagesetpixel( $this->imageData, $x - $horizontalBorder, $this->imageHeader["Height"] - $y - $verticalBorder, $color );
  150.                             break;
  151.                         }
  152.                         case TGA_IMAGE_ORIGIN_BOTTOM_RIGHT : {
  153.                             imagesetpixel( $this->imageData, $this->imageHeader["Width"] - $x - $horizontalBorder, $this->imageHeader["Height"] - $y - $verticalBorder, $color );
  154.                             break;
  155.                         }
  156.                         case TGA_IMAGE_ORIGIN_TOP_LEFT : {
  157.                             imagesetpixel( $this->imageData, $x - $horizontalBorder, $y - $verticalBorder, $color );
  158.                             break;
  159.                         }
  160.                         case TGA_IMAGE_ORIGIN_TOP_RIGHT : {
  161.                             imagesetpixel( $this->imageData, $this->imageHeader["Width"] - $x - $horizontalBorder, $y - $verticalBorder, $color );
  162.                             break;
  163.                         }
  164.                     }
  165.                 }
  166.             }
  167.         }
  168.     }
  169.  
  170.     public function getImage() {
  171.         return $this->imageData;
  172.     }
  173. }
  174.  
  175. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement