Here's my stab at the imagecreatefromtga function. I used code from send at mail dot 2aj dot net and others below as a basis, and added support for targa 16, targa 24 and targa 32. However, I only support uncompressed RBG data type as that's the only one I need. (I removed the return_array feature since you can simply use imagesx() and imagesy() to get the image size).
Please note that I have not tested this with a targa 16 since I don't have one handy at the moment.
<?php
function imagecreatefromtga( $filename )
{
    $handle = fopen( $filename, 'rb' );
    $data = fread( $handle, filesize( $filename ) );
    fclose( $handle );
  
    $string_length = base_convert( bin2hex( substr($data,1,1) ), 16, 10 );
    $data_type = base_convert( bin2hex( substr($data,2,1) ), 16, 10 );
    $width = base_convert( bin2hex( strrev( substr($data,12,2) ) ), 16, 10 );
    $height = base_convert( bin2hex( strrev( substr($data,14,2) ) ), 16, 10 );
    $bits_per_pixel = base_convert( bin2hex( substr($data,16,1) ), 16, 10 );
    
    switch( $data_type )        {
        case 2:        break;
        case 0:        case 1:        case 3:        case 9:        case 10:    case 11:    case 32:    case 33:    default:
            return NULL;    }    
    
    $pointer = 18 + $string_length;
    $bytes_per_pixel = (int) $bits_per_pixel/8;
    $x = 0;  $y = $height;
    
    $image = imagecreatetruecolor($width, $height);
    while ( $pointer < strlen($data) )
    {
        if( $bytes_per_pixel == 2 )            {
            $low_byte = bin2hex( strrev( substr($data, $pointer, $bytes_per_pixel)));
            $high_byte = bin2hex( strrev( substr($data, $pointer, $bytes_per_pixel)));
            $r = base_convert( ($high_byte & 0x7C)>>2, 16, 10);
            $g = base_convert( (($high_byte & 0x03)<<3) | (($low_byte & 0xE0)>>5), 16, 10);
            $b = base_convert( $low_byte & 0x1F, 16, 10);
            imagesetpixel( $image, $x, $y, $r<<16 | $g<<8 | $b);
        }
        else if( $bytes_per_pixel == 3 )    {
            imagesetpixel( $image, $x, $y, base_convert( bin2hex( strrev( substr($data, $pointer, $bytes_per_pixel))), 16, 10));
        }
        else if( $bytes_per_pixel == 4 )    {
            imagesetpixel( $image, $x, $y, base_convert( bin2hex( strrev( substr($data, $pointer, $bytes_per_pixel-1))), 16, 10));
        }
            
        if(++$x == $width)
        {
            $y--;
            $x=0;
        }
       $pointer += $bytes_per_pixel;
    }
  
    return $image;
}
?>