Fixes bad upload quality issue with OpenJPEG (#2054)

meow-7.2.2
Ayane 2024-07-18 09:48:47 +02:00 committed by GitHub
parent 6535ce51fd
commit 87b5ecf565
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 50 additions and 9 deletions

View File

@ -431,23 +431,20 @@ public:
opj_set_default_encoder_parameters(&parameters);
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, &parameters, image))
{
return false;