- updated error handling to be more flexible so we can display better error details (like bad tga file, etc)

This commit is contained in:
Mark Vejvoda
2012-11-10 23:19:42 +00:00
parent 56e4843d13
commit 8ba5524f35
12 changed files with 377 additions and 258 deletions

View File

@@ -66,133 +66,143 @@ static inline std::vector<string> getExtensionStrings() {
TGAReader3D::TGAReader3D(): FileReader<Pixmap3D>(getExtensionStrings()) {}
Pixmap3D* TGAReader3D::read(ifstream& in, const string& path, Pixmap3D* ret) const {
assert(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false);
//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");
}
//check that we can load this tga file
if(fileHeader.idLength!=0){
throw megaglest_runtime_error(path + ": id field is not 0");
}
if(fileHeader.dataTypeCode!=tgaUncompressedRgb && fileHeader.dataTypeCode!=tgaUncompressedBw){
throw megaglest_runtime_error(path + ": only uncompressed BW and RGB targa images are supported");
}
//check bits per pixel
if(fileHeader.bitsPerPixel!=8 && fileHeader.bitsPerPixel!=24 && fileHeader.bitsPerPixel!=32){
throw megaglest_runtime_error(path + ": only 8, 24 and 32 bit targa images are supported");
}
const int h = fileHeader.height;
const int w = fileHeader.width;
const int d = ret->getD();
const int slice = ret->getSlice();
const int fileComponents= fileHeader.bitsPerPixel/8;
const int picComponents = (ret->getComponents()==-1)?fileComponents:ret->getComponents();
//std::cout << "TGA-Components: Pic: " << picComponents << " old: " << (ret->getComponents()) << " File: " << fileComponents << " slice:" << ret->getSlice() << std::endl;
if(ret->getPixels() == NULL){
ret->init(w,h,d, picComponents);
}
uint8* pixels = ret->getPixels();
if(slice > 0) {
pixels = &pixels[slice*w*h*picComponents];
}
//read file
for(int i=0; i<h*w*picComponents; i+=picComponents){
uint8 r=0, g=0, b=0, a=0, l=0;
if(fileComponents==1){
in.read((char*)&l,1);
if(bigEndianSystem == true) {
l = Shared::PlatformByteOrder::fromCommonEndian(l);
}
r= l;
g= l;
b= l;
a= 255;
//printf("In [%s] line: %d\n",__FILE__,__LINE__);
// try {
assert(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false);
//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);
}
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);
}
if (!in.good()) {
throw megaglest_runtime_error(path + " could not be read",true);
}
in.read((char*)&r, 1);
if(bigEndianSystem == true) {
r = Shared::PlatformByteOrder::fromCommonEndian(r);
}
//check that we can load this tga file
if(fileHeader.idLength!=0){
throw megaglest_runtime_error(path + ": id field is not 0",true);
}
if(fileComponents==4){
in.read((char*)&a, 1);
if(fileHeader.dataTypeCode!=tgaUncompressedRgb && fileHeader.dataTypeCode!=tgaUncompressedBw){
throw megaglest_runtime_error(path + ": only uncompressed BW and RGB targa images are supported",true);
}
//check bits per pixel
if(fileHeader.bitsPerPixel!=8 && fileHeader.bitsPerPixel!=24 && fileHeader.bitsPerPixel!=32){
throw megaglest_runtime_error(path + ": only 8, 24 and 32 bit targa images are supported",true);
}
const int h = fileHeader.height;
const int w = fileHeader.width;
const int d = ret->getD();
const int slice = ret->getSlice();
const int fileComponents= fileHeader.bitsPerPixel/8;
const int picComponents = (ret->getComponents()==-1)?fileComponents:ret->getComponents();
//std::cout << "TGA-Components: Pic: " << picComponents << " old: " << (ret->getComponents()) << " File: " << fileComponents << " slice:" << ret->getSlice() << std::endl;
if(ret->getPixels() == NULL){
ret->init(w,h,d, picComponents);
}
uint8* pixels = ret->getPixels();
if(slice > 0) {
pixels = &pixels[slice*w*h*picComponents];
}
//read file
for(int i=0; i<h*w*picComponents; i+=picComponents){
uint8 r=0, g=0, b=0, a=0, l=0;
if(fileComponents==1){
in.read((char*)&l,1);
if(bigEndianSystem == true) {
a = Shared::PlatformByteOrder::fromCommonEndian(a);
l = Shared::PlatformByteOrder::fromCommonEndian(l);
}
} else {
r= l;
g= l;
b= l;
a= 255;
}
l= (r+g+b)/3;
}
//if (!in.good()) {
// return NULL;
//}
else{
in.read((char*)&b, 1);
if(bigEndianSystem == true) {
b = Shared::PlatformByteOrder::fromCommonEndian(b);
}
switch(picComponents){
case 1:
pixels[i]= l;
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;
}
l= (r+g+b)/3;
}
//if (!in.good()) {
// return NULL;
//}
switch(picComponents){
case 1:
pixels[i]= l;
break;
case 3:
pixels[i]= r;
pixels[i+1]= g;
pixels[i+2]= b;
break;
case 4:
pixels[i]= r;
pixels[i+1]= g;
pixels[i+2]= b;
pixels[i+3]= a;
break;
case 3:
pixels[i]= r;
pixels[i+1]= g;
pixels[i+2]= b;
break;
case 4:
pixels[i]= r;
pixels[i+1]= g;
pixels[i+2]= b;
pixels[i+3]= a;
break;
}
}
}
/*for(int i = 0; i < w*h*picComponents; ++i) {
if (i%39 == 0) std::cout << std::endl;
int first = pixels[i]/16;
if (first < 10)
std:: cout << first;
else
std::cout << (char)('A'+(first-10));
first = pixels[i]%16;
if (first < 10)
std:: cout << first;
else
std::cout << (char)('A'+(first-10));
std::cout << " ";
}*/
/*for(int i = 0; i < w*h*picComponents; ++i) {
if (i%39 == 0) std::cout << std::endl;
int first = pixels[i]/16;
if (first < 10)
std:: cout << first;
else
std::cout << (char)('A'+(first-10));
first = pixels[i]%16;
if (first < 10)
std:: cout << first;
else
std::cout << (char)('A'+(first-10));
std::cout << " ";
}*/
// }
// catch(exception& ex) {
// char szBuf[8096]="";
// snprintf(szBuf,8096,"Error in [%s] on line: %d msg: %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,ex.what());
// throw megaglest_runtime_error(szBuf);
// }
return ret;
}
@@ -200,125 +210,137 @@ Pixmap3D* TGAReader3D::read(ifstream& in, const string& path, Pixmap3D* ret) con
TGAReader::TGAReader(): FileReader<Pixmap2D>(getExtensionStrings()) {}
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");
}
//check that we can load this tga file
if(fileHeader.idLength!=0){
throw megaglest_runtime_error(path + ": id field is not 0");
}
if(fileHeader.dataTypeCode!=tgaUncompressedRgb && fileHeader.dataTypeCode!=tgaUncompressedBw){
throw megaglest_runtime_error(path + ": only uncompressed BW and RGB targa images are supported");
}
//check bits per pixel
if(fileHeader.bitsPerPixel!=8 && fileHeader.bitsPerPixel!=24 && fileHeader.bitsPerPixel!=32){
throw megaglest_runtime_error(path + ": only 8, 24 and 32 bit targa images are supported");
}
const int h = fileHeader.height;
const int w = fileHeader.width;
const int fileComponents= fileHeader.bitsPerPixel/8;
const int picComponents = (ret->getComponents()==-1)?fileComponents:ret->getComponents();
//std::cout << "TGA-Components: Pic: " << picComponents << " old: " << (ret->getComponents()) << " File: " << fileComponents << std::endl;
ret->init(w,h,picComponents);
uint8* pixels = ret->getPixels();
//read file
for(int i=0; i<h*w*picComponents; i+=picComponents){
uint8 r=0, g=0, b=0, a=0, l=0;
if(fileComponents==1){
in.read((char*)&l,1);
if(bigEndianSystem == true) {
l = Shared::PlatformByteOrder::fromCommonEndian(l);
}
r= l;
g= l;
b= l;
a= 255;
//printf("In [%s] line: %d\n",__FILE__,__LINE__);
//try {
//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);
}
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);
}
if (!in.good()) {
throw megaglest_runtime_error(path + " could not be read",true);
}
in.read((char*)&r, 1);
if(bigEndianSystem == true) {
r = Shared::PlatformByteOrder::fromCommonEndian(r);
}
//check that we can load this tga file
if(fileHeader.idLength!=0){
throw megaglest_runtime_error(path + ": id field is not 0",true);
}
if(fileComponents==4){
in.read((char*)&a, 1);
if(fileHeader.dataTypeCode!=tgaUncompressedRgb && fileHeader.dataTypeCode!=tgaUncompressedBw){
throw megaglest_runtime_error(path + ": only uncompressed BW and RGB targa images are supported",true);
}
//check bits per pixel
if(fileHeader.bitsPerPixel!=8 && fileHeader.bitsPerPixel!=24 && fileHeader.bitsPerPixel!=32){
throw megaglest_runtime_error(path + ": only 8, 24 and 32 bit targa images are supported",true);
}
const int h = fileHeader.height;
const int w = fileHeader.width;
const int fileComponents= fileHeader.bitsPerPixel/8;
const int picComponents = (ret->getComponents()==-1)?fileComponents:ret->getComponents();
//std::cout << "TGA-Components: Pic: " << picComponents << " old: " << (ret->getComponents()) << " File: " << fileComponents << std::endl;
ret->init(w,h,picComponents);
uint8* pixels = ret->getPixels();
//read file
for(int i=0; i<h*w*picComponents; i+=picComponents){
uint8 r=0, g=0, b=0, a=0, l=0;
if(fileComponents==1){
in.read((char*)&l,1);
if(bigEndianSystem == true) {
a = Shared::PlatformByteOrder::fromCommonEndian(a);
l = Shared::PlatformByteOrder::fromCommonEndian(l);
}
} else {
r= l;
g= l;
b= l;
a= 255;
}
l= (r+g+b)/3;
}
if (!in.good()) {
return NULL;
}
else{
in.read((char*)&b, 1);
if(bigEndianSystem == true) {
b = Shared::PlatformByteOrder::fromCommonEndian(b);
}
switch(picComponents){
case 1:
pixels[i]= l;
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;
}
l= (r+g+b)/3;
}
if (!in.good()) {
return NULL;
}
switch(picComponents){
case 1:
pixels[i]= l;
break;
case 3:
pixels[i]= r;
pixels[i+1]= g;
pixels[i+2]= b;
break;
case 4:
pixels[i]= r;
pixels[i+1]= g;
pixels[i+2]= b;
pixels[i+3]= a;
break;
case 3:
pixels[i]= r;
pixels[i+1]= g;
pixels[i+2]= b;
break;
case 4:
pixels[i]= r;
pixels[i+1]= g;
pixels[i+2]= b;
pixels[i+3]= a;
break;
}
}
}
/*for(int i = 0; i < w*h*picComponents; ++i) {
if (i%39 == 0) std::cout << std::endl;
int first = pixels[i]/16;
if (first < 10)
std:: cout << first;
else
std::cout << (char)('A'+(first-10));
first = pixels[i]%16;
if (first < 10)
std:: cout << first;
else
std::cout << (char)('A'+(first-10));
std::cout << " ";
}*/
/*for(int i = 0; i < w*h*picComponents; ++i) {
if (i%39 == 0) std::cout << std::endl;
int first = pixels[i]/16;
if (first < 10)
std:: cout << first;
else
std::cout << (char)('A'+(first-10));
first = pixels[i]%16;
if (first < 10)
std:: cout << first;
else
std::cout << (char)('A'+(first-10));
std::cout << " ";
}*/
// }
// catch(exception& ex) {
// //printf("In [%s] line: %d msf [%s]\n",__FILE__,__LINE__,ex.what());
// //abort();
// char szBuf[8096]="";
// snprintf(szBuf,8096,"Error in [%s] on line: %d msg: %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,ex.what());
// throw megaglest_runtime_error(szBuf);
// }
//printf("In [%s] line: %d\n",__FILE__,__LINE__);
return ret;
}

