diff options
Diffstat (limited to 'indra/llimage')
-rw-r--r-- | indra/llimage/llimage.cpp | 13 | ||||
-rw-r--r-- | indra/llimage/llimage.h | 5 | ||||
-rw-r--r-- | indra/llimage/llimagepng.cpp | 46 | ||||
-rw-r--r-- | indra/llimage/llimageworker.cpp | 13 | ||||
-rw-r--r-- | indra/llimage/llimageworker.h | 2 | ||||
-rw-r--r-- | indra/llimage/llpngwrapper.cpp | 7 |
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(); |