summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llimage/llimage.cpp4
-rw-r--r--indra/llimage/llimage.h8
-rw-r--r--indra/llimage/llimagej2c.cpp73
-rw-r--r--indra/llimage/llimagej2c.h6
-rw-r--r--indra/llkdu/llimagej2ckdu.cpp125
-rw-r--r--indra/llkdu/tests/llimagej2ckdu_test.cpp3
-rwxr-xr-xindra/newview/app_settings/settings.xml11
-rw-r--r--indra/newview/llappviewer.cpp2
-rw-r--r--indra/newview/lltexlayer.cpp1
-rw-r--r--indra/newview/llviewertexturelist.cpp1
10 files changed, 121 insertions, 113 deletions
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 937655a22d..7f95441075 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -48,11 +48,13 @@
//static
std::string LLImage::sLastErrorMessage;
LLMutex* LLImage::sMutex = NULL;
+bool LLImage::sUseNewByteRange = false;
LLPrivateMemoryPool* LLImageBase::sPrivatePoolp = NULL ;
//static
-void LLImage::initClass()
+void LLImage::initClass(bool use_new_byte_range)
{
+ sUseNewByteRange = use_new_byte_range;
sMutex = new LLMutex(NULL);
LLImageBase::createPrivatePool() ;
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index eba8362f1c..a643e4d9f5 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -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,18 @@ typedef enum e_image_codec
class LLImage
{
public:
- static void initClass();
+ static void initClass(bool use_new_byte_range = false);
static void cleanupClass();
static const std::string& getLastError();
static void setLastError(const std::string& message);
+ static bool useNewByteRange() { return sUseNewByteRange; }
+
protected:
static LLMutex* sMutex;
static std::string sLastErrorMessage;
+ static bool sUseNewByteRange;
};
//============================================================================
diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp
index fbf4b769e1..69d261c9a6 100644
--- a/indra/llimage/llimagej2c.cpp
+++ b/indra/llimage/llimagej2c.cpp
@@ -56,7 +56,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)
{
@@ -262,19 +262,35 @@ 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 = sqrt((F32)(w*h))*(F32)(comp)*rate*1000.f/layer_factor;
+ S32 old_bytes = (S32)((F32)(w*h*comp)*rate);
+ //llinfos << "Merov debug : w = " << w << ", h = " << h << ", c = " << comp << ", r = " << rate << ", d = " << discard_level << ", l = " << nb_layers << ", old = " << old_bytes << ", new = " << new_bytes << llendl;
+ bytes = (LLImage::useNewByteRange() ? new_bytes : old_bytes);
bytes = llmax(bytes, calcHeaderSizeJ2C());
return bytes;
}
@@ -284,17 +300,12 @@ S32 LLImageJ2C::calcHeaderSize()
return calcHeaderSizeJ2C();
}
-
-// calcDataSize() returns how many bytes to read
-// to load discard_level (including header and higher discard levels)
-// *TODO: This is deeply wrong. That size should be taken from the image file header or other
-// relevant infos. In any case, this is only an approximation.
+// 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();
@@ -304,25 +315,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];
}
@@ -351,11 +343,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;
diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h
index 914174fc57..91c344d12f 100644
--- 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();
diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index 8b170a3206..cbfc34ebb8 100644
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -245,6 +245,8 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECod
mCodeStreamp->create(mInputp);
// Set the maximum number of bytes to use from the codestream
+ // *TODO: This seems to be wrong. The base class should have no idea of how j2c compression works so no
+ // good way of computing what's the byte range to be used.
mCodeStreamp->set_max_bytes(max_bytes,true);
// If you want to flip or rotate the image for some reason, change
@@ -294,7 +296,7 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECod
// Get the number of resolution levels in that image
mLevels = mCodeStreamp->get_min_dwt_levels();
-
+
// Set the base dimensions
base.setSize(dims.size.x, dims.size.y, components);
base.setLevels(mLevels);
@@ -357,7 +359,8 @@ BOOL LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int bloc
mLevels = levels;
if (mLevels != 0)
{
- mLevels = llclamp(mLevels,MIN_DECOMPOSITION_LEVELS,MIN_DECOMPOSITION_LEVELS);
+ mLevels = llclamp(mLevels,MIN_DECOMPOSITION_LEVELS,MAX_DECOMPOSITION_LEVELS);
+ base.setLevels(mLevels);
}
return TRUE;
}
@@ -390,7 +393,7 @@ BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
region_kdu->size.y = region[3] - region[1];
}
int discard = (discard_level != -1 ? discard_level : base.getRawDiscardLevel());
-
+ //llinfos << "Merov debug : initDecode, discard used = " << discard << ", asked = " << discard_level << llendl;
// Apply loading restrictions
mCodeStreamp->apply_input_restrictions( first_channel, max_channel_count, discard, 0, region_kdu);
@@ -589,12 +592,6 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
comment.put_text(comment_text);
}
- // Set codestream options
- int num_layer_specs = 0;
-
- kdu_long layer_bytes[64];
- U32 max_bytes = 0;
-
if (num_components >= 3)
{
// Note that we always use YCC and not YUV
@@ -602,67 +599,63 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
set_default_colour_weights(codestream.access_siz());
}
+ // Set codestream options
+ int nb_layers = 0;
+ kdu_long layer_bytes[MAX_NB_LAYERS];
+ U32 max_bytes = (U32)(base.getWidth() * base.getHeight() * base.getComponents());
+
+ // Rate is the argument passed into the LLImageJ2C which specifies the target compression rate. The default is 8:1.
+ // *TODO: mRate is actually always 8:1 in the viewer. Test different values.
+ llassert (base.mRate > 0.f);
+ max_bytes = (U32)((F32)(max_bytes) * base.mRate);
+
+ // If the image is very small, code it in a lossless way.
+ // Note: it'll also have only 1 layer which is fine as there's no point reordering blocks in that case.
+ if (max_bytes < FIRST_PACKET_SIZE)
+ {
+ reversible = true;
+ }
+
+ // This code is where we specify the target number of bytes for each quality layer.
+ // We're using a logarithmic spacing rule that fits with our way of fetching texture data.
+ // Note: For more info on this layers business, read kdu_codestream::flush() doc in kdu_compressed.h
+ U32 i = FIRST_PACKET_SIZE;
+ while ((i < max_bytes) && (nb_layers < (MAX_NB_LAYERS-1)))
+ {
+ if (i == FIRST_PACKET_SIZE * 4)
+ {
+ // That really just means that the first layer is FIRST_PACKET_SIZE and the second is MIN_LAYER_SIZE
+ i = MIN_LAYER_SIZE;
+ }
+ layer_bytes[nb_layers] = i;
+ nb_layers++;
+ i *= 4;
+ }
+
if (reversible)
{
codestream.access_siz()->parse_string("Creversible=yes");
- // *TODO: we should use yuv in reversible mode and one level since those images are small.
+ // *TODO: we should use yuv in reversible mode and one res level since those images are small.
// Don't turn this on now though as both create problems on decoding for the moment
//codestream.access_siz()->parse_string("Clevels=1");
//codestream.access_siz()->parse_string("Cycc=no");
- // If we're doing reversible (i.e. lossless compression), assumes we're not using quality layers.
- // *TODO: this is incorrect and unecessary. Try using the regular layer setting.
- codestream.access_siz()->parse_string("Clayers=1");
- num_layer_specs = 1;
- layer_bytes[0] = 0;
+ // In the reversible case, set the last entry of that table to 0 so that all generated bits will
+ // indeed be output by the time the last quality layer is encountered.
+ layer_bytes[nb_layers] = 0;
}
else
{
- // Rate is the argument passed into the LLImageJ2C which
- // specifies the target compression rate. The default is 8:1.
- // Possibly if max_bytes < 500, we should just use the default setting?
- // *TODO: mRate is actually always 8:1 in the viewer. Test different values. Also force to reversible for small (< 500 bytes) textures.
- if (base.mRate != 0.f)
- {
- max_bytes = (U32)(base.mRate*base.getWidth()*base.getHeight()*base.getComponents());
- }
- else
- {
- max_bytes = (U32)(base.getWidth()*base.getHeight()*base.getComponents()*0.125);
- }
-
- const U32 min_bytes = FIRST_PACKET_SIZE;
- if (max_bytes > min_bytes)
- {
- U32 i;
- // This code is where we specify the target number of bytes for
- // each layer. Not sure if we should do this for small images
- // or not. The goal is to have this roughly align with
- // different quality levels that we decode at.
- for (i = min_bytes; i < max_bytes; i*=4)
- {
- if (i == min_bytes * 4)
- {
- i = 2000;
- }
- layer_bytes[num_layer_specs] = i;
- num_layer_specs++;
- }
- layer_bytes[num_layer_specs] = max_bytes;
- num_layer_specs++;
-
- std::string layer_string = llformat("Clayers=%d",num_layer_specs);
- codestream.access_siz()->parse_string(layer_string.c_str());
- }
- else
- {
- layer_bytes[0] = min_bytes;
- num_layer_specs = 1;
- std::string layer_string = llformat("Clayers=%d",num_layer_specs);
- codestream.access_siz()->parse_string(layer_string.c_str());
- }
+ // Truncate the last quality layer if necessary so to fit the set compression ratio
+ layer_bytes[nb_layers] = max_bytes;
}
+ nb_layers++;
+
+ std::string layer_string = llformat("Clayers=%d",nb_layers);
+ codestream.access_siz()->parse_string(layer_string.c_str());
// Set up data ordering, markers, etc... if precincts or blocks specified
+ // Note: This code is *not* used in the encoding made by the viewer. It is currently used only
+ // by llimage_libtest to create various j2c and test alternative compression schemes.
if ((mBlocksSize != -1) || (mPrecinctsSize != -1))
{
if (mPrecinctsSize != -1)
@@ -675,23 +668,26 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
std::string blocks_string = llformat("Cblk={%d,%d}",mBlocksSize,mBlocksSize);
codestream.access_siz()->parse_string(blocks_string.c_str());
}
- std::string ordering_string = llformat("Corder=RPCL");
+ std::string ordering_string = llformat("Corder=LRCP");
codestream.access_siz()->parse_string(ordering_string.c_str());
std::string PLT_string = llformat("ORGgen_plt=yes");
codestream.access_siz()->parse_string(PLT_string.c_str());
std::string Parts_string = llformat("ORGtparts=R");
codestream.access_siz()->parse_string(Parts_string.c_str());
}
+
+ // Set the number of wavelets subresolutions (aka levels)
if (mLevels != 0)
{
std::string levels_string = llformat("Clevels=%d",mLevels);
codestream.access_siz()->parse_string(levels_string.c_str());
}
+ // Complete the encode settings
codestream.access_siz()->finalize_all();
codestream.change_appearance(transpose,vflip,hflip);
- // Now we are ready for sample data processing.
+ // Now we are ready for sample data processing
kdc_flow_control *tile = new kdc_flow_control(&mem_in,codestream);
bool done = false;
while (!done)
@@ -708,7 +704,7 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
}
// Produce the compressed output
- codestream.flush(layer_bytes,num_layer_specs);
+ codestream.flush(layer_bytes,nb_layers);
// Cleanup
delete tile;
@@ -807,12 +803,14 @@ copy_tile(kdu_tile tile_in, kdu_tile tile_out, int tnum_in, int tnum_out,
comp_in = tile_in.access_component(c);
comp_out = tile_out.access_component(c);
int num_resolutions = comp_out.get_num_resolutions();
+ //std::cout << " Copying tile : num_resolutions = " << num_resolutions << std::endl;
for (int r=0; r < num_resolutions; r++)
{
kdu_resolution res_in; res_in = comp_in.access_resolution(r);
kdu_resolution res_out; res_out = comp_out.access_resolution(r);
int b, min_band;
int num_bands = res_in.get_valid_band_indices(min_band);
+ std::cout << " Copying tile : num_bands = " << num_bands << std::endl;
for (b=min_band; num_bands > 0; num_bands--, b++)
{
kdu_subband band_in; band_in = res_in.access_subband(b);
@@ -826,6 +824,7 @@ copy_tile(kdu_tile tile_in, kdu_tile tile_out, int tnum_in, int tnum_out,
return;
}
kdu_coords idx;
+ //std::cout << " Copying tile : block indices, x = " << blocks_out.size.x << " and y = " << blocks_out.size.y << std::endl;
for (idx.y=0; idx.y < blocks_out.size.y; idx.y++)
{
for (idx.x=0; idx.x < blocks_out.size.x; idx.x++)
@@ -857,10 +856,11 @@ void LLImageJ2CKDU::findDiscardLevelsBoundaries(LLImageJ2C &base)
for (int discard_level = 0; discard_level < mLevels; discard_level++)
{
+ //std::cout << "Parsing discard level = " << discard_level << std::endl;
// Create the input codestream object.
setupCodeStream(base, TRUE, MODE_FAST);
mCodeStreamp->apply_input_restrictions(0, 4, discard_level, 0, NULL);
- //mCodeStreamp->set_max_bytes(max,true);
+ mCodeStreamp->set_max_bytes(KDU_LONG_MAX,true);
siz_params *siz_in = mCodeStreamp->access_siz();
// Create the output codestream object.
@@ -898,6 +898,7 @@ void LLImageJ2CKDU::findDiscardLevelsBoundaries(LLImageJ2C &base)
int num_blocks=0;
kdu_coords idx;
+ //std::cout << "Parsing tiles : x = " << tile_indices_out.size.x << " to y = " << tile_indices_out.size.y << std::endl;
for (idx.y=0; idx.y < tile_indices_out.size.y; idx.y++)
{
for (idx.x=0; idx.x < tile_indices_out.size.x; idx.x++)
diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp
index feb6671e40..beee99a522 100644
--- a/indra/llkdu/tests/llimagej2ckdu_test.cpp
+++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp
@@ -87,7 +87,7 @@ void LLImageFormatted::resetLastError() { }
void LLImageFormatted::sanityCheck() { }
void LLImageFormatted::setLastError(const std::string& , const std::string& ) { }
-LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C) { }
+LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C), mRate(DEFAULT_COMPRESSION_RATE) { }
LLImageJ2C::~LLImageJ2C() { }
S32 LLImageJ2C::calcDataSize(S32 ) { return 0; }
S32 LLImageJ2C::calcDiscardLevelBytes(S32 ) { return 0; }
@@ -146,6 +146,7 @@ void kdu_codestream::set_fast() { }
void kdu_codestream::set_fussy() { }
void kdu_codestream::get_dims(int, kdu_dims&, bool ) { }
int kdu_codestream::get_min_dwt_levels() { return 5; }
+int kdu_codestream::get_max_tile_layers() { return 1; }
void kdu_codestream::change_appearance(bool, bool, bool) { }
void kdu_codestream::get_tile_dims(kdu_coords, int, kdu_dims&, bool ) { }
void kdu_codestream::destroy() { }
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 9fff543b13..5fc9c5d863 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -10686,6 +10686,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>TextureNewByteRange</key>
+ <map>
+ <key>Comment</key>
+ <string>Use the new more accurate byte range computation for j2c discard levels</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>TexturePickerShowFolders</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 971b096a15..93ad72a147 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1945,7 +1945,7 @@ bool LLAppViewer::initThreads()
static const bool enable_threads = true;
#endif
- LLImage::initClass();
+ LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"));
LLVFSThread::initClass(enable_threads && false);
LLLFSThread::initClass(enable_threads && false);
diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp
index 1693cfc9e2..467115c928 100644
--- a/indra/newview/lltexlayer.cpp
+++ b/indra/newview/lltexlayer.cpp
@@ -497,7 +497,6 @@ void LLTexLayerSetBuffer::doUpload()
}
LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C;
- compressedImage->setRate(0.f);
const char* comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // writes into baked_color_data. 5 channels (rgb, heightfield/alpha, mask)
if (compressedImage->encode(baked_image, comment_text))
{
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 089f45ca89..54ae519422 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -1030,7 +1030,6 @@ LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImage
{
raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C();
- compressedImage->setRate(0.f);
if (gSavedSettings.getBOOL("LosslessJ2CUpload") &&
(raw_image->getWidth() * raw_image->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF))