Apply second half of [#21590] .dds textures: fix for DXT1n format + sync with upstrea...
[blender.git] / source / blender / imbuf / intern / dds / BlockDXT.cpp
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * Contributors: Amorilia (amorilia@users.sourceforge.net)
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 /** \file blender/imbuf/intern/dds/BlockDXT.cpp
26  *  \ingroup imbdds
27  */
28
29
30 /*
31  * This file is based on a similar file from the NVIDIA texture tools
32  * (http://nvidia-texture-tools.googlecode.com/)
33  *
34  * Original license from NVIDIA follows.
35  */
36
37 // Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
38 // 
39 // Permission is hereby granted, free of charge, to any person
40 // obtaining a copy of this software and associated documentation
41 // files (the "Software"), to deal in the Software without
42 // restriction, including without limitation the rights to use,
43 // copy, modify, merge, publish, distribute, sublicense, and/or sell
44 // copies of the Software, and to permit persons to whom the
45 // Software is furnished to do so, subject to the following
46 // conditions:
47 // 
48 // The above copyright notice and this permission notice shall be
49 // included in all copies or substantial portions of the Software.
50 // 
51 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
52 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
53 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
54 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
55 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
56 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
57 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
58 // OTHER DEALINGS IN THE SOFTWARE.
59
60 #include <Common.h>
61 #include <Stream.h>
62 #include <ColorBlock.h>
63 #include <BlockDXT.h>
64
65 /*----------------------------------------------------------------------------
66         BlockDXT1
67 ----------------------------------------------------------------------------*/
68
69 uint BlockDXT1::evaluatePalette(Color32 color_array[4]) const
70 {
71         // Does bit expansion before interpolation.
72         color_array[0].b = (col0.b << 3) | (col0.b >> 2);
73         color_array[0].g = (col0.g << 2) | (col0.g >> 4);
74         color_array[0].r = (col0.r << 3) | (col0.r >> 2);
75         color_array[0].a = 0xFF;
76         
77         // @@ Same as above, but faster?
78 //      Color32 c;
79 //      c.u = ((col0.u << 3) & 0xf8) | ((col0.u << 5) & 0xfc00) | ((col0.u << 8) & 0xf80000);
80 //      c.u |= (c.u >> 5) & 0x070007;
81 //      c.u |= (c.u >> 6) & 0x000300;
82 //      color_array[0].u = c.u;
83         
84         color_array[1].r = (col1.r << 3) | (col1.r >> 2);
85         color_array[1].g = (col1.g << 2) | (col1.g >> 4);
86         color_array[1].b = (col1.b << 3) | (col1.b >> 2);
87         color_array[1].a = 0xFF;
88         
89         // @@ Same as above, but faster?
90 //      c.u = ((col1.u << 3) & 0xf8) | ((col1.u << 5) & 0xfc00) | ((col1.u << 8) & 0xf80000);
91 //      c.u |= (c.u >> 5) & 0x070007;
92 //      c.u |= (c.u >> 6) & 0x000300;
93 //      color_array[1].u = c.u;
94         
95         if( col0.u > col1.u ) {
96                 // Four-color block: derive the other two colors.
97                 color_array[2].r = (2 * color_array[0].r + color_array[1].r) / 3;
98                 color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3;
99                 color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3;
100                 color_array[2].a = 0xFF;
101                 
102                 color_array[3].r = (2 * color_array[1].r + color_array[0].r) / 3;
103                 color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3;
104                 color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3;
105                 color_array[3].a = 0xFF;
106                 
107                 return 4;
108         }
109         else {
110                 // Three-color block: derive the other color.
111                 color_array[2].r = (color_array[0].r + color_array[1].r) / 2;
112                 color_array[2].g = (color_array[0].g + color_array[1].g) / 2;
113                 color_array[2].b = (color_array[0].b + color_array[1].b) / 2;
114                 color_array[2].a = 0xFF;
115                 
116                 // Set all components to 0 to match DXT specs.
117                 color_array[3].r = 0x00; // color_array[2].r;
118                 color_array[3].g = 0x00; // color_array[2].g;
119                 color_array[3].b = 0x00; // color_array[2].b;
120                 color_array[3].a = 0x00;
121                 
122                 return 3;
123         }
124 }
125
126
127 uint BlockDXT1::evaluatePaletteNV5x(Color32 color_array[4]) const
128 {
129         // Does bit expansion before interpolation.
130         color_array[0].b = (3 * col0.b * 22) / 8;
131         color_array[0].g = (col0.g << 2) | (col0.g >> 4);
132         color_array[0].r = (3 * col0.r * 22) / 8;
133         color_array[0].a = 0xFF;
134
135         color_array[1].r = (3 * col1.r * 22) / 8;
136         color_array[1].g = (col1.g << 2) | (col1.g >> 4);
137         color_array[1].b = (3 * col1.b * 22) / 8;
138         color_array[1].a = 0xFF;
139         
140     int gdiff = color_array[1].g - color_array[0].g;
141
142         if( col0.u > col1.u ) {
143                 // Four-color block: derive the other two colors.
144         color_array[2].r = ((2 * col0.r + col1.r) * 22) / 8;
145         color_array[2].g = (256 * color_array[0].g + gdiff / 4 + 128 + gdiff * 80) / 256;
146         color_array[2].b = ((2 * col0.b + col1.b) * 22) / 8;
147                 color_array[2].a = 0xFF;
148                 
149         color_array[3].r = ((2 * col1.r + col0.r) * 22) / 8;
150         color_array[3].g = (256 * color_array[1].g - gdiff / 4 + 128 - gdiff * 80) / 256;
151         color_array[3].b = ((2 * col1.b + col0.b) * 22) / 8;
152                 color_array[3].a = 0xFF;
153
154                 return 4;
155         }
156         else {
157                 // Three-color block: derive the other color.
158         color_array[2].r = ((col0.r + col1.r) * 33) / 8;
159         color_array[2].g = (256 * color_array[0].g + gdiff / 4 + 128 + gdiff * 128) / 256;
160         color_array[2].b = ((col0.b + col1.b) * 33) / 8;
161                 color_array[2].a = 0xFF;
162                 
163                 // Set all components to 0 to match DXT specs.
164                 color_array[3].r = 0x00; // color_array[2].r;
165                 color_array[3].g = 0x00; // color_array[2].g;
166                 color_array[3].b = 0x00; // color_array[2].b;
167                 color_array[3].a = 0x00;
168                 
169                 return 3;
170         }
171 }
172
173 // Evaluate palette assuming 3 color block.
174 void BlockDXT1::evaluatePalette3(Color32 color_array[4]) const
175 {
176         color_array[0].b = (col0.b << 3) | (col0.b >> 2);
177         color_array[0].g = (col0.g << 2) | (col0.g >> 4);
178         color_array[0].r = (col0.r << 3) | (col0.r >> 2);
179         color_array[0].a = 0xFF;
180         
181         color_array[1].r = (col1.r << 3) | (col1.r >> 2);
182         color_array[1].g = (col1.g << 2) | (col1.g >> 4);
183         color_array[1].b = (col1.b << 3) | (col1.b >> 2);
184         color_array[1].a = 0xFF;
185         
186         // Three-color block: derive the other color.
187         color_array[2].r = (color_array[0].r + color_array[1].r) / 2;
188         color_array[2].g = (color_array[0].g + color_array[1].g) / 2;
189         color_array[2].b = (color_array[0].b + color_array[1].b) / 2;
190         color_array[2].a = 0xFF;
191                 
192         // Set all components to 0 to match DXT specs.
193         color_array[3].r = 0x00; // color_array[2].r;
194         color_array[3].g = 0x00; // color_array[2].g;
195         color_array[3].b = 0x00; // color_array[2].b;
196         color_array[3].a = 0x00;
197 }
198
199 // Evaluate palette assuming 4 color block.
200 void BlockDXT1::evaluatePalette4(Color32 color_array[4]) const
201 {
202         color_array[0].b = (col0.b << 3) | (col0.b >> 2);
203         color_array[0].g = (col0.g << 2) | (col0.g >> 4);
204         color_array[0].r = (col0.r << 3) | (col0.r >> 2);
205         color_array[0].a = 0xFF;
206         
207         color_array[1].r = (col1.r << 3) | (col1.r >> 2);
208         color_array[1].g = (col1.g << 2) | (col1.g >> 4);
209         color_array[1].b = (col1.b << 3) | (col1.b >> 2);
210         color_array[1].a = 0xFF;
211         
212         // Four-color block: derive the other two colors.
213         color_array[2].r = (2 * color_array[0].r + color_array[1].r) / 3;
214         color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3;
215         color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3;
216         color_array[2].a = 0xFF;
217                 
218         color_array[3].r = (2 * color_array[1].r + color_array[0].r) / 3;
219         color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3;
220         color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3;
221         color_array[3].a = 0xFF;
222 }
223
224
225 void BlockDXT1::decodeBlock(ColorBlock * block) const
226 {
227         // Decode color block.
228         Color32 color_array[4];
229         evaluatePalette(color_array);
230         
231         // Write color block.
232         for( uint j = 0; j < 4; j++ ) {
233                 for( uint i = 0; i < 4; i++ ) {
234                         uint idx = (row[j] >> (2 * i)) & 3;
235                         block->color(i, j) = color_array[idx];
236                 }
237         }       
238 }
239
240 void BlockDXT1::decodeBlockNV5x(ColorBlock * block) const
241 {
242         // Decode color block.
243         Color32 color_array[4];
244         evaluatePaletteNV5x(color_array);
245
246         // Write color block.
247         for( uint j = 0; j < 4; j++ ) {
248                 for( uint i = 0; i < 4; i++ ) {
249                         uint idx = (row[j] >> (2 * i)) & 3;
250                         block->color(i, j) = color_array[idx];
251                 }
252         }
253 }
254
255 void BlockDXT1::setIndices(int * idx)
256 {
257         indices = 0;
258         for(uint i = 0; i < 16; i++) {
259                 indices |= (idx[i] & 3) << (2 * i);
260         }
261 }
262
263
264 /// Flip DXT1 block vertically.
265 inline void BlockDXT1::flip4()
266 {
267         swap(row[0], row[3]);
268         swap(row[1], row[2]);
269 }
270
271 /// Flip half DXT1 block vertically.
272 inline void BlockDXT1::flip2()
273 {
274         swap(row[0], row[1]);
275 }
276
277
278 /*----------------------------------------------------------------------------
279         BlockDXT3
280 ----------------------------------------------------------------------------*/
281
282 void BlockDXT3::decodeBlock(ColorBlock * block) const
283 {
284         // Decode color.
285         color.decodeBlock(block);
286         
287         // Decode alpha.
288         alpha.decodeBlock(block);
289 }
290
291 void BlockDXT3::decodeBlockNV5x(ColorBlock * block) const
292 {
293         color.decodeBlockNV5x(block);
294         alpha.decodeBlock(block);
295 }
296
297 void AlphaBlockDXT3::decodeBlock(ColorBlock * block) const
298 {
299         block->color(0x0).a = (alpha0 << 4) | alpha0;
300         block->color(0x1).a = (alpha1 << 4) | alpha1;
301         block->color(0x2).a = (alpha2 << 4) | alpha2;
302         block->color(0x3).a = (alpha3 << 4) | alpha3;
303         block->color(0x4).a = (alpha4 << 4) | alpha4;
304         block->color(0x5).a = (alpha5 << 4) | alpha5;
305         block->color(0x6).a = (alpha6 << 4) | alpha6;
306         block->color(0x7).a = (alpha7 << 4) | alpha7;
307         block->color(0x8).a = (alpha8 << 4) | alpha8;
308         block->color(0x9).a = (alpha9 << 4) | alpha9;
309         block->color(0xA).a = (alphaA << 4) | alphaA;
310         block->color(0xB).a = (alphaB << 4) | alphaB;
311         block->color(0xC).a = (alphaC << 4) | alphaC;
312         block->color(0xD).a = (alphaD << 4) | alphaD;
313         block->color(0xE).a = (alphaE << 4) | alphaE;
314         block->color(0xF).a = (alphaF << 4) | alphaF;
315 }
316
317 /// Flip DXT3 alpha block vertically.
318 void AlphaBlockDXT3::flip4()
319 {
320         swap(row[0], row[3]);
321         swap(row[1], row[2]);
322 }
323
324 /// Flip half DXT3 alpha block vertically.
325 void AlphaBlockDXT3::flip2()
326 {
327         swap(row[0], row[1]);
328 }
329
330 /// Flip DXT3 block vertically.
331 void BlockDXT3::flip4()
332 {
333         alpha.flip4();
334         color.flip4();
335 }
336
337 /// Flip half DXT3 block vertically.
338 void BlockDXT3::flip2()
339 {
340         alpha.flip2();
341         color.flip2();
342 }
343
344
345 /*----------------------------------------------------------------------------
346         BlockDXT5
347 ----------------------------------------------------------------------------*/
348
349 void AlphaBlockDXT5::evaluatePalette(uint8 alpha[8]) const
350 {
351         if (alpha0() > alpha1()) {
352                 evaluatePalette8(alpha);
353         }
354         else {
355                 evaluatePalette6(alpha);
356         }
357 }
358
359 void AlphaBlockDXT5::evaluatePalette8(uint8 alpha[8]) const
360 {
361         // 8-alpha block:  derive the other six alphas.
362         // Bit code 000 = alpha0, 001 = alpha1, others are interpolated.
363         alpha[0] = alpha0();
364         alpha[1] = alpha1();
365         alpha[2] = (6 * alpha[0] + 1 * alpha[1]) / 7;   // bit code 010
366         alpha[3] = (5 * alpha[0] + 2 * alpha[1]) / 7;   // bit code 011
367         alpha[4] = (4 * alpha[0] + 3 * alpha[1]) / 7;   // bit code 100
368         alpha[5] = (3 * alpha[0] + 4 * alpha[1]) / 7;   // bit code 101
369         alpha[6] = (2 * alpha[0] + 5 * alpha[1]) / 7;   // bit code 110
370         alpha[7] = (1 * alpha[0] + 6 * alpha[1]) / 7;   // bit code 111
371 }
372
373 void AlphaBlockDXT5::evaluatePalette6(uint8 alpha[8]) const
374 {
375         // 6-alpha block.
376         // Bit code 000 = alpha0, 001 = alpha1, others are interpolated.
377         alpha[0] = alpha0();
378         alpha[1] = alpha1();
379         alpha[2] = (4 * alpha[0] + 1 * alpha[1]) / 5;   // Bit code 010
380         alpha[3] = (3 * alpha[0] + 2 * alpha[1]) / 5;   // Bit code 011
381         alpha[4] = (2 * alpha[0] + 3 * alpha[1]) / 5;   // Bit code 100
382         alpha[5] = (1 * alpha[0] + 4 * alpha[1]) / 5;   // Bit code 101
383         alpha[6] = 0x00;                                                        // Bit code 110
384         alpha[7] = 0xFF;                                                        // Bit code 111
385 }
386
387 void AlphaBlockDXT5::indices(uint8 index_array[16]) const
388 {
389         index_array[0x0] = bits0();
390         index_array[0x1] = bits1();
391         index_array[0x2] = bits2();
392         index_array[0x3] = bits3();
393         index_array[0x4] = bits4();
394         index_array[0x5] = bits5();
395         index_array[0x6] = bits6();
396         index_array[0x7] = bits7();
397         index_array[0x8] = bits8();
398         index_array[0x9] = bits9();
399         index_array[0xA] = bitsA();
400         index_array[0xB] = bitsB();
401         index_array[0xC] = bitsC();
402         index_array[0xD] = bitsD();
403         index_array[0xE] = bitsE();
404         index_array[0xF] = bitsF();
405 }
406
407 uint AlphaBlockDXT5::index(uint index) const
408 {
409         int offset = (3 * index + 16);
410         return uint((this->u >> offset) & 0x7);
411 }
412
413 void AlphaBlockDXT5::setIndex(uint index, uint value)
414 {
415         int offset = (3 * index + 16);
416         uint64 mask = uint64(0x7) << offset;
417         this->u = (this->u & ~mask) | (uint64(value) << offset);
418 }
419
420 void AlphaBlockDXT5::decodeBlock(ColorBlock * block) const
421 {
422         uint8 alpha_array[8];
423         evaluatePalette(alpha_array);
424         
425         uint8 index_array[16];
426         indices(index_array);
427         
428         for(uint i = 0; i < 16; i++) {
429                 block->color(i).a = alpha_array[index_array[i]];
430         }
431 }
432
433 void AlphaBlockDXT5::flip4()
434 {
435         uint64 * b = (uint64 *)this;
436         
437         // @@ The masks might have to be byte swapped.
438         uint64 tmp = (*b & (uint64)(0x000000000000FFFFLL));
439         tmp |= (*b & (uint64)(0x000000000FFF0000LL)) << 36;
440         tmp |= (*b & (uint64)(0x000000FFF0000000LL)) << 12;
441         tmp |= (*b & (uint64)(0x000FFF0000000000LL)) >> 12;
442         tmp |= (*b & (uint64)(0xFFF0000000000000LL)) >> 36;
443         
444         *b = tmp;
445 }
446
447 void AlphaBlockDXT5::flip2()
448 {
449         uint * b = (uint *)this;
450         
451         // @@ The masks might have to be byte swapped.
452         uint tmp = (*b & 0xFF000000);
453         tmp |=  (*b & 0x00000FFF) << 12;
454         tmp |= (*b & 0x00FFF000) >> 12;
455         
456         *b = tmp;
457 }
458
459 void BlockDXT5::decodeBlock(ColorBlock * block) const
460 {
461         // Decode color.
462         color.decodeBlock(block);
463         
464         // Decode alpha.
465         alpha.decodeBlock(block);
466 }
467
468 void BlockDXT5::decodeBlockNV5x(ColorBlock * block) const
469 {
470         // Decode color.
471         color.decodeBlockNV5x(block);
472         
473         // Decode alpha.
474         alpha.decodeBlock(block);
475 }
476
477 /// Flip DXT5 block vertically.
478 void BlockDXT5::flip4()
479 {
480         alpha.flip4();
481         color.flip4();
482 }
483
484 /// Flip half DXT5 block vertically.
485 void BlockDXT5::flip2()
486 {
487         alpha.flip2();
488         color.flip2();
489 }
490
491
492 /// Decode ATI1 block.
493 void BlockATI1::decodeBlock(ColorBlock * block) const
494 {
495         uint8 alpha_array[8];
496         alpha.evaluatePalette(alpha_array);
497         
498         uint8 index_array[16];
499         alpha.indices(index_array);
500         
501         for(uint i = 0; i < 16; i++) {
502                 Color32 & c = block->color(i);
503                 c.b = c.g = c.r = alpha_array[index_array[i]];
504                 c.a = 255;
505         }
506 }
507
508 /// Flip ATI1 block vertically.
509 void BlockATI1::flip4()
510 {
511         alpha.flip4();
512 }
513
514 /// Flip half ATI1 block vertically.
515 void BlockATI1::flip2()
516 {
517         alpha.flip2();
518 }
519
520
521 /// Decode ATI2 block.
522 void BlockATI2::decodeBlock(ColorBlock * block) const
523 {
524         uint8 alpha_array[8];
525         uint8 index_array[16];
526         
527         x.evaluatePalette(alpha_array);
528         x.indices(index_array);
529         
530         for(uint i = 0; i < 16; i++) {
531                 Color32 & c = block->color(i);
532                 c.r = alpha_array[index_array[i]];
533         }
534
535         y.evaluatePalette(alpha_array);
536         y.indices(index_array);
537         
538         for(uint i = 0; i < 16; i++) {
539                 Color32 & c = block->color(i);
540                 c.g = alpha_array[index_array[i]];
541                 c.b = 0;
542                 c.a = 255;
543         }
544 }
545
546 /// Flip ATI2 block vertically.
547 void BlockATI2::flip4()
548 {
549         x.flip4();
550         y.flip4();
551 }
552
553 /// Flip half ATI2 block vertically.
554 void BlockATI2::flip2()
555 {
556         x.flip2();
557         y.flip2();
558 }
559
560
561 void BlockCTX1::evaluatePalette(Color32 color_array[4]) const
562 {
563         // Does bit expansion before interpolation.
564         color_array[0].b = 0x00;
565         color_array[0].g = col0[1];
566         color_array[0].r = col0[0];
567         color_array[0].a = 0xFF;
568         
569         color_array[1].r = 0x00;
570         color_array[1].g = col0[1];
571         color_array[1].b = col1[0];
572         color_array[1].a = 0xFF;
573         
574         color_array[2].r = 0x00;
575         color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3;
576         color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3;
577         color_array[2].a = 0xFF;
578                 
579         color_array[3].r = 0x00;
580         color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3;
581         color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3;
582         color_array[3].a = 0xFF;
583 }
584
585 void BlockCTX1::decodeBlock(ColorBlock * block) const
586 {
587         // Decode color block.
588         Color32 color_array[4];
589         evaluatePalette(color_array);
590         
591         // Write color block.
592         for( uint j = 0; j < 4; j++ ) {
593                 for( uint i = 0; i < 4; i++ ) {
594                         uint idx = (row[j] >> (2 * i)) & 3;
595                         block->color(i, j) = color_array[idx];
596                 }
597         }       
598 }
599
600 void BlockCTX1::setIndices(int * idx)
601 {
602         indices = 0;
603         for(uint i = 0; i < 16; i++) {
604                 indices |= (idx[i] & 3) << (2 * i);
605         }
606 }
607
608
609 /// Flip CTX1 block vertically.
610 inline void BlockCTX1::flip4()
611 {
612         swap(row[0], row[3]);
613         swap(row[1], row[2]);
614 }
615
616 /// Flip half CTX1 block vertically.
617 inline void BlockCTX1::flip2()
618 {
619         swap(row[0], row[1]);
620 }
621
622 void mem_read(Stream & mem, BlockDXT1 & block)
623 {
624         mem_read(mem, block.col0.u);
625         mem_read(mem, block.col1.u);
626         mem_read(mem, block.indices);
627 }
628
629 void mem_read(Stream & mem, AlphaBlockDXT3 & block)
630 {
631         for (unsigned int i = 0; i < 4; i++) mem_read(mem, block.row[i]);
632 }
633
634 void mem_read(Stream & mem, BlockDXT3 & block)
635 {
636         mem_read(mem, block.alpha);
637         mem_read(mem, block.color);
638 }
639
640 void mem_read(Stream & mem, AlphaBlockDXT5 & block)
641 {
642         mem_read(mem, block.u);
643 }
644
645 void mem_read(Stream & mem, BlockDXT5 & block)
646 {
647         mem_read(mem, block.alpha);
648         mem_read(mem, block.color);
649 }
650
651 void mem_read(Stream & mem, BlockATI1 & block)
652 {
653         mem_read(mem, block.alpha);
654 }
655
656 void mem_read(Stream & mem, BlockATI2 & block)
657 {
658         mem_read(mem, block.x);
659         mem_read(mem, block.y);
660 }
661
662 void mem_read(Stream & mem, BlockCTX1 & block)
663 {
664         mem_read(mem, block.col0[0]);
665         mem_read(mem, block.col0[1]);
666         mem_read(mem, block.col1[0]);
667         mem_read(mem, block.col1[1]);
668         mem_read(mem, block.indices);
669 }
670