Skip to content

Commit 17f515c

Browse files
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.
1 parent 45b2d69 commit 17f515c

File tree

1 file changed

+13
-9
lines changed

1 file changed

+13
-9
lines changed

indra/llimage/llimagej2c.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -276,16 +276,20 @@ S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 r
276276
// Estimate the number of layers. This is consistent with what's done for j2c encoding in LLImageJ2CKDU::encodeImpl().
277277
constexpr S32 precision = 8; // assumed bitrate per component channel, might change in future for HDR support
278278
constexpr S32 max_components = 4; // assumed the file has four components; three color and alpha
279-
S32 nb_layers = 1;
280-
const S32 surface = w*h;
281-
S32 s = 64*64;
282-
S32 totalbytes = (S32)(s * max_components * precision * rate); // first level computed before loop
283-
while (surface > s)
279+
// Use MAX_IMAGE_SIZE_DEFAULT (currently 2048) if either dimension is unknown (zero)
280+
S32 width = (w > 0) ? w : 2048;
281+
S32 height = (h > 0) ? h : 2048;
282+
S32 max_dimension = llmax(width, height); // Find largest dimension
283+
S32 block_area = MAX_BLOCK_SIZE * MAX_BLOCK_SIZE; // Calculated initial block area from established max block size (currently 64)
284+
block_area *= (max_dimension / MAX_BLOCK_SIZE / max_components); // Adjust initial block area by ratio of largest dimension to block size per component
285+
S32 totalbytes = (S32) (block_area * max_components * precision); // First block layer computed before loop without compression rate
286+
S32 block_layers = 1; // Start at layer 1 since first block layer is computed outside loop
287+
while (block_layers < 6) // Walk five layers for the five discards in JPEG2000
284288
{
285-
if (nb_layers <= (5 - discard_level))
286-
totalbytes += (S32)(s * max_components * precision * rate);
287-
nb_layers++;
288-
s *= 4;
289+
if (block_layers <= (5 - discard_level)) // Walk backwards from discard 5 to required discard layer.
290+
totalbytes += (S32) (block_area * max_components * precision * rate); // Add each block layer reduced by assumed compression rate
291+
block_layers++; // Move to next layer
292+
block_area *= 4; // Increase block area by power of four
289293
}
290294

291295
totalbytes /= 8; // to bytes

0 commit comments

Comments
 (0)