]> git.xonotic.org Git - xonotic/netradiant.git/blobdiff - plugins/image/tga.cpp
reformat code! now the code is only ugly on the *inside*
[xonotic/netradiant.git] / plugins / image / tga.cpp
index 4fa8731f5a3b7600ead4d9e16982b0002567bb58..c430700dd7ce8c047585ae05d26d58d23f9e7ecf 100644 (file)
@@ -40,377 +40,394 @@ class Flip10 {}; // horizontal flip only
 class Flip11 {}; // both
 
 template<typename PixelDecoder>
-void image_decode( PointerInputStream& istream, PixelDecoder& decode, RGBAImage& image, const Flip00& ){
-       RGBAPixel* end = image.pixels + ( image.height * image.width );
-       for ( RGBAPixel* row = end; row != image.pixels; row -= image.width )
-       {
-               for ( RGBAPixel* pixel = row - image.width; pixel != row; ++pixel )
-               {
-                       decode( istream, *pixel );
-               }
-       }
+void image_decode(PointerInputStream &istream, PixelDecoder &decode, RGBAImage &image, const Flip00 &)
+{
+    RGBAPixel *end = image.pixels + (image.height * image.width);
+    for (RGBAPixel *row = end; row != image.pixels; row -= image.width) {
+        for (RGBAPixel *pixel = row - image.width; pixel != row; ++pixel) {
+            decode(istream, *pixel);
+        }
+    }
 }
 
 template<typename PixelDecoder>
-void image_decode( PointerInputStream& istream, PixelDecoder& decode, RGBAImage& image, const Flip01& ){
-       RGBAPixel* end = image.pixels + ( image.height * image.width );
-       for ( RGBAPixel* row = image.pixels; row != end; row += image.width )
-       {
-               for ( RGBAPixel* pixel = row; pixel != row + image.width; ++pixel )
-               {
-                       decode( istream, *pixel );
-               }
-       }
+void image_decode(PointerInputStream &istream, PixelDecoder &decode, RGBAImage &image, const Flip01 &)
+{
+    RGBAPixel *end = image.pixels + (image.height * image.width);
+    for (RGBAPixel *row = image.pixels; row != end; row += image.width) {
+        for (RGBAPixel *pixel = row; pixel != row + image.width; ++pixel) {
+            decode(istream, *pixel);
+        }
+    }
 }
 
 template<typename PixelDecoder>
-void image_decode( PointerInputStream& istream, PixelDecoder& decode, RGBAImage& image, const Flip10& ){
-       RGBAPixel* end = image.pixels + ( image.height * image.width );
-       for ( RGBAPixel* row = end; row != image.pixels; row -= image.width )
-       {
-               for ( RGBAPixel* pixel = row; pixel != row - image.width; )
-               {
-                       decode( istream, *--pixel );
-               }
-       }
+void image_decode(PointerInputStream &istream, PixelDecoder &decode, RGBAImage &image, const Flip10 &)
+{
+    RGBAPixel *end = image.pixels + (image.height * image.width);
+    for (RGBAPixel *row = end; row != image.pixels; row -= image.width) {
+        for (RGBAPixel *pixel = row; pixel != row - image.width;) {
+            decode(istream, *--pixel);
+        }
+    }
 }
 
 template<typename PixelDecoder>
-void image_decode( PointerInputStream& istream, PixelDecoder& decode, RGBAImage& image, const Flip11& ){
-       RGBAPixel* end = image.pixels + ( image.height * image.width );
-       for ( RGBAPixel* row = image.pixels; row != end; row += image.width )
-       {
-               for ( RGBAPixel* pixel = row + image.width; pixel != row; )
-               {
-                       decode( istream, *--pixel );
-               }
-       }
+void image_decode(PointerInputStream &istream, PixelDecoder &decode, RGBAImage &image, const Flip11 &)
+{
+    RGBAPixel *end = image.pixels + (image.height * image.width);
+    for (RGBAPixel *row = image.pixels; row != end; row += image.width) {
+        for (RGBAPixel *pixel = row + image.width; pixel != row;) {
+            decode(istream, *--pixel);
+        }
+    }
 }
 
-inline void istream_read_gray( PointerInputStream& istream, RGBAPixel& pixel ){
-       istream.read( &pixel.blue, 1 );
-       pixel.red = pixel.green = pixel.blue;
-       pixel.alpha = 0xff;
+inline void istream_read_gray(PointerInputStream &istream, RGBAPixel &pixel)
+{
+    istream.read(&pixel.blue, 1);
+    pixel.red = pixel.green = pixel.blue;
+    pixel.alpha = 0xff;
 }
 
-inline void istream_read_rgb( PointerInputStream& istream, RGBAPixel& pixel ){
-       istream.read( &pixel.blue, 1 );
-       istream.read( &pixel.green, 1 );
-       istream.read( &pixel.red, 1 );
-       pixel.alpha = 0xff;
+inline void istream_read_rgb(PointerInputStream &istream, RGBAPixel &pixel)
+{
+    istream.read(&pixel.blue, 1);
+    istream.read(&pixel.green, 1);
+    istream.read(&pixel.red, 1);
+    pixel.alpha = 0xff;
 }
 
-inline void istream_read_rgba( PointerInputStream& istream, RGBAPixel& pixel ){
-       istream.read( &pixel.blue, 1 );
-       istream.read( &pixel.green, 1 );
-       istream.read( &pixel.red, 1 );
-       istream.read( &pixel.alpha, 1 );
+inline void istream_read_rgba(PointerInputStream &istream, RGBAPixel &pixel)
+{
+    istream.read(&pixel.blue, 1);
+    istream.read(&pixel.green, 1);
+    istream.read(&pixel.red, 1);
+    istream.read(&pixel.alpha, 1);
 }
 
-class TargaDecodeGrayPixel
-{
+class TargaDecodeGrayPixel {
 public:
-void operator()( PointerInputStream& istream, RGBAPixel& pixel ){
-       istream_read_gray( istream, pixel );
-}
+    void operator()(PointerInputStream &istream, RGBAPixel &pixel)
+    {
+        istream_read_gray(istream, pixel);
+    }
 };
 
 template<typename Flip>
-void targa_decode_grayscale( PointerInputStream& istream, RGBAImage& image, const Flip& flip ){
-       TargaDecodeGrayPixel decode;
-       image_decode( istream, decode, image, flip );
+void targa_decode_grayscale(PointerInputStream &istream, RGBAImage &image, const Flip &flip)
+{
+    TargaDecodeGrayPixel decode;
+    image_decode(istream, decode, image, flip);
 }
 
-class TargaDecodeRGBPixel
-{
+class TargaDecodeRGBPixel {
 public:
-void operator()( PointerInputStream& istream, RGBAPixel& pixel ){
-       istream_read_rgb( istream, pixel );
-}
+    void operator()(PointerInputStream &istream, RGBAPixel &pixel)
+    {
+        istream_read_rgb(istream, pixel);
+    }
 };
 
 template<typename Flip>
-void targa_decode_rgb( PointerInputStream& istream, RGBAImage& image, const Flip& flip ){
-       TargaDecodeRGBPixel decode;
-       image_decode( istream, decode, image, flip );
+void targa_decode_rgb(PointerInputStream &istream, RGBAImage &image, const Flip &flip)
+{
+    TargaDecodeRGBPixel decode;
+    image_decode(istream, decode, image, flip);
 }
 
-class TargaDecodeRGBAPixel
-{
+class TargaDecodeRGBAPixel {
 public:
-void operator()( PointerInputStream& istream, RGBAPixel& pixel ){
-       istream_read_rgba( istream, pixel );
-}
+    void operator()(PointerInputStream &istream, RGBAPixel &pixel)
+    {
+        istream_read_rgba(istream, pixel);
+    }
 };
 
 template<typename Flip>
-void targa_decode_rgba( PointerInputStream& istream, RGBAImage& image, const Flip& flip ){
-       TargaDecodeRGBAPixel decode;
-       image_decode( istream, decode, image, flip );
+void targa_decode_rgba(PointerInputStream &istream, RGBAImage &image, const Flip &flip)
+{
+    TargaDecodeRGBAPixel decode;
+    image_decode(istream, decode, image, flip);
 }
 
 typedef byte TargaPacket;
 typedef byte TargaPacketSize;
 
-inline void targa_packet_read_istream( TargaPacket& packet, PointerInputStream& istream ){
-       istream.read( &packet, 1 );
+inline void targa_packet_read_istream(TargaPacket &packet, PointerInputStream &istream)
+{
+    istream.read(&packet, 1);
 }
 
-inline bool targa_packet_is_rle( const TargaPacket& packet ){
-       return ( packet & 0x80 ) != 0;
+inline bool targa_packet_is_rle(const TargaPacket &packet)
+{
+    return (packet & 0x80) != 0;
 }
 
-inline TargaPacketSize targa_packet_size( const TargaPacket& packet ){
-       return 1 + ( packet & 0x7f );
+inline TargaPacketSize targa_packet_size(const TargaPacket &packet)
+{
+    return 1 + (packet & 0x7f);
 }
 
 
-class TargaDecodeGrayPixelRLE
-{
-TargaPacketSize m_packetSize;
-RGBAPixel m_pixel;
-TargaPacket m_packet;
+class TargaDecodeGrayPixelRLE {
+    TargaPacketSize m_packetSize;
+    RGBAPixel m_pixel;
+    TargaPacket m_packet;
 public:
-TargaDecodeGrayPixelRLE() : m_packetSize( 0 ){
-}
-void operator()( PointerInputStream& istream, RGBAPixel& pixel ){
-       if ( m_packetSize == 0 ) {
-               targa_packet_read_istream( m_packet, istream );
-               m_packetSize = targa_packet_size( m_packet );
-
-               if ( targa_packet_is_rle( m_packet ) ) {
-                       istream_read_gray( istream, m_pixel );
-               }
-       }
-
-       if ( targa_packet_is_rle( m_packet ) ) {
-               pixel = m_pixel;
-       }
-       else
-       {
-               istream_read_gray( istream, pixel );
-       }
-
-       --m_packetSize;
-}
+    TargaDecodeGrayPixelRLE() : m_packetSize(0)
+    {
+    }
+
+    void operator()(PointerInputStream &istream, RGBAPixel &pixel)
+    {
+        if (m_packetSize == 0) {
+            targa_packet_read_istream(m_packet, istream);
+            m_packetSize = targa_packet_size(m_packet);
+
+            if (targa_packet_is_rle(m_packet)) {
+                istream_read_gray(istream, m_pixel);
+            }
+        }
+
+        if (targa_packet_is_rle(m_packet)) {
+            pixel = m_pixel;
+        } else {
+            istream_read_gray(istream, pixel);
+        }
+
+        --m_packetSize;
+    }
 };
 
 template<typename Flip>
-void targa_decode_rle_grayscale( PointerInputStream& istream, RGBAImage& image, const Flip& flip ){
-       TargaDecodeGrayPixelRLE decode;
-       image_decode( istream, decode, image, flip );
+void targa_decode_rle_grayscale(PointerInputStream &istream, RGBAImage &image, const Flip &flip)
+{
+    TargaDecodeGrayPixelRLE decode;
+    image_decode(istream, decode, image, flip);
 }
 
-class TargaDecodeRGBPixelRLE
-{
-TargaPacketSize m_packetSize;
-RGBAPixel m_pixel;
-TargaPacket m_packet;
+class TargaDecodeRGBPixelRLE {
+    TargaPacketSize m_packetSize;
+    RGBAPixel m_pixel;
+    TargaPacket m_packet;
 public:
-TargaDecodeRGBPixelRLE() : m_packetSize( 0 ){
-}
-void operator()( PointerInputStream& istream, RGBAPixel& pixel ){
-       if ( m_packetSize == 0 ) {
-               targa_packet_read_istream( m_packet, istream );
-               m_packetSize = targa_packet_size( m_packet );
-
-               if ( targa_packet_is_rle( m_packet ) ) {
-                       istream_read_rgb( istream, m_pixel );
-               }
-       }
-
-       if ( targa_packet_is_rle( m_packet ) ) {
-               pixel = m_pixel;
-       }
-       else
-       {
-               istream_read_rgb( istream, pixel );
-       }
-
-       --m_packetSize;
-}
+    TargaDecodeRGBPixelRLE() : m_packetSize(0)
+    {
+    }
+
+    void operator()(PointerInputStream &istream, RGBAPixel &pixel)
+    {
+        if (m_packetSize == 0) {
+            targa_packet_read_istream(m_packet, istream);
+            m_packetSize = targa_packet_size(m_packet);
+
+            if (targa_packet_is_rle(m_packet)) {
+                istream_read_rgb(istream, m_pixel);
+            }
+        }
+
+        if (targa_packet_is_rle(m_packet)) {
+            pixel = m_pixel;
+        } else {
+            istream_read_rgb(istream, pixel);
+        }
+
+        --m_packetSize;
+    }
 };
 
 template<typename Flip>
-void targa_decode_rle_rgb( PointerInputStream& istream, RGBAImage& image, const Flip& flip ){
-       TargaDecodeRGBPixelRLE decode;
-       image_decode( istream, decode, image, flip );
+void targa_decode_rle_rgb(PointerInputStream &istream, RGBAImage &image, const Flip &flip)
+{
+    TargaDecodeRGBPixelRLE decode;
+    image_decode(istream, decode, image, flip);
 }
 
-class TargaDecodeRGBAPixelRLE
-{
-TargaPacketSize m_packetSize;
-RGBAPixel m_pixel;
-TargaPacket m_packet;
+class TargaDecodeRGBAPixelRLE {
+    TargaPacketSize m_packetSize;
+    RGBAPixel m_pixel;
+    TargaPacket m_packet;
 public:
-TargaDecodeRGBAPixelRLE() : m_packetSize( 0 ){
-}
-void operator()( PointerInputStream& istream, RGBAPixel& pixel ){
-       if ( m_packetSize == 0 ) {
-               targa_packet_read_istream( m_packet, istream );
-               m_packetSize = targa_packet_size( m_packet );
-
-               if ( targa_packet_is_rle( m_packet ) ) {
-                       istream_read_rgba( istream, m_pixel );
-               }
-       }
-
-       if ( targa_packet_is_rle( m_packet ) ) {
-               pixel = m_pixel;
-       }
-       else
-       {
-               istream_read_rgba( istream, pixel );
-       }
-
-       --m_packetSize;
-}
+    TargaDecodeRGBAPixelRLE() : m_packetSize(0)
+    {
+    }
+
+    void operator()(PointerInputStream &istream, RGBAPixel &pixel)
+    {
+        if (m_packetSize == 0) {
+            targa_packet_read_istream(m_packet, istream);
+            m_packetSize = targa_packet_size(m_packet);
+
+            if (targa_packet_is_rle(m_packet)) {
+                istream_read_rgba(istream, m_pixel);
+            }
+        }
+
+        if (targa_packet_is_rle(m_packet)) {
+            pixel = m_pixel;
+        } else {
+            istream_read_rgba(istream, pixel);
+        }
+
+        --m_packetSize;
+    }
 };
 
 template<typename Flip>
-void targa_decode_rle_rgba( PointerInputStream& istream, RGBAImage& image, const Flip& flip ){
-       TargaDecodeRGBAPixelRLE decode;
-       image_decode( istream, decode, image, flip );
+void targa_decode_rle_rgba(PointerInputStream &istream, RGBAImage &image, const Flip &flip)
+{
+    TargaDecodeRGBAPixelRLE decode;
+    image_decode(istream, decode, image, flip);
 }
 
-struct TargaHeader
-{
-       unsigned char id_length, colormap_type, image_type;
-       unsigned short colormap_index, colormap_length;
-       unsigned char colormap_size;
-       unsigned short x_origin, y_origin, width, height;
-       unsigned char pixel_size, attributes;
+struct TargaHeader {
+    unsigned char id_length, colormap_type, image_type;
+    unsigned short colormap_index, colormap_length;
+    unsigned char colormap_size;
+    unsigned short x_origin, y_origin, width, height;
+    unsigned char pixel_size, attributes;
 };
 
-inline void targa_header_read_istream( TargaHeader& targa_header, PointerInputStream& istream ){
-       targa_header.id_length = istream_read_byte( istream );
-       targa_header.colormap_type = istream_read_byte( istream );
-       targa_header.image_type = istream_read_byte( istream );
-
-       targa_header.colormap_index = istream_read_int16_le( istream );
-       targa_header.colormap_length = istream_read_int16_le( istream );
-       targa_header.colormap_size = istream_read_byte( istream );
-       targa_header.x_origin = istream_read_int16_le( istream );
-       targa_header.y_origin = istream_read_int16_le( istream );
-       targa_header.width = istream_read_int16_le( istream );
-       targa_header.height = istream_read_int16_le( istream );
-       targa_header.pixel_size = istream_read_byte( istream );
-       targa_header.attributes = istream_read_byte( istream );
-
-       if ( targa_header.id_length != 0 ) {
-               istream.seek( targa_header.id_length ); // skip TARGA image comment
-       }
+inline void targa_header_read_istream(TargaHeader &targa_header, PointerInputStream &istream)
+{
+    targa_header.id_length = istream_read_byte(istream);
+    targa_header.colormap_type = istream_read_byte(istream);
+    targa_header.image_type = istream_read_byte(istream);
+
+    targa_header.colormap_index = istream_read_int16_le(istream);
+    targa_header.colormap_length = istream_read_int16_le(istream);
+    targa_header.colormap_size = istream_read_byte(istream);
+    targa_header.x_origin = istream_read_int16_le(istream);
+    targa_header.y_origin = istream_read_int16_le(istream);
+    targa_header.width = istream_read_int16_le(istream);
+    targa_header.height = istream_read_int16_le(istream);
+    targa_header.pixel_size = istream_read_byte(istream);
+    targa_header.attributes = istream_read_byte(istream);
+
+    if (targa_header.id_length != 0) {
+        istream.seek(targa_header.id_length); // skip TARGA image comment
+    }
 }
 
 template<typename Type>
-class ScopeDelete
-{
-Type* m_value;
-ScopeDelete( const ScopeDelete& );
-ScopeDelete& operator=( const ScopeDelete& );
+class ScopeDelete {
+    Type *m_value;
+
+    ScopeDelete(const ScopeDelete &);
+
+    ScopeDelete &operator=(const ScopeDelete &);
+
 public:
-ScopeDelete( Type* value ) : m_value( value ){
-}
-~ScopeDelete(){
-       delete m_value;
-}
-Type* get_pointer() const {
-       return m_value;
-}
+    ScopeDelete(Type *value) : m_value(value)
+    {
+    }
+
+    ~ScopeDelete()
+    {
+        delete m_value;
+    }
+
+    Type *get_pointer() const
+    {
+        return m_value;
+    }
 };
 
 template<typename Flip>
-Image* Targa_decodeImageData( const TargaHeader& targa_header, PointerInputStream& istream, const Flip& flip ){
-       RGBAImage* image = new RGBAImage( targa_header.width, targa_header.height );
-
-       if ( targa_header.image_type == 2 || targa_header.image_type == 3 ) {
-               switch ( targa_header.pixel_size )
-               {
-               case 8:
-                       targa_decode_grayscale( istream, *image, flip );
-                       break;
-               case 24:
-                       targa_decode_rgb( istream, *image, flip );
-                       break;
-               case 32:
-                       targa_decode_rgba( istream, *image, flip );
-                       break;
-               default:
-                       globalErrorStream() << "LoadTGA: illegal pixel_size '" << targa_header.pixel_size << "'\n";
-                       image->release();
-                       return 0;
-               }
-       }
-       else if ( targa_header.image_type == 10 || targa_header.image_type == 11 ) {
-               switch ( targa_header.pixel_size )
-               {
-               case 8:
-                       targa_decode_rle_grayscale( istream, *image, flip );
-                       break;
-               case 24:
-                       targa_decode_rle_rgb( istream, *image, flip );
-                       break;
-               case 32:
-                       targa_decode_rle_rgba( istream, *image, flip );
-                       break;
-               default:
-                       globalErrorStream() << "LoadTGA: illegal pixel_size '" << targa_header.pixel_size << "'\n";
-                       image->release();
-                       return 0;
-               }
-       }
-
-       return image;
+Image *Targa_decodeImageData(const TargaHeader &targa_header, PointerInputStream &istream, const Flip &flip)
+{
+    RGBAImage *image = new RGBAImage(targa_header.width, targa_header.height);
+
+    if (targa_header.image_type == 2 || targa_header.image_type == 3) {
+        switch (targa_header.pixel_size) {
+            case 8:
+                targa_decode_grayscale(istream, *image, flip);
+                break;
+            case 24:
+                targa_decode_rgb(istream, *image, flip);
+                break;
+            case 32:
+                targa_decode_rgba(istream, *image, flip);
+                break;
+            default:
+                globalErrorStream() << "LoadTGA: illegal pixel_size '" << targa_header.pixel_size << "'\n";
+                image->release();
+                return 0;
+        }
+    } else if (targa_header.image_type == 10 || targa_header.image_type == 11) {
+        switch (targa_header.pixel_size) {
+            case 8:
+                targa_decode_rle_grayscale(istream, *image, flip);
+                break;
+            case 24:
+                targa_decode_rle_rgb(istream, *image, flip);
+                break;
+            case 32:
+                targa_decode_rle_rgba(istream, *image, flip);
+                break;
+            default:
+                globalErrorStream() << "LoadTGA: illegal pixel_size '" << targa_header.pixel_size << "'\n";
+                image->release();
+                return 0;
+        }
+    }
+
+    return image;
 }
 
 const unsigned int TGA_FLIP_HORIZONTAL = 0x10;
 const unsigned int TGA_FLIP_VERTICAL = 0x20;
 
-Image* LoadTGABuff( const byte* buffer ){
-       PointerInputStream istream( buffer );
-       TargaHeader targa_header;
-
-       targa_header_read_istream( targa_header, istream );
-
-       if ( targa_header.image_type != 2 && targa_header.image_type != 10 && targa_header.image_type != 3 && targa_header.image_type != 11 ) {
-               globalErrorStream() << "LoadTGA: TGA type " << targa_header.image_type << " not supported\n";
-               globalErrorStream() << "LoadTGA: Only type 2 (RGB), 3 (gray), 10 (RGB), and 11 (gray) TGA images supported\n";
-               return 0;
-       }
-
-       if ( targa_header.colormap_type != 0 ) {
-               globalErrorStream() << "LoadTGA: colormaps not supported\n";
-               return 0;
-       }
-
-       if ( ( ( targa_header.image_type == 2 || targa_header.image_type == 10 ) && targa_header.pixel_size != 32 && targa_header.pixel_size != 24 ) ||
-            ( ( targa_header.image_type == 3 || targa_header.image_type == 11 ) && targa_header.pixel_size != 8 ) ) {
-               globalErrorStream() << "LoadTGA: Only 32, 24 or 8 bit images supported\n";
-               return 0;
-       }
-
-       if ( !bitfield_enabled( targa_header.attributes, TGA_FLIP_HORIZONTAL )
-                && !bitfield_enabled( targa_header.attributes, TGA_FLIP_VERTICAL ) ) {
-               return Targa_decodeImageData( targa_header, istream, Flip00() );
-       }
-       if ( !bitfield_enabled( targa_header.attributes, TGA_FLIP_HORIZONTAL )
-                && bitfield_enabled( targa_header.attributes, TGA_FLIP_VERTICAL ) ) {
-               return Targa_decodeImageData( targa_header, istream, Flip01() );
-       }
-       if ( bitfield_enabled( targa_header.attributes, TGA_FLIP_HORIZONTAL )
-                && !bitfield_enabled( targa_header.attributes, TGA_FLIP_VERTICAL ) ) {
-               return Targa_decodeImageData( targa_header, istream, Flip10() );
-       }
-       if ( bitfield_enabled( targa_header.attributes, TGA_FLIP_HORIZONTAL )
-                && bitfield_enabled( targa_header.attributes, TGA_FLIP_VERTICAL ) ) {
-               return Targa_decodeImageData( targa_header, istream, Flip11() );
-       }
-
-       // unreachable
-       return 0;
-}
-
-Image* LoadTGA( ArchiveFile& file ){
-       ScopedArchiveBuffer buffer( file );
-       return LoadTGABuff( buffer.buffer );
+Image *LoadTGABuff(const byte *buffer)
+{
+    PointerInputStream istream(buffer);
+    TargaHeader targa_header;
+
+    targa_header_read_istream(targa_header, istream);
+
+    if (targa_header.image_type != 2 && targa_header.image_type != 10 && targa_header.image_type != 3 &&
+        targa_header.image_type != 11) {
+        globalErrorStream() << "LoadTGA: TGA type " << targa_header.image_type << " not supported\n";
+        globalErrorStream() << "LoadTGA: Only type 2 (RGB), 3 (gray), 10 (RGB), and 11 (gray) TGA images supported\n";
+        return 0;
+    }
+
+    if (targa_header.colormap_type != 0) {
+        globalErrorStream() << "LoadTGA: colormaps not supported\n";
+        return 0;
+    }
+
+    if (((targa_header.image_type == 2 || targa_header.image_type == 10) && targa_header.pixel_size != 32 &&
+         targa_header.pixel_size != 24) ||
+        ((targa_header.image_type == 3 || targa_header.image_type == 11) && targa_header.pixel_size != 8)) {
+        globalErrorStream() << "LoadTGA: Only 32, 24 or 8 bit images supported\n";
+        return 0;
+    }
+
+    if (!bitfield_enabled(targa_header.attributes, TGA_FLIP_HORIZONTAL)
+        && !bitfield_enabled(targa_header.attributes, TGA_FLIP_VERTICAL)) {
+        return Targa_decodeImageData(targa_header, istream, Flip00());
+    }
+    if (!bitfield_enabled(targa_header.attributes, TGA_FLIP_HORIZONTAL)
+        && bitfield_enabled(targa_header.attributes, TGA_FLIP_VERTICAL)) {
+        return Targa_decodeImageData(targa_header, istream, Flip01());
+    }
+    if (bitfield_enabled(targa_header.attributes, TGA_FLIP_HORIZONTAL)
+        && !bitfield_enabled(targa_header.attributes, TGA_FLIP_VERTICAL)) {
+        return Targa_decodeImageData(targa_header, istream, Flip10());
+    }
+    if (bitfield_enabled(targa_header.attributes, TGA_FLIP_HORIZONTAL)
+        && bitfield_enabled(targa_header.attributes, TGA_FLIP_VERTICAL)) {
+        return Targa_decodeImageData(targa_header, istream, Flip11());
+    }
+
+    // unreachable
+    return 0;
+}
+
+Image *LoadTGA(ArchiveFile &file)
+{
+    ScopedArchiveBuffer buffer(file);
+    return LoadTGABuff(buffer.buffer);
 }