| 613 | } |
| 614 | |
| 615 | static bool LoadDXT5( QDataStream & s, const DDSHeader & header, QImage & img ) |
| 616 | { |
| 617 | const uint w = header.width; |
| 618 | const uint h = header.height; |
| 619 | |
| 620 | BlockDXT block; |
| 621 | BlockDXTAlphaLinear alpha; |
| 622 | QRgb * scanline[4]; |
| 623 | |
| 624 | for( uint y = 0; y < h; y += 4 ) { |
| 625 | for( uint j = 0; j < 4; j++ ) { |
| 626 | scanline[j] = (QRgb *) img.scanLine( y + j ); |
| 627 | } |
| 628 | for( uint x = 0; x < w; x += 4 ) { |
| 629 | |
| 630 | // Read 128bit color block. |
| 631 | s >> alpha; |
| 632 | s >> block; |
| 633 | |
| 634 | // Decode color block. |
| 635 | Color8888 color_array[4]; |
| 636 | block.GetColors(color_array); |
| 637 | |
| 638 | uchar alpha_array[8]; |
| 639 | alpha.GetAlphas(alpha_array); |
| 640 | |
| 641 | uchar bit_array[16]; |
| 642 | alpha.GetBits(bit_array); |
| 643 | |
| 644 | // bit masks = 00000011, 00001100, 00110000, 11000000 |
| 645 | const uint masks[4] = { 3, 3<<2, 3<<4, 3<<6 }; |
| 646 | const int shift[4] = { 0, 2, 4, 6 }; |
| 647 | |
| 648 | // Write color block. |
| 649 | for( uint j = 0; j < 4; j++ ) { |
| 650 | for( uint i = 0; i < 4; i++ ) { |
| 651 | if( img.valid( x+i, y+j ) ) { |
| 652 | uint idx = (block.row[j] & masks[i]) >> shift[i]; |
| 653 | color_array[idx].a = alpha_array[bit_array[j*4+i]]; |
| 654 | scanline[j][x+i] = qRgba(color_array[idx].r, color_array[idx].g, color_array[idx].b, color_array[idx].a); |
| 655 | } |
| 656 | } |
| 657 | } |
| 658 | } |
| 659 | } |
| 660 | |
| 661 | return true; |
| 662 | } |
| 663 | static bool LoadDXT4( QDataStream & s, const DDSHeader & header, QImage & img ) |
| 664 | { |
| 665 | if( !LoadDXT5(s, header, img) ) { |