summaryrefslogtreecommitdiff
path: root/indra/llimage/llimagej2c.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llimage/llimagej2c.cpp')
-rw-r--r--indra/llimage/llimagej2c.cpp69
1 files changed, 39 insertions, 30 deletions
diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp
index 5175849ad8..42f3e92257 100644
--- a/indra/llimage/llimagej2c.cpp
+++ b/indra/llimage/llimagej2c.cpp
@@ -107,6 +107,8 @@ bool LLImageJ2C::updateData()
bool res = true;
resetLastError();
+ LLImageDataLock lock(this);
+
// Check to make sure that this instance has been initialized with data
if (!getData() || (getDataSize() < 16))
{
@@ -157,22 +159,25 @@ bool LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 fir
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
LLTimer elapsed;
- bool res = true;
-
resetLastError();
- // Check to make sure that this instance has been initialized with data
- if (!getData() || (getDataSize() < 16))
- {
- setLastError("LLImageJ2C uninitialized");
- res = true; // done
- }
- else
+ bool res;
{
- // Update the raw discard level
- updateRawDiscardLevel();
+ LLImageDataLock lock(this);
+
mDecoding = true;
- res = mImpl->decodeImpl(*this, *raw_imagep, decode_time, first_channel, max_channel_count);
+ // Check to make sure that this instance has been initialized with data
+ if (!getData() || (getDataSize() < 16))
+ {
+ setLastError("LLImageJ2C uninitialized");
+ res = true; // done
+ }
+ else
+ {
+ // Update the raw discard level
+ updateRawDiscardLevel();
+ res = mImpl->decodeImpl(*this, *raw_imagep, decode_time, first_channel, max_channel_count);
+ }
}
if (res)
@@ -181,12 +186,21 @@ bool LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 fir
{
// Failed
raw_imagep->deleteData();
+ res = false;
}
else
{
mDecoding = false;
}
}
+ else
+ {
+ if (mDecoding)
+ {
+ LL_WARNS() << "decodeImpl failed but mDecoding is true" << LL_ENDL;
+ mDecoding = false;
+ }
+ }
if (!mLastError.empty())
{
@@ -261,30 +275,24 @@ S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 r
// For details about the equation used here, see https://wiki.lindenlab.com/wiki/THX1138_KDU_Improvements#Byte_Range_Study
// Estimate the number of layers. This is consistent with what's done for j2c encoding in LLImageJ2CKDU::encodeImpl().
+ constexpr S32 precision = 8; // assumed bitrate per component channel, might change in future for HDR support
+ constexpr S32 max_components = 4; // assumed the file has four components; three color and alpha
S32 nb_layers = 1;
- S32 surface = w*h;
+ const S32 surface = w*h;
S32 s = 64*64;
+ S32 totalbytes = (S32)(s * max_components * precision * rate); // first level computed before loop
while (surface > s)
{
+ if (nb_layers <= (5 - discard_level))
+ totalbytes += (S32)(s * max_components * precision * rate);
nb_layers++;
s *= 4;
}
- F32 layer_factor = 3.0f * (7 - llclamp(nb_layers,1,6));
-
- // Compute w/pow(2,discard_level) and h/pow(2,discard_level)
- w >>= discard_level;
- h >>= discard_level;
- w = llmax(w, 1);
- h = llmax(h, 1);
-
- // Temporary: compute both new and old range and pick one according to the settings TextureNewByteRange
- // *TODO: Take the old code out once we have enough tests done
- S32 bytes;
- S32 new_bytes = (S32) (sqrt((F32)(w*h))*(F32)(comp)*rate*1000.f/layer_factor);
- S32 old_bytes = (S32)((F32)(w*h*comp)*rate);
- bytes = (LLImage::useNewByteRange() && (new_bytes < old_bytes) ? new_bytes : old_bytes);
- bytes = llmax(bytes, calcHeaderSizeJ2C());
- return bytes;
+
+ totalbytes /= 8; // to bytes
+ totalbytes += calcHeaderSizeJ2C(); // header
+
+ return totalbytes;
}
S32 LLImageJ2C::calcHeaderSize()
@@ -406,9 +414,10 @@ bool LLImageJ2C::loadAndValidate(const std::string &filename)
bool LLImageJ2C::validate(U8 *data, U32 file_size)
{
-
resetLastError();
+ LLImageDataLock lock(this);
+
setData(data, file_size);
bool res = updateData();