diff options
| author | Ayane <chanayane83@gmail.com> | 2024-07-18 09:48:47 +0200 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-18 10:48:47 +0300 | 
| commit | 87b5ecf565e78ca49b2c90478eb2c26d537e4831 (patch) | |
| tree | 8ffc48ef115ce9394b9592349c994e88aed68711 | |
| parent | 6535ce51fd1e3f2b0efdc650310ec75a7638f6f9 (diff) | |
Fixes bad upload quality issue with OpenJPEG (#2054)
| -rw-r--r-- | indra/llimagej2coj/llimagej2coj.cpp | 59 | 
1 files changed, 50 insertions, 9 deletions
diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index b2bd3186a0..f4bcb97a5d 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -431,23 +431,20 @@ public:          opj_set_default_encoder_parameters(¶meters);          parameters.cod_format = OPJ_CODEC_J2K;          parameters.cp_disto_alloc = 1; -        parameters.max_cs_size = (1 << 15);          if (reversible)          { +            parameters.max_cs_size = 0; // do not limit size for reversible compression +            parameters.irreversible = 0; // should be the default, but, just in case              parameters.tcp_numlayers = 1; -            parameters.tcp_rates[0] = 1.0f; +            /* documentation seems to be wrong, should be 0.0f for lossless, not 1.0f +               see https://github.com/uclouvain/openjpeg/blob/39e8c50a2f9bdcf36810ee3d41bcbf1cc78968ae/src/lib/openjp2/j2k.c#L7755 +            */ +            parameters.tcp_rates[0] = 0.0f;          }          else          { -            parameters.tcp_numlayers = 5; -            parameters.tcp_rates[0] = 1920.0f; -            parameters.tcp_rates[1] = 960.0f; -            parameters.tcp_rates[2] = 480.0f; -            parameters.tcp_rates[3] = 120.0f; -            parameters.tcp_rates[4] = 30.0f;              parameters.irreversible = 1; -            parameters.tcp_mct = 1;          }          if (comment_text) @@ -501,6 +498,50 @@ public:          parameters.prog_order = OPJ_RLCP;          parameters.cp_disto_alloc = 1; +        // if not lossless compression, computes tcp_numlayers and max_cs_size depending on the image dimensions +        if( parameters.irreversible ) { + +            // computes a number of layers +            U32 surface = rawImageIn.getWidth() * rawImageIn.getHeight(); +            U32 nb_layers = 1; +            U32 s = 64*64; +            while (surface > s) +            { +                nb_layers++; +                s *= 4; +            } +            nb_layers = llclamp(nb_layers, 1, 6); + +            parameters.tcp_numlayers = nb_layers; +            parameters.tcp_rates[nb_layers - 1] = (U32)(1.f / DEFAULT_COMPRESSION_RATE); // 1:8 by default + +            // for each subsequent layer, computes its rate and adds surface * numcomps * 1/rate to the max_cs_size +            U32 max_cs_size = (U32)(surface * image->numcomps * DEFAULT_COMPRESSION_RATE); +            U32 multiplier; +            for (int i = nb_layers - 2; i >= 0; i--) +            { +                if( i == nb_layers - 2 ) +                { +                    multiplier = 15; +                } +                else if( i == nb_layers - 3 ) +                { +                    multiplier = 4; +                } +                else +                { +                    multiplier = 2; +                } +                parameters.tcp_rates[i] = parameters.tcp_rates[i + 1] * multiplier; +                max_cs_size += (U32)(surface * image->numcomps * (1 / parameters.tcp_rates[i])); +            } + +            //ensure that we have at least a minimal size +            max_cs_size = llmax(max_cs_size, (U32)FIRST_PACKET_SIZE); + +            parameters.max_cs_size = max_cs_size; +        } +          if (!opj_setup_encoder(encoder, ¶meters, image))          {              return false;  | 
