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