View File

@@ -1279,8 +1279,15 @@ void Model::loadG3d(const string &path, bool deletePixMapAfterLoad,
}
fclose(f);
}
catch(megaglest_runtime_error& ex) {
//printf("1111111 ex.wantStackTrace() = %d\n",ex.wantStackTrace());
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
//printf("2222222\n");
throw megaglest_runtime_error("Exception caught loading 3d file: " + path +"\n"+ ex.what(),!ex.wantStackTrace());
}
catch(exception &e){
//abort();
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what());
throw megaglest_runtime_error("Exception caught loading 3d file: " + path +"\n"+ e.what());
}

View File

@@ -108,6 +108,8 @@ PixmapIoTga::~PixmapIoTga() {
}
void PixmapIoTga::openRead(const string &path) {
try {
#ifdef WIN32
file= _wfopen(utf8_decode(path).c_str(), L"rb");
#else
@@ -155,6 +157,14 @@ void PixmapIoTga::openRead(const string &path) {
h= fileHeader.height;
w= fileHeader.width;
components= fileHeader.bitsPerPixel / 8;
}
catch(exception& ex) {
char szBuf[8096]="";
snprintf(szBuf,8096,"Error in [%s] on line: %d msg: %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,ex.what());
throw megaglest_runtime_error(szBuf);
}
}
void PixmapIoTga::read(uint8 *pixels) {
@@ -162,6 +172,7 @@ void PixmapIoTga::read(uint8 *pixels) {
}
void PixmapIoTga::read(uint8 *pixels, int components) {
try {
static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian();
for(int i=0; i<h*w*components; i+=components) {
@@ -248,6 +259,14 @@ void PixmapIoTga::read(uint8 *pixels, int components) {
break;
}
}
}
catch(exception& ex) {
char szBuf[8096]="";
snprintf(szBuf,8096,"Error in [%s] on line: %d msg: %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,ex.what());
throw megaglest_runtime_error(szBuf);
}
}
void PixmapIoTga::openWrite(const string &path, int w, int h, int components) {

View File

@@ -253,7 +253,7 @@ string PlatformExceptionHandler::getStackTrace() {
}
megaglest_runtime_error::megaglest_runtime_error(const string& __arg,bool noStackTrace)
: std::runtime_error(noStackTrace ? __arg + PlatformExceptionHandler::getStackTrace() : __arg), noStackTrace(noStackTrace) {
: std::runtime_error(noStackTrace == false ? __arg + PlatformExceptionHandler::getStackTrace() : __arg), noStackTrace(noStackTrace) {
}
}}//end namespace

View File

@@ -225,7 +225,7 @@ string PlatformExceptionHandler::getStackTrace() {
}
megaglest_runtime_error::megaglest_runtime_error(const string& __arg,bool noStackTrace)
: std::runtime_error(noStackTrace ? __arg + PlatformExceptionHandler::getStackTrace() : __arg), noStackTrace(noStackTrace) {
: std::runtime_error(noStackTrace == false ? __arg + PlatformExceptionHandler::getStackTrace() : __arg), noStackTrace(noStackTrace) {
}
// =====================================================