Need to read big-endian file (Windows)
-
I have a bunch of DXT5 DDS files, but information on the format is so sparse I have no idea how to write something to convert them. I have the following code as part of a library and this converts it to a format I can use, but I can't understand what I need to change to make it read the files as big endian. If anyone could at least explain how the the *src variable is being used so I could determine where I need to convert stuff that would help, I currently don't get how values are being derived from it.
//-----------------------------------------------------------------------------------------------------
// DecompressDXT5(vlByte *src, vlByte *dst, vlUInt uiWidth, vlUInt uiHeight)
//
// Converts data from the DXT5 to RGBA8888 format. Data is read from *src
// and written to *dst. Width and height are needed to it knows how much data to process
//-----------------------------------------------------------------------------------------------------
vlBool CVTFFile::DecompressDXT5(vlByte *src, vlByte *dst, vlUInt uiWidth, vlUInt uiHeight)
{
vlUInt x, y, i, j, k, Select;
vlByte *Temp;
Colour565 *color_0, *color_1;
Colour8888 colours[4], *col;
vlUInt bitmask, Offset;
vlByte alphas[8], *alphamask;
vlUInt bits;vlByte nBpp = 4; // bytes per pixel (4 channels (RGBA)) vlByte nBpc = 1; // bytes per channel (1 byte per channel) vlUInt iBps = nBpp \* nBpc \* uiWidth; // bytes per scanline Temp = src; for (y = 0; y < uiHeight; y += 4) { for (x = 0; x < uiWidth; x += 4) { //if (y >= uiHeight || x >= uiWidth) // break; alphas\[0\] = Temp\[0\]; alphas\[1\] = Temp\[1\]; alphamask = Temp + 2; Temp += 8; color\_0 = ((Colour565\*)Temp); color\_1 = ((Colour565\*)(Temp+2)); bitmask = ((vlUInt\*)Temp)\[1\]; Temp += 8; colours\[0\].r = color\_0->nRed << 3; colours\[0\].g = color\_0->nGreen << 2; colours\[0\].b = color\_0->nBlue << 3; colours\[0\].a = 0xFF; colours\[1\].r = color\_1->nRed << 3; colours\[1\].g = color\_1->nGreen << 2; colours\[1\].b = color\_1->nBlue << 3; colours\[1\].a = 0xFF; // Four-color block: derive the other two colors. // 00 = color\_0, 01 = color\_1, 10 = color\_2, 11 = color\_3 // These 2-bit codes correspond to the 2-bit fields // stored in the 64-bit block. colours\[2\].b = (2 \* colours\[0\].b + colours\[1\].b + 1) / 3; colours\[2\].g = (2 \* colours\[0\].g + colours\[1\].g + 1) / 3; colours\[2\].r = (2 \* colours\[0\].r + c
-
I have a bunch of DXT5 DDS files, but information on the format is so sparse I have no idea how to write something to convert them. I have the following code as part of a library and this converts it to a format I can use, but I can't understand what I need to change to make it read the files as big endian. If anyone could at least explain how the the *src variable is being used so I could determine where I need to convert stuff that would help, I currently don't get how values are being derived from it.
//-----------------------------------------------------------------------------------------------------
// DecompressDXT5(vlByte *src, vlByte *dst, vlUInt uiWidth, vlUInt uiHeight)
//
// Converts data from the DXT5 to RGBA8888 format. Data is read from *src
// and written to *dst. Width and height are needed to it knows how much data to process
//-----------------------------------------------------------------------------------------------------
vlBool CVTFFile::DecompressDXT5(vlByte *src, vlByte *dst, vlUInt uiWidth, vlUInt uiHeight)
{
vlUInt x, y, i, j, k, Select;
vlByte *Temp;
Colour565 *color_0, *color_1;
Colour8888 colours[4], *col;
vlUInt bitmask, Offset;
vlByte alphas[8], *alphamask;
vlUInt bits;vlByte nBpp = 4; // bytes per pixel (4 channels (RGBA)) vlByte nBpc = 1; // bytes per channel (1 byte per channel) vlUInt iBps = nBpp \* nBpc \* uiWidth; // bytes per scanline Temp = src; for (y = 0; y < uiHeight; y += 4) { for (x = 0; x < uiWidth; x += 4) { //if (y >= uiHeight || x >= uiWidth) // break; alphas\[0\] = Temp\[0\]; alphas\[1\] = Temp\[1\]; alphamask = Temp + 2; Temp += 8; color\_0 = ((Colour565\*)Temp); color\_1 = ((Colour565\*)(Temp+2)); bitmask = ((vlUInt\*)Temp)\[1\]; Temp += 8; colours\[0\].r = color\_0->nRed << 3; colours\[0\].g = color\_0->nGreen << 2; colours\[0\].b = color\_0->nBlue << 3; colours\[0\].a = 0xFF; colours\[1\].r = color\_1->nRed << 3; colours\[1\].g = color\_1->nGreen << 2; colours\[1\].b = color\_1->nBlue << 3; colours\[1\].a = 0xFF; // Four-color block: derive the other two colors. // 00 = color\_0, 01 = color\_1, 10 = color\_2, 11 = color\_3 // These 2-bit codes correspond to the 2-bit fields // stored in the 64-bit block. colours\[2\].b = (2 \* colours\[0\].b + colours\[1\].b + 1) / 3; colours\[2\].g = (2 \* colours\[0\].g + colours\[1\].g + 1) / 3; colours\[2\].r = (2 \* colours\[0\].r + c
do you have a type definition for v1Byte ? (assuming its just 'byte' could be dangerous) I am formulating a longer response, I just want to be careful in how I frame it 'g'
-
I have a bunch of DXT5 DDS files, but information on the format is so sparse I have no idea how to write something to convert them. I have the following code as part of a library and this converts it to a format I can use, but I can't understand what I need to change to make it read the files as big endian. If anyone could at least explain how the the *src variable is being used so I could determine where I need to convert stuff that would help, I currently don't get how values are being derived from it.
//-----------------------------------------------------------------------------------------------------
// DecompressDXT5(vlByte *src, vlByte *dst, vlUInt uiWidth, vlUInt uiHeight)
//
// Converts data from the DXT5 to RGBA8888 format. Data is read from *src
// and written to *dst. Width and height are needed to it knows how much data to process
//-----------------------------------------------------------------------------------------------------
vlBool CVTFFile::DecompressDXT5(vlByte *src, vlByte *dst, vlUInt uiWidth, vlUInt uiHeight)
{
vlUInt x, y, i, j, k, Select;
vlByte *Temp;
Colour565 *color_0, *color_1;
Colour8888 colours[4], *col;
vlUInt bitmask, Offset;
vlByte alphas[8], *alphamask;
vlUInt bits;vlByte nBpp = 4; // bytes per pixel (4 channels (RGBA)) vlByte nBpc = 1; // bytes per channel (1 byte per channel) vlUInt iBps = nBpp \* nBpc \* uiWidth; // bytes per scanline Temp = src; for (y = 0; y < uiHeight; y += 4) { for (x = 0; x < uiWidth; x += 4) { //if (y >= uiHeight || x >= uiWidth) // break; alphas\[0\] = Temp\[0\]; alphas\[1\] = Temp\[1\]; alphamask = Temp + 2; Temp += 8; color\_0 = ((Colour565\*)Temp); color\_1 = ((Colour565\*)(Temp+2)); bitmask = ((vlUInt\*)Temp)\[1\]; Temp += 8; colours\[0\].r = color\_0->nRed << 3; colours\[0\].g = color\_0->nGreen << 2; colours\[0\].b = color\_0->nBlue << 3; colours\[0\].a = 0xFF; colours\[1\].r = color\_1->nRed << 3; colours\[1\].g = color\_1->nGreen << 2; colours\[1\].b = color\_1->nBlue << 3; colours\[1\].a = 0xFF; // Four-color block: derive the other two colors. // 00 = color\_0, 01 = color\_1, 10 = color\_2, 11 = color\_3 // These 2-bit codes correspond to the 2-bit fields // stored in the 64-bit block. colours\[2\].b = (2 \* colours\[0\].b + colours\[1\].b + 1) / 3; colours\[2\].g = (2 \* colours\[0\].g + colours\[1\].g + 1) / 3; colours\[2\].r = (2 \* colours\[0\].r + c
Just convert your
src
sequence (with the length in bytes =uiWidth * uiHeight
) into the Intel-format (by granularity ofDWORD
) at the beginning of the function... :)virtual void BeHappy() = 0;
-
I have a bunch of DXT5 DDS files, but information on the format is so sparse I have no idea how to write something to convert them. I have the following code as part of a library and this converts it to a format I can use, but I can't understand what I need to change to make it read the files as big endian. If anyone could at least explain how the the *src variable is being used so I could determine where I need to convert stuff that would help, I currently don't get how values are being derived from it.
//-----------------------------------------------------------------------------------------------------
// DecompressDXT5(vlByte *src, vlByte *dst, vlUInt uiWidth, vlUInt uiHeight)
//
// Converts data from the DXT5 to RGBA8888 format. Data is read from *src
// and written to *dst. Width and height are needed to it knows how much data to process
//-----------------------------------------------------------------------------------------------------
vlBool CVTFFile::DecompressDXT5(vlByte *src, vlByte *dst, vlUInt uiWidth, vlUInt uiHeight)
{
vlUInt x, y, i, j, k, Select;
vlByte *Temp;
Colour565 *color_0, *color_1;
Colour8888 colours[4], *col;
vlUInt bitmask, Offset;
vlByte alphas[8], *alphamask;
vlUInt bits;vlByte nBpp = 4; // bytes per pixel (4 channels (RGBA)) vlByte nBpc = 1; // bytes per channel (1 byte per channel) vlUInt iBps = nBpp \* nBpc \* uiWidth; // bytes per scanline Temp = src; for (y = 0; y < uiHeight; y += 4) { for (x = 0; x < uiWidth; x += 4) { //if (y >= uiHeight || x >= uiWidth) // break; alphas\[0\] = Temp\[0\]; alphas\[1\] = Temp\[1\]; alphamask = Temp + 2; Temp += 8; color\_0 = ((Colour565\*)Temp); color\_1 = ((Colour565\*)(Temp+2)); bitmask = ((vlUInt\*)Temp)\[1\]; Temp += 8; colours\[0\].r = color\_0->nRed << 3; colours\[0\].g = color\_0->nGreen << 2; colours\[0\].b = color\_0->nBlue << 3; colours\[0\].a = 0xFF; colours\[1\].r = color\_1->nRed << 3; colours\[1\].g = color\_1->nGreen << 2; colours\[1\].b = color\_1->nBlue << 3; colours\[1\].a = 0xFF; // Four-color block: derive the other two colors. // 00 = color\_0, 01 = color\_1, 10 = color\_2, 11 = color\_3 // These 2-bit codes correspond to the 2-bit fields // stored in the 64-bit block. colours\[2\].b = (2 \* colours\[0\].b + colours\[1\].b + 1) / 3; colours\[2\].g = (2 \* colours\[0\].g + colours\[1\].g + 1) / 3; colours\[2\].r = (2 \* colours\[0\].r + c
Hi, the difference between little-endian and big-endian is: multi-byte values are stored with their least significant byte first for little-endian, and with their most significant byte first for big-endian. This implies variables of type short, int, long, float, double get their bytes swapped, however byte-oriented values (such as char, and string) remain unchanged. Now, assuming vlByte is a byte, that may make no difference whatsoever to the code shown. Maybe the only difference is where you obtain uiWidth and uiHeight, however that must happen outside the function shown. :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
modified on Wednesday, April 7, 2010 7:03 AM
-
do you have a type definition for v1Byte ? (assuming its just 'byte' could be dangerous) I am formulating a longer response, I just want to be careful in how I frame it 'g'