i'm dealing with a weird problem. the following routine uncompresses some data. it runs fine on x86-systems:
CODE
char loop;
char indic;
unsigned char *readback;
int size;
unsigned short int temp;
int i;
do
{
loop = 8;
indic = *(source++); ///Read in one byte
do
{
if (!(indic & 1)) /// if bit is not set
{
temp = *((short*)source);
source += 2;
size = temp & 0x0F; ///size defines length of sequence
size += 2;///sequence length 0 & 1 don't make sense
decompressedSize -= size;
readback = (destination - (temp >> 4)) - 1; ///write back from output to output
for (i = 0; i < size; i++)
{
*(destination++) = *(readback++);
}
if (decompressedSize <= 0)
return;
loop--;
}
else
{
*(destination++) = *(source++);
loop--;
decompressedSize--;
if (decompressedSize <= 0)
return;
}
indic >>= 1;
}while (loop);
}while (decompressedSize); ///work through the whole buffer!
but compiled with arm-gcc, there seems to be a problem with the line
CODE
temp = *((short*)source);
the first few bytes of the compressed data are for example
03 00 20 1F 00 1F
the correct behaviour would be (may source start at pos 0):
transfer 1 byte from source to indic , increase source
=> source = 1, indic=3
=> transfer 1 byte from source to destination, increase source , shift indic
=> source = 2, indic=1
=> transfer 1 byte from source to destination, increase source, shift indic
=> source = 3, indic=0
=> indic = 0 => transfer 2 bytes from source to temp, increase source by 2
now temp should contain the value 0x001F (because it's little endian)
but instead, on the gp2x, temp contains the value 0x1F20.
if i use the following statement instead, it works correctly on gp2x:
CODE
temp = (*(source+1)<<8)+(*source);
is this a bug in the casting from char* to short* or was is pure luck, that this statement worked correctly on x86? i'm not familiar with the expected behaviour for casting a pointer, i just never expected that this could lead to a problem
CODE
char loop;
char indic;
unsigned char *readback;
int size;
unsigned short int temp;
int i;
do
{
loop = 8;
indic = *(source++); ///Read in one byte
do
{
if (!(indic & 1)) /// if bit is not set
{
temp = *((short*)source);
source += 2;
size = temp & 0x0F; ///size defines length of sequence
size += 2;///sequence length 0 & 1 don't make sense
decompressedSize -= size;
readback = (destination - (temp >> 4)) - 1; ///write back from output to output
for (i = 0; i < size; i++)
{
*(destination++) = *(readback++);
}
if (decompressedSize <= 0)
return;
loop--;
}
else
{
*(destination++) = *(source++);
loop--;
decompressedSize--;
if (decompressedSize <= 0)
return;
}
indic >>= 1;
}while (loop);
}while (decompressedSize); ///work through the whole buffer!
but compiled with arm-gcc, there seems to be a problem with the line
CODE
temp = *((short*)source);
the first few bytes of the compressed data are for example
03 00 20 1F 00 1F
the correct behaviour would be (may source start at pos 0):
transfer 1 byte from source to indic , increase source
=> source = 1, indic=3
=> transfer 1 byte from source to destination, increase source , shift indic
=> source = 2, indic=1
=> transfer 1 byte from source to destination, increase source, shift indic
=> source = 3, indic=0
=> indic = 0 => transfer 2 bytes from source to temp, increase source by 2
now temp should contain the value 0x001F (because it's little endian)
but instead, on the gp2x, temp contains the value 0x1F20.
if i use the following statement instead, it works correctly on gp2x:
CODE
temp = (*(source+1)<<8)+(*source);
is this a bug in the casting from char* to short* or was is pure luck, that this statement worked correctly on x86? i'm not familiar with the expected behaviour for casting a pointer, i just never expected that this could lead to a problem