]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - plugins/image/ktx.cpp
Revert partially (auto) "reformat code! now the code is only ugly on the *inside*"
[xonotic/netradiant.git] / plugins / image / ktx.cpp
index 9d2205359d3329bb32dc0216e5d8ae3a000fdf90..696ede55dfcaba4b9d5a27cdf6795adfe91f6acf 100644 (file)
 #include "imagelib.h"
 
 
 #include "imagelib.h"
 
 
-const int KTX_TYPE_UNSIGNED_BYTE = 0x1401;
-const int KTX_TYPE_UNSIGNED_SHORT_4_4_4_4 = 0x8033;
-const int KTX_TYPE_UNSIGNED_SHORT_5_5_5_1 = 0x8034;
-const int KTX_TYPE_UNSIGNED_SHORT_5_6_5 = 0x8363;
-
-const int KTX_FORMAT_ALPHA = 0x1906;
-const int KTX_FORMAT_RGB = 0x1907;
-const int KTX_FORMAT_RGBA = 0x1908;
-const int KTX_FORMAT_LUMINANCE = 0x1909;
-const int KTX_FORMAT_LUMINANCE_ALPHA = 0x190A;
-const int KTX_FORMAT_BGR = 0x80E0;
-const int KTX_FORMAT_BGRA = 0x80E1;
-
-const int KTX_FORMAT_ETC1_RGB8 = 0x8D64;
-
-class KTX_Decoder {
+const int KTX_TYPE_UNSIGNED_BYTE                       = 0x1401;
+const int KTX_TYPE_UNSIGNED_SHORT_4_4_4_4      = 0x8033;
+const int KTX_TYPE_UNSIGNED_SHORT_5_5_5_1      = 0x8034;
+const int KTX_TYPE_UNSIGNED_SHORT_5_6_5                = 0x8363;
+
+const int KTX_FORMAT_ALPHA                                     = 0x1906;
+const int KTX_FORMAT_RGB                                       = 0x1907;
+const int KTX_FORMAT_RGBA                                      = 0x1908;
+const int KTX_FORMAT_LUMINANCE                         = 0x1909;
+const int KTX_FORMAT_LUMINANCE_ALPHA           = 0x190A;
+const int KTX_FORMAT_BGR                                       = 0x80E0;
+const int KTX_FORMAT_BGRA                                      = 0x80E1;
+
+const int KTX_FORMAT_ETC1_RGB8                         = 0x8D64;
+
+class KTX_Decoder
+{
 public:
 public:
-    virtual ~KTX_Decoder() = default;
-
-    virtual void Decode(PointerInputStream &istream, byte *out) = 0;
-
-    virtual unsigned int GetPixelSize() = 0;
+       virtual ~KTX_Decoder() = default;
+       virtual void Decode( PointerInputStream& istream, byte* out ) = 0;
+       virtual unsigned int GetPixelSize() = 0;
 };
 
 };
 
-class KTX_Decoder_A8 : public KTX_Decoder {
+class KTX_Decoder_A8 : public KTX_Decoder
+{
 public:
 public:
-    virtual void Decode(PointerInputStream &istream, byte *out)
-    {
-        out[0] = out[1] = out[2] = 0;
-        out[3] = istream_read_byte(istream);
-    }
-
-    virtual unsigned int GetPixelSize()
-    {
-        return 1;
-    }
+       virtual void Decode( PointerInputStream& istream, byte* out ){
+               out[0] = out[1] = out[2] = 0;
+               out[3] = istream_read_byte( istream );
+       }
+       virtual unsigned int GetPixelSize(){
+               return 1;
+       }
 };
 
 };
 
-class KTX_Decoder_RGB8 : public KTX_Decoder {
+class KTX_Decoder_RGB8 : public KTX_Decoder
+{
 public:
 public:
-    virtual void Decode(PointerInputStream &istream, byte *out)
-    {
-        istream.read(out, 3);
-        out[3] = 255;
-    }
-
-    virtual unsigned int GetPixelSize()
-    {
-        return 3;
-    }
+       virtual void Decode( PointerInputStream& istream, byte* out ){
+               istream.read( out, 3 );
+               out[3] = 255;
+       }
+       virtual unsigned int GetPixelSize(){
+               return 3;
+       }
 };
 
 };
 
