From 2f83b0aed2ad123b86faad5b4cb1b55abc0a3a85 Mon Sep 17 00:00:00 2001 From: TommyTheTerrible <81168766+TommyTheTerrible@users.noreply.github.com> Date: Tue, 16 Jul 2024 21:02:57 -0400 Subject: Fix: Update calcDataSizeJ2C to pyramid-base file size estimation (#2032) * Fix: Update calcDataSizeJ2C to pyramid-base file size estimation Used the loop from the previous LayerFactored method to create a more accurate file size estimation by walking up the pyramid tiles. Sizes are much larger in many cases and eliminate partial decoder issues with OpenJPEG. KDU not tested but expected to produce better files as well. Should also stop decode failures on tiny or very rectangular dimensions. --------- Co-authored-by: Andrey Lihatskiy --- indra/llimage/llimagej2c.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'indra/llimage/llimagej2c.cpp') diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 0058b91b0f..5dfd8cd947 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -278,13 +278,20 @@ S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 r S32 nb_layers = 1; S32 surface = w*h; S32 s = 64*64; + S32 precision = 8; // assumed bitrate per component channel, might change in future for HDR support + S32 totalbytes = (S32)(s * comp * precision * rate); // first level computed before loop while (surface > s) { + if (nb_layers <= (5 - discard_level)) + totalbytes += (S32)(s * comp * precision * rate); nb_layers++; s *= 4; } F32 layer_factor = 3.0f * (7 - llclamp(nb_layers,1,6)); + totalbytes /= 8; // to bytes + totalbytes += calcHeaderSizeJ2C(); // header + // Compute w/pow(2,discard_level) and h/pow(2,discard_level) w >>= discard_level; h >>= discard_level; @@ -297,7 +304,9 @@ S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 r 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()); + bytes = llmax(totalbytes, calcHeaderSizeJ2C()); + //LL_WARNS() << "calcDataSizeJ2C w-h-c-d-p " << w << "-" << h << "-" << comp << "-" << discard_level << "-" << precision + // << " Pyramid: " << (S32)totalbytes << " LayerFactored: " << new_bytes << " WJCR: " << old_bytes << LL_ENDL; return bytes; } -- cgit v1.2.3 From 6535ce51fd1e3f2b0efdc650310ec75a7638f6f9 Mon Sep 17 00:00:00 2001 From: Ansariel Hiller Date: Thu, 18 Jul 2024 09:48:24 +0200 Subject: Remove unnecessary code and (re-)add some more compile time constants (#2057) --- indra/llimage/llimagej2c.cpp | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) (limited to 'indra/llimage/llimagej2c.cpp') diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 5dfd8cd947..29449a5d2e 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -275,10 +275,10 @@ S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 r // 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(). + constexpr S32 precision = 8; // assumed bitrate per component channel, might change in future for HDR support S32 nb_layers = 1; - S32 surface = w*h; + const S32 surface = w*h; S32 s = 64*64; - S32 precision = 8; // assumed bitrate per component channel, might change in future for HDR support S32 totalbytes = (S32)(s * comp * precision * rate); // first level computed before loop while (surface > s) { @@ -287,27 +287,11 @@ S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 r nb_layers++; s *= 4; } - F32 layer_factor = 3.0f * (7 - llclamp(nb_layers,1,6)); totalbytes /= 8; // to bytes totalbytes += calcHeaderSizeJ2C(); // header - // 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(totalbytes, calcHeaderSizeJ2C()); - //LL_WARNS() << "calcDataSizeJ2C w-h-c-d-p " << w << "-" << h << "-" << comp << "-" << discard_level << "-" << precision - // << " Pyramid: " << (S32)totalbytes << " LayerFactored: " << new_bytes << " WJCR: " << old_bytes << LL_ENDL; - return bytes; + return totalbytes; } S32 LLImageJ2C::calcHeaderSize() -- cgit v1.2.3 From bffd4a12b8e6677d8cd8bec2e38909e5200b69dd Mon Sep 17 00:00:00 2001 From: TommyTheTerrible <81168766+TommyTheTerrible@users.noreply.github.com> Date: Sat, 20 Jul 2024 06:37:23 -0400 Subject: calcDataSizeJ2C adjusted to use maximum possible components (#2073) Previous pyramid walking calculation (#2032) assumed the incoming components variable can be accurate but unfortunately the needs_aux is only set to true if the face has an alpha mask setting. Without this information we must assume the J2C files have the maximum component size of four so that alpha channels are found when decoding both the color and aux textures. --- indra/llimage/llimagej2c.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra/llimage/llimagej2c.cpp') diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 29449a5d2e..42f3e92257 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -276,14 +276,15 @@ S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 r // Estimate the number of layers. This is consistent with what's done for j2c encoding in LLImageJ2CKDU::encodeImpl(). constexpr S32 precision = 8; // assumed bitrate per component channel, might change in future for HDR support + constexpr S32 max_components = 4; // assumed the file has four components; three color and alpha S32 nb_layers = 1; const S32 surface = w*h; S32 s = 64*64; - S32 totalbytes = (S32)(s * comp * precision * rate); // first level computed before loop + S32 totalbytes = (S32)(s * max_components * precision * rate); // first level computed before loop while (surface > s) { if (nb_layers <= (5 - discard_level)) - totalbytes += (S32)(s * comp * precision * rate); + totalbytes += (S32)(s * max_components * precision * rate); nb_layers++; s *= 4; } -- cgit v1.2.3 From 9f7dd0177201fe080c287144b99a70125be1fb2b Mon Sep 17 00:00:00 2001 From: Ansariel Hiller Date: Tue, 20 Aug 2024 17:41:48 +0200 Subject: Clean up boost includes and remove compiler warning pragma for unreachable code in PCH (#2361) --- indra/llimage/llimagej2c.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'indra/llimage/llimagej2c.cpp') diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 42f3e92257..4ec95bbcc3 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -31,7 +31,6 @@ #include "llmath.h" #include "llmemory.h" #include "llsd.h" -#include // Declare the prototype for this factory function here. It is implemented in // other files which define a LLImageJ2CImpl subclass, but only ONE static -- cgit v1.2.3