Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/imbuf/intern/dds/FlipDXT.cpp')
-rw-r--r--source/blender/imbuf/intern/dds/FlipDXT.cpp346
1 files changed, 172 insertions, 174 deletions
diff --git a/source/blender/imbuf/intern/dds/FlipDXT.cpp b/source/blender/imbuf/intern/dds/FlipDXT.cpp
index 50488b923db..0660d5ce5cc 100644
--- a/source/blender/imbuf/intern/dds/FlipDXT.cpp
+++ b/source/blender/imbuf/intern/dds/FlipDXT.cpp
@@ -50,207 +50,205 @@ typedef void (*FlipBlockFunction)(uint8_t *block);
// Flips a full DXT1 block in the y direction.
static void FlipDXT1BlockFull(uint8_t *block)
{
- // A DXT1 block layout is:
- // [0-1] color0.
- // [2-3] color1.
- // [4-7] color bitmap, 2 bits per pixel.
- // So each of the 4-7 bytes represents one line, flipping a block is just
- // flipping those bytes.
- uint8_t tmp = block[4];
- block[4] = block[7];
- block[7] = tmp;
- tmp = block[5];
- block[5] = block[6];
- block[6] = tmp;
+ // A DXT1 block layout is:
+ // [0-1] color0.
+ // [2-3] color1.
+ // [4-7] color bitmap, 2 bits per pixel.
+ // So each of the 4-7 bytes represents one line, flipping a block is just
+ // flipping those bytes.
+ uint8_t tmp = block[4];
+ block[4] = block[7];
+ block[7] = tmp;
+ tmp = block[5];
+ block[5] = block[6];
+ block[6] = tmp;
}
// Flips the first 2 lines of a DXT1 block in the y direction.
static void FlipDXT1BlockHalf(uint8_t *block)
{
- // See layout above.
- uint8_t tmp = block[4];
- block[4] = block[5];
- block[5] = tmp;
+ // See layout above.
+ uint8_t tmp = block[4];
+ block[4] = block[5];
+ block[5] = tmp;
}
// Flips a full DXT3 block in the y direction.
static void FlipDXT3BlockFull(uint8_t *block)
{
- // A DXT3 block layout is:
- // [0-7] alpha bitmap, 4 bits per pixel.
- // [8-15] a DXT1 block.
-
- // We can flip the alpha bits at the byte level (2 bytes per line).
- uint8_t tmp = block[0];
-
- block[0] = block[6];
- block[6] = tmp;
- tmp = block[1];
- block[1] = block[7];
- block[7] = tmp;
- tmp = block[2];
- block[2] = block[4];
- block[4] = tmp;
- tmp = block[3];
- block[3] = block[5];
- block[5] = tmp;
-
- // And flip the DXT1 block using the above function.
- FlipDXT1BlockFull(block + 8);
+ // A DXT3 block layout is:
+ // [0-7] alpha bitmap, 4 bits per pixel.
+ // [8-15] a DXT1 block.
+
+ // We can flip the alpha bits at the byte level (2 bytes per line).
+ uint8_t tmp = block[0];
+
+ block[0] = block[6];
+ block[6] = tmp;
+ tmp = block[1];
+ block[1] = block[7];
+ block[7] = tmp;
+ tmp = block[2];
+ block[2] = block[4];
+ block[4] = tmp;
+ tmp = block[3];
+ block[3] = block[5];
+ block[5] = tmp;
+
+ // And flip the DXT1 block using the above function.
+ FlipDXT1BlockFull(block + 8);
}
// Flips the first 2 lines of a DXT3 block in the y direction.
static void FlipDXT3BlockHalf(uint8_t *block)
{
- // See layout above.
- uint8_t tmp = block[0];
-
- block[0] = block[2];
- block[2] = tmp;
- tmp = block[1];
- block[1] = block[3];
- block[3] = tmp;
- FlipDXT1BlockHalf(block + 8);
+ // See layout above.
+ uint8_t tmp = block[0];
+
+ block[0] = block[2];
+ block[2] = tmp;
+ tmp = block[1];
+ block[1] = block[3];
+ block[3] = tmp;
+ FlipDXT1BlockHalf(block + 8);
}
// Flips a full DXT5 block in the y direction.
static void FlipDXT5BlockFull(uint8_t *block)
{
- // A DXT5 block layout is:
- // [0] alpha0.
- // [1] alpha1.
- // [2-7] alpha bitmap, 3 bits per pixel.
- // [8-15] a DXT1 block.
-
- // The alpha bitmap doesn't easily map lines to bytes, so we have to
- // interpret it correctly. Extracted from
- // http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt :
- //
- // The 6 "bits" bytes of the block are decoded into one 48-bit integer:
- //
- // bits = bits_0 + 256 * (bits_1 + 256 * (bits_2 + 256 * (bits_3 +
- // 256 * (bits_4 + 256 * bits_5))))
- //
- // bits is a 48-bit unsigned integer, from which a three-bit control code
- // is extracted for a texel at location (x,y) in the block using:
- //
- // code(x,y) = bits[3*(4*y+x)+1..3*(4*y+x)+0]
- //
- // where bit 47 is the most significant and bit 0 is the least
- // significant bit.
- unsigned int line_0_1 = block[2] + 256 * (block[3] + 256 * block[4]);
- unsigned int line_2_3 = block[5] + 256 * (block[6] + 256 * block[7]);
- // swap lines 0 and 1 in line_0_1.
- unsigned int line_1_0 = ((line_0_1 & 0x000fff) << 12) |
- ((line_0_1 & 0xfff000) >> 12);
- // swap lines 2 and 3 in line_2_3.
- unsigned int line_3_2 = ((line_2_3 & 0x000fff) << 12) |
- ((line_2_3 & 0xfff000) >> 12);
-
- block[2] = line_3_2 & 0xff;
- block[3] = (line_3_2 & 0xff00) >> 8;
- block[4] = (line_3_2 & 0xff0000) >> 16;
- block[5] = line_1_0 & 0xff;
- block[6] = (line_1_0 & 0xff00) >> 8;
- block[7] = (line_1_0 & 0xff0000) >> 16;
-
- // And flip the DXT1 block using the above function.
- FlipDXT1BlockFull(block + 8);
+ // A DXT5 block layout is:
+ // [0] alpha0.
+ // [1] alpha1.
+ // [2-7] alpha bitmap, 3 bits per pixel.
+ // [8-15] a DXT1 block.
+
+ // The alpha bitmap doesn't easily map lines to bytes, so we have to
+ // interpret it correctly. Extracted from
+ // http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt :
+ //
+ // The 6 "bits" bytes of the block are decoded into one 48-bit integer:
+ //
+ // bits = bits_0 + 256 * (bits_1 + 256 * (bits_2 + 256 * (bits_3 +
+ // 256 * (bits_4 + 256 * bits_5))))
+ //
+ // bits is a 48-bit unsigned integer, from which a three-bit control code
+ // is extracted for a texel at location (x,y) in the block using:
+ //
+ // code(x,y) = bits[3*(4*y+x)+1..3*(4*y+x)+0]
+ //
+ // where bit 47 is the most significant and bit 0 is the least
+ // significant bit.
+ unsigned int line_0_1 = block[2] + 256 * (block[3] + 256 * block[4]);
+ unsigned int line_2_3 = block[5] + 256 * (block[6] + 256 * block[7]);
+ // swap lines 0 and 1 in line_0_1.
+ unsigned int line_1_0 = ((line_0_1 & 0x000fff) << 12) | ((line_0_1 & 0xfff000) >> 12);
+ // swap lines 2 and 3 in line_2_3.
+ unsigned int line_3_2 = ((line_2_3 & 0x000fff) << 12) | ((line_2_3 & 0xfff000) >> 12);
+
+ block[2] = line_3_2 & 0xff;
+ block[3] = (line_3_2 & 0xff00) >> 8;
+ block[4] = (line_3_2 & 0xff0000) >> 16;
+ block[5] = line_1_0 & 0xff;
+ block[6] = (line_1_0 & 0xff00) >> 8;
+ block[7] = (line_1_0 & 0xff0000) >> 16;
+
+ // And flip the DXT1 block using the above function.
+ FlipDXT1BlockFull(block + 8);
}
// Flips the first 2 lines of a DXT5 block in the y direction.
static void FlipDXT5BlockHalf(uint8_t *block)
{
- // See layout above.
- unsigned int line_0_1 = block[2] + 256 * (block[3] + 256 * block[4]);
- unsigned int line_1_0 = ((line_0_1 & 0x000fff) << 12) |
- ((line_0_1 & 0xfff000) >> 12);
- block[2] = line_1_0 & 0xff;
- block[3] = (line_1_0 & 0xff00) >> 8;
- block[4] = (line_1_0 & 0xff0000) >> 16;
- FlipDXT1BlockHalf(block + 8);
+ // See layout above.
+ unsigned int line_0_1 = block[2] + 256 * (block[3] + 256 * block[4]);
+ unsigned int line_1_0 = ((line_0_1 & 0x000fff) << 12) | ((line_0_1 & 0xfff000) >> 12);
+ block[2] = line_1_0 & 0xff;
+ block[3] = (line_1_0 & 0xff00) >> 8;
+ block[4] = (line_1_0 & 0xff0000) >> 16;
+ FlipDXT1BlockHalf(block + 8);
}
// Flips a DXTC image, by flipping and swapping DXTC blocks as appropriate.
-int FlipDXTCImage(unsigned int width, unsigned int height, unsigned int levels, int fourcc, uint8_t *data)
+int FlipDXTCImage(
+ unsigned int width, unsigned int height, unsigned int levels, int fourcc, uint8_t *data)
{
- // must have valid dimensions
- if (width == 0 || height == 0)
- return 0;
- // height must be a power-of-two
- if ((height & (height - 1)) != 0)
- return 0;
-
- FlipBlockFunction full_block_function;
- FlipBlockFunction half_block_function;
- unsigned int block_bytes = 0;
-
- switch (fourcc) {
- case FOURCC_DXT1:
- full_block_function = FlipDXT1BlockFull;
- half_block_function = FlipDXT1BlockHalf;
- block_bytes = 8;
- break;
- case FOURCC_DXT3:
- full_block_function = FlipDXT3BlockFull;
- half_block_function = FlipDXT3BlockHalf;
- block_bytes = 16;
- break;
- case FOURCC_DXT5:
- full_block_function = FlipDXT5BlockFull;
- half_block_function = FlipDXT5BlockHalf;
- block_bytes = 16;
- break;
- default:
- return 0;
- }
-
- unsigned int mip_width = width;
- unsigned int mip_height = height;
-
- for (unsigned int i = 0; i < levels; ++i) {
- unsigned int blocks_per_row = (mip_width + 3) / 4;
- unsigned int blocks_per_col = (mip_height + 3) / 4;
- unsigned int blocks = blocks_per_row * blocks_per_col;
-
- if (mip_height == 1) {
- // no flip to do, and we're done.
- break;
- }
- else if (mip_height == 2) {
- // flip the first 2 lines in each block.
- for (unsigned int i = 0; i < blocks_per_row; ++i) {
- half_block_function(data + i * block_bytes);
- }
- }
- else {
- // flip each block.
- for (unsigned int i = 0; i < blocks; ++i)
- full_block_function(data + i * block_bytes);
-
- // swap each block line in the first half of the image with the
- // corresponding one in the second half.
- // note that this is a no-op if mip_height is 4.
- unsigned int row_bytes = block_bytes * blocks_per_row;
- uint8_t *temp_line = new uint8_t[row_bytes];
-
- for (unsigned int y = 0; y < blocks_per_col / 2; ++y) {
- uint8_t *line1 = data + y * row_bytes;
- uint8_t *line2 = data + (blocks_per_col - y - 1) * row_bytes;
-
- memcpy(temp_line, line1, row_bytes);
- memcpy(line1, line2, row_bytes);
- memcpy(line2, temp_line, row_bytes);
- }
-
- delete[] temp_line;
- }
-
- // mip levels are contiguous.
- data += block_bytes * blocks;
- mip_width = MAX(1U, mip_width >> 1);
- mip_height = MAX(1U, mip_height >> 1);
- }
-
- return 1;
+ // must have valid dimensions
+ if (width == 0 || height == 0)
+ return 0;
+ // height must be a power-of-two
+ if ((height & (height - 1)) != 0)
+ return 0;
+
+ FlipBlockFunction full_block_function;
+ FlipBlockFunction half_block_function;
+ unsigned int block_bytes = 0;
+
+ switch (fourcc) {
+ case FOURCC_DXT1:
+ full_block_function = FlipDXT1BlockFull;
+ half_block_function = FlipDXT1BlockHalf;
+ block_bytes = 8;
+ break;
+ case FOURCC_DXT3:
+ full_block_function = FlipDXT3BlockFull;
+ half_block_function = FlipDXT3BlockHalf;
+ block_bytes = 16;
+ break;
+ case FOURCC_DXT5:
+ full_block_function = FlipDXT5BlockFull;
+ half_block_function = FlipDXT5BlockHalf;
+ block_bytes = 16;
+ break;
+ default:
+ return 0;
+ }
+
+ unsigned int mip_width = width;
+ unsigned int mip_height = height;
+
+ for (unsigned int i = 0; i < levels; ++i) {
+ unsigned int blocks_per_row = (mip_width + 3) / 4;
+ unsigned int blocks_per_col = (mip_height + 3) / 4;
+ unsigned int blocks = blocks_per_row * blocks_per_col;
+
+ if (mip_height == 1) {
+ // no flip to do, and we're done.
+ break;
+ }
+ else if (mip_height == 2) {
+ // flip the first 2 lines in each block.
+ for (unsigned int i = 0; i < blocks_per_row; ++i) {
+ half_block_function(data + i * block_bytes);
+ }
+ }
+ else {
+ // flip each block.
+ for (unsigned int i = 0; i < blocks; ++i)
+ full_block_function(data + i * block_bytes);
+
+ // swap each block line in the first half of the image with the
+ // corresponding one in the second half.
+ // note that this is a no-op if mip_height is 4.
+ unsigned int row_bytes = block_bytes * blocks_per_row;
+ uint8_t *temp_line = new uint8_t[row_bytes];
+
+ for (unsigned int y = 0; y < blocks_per_col / 2; ++y) {
+ uint8_t *line1 = data + y * row_bytes;
+ uint8_t *line2 = data + (blocks_per_col - y - 1) * row_bytes;
+
+ memcpy(temp_line, line1, row_bytes);
+ memcpy(line1, line2, row_bytes);
+ memcpy(line2, temp_line, row_bytes);
+ }
+
+ delete[] temp_line;
+ }
+
+ // mip levels are contiguous.
+ data += block_bytes * blocks;
+ mip_width = MAX(1U, mip_width >> 1);
+ mip_height = MAX(1U, mip_height >> 1);
+ }
+
+ return 1;
}