summaryrefslogtreecommitdiff
path: root/indra/llimage
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llimage')
-rw-r--r--indra/llimage/llimage.cpp13
-rw-r--r--indra/llimage/llimage.h5
-rw-r--r--indra/llimage/llimagepng.cpp46
-rw-r--r--indra/llimage/llimageworker.cpp13
-rw-r--r--indra/llimage/llimageworker.h2
-rw-r--r--indra/llimage/llpngwrapper.cpp7
6 files changed, 57 insertions, 29 deletions
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 196ec7805a..c4d7096036 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -584,8 +584,7 @@ static void bilinear_scale(const U8 *src, U32 srcW, U32 srcH, U32 srcCh, U32 src
//---------------------------------------------------------------------------
//static
-std::string LLImage::sLastErrorMessage;
-LLMutex* LLImage::sMutex = NULL;
+thread_local std::string LLImage::sLastThreadErrorMessage;
bool LLImage::sUseNewByteRange = false;
S32 LLImage::sMinimalReverseByteRangePercent = 75;
@@ -594,28 +593,24 @@ void LLImage::initClass(bool use_new_byte_range, S32 minimal_reverse_byte_range_
{
sUseNewByteRange = use_new_byte_range;
sMinimalReverseByteRangePercent = minimal_reverse_byte_range_percent;
- sMutex = new LLMutex();
}
//static
void LLImage::cleanupClass()
{
- delete sMutex;
- sMutex = NULL;
}
//static
-const std::string& LLImage::getLastError()
+const std::string& LLImage::getLastThreadError()
{
static const std::string noerr("No Error");
- return sLastErrorMessage.empty() ? noerr : sLastErrorMessage;
+ return sLastThreadErrorMessage.empty() ? noerr : sLastThreadErrorMessage;
}
//static
void LLImage::setLastError(const std::string& message)
{
- LLMutexLock m(sMutex);
- sLastErrorMessage = message;
+ sLastThreadErrorMessage = message;
}
//---------------------------------------------------------------------------
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 32e0781fae..0335be8d2f 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -95,15 +95,14 @@ public:
static void initClass(bool use_new_byte_range = false, S32 minimal_reverse_byte_range_percent = 75);
static void cleanupClass();
- static const std::string& getLastError();
+ static const std::string& getLastThreadError();
static void setLastError(const std::string& message);
static bool useNewByteRange() { return sUseNewByteRange; }
static S32 getReverseByteRangePercent() { return sMinimalReverseByteRangePercent; }
protected:
- static LLMutex* sMutex;
- static std::string sLastErrorMessage;
+ static thread_local std::string sLastThreadErrorMessage;
static bool sUseNewByteRange;
static S32 sMinimalReverseByteRangePercent;
};
diff --git a/indra/llimage/llimagepng.cpp b/indra/llimage/llimagepng.cpp
index 29a86f77f6..4d081ce169 100644
--- a/indra/llimage/llimagepng.cpp
+++ b/indra/llimage/llimagepng.cpp
@@ -27,6 +27,7 @@
#include "linden_common.h"
#include "stdtypes.h"
#include "llerror.h"
+#include "llexception.h"
#include "llimage.h"
#include "llpngwrapper.h"
@@ -51,30 +52,45 @@ bool LLImagePNG::updateData()
{
resetLastError();
- // Check to make sure that this instance has been initialized with data
- if (!getData() || (0 == getDataSize()))
+ try
{
- setLastError("Uninitialized instance of LLImagePNG");
- return false;
+ // Check to make sure that this instance has been initialized with data
+ if (!getData() || (0 == getDataSize()))
+ {
+ setLastError("Uninitialized instance of LLImagePNG");
+ return false;
+ }
+
+ // Decode the PNG data and extract sizing information
+ LLPngWrapper pngWrapper;
+ if (!pngWrapper.isValidPng(getData()))
+ {
+ setLastError("LLImagePNG data does not have a valid PNG header!");
+ return false;
+ }
+
+ LLPngWrapper::ImageInfo infop;
+ if (!pngWrapper.readPng(getData(), getDataSize(), NULL, &infop))
+ {
+ setLastError(pngWrapper.getErrorMessage());
+ return false;
+ }
+
+ setSize(infop.mWidth, infop.mHeight, infop.mComponents);
}
-
- // Decode the PNG data and extract sizing information
- LLPngWrapper pngWrapper;
- if (!pngWrapper.isValidPng(getData()))
+ catch (const LLContinueError& msg)
{
- setLastError("LLImagePNG data does not have a valid PNG header!");
+ setLastError(msg.what());
+ LOG_UNHANDLED_EXCEPTION("");
return false;
}
-
- LLPngWrapper::ImageInfo infop;
- if (! pngWrapper.readPng(getData(), getDataSize(), NULL, &infop))
+ catch (...)
{
- setLastError(pngWrapper.getErrorMessage());
+ setLastError("LLImagePNG");
+ LOG_UNHANDLED_EXCEPTION("");
return false;
}
- setSize(infop.mWidth, infop.mHeight, infop.mComponents);
-
return true;
}
diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp
index 553e5cd7bf..587f25dc1b 100644
--- a/indra/llimage/llimageworker.cpp
+++ b/indra/llimage/llimageworker.cpp
@@ -58,6 +58,7 @@ private:
BOOL mDecodedRaw;
BOOL mDecodedAux;
LLPointer<LLImageDecodeThread::Responder> mResponder;
+ std::string mErrorString;
};
@@ -156,6 +157,7 @@ bool ImageRequest::processRequest()
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
const F32 decode_time_slice = 0.f; //disable time slicing
bool done = true;
+ mErrorString.clear();
if (!mDecodedRaw && mFormattedImage.notNull())
{
// Decode primary channels
@@ -164,10 +166,13 @@ bool ImageRequest::processRequest()
// parse formatted header
if (!mFormattedImage->updateData())
{
+ // Pick up errors from updateData
+ mErrorString = LLImage::getLastThreadError();
return true; // done (failed)
}
if (!(mFormattedImage->getWidth() * mFormattedImage->getHeight() * mFormattedImage->getComponents()))
{
+ mErrorString = "Invalid image size";
return true; // done (failed)
}
if (mDiscardLevel >= 0)
@@ -181,6 +186,9 @@ bool ImageRequest::processRequest()
done = mFormattedImage->decode(mDecodedImageRaw, decode_time_slice);
// some decoders are removing data when task is complete and there were errors
mDecodedRaw = done && mDecodedImageRaw->getData();
+
+ // Pick up errors from decoding
+ mErrorString = LLImage::getLastThreadError();
}
if (done && mNeedsAux && !mDecodedAux && mFormattedImage.notNull())
{
@@ -193,6 +201,9 @@ bool ImageRequest::processRequest()
}
done = mFormattedImage->decodeChannels(mDecodedImageAux, decode_time_slice, 4, 4);
mDecodedAux = done && mDecodedImageAux->getData();
+
+ // Pick up errors from decoding
+ mErrorString = LLImage::getLastThreadError();
}
return done;
@@ -204,7 +215,7 @@ void ImageRequest::finishRequest(bool completed)
if (mResponder.notNull())
{
bool success = completed && mDecodedRaw && (!mNeedsAux || mDecodedAux);
- mResponder->completed(success, mDecodedImageRaw, mDecodedImageAux, mRequestId);
+ mResponder->completed(success, mErrorString, mDecodedImageRaw, mDecodedImageAux, mRequestId);
}
// Will automatically be deleted
}
diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h
index 92d70b451d..8c43a7c32c 100644
--- a/indra/llimage/llimageworker.h
+++ b/indra/llimage/llimageworker.h
@@ -39,7 +39,7 @@ public:
protected:
virtual ~Responder();
public:
- virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux, U32 request_id) = 0;
+ virtual void completed(bool success, const std::string& error_message, LLImageRaw* raw, LLImageRaw* aux, U32 request_id) = 0;
};
public:
diff --git a/indra/llimage/llpngwrapper.cpp b/indra/llimage/llpngwrapper.cpp
index 6167ba5b43..24b6d34fe2 100644
--- a/indra/llimage/llpngwrapper.cpp
+++ b/indra/llimage/llpngwrapper.cpp
@@ -216,6 +216,13 @@ BOOL LLPngWrapper::readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInf
releaseResources();
return (FALSE);
}
+ catch (...)
+ {
+ mErrorMessage = "LLPngWrapper";
+ releaseResources();
+ LOG_UNHANDLED_EXCEPTION("");
+ return (FALSE);
+ }
// Clean up and return
releaseResources();