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