-class KTX_Decoder_RGBA8 : public KTX_Decoder {
+class KTX_Decoder_RGBA8 : public KTX_Decoder
+{
 public:
 public:
-    virtual void Decode(PointerInputStream &istream, byte *out)
-    {
-        istream.read(out, 4);
-    }
-
-    virtual unsigned int GetPixelSize()
-    {
-        return 4;
-    }
+       virtual void Decode( PointerInputStream& istream, byte* out ){
+               istream.read( out, 4 );
+       }
+       virtual unsigned int GetPixelSize(){
+               return 4;
+       }
 };
 
 };
 
-class KTX_Decoder_L8 : public KTX_Decoder {
+class KTX_Decoder_L8 : public KTX_Decoder
+{
 public:
 public:
-    virtual void Decode(PointerInputStream &istream, byte *out)
-    {
-        byte l = istream_read_byte(istream);
-        out[0] = out[1] = out[2] = l;
-        out[3] = 255;
-    }
-
-    virtual unsigned int GetPixelSize()
-    {
-        return 1;
-    }
+       virtual void Decode( PointerInputStream& istream, byte* out ){
+               byte l = istream_read_byte( istream );
+               out[0] = out[1] = out[2] = l;
+               out[3] = 255;
+       }
+       virtual unsigned int GetPixelSize(){
+               return 1;
+       }
 };
 
 };
 
-class KTX_Decoder_LA8 : public KTX_Decoder {
+class KTX_Decoder_LA8 : public KTX_Decoder
+{
 public:
 public:
-    virtual void Decode(PointerInputStream &istream, byte *out)
-    {
-        byte la[2];
-        istream.read(la, 2);
-        out[0] = out[1] = out[2] = la[0];
-        out[3] = la[1];
-    }
-
-    virtual unsigned int GetPixelSize()
-    {
-        return 2;
-    }
+       virtual void Decode( PointerInputStream& istream, byte* out ){
+               byte la[2];
+               istream.read( la, 2 );
+               out[0] = out[1] = out[2] = la[0];
+               out[3] = la[1];
+       }
+       virtual unsigned int GetPixelSize(){
+               return 2;
+       }
 };
 
 };
 
-class KTX_Decoder_BGR8 : public KTX_Decoder {
+class KTX_Decoder_BGR8 : public KTX_Decoder
+{
 public:
 public:
-    virtual void Decode(PointerInputStream &istream, byte *out)
-    {
-        byte bgr[3];
-        istream.read(bgr, 3);
-        out[0] = bgr[2];
-        out[1] = bgr[1];
-        out[2] = bgr[0];
-        out[3] = 255;
-    }
-
-    virtual unsigned int GetPixelSize()
-    {
-        return 3;
-    }
+       virtual void Decode( PointerInputStream& istream, byte* out ){
+               byte bgr[3];
+               istream.read( bgr, 3 );
+               out[0] = bgr[2];
+               out[1] = bgr[1];
+               out[2] = bgr[0];
+               out[3] = 255;
+       }
+       virtual unsigned int GetPixelSize(){
+               return 3;
+       }
 };
 
 };
 
-class KTX_Decoder_BGRA8 : public KTX_Decoder {
+class KTX_Decoder_BGRA8 : public KTX_Decoder
+{
 public:
 public:
-    virtual void Decode(PointerInputStream &istream, byte *out)
-    {
-        byte bgra[4];
-        istream.read(bgra, 4);
-        out[0] = bgra[2];
-        out[1] = bgra[1];
-        out[2] = bgra[0];
-        out[3] = bgra[3];
-    }
-
-    virtual unsigned int GetPixelSize()
-    {
-        return 4;
-    }
+       virtual void Decode( PointerInputStream& istream, byte* out ){
+               byte bgra[4];
+               istream.read( bgra, 4 );
+               out[0] = bgra[2];
+               out[1] = bgra[1];
+               out[2] = bgra[0];
+               out[3] = bgra[3];
+       }
+       virtual unsigned int GetPixelSize(){
+               return 4;
+       }
 };
 
 };
 
-class KTX_Decoder_RGBA4 : public KTX_Decoder {
+class KTX_Decoder_RGBA4 : public KTX_Decoder
+{
 protected:
 protected:
-    bool m_bigEndian;
+       bool m_bigEndian;
 public:
 public:
-    KTX_Decoder_RGBA4(bool bigEndian) : m_bigEndian(bigEndian)
-    {}
-
-    virtual void Decode(PointerInputStream &istream, byte *out)
-    {
-        uint16_t rgba;
-        if (m_bigEndian) {
-            rgba = istream_read_uint16_be(istream);
-        } else {
-            rgba = istream_read_uint16_le(istream);
-        }
-        int r = (rgba >> 12) & 0xf;
-        int g = (rgba >> 8) & 0xf;
-        int b = (rgba >> 4) & 0xf;
-        int a = rgba & 0xf;
-        out[0] = (r << 4) | r;
-        out[1] = (g << 4) | g;
-        out[2] = (b << 4) | b;
-        out[3] = (a << 4) | a;
-    }
-
-    virtual unsigned int GetPixelSize()
-    {
-        return 2;
-    }
+       KTX_Decoder_RGBA4( bool bigEndian ) : m_bigEndian( bigEndian ){}
+       virtual void Decode( PointerInputStream& istream, byte* out ){
+               uint16_t rgba;
+               if ( m_bigEndian ) {
+                       rgba = istream_read_uint16_be( istream );
+               }
+               else {
+                       rgba = istream_read_uint16_le( istream );
+               }
+               int r = ( rgba >> 12 ) & 0xf;
+               int g = ( rgba >> 8 ) & 0xf;
+               int b = ( rgba >> 4 ) & 0xf;
+               int a = rgba & 0xf;
+               out[0] = ( r << 4 ) | r;
+               out[1] = ( g << 4 ) | g;
+               out[2] = ( b << 4 ) | b;
+               out[3] = ( a << 4 ) | a;
+       }
+       virtual unsigned int GetPixelSize(){
+               return 2;
+       }
 };
 
 };
 
-class KTX_Decoder_RGBA5 : public KTX_Decoder {
+class KTX_Decoder_RGBA5 : public KTX_Decoder
+{
 protected:
 protected:
-    bool m_bigEndian;
+       bool m_bigEndian;
 public:
 public:
-    KTX_Decoder_RGBA5(bool bigEndian) : m_bigEndian(bigEndian)
-    {}
-
-    virtual void Decode(PointerInputStream &istream, byte *out)
-    {
-        uint16_t rgba;
-        if (m_bigEndian) {
-            rgba = istream_read_uint16_be(istream);
-        } else {
-            rgba = istream_read_uint16_le(istream);
-        }
-        int r = (rgba >> 11) & 0x1f;
-        int g = (rgba >> 6) & 0x1f;
-        int b = (rgba >> 1) & 0x1f;
-        out[0] = (r << 3) | (r >> 2);
-        out[1] = (g << 3) | (g >> 2);
-        out[2] = (b << 3) | (b >> 2);
-        out[3] = (rgba & 1) * 255;
-    }
-
-    virtual unsigned int GetPixelSize()
-    {
-        return 2;
-    }
+       KTX_Decoder_RGBA5( bool bigEndian ) : m_bigEndian( bigEndian ){}
+       virtual void Decode( PointerInputStream& istream, byte* out ){
+               uint16_t rgba;
+               if ( m_bigEndian ) {
+                       rgba = istream_read_uint16_be( istream );
+               }
+               else {
+                       rgba = istream_read_uint16_le( istream );
+               }
+               int r = ( rgba >> 11 ) & 0x1f;
+               int g = ( rgba >> 6 ) & 0x1f;
+               int b = ( rgba >> 1 ) & 0x1f;
+               out[0] = ( r << 3 ) | ( r >> 2 );
+               out[1] = ( g << 3 ) | ( g >> 2 );
+               out[2] = ( b << 3 ) | ( b >> 2 );
+               out[3] = ( rgba & 1 ) * 255;
+       }
+       virtual unsigned int GetPixelSize(){
+               return 2;
+       }
 };
 
 };
 
-class KTX_Decoder_RGB5 : public KTX_Decoder {
+class KTX_Decoder_RGB5 : public KTX_Decoder
+{
 protected:
 protected:
-    bool m_bigEndian;
+       bool m_bigEndian;
 public:
 public:
-    KTX_Decoder_RGB5(bool bigEndian) : m_bigEndian(bigEndian)
-    {}
-
-    virtual void Decode(PointerInputStream &istream, byte *out)
-    {
-        uint16_t rgb;
-        if (m_bigEndian) {
-            rgb = istream_read_uint16_be(istream);
-        } else {
-            rgb = istream_read_uint16_le(istream);
-        }
-        int r = (rgb >> 11) & 0x1f;
-        int g = (rgb >> 5) & 0x3f;
-        int b = rgb & 0x1f;
-        out[0] = (r << 3) | (r >> 2);
-        out[1] = (g << 2) | (g >> 4);
-        out[2] = (b << 3) | (b >> 2);
-        out[3] = 255;
-    }
-
-    virtual unsigned int GetPixelSize()
-    {
-        return 2;
-    }
+       KTX_Decoder_RGB5( bool bigEndian ) : m_bigEndian( bigEndian ){}
+       virtual void Decode( PointerInputStream& istream, byte* out ){
+               uint16_t rgb;
+               if ( m_bigEndian ) {
+                       rgb = istream_read_uint16_be( istream );
+               }
+               else {
+                       rgb = istream_read_uint16_le( istream );
+               }
+               int r = ( rgb >> 11 ) & 0x1f;
+               int g = ( rgb >> 5 ) & 0x3f;
+               int b = rgb & 0x1f;
+               out[0] = ( r << 3 ) | ( r >> 2 );
+               out[1] = ( g << 2 ) | ( g >> 4 );
+               out[2] = ( b << 3 ) | ( b >> 2 );
+               out[3] = 255;
+       }
+       virtual unsigned int GetPixelSize(){
+               return 2;
+       }
 };
 
 };
 
-static void KTX_DecodeETC1(PointerInputStream &istream, Image &image)
-{
-    unsigned int width = image.getWidth(), height = image.getHeight();
-    unsigned int stride = width * 4;
-    byte *pixbuf = image.getRGBAPixels();
-    byte etc[8], rgba[64];
-
-    for (unsigned int y = 0; y < height; y += 4, pixbuf += stride * 4) {
-        unsigned int blockrows = height - y;
-        if (blockrows > 4) {
-            blockrows = 4;
-        }
-
-        byte *p = pixbuf;
-        for (unsigned int x = 0; x < width; x += 4, p += 16) {
-            istream.read(etc, 8);
-            ETC_DecodeETC1Block(etc, rgba, qtrue);
-
-            unsigned int blockrowsize = width - x;
-            if (blockrowsize > 4) {
-                blockrowsize = 4;
-            }
-            blockrowsize *= 4;
-            for (unsigned int blockrow = 0; blockrow < blockrows; blockrow++) {
-                memcpy(p + blockrow * stride, rgba + blockrow * 16, blockrowsize);
-            }
-        }
-    }
+static void KTX_DecodeETC1( PointerInputStream& istream, Image& image ){
+       unsigned int width = image.getWidth(), height = image.getHeight();
+       unsigned int stride = width * 4;
+       byte* pixbuf = image.getRGBAPixels();
+       byte etc[8], rgba[64];
+
+       for ( unsigned int y = 0; y < height; y += 4, pixbuf += stride * 4 )
+       {
+               unsigned int blockrows = height - y;
+               if ( blockrows > 4 ) {
+                       blockrows = 4;
+               }
+
+               byte* p = pixbuf;
+               for ( unsigned int x = 0; x < width; x += 4, p += 16 )
+               {
+                       istream.read( etc, 8 );
+                       ETC_DecodeETC1Block( etc, rgba, qtrue );
+
+                       unsigned int blockrowsize = width - x;
+                       if ( blockrowsize > 4 ) {
+                               blockrowsize = 4;
+                       }
+                       blockrowsize *= 4;
+                       for ( unsigned int blockrow = 0; blockrow < blockrows; blockrow++ )
+                       {
+                               memcpy( p + blockrow * stride, rgba + blockrow * 16, blockrowsize );
+                       }
+               }
+       }
 }
 
 }
 
-Image *LoadKTXBuff(PointerInputStream &istream)
-{
-    byte identifier[12];
-    istream.read(identifier, 12);
-    if (memcmp(identifier, "\xABKTX 11\xBB\r\n\x1A\n", 12)) {
-        globalErrorStream() << "LoadKTX: Image has the wrong identifier\n";
-        return 0;
-    }
-
-    bool bigEndian = (istream_read_uint32_le(istream) == 0x01020304);
-
-    unsigned int type;
-    if (bigEndian) {
-        type = istream_read_uint32_be(istream);
-    } else {
-        type = istream_read_uint32_le(istream);
-    }
-
-    // For compressed textures, the format is in glInternalFormat.
-    // For uncompressed textures, it's in glBaseInternalFormat.
-    istream.seek((type ? 3 : 2) * sizeof(uint32_t));
-    unsigned int format;
-    if (bigEndian) {
-        format = istream_read_uint32_be(istream);
-    } else {
-        format = istream_read_uint32_le(istream);
-    }
-    if (!type) {
-        istream.seek(sizeof(uint32_t));
-    }
-
-    unsigned int width, height;
-    if (bigEndian) {
-        width = istream_read_uint32_be(istream);
-        height = istream_read_uint32_be(istream);
-    } else {
-        width = istream_read_uint32_le(istream);
-        height = istream_read_uint32_le(istream);
-    }
-    if (!width) {
-        globalErrorStream() << "LoadKTX: Image has zero width\n";
-        return 0;
-    }
-    if (!height) {
-        height = 1;
-    }
-
-    // Skip the key/values and load the first 2D image in the texture.
-    // Since KTXorientation is only a hint and has no effect on the texture data and coordinates, it must be ignored.
-    istream.seek(4 * sizeof(uint32_t));
-    unsigned int bytesOfKeyValueData;
-    if (bigEndian) {
-        bytesOfKeyValueData = istream_read_uint32_be(istream);
-    } else {
-        bytesOfKeyValueData = istream_read_uint32_le(istream);
-    }
-    istream.seek(bytesOfKeyValueData + sizeof(uint32_t));
-
-    RGBAImage *image = new RGBAImage(width, height);
-
-    if (type) {
-        KTX_Decoder *decoder = NULL;
-        switch (type) {
-            case KTX_TYPE_UNSIGNED_BYTE:
-                switch (format) {
-                    case KTX_FORMAT_ALPHA:
-                        decoder = new KTX_Decoder_A8();
-                        break;
-                    case KTX_FORMAT_RGB:
-                        decoder = new KTX_Decoder_RGB8();
-                        break;
-                    case KTX_FORMAT_RGBA:
-                        decoder = new KTX_Decoder_RGBA8();
-                        break;
-                    case KTX_FORMAT_LUMINANCE:
-                        decoder = new KTX_Decoder_L8();
-                        break;
-                    case KTX_FORMAT_LUMINANCE_ALPHA:
-                        decoder = new KTX_Decoder_LA8();
-                        break;
-                    case KTX_FORMAT_BGR:
-                        decoder = new KTX_Decoder_BGR8();
-                        break;
-                    case KTX_FORMAT_BGRA:
-                        decoder = new KTX_Decoder_BGRA8();
-                        break;
-                }
-                break;
-            case KTX_TYPE_UNSIGNED_SHORT_4_4_4_4:
-                if (format == KTX_FORMAT_RGBA) {
-                    decoder = new KTX_Decoder_RGBA4(bigEndian);
-                }
-                break;
-            case KTX_TYPE_UNSIGNED_SHORT_5_5_5_1:
-                if (format == KTX_FORMAT_RGBA) {
-                    decoder = new KTX_Decoder_RGBA5(bigEndian);
-                }
-                break;
-            case KTX_TYPE_UNSIGNED_SHORT_5_6_5:
-                if (format == KTX_FORMAT_RGB) {
-                    decoder = new KTX_Decoder_RGB5(bigEndian);
-                }
-                break;
-        }
-
-        if (!decoder) {
-            globalErrorStream() << "LoadKTX: Image has an unsupported pixel type " << type << " or format " << format
-                                << "\n";
-            image->release();
-            return 0;
-        }
-
-        unsigned int inRowLength = width * decoder->GetPixelSize();
-        unsigned int inPadding = ((inRowLength + 3) & ~3) - inRowLength;
-        byte *out = image->getRGBAPixels();
-        for (unsigned int y = 0; y < height; y++) {
-            for (unsigned int x = 0; x < width; x++, out += 4) {
-                decoder->Decode(istream, out);
-            }
-
-            if (inPadding) {
-                istream.seek(inPadding);
-            }
-        }
-
-        delete decoder;
-    } else {
-        switch (format) {
-            case KTX_FORMAT_ETC1_RGB8:
-                KTX_DecodeETC1(istream, *image);
-                break;
-            default:
-                globalErrorStream() << "LoadKTX: Image has an unsupported compressed format " << format << "\n";
-                image->release();
-                return 0;
-        }
-    }
-
-    return image;
+Image* LoadKTXBuff( PointerInputStream& istream ){
+       byte identifier[12];
+       istream.read( identifier, 12 );
+       if ( memcmp( identifier, "\xABKTX 11\xBB\r\n\x1A\n", 12 ) ) {
+               globalErrorStream() << "LoadKTX: Image has the wrong identifier\n";
+               return 0;
+       }
+
+       bool bigEndian = ( istream_read_uint32_le( istream ) == 0x01020304 );
+
+       unsigned int type;
+       if ( bigEndian ) {
+               type = istream_read_uint32_be( istream );
+       }
+       else {
+               type = istream_read_uint32_le( istream );
+       }
+
+       // For compressed textures, the format is in glInternalFormat.
+       // For uncompressed textures, it's in glBaseInternalFormat.
+       istream.seek( ( type ? 3 : 2 ) * sizeof( uint32_t ) );
+       unsigned int format;
+       if ( bigEndian ) {
+               format = istream_read_uint32_be( istream );
+       }
+       else {
+               format = istream_read_uint32_le( istream );
+       }
+       if ( !type ) {
+               istream.seek( sizeof( uint32_t ) );
+       }
+
+       unsigned int width, height;
+       if ( bigEndian ) {
+               width = istream_read_uint32_be( istream );
+               height = istream_read_uint32_be( istream );
+       }
+       else {
+               width = istream_read_uint32_le( istream );
+               height = istream_read_uint32_le( istream );
+       }
+       if ( !width ) {
+               globalErrorStream() << "LoadKTX: Image has zero width\n";
+               return 0;
+       }
+       if ( !height ) {
+               height = 1;
+       }
+
+       // Skip the key/values and load the first 2D image in the texture.
+       // Since KTXorientation is only a hint and has no effect on the texture data and coordinates, it must be ignored.
+       istream.seek( 4 * sizeof( uint32_t ) );
+       unsigned int bytesOfKeyValueData;
+       if ( bigEndian ) {
+               bytesOfKeyValueData = istream_read_uint32_be( istream );
+       }
+       else {
+               bytesOfKeyValueData = istream_read_uint32_le( istream );
+       }
+       istream.seek( bytesOfKeyValueData + sizeof( uint32_t ) );
+
+       RGBAImage* image = new RGBAImage( width, height );
+
+       if ( type ) {
+               KTX_Decoder* decoder = NULL;
+               switch ( type )
+               {
+               case KTX_TYPE_UNSIGNED_BYTE:
+                       switch ( format )
+                       {
+                       case KTX_FORMAT_ALPHA:
+                               decoder = new KTX_Decoder_A8();
+                               break;
+                       case KTX_FORMAT_RGB:
+                               decoder = new KTX_Decoder_RGB8();
+                               break;
+                       case KTX_FORMAT_RGBA:
+                               decoder = new KTX_Decoder_RGBA8();
+                               break;
+                       case KTX_FORMAT_LUMINANCE:
+                               decoder = new KTX_Decoder_L8();
+                               break;
+                       case KTX_FORMAT_LUMINANCE_ALPHA:
+                               decoder = new KTX_Decoder_LA8();
+                               break;
+                       case KTX_FORMAT_BGR:
+                               decoder = new KTX_Decoder_BGR8();
+                               break;
+                       case KTX_FORMAT_BGRA:
+                               decoder = new KTX_Decoder_BGRA8();
+                               break;
+                       }
+                       break;
+               case KTX_TYPE_UNSIGNED_SHORT_4_4_4_4:
+                       if ( format == KTX_FORMAT_RGBA ) {
+                               decoder = new KTX_Decoder_RGBA4( bigEndian );
+                       }
+                       break;
+               case KTX_TYPE_UNSIGNED_SHORT_5_5_5_1:
+                       if ( format == KTX_FORMAT_RGBA ) {
+                               decoder = new KTX_Decoder_RGBA5( bigEndian );
+                       }
+                       break;
+               case KTX_TYPE_UNSIGNED_SHORT_5_6_5:
+                       if ( format == KTX_FORMAT_RGB ) {
+                               decoder = new KTX_Decoder_RGB5( bigEndian );
+                       }
+                       break;
+               }
+
+               if ( !decoder ) {
+                       globalErrorStream() << "LoadKTX: Image has an unsupported pixel type " << type << " or format " << format << "\n";
+                       image->release();
+                       return 0;
+               }
+
+               unsigned int inRowLength = width * decoder->GetPixelSize();
+               unsigned int inPadding = ( ( inRowLength + 3 ) & ~3 ) - inRowLength;
+               byte* out = image->getRGBAPixels();
+               for ( unsigned int y = 0; y < height; y++ )
+               {
+                       for ( unsigned int x = 0; x < width; x++, out += 4 )
+                       {
+                               decoder->Decode( istream, out );
+                       }
+
+                       if ( inPadding ) {
+                               istream.seek( inPadding );
+                       }
+               }
+
+               delete decoder;
+       }
+       else {
+               switch ( format )
+               {
+               case KTX_FORMAT_ETC1_RGB8:
+                       KTX_DecodeETC1( istream, *image );
+                       break;
+               default:
+                       globalErrorStream() << "LoadKTX: Image has an unsupported compressed format " << format << "\n";
+                       image->release();
+                       return 0;
+               }
+       }
+
+       return image;
 }
 
 }
 
-Image *LoadKTX(ArchiveFile &file)
-{
-    ScopedArchiveBuffer buffer(file);
-    PointerInputStream istream(buffer.buffer);
-    return LoadKTXBuff(istream);
+Image* LoadKTX( ArchiveFile& file ){
+       ScopedArchiveBuffer buffer( file );
+       PointerInputStream istream( buffer.buffer );
+       return LoadKTXBuff( istream );
 }
 }