Skip to main content
GameDev.net gamedev.net
🔒 Locked

DXTC Image Format

Started by Jallen Nov 28, 2001 at 3:46 PM 1 replies 900+ views
Original Post
Jallen
Jallen
Is anyone intimately familiar with DX texture compression? I need to know exactly how they bytes in the image are arranged as I want to be able to flip an image once I have loaded it into memory. I am manually loading an image from a DDS file (stored in DXT1 format) and I attemp to flip the image like so:
linesize = size/height;

char *line = (char *)malloc(linesize);
char *top = image;
char *bottom = image + (linesize*(height-1));

for (int i = 0; i < (height >> 1)-1; i++)
{
    memcpy(line, top, linesize);
    memcpy(top, bottom, linesize);
    memcpy(bottom, line, linesize);

    top += linesize;
    bottom -= linesize;
}

delete [] line;
 
Where size is the number of bytes in that specifc image (which is separate from its mipmaps). This produces a rather bizarre images, where it looks like four vertical "stripes" of the image (as if the image was divided into 4 equal sized chunks) are ordered wrong. Anyone know where I can get some good technical documents on the S3TC/DXTC format? Google points me to some nonexistant S3.com websites and the DXTC documentation in MSDN is fairly sparse. Thanks, Jason A. --- I write code. DelphiGL (http://delphigl.cfxweb.net)
---I write code.DelphiGL (http://delphigl.cfxweb.net)
xyzzy00
xyzzy00
DXT1 compresses the image, a 4x4 block of pixels at a time. Each block contains two 16-bit colors, followed by a 32-bit bitmap (2 bits for each pixel in 4x4 block).

To invert the image, you''ll need to flip all the blocks (similar to what you do now for scanlines, except that each scanline is a row of blocks). You will also need to edit each block''s bitmap, flipping the pixels internally.

xyzzy
Jallen
Jallen
Aah, that was the problem, I wasn't flipping the pixels within each block. Got it working now

code to swap all pixels within a line in the image (DXTC1):

DXTColBlock *curblock = line;

for (int i = 0; i < numBlocks; i++)
{
swap(&curblock->row[0], &curblock->row[3], sizeof(unsigned char));
swap(&curblock->row[1], &curblock->row[2], sizeof(unsigned char));

curblock++;
}


code to swap all pixels within a line in the image (DXTC3/5):

DXTColBlock *curblock = line;
DXTAlphaBlock *alphablock;

for (int i = 0; i < numBlocks; i++)
{
alphablock = (DXTAlphaBlock*)curblock;

swap(&alphablock->row[0], &alphablock->row[3], sizeof(unsigned short));
swap(&alphablock->row[1], &alphablock->row[2], sizeof(unsigned short));

curblock++;

swap(&curblock->row[0], &curblock->row[3], sizeof(unsigned char));
swap(&curblock->row[1], &curblock->row[2], sizeof(unsigned char));

curblock++;
}


code to flip entire image:


void (*flipblocks)(DXTColBlock*, int);
int xblocks = width / 4;
int yblocks = height / 4;
int blocksize;

switch (format)
{
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
blocksize = 8;
flipblocks = flip_blocks_dxtc1;
break;
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
blocksize = 16;
flipblocks = flip_blocks_dxtc35;
break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
blocksize = 16;
flipblocks = flip_blocks_dxtc35;
break;
default:
return;
}

linesize = xblocks * blocksize;

DXTColBlock *top;
DXTColBlock *bottom;

for (int j = 0; j < (yblocks >> 1); j++)
{
top = (DXTColBlock*)((DWORD)image + j * linesize );
bottom = (DXTColBlock*)((DWORD)image + (((yblocks-j)-1) * linesize));

flipblocks(top, xblocks);
flipblocks(bottom, xblocks);

swap(bottom, top, linesize);
}


swap is a function that simply swaps to chunks in memory, flipblocks is a function pointer that points to the correct function (depending on whether image is DXTC1 or DXTC3/5) for flipping the pixels in each block.

Thanks for your help,

Jason A.

---
I write code.
DelphiGL (http://delphigl.cfxweb.net)

Edited by - Jallen on November 29, 2001 6:19:29 PM
---I write code.DelphiGL (http://delphigl.cfxweb.net)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.