diff options
author | Merov Linden <merov@lindenlab.com> | 2012-04-04 18:58:34 -0700 |
---|---|---|
committer | Merov Linden <merov@lindenlab.com> | 2012-04-04 18:58:34 -0700 |
commit | 782981866a70f4a33a298c93ee80aaf138fdf459 (patch) | |
tree | 61a15a6a262bc6052750b6ca63049f3e97e70539 | |
parent | c6511d9c857c079e0360f88c05328feb70a8bc0d (diff) |
SH-3060 : New byte range implementation. Intermediate (not working) state.
-rw-r--r-- | indra/llimage/llimage.cpp | 3 | ||||
-rw-r--r-- | indra/llimage/llimage.h | 3 | ||||
-rw-r--r-- | indra/llimage/llimagej2c.cpp | 20 | ||||
-rw-r--r-- | indra/llimage/llimagej2c.h | 3 | ||||
-rw-r--r-- | indra/llkdu/llimagej2ckdu.cpp | 40 | ||||
-rw-r--r-- | indra/llkdu/llimagej2ckdu.h | 1 | ||||
-rw-r--r-- | indra/llkdu/tests/llimagej2ckdu_test.cpp | 1 |
7 files changed, 44 insertions, 27 deletions
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 7f95441075..cce03ff6e6 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -1337,7 +1337,8 @@ LLImageFormatted::LLImageFormatted(S8 codec) mDecoding(0), mDecoded(0), mDiscardLevel(-1), - mLevels(0) + mLevels(0), + mLayers(0) { mMemType = LLMemType::MTYPE_IMAGEFORMATTED; } diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 18f8ae2fbb..c5a7d6262e 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -320,6 +320,8 @@ public: S8 getDiscardLevel() const { return mDiscardLevel; } S8 getLevels() const { return mLevels; } void setLevels(S8 nlevels) { mLevels = nlevels; } + S32 getLayers() const { return mLayers; } + void setLayers(S32 nlayers) { mLayers = nlayers; } // setLastError needs to be deferred for J2C images since it may be called from a DLL virtual void resetLastError(); @@ -334,6 +336,7 @@ protected: S8 mDecoded; // unused, but changing LLImage layout requires recompiling static Mac/Linux libs. 2009-01-30 JC 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. + S32 mLayers; // Number of quality layers in that image. Min is 1. 0 means unknown. public: static S32 sGlobalFormattedMemory; diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index cbb6f75b43..dc5bd8b5d5 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -58,7 +58,8 @@ LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C), mRawDiscardLevel(-1), mRate(0.0f), mReversible(FALSE), - mAreaUsedForDataSizeCalcs(0) + mAreaUsedForDataSizeCalcs(0), + mLayersUsedForDataSizeCalcs(0) { mImpl = fallbackCreateLLImageJ2CImpl(); @@ -260,7 +261,7 @@ S32 LLImageJ2C::calcHeaderSizeJ2C() } //static -S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate) +S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, S32 nb_layers, F32 rate) { // Note: This provides an estimation for the first quality layer of a given discard level // This is however an efficient approximation, as the true discard level boundary would be @@ -278,10 +279,11 @@ S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 r } // 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 - // *TODO: Replace the magic "7" by the number of quality layers in the j2c image S32 bytes; - S32 new_bytes = sqrt((F32)(w*h))*(F32)(comp)*rate*1000.f/7.f; + F32 layer_factor = ((nb_layers > 0) && (nb_layers < 7) ? 3.0f * (7 - nb_layers): 3.0f); + 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 : calcDataSizeJ2C, layers = " << nb_layers << ", old = " << old_bytes << ", new = " << new_bytes << llendl; bytes = (LLImage::useNewByteRange() ? new_bytes : old_bytes); bytes = llmax(bytes, calcHeaderSizeJ2C()); return bytes; @@ -298,14 +300,20 @@ S32 LLImageJ2C::calcDataSize(S32 discard_level) discard_level = llclamp(discard_level, 0, MAX_DISCARD_LEVEL); if ( mAreaUsedForDataSizeCalcs != (getHeight() * getWidth()) - || mDataSizes[0] == 0) + || (mLayersUsedForDataSizeCalcs != getLayers()) + || (mDataSizes[0] == 0)) { + if (mLayersUsedForDataSizeCalcs != getLayers()) + { + llinfos << "Merov debug : recomputing data size because " << mLayersUsedForDataSizeCalcs << " != " << getLayers() << llendl; + } mAreaUsedForDataSizeCalcs = getHeight() * getWidth(); + mLayersUsedForDataSizeCalcs = getLayers(); S32 level = MAX_DISCARD_LEVEL; // Start at the highest discard while ( level >= 0 ) { - mDataSizes[level] = calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, mRate); + mDataSizes[level] = calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, getLayers(), mRate); level--; } } diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h index 914174fc57..28e3026aac 100644 --- a/indra/llimage/llimagej2c.h +++ b/indra/llimage/llimagej2c.h @@ -72,7 +72,7 @@ public: 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, S32 nb_layers = 0, F32 rate = 0.f); static std::string getEngineInfo(); @@ -88,6 +88,7 @@ protected: S32 mDataSizes[MAX_DISCARD_LEVEL+1]; // Size of data required to reach a given level U32 mAreaUsedForDataSizeCalcs; // Height * width used to calculate mDataSizes + S32 mLayersUsedForDataSizeCalcs; // Numbers of layers used to calculate mDataSizes S8 mRawDiscardLevel; F32 mRate; diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 78c9be7bfd..08d840917d 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -195,7 +195,8 @@ mRawImagep(NULL), mDecodeState(NULL), mBlocksSize(-1), mPrecinctsSize(-1), -mLevels(0) +mLevels(0), +mLayers(0) { } @@ -245,6 +246,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 @@ -295,13 +298,6 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECod // Get the number of resolution levels in that image mLevels = mCodeStreamp->get_min_dwt_levels(); - //kdu_coords idx; idx.x = 0; idx.y = 0; - //kdu_dims tile_indices_in; - //mCodeStreamp->get_valid_tiles(tile_indices_in); - //mCodeStreamp->create_tile(idx+tile_indices_in.pos); - //int layers = mCodeStreamp->get_max_tile_layers(); - //llinfos << "Merov debug : setupCodeStream, levels = " << mLevels << ", layers = " << layers << llendl; - // Set the base dimensions base.setSize(dims.size.x, dims.size.y, components); base.setLevels(mLevels); @@ -364,7 +360,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; } @@ -476,7 +473,11 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco kdu_tile tile = mCodeStreamp->open_tile(*(mTPosp)+mTileIndicesp->pos); int layers = mCodeStreamp->get_max_tile_layers(); - llinfos << "Merov debug : decodeImpl, levels = " << mLevels << ", layers = " << layers << llendl; + if (layers > mLayers) + { + mLayers = layers; + base.setLayers(mLayers); + } // Find the region of the buffer occupied by this // tile. Note that we have no control over @@ -607,7 +608,7 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co } // Set codestream options - int num_layer_specs = 0; + mLayers = 0; kdu_long layer_bytes[MAX_NB_LAYERS]; U32 max_bytes = (U32)(base.getWidth() * base.getHeight() * base.getComponents()); @@ -634,15 +635,15 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co // 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) && (num_layer_specs < (MAX_NB_LAYERS-1))) + while ((i < max_bytes) && (mLayers < (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[num_layer_specs] = i; - num_layer_specs++; + layer_bytes[mLayers] = i; + mLayers++; i *= 4; } @@ -655,17 +656,18 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co //codestream.access_siz()->parse_string("Cycc=no"); // 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[num_layer_specs] = 0; + layer_bytes[mLayers] = 0; } else { // Truncate the last quality layer if necessary so to fit the set compression ratio - layer_bytes[num_layer_specs] = max_bytes; + layer_bytes[mLayers] = max_bytes; } - num_layer_specs++; + mLayers++; - std::string layer_string = llformat("Clayers=%d",num_layer_specs); + std::string layer_string = llformat("Clayers=%d",mLayers); codestream.access_siz()->parse_string(layer_string.c_str()); + base.setLayers(mLayers); // 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 @@ -718,7 +720,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,mLayers); // Cleanup delete tile; diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h index 9ab0b9e4a7..fab97326d4 100644 --- a/indra/llkdu/llimagej2ckdu.h +++ b/indra/llkdu/llimagej2ckdu.h @@ -75,6 +75,7 @@ private: int mBlocksSize; int mPrecinctsSize; int mLevels; + int mLayers; // Temporary variables for in-progress decodes... LLImageRaw *mRawImagep; diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp index feb6671e40..405f7c9388 100644 --- a/indra/llkdu/tests/llimagej2ckdu_test.cpp +++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp @@ -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() { } |