mirror of https://github.com/ecmwf/eccodes.git
ECC-386: Slow-down of read routine. Fixed decoding
This commit is contained in:
parent
09a4f88014
commit
3dd428aa4f
|
@ -94,42 +94,67 @@ int grib_decode_double_array(const unsigned char* p, long *bitp, long bitsPerVal
|
|||
val[i] = (double)x;
|
||||
}
|
||||
#endif
|
||||
unsigned long mask = BIT_MASK(bitsPerValue);
|
||||
if (bitsPerValue%8 == 0)
|
||||
{
|
||||
/* See ECC-386 */
|
||||
int bc;
|
||||
int l = bitsPerValue/8;
|
||||
size_t o = 0;
|
||||
|
||||
/* pi: position of bitp in p[]. >>3 == /8 */
|
||||
long pi = *bitp / 8;
|
||||
/* some bits might of the current byte at pi might be used */
|
||||
/* by the previous number usefulBitsInByte gives remaining unused bits */
|
||||
/* number of useful bits in current byte */
|
||||
int usefulBitsInByte = 8-(*bitp & 7);
|
||||
for(i=0;i < n_vals;i++) {
|
||||
/* value read as long */
|
||||
long bitsToRead = 0;
|
||||
lvalue = 0;
|
||||
bitsToRead = bitsPerValue;
|
||||
/* read one byte after the other to lvalue until >= bitsPerValue are read */
|
||||
while (bitsToRead > 0) {
|
||||
for(i=0;i < n_vals;i++)
|
||||
{
|
||||
lvalue = 0;
|
||||
lvalue <<= 8;
|
||||
lvalue += p[pi];
|
||||
pi++;
|
||||
bitsToRead -= usefulBitsInByte;
|
||||
usefulBitsInByte = 8;
|
||||
}
|
||||
*bitp += bitsPerValue;
|
||||
/* bitsToRead is now <= 0, remove the last bits */
|
||||
lvalue >>= -1*bitsToRead;
|
||||
/* set leading bits to 0 - removing bits used for previous number */
|
||||
lvalue &= mask;
|
||||
lvalue |= p[o++] ;
|
||||
|
||||
usefulBitsInByte = -1*bitsToRead; /* prepare for next round */
|
||||
if (usefulBitsInByte > 0) {
|
||||
pi--; /* reread the current byte */
|
||||
} else {
|
||||
usefulBitsInByte = 8; /* start with next full byte */
|
||||
for ( bc=1; bc<l; bc++ )
|
||||
{
|
||||
lvalue <<= 8;
|
||||
lvalue |= p[o++] ;
|
||||
}
|
||||
x=((lvalue*s)+reference_value)*d;
|
||||
val[i] = (double)x;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned long mask = BIT_MASK(bitsPerValue);
|
||||
|
||||
/* pi: position of bitp in p[]. >>3 == /8 */
|
||||
long pi = *bitp / 8;
|
||||
/* some bits might of the current byte at pi might be used */
|
||||
/* by the previous number usefulBitsInByte gives remaining unused bits */
|
||||
/* number of useful bits in current byte */
|
||||
int usefulBitsInByte = 8-(*bitp & 7);
|
||||
for(i=0;i < n_vals;i++) {
|
||||
/* value read as long */
|
||||
long bitsToRead = 0;
|
||||
lvalue = 0;
|
||||
bitsToRead = bitsPerValue;
|
||||
/* read one byte after the other to lvalue until >= bitsPerValue are read */
|
||||
while (bitsToRead > 0) {
|
||||
lvalue <<= 8;
|
||||
lvalue += p[pi];
|
||||
pi++;
|
||||
bitsToRead -= usefulBitsInByte;
|
||||
usefulBitsInByte = 8;
|
||||
}
|
||||
*bitp += bitsPerValue;
|
||||
/* bitsToRead is now <= 0, remove the last bits */
|
||||
lvalue >>= -1*bitsToRead;
|
||||
/* set leading bits to 0 - removing bits used for previous number */
|
||||
lvalue &= mask;
|
||||
|
||||
usefulBitsInByte = -1*bitsToRead; /* prepare for next round */
|
||||
if (usefulBitsInByte > 0) {
|
||||
pi--; /* reread the current byte */
|
||||
} else {
|
||||
usefulBitsInByte = 8; /* start with next full byte */
|
||||
}
|
||||
/* scaling and move value to output */
|
||||
x=((lvalue*s)+reference_value)*d;
|
||||
val[i] = (double)x;
|
||||
}
|
||||
/* scaling and move value to output */
|
||||
x=((lvalue*s)+reference_value)*d;
|
||||
val[i] = (double)x;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue