summaryrefslogtreecommitdiff
path: root/indra/llimage
diff options
context:
space:
mode:
authorOz Linden <oz@lindenlab.com>2013-11-19 17:59:55 -0500
committerOz Linden <oz@lindenlab.com>2013-11-19 17:59:55 -0500
commit0031e9a97be1bf6e9fe773c23506494d09ce91ae (patch)
tree220f195c82174b7cc8e94dceb2553e59fe5837a5 /indra/llimage
parentb7edc965bc77ab21e9a1e3f6b424299a50053529 (diff)
parentebc9bcbf69f7a519677a6522979a6bf6cbb04bb8 (diff)
merge up to 3.6.10-release; some of the storm-68 changes lost
Diffstat (limited to 'indra/llimage')
-rwxr-xr-x[-rw-r--r--]indra/llimage/CMakeLists.txt13
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimage.cpp158
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimage.h36
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagebmp.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagebmp.h0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagedimensionsinfo.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagedimensionsinfo.h0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagedxt.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagedxt.h0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagej2c.cpp89
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagej2c.h10
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagejpeg.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagejpeg.h0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagepng.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagepng.h0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagetga.cpp12
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagetga.h0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimageworker.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimageworker.h0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llmapimagetype.h0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llpngwrapper.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llpngwrapper.h0
-rwxr-xr-x[-rw-r--r--]indra/llimage/tests/llimageworker_test.cpp3
23 files changed, 157 insertions, 164 deletions
diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt
index ea8c1a1107..e837b0cac2 100644..100755
--- a/indra/llimage/CMakeLists.txt
+++ b/indra/llimage/CMakeLists.txt
@@ -7,12 +7,15 @@ include(LLCommon)
include(LLImage)
include(LLMath)
include(LLVFS)
+include(LLKDU)
+include(LLImageJ2COJ)
include(ZLIB)
include(LLAddBuildTest)
include(Tut)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${PNG_INCLUDE_DIRS}
@@ -56,8 +59,16 @@ list(APPEND llimage_SOURCE_FILES ${llimage_HEADER_FILES})
add_library (llimage ${llimage_SOURCE_FILES})
# Libraries on which this library depends, needed for Linux builds
# Sort by high-level to low-level
+if (USE_KDU)
+ target_link_libraries(llimage ${LLKDU_LIBRARIES})
+else (USE_KDU)
+ target_link_libraries(llimage ${LLIMAGEJ2COJ_LIBRARIES})
+endif (USE_KDU)
+
target_link_libraries(llimage
- llcommon
+ ${LLVFS_LIBRARIES}
+ ${LLMATH_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
${JPEG_LIBRARIES}
${PNG_LIBRARIES}
${ZLIB_LIBRARIES}
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 56e01ac851..c8a05e1fae 100644..100755
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -30,7 +30,6 @@
#include "llmath.h"
#include "v4coloru.h"
-#include "llmemtype.h"
#include "llimagebmp.h"
#include "llimagetga.h"
@@ -48,11 +47,15 @@
//static
std::string LLImage::sLastErrorMessage;
LLMutex* LLImage::sMutex = NULL;
+bool LLImage::sUseNewByteRange = false;
+S32 LLImage::sMinimalReverseByteRangePercent = 75;
LLPrivateMemoryPool* LLImageBase::sPrivatePoolp = NULL ;
//static
-void LLImage::initClass()
+void LLImage::initClass(bool use_new_byte_range, S32 minimal_reverse_byte_range_percent)
{
+ sUseNewByteRange = use_new_byte_range;
+ sMinimalReverseByteRangePercent = minimal_reverse_byte_range_percent;
sMutex = new LLMutex(NULL);
LLImageBase::createPrivatePool() ;
@@ -92,8 +95,7 @@ LLImageBase::LLImageBase()
mHeight(0),
mComponents(0),
mBadBufferAllocation(false),
- mAllowOverSize(false),
- mMemType(LLMemType::MTYPE_IMAGEBASE)
+ mAllowOverSize(false)
{
}
@@ -163,8 +165,6 @@ void LLImageBase::deleteData()
// virtual
U8* LLImageBase::allocateData(S32 size)
{
- LLMemType mt1(mMemType);
-
if (size < 0)
{
size = mWidth * mHeight * mComponents;
@@ -209,7 +209,6 @@ U8* LLImageBase::allocateData(S32 size)
// virtual
U8* LLImageBase::reallocateData(S32 size)
{
- LLMemType mt1(mMemType);
U8 *new_datap = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);
if (!new_datap)
{
@@ -275,24 +274,26 @@ S32 LLImageRaw::sRawImageCount = 0;
LLImageRaw::LLImageRaw()
: LLImageBase()
{
- mMemType = LLMemType::MTYPE_IMAGERAW;
++sRawImageCount;
}
LLImageRaw::LLImageRaw(U16 width, U16 height, S8 components)
: LLImageBase()
{
- mMemType = LLMemType::MTYPE_IMAGERAW;
//llassert( S32(width) * S32(height) * S32(components) <= MAX_IMAGE_DATA_SIZE );
allocateDataSize(width, height, components);
++sRawImageCount;
}
-LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components)
+LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components, bool no_copy)
: LLImageBase()
{
- mMemType = LLMemType::MTYPE_IMAGERAW;
- if(allocateDataSize(width, height, components))
+
+ if(no_copy)
+ {
+ setDataAndSize(data, width, height, components);
+ }
+ else if(allocateDataSize(width, height, components))
{
memcpy(getData(), data, width*height*components);
}
@@ -366,29 +367,6 @@ BOOL LLImageRaw::resize(U16 width, U16 height, S8 components)
return TRUE;
}
-#if 0
-U8 * LLImageRaw::getSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height) const
-{
- LLMemType mt1(mMemType);
- U8 *data = new U8[width*height*getComponents()];
-
- // Should do some simple bounds checking
- if (!data)
- {
- llerrs << "Out of memory in LLImageRaw::getSubImage" << llendl;
- return NULL;
- }
-
- U32 i;
- for (i = y_pos; i < y_pos+height; i++)
- {
- memcpy(data + i*width*getComponents(), /* Flawfinder: ignore */
- getData() + ((y_pos + i)*getWidth() + x_pos)*getComponents(), getComponents()*width);
- }
- return data;
-}
-#endif
-
BOOL LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,
const U8 *data, U32 stride, BOOL reverse_y)
{
@@ -453,7 +431,6 @@ void LLImageRaw::clear(U8 r, U8 g, U8 b, U8 a)
// Reverses the order of the rows in the image
void LLImageRaw::verticalFlip()
{
- LLMemType mt1(mMemType);
S32 row_bytes = getWidth() * getComponents();
llassert(row_bytes > 0);
std::vector<U8> line_buffer(row_bytes);
@@ -586,7 +563,6 @@ void LLImageRaw::composite( LLImageRaw* src )
// Src and dst can be any size. Src has 4 components. Dst has 3 components.
void LLImageRaw::compositeScaled4onto3(LLImageRaw* src)
{
- LLMemType mt1(mMemType);
llinfos << "compositeScaled4onto3" << llendl;
LLImageRaw* dst = this; // Just for clarity.
@@ -664,6 +640,29 @@ void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src )
}
}
+void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill)
+{
+ LLImageRaw* dst = this; // Just for clarity.
+
+ llassert( 1 == src->getComponents() );
+ llassert( 4 == dst->getComponents() );
+ llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
+
+ S32 pixels = getWidth() * getHeight();
+ U8* src_data = src->getData();
+ U8* dst_data = dst->getData();
+ for ( S32 i = 0; i < pixels; i++ )
+ {
+ dst_data[0] = fill.mV[0];
+ dst_data[1] = fill.mV[1];
+ dst_data[2] = fill.mV[2];
+ dst_data[3] = src_data[0];
+ src_data += 1;
+ dst_data += 4;
+ }
+}
+
+
// Fill the buffer with a constant color
void LLImageRaw::fill( const LLColor4U& color )
{
@@ -690,8 +689,17 @@ void LLImageRaw::fill( const LLColor4U& color )
}
}
+LLPointer<LLImageRaw> LLImageRaw::duplicate()
+{
+ if(getNumRefs() < 2)
+ {
+ return this; //nobody else refences to this image, no need to duplicate.
+ }
-
+ //make a duplicate
+ LLPointer<LLImageRaw> dup = new LLImageRaw(getData(), getWidth(), getHeight(), getComponents());
+ return dup;
+}
// Src and dst can be any size. Src and dst can each have 3 or 4 components.
void LLImageRaw::copy(LLImageRaw* src)
@@ -828,7 +836,6 @@ void LLImageRaw::copyUnscaled3onto4( LLImageRaw* src )
// Src and dst can be any size. Src and dst have same number of components.
void LLImageRaw::copyScaled( LLImageRaw* src )
{
- LLMemType mt1(mMemType);
LLImageRaw* dst = this; // Just for clarity.
llassert_always( (1 == src->getComponents()) || (3 == src->getComponents()) || (4 == src->getComponents()) );
@@ -857,57 +864,9 @@ void LLImageRaw::copyScaled( LLImageRaw* src )
}
}
-#if 0
-//scale down image by not blending a pixel with its neighbors.
-BOOL LLImageRaw::scaleDownWithoutBlending( S32 new_width, S32 new_height)
-{
- LLMemType mt1(mMemType);
-
- S8 c = getComponents() ;
- llassert((1 == c) || (3 == c) || (4 == c) );
-
- S32 old_width = getWidth();
- S32 old_height = getHeight();
-
- S32 new_data_size = old_width * new_height * c ;
- llassert_always(new_data_size > 0);
-
- F32 ratio_x = (F32)old_width / new_width ;
- F32 ratio_y = (F32)old_height / new_height ;
- if( ratio_x < 1.0f || ratio_y < 1.0f )
- {
- return TRUE; // Nothing to do.
- }
- ratio_x -= 1.0f ;
- ratio_y -= 1.0f ;
-
- U8* new_data = allocateMemory(new_data_size) ;
- llassert_always(new_data != NULL) ;
-
- U8* old_data = getData() ;
- S32 i, j, k, s, t;
- for(i = 0, s = 0, t = 0 ; i < new_height ; i++)
- {
- for(j = 0 ; j < new_width ; j++)
- {
- for(k = 0 ; k < c ; k++)
- {
- new_data[s++] = old_data[t++] ;
- }
- t += (S32)(ratio_x * c + 0.1f) ;
- }
- t += (S32)(ratio_y * old_width * c + 0.1f) ;
- }
-
- setDataAndSize(new_data, new_width, new_height, c) ;
-
- return TRUE ;
-}
-#endif
BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )
{
- LLMemType mt1(mMemType);
llassert((1 == getComponents()) || (3 == getComponents()) || (4 == getComponents()) );
S32 old_width = getWidth();
@@ -1334,9 +1293,9 @@ LLImageFormatted::LLImageFormatted(S8 codec)
mCodec(codec),
mDecoding(0),
mDecoded(0),
- mDiscardLevel(-1)
+ mDiscardLevel(-1),
+ mLevels(0)
{
- mMemType = LLMemType::MTYPE_IMAGEFORMATTED;
}
// virtual
@@ -1561,7 +1520,7 @@ void LLImageFormatted::appendData(U8 *data, S32 size)
//----------------------------------------------------------------------------
-BOOL LLImageFormatted::load(const std::string &filename)
+BOOL LLImageFormatted::load(const std::string &filename, int load_size)
{
resetLastError();
@@ -1580,14 +1539,19 @@ BOOL LLImageFormatted::load(const std::string &filename)
return FALSE;
}
+ // Constrain the load size to acceptable values
+ if ((load_size == 0) || (load_size > file_size))
+ {
+ load_size = file_size;
+ }
BOOL res;
- U8 *data = allocateData(file_size);
- apr_size_t bytes_read = file_size;
+ U8 *data = allocateData(load_size);
+ apr_size_t bytes_read = load_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)
+ if (s != APR_SUCCESS || (S32) bytes_read != load_size)
{
deleteData();
- setLastError("Unable to read entire file",filename);
+ setLastError("Unable to read file",filename);
res = FALSE;
}
else
@@ -1650,6 +1614,12 @@ static void avg4_colors2(const U8* a, const U8* b, const U8* c, const U8* d, U8*
dst[1] = (U8)(((U32)(a[1]) + b[1] + c[1] + d[1])>>2);
}
+void LLImageBase::setDataAndSize(U8 *data, S32 size)
+{
+ ll_assert_aligned(data, 16);
+ mData = data; mDataSize = size;
+}
+
//static
void LLImageBase::generateMip(const U8* indata, U8* mipdata, S32 width, S32 height, S32 nchannels)
{
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 4469c9e860..2277afc585 100644..100755
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -30,7 +30,7 @@
#include "lluuid.h"
#include "llstring.h"
#include "llthread.h"
-#include "llmemtype.h"
+#include "llpointer.h"
const S32 MIN_IMAGE_MIP = 2; // 4x4, only used for expand/contract power of 2
const S32 MAX_IMAGE_MIP = 11; // 2048x2048
@@ -48,6 +48,8 @@ const S32 MAX_PRECINCT_SIZE = 2048; // No reason to be bigger than MAX_IMAGE_S
const S32 MIN_PRECINCT_SIZE = 4; // Can't be smaller than MIN_BLOCK_SIZE
const S32 MAX_BLOCK_SIZE = 64; // Max total block size is 4096, hence 64x64 when using square blocks
const S32 MIN_BLOCK_SIZE = 4; // Min block dim is 4 according to jpeg2000 spec
+const S32 MIN_LAYER_SIZE = 2000; // Size of the first quality layer (after header). Must be > to FIRST_PACKET_SIZE!!
+const S32 MAX_NB_LAYERS = 64; // Max number of layers we'll entertain in SL (practical limit)
const S32 MIN_IMAGE_SIZE = (1<<MIN_IMAGE_MIP); // 4, only used for expand/contract power of 2
const S32 MAX_IMAGE_SIZE = (1<<MAX_IMAGE_MIP); // 2048
@@ -60,6 +62,7 @@ const S32 MAX_IMAGE_DATA_SIZE = MAX_IMAGE_AREA * MAX_IMAGE_COMPONENTS; //2048 *
// *TODO: change both to 1024 when SIM texture fetching is deprecated
const S32 FIRST_PACKET_SIZE = 600;
const S32 MAX_IMG_PACKET_SIZE = 1000;
+const S32 HTTP_PACKET_SIZE = 1496;
// Base classes for images.
// There are two major parts for the image:
@@ -89,15 +92,20 @@ typedef enum e_image_codec
class LLImage
{
public:
- static void initClass();
+ 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 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 bool sUseNewByteRange;
+ static S32 sMinimalReverseByteRangePercent;
};
//============================================================================
@@ -140,7 +148,7 @@ public:
protected:
// special accessor to allow direct setting of mData and mDataSize by LLImageFormatted
- void setDataAndSize(U8 *data, S32 size) { mData = data; mDataSize = size; }
+ void setDataAndSize(U8 *data, S32 size);
public:
static void generateMip(const U8 *indata, U8* mipdata, int width, int height, S32 nchannels);
@@ -168,8 +176,6 @@ private:
bool mAllowOverSize ;
static LLPrivateMemoryPool* sPrivatePoolp ;
-public:
- LLMemType::DeclareMemType& mMemType; // debug
};
// Raw representation of an image (used for textures, and other uncompressed formats
@@ -181,7 +187,7 @@ protected:
public:
LLImageRaw();
LLImageRaw(U16 width, U16 height, S8 components);
- LLImageRaw(U8 *data, U16 width, U16 height, S8 components);
+ LLImageRaw(U8 *data, U16 width, U16 height, S8 components, bool no_copy = false);
// Construct using createFromFile (used by tools)
//LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only = false);
@@ -203,13 +209,15 @@ public:
void contractToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE, BOOL scale_image = TRUE);
void biasedScaleToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE);
BOOL scale( S32 new_width, S32 new_height, BOOL scale_image = TRUE );
- //BOOL scaleDownWithoutBlending( S32 new_width, S32 new_height) ;
-
+
// Fill the buffer with a constant color
void fill( const LLColor4U& color );
// Copy operations
+ //duplicate this raw image if refCount > 1.
+ LLPointer<LLImageRaw> duplicate();
+
// Src and dst can be any size. Src and dst can each have 3 or 4 components.
void copy( LLImageRaw* src );
@@ -222,6 +230,11 @@ public:
// Src and dst are same size. Src has 3 components. Dst has 4 components.
void copyUnscaled3onto4( LLImageRaw* src );
+ // Src and dst are same size. Src has 1 component. Dst has 4 components.
+ // Alpha component is set to source alpha mask component.
+ // RGB components are set to fill color.
+ void copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill);
+
// Src and dst can be any size. Src and dst have same number of components.
void copyScaled( LLImageRaw* src );
@@ -294,7 +307,7 @@ public:
// getRawDiscardLevel() by default returns mDiscardLevel, but may be overridden (LLImageJ2C)
virtual S8 getRawDiscardLevel() { return mDiscardLevel; }
- BOOL load(const std::string& filename);
+ BOOL load(const std::string& filename, int load_size = 0);
BOOL save(const std::string& filename);
virtual BOOL updateData() = 0; // pure virtual
@@ -313,6 +326,8 @@ public:
BOOL isDecoded() const { return mDecoded ? TRUE : FALSE; }
void setDiscardLevel(S8 discard_level) { mDiscardLevel = discard_level; }
S8 getDiscardLevel() const { return mDiscardLevel; }
+ S8 getLevels() const { return mLevels; }
+ void setLevels(S8 nlevels) { mLevels = nlevels; }
// setLastError needs to be deferred for J2C images since it may be called from a DLL
virtual void resetLastError();
@@ -325,7 +340,8 @@ protected:
S8 mCodec;
S8 mDecoding;
S8 mDecoded; // unused, but changing LLImage layout requires recompiling static Mac/Linux libs. 2009-01-30 JC
- S8 mDiscardLevel;
+ S8 mDiscardLevel; // Current resolution level worked on. 0 = full res, 1 = half res, 2 = quarter res, etc...
+ S8 mLevels; // Number of resolution levels in that image. Min is 1. 0 means unknown.
public:
static S32 sGlobalFormattedMemory;
diff --git a/indra/llimage/llimagebmp.cpp b/indra/llimage/llimagebmp.cpp
index 60b1c628d7..60b1c628d7 100644..100755
--- a/indra/llimage/llimagebmp.cpp
+++ b/indra/llimage/llimagebmp.cpp
diff --git a/indra/llimage/llimagebmp.h b/indra/llimage/llimagebmp.h
index db0b45def0..db0b45def0 100644..100755
--- a/indra/llimage/llimagebmp.h
+++ b/indra/llimage/llimagebmp.h
diff --git a/indra/llimage/llimagedimensionsinfo.cpp b/indra/llimage/llimagedimensionsinfo.cpp
index c6bfa50b40..c6bfa50b40 100644..100755
--- a/indra/llimage/llimagedimensionsinfo.cpp
+++ b/indra/llimage/llimagedimensionsinfo.cpp
diff --git a/indra/llimage/llimagedimensionsinfo.h b/indra/llimage/llimagedimensionsinfo.h
index 382fdb2a0e..382fdb2a0e 100644..100755
--- a/indra/llimage/llimagedimensionsinfo.h
+++ b/indra/llimage/llimagedimensionsinfo.h
diff --git a/indra/llimage/llimagedxt.cpp b/indra/llimage/llimagedxt.cpp
index 34c6793522..34c6793522 100644..100755
--- a/indra/llimage/llimagedxt.cpp
+++ b/indra/llimage/llimagedxt.cpp
diff --git a/indra/llimage/llimagedxt.h b/indra/llimage/llimagedxt.h
index a8756ba8ed..a8756ba8ed 100644..100755
--- a/indra/llimage/llimagedxt.h
+++ b/indra/llimage/llimagedxt.h
diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp
index 8241746a74..5412f98ee5 100644..100755
--- a/indra/llimage/llimagej2c.cpp
+++ b/indra/llimage/llimagej2c.cpp
@@ -26,7 +26,6 @@
#include "lldir.h"
#include "llimagej2c.h"
-#include "llmemtype.h"
#include "lltimer.h"
#include "llmath.h"
#include "llmemory.h"
@@ -56,7 +55,7 @@ std::string LLImageJ2C::getEngineInfo()
LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C),
mMaxBytes(0),
mRawDiscardLevel(-1),
- mRate(0.0f),
+ mRate(DEFAULT_COMPRESSION_RATE),
mReversible(FALSE),
mAreaUsedForDataSizeCalcs(0)
{
@@ -142,6 +141,7 @@ BOOL LLImageJ2C::updateData()
BOOL LLImageJ2C::initDecode(LLImageRaw &raw_image, int discard_level, int* region)
{
+ setDiscardLevel(discard_level != -1 ? discard_level : 0);
return mImpl->initDecode(*this,raw_image,discard_level,region);
}
@@ -160,7 +160,6 @@ BOOL LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time)
BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 first_channel, S32 max_channel_count )
{
LLTimer elapsed;
- LLMemType mt1(mMemType);
BOOL res = TRUE;
@@ -226,7 +225,6 @@ BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, F32 encode_time)
BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, const char* comment_text, F32 encode_time)
{
LLTimer elapsed;
- LLMemType mt1(mMemType);
resetLastError();
BOOL res = mImpl->encodeImpl(*this, *raw_imagep, comment_text, encode_time, mReversible);
if (!mLastError.empty())
@@ -261,19 +259,34 @@ S32 LLImageJ2C::calcHeaderSizeJ2C()
//static
S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate)
{
- // Note: this only provides an *estimate* of the size in bytes of an image level
- // *TODO: find a way to read the true size (when available) and convey the fact
- // that the result is an estimate in the other cases
- if (rate <= 0.f) rate = .125f;
- while (discard_level > 0)
+ // Note: This provides an estimation for the first to last quality layer of a given discard level
+ // This is however an efficient approximation, as the true discard level boundary would be
+ // in general too big for fast fetching.
+ // 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().
+ S32 nb_layers = 1;
+ S32 surface = w*h;
+ S32 s = 64*64;
+ while (surface > s)
{
- if (w < 1 || h < 1)
- break;
- w >>= 1;
- h >>= 1;
- discard_level--;
+ nb_layers++;
+ s *= 4;
}
- S32 bytes = (S32)((F32)(w*h*comp)*rate);
+ 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;
}
@@ -283,15 +296,12 @@ S32 LLImageJ2C::calcHeaderSize()
return calcHeaderSizeJ2C();
}
-
-// calcDataSize() returns how many bytes to read
-// to load discard_level (including header and higher discard levels)
+// calcDataSize() returns how many bytes to read to load discard_level (including header)
S32 LLImageJ2C::calcDataSize(S32 discard_level)
{
discard_level = llclamp(discard_level, 0, MAX_DISCARD_LEVEL);
-
if ( mAreaUsedForDataSizeCalcs != (getHeight() * getWidth())
- || mDataSizes[0] == 0)
+ || (mDataSizes[0] == 0))
{
mAreaUsedForDataSizeCalcs = getHeight() * getWidth();
@@ -301,25 +311,6 @@ S32 LLImageJ2C::calcDataSize(S32 discard_level)
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];
}
@@ -334,8 +325,9 @@ S32 LLImageJ2C::calcDiscardLevelBytes(S32 bytes)
}
while (1)
{
- S32 bytes_needed = calcDataSize(discard_level); // virtual
- if (bytes >= bytes_needed - (bytes_needed>>2)) // For J2c, up the res at 75% of the optimal number of bytes
+ S32 bytes_needed = calcDataSize(discard_level);
+ // Use TextureReverseByteRange percent (see settings.xml) of the optimal size to qualify as correct rendering for the given discard level
+ if (bytes >= (bytes_needed*LLImage::getReverseByteRangePercent()/100))
{
break;
}
@@ -348,11 +340,6 @@ S32 LLImageJ2C::calcDiscardLevelBytes(S32 bytes)
return discard_level;
}
-void LLImageJ2C::setRate(F32 rate)
-{
- mRate = rate;
-}
-
void LLImageJ2C::setMaxBytes(S32 max_bytes)
{
mMaxBytes = max_bytes;
@@ -414,7 +401,6 @@ BOOL LLImageJ2C::loadAndValidate(const std::string &filename)
BOOL LLImageJ2C::validate(U8 *data, U32 file_size)
{
- LLMemType mt1(mMemType);
resetLastError();
@@ -474,6 +460,7 @@ LLImageCompressionTester::LLImageCompressionTester() : LLMetricPerformanceTester
addMetric("Perf Compression (kB/s)");
mRunBytesInDecompression = 0;
+ mRunBytesOutDecompression = 0;
mRunBytesInCompression = 0;
mTotalBytesInDecompression = 0;
@@ -483,6 +470,7 @@ LLImageCompressionTester::LLImageCompressionTester() : LLMetricPerformanceTester
mTotalTimeDecompression = 0.0f;
mTotalTimeCompression = 0.0f;
+ mRunTimeDecompression = 0.0f;
}
LLImageCompressionTester::~LLImageCompressionTester()
@@ -565,12 +553,17 @@ void LLImageCompressionTester::updateDecompressionStats(const S32 bytesIn, const
mTotalBytesInDecompression += bytesIn;
mRunBytesInDecompression += bytesIn;
mTotalBytesOutDecompression += bytesOut;
- if (mRunBytesInDecompression > (1000000))
+ mRunBytesOutDecompression += bytesOut;
+ //if (mRunBytesInDecompression > (1000000))
+ if (mRunBytesOutDecompression > (10000000))
+ //if ((mTotalTimeDecompression - mRunTimeDecompression) >= (5.0f))
{
// Output everything
outputTestResults();
// Reset the decompression data of the run
mRunBytesInDecompression = 0;
+ mRunBytesOutDecompression = 0;
+ mRunTimeDecompression = mTotalTimeDecompression;
}
}
diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h
index 914174fc57..ce8195940d 100644..100755
--- a/indra/llimage/llimagej2c.h
+++ b/indra/llimage/llimagej2c.h
@@ -31,6 +31,9 @@
#include "llassettype.h"
#include "llmetricperformancetester.h"
+// JPEG2000 : compression rate used in j2c conversion.
+const F32 DEFAULT_COMPRESSION_RATE = 1.f/8.f;
+
class LLImageJ2CImpl;
class LLImageCompressionTester ;
@@ -67,12 +70,11 @@ public:
// Encode accessors
void setReversible(const BOOL reversible); // Use non-lossy?
- void setRate(F32 rate);
void setMaxBytes(S32 max_bytes);
S32 getMaxBytes() const { return mMaxBytes; }
static S32 calcHeaderSizeJ2C();
- static S32 calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate = 0.f);
+ static S32 calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate = DEFAULT_COMPRESSION_RATE);
static std::string getEngineInfo();
@@ -154,13 +156,15 @@ class LLImageCompressionTester : public LLMetricPerformanceTesterBasic
U32 mTotalBytesOutDecompression; // Total bytes produced by decompressor
U32 mTotalBytesInCompression; // Total bytes fed to compressor
U32 mTotalBytesOutCompression; // Total bytes produced by compressor
- U32 mRunBytesInDecompression; // Bytes fed to decompressor in this run
+ U32 mRunBytesInDecompression; // Bytes fed to decompressor in this run
+ U32 mRunBytesOutDecompression; // Bytes produced by the decompressor in this run
U32 mRunBytesInCompression; // Bytes fed to compressor in this run
//
// Time
//
F32 mTotalTimeDecompression; // Total time spent in computing decompression
F32 mTotalTimeCompression; // Total time spent in computing compression
+ F32 mRunTimeDecompression; // Time in this run (we output every 5 sec in decompress)
};
#endif
diff --git a/indra/llimage/llimagejpeg.cpp b/indra/llimage/llimagejpeg.cpp
index b70f84efc8..b70f84efc8 100644..100755
--- a/indra/llimage/llimagejpeg.cpp
+++ b/indra/llimage/llimagejpeg.cpp
diff --git a/indra/llimage/llimagejpeg.h b/indra/llimage/llimagejpeg.h
index 7ac7f5d2e0..7ac7f5d2e0 100644..100755
--- a/indra/llimage/llimagejpeg.h
+++ b/indra/llimage/llimagejpeg.h
diff --git a/indra/llimage/llimagepng.cpp b/indra/llimage/llimagepng.cpp
index 294f68b122..294f68b122 100644..100755
--- a/indra/llimage/llimagepng.cpp
+++ b/indra/llimage/llimagepng.cpp
diff --git a/indra/llimage/llimagepng.h b/indra/llimage/llimagepng.h
index 1fbd850a2e..1fbd850a2e 100644..100755
--- a/indra/llimage/llimagepng.h
+++ b/indra/llimage/llimagepng.h
diff --git a/indra/llimage/llimagetga.cpp b/indra/llimage/llimagetga.cpp
index 58426d31fa..920ae2891f 100644..100755
--- a/indra/llimage/llimagetga.cpp
+++ b/indra/llimage/llimagetga.cpp
@@ -132,12 +132,12 @@ BOOL LLImageTGA::updateData()
** FIELD 2 : COLOR MAP TYPE (1 BYTES)
** FIELD 3 : IMAGE TYPE CODE (1 BYTES)
** = 0 NO IMAGE DATA INCLUDED
- ** = 1 UNCOMPRESSED, COLOR-MAPPED IMAGE
- ** = 2 UNCOMPRESSED, TRUE-COLOR IMAGE
- ** = 3 UNCOMPRESSED, BLACK AND WHITE IMAGE
- ** = 9 RUN-LENGTH ENCODED COLOR-MAPPED IMAGE
- ** = 10 RUN-LENGTH ENCODED TRUE-COLOR IMAGE
- ** = 11 RUN-LENGTH ENCODED BLACK AND WHITE IMAGE
+ ** = (0001) 1 UNCOMPRESSED, COLOR-MAPPED IMAGE
+ ** = (0010) 2 UNCOMPRESSED, TRUE-COLOR IMAGE
+ ** = (0011) 3 UNCOMPRESSED, BLACK AND WHITE IMAGE
+ ** = (1001) 9 RUN-LENGTH ENCODED COLOR-MAPPED IMAGE
+ ** = (1010) 10 RUN-LENGTH ENCODED TRUE-COLOR IMAGE
+ ** = (1011) 11 RUN-LENGTH ENCODED BLACK AND WHITE IMAGE
** FIELD 4 : COLOR MAP SPECIFICATION (5 BYTES)
** 4.1 : COLOR MAP ORIGIN (2 BYTES)
** 4.2 : COLOR MAP LENGTH (2 BYTES)
diff --git a/indra/llimage/llimagetga.h b/indra/llimage/llimagetga.h
index 5da3525149..5da3525149 100644..100755
--- a/indra/llimage/llimagetga.h
+++ b/indra/llimage/llimagetga.h
diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp
index ad2eb0f69c..ad2eb0f69c 100644..100755
--- a/indra/llimage/llimageworker.cpp
+++ b/indra/llimage/llimageworker.cpp
diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h
index 1bfb0ddfd3..1bfb0ddfd3 100644..100755
--- a/indra/llimage/llimageworker.h
+++ b/indra/llimage/llimageworker.h
diff --git a/indra/llimage/llmapimagetype.h b/indra/llimage/llmapimagetype.h
index 0a040d3db9..0a040d3db9 100644..100755
--- a/indra/llimage/llmapimagetype.h
+++ b/indra/llimage/llmapimagetype.h
diff --git a/indra/llimage/llpngwrapper.cpp b/indra/llimage/llpngwrapper.cpp
index 2cc7d3c460..2cc7d3c460 100644..100755
--- a/indra/llimage/llpngwrapper.cpp
+++ b/indra/llimage/llpngwrapper.cpp
diff --git a/indra/llimage/llpngwrapper.h b/indra/llimage/llpngwrapper.h
index 739f435996..739f435996 100644..100755
--- a/indra/llimage/llpngwrapper.h
+++ b/indra/llimage/llpngwrapper.h
diff --git a/indra/llimage/tests/llimageworker_test.cpp b/indra/llimage/tests/llimageworker_test.cpp
index 08476fb72c..e255d65b43 100644..100755
--- a/indra/llimage/tests/llimageworker_test.cpp
+++ b/indra/llimage/tests/llimageworker_test.cpp
@@ -49,8 +49,7 @@ mWidth(0),
mHeight(0),
mComponents(0),
mBadBufferAllocation(false),
-mAllowOverSize(false),
-mMemType(LLMemType::MTYPE_IMAGEBASE)
+mAllowOverSize(false)
{
}
LLImageBase::~LLImageBase() {}