Blender  V2.59
BlockDXT.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: BlockDXT.cpp 36546 2011-05-08 09:05:52Z jesterking $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * Contributors: Amorilia (amorilia@users.sourceforge.net)
00021  *
00022  * ***** END GPL LICENSE BLOCK *****
00023  */
00024 
00030 /*
00031  * This file is based on a similar file from the NVIDIA texture tools
00032  * (http://nvidia-texture-tools.googlecode.com/)
00033  *
00034  * Original license from NVIDIA follows.
00035  */
00036 
00037 // Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
00038 // 
00039 // Permission is hereby granted, free of charge, to any person
00040 // obtaining a copy of this software and associated documentation
00041 // files (the "Software"), to deal in the Software without
00042 // restriction, including without limitation the rights to use,
00043 // copy, modify, merge, publish, distribute, sublicense, and/or sell
00044 // copies of the Software, and to permit persons to whom the
00045 // Software is furnished to do so, subject to the following
00046 // conditions:
00047 // 
00048 // The above copyright notice and this permission notice shall be
00049 // included in all copies or substantial portions of the Software.
00050 // 
00051 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00052 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
00053 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00054 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
00055 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
00056 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00057 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00058 // OTHER DEALINGS IN THE SOFTWARE.
00059 
00060 #include <Common.h>
00061 #include <Stream.h>
00062 #include <ColorBlock.h>
00063 #include <BlockDXT.h>
00064 
00065 /*----------------------------------------------------------------------------
00066         BlockDXT1
00067 ----------------------------------------------------------------------------*/
00068 
00069 uint BlockDXT1::evaluatePalette(Color32 color_array[4]) const
00070 {
00071         // Does bit expansion before interpolation.
00072         color_array[0].b = (col0.b << 3) | (col0.b >> 2);
00073         color_array[0].g = (col0.g << 2) | (col0.g >> 4);
00074         color_array[0].r = (col0.r << 3) | (col0.r >> 2);
00075         color_array[0].a = 0xFF;
00076         
00077         // @@ Same as above, but faster?
00078 //      Color32 c;
00079 //      c.u = ((col0.u << 3) & 0xf8) | ((col0.u << 5) & 0xfc00) | ((col0.u << 8) & 0xf80000);
00080 //      c.u |= (c.u >> 5) & 0x070007;
00081 //      c.u |= (c.u >> 6) & 0x000300;
00082 //      color_array[0].u = c.u;
00083         
00084         color_array[1].r = (col1.r << 3) | (col1.r >> 2);
00085         color_array[1].g = (col1.g << 2) | (col1.g >> 4);
00086         color_array[1].b = (col1.b << 3) | (col1.b >> 2);
00087         color_array[1].a = 0xFF;
00088         
00089         // @@ Same as above, but faster?
00090 //      c.u = ((col1.u << 3) & 0xf8) | ((col1.u << 5) & 0xfc00) | ((col1.u << 8) & 0xf80000);
00091 //      c.u |= (c.u >> 5) & 0x070007;
00092 //      c.u |= (c.u >> 6) & 0x000300;
00093 //      color_array[1].u = c.u;
00094         
00095         if( col0.u > col1.u ) {
00096                 // Four-color block: derive the other two colors.
00097                 color_array[2].r = (2 * color_array[0].r + color_array[1].r) / 3;
00098                 color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3;
00099                 color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3;
00100                 color_array[2].a = 0xFF;
00101                 
00102                 color_array[3].r = (2 * color_array[1].r + color_array[0].r) / 3;
00103                 color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3;
00104                 color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3;
00105                 color_array[3].a = 0xFF;
00106                 
00107                 return 4;
00108         }
00109         else {
00110                 // Three-color block: derive the other color.
00111                 color_array[2].r = (color_array[0].r + color_array[1].r) / 2;
00112                 color_array[2].g = (color_array[0].g + color_array[1].g) / 2;
00113                 color_array[2].b = (color_array[0].b + color_array[1].b) / 2;
00114                 color_array[2].a = 0xFF;
00115                 
00116                 // Set all components to 0 to match DXT specs.
00117                 color_array[3].r = 0x00; // color_array[2].r;
00118                 color_array[3].g = 0x00; // color_array[2].g;
00119                 color_array[3].b = 0x00; // color_array[2].b;
00120                 color_array[3].a = 0x00;
00121                 
00122                 return 3;
00123         }
00124 }
00125 
00126 
00127 uint BlockDXT1::evaluatePaletteNV5x(Color32 color_array[4]) const
00128 {
00129         // Does bit expansion before interpolation.
00130         color_array[0].b = (3 * col0.b * 22) / 8;
00131         color_array[0].g = (col0.g << 2) | (col0.g >> 4);
00132         color_array[0].r = (3 * col0.r * 22) / 8;
00133         color_array[0].a = 0xFF;
00134 
00135         color_array[1].r = (3 * col1.r * 22) / 8;
00136         color_array[1].g = (col1.g << 2) | (col1.g >> 4);
00137         color_array[1].b = (3 * col1.b * 22) / 8;
00138         color_array[1].a = 0xFF;
00139         
00140     int gdiff = color_array[1].g - color_array[0].g;
00141 
00142         if( col0.u > col1.u ) {
00143                 // Four-color block: derive the other two colors.
00144         color_array[2].r = ((2 * col0.r + col1.r) * 22) / 8;
00145         color_array[2].g = (256 * color_array[0].g + gdiff / 4 + 128 + gdiff * 80) / 256;
00146         color_array[2].b = ((2 * col0.b + col1.b) * 22) / 8;
00147                 color_array[2].a = 0xFF;
00148                 
00149         color_array[3].r = ((2 * col1.r + col0.r) * 22) / 8;
00150         color_array[3].g = (256 * color_array[1].g - gdiff / 4 + 128 - gdiff * 80) / 256;
00151         color_array[3].b = ((2 * col1.b + col0.b) * 22) / 8;
00152                 color_array[3].a = 0xFF;
00153 
00154                 return 4;
00155         }
00156         else {
00157                 // Three-color block: derive the other color.
00158         color_array[2].r = ((col0.r + col1.r) * 33) / 8;
00159         color_array[2].g = (256 * color_array[0].g + gdiff / 4 + 128 + gdiff * 128) / 256;
00160         color_array[2].b = ((col0.b + col1.b) * 33) / 8;
00161                 color_array[2].a = 0xFF;
00162                 
00163                 // Set all components to 0 to match DXT specs.
00164                 color_array[3].r = 0x00; // color_array[2].r;
00165                 color_array[3].g = 0x00; // color_array[2].g;
00166                 color_array[3].b = 0x00; // color_array[2].b;
00167                 color_array[3].a = 0x00;
00168                 
00169                 return 3;
00170         }
00171 }
00172 
00173 // Evaluate palette assuming 3 color block.
00174 void BlockDXT1::evaluatePalette3(Color32 color_array[4]) const
00175 {
00176         color_array[0].b = (col0.b << 3) | (col0.b >> 2);
00177         color_array[0].g = (col0.g << 2) | (col0.g >> 4);
00178         color_array[0].r = (col0.r << 3) | (col0.r >> 2);
00179         color_array[0].a = 0xFF;
00180         
00181         color_array[1].r = (col1.r << 3) | (col1.r >> 2);
00182         color_array[1].g = (col1.g << 2) | (col1.g >> 4);
00183         color_array[1].b = (col1.b << 3) | (col1.b >> 2);
00184         color_array[1].a = 0xFF;
00185         
00186         // Three-color block: derive the other color.
00187         color_array[2].r = (color_array[0].r + color_array[1].r) / 2;
00188         color_array[2].g = (color_array[0].g + color_array[1].g) / 2;
00189         color_array[2].b = (color_array[0].b + color_array[1].b) / 2;
00190         color_array[2].a = 0xFF;
00191                 
00192         // Set all components to 0 to match DXT specs.
00193         color_array[3].r = 0x00; // color_array[2].r;
00194         color_array[3].g = 0x00; // color_array[2].g;
00195         color_array[3].b = 0x00; // color_array[2].b;
00196         color_array[3].a = 0x00;
00197 }
00198 
00199 // Evaluate palette assuming 4 color block.
00200 void BlockDXT1::evaluatePalette4(Color32 color_array[4]) const
00201 {
00202         color_array[0].b = (col0.b << 3) | (col0.b >> 2);
00203         color_array[0].g = (col0.g << 2) | (col0.g >> 4);
00204         color_array[0].r = (col0.r << 3) | (col0.r >> 2);
00205         color_array[0].a = 0xFF;
00206         
00207         color_array[1].r = (col1.r << 3) | (col1.r >> 2);
00208         color_array[1].g = (col1.g << 2) | (col1.g >> 4);
00209         color_array[1].b = (col1.b << 3) | (col1.b >> 2);
00210         color_array[1].a = 0xFF;
00211         
00212         // Four-color block: derive the other two colors.
00213         color_array[2].r = (2 * color_array[0].r + color_array[1].r) / 3;
00214         color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3;
00215         color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3;
00216         color_array[2].a = 0xFF;
00217                 
00218         color_array[3].r = (2 * color_array[1].r + color_array[0].r) / 3;
00219         color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3;
00220         color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3;
00221         color_array[3].a = 0xFF;
00222 }
00223 
00224 
00225 void BlockDXT1::decodeBlock(ColorBlock * block) const
00226 {
00227         // Decode color block.
00228         Color32 color_array[4];
00229         evaluatePalette(color_array);
00230         
00231         // Write color block.
00232         for( uint j = 0; j < 4; j++ ) {
00233                 for( uint i = 0; i < 4; i++ ) {
00234                         uint idx = (row[j] >> (2 * i)) & 3;
00235                         block->color(i, j) = color_array[idx];
00236                 }
00237         }       
00238 }
00239 
00240 void BlockDXT1::decodeBlockNV5x(ColorBlock * block) const
00241 {
00242         // Decode color block.
00243         Color32 color_array[4];
00244         evaluatePaletteNV5x(color_array);
00245 
00246         // Write color block.
00247         for( uint j = 0; j < 4; j++ ) {
00248                 for( uint i = 0; i < 4; i++ ) {
00249                         uint idx = (row[j] >> (2 * i)) & 3;
00250                         block->color(i, j) = color_array[idx];
00251                 }
00252         }
00253 }
00254 
00255 void BlockDXT1::setIndices(int * idx)
00256 {
00257         indices = 0;
00258         for(uint i = 0; i < 16; i++) {
00259                 indices |= (idx[i] & 3) << (2 * i);
00260         }
00261 }
00262 
00263 
00265 inline void BlockDXT1::flip4()
00266 {
00267         swap(row[0], row[3]);
00268         swap(row[1], row[2]);
00269 }
00270 
00272 inline void BlockDXT1::flip2()
00273 {
00274         swap(row[0], row[1]);
00275 }
00276 
00277 
00278 /*----------------------------------------------------------------------------
00279         BlockDXT3
00280 ----------------------------------------------------------------------------*/
00281 
00282 void BlockDXT3::decodeBlock(ColorBlock * block) const
00283 {
00284         // Decode color.
00285         color.decodeBlock(block);
00286         
00287         // Decode alpha.
00288         alpha.decodeBlock(block);
00289 }
00290 
00291 void BlockDXT3::decodeBlockNV5x(ColorBlock * block) const
00292 {
00293         color.decodeBlockNV5x(block);
00294         alpha.decodeBlock(block);
00295 }
00296 
00297 void AlphaBlockDXT3::decodeBlock(ColorBlock * block) const
00298 {
00299         block->color(0x0).a = (alpha0 << 4) | alpha0;
00300         block->color(0x1).a = (alpha1 << 4) | alpha1;
00301         block->color(0x2).a = (alpha2 << 4) | alpha2;
00302         block->color(0x3).a = (alpha3 << 4) | alpha3;
00303         block->color(0x4).a = (alpha4 << 4) | alpha4;
00304         block->color(0x5).a = (alpha5 << 4) | alpha5;
00305         block->color(0x6).a = (alpha6 << 4) | alpha6;
00306         block->color(0x7).a = (alpha7 << 4) | alpha7;
00307         block->color(0x8).a = (alpha8 << 4) | alpha8;
00308         block->color(0x9).a = (alpha9 << 4) | alpha9;
00309         block->color(0xA).a = (alphaA << 4) | alphaA;
00310         block->color(0xB).a = (alphaB << 4) | alphaB;
00311         block->color(0xC).a = (alphaC << 4) | alphaC;
00312         block->color(0xD).a = (alphaD << 4) | alphaD;
00313         block->color(0xE).a = (alphaE << 4) | alphaE;
00314         block->color(0xF).a = (alphaF << 4) | alphaF;
00315 }
00316 
00318 void AlphaBlockDXT3::flip4()
00319 {
00320         swap(row[0], row[3]);
00321         swap(row[1], row[2]);
00322 }
00323 
00325 void AlphaBlockDXT3::flip2()
00326 {
00327         swap(row[0], row[1]);
00328 }
00329 
00331 void BlockDXT3::flip4()
00332 {
00333         alpha.flip4();
00334         color.flip4();
00335 }
00336 
00338 void BlockDXT3::flip2()
00339 {
00340         alpha.flip2();
00341         color.flip2();
00342 }
00343 
00344 
00345 /*----------------------------------------------------------------------------
00346         BlockDXT5
00347 ----------------------------------------------------------------------------*/
00348 
00349 void AlphaBlockDXT5::evaluatePalette(uint8 alpha[8]) const
00350 {
00351         if (alpha0() > alpha1()) {
00352                 evaluatePalette8(alpha);
00353         }
00354         else {
00355                 evaluatePalette6(alpha);
00356         }
00357 }
00358 
00359 void AlphaBlockDXT5::evaluatePalette8(uint8 alpha[8]) const
00360 {
00361         // 8-alpha block:  derive the other six alphas.
00362         // Bit code 000 = alpha0, 001 = alpha1, others are interpolated.
00363         alpha[0] = alpha0();
00364         alpha[1] = alpha1();
00365         alpha[2] = (6 * alpha[0] + 1 * alpha[1]) / 7;   // bit code 010
00366         alpha[3] = (5 * alpha[0] + 2 * alpha[1]) / 7;   // bit code 011
00367         alpha[4] = (4 * alpha[0] + 3 * alpha[1]) / 7;   // bit code 100
00368         alpha[5] = (3 * alpha[0] + 4 * alpha[1]) / 7;   // bit code 101
00369         alpha[6] = (2 * alpha[0] + 5 * alpha[1]) / 7;   // bit code 110
00370         alpha[7] = (1 * alpha[0] + 6 * alpha[1]) / 7;   // bit code 111
00371 }
00372 
00373 void AlphaBlockDXT5::evaluatePalette6(uint8 alpha[8]) const
00374 {
00375         // 6-alpha block.
00376         // Bit code 000 = alpha0, 001 = alpha1, others are interpolated.
00377         alpha[0] = alpha0();
00378         alpha[1] = alpha1();
00379         alpha[2] = (4 * alpha[0] + 1 * alpha[1]) / 5;   // Bit code 010
00380         alpha[3] = (3 * alpha[0] + 2 * alpha[1]) / 5;   // Bit code 011
00381         alpha[4] = (2 * alpha[0] + 3 * alpha[1]) / 5;   // Bit code 100
00382         alpha[5] = (1 * alpha[0] + 4 * alpha[1]) / 5;   // Bit code 101
00383         alpha[6] = 0x00;                                                        // Bit code 110
00384         alpha[7] = 0xFF;                                                        // Bit code 111
00385 }
00386 
00387 void AlphaBlockDXT5::indices(uint8 index_array[16]) const
00388 {
00389         index_array[0x0] = bits0();
00390         index_array[0x1] = bits1();
00391         index_array[0x2] = bits2();
00392         index_array[0x3] = bits3();
00393         index_array[0x4] = bits4();
00394         index_array[0x5] = bits5();
00395         index_array[0x6] = bits6();
00396         index_array[0x7] = bits7();
00397         index_array[0x8] = bits8();
00398         index_array[0x9] = bits9();
00399         index_array[0xA] = bitsA();
00400         index_array[0xB] = bitsB();
00401         index_array[0xC] = bitsC();
00402         index_array[0xD] = bitsD();
00403         index_array[0xE] = bitsE();
00404         index_array[0xF] = bitsF();
00405 }
00406 
00407 uint AlphaBlockDXT5::index(uint index) const
00408 {
00409         int offset = (3 * index + 16);
00410         return uint((this->u >> offset) & 0x7);
00411 }
00412 
00413 void AlphaBlockDXT5::setIndex(uint index, uint value)
00414 {
00415         int offset = (3 * index + 16);
00416         uint64 mask = uint64(0x7) << offset;
00417         this->u = (this->u & ~mask) | (uint64(value) << offset);
00418 }
00419 
00420 void AlphaBlockDXT5::decodeBlock(ColorBlock * block) const
00421 {
00422         uint8 alpha_array[8];
00423         evaluatePalette(alpha_array);
00424         
00425         uint8 index_array[16];
00426         indices(index_array);
00427         
00428         for(uint i = 0; i < 16; i++) {
00429                 block->color(i).a = alpha_array[index_array[i]];
00430         }
00431 }
00432 
00433 void AlphaBlockDXT5::flip4()
00434 {
00435         uint64 * b = (uint64 *)this;
00436         
00437         // @@ The masks might have to be byte swapped.
00438         uint64 tmp = (*b & (uint64)(0x000000000000FFFFLL));
00439         tmp |= (*b & (uint64)(0x000000000FFF0000LL)) << 36;
00440         tmp |= (*b & (uint64)(0x000000FFF0000000LL)) << 12;
00441         tmp |= (*b & (uint64)(0x000FFF0000000000LL)) >> 12;
00442         tmp |= (*b & (uint64)(0xFFF0000000000000LL)) >> 36;
00443         
00444         *b = tmp;
00445 }
00446 
00447 void AlphaBlockDXT5::flip2()
00448 {
00449         uint * b = (uint *)this;
00450         
00451         // @@ The masks might have to be byte swapped.
00452         uint tmp = (*b & 0xFF000000);
00453         tmp |=  (*b & 0x00000FFF) << 12;
00454         tmp |= (*b & 0x00FFF000) >> 12;
00455         
00456         *b = tmp;
00457 }
00458 
00459 void BlockDXT5::decodeBlock(ColorBlock * block) const
00460 {
00461         // Decode color.
00462         color.decodeBlock(block);
00463         
00464         // Decode alpha.
00465         alpha.decodeBlock(block);
00466 }
00467 
00468 void BlockDXT5::decodeBlockNV5x(ColorBlock * block) const
00469 {
00470         // Decode color.
00471         color.decodeBlockNV5x(block);
00472         
00473         // Decode alpha.
00474         alpha.decodeBlock(block);
00475 }
00476 
00478 void BlockDXT5::flip4()
00479 {
00480         alpha.flip4();
00481         color.flip4();
00482 }
00483 
00485 void BlockDXT5::flip2()
00486 {
00487         alpha.flip2();
00488         color.flip2();
00489 }
00490 
00491 
00493 void BlockATI1::decodeBlock(ColorBlock * block) const
00494 {
00495         uint8 alpha_array[8];
00496         alpha.evaluatePalette(alpha_array);
00497         
00498         uint8 index_array[16];
00499         alpha.indices(index_array);
00500         
00501         for(uint i = 0; i < 16; i++) {
00502                 Color32 & c = block->color(i);
00503                 c.b = c.g = c.r = alpha_array[index_array[i]];
00504                 c.a = 255;
00505         }
00506 }
00507 
00509 void BlockATI1::flip4()
00510 {
00511         alpha.flip4();
00512 }
00513 
00515 void BlockATI1::flip2()
00516 {
00517         alpha.flip2();
00518 }
00519 
00520 
00522 void BlockATI2::decodeBlock(ColorBlock * block) const
00523 {
00524         uint8 alpha_array[8];
00525         uint8 index_array[16];
00526         
00527         x.evaluatePalette(alpha_array);
00528         x.indices(index_array);
00529         
00530         for(uint i = 0; i < 16; i++) {
00531                 Color32 & c = block->color(i);
00532                 c.r = alpha_array[index_array[i]];
00533         }
00534 
00535         y.evaluatePalette(alpha_array);
00536         y.indices(index_array);
00537         
00538         for(uint i = 0; i < 16; i++) {
00539                 Color32 & c = block->color(i);
00540                 c.g = alpha_array[index_array[i]];
00541                 c.b = 0;
00542                 c.a = 255;
00543         }
00544 }
00545 
00547 void BlockATI2::flip4()
00548 {
00549         x.flip4();
00550         y.flip4();
00551 }
00552 
00554 void BlockATI2::flip2()
00555 {
00556         x.flip2();
00557         y.flip2();
00558 }
00559 
00560 
00561 void BlockCTX1::evaluatePalette(Color32 color_array[4]) const
00562 {
00563         // Does bit expansion before interpolation.
00564         color_array[0].b = 0x00;
00565         color_array[0].g = col0[1];
00566         color_array[0].r = col0[0];
00567         color_array[0].a = 0xFF;
00568         
00569         color_array[1].r = 0x00;
00570         color_array[1].g = col0[1];
00571         color_array[1].b = col1[0];
00572         color_array[1].a = 0xFF;
00573         
00574         color_array[2].r = 0x00;
00575         color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3;
00576         color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3;
00577         color_array[2].a = 0xFF;
00578                 
00579         color_array[3].r = 0x00;
00580         color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3;
00581         color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3;
00582         color_array[3].a = 0xFF;
00583 }
00584 
00585 void BlockCTX1::decodeBlock(ColorBlock * block) const
00586 {
00587         // Decode color block.
00588         Color32 color_array[4];
00589         evaluatePalette(color_array);
00590         
00591         // Write color block.
00592         for( uint j = 0; j < 4; j++ ) {
00593                 for( uint i = 0; i < 4; i++ ) {
00594                         uint idx = (row[j] >> (2 * i)) & 3;
00595                         block->color(i, j) = color_array[idx];
00596                 }
00597         }       
00598 }
00599 
00600 void BlockCTX1::setIndices(int * idx)
00601 {
00602         indices = 0;
00603         for(uint i = 0; i < 16; i++) {
00604                 indices |= (idx[i] & 3) << (2 * i);
00605         }
00606 }
00607 
00608 
00610 inline void BlockCTX1::flip4()
00611 {
00612         swap(row[0], row[3]);
00613         swap(row[1], row[2]);
00614 }
00615 
00617 inline void BlockCTX1::flip2()
00618 {
00619         swap(row[0], row[1]);
00620 }
00621 
00622 void mem_read(Stream & mem, BlockDXT1 & block)
00623 {
00624         mem_read(mem, block.col0.u);
00625         mem_read(mem, block.col1.u);
00626         mem_read(mem, block.indices);
00627 }
00628 
00629 void mem_read(Stream & mem, AlphaBlockDXT3 & block)
00630 {
00631         for (unsigned int i = 0; i < 4; i++) mem_read(mem, block.row[i]);
00632 }
00633 
00634 void mem_read(Stream & mem, BlockDXT3 & block)
00635 {
00636         mem_read(mem, block.alpha);
00637         mem_read(mem, block.color);
00638 }
00639 
00640 void mem_read(Stream & mem, AlphaBlockDXT5 & block)
00641 {
00642         mem_read(mem, block.u);
00643 }
00644 
00645 void mem_read(Stream & mem, BlockDXT5 & block)
00646 {
00647         mem_read(mem, block.alpha);
00648         mem_read(mem, block.color);
00649 }
00650 
00651 void mem_read(Stream & mem, BlockATI1 & block)
00652 {
00653         mem_read(mem, block.alpha);
00654 }
00655 
00656 void mem_read(Stream & mem, BlockATI2 & block)
00657 {
00658         mem_read(mem, block.x);
00659         mem_read(mem, block.y);
00660 }
00661 
00662 void mem_read(Stream & mem, BlockCTX1 & block)
00663 {
00664         mem_read(mem, block.col0[0]);
00665         mem_read(mem, block.col0[1]);
00666         mem_read(mem, block.col1[0]);
00667         mem_read(mem, block.col1[1]);
00668         mem_read(mem, block.indices);
00669 }
00670