From 17f515cd3e4239d3c6e1958d998e455a8300da90 Mon Sep 17 00:00:00 2001 From: TommyTheTerrible <81168766+TommyTheTerrible@users.noreply.github.com> Date: Sat, 24 Aug 2024 00:21:03 -0400 Subject: Update LLImageJ2C::calcDataSizeJ2C for better 2k image support (#2406) Adjusted calculations based on dimensions and assumed maximum block size so that higher discards (4-5) of 2048x2048 images can be decoded with aux/alpha. (It should also work for dimensions larger than 2048.) This function will now return a reliable discard 5 data size for unknown dimensions (w and/or h equals 0), which could be used in LLTextureFetch::createRequest to skip the header fetch and go right to a discard 5 decode. Tested on OpenJPEG 2.5 with partial decode support (opj_decoder_set_strict_mode set to false). Should work on KDU fine but might be a good idea to test. --- indra/llimage/llimagej2c.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'indra/llimage') diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 4ec95bbcc3..753e5d24df 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -276,16 +276,20 @@ 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 * max_components * precision * rate); // first level computed before loop - while (surface > s) + // Use MAX_IMAGE_SIZE_DEFAULT (currently 2048) if either dimension is unknown (zero) + S32 width = (w > 0) ? w : 2048; + S32 height = (h > 0) ? h : 2048; + S32 max_dimension = llmax(width, height); // Find largest dimension + S32 block_area = MAX_BLOCK_SIZE * MAX_BLOCK_SIZE; // Calculated initial block area from established max block size (currently 64) + block_area *= (max_dimension / MAX_BLOCK_SIZE / max_components); // Adjust initial block area by ratio of largest dimension to block size per component + S32 totalbytes = (S32) (block_area * max_components * precision); // First block layer computed before loop without compression rate + S32 block_layers = 1; // Start at layer 1 since first block layer is computed outside loop + while (block_layers < 6) // Walk five layers for the five discards in JPEG2000 { - if (nb_layers <= (5 - discard_level)) - totalbytes += (S32)(s * max_components * precision * rate); - nb_layers++; - s *= 4; + if (block_layers <= (5 - discard_level)) // Walk backwards from discard 5 to required discard layer. + totalbytes += (S32) (block_area * max_components * precision * rate); // Add each block layer reduced by assumed compression rate + block_layers++; // Move to next layer + block_area *= 4; // Increase block area by power of four } totalbytes /= 8; // to bytes -- cgit v1.2.3 From 2f692fbac36117e1b3c5f2ec214fd188c7e73da7 Mon Sep 17 00:00:00 2001 From: TommyTheTerrible <81168766+TommyTheTerrible@users.noreply.github.com> Date: Mon, 9 Sep 2024 05:31:00 -0400 Subject: Update calcDataSizeJ2C to stop undersized blocks (#2525) The initial block area for the pyramid walk should not be smaller than the max_block_size area so need an llmax to not allow multiplication below 1. This was causing decode errors for complex small images (128x128 or smaller) on discard 1 and 2. --- indra/llimage/llimagej2c.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llimage') diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 753e5d24df..aa161709a1 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -281,7 +281,7 @@ S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 r S32 height = (h > 0) ? h : 2048; S32 max_dimension = llmax(width, height); // Find largest dimension S32 block_area = MAX_BLOCK_SIZE * MAX_BLOCK_SIZE; // Calculated initial block area from established max block size (currently 64) - block_area *= (max_dimension / MAX_BLOCK_SIZE / max_components); // Adjust initial block area by ratio of largest dimension to block size per component + block_area *= llmax((max_dimension / MAX_BLOCK_SIZE / max_components), 1); // Adjust initial block area by ratio of largest dimension to block size per component S32 totalbytes = (S32) (block_area * max_components * precision); // First block layer computed before loop without compression rate S32 block_layers = 1; // Start at layer 1 since first block layer is computed outside loop while (block_layers < 6) // Walk five layers for the five discards in JPEG2000 -- cgit v1.2.3 From 25969b330e4dc69f6eb39a487b171ccc07a5df14 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 19 Sep 2024 20:11:17 +0300 Subject: viewer#2608 Crash at LLSnapshotLivePreview::getFormattedImage --- indra/llimage/llimage.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llimage') diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 8b966b8ea3..6b14b68c78 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -179,7 +179,7 @@ private: public: template - class DataLock : LLSharedMutexLockTemplate + class DataLock : public LLSharedMutexLockTemplate { public: DataLock(const LLImageBase* image) -- cgit v1.2.3