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