summaryrefslogtreecommitdiff
path: root/indra/llimage
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llimage')
-rw-r--r--indra/llimage/llimage.cpp33
-rw-r--r--indra/llimage/llimagej2c.cpp48
-rw-r--r--indra/llimage/llimagej2c.h4
3 files changed, 67 insertions, 18 deletions
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 488f3bf78d..73c23fa8d8 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -159,7 +159,7 @@ U8* LLImageBase::allocateData(S32 size)
size = mWidth * mHeight * mComponents;
if (size <= 0)
{
- llerrs << llformat("LLImageBase::allocateData called with bad dimentions: %dx%dx%d",mWidth,mHeight,mComponents) << llendl;
+ llerrs << llformat("LLImageBase::allocateData called with bad dimensions: %dx%dx%d",mWidth,mHeight,mComponents) << llendl;
}
}
else if (size <= 0 || (size > 4096*4096*16 && sSizeOverride == FALSE))
@@ -1223,25 +1223,28 @@ bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip
ifs.read ((char*)buffer, length);
ifs.close();
- image->updateData();
-
- if (j2c_lowest_mip_only && codec == IMG_CODEC_J2C)
+ BOOL success;
+
+ success = image->updateData();
+ if (success)
{
- S32 width = image->getWidth();
- S32 height = image->getHeight();
- S32 discard_level = 0;
- while (width > 1 && height > 1 && discard_level < MAX_DISCARD_LEVEL)
+ if (j2c_lowest_mip_only && codec == IMG_CODEC_J2C)
{
- width >>= 1;
- height >>= 1;
- discard_level++;
+ S32 width = image->getWidth();
+ S32 height = image->getHeight();
+ S32 discard_level = 0;
+ while (width > 1 && height > 1 && discard_level < MAX_DISCARD_LEVEL)
+ {
+ width >>= 1;
+ height >>= 1;
+ discard_level++;
+ }
+ ((LLImageJ2C *)((LLImageFormatted*)image))->setDiscardLevel(discard_level);
}
- ((LLImageJ2C *)((LLImageFormatted*)image))->setDiscardLevel(discard_level);
+ success = image->decode(this, 100000.0f);
}
-
- BOOL success = image->decode(this, 100000.0f);
- image = NULL; // deletes image
+ image = NULL; // deletes image
if (!success)
{
deleteData();
diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp
index 363486fb9c..2352c8edd7 100644
--- a/indra/llimage/llimagej2c.cpp
+++ b/indra/llimage/llimagej2c.cpp
@@ -178,8 +178,8 @@ LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C),
mMaxBytes(0),
mRawDiscardLevel(-1),
mRate(0.0f),
- mReversible(FALSE)
-
+ mReversible(FALSE),
+ mAreaUsedForDataSizeCalcs(0)
{
//We assume here that if we wanted to create via
//a dynamic library that the approriate open calls were made
@@ -195,6 +195,12 @@ LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C),
}
mImpl = j2cimpl_create_func();
+
+ // Clear data size table
+ for( S32 i = 0; i <= MAX_DISCARD_LEVEL; i++)
+ { // Array size is MAX_DISCARD_LEVEL+1
+ mDataSizes[i] = 0;
+ }
}
// virtual
@@ -367,9 +373,45 @@ S32 LLImageJ2C::calcHeaderSize()
return calcHeaderSizeJ2C();
}
+
+// calcDataSize() returns how many bytes to read
+// to load discard_level (including header and higher discard levels)
S32 LLImageJ2C::calcDataSize(S32 discard_level)
{
- return calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), discard_level, mRate);
+ discard_level = llclamp(discard_level, 0, MAX_DISCARD_LEVEL);
+
+ if ( mAreaUsedForDataSizeCalcs != (getHeight() * getWidth())
+ || mDataSizes[0] == 0)
+ {
+ mAreaUsedForDataSizeCalcs = getHeight() * getWidth();
+
+ S32 level = MAX_DISCARD_LEVEL; // Start at the highest discard
+ while ( level >= 0 )
+ {
+ mDataSizes[level] = calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, mRate);
+ level--;
+ }
+
+ /* This is technically a more correct way to calculate the size required
+ for each discard level, since they should include the size needed for
+ lower levels. Unfortunately, this doesn't work well and will lead to
+ download stalls. The true correct way is to parse the header. This will
+ all go away with http textures at some point.
+
+ // Calculate the size for each discard level. Lower levels (higher quality)
+ // contain the cumulative size of higher levels
+ S32 total_size = calcHeaderSizeJ2C();
+
+ S32 level = MAX_DISCARD_LEVEL; // Start at the highest discard
+ while ( level >= 0 )
+ { // Add in this discard level and all before it
+ total_size += calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, mRate);
+ mDataSizes[level] = total_size;
+ level--;
+ }
+ */
+ }
+ return mDataSizes[discard_level];
}
S32 LLImageJ2C::calcDiscardLevelBytes(S32 bytes)
diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h
index 23f6ef5fd1..55df7f4429 100644
--- a/indra/llimage/llimagej2c.h
+++ b/indra/llimage/llimagej2c.h
@@ -87,6 +87,10 @@ protected:
void updateRawDiscardLevel();
S32 mMaxBytes; // Maximum number of bytes of data to use...
+
+ S32 mDataSizes[MAX_DISCARD_LEVEL+1]; // Size of data required to reach a given level
+ U32 mAreaUsedForDataSizeCalcs; // Height * width used to calculate mDataSizes
+
S8 mRawDiscardLevel;
F32 mRate;
BOOL mReversible;