summaryrefslogtreecommitdiff
path: root/indra/llimage
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llimage')
-rw-r--r--indra/llimage/llimage.cpp75
-rw-r--r--indra/llimage/llimage.h33
-rw-r--r--indra/llimage/llimagej2c.cpp141
-rw-r--r--indra/llimage/llimagej2c.h5
-rw-r--r--indra/llimage/llimageworker.cpp4
-rw-r--r--indra/llimage/llimageworker.h6
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