diff options
Diffstat (limited to 'indra/llimage')
-rw-r--r-- | indra/llimage/llimage.cpp | 75 | ||||
-rw-r--r-- | indra/llimage/llimage.h | 33 | ||||
-rw-r--r-- | indra/llimage/llimagej2c.cpp | 141 | ||||
-rw-r--r-- | indra/llimage/llimagej2c.h | 5 | ||||
-rw-r--r-- | indra/llimage/llimageworker.cpp | 4 | ||||
-rw-r--r-- | indra/llimage/llimageworker.h | 6 |
6 files changed, 195 insertions, 69 deletions
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index ef1467ce50..4f4473a366 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -43,6 +43,49 @@ #include "llimagejpeg.h" #include "llimagepng.h" #include "llimagedxt.h" +#include "llimageworker.h" + +//--------------------------------------------------------------------------- +// LLImage +//--------------------------------------------------------------------------- + +//static +std::string LLImage::sLastErrorMessage; +LLMutex* LLImage::sMutex = NULL; + +//static +void LLImage::initClass(LLWorkerThread* workerthread) +{ + sMutex = new LLMutex(NULL); + if (workerthread) + { + LLImageWorker::initImageWorker(workerthread); + } + LLImageJ2C::openDSO(); +} + +//static +void LLImage::cleanupClass() +{ + LLImageJ2C::closeDSO(); + LLImageWorker::cleanupImageWorker(); + delete sMutex; + sMutex = NULL; +} + +//static +const std::string& LLImage::getLastError() +{ + static const std::string noerr("No Error"); + return sLastErrorMessage.empty() ? noerr : sLastErrorMessage; +} + +//static +void LLImage::setLastError(const std::string& message) +{ + LLMutexLock m(sMutex); + sLastErrorMessage = message; +} //--------------------------------------------------------------------------- // LLImageBase @@ -95,21 +138,8 @@ void LLImageBase::sanityCheck() } } -std::string LLImageBase::sLastErrorMessage; BOOL LLImageBase::sSizeOverride = FALSE; -BOOL LLImageBase::setLastError(const std::string& message, const std::string& filename) -{ - sLastErrorMessage = message; - if (!filename.empty()) - { - sLastErrorMessage += " FILE:"; - sLastErrorMessage += filename; - } - llwarns << sLastErrorMessage << llendl; - return FALSE; -} - // virtual void LLImageBase::deleteData() { @@ -136,8 +166,6 @@ U8* LLImageBase::allocateData(S32 size) llerrs << "LLImageBase::allocateData: bad size: " << size << llendl; } - resetLastError(); - if (!mData || size != mDataSize) { deleteData(); // virtual @@ -1269,6 +1297,23 @@ LLImageFormatted::~LLImageFormatted() //---------------------------------------------------------------------------- +//virtual +void LLImageFormatted::resetLastError() +{ + LLImage::setLastError(""); +} + +//virtual +void LLImageFormatted::setLastError(const std::string& message, const std::string& filename) +{ + std::string error = message; + if (!filename.empty()) + error += std::string(" FILE: ") + filename; + LLImage::setLastError(error); +} + +//---------------------------------------------------------------------------- + // static LLImageFormatted* LLImageFormatted::createFromType(S8 codec) { diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 8db6a6c5bd..fbff9eae64 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -59,6 +59,7 @@ const S32 MAX_IMG_PACKET_SIZE = 1000; class LLImageFormatted; class LLImageRaw; class LLColor4U; +class LLWorkerThread; typedef enum e_image_codec { @@ -74,6 +75,24 @@ typedef enum e_image_codec } EImageCodec; //============================================================================ +// library initialization class + +class LLImage +{ +public: + static void initClass(LLWorkerThread* workerthread); + static void cleanupClass(); + + static const std::string& getLastError(); + static void setLastError(const std::string& message); + +protected: + static LLMutex* sMutex; + static std::string sLastErrorMessage; +}; + +//============================================================================ +// Image base class class LLImageBase : public LLThreadSafeRefCount { @@ -113,10 +132,6 @@ protected: void setDataAndSize(U8 *data, S32 size) { mData = data; mDataSize = size; }; public: - static const std::string& getLastError() {return sLastErrorMessage;}; - static void resetLastError() {sLastErrorMessage = "No Error"; }; - static BOOL setLastError(const std::string& message, const std::string& filename = std::string()); // returns FALSE - static void generateMip(const U8 *indata, U8* mipdata, int width, int height, S32 nchannels); // Function for calculating the download priority for textures @@ -141,8 +156,6 @@ private: public: S16 mMemType; // debug - static std::string sLastErrorMessage; - static BOOL sSizeOverride; }; @@ -245,7 +258,6 @@ public: LLImageFormatted(S8 codec); // LLImageBase -public: /*virtual*/ void deleteData(); /*virtual*/ U8* allocateData(S32 size = -1); /*virtual*/ U8* reallocateData(S32 size); @@ -254,7 +266,6 @@ public: /*virtual*/ void sanityCheck(); // New methods -public: // subclasses must return a prefered file extension (lowercase without a leading dot) virtual std::string getExtension() = 0; // calcHeaderSize() returns the maximum size of header; @@ -287,6 +298,10 @@ public: void setDiscardLevel(S8 discard_level) { mDiscardLevel = discard_level; } S8 getDiscardLevel() const { return mDiscardLevel; } + // setLastError needs to be deferred for J2C images since it may be called from a DLL + virtual void resetLastError(); + virtual void setLastError(const std::string& message, const std::string& filename = std::string()); + protected: BOOL copyData(U8 *data, S32 size); // calls updateData() @@ -295,7 +310,7 @@ protected: S8 mDecoding; S8 mDecoded; S8 mDiscardLevel; - + public: static S32 sGlobalFormattedMemory; }; diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 73c5b111c3..3b3d08d3aa 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -219,32 +219,54 @@ LLImageJ2C::~LLImageJ2C() } // virtual +void LLImageJ2C::resetLastError() +{ + mLastError.clear(); +} + +//virtual +void LLImageJ2C::setLastError(const std::string& message, const std::string& filename) +{ + mLastError = message; + if (!filename.empty()) + mLastError += std::string(" FILE: ") + filename; +} + +// virtual S8 LLImageJ2C::getRawDiscardLevel() { return mRawDiscardLevel; } BOOL LLImageJ2C::updateData() -{ +{ + BOOL res = TRUE; resetLastError(); // Check to make sure that this instance has been initialized with data if (!getData() || (getDataSize() < 16)) { setLastError("LLImageJ2C uninitialized"); - return FALSE; + res = FALSE; + } + else + { + res = mImpl->getMetadata(*this); } - if (!mImpl->getMetadata(*this)) + if (res) { - return FALSE; + // SJB: override discard based on mMaxBytes elsewhere + S32 max_bytes = getDataSize(); // mMaxBytes ? mMaxBytes : getDataSize(); + S32 discard = calcDiscardLevelBytes(max_bytes); + setDiscardLevel(discard); } - // SJB: override discard based on mMaxBytes elsewhere - S32 max_bytes = getDataSize(); // mMaxBytes ? mMaxBytes : getDataSize(); - S32 discard = calcDiscardLevelBytes(max_bytes); - setDiscardLevel(discard); - return TRUE; + if (!mLastError.empty()) + { + LLImage::setLastError(mLastError); + } + return res; } @@ -258,20 +280,24 @@ BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 fir { LLMemType mt1((LLMemType::EMemType)mMemType); + BOOL res = TRUE; + resetLastError(); // Check to make sure that this instance has been initialized with data if (!getData() || (getDataSize() < 16)) { setLastError("LLImageJ2C uninitialized"); - return FALSE; + res = FALSE; } - - // Update the raw discard level - updateRawDiscardLevel(); - - mDecoding = TRUE; - BOOL res = mImpl->decodeImpl(*this, *raw_imagep, decode_time, first_channel, max_channel_count); + else + { + // Update the raw discard level + updateRawDiscardLevel(); + mDecoding = TRUE; + res = mImpl->decodeImpl(*this, *raw_imagep, decode_time, first_channel, max_channel_count); + } + if (res) { if (!mDecoding) @@ -283,9 +309,14 @@ BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 fir { mDecoding = FALSE; } - return TRUE; // done } - return FALSE; + + if (!mLastError.empty()) + { + LLImage::setLastError(mLastError); + } + + return res; } @@ -298,7 +329,13 @@ BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, F32 encode_time) BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, const char* comment_text, F32 encode_time) { LLMemType mt1((LLMemType::EMemType)mMemType); - return mImpl->encodeImpl(*this, *raw_imagep, comment_text, encode_time, mReversible); + resetLastError(); + BOOL res = mImpl->encodeImpl(*this, *raw_imagep, comment_text, encode_time, mReversible); + if (!mLastError.empty()) + { + LLImage::setLastError(mLastError); + } + return res; } //static @@ -376,6 +413,8 @@ void LLImageJ2C::setReversible(const BOOL reversible) BOOL LLImageJ2C::loadAndValidate(const std::string &filename) { + BOOL res = TRUE; + resetLastError(); S32 file_size = 0; @@ -383,27 +422,38 @@ BOOL LLImageJ2C::loadAndValidate(const std::string &filename) if (!apr_file) { setLastError("Unable to open file for reading", filename); - return FALSE; + res = FALSE; } - if (file_size == 0) + else if (file_size == 0) { setLastError("File is empty",filename); apr_file_close(apr_file); - return FALSE; + res = FALSE; } - - U8 *data = new U8[file_size]; - apr_size_t bytes_read = file_size; - apr_status_t s = apr_file_read(apr_file, data, &bytes_read); // modifies bytes_read - if (s != APR_SUCCESS || (S32)bytes_read != file_size) + else { - delete[] data; - setLastError("Unable to read entire file"); - return FALSE; + U8 *data = new U8[file_size]; + apr_size_t bytes_read = file_size; + apr_status_t s = apr_file_read(apr_file, data, &bytes_read); // modifies bytes_read + apr_file_close(apr_file); + if (s != APR_SUCCESS || (S32)bytes_read != file_size) + { + delete[] data; + setLastError("Unable to read entire file"); + res = FALSE; + } + else + { + res = validate(data, file_size); + } } - apr_file_close(apr_file); - return validate(data, file_size); + if (!mLastError.empty()) + { + LLImage::setLastError(mLastError); + } + + return res; } @@ -411,21 +461,30 @@ BOOL LLImageJ2C::validate(U8 *data, U32 file_size) { LLMemType mt1((LLMemType::EMemType)mMemType); + resetLastError(); + setData(data, file_size); + BOOL res = updateData(); - if ( !res ) + if ( res ) { - return FALSE; + // Check to make sure that this instance has been initialized with data + if (!getData() || (0 == getDataSize())) + { + setLastError("LLImageJ2C uninitialized"); + res = FALSE; + } + else + { + res = mImpl->getMetadata(*this); + } } - - // Check to make sure that this instance has been initialized with data - if (!getData() || (0 == getDataSize())) + + if (!mLastError.empty()) { - setLastError("LLImageJ2C uninitialized"); - return FALSE; + LLImage::setLastError(mLastError); } - - return mImpl->getMetadata(*this); + return res; } void LLImageJ2C::decodeFailed() diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h index 03172d344f..4dc39ccc36 100644 --- a/indra/llimage/llimagej2c.h +++ b/indra/llimage/llimagej2c.h @@ -54,6 +54,10 @@ public: /*virtual*/ S32 calcDataSize(S32 discard_level = 0); /*virtual*/ S32 calcDiscardLevelBytes(S32 bytes); /*virtual*/ S8 getRawDiscardLevel(); + // Override these so that we don't try to set a global variable from a DLL + /*virtual*/ void resetLastError(); + /*virtual*/ void setLastError(const std::string& message, const std::string& filename = std::string()); + // Encode with comment text BOOL encode(const LLImageRaw *raw_imagep, const char* comment_text, F32 encode_time=0.0); @@ -86,6 +90,7 @@ protected: F32 mRate; BOOL mReversible; LLImageJ2CImpl *mImpl; + std::string mLastError; }; // Derive from this class to implement JPEG2000 decoding diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp index cdec2bfe6c..cbc6ea7911 100644 --- a/indra/llimage/llimageworker.cpp +++ b/indra/llimage/llimageworker.cpp @@ -41,13 +41,13 @@ LLWorkerThread* LLImageWorker::sWorkerThread = NULL; S32 LLImageWorker::sCount = 0; //static -void LLImageWorker::initClass(LLWorkerThread* workerthread) +void LLImageWorker::initImageWorker(LLWorkerThread* workerthread) { sWorkerThread = workerthread; } //static -void LLImageWorker::cleanupClass() +void LLImageWorker::cleanupImageWorker() { } diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h index f9c592fa51..f3304130ea 100644 --- a/indra/llimage/llimageworker.h +++ b/indra/llimage/llimageworker.h @@ -38,8 +38,10 @@ class LLImageWorker : public LLWorkerClass { public: - static void initClass(LLWorkerThread* workerthread); - static void cleanupClass(); + static void initImageWorker(LLWorkerThread* workerthread); + static void cleanupImageWorker(); + +public: static LLWorkerThread* getWorkerThread() { return sWorkerThread; } // LLWorkerThread |