Skip to content
Snippets Groups Projects
Commit 78298186 authored by Merov Linden's avatar Merov Linden
Browse files

SH-3060 : New byte range implementation. Intermediate (not working) state.

parent c6511d9c
No related branches found
No related tags found
No related merge requests found
...@@ -1337,7 +1337,8 @@ LLImageFormatted::LLImageFormatted(S8 codec) ...@@ -1337,7 +1337,8 @@ LLImageFormatted::LLImageFormatted(S8 codec)
mDecoding(0), mDecoding(0),
mDecoded(0), mDecoded(0),
mDiscardLevel(-1), mDiscardLevel(-1),
mLevels(0) mLevels(0),
mLayers(0)
{ {
mMemType = LLMemType::MTYPE_IMAGEFORMATTED; mMemType = LLMemType::MTYPE_IMAGEFORMATTED;
} }
......
...@@ -320,6 +320,8 @@ class LLImageFormatted : public LLImageBase ...@@ -320,6 +320,8 @@ class LLImageFormatted : public LLImageBase
S8 getDiscardLevel() const { return mDiscardLevel; } S8 getDiscardLevel() const { return mDiscardLevel; }
S8 getLevels() const { return mLevels; } S8 getLevels() const { return mLevels; }
void setLevels(S8 nlevels) { mLevels = nlevels; } 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 // setLastError needs to be deferred for J2C images since it may be called from a DLL
virtual void resetLastError(); virtual void resetLastError();
...@@ -334,6 +336,7 @@ class LLImageFormatted : public LLImageBase ...@@ -334,6 +336,7 @@ class LLImageFormatted : public LLImageBase
S8 mDecoded; // unused, but changing LLImage layout requires recompiling static Mac/Linux libs. 2009-01-30 JC 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 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. 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: public:
static S32 sGlobalFormattedMemory; static S32 sGlobalFormattedMemory;
......
...@@ -58,7 +58,8 @@ LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C), ...@@ -58,7 +58,8 @@ LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C),
mRawDiscardLevel(-1), mRawDiscardLevel(-1),
mRate(0.0f), mRate(0.0f),
mReversible(FALSE), mReversible(FALSE),
mAreaUsedForDataSizeCalcs(0) mAreaUsedForDataSizeCalcs(0),
mLayersUsedForDataSizeCalcs(0)
{ {
mImpl = fallbackCreateLLImageJ2CImpl(); mImpl = fallbackCreateLLImageJ2CImpl();
...@@ -260,7 +261,7 @@ S32 LLImageJ2C::calcHeaderSizeJ2C() ...@@ -260,7 +261,7 @@ S32 LLImageJ2C::calcHeaderSizeJ2C()
} }
//static //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 // 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 // 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 ...@@ -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 // 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: 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 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); 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 = (LLImage::useNewByteRange() ? new_bytes : old_bytes);
bytes = llmax(bytes, calcHeaderSizeJ2C()); bytes = llmax(bytes, calcHeaderSizeJ2C());
return bytes; return bytes;
...@@ -298,14 +300,20 @@ S32 LLImageJ2C::calcDataSize(S32 discard_level) ...@@ -298,14 +300,20 @@ S32 LLImageJ2C::calcDataSize(S32 discard_level)
discard_level = llclamp(discard_level, 0, MAX_DISCARD_LEVEL); discard_level = llclamp(discard_level, 0, MAX_DISCARD_LEVEL);
if ( mAreaUsedForDataSizeCalcs != (getHeight() * getWidth()) 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(); mAreaUsedForDataSizeCalcs = getHeight() * getWidth();
mLayersUsedForDataSizeCalcs = getLayers();
S32 level = MAX_DISCARD_LEVEL; // Start at the highest discard S32 level = MAX_DISCARD_LEVEL; // Start at the highest discard
while ( level >= 0 ) while ( level >= 0 )
{ {
mDataSizes[level] = calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, mRate); mDataSizes[level] = calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, getLayers(), mRate);
level--; level--;
} }
} }
......
...@@ -72,7 +72,7 @@ class LLImageJ2C : public LLImageFormatted ...@@ -72,7 +72,7 @@ class LLImageJ2C : public LLImageFormatted
S32 getMaxBytes() const { return mMaxBytes; } S32 getMaxBytes() const { return mMaxBytes; }
static S32 calcHeaderSizeJ2C(); 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(); static std::string getEngineInfo();
...@@ -88,6 +88,7 @@ class LLImageJ2C : public LLImageFormatted ...@@ -88,6 +88,7 @@ class LLImageJ2C : public LLImageFormatted
S32 mDataSizes[MAX_DISCARD_LEVEL+1]; // Size of data required to reach a given level S32 mDataSizes[MAX_DISCARD_LEVEL+1]; // Size of data required to reach a given level
U32 mAreaUsedForDataSizeCalcs; // Height * width used to calculate mDataSizes U32 mAreaUsedForDataSizeCalcs; // Height * width used to calculate mDataSizes
S32 mLayersUsedForDataSizeCalcs; // Numbers of layers used to calculate mDataSizes
S8 mRawDiscardLevel; S8 mRawDiscardLevel;
F32 mRate; F32 mRate;
......
...@@ -195,7 +195,8 @@ mRawImagep(NULL), ...@@ -195,7 +195,8 @@ mRawImagep(NULL),
mDecodeState(NULL), mDecodeState(NULL),
mBlocksSize(-1), mBlocksSize(-1),
mPrecinctsSize(-1), mPrecinctsSize(-1),
mLevels(0) mLevels(0),
mLayers(0)
{ {
} }
...@@ -245,6 +246,8 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECod ...@@ -245,6 +246,8 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECod
mCodeStreamp->create(mInputp); mCodeStreamp->create(mInputp);
// Set the maximum number of bytes to use from the codestream // 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); mCodeStreamp->set_max_bytes(max_bytes,true);
// If you want to flip or rotate the image for some reason, change // 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 ...@@ -295,13 +298,6 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECod
// Get the number of resolution levels in that image // Get the number of resolution levels in that image
mLevels = mCodeStreamp->get_min_dwt_levels(); 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 // Set the base dimensions
base.setSize(dims.size.x, dims.size.y, components); base.setSize(dims.size.x, dims.size.y, components);
base.setLevels(mLevels); base.setLevels(mLevels);
...@@ -364,7 +360,8 @@ BOOL LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int bloc ...@@ -364,7 +360,8 @@ BOOL LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int bloc
mLevels = levels; mLevels = levels;
if (mLevels != 0) 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; return TRUE;
} }
...@@ -476,7 +473,11 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco ...@@ -476,7 +473,11 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
kdu_tile tile = mCodeStreamp->open_tile(*(mTPosp)+mTileIndicesp->pos); kdu_tile tile = mCodeStreamp->open_tile(*(mTPosp)+mTileIndicesp->pos);
int layers = mCodeStreamp->get_max_tile_layers(); 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 // Find the region of the buffer occupied by this
// tile. Note that we have no control over // tile. Note that we have no control over
...@@ -607,7 +608,7 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co ...@@ -607,7 +608,7 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
} }
// Set codestream options // Set codestream options
int num_layer_specs = 0; mLayers = 0;
kdu_long layer_bytes[MAX_NB_LAYERS]; kdu_long layer_bytes[MAX_NB_LAYERS];
U32 max_bytes = (U32)(base.getWidth() * base.getHeight() * base.getComponents()); U32 max_bytes = (U32)(base.getWidth() * base.getHeight() * base.getComponents());
...@@ -634,15 +635,15 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co ...@@ -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. // 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 // Note: For more info on this layers business, read kdu_codestream::flush() doc in kdu_compressed.h
U32 i = FIRST_PACKET_SIZE; 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) 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 // That really just means that the first layer is FIRST_PACKET_SIZE and the second is MIN_LAYER_SIZE
i = MIN_LAYER_SIZE; i = MIN_LAYER_SIZE;
} }
layer_bytes[num_layer_specs] = i; layer_bytes[mLayers] = i;
num_layer_specs++; mLayers++;
i *= 4; i *= 4;
} }
...@@ -655,17 +656,18 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co ...@@ -655,17 +656,18 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
//codestream.access_siz()->parse_string("Cycc=no"); //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 // 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. // indeed be output by the time the last quality layer is encountered.
layer_bytes[num_layer_specs] = 0; layer_bytes[mLayers] = 0;
} }
else else
{ {
// Truncate the last quality layer if necessary so to fit the set compression ratio // 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()); codestream.access_siz()->parse_string(layer_string.c_str());
base.setLayers(mLayers);
// Set up data ordering, markers, etc... if precincts or blocks specified // 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 // 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 ...@@ -718,7 +720,7 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
} }
// Produce the compressed output // Produce the compressed output
codestream.flush(layer_bytes,num_layer_specs); codestream.flush(layer_bytes,mLayers);
// Cleanup // Cleanup
delete tile; delete tile;
......
...@@ -75,6 +75,7 @@ class LLImageJ2CKDU : public LLImageJ2CImpl ...@@ -75,6 +75,7 @@ class LLImageJ2CKDU : public LLImageJ2CImpl
int mBlocksSize; int mBlocksSize;
int mPrecinctsSize; int mPrecinctsSize;
int mLevels; int mLevels;
int mLayers;
// Temporary variables for in-progress decodes... // Temporary variables for in-progress decodes...
LLImageRaw *mRawImagep; LLImageRaw *mRawImagep;
......
...@@ -146,6 +146,7 @@ void kdu_codestream::set_fast() { } ...@@ -146,6 +146,7 @@ void kdu_codestream::set_fast() { }
void kdu_codestream::set_fussy() { } void kdu_codestream::set_fussy() { }
void kdu_codestream::get_dims(int, kdu_dims&, bool ) { } void kdu_codestream::get_dims(int, kdu_dims&, bool ) { }
int kdu_codestream::get_min_dwt_levels() { return 5; } 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::change_appearance(bool, bool, bool) { }
void kdu_codestream::get_tile_dims(kdu_coords, int, kdu_dims&, bool ) { } void kdu_codestream::get_tile_dims(kdu_coords, int, kdu_dims&, bool ) { }
void kdu_codestream::destroy() { } void kdu_codestream::destroy() { }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment