-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;