From 7243a22abc0f48f72706215c6bd955212b583120 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Thu, 1 Nov 2012 23:07:51 +0000 Subject: [PATCH] - added byte order logic for loading textures and sounds --- .../shared_lib/sources/graphics/BMPReader.cpp | 40 +++++- .../shared_lib/sources/graphics/JPGReader.cpp | 4 + .../shared_lib/sources/graphics/PNGReader.cpp | 13 ++ .../shared_lib/sources/graphics/TGAReader.cpp | 68 ++++++++++ source/shared_lib/sources/graphics/pixmap.cpp | 123 +++++++++++++++++- .../sources/sound/sound_file_loader.cpp | 59 +++++++++ 6 files changed, 301 insertions(+), 6 deletions(-) diff --git a/source/shared_lib/sources/graphics/BMPReader.cpp b/source/shared_lib/sources/graphics/BMPReader.cpp index 3bdb8b6e..935415ee 100644 --- a/source/shared_lib/sources/graphics/BMPReader.cpp +++ b/source/shared_lib/sources/graphics/BMPReader.cpp @@ -80,15 +80,41 @@ Pixmap2D* BMPReader::read(ifstream& in, const string& path, Pixmap2D* ret) const //read file header BitmapFileHeader fileHeader; in.read((char*)&fileHeader, sizeof(BitmapFileHeader)); + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if(bigEndianSystem == true) { + fileHeader.offsetBits = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.offsetBits); + fileHeader.reserved1 = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.reserved1); + fileHeader.reserved2 = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.reserved2); + fileHeader.size = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.size); + fileHeader.type1 = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.type1); + fileHeader.type2 = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.type2); + } + if(fileHeader.type1!='B' || fileHeader.type2!='M'){ throw megaglest_runtime_error(path +" is not a bitmap"); } - //read info header + + //read info header BitmapInfoHeader infoHeader; in.read((char*)&infoHeader, sizeof(BitmapInfoHeader)); + if(bigEndianSystem == true) { + infoHeader.bitCount = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.bitCount); + infoHeader.clrImportant = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.clrImportant); + infoHeader.clrUsed = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.clrUsed); + infoHeader.compression = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.compression); + infoHeader.height = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.height); + infoHeader.planes = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.planes); + infoHeader.size = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.size); + infoHeader.sizeImage = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.sizeImage); + infoHeader.width = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.width); + infoHeader.xPelsPerMeter = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.xPelsPerMeter); + infoHeader.yPelsPerMeter = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.yPelsPerMeter); + } + if(infoHeader.bitCount!=24){ throw megaglest_runtime_error(path+" is not a 24 bit bitmap"); } + int h= infoHeader.height; int w= infoHeader.width; int components= (ret->getComponents() == -1)?3:ret->getComponents(); @@ -104,8 +130,20 @@ Pixmap2D* BMPReader::read(ifstream& in, const string& path, Pixmap2D* ret) const for (int x = 0; x < w; ++x, i+=components) { uint8 r, g, b; in.read((char*)&b, 1); + if(bigEndianSystem == true) { + b = Shared::PlatformByteOrder::fromCommonEndian(b); + } + in.read((char*)&g, 1); + if(bigEndianSystem == true) { + g = Shared::PlatformByteOrder::fromCommonEndian(g); + } + in.read((char*)&r, 1); + if(bigEndianSystem == true) { + r = Shared::PlatformByteOrder::fromCommonEndian(r); + } + if (!in.good()) { return NULL; } diff --git a/source/shared_lib/sources/graphics/JPGReader.cpp b/source/shared_lib/sources/graphics/JPGReader.cpp index ef334890..756e333a 100644 --- a/source/shared_lib/sources/graphics/JPGReader.cpp +++ b/source/shared_lib/sources/graphics/JPGReader.cpp @@ -82,6 +82,10 @@ Pixmap2D* JPGReader::read(ifstream& is, const string& path, Pixmap2D* ret) const is.seekg(0, ios::beg); uint8 *buffer = new uint8[(unsigned int)length]; is.read((char*)buffer, (std::streamsize)length); + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if(bigEndianSystem == true) { + Shared::PlatformByteOrder::fromEndianTypeArray(buffer,length); + } //Check buffer (weak jpeg check) //if (buffer[0] != 0x46 || buffer[1] != 0xA0) { // Proper header check found from: http://www.fastgraph.com/help/jpeg_header_format.html diff --git a/source/shared_lib/sources/graphics/PNGReader.cpp b/source/shared_lib/sources/graphics/PNGReader.cpp index cb473f6d..88e5c03f 100644 --- a/source/shared_lib/sources/graphics/PNGReader.cpp +++ b/source/shared_lib/sources/graphics/PNGReader.cpp @@ -33,6 +33,11 @@ namespace Shared{ namespace Graphics{ static void user_read_data(png_structp read_ptr, png_bytep data, png_size_t length) { ifstream& is = *((ifstream*)png_get_io_ptr(read_ptr)); is.read((char*)data,(std::streamsize)length); + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if(bigEndianSystem == true) { + Shared::PlatformByteOrder::fromEndianTypeArray(data,length); + } + if (!is.good()) { png_error(read_ptr,"Could not read from png-file"); } @@ -67,6 +72,10 @@ Pixmap2D* PNGReader::read(ifstream& is, const string& path, Pixmap2D* ret) const is.seekg(0, ios::beg); uint8 *buffer = new uint8[8]; is.read((char*)buffer, 8); + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if(bigEndianSystem == true) { + Shared::PlatformByteOrder::fromEndianTypeArray(buffer,8); + } if (png_sig_cmp(buffer, 0, 8) != 0) { delete [] buffer; @@ -208,6 +217,10 @@ Pixmap3D* PNGReader3D::read(ifstream& is, const string& path, Pixmap3D* ret) con is.seekg(0, ios::beg); uint8 *buffer = new uint8[8]; is.read((char*)buffer, 8); + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if(bigEndianSystem == true) { + Shared::PlatformByteOrder::fromEndianTypeArray(buffer,8); + } if (png_sig_cmp(buffer, 0, 8) != 0) { delete [] buffer; diff --git a/source/shared_lib/sources/graphics/TGAReader.cpp b/source/shared_lib/sources/graphics/TGAReader.cpp index 59ce3e1b..c0336b87 100644 --- a/source/shared_lib/sources/graphics/TGAReader.cpp +++ b/source/shared_lib/sources/graphics/TGAReader.cpp @@ -70,6 +70,20 @@ Pixmap3D* TGAReader3D::read(ifstream& in, const string& path, Pixmap3D* ret) con //read header TargaFileHeader fileHeader; in.read((char*)&fileHeader, sizeof(TargaFileHeader)); + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if(bigEndianSystem == true) { + fileHeader.bitsPerPixel = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.bitsPerPixel); + fileHeader.colourMapDepth = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapDepth); + fileHeader.colourMapLength = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapDepth); + fileHeader.colourMapOrigin = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapOrigin); + fileHeader.colourMapType = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapType); + fileHeader.dataTypeCode = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.dataTypeCode); + fileHeader.height = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.height); + fileHeader.idLength = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.idLength); + fileHeader.imageDescriptor = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.imageDescriptor); + fileHeader.width = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.width); + } + if (!in.good()) { throw megaglest_runtime_error(path + " could not be read"); } @@ -108,6 +122,10 @@ Pixmap3D* TGAReader3D::read(ifstream& in, const string& path, Pixmap3D* ret) con if(fileComponents==1){ in.read((char*)&l,1); + if(bigEndianSystem == true) { + l = Shared::PlatformByteOrder::fromCommonEndian(l); + } + r= l; g= l; b= l; @@ -115,10 +133,26 @@ Pixmap3D* TGAReader3D::read(ifstream& in, const string& path, Pixmap3D* ret) con } else{ in.read((char*)&b, 1); + if(bigEndianSystem == true) { + b = Shared::PlatformByteOrder::fromCommonEndian(b); + } + in.read((char*)&g, 1); + if(bigEndianSystem == true) { + g = Shared::PlatformByteOrder::fromCommonEndian(g); + } + in.read((char*)&r, 1); + if(bigEndianSystem == true) { + r = Shared::PlatformByteOrder::fromCommonEndian(r); + } + if(fileComponents==4){ in.read((char*)&a, 1); + if(bigEndianSystem == true) { + a = Shared::PlatformByteOrder::fromCommonEndian(a); + } + } else { a= 255; } @@ -169,6 +203,20 @@ Pixmap2D* TGAReader::read(ifstream& in, const string& path, Pixmap2D* ret) const //read header TargaFileHeader fileHeader; in.read((char*)&fileHeader, sizeof(TargaFileHeader)); + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if(bigEndianSystem == true) { + fileHeader.bitsPerPixel = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.bitsPerPixel); + fileHeader.colourMapDepth = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapDepth); + fileHeader.colourMapLength = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapDepth); + fileHeader.colourMapOrigin = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapOrigin); + fileHeader.colourMapType = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapType); + fileHeader.dataTypeCode = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.dataTypeCode); + fileHeader.height = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.height); + fileHeader.idLength = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.idLength); + fileHeader.imageDescriptor = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.imageDescriptor); + fileHeader.width = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.width); + } + if (!in.good()) { throw megaglest_runtime_error(path + " could not be read"); } @@ -200,6 +248,10 @@ Pixmap2D* TGAReader::read(ifstream& in, const string& path, Pixmap2D* ret) const if(fileComponents==1){ in.read((char*)&l,1); + if(bigEndianSystem == true) { + l = Shared::PlatformByteOrder::fromCommonEndian(l); + } + r= l; g= l; b= l; @@ -207,10 +259,26 @@ Pixmap2D* TGAReader::read(ifstream& in, const string& path, Pixmap2D* ret) const } else{ in.read((char*)&b, 1); + if(bigEndianSystem == true) { + b = Shared::PlatformByteOrder::fromCommonEndian(b); + } + in.read((char*)&g, 1); + if(bigEndianSystem == true) { + g = Shared::PlatformByteOrder::fromCommonEndian(g); + } + in.read((char*)&r, 1); + if(bigEndianSystem == true) { + r = Shared::PlatformByteOrder::fromCommonEndian(r); + } + if(fileComponents==4){ in.read((char*)&a, 1); + if(bigEndianSystem == true) { + a = Shared::PlatformByteOrder::fromCommonEndian(a); + } + } else { a= 255; } diff --git a/source/shared_lib/sources/graphics/pixmap.cpp b/source/shared_lib/sources/graphics/pixmap.cpp index e74ff9de..7b8dd97a 100644 --- a/source/shared_lib/sources/graphics/pixmap.cpp +++ b/source/shared_lib/sources/graphics/pixmap.cpp @@ -125,7 +125,19 @@ void PixmapIoTga::openRead(const string &path) { snprintf(szBuf,8096,"fread returned wrong size = %zu on line: %d.",readBytes,__LINE__); throw megaglest_runtime_error(szBuf); } - + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if(bigEndianSystem == true) { + fileHeader.bitsPerPixel = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.bitsPerPixel); + fileHeader.colourMapDepth = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapDepth); + fileHeader.colourMapLength = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapDepth); + fileHeader.colourMapOrigin = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapOrigin); + fileHeader.colourMapType = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapType); + fileHeader.dataTypeCode = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.dataTypeCode); + fileHeader.height = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.height); + fileHeader.idLength = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.idLength); + fileHeader.imageDescriptor = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.imageDescriptor); + fileHeader.width = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.width); + } //check that we can load this tga file if(fileHeader.idLength != 0) { throw megaglest_runtime_error(path + ": id field is not 0"); @@ -150,6 +162,8 @@ void PixmapIoTga::read(uint8 *pixels) { } void PixmapIoTga::read(uint8 *pixels, int components) { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + for(int i=0; icomponents == 4) { readBytes = fread(&a, 1, 1, file); @@ -195,6 +220,9 @@ void PixmapIoTga::read(uint8 *pixels, int components) { snprintf(szBuf,8096,"fread returned wrong size = %zu on line: %d.",readBytes,__LINE__); throw megaglest_runtime_error(szBuf); } + if(bigEndianSystem == true) { + a = Shared::PlatformByteOrder::fromCommonEndian(a); + } } else { @@ -244,14 +272,39 @@ void PixmapIoTga::openWrite(const string &path, int w, int h, int components) { fileHeader.height= h; fileHeader.imageDescriptor= components==4? 8: 0; + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if(bigEndianSystem == true) { + fileHeader.bitsPerPixel = Shared::PlatformByteOrder::toCommonEndian(fileHeader.bitsPerPixel); + fileHeader.colourMapDepth = Shared::PlatformByteOrder::toCommonEndian(fileHeader.colourMapDepth); + fileHeader.colourMapLength = Shared::PlatformByteOrder::toCommonEndian(fileHeader.colourMapDepth); + fileHeader.colourMapOrigin = Shared::PlatformByteOrder::toCommonEndian(fileHeader.colourMapOrigin); + fileHeader.colourMapType = Shared::PlatformByteOrder::toCommonEndian(fileHeader.colourMapType); + fileHeader.dataTypeCode = Shared::PlatformByteOrder::toCommonEndian(fileHeader.dataTypeCode); + fileHeader.height = Shared::PlatformByteOrder::toCommonEndian(fileHeader.height); + fileHeader.idLength = Shared::PlatformByteOrder::toCommonEndian(fileHeader.idLength); + fileHeader.imageDescriptor = Shared::PlatformByteOrder::toCommonEndian(fileHeader.imageDescriptor); + fileHeader.width = Shared::PlatformByteOrder::toCommonEndian(fileHeader.width); + } + fwrite(&fileHeader, sizeof(TargaFileHeader), 1, file); } void PixmapIoTga::write(uint8 *pixels) { if(components == 1) { + + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if(bigEndianSystem == true) { + Shared::PlatformByteOrder::toEndianTypeArray(pixels,h*w); + } + fwrite(pixels, h*w, 1, file); } else { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if(bigEndianSystem == true) { + Shared::PlatformByteOrder::toEndianTypeArray(pixels,h*w*components); + } + for(int i=0; i(pixels,h*w*components); + } + for (int i=0; isetChannels(size16); //first sub-chunk (header) - Data (nsamplesPerSecond) f.read((char*) &size32, 4); + if(bigEndianSystem == true) { + size32 = Shared::PlatformByteOrder::fromCommonEndian(size32); + } + soundInfo->setsamplesPerSecond(size32); //first sub-chunk (header) - Data (nAvgBytesPerSec) - Ignore f.read((char*) &size32, 4); + if(bigEndianSystem == true) { + size32 = Shared::PlatformByteOrder::fromCommonEndian(size32); + } //first sub-chunk (header) - Data (blockAlign) - Ignore f.read((char*) &size16, 2); + if(bigEndianSystem == true) { + size16 = Shared::PlatformByteOrder::fromCommonEndian(size16); + } //first sub-chunk (header) - Data (nsamplesPerSecond) f.read((char*) &size16, 2); + if(bigEndianSystem == true) { + size16 = Shared::PlatformByteOrder::fromCommonEndian(size16); + } + soundInfo->setBitsPerSample(size16); soundInfo->setBitRate(soundInfo->getSamplesPerSecond() * soundInfo->getChannels() * soundInfo->getBitsPerSample() / 8); @@ -106,12 +150,22 @@ void WavSoundFileLoader::open(const string &path, SoundInfo *soundInfo){ // === DATA === //second sub-chunk (samples) - Id f.read(chunkId, 4); + if(bigEndianSystem == true) { + for(unsigned int i = 0; i < 4; ++i) { + chunkId[i] = Shared::PlatformByteOrder::fromCommonEndian(chunkId[i]); + } + } + if(strncmp(chunkId, "data", 4)!=0){ continue; } //second sub-chunk (samples) - Size f.read((char*) &size32, 4); + if(bigEndianSystem == true) { + size32 = Shared::PlatformByteOrder::fromCommonEndian(size32); + } + dataSize= size32; soundInfo->setSize(dataSize); } @@ -127,6 +181,11 @@ void WavSoundFileLoader::open(const string &path, SoundInfo *soundInfo){ uint32 WavSoundFileLoader::read(int8 *samples, uint32 size){ f.read(reinterpret_cast (samples), size); + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if(bigEndianSystem == true) { + Shared::PlatformByteOrder::toEndianTypeArray(samples,size); + } + return (uint32)f.gcount(); }