~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to source/blender/imbuf/intern/dds/DirectDrawSurface.cpp

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-07-23 08:54:18 UTC
  • mfrom: (14.2.16 sid)
  • mto: (14.2.19 sid)
  • mto: This revision was merged to the branch mainline in revision 42.
  • Revision ID: package-import@ubuntu.com-20120723085418-9foz30v6afaf5ffs
Tags: 2.63a-2
* debian/: Cycles support added (Closes: #658075)
  For now, this top feature has been enabled only
  on [any-amd64 any-i386] architectures because
  of OpenImageIO failing on all others
* debian/: scripts installation path changed
  from /usr/lib to /usr/share:
  + debian/patches/: patchset re-worked for path changing
  + debian/control: "Breaks" field added on yafaray-exporter

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * $Id: DirectDrawSurface.cpp 26841 2010-02-12 13:34:04Z campbellbarton $
3
 
 *
 
1
/*
4
2
 * ***** BEGIN GPL LICENSE BLOCK *****
5
3
 *
6
4
 * This program is free software; you can redistribute it and/or
17
15
 * along with this program; if not, write to the Free Software Foundation,
18
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
17
 *
20
 
 * Contributors: Amorilia (amorilia@gamebox.net)
 
18
 * Contributors: Amorilia (amorilia@users.sourceforge.net)
21
19
 *
22
20
 * ***** END GPL LICENSE BLOCK *****
23
21
 */
24
22
 
 
23
/** \file blender/imbuf/intern/dds/DirectDrawSurface.cpp
 
24
 *  \ingroup imbdds
 
25
 */
 
26
 
 
27
 
25
28
/*
26
29
 * This file is based on a similar file from the NVIDIA texture tools
27
30
 * (http://nvidia-texture-tools.googlecode.com/)
64
67
 
65
68
#if !defined(MAKEFOURCC)
66
69
#       define MAKEFOURCC(ch0, ch1, ch2, ch3) \
67
 
                ((uint)((unsigned char)(ch0)) | \
68
 
                ((uint)((unsigned char)(ch1)) << 8) | \
69
 
                ((uint)((unsigned char)(ch2)) << 16) | \
70
 
                ((uint)((unsigned char)(ch3)) << 24 ))
 
70
    (uint(uint8(ch0)) | (uint(uint8(ch1)) << 8) | \
 
71
    (uint(uint8(ch2)) << 16) | (uint(uint8(ch3)) << 24 ))
71
72
#endif
72
73
 
 
74
static const uint FOURCC_NVTT = MAKEFOURCC('N', 'V', 'T', 'T');
73
75
static const uint FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' ');
74
76
static const uint FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1');
75
77
static const uint FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2');
84
86
        
85
87
static const uint FOURCC_DX10 = MAKEFOURCC('D', 'X', '1', '0');
86
88
 
 
89
static const uint FOURCC_UVER = MAKEFOURCC('U', 'V', 'E', 'R');
 
90
 
87
91
// 32 bit RGB formats.
88
92
static const uint D3DFMT_R8G8B8 = 20;
89
93
static const uint D3DFMT_A8R8G8B8 = 21;
155
159
static const uint DDPF_PALETTEINDEXED8 = 0x00000020U;
156
160
static const uint DDPF_LUMINANCE = 0x00020000U;
157
161
static const uint DDPF_ALPHAPREMULT = 0x00008000U;
158
 
static const uint DDPF_NORMAL = 0x80000000U;    // @@ Custom nv flag.
 
162
 
 
163
// Custom NVTT flags.
 
164
static const uint DDPF_NORMAL = 0x80000000U;  
 
165
static const uint DDPF_SRGB = 0x40000000U;
159
166
 
160
167
        // DX10 formats.
161
168
        enum DXGI_FORMAT
272
279
                DXGI_FORMAT_B5G5R5A1_UNORM = 86,
273
280
                DXGI_FORMAT_B8G8R8A8_UNORM = 87,
274
281
                DXGI_FORMAT_B8G8R8X8_UNORM = 88,
 
282
 
 
283
        DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
 
284
        DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
 
285
        DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
 
286
        DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
 
287
        DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
 
288
 
 
289
        DXGI_FORMAT_BC6H_TYPELESS = 94,
 
290
        DXGI_FORMAT_BC6H_UF16 = 95,
 
291
        DXGI_FORMAT_BC6H_SF16 = 96,
 
292
 
 
293
        DXGI_FORMAT_BC7_TYPELESS = 97,
 
294
        DXGI_FORMAT_BC7_UNORM = 98,
 
295
        DXGI_FORMAT_BC7_UNORM_SRGB = 99,
275
296
        };
276
297
 
277
298
        enum D3D10_RESOURCE_DIMENSION
473
494
        }
474
495
}
475
496
 
 
497
namespace
 
498
{
 
499
    struct FormatDescriptor
 
500
    {
 
501
        uint format;
 
502
        uint bitcount;
 
503
        uint rmask;
 
504
        uint gmask;
 
505
        uint bmask;
 
506
        uint amask;
 
507
    };
 
508
 
 
509
    static const FormatDescriptor s_d3dFormats[] =
 
510
    {
 
511
        { D3DFMT_R8G8B8,                24, 0xFF0000,   0xFF00,     0xFF,       0 },
 
512
        { D3DFMT_A8R8G8B8,              32, 0xFF0000,   0xFF00,     0xFF,       0xFF000000 },  // DXGI_FORMAT_B8G8R8A8_UNORM
 
513
        { D3DFMT_X8R8G8B8,              32, 0xFF0000,   0xFF00,     0xFF,       0 },           // DXGI_FORMAT_B8G8R8X8_UNORM
 
514
        { D3DFMT_R5G6B5,                16,     0xF800,     0x7E0,      0x1F,       0 },           // DXGI_FORMAT_B5G6R5_UNORM
 
515
        { D3DFMT_X1R5G5B5,              16, 0x7C00,     0x3E0,      0x1F,       0 },
 
516
        { D3DFMT_A1R5G5B5,              16, 0x7C00,     0x3E0,      0x1F,       0x8000 },      // DXGI_FORMAT_B5G5R5A1_UNORM
 
517
        { D3DFMT_A4R4G4B4,              16, 0xF00,      0xF0,       0xF,        0xF000 },
 
518
        { D3DFMT_R3G3B2,                8,  0xE0,       0x1C,       0x3,            0 },
 
519
        { D3DFMT_A8,                    8,  0,          0,          0,              8 },           // DXGI_FORMAT_A8_UNORM
 
520
        { D3DFMT_A8R3G3B2,              16, 0xE0,       0x1C,       0x3,        0xFF00 },
 
521
        { D3DFMT_X4R4G4B4,              16, 0xF00,      0xF0,       0xF,        0 },
 
522
        { D3DFMT_A2B10G10R10,   32, 0x3FF,      0xFFC00,    0x3FF00000, 0xC0000000 },  // DXGI_FORMAT_R10G10B10A2
 
523
        { D3DFMT_A8B8G8R8,              32, 0xFF,       0xFF00,     0xFF0000,   0xFF000000 },  // DXGI_FORMAT_R8G8B8A8_UNORM
 
524
        { D3DFMT_X8B8G8R8,              32, 0xFF,       0xFF00,     0xFF0000,   0 },
 
525
        { D3DFMT_G16R16,                32, 0xFFFF,     0xFFFF0000, 0,          0 },           // DXGI_FORMAT_R16G16_UNORM
 
526
        { D3DFMT_A2R10G10B10,   32, 0x3FF00000, 0xFFC00,    0x3FF,      0xC0000000 },
 
527
        { D3DFMT_A2B10G10R10,   32, 0x3FF,      0xFFC00,    0x3FF00000, 0xC0000000 },
 
528
 
 
529
        { D3DFMT_L8,                    8,  8,          0,          0,          0 },           // DXGI_FORMAT_R8_UNORM 
 
530
        { D3DFMT_L16,                   16, 16,         0,          0,          0 },           // DXGI_FORMAT_R16_UNORM
 
531
    };
 
532
 
 
533
    static const uint s_d3dFormatCount = sizeof(s_d3dFormats) / sizeof(s_d3dFormats[0]);
 
534
 
 
535
} // namespace
 
536
 
 
537
uint findD3D9Format(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask)
 
538
{
 
539
    for (int i = 0; i < s_d3dFormatCount; i++)
 
540
        {
 
541
            if (s_d3dFormats[i].bitcount == bitcount &&
 
542
                s_d3dFormats[i].rmask == rmask &&
 
543
                s_d3dFormats[i].gmask == gmask &&
 
544
                s_d3dFormats[i].bmask == bmask &&
 
545
                s_d3dFormats[i].amask == amask)
 
546
            {
 
547
                return s_d3dFormats[i].format;
 
548
            }
 
549
        }
 
550
 
 
551
        return 0;
 
552
    }
 
553
 
476
554
 
477
555
 
478
556
DDSHeader::DDSHeader()
488
566
        for (uint i = 0; i < 11; i++) this->reserved[i] = 0;
489
567
 
490
568
        // Store version information on the reserved header attributes.
491
 
        this->reserved[9] = MAKEFOURCC('N', 'V', 'T', 'T');
492
 
        this->reserved[10] = (0 << 16) | (9 << 8) | (5);        // major.minor.revision
 
569
    this->reserved[9] = FOURCC_NVTT;
 
570
        this->reserved[10] = (2 << 16) | (1 << 8) | (0);        // major.minor.revision
493
571
 
494
572
        this->pf.size = 32;
495
573
        this->pf.flags = 0;
527
605
void DDSHeader::setDepth(uint d)
528
606
{
529
607
        this->flags |= DDSD_DEPTH;
530
 
        this->height = d;
 
608
        this->depth = d;
531
609
}
532
610
 
533
611
void DDSHeader::setMipmapCount(uint count)
535
613
        if (count == 0 || count == 1)
536
614
        {
537
615
                this->flags &= ~DDSD_MIPMAPCOUNT;
538
 
                this->mipmapcount = 0;
 
616
        this->mipmapcount = 1;
539
617
 
540
618
                if (this->caps.caps2 == 0) {
541
619
                        this->caps.caps1 = DDSCAPS_TEXTURE;
556
634
void DDSHeader::setTexture2D()
557
635
{
558
636
        this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D;
 
637
        this->header10.arraySize = 1;
559
638
}
560
639
 
561
640
void DDSHeader::setTexture3D()
563
642
        this->caps.caps2 = DDSCAPS2_VOLUME;
564
643
 
565
644
        this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE3D;
 
645
        this->header10.arraySize = 1;
566
646
}
567
647
 
568
648
void DDSHeader::setTextureCube()
594
674
        this->pf.flags = DDPF_FOURCC;
595
675
        this->pf.fourcc = MAKEFOURCC(c0, c1, c2, c3);
596
676
 
597
 
        if (this->pf.fourcc == FOURCC_ATI2)
598
 
        {
599
 
                this->pf.bitcount = FOURCC_A2XY;
600
 
        }
601
 
        else
602
 
        {
603
 
                this->pf.bitcount = 0;
604
 
        }
 
677
        this->pf.bitcount = 0;
 
678
        this->pf.rmask = 0;
 
679
        this->pf.gmask = 0;
 
680
        this->pf.bmask = 0;
 
681
        this->pf.amask = 0;
 
682
}
 
683
 
 
684
void DDSHeader::setFormatCode(uint32 code)
 
685
{
 
686
        // set fourcc pixel format.
 
687
        this->pf.flags = DDPF_FOURCC;
 
688
        this->pf.fourcc = code;
605
689
        
 
690
        this->pf.bitcount = 0;
606
691
        this->pf.rmask = 0;
607
692
        this->pf.gmask = 0;
608
693
        this->pf.bmask = 0;
609
694
        this->pf.amask = 0;
610
695
}
611
696
 
 
697
void DDSHeader::setSwizzleCode(uint8 c0, uint8 c1, uint8 c2, uint8 c3)
 
698
{
 
699
        this->pf.bitcount = MAKEFOURCC(c0, c1, c2, c3);
 
700
}
 
701
 
 
702
 
612
703
void DDSHeader::setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask)
613
704
{
614
705
        // Make sure the masks are correct.
615
 
        if ((rmask & gmask) || \
616
 
                (rmask & bmask) || \
617
 
                (rmask & amask) || \
618
 
                (gmask & bmask) || \
619
 
                (gmask & amask) || \
 
706
        if ((rmask & gmask) ||
 
707
                (rmask & bmask) ||
 
708
                (rmask & amask) ||
 
709
                (gmask & bmask) ||
 
710
                (gmask & amask) ||
620
711
                (bmask & amask)) {
621
712
                printf("DDS: bad RGBA masks, pixel format not set\n");
622
713
                return;
623
714
        }
624
715
 
625
 
        this->pf.flags = DDPF_RGB;
 
716
        if (rmask != 0 || gmask != 0 || bmask != 0)
 
717
        {
 
718
        if (gmask == 0 && bmask == 0)
 
719
        {
 
720
            this->pf.flags = DDPF_LUMINANCE;
 
721
        }
 
722
        else
 
723
        {
 
724
                    this->pf.flags = DDPF_RGB;
 
725
        }
626
726
 
627
 
        if (amask != 0) {
628
 
                this->pf.flags |= DDPF_ALPHAPIXELS;
 
727
                if (amask != 0) {
 
728
                        this->pf.flags |= DDPF_ALPHAPIXELS;
 
729
                }
 
730
        }
 
731
        else if (amask != 0)
 
732
        {
 
733
                this->pf.flags |= DDPF_ALPHA;
629
734
        }
630
735
 
631
736
        if (bitcount == 0)
638
743
                }
639
744
        }
640
745
 
 
746
    // D3DX functions do not like this:
 
747
        this->pf.fourcc = 0; //findD3D9Format(bitcount, rmask, gmask, bmask, amask);
 
748
    /*if (this->pf.fourcc) {
 
749
        this->pf.flags |= DDPF_FOURCC;
 
750
    }*/
 
751
 
641
752
        if (!(bitcount > 0 && bitcount <= 32)) {
642
753
                printf("DDS: bad bit count, pixel format not set\n");
643
754
                return;
644
755
        }
645
 
 
646
 
        // Align to 8.
647
 
        if (bitcount <= 8) bitcount = 8;
648
 
        else if (bitcount <= 16) bitcount = 16;
649
 
        else if (bitcount <= 24) bitcount = 24;
650
 
        else bitcount = 32;
651
 
 
652
 
        this->pf.fourcc = 0; //findD3D9Format(bitcount, rmask, gmask, bmask, amask);
653
756
        this->pf.bitcount = bitcount;
654
757
        this->pf.rmask = rmask;
655
758
        this->pf.gmask = gmask;
670
773
        else this->pf.flags &= ~DDPF_NORMAL;
671
774
}
672
775
 
 
776
void DDSHeader::setSrgbFlag(bool b)
 
777
{
 
778
    if (b) this->pf.flags |= DDPF_SRGB;
 
779
    else this->pf.flags &= ~DDPF_SRGB;
 
780
}
 
781
 
 
782
void DDSHeader::setHasAlphaFlag(bool b)
 
783
{
 
784
        if (b) this->pf.flags |= DDPF_ALPHAPIXELS;
 
785
        else this->pf.flags &= ~DDPF_ALPHAPIXELS;
 
786
}
 
787
 
 
788
void DDSHeader::setUserVersion(int version)
 
789
{
 
790
    this->reserved[7] = FOURCC_UVER;
 
791
    this->reserved[8] = version;
 
792
}
 
793
 
 
794
/*
 
795
void DDSHeader::swapBytes()
 
796
{
 
797
        this->fourcc = POSH_LittleU32(this->fourcc);
 
798
        this->size = POSH_LittleU32(this->size);
 
799
        this->flags = POSH_LittleU32(this->flags);
 
800
        this->height = POSH_LittleU32(this->height);
 
801
        this->width = POSH_LittleU32(this->width);
 
802
        this->pitch = POSH_LittleU32(this->pitch);
 
803
        this->depth = POSH_LittleU32(this->depth);
 
804
        this->mipmapcount = POSH_LittleU32(this->mipmapcount);
 
805
        
 
806
        for (int i = 0; i < 11; i++) {
 
807
                this->reserved[i] = POSH_LittleU32(this->reserved[i]);
 
808
        }
 
809
 
 
810
        this->pf.size = POSH_LittleU32(this->pf.size);
 
811
        this->pf.flags = POSH_LittleU32(this->pf.flags);
 
812
        this->pf.fourcc = POSH_LittleU32(this->pf.fourcc);
 
813
        this->pf.bitcount = POSH_LittleU32(this->pf.bitcount);
 
814
        this->pf.rmask = POSH_LittleU32(this->pf.rmask);
 
815
        this->pf.gmask = POSH_LittleU32(this->pf.gmask);
 
816
        this->pf.bmask = POSH_LittleU32(this->pf.bmask);
 
817
        this->pf.amask = POSH_LittleU32(this->pf.amask);
 
818
        this->caps.caps1 = POSH_LittleU32(this->caps.caps1);
 
819
        this->caps.caps2 = POSH_LittleU32(this->caps.caps2);
 
820
        this->caps.caps3 = POSH_LittleU32(this->caps.caps3);
 
821
        this->caps.caps4 = POSH_LittleU32(this->caps.caps4);
 
822
        this->notused = POSH_LittleU32(this->notused);
 
823
 
 
824
        this->header10.dxgiFormat = POSH_LittleU32(this->header10.dxgiFormat);
 
825
        this->header10.resourceDimension = POSH_LittleU32(this->header10.resourceDimension);
 
826
        this->header10.miscFlag = POSH_LittleU32(this->header10.miscFlag);
 
827
        this->header10.arraySize = POSH_LittleU32(this->header10.arraySize);
 
828
        this->header10.reserved = POSH_LittleU32(this->header10.reserved);
 
829
}
 
830
*/
 
831
 
673
832
bool DDSHeader::hasDX10Header() const
674
833
{
675
 
        return this->pf.fourcc == FOURCC_DX10;  // @@ This is according to AMD
676
 
        //return this->pf.flags == 0;             // @@ This is according to MS
 
834
        return this->pf.fourcc == FOURCC_DX10;
 
835
}
 
836
 
 
837
uint DDSHeader::signature() const
 
838
{
 
839
    return this->reserved[9];
 
840
}
 
841
 
 
842
uint DDSHeader::toolVersion() const
 
843
{
 
844
    return this->reserved[10];
 
845
}
 
846
 
 
847
uint DDSHeader::userVersion() const
 
848
{
 
849
    if (this->reserved[7] == FOURCC_UVER) {
 
850
        return this->reserved[8];
 
851
    }
 
852
    return 0;
 
853
}
 
854
 
 
855
bool DDSHeader::isNormalMap() const
 
856
{
 
857
    return (pf.flags & DDPF_NORMAL) != 0;
 
858
}
 
859
 
 
860
bool DDSHeader::isSrgb() const
 
861
{
 
862
    return (pf.flags & DDPF_SRGB) != 0;
 
863
}
 
864
 
 
865
bool DDSHeader::hasAlpha() const
 
866
{
 
867
    return (pf.flags & DDPF_ALPHAPIXELS) != 0;
 
868
}
 
869
 
 
870
uint DDSHeader::d3d9Format() const
 
871
{
 
872
    if (pf.flags & DDPF_FOURCC) {
 
873
        return pf.fourcc;
 
874
    }
 
875
    else {
 
876
        return findD3D9Format(pf.bitcount, pf.rmask, pf.gmask, pf.bmask, pf.amask);
 
877
    }
677
878
}
678
879
 
679
880
DirectDrawSurface::DirectDrawSurface(unsigned char *mem, uint size) : stream(mem, size), header()
698
899
        }
699
900
        
700
901
        const uint required = (DDSD_WIDTH|DDSD_HEIGHT/*|DDSD_CAPS|DDSD_PIXELFORMAT*/);
701
 
        if( (header.flags & required) != required ) {
 
902
        if ( (header.flags & required) != required ) {
702
903
                return false;
703
904
        }
704
905
        
708
909
 
709
910
        /* in some files DDSCAPS_TEXTURE is missing: silently ignore */
710
911
        /*
711
 
        if( !(header.caps.caps1 & DDSCAPS_TEXTURE) ) {
 
912
        if ( !(header.caps.caps1 & DDSCAPS_TEXTURE) ) {
712
913
                return false;
713
914
        }
714
915
        */
720
921
{
721
922
        if (header.hasDX10Header())
722
923
        {
 
924
                if (header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM ||
 
925
                        header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM ||
 
926
                        header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM ||
 
927
                        header.header10.dxgiFormat == DXGI_FORMAT_BC4_UNORM ||
 
928
                        header.header10.dxgiFormat == DXGI_FORMAT_BC5_UNORM)
 
929
                {
 
930
                        return true;
 
931
                }
 
932
 
 
933
                return false;
723
934
        }
724
935
        else
725
936
        {
738
949
                                return false;
739
950
                        }
740
951
                }
741
 
                else if (header.pf.flags & DDPF_RGB)
742
 
                {
743
 
                        // All RGB formats are supported now.
 
952
        else if ((header.pf.flags & DDPF_RGB) || (header.pf.flags & DDPF_LUMINANCE))
 
953
        {
 
954
            // All RGB and luminance formats are supported now.
744
955
                }
745
956
                else
746
957
                {
763
974
        return true;
764
975
}
765
976
 
 
977
bool DirectDrawSurface::hasAlpha() const
 
978
{
 
979
        if (header.hasDX10Header())
 
980
        {
 
981
                /* TODO: Update hasAlpha to handle all DX10 formats. */
 
982
                return 
 
983
                        header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM ||
 
984
                        header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM ||
 
985
                        header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM;
 
986
        }
 
987
        else
 
988
        {
 
989
                if (header.pf.flags & DDPF_RGB) 
 
990
                {
 
991
                        return header.pf.amask != 0;
 
992
                }
 
993
                else if (header.pf.flags & DDPF_FOURCC)
 
994
                {
 
995
                        if (header.pf.fourcc == FOURCC_RXGB ||
 
996
                                header.pf.fourcc == FOURCC_ATI1 ||
 
997
                                header.pf.fourcc == FOURCC_ATI2 ||
 
998
                                header.pf.flags & DDPF_NORMAL)
 
999
                        {
 
1000
                                return false;
 
1001
                        }
 
1002
                        else
 
1003
                        {
 
1004
                // @@ Here we could check the ALPHA_PIXELS flag, but nobody sets it. (except us?)
 
1005
                                return true;
 
1006
                        }
 
1007
                }
 
1008
 
 
1009
                return false;
 
1010
        }
 
1011
}
766
1012
 
767
1013
uint DirectDrawSurface::mipmapCount() const
768
1014
{
789
1035
        else return 1;
790
1036
}
791
1037
 
792
 
bool DirectDrawSurface::hasAlpha() const
793
 
{
794
 
        if ((header.pf.flags & DDPF_RGB) && (header.pf.amask == 0))
795
 
        {
796
 
                return false;
797
 
        }
798
 
        else if (header.pf.fourcc == FOURCC_DXT1)
799
 
        {
800
 
                return false;
801
 
        }
802
 
        else
803
 
        {
804
 
                return true;
805
 
        }
806
 
}
807
 
 
808
1038
bool DirectDrawSurface::isTexture1D() const
809
1039
{
810
1040
        if (header.hasDX10Header())
848
1078
        header.setNormalFlag(b);
849
1079
}
850
1080
 
 
1081
void DirectDrawSurface::setHasAlphaFlag(bool b)
 
1082
{
 
1083
        header.setHasAlphaFlag(b);
 
1084
}
 
1085
 
 
1086
void DirectDrawSurface::setUserVersion(int version)
 
1087
{
 
1088
    header.setUserVersion(version);
 
1089
}
 
1090
 
851
1091
void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap)
852
1092
{
853
1093
        stream.seek(offset(face, mipmap));
864
1104
        
865
1105
        img->allocate(w, h);
866
1106
        
867
 
        if (header.pf.flags & DDPF_RGB) 
868
 
        {
869
 
                readLinearImage(img);
870
 
        }
871
 
        else if (header.pf.flags & DDPF_FOURCC)
872
 
        {
 
1107
        if (hasAlpha())
 
1108
        {
 
1109
                img->setFormat(Image::Format_ARGB);
 
1110
        }
 
1111
        else
 
1112
        {
 
1113
                img->setFormat(Image::Format_RGB);
 
1114
        }
 
1115
 
 
1116
        if (header.hasDX10Header())
 
1117
        {
 
1118
                // So far only block formats supported.
873
1119
                readBlockImage(img);
874
1120
        }
 
1121
        else
 
1122
        {
 
1123
                if (header.pf.flags & DDPF_RGB) 
 
1124
                {
 
1125
                        readLinearImage(img);
 
1126
                }
 
1127
                else if (header.pf.flags & DDPF_FOURCC)
 
1128
                {
 
1129
                        readBlockImage(img);
 
1130
                }
 
1131
        }
875
1132
}
876
1133
 
877
1134
void DirectDrawSurface::readLinearImage(Image * img)
901
1158
                return;
902
1159
        }
903
1160
 
904
 
        // set image format: RGB or ARGB
905
 
        // alpha channel exists if and only if the alpha mask is non-zero
906
 
        if (header.pf.amask == 0)
907
 
        {
908
 
                img->setFormat(Image::Format_RGB);
909
 
        }
910
 
        else
911
 
        {
912
 
                img->setFormat(Image::Format_ARGB);
913
 
        }
914
 
 
915
1161
        // Read linear RGB images.
916
1162
        for (uint y = 0; y < h; y++)
917
1163
        {
921
1167
                        mem_read(stream, (unsigned char *)(&c), byteCount);
922
1168
 
923
1169
                        Color32 pixel(0, 0, 0, 0xFF);
924
 
                        pixel.r = PixelFormat::convert(c >> rshift, rsize, 8);
925
 
                        pixel.g = PixelFormat::convert(c >> gshift, gsize, 8);
926
 
                        pixel.b = PixelFormat::convert(c >> bshift, bsize, 8);
927
 
                        pixel.a = PixelFormat::convert(c >> ashift, asize, 8);
 
1170
                        pixel.r = PixelFormat::convert((c & header.pf.rmask) >> rshift, rsize, 8);
 
1171
                        pixel.g = PixelFormat::convert((c & header.pf.gmask) >> gshift, gsize, 8);
 
1172
                        pixel.b = PixelFormat::convert((c & header.pf.bmask) >> bshift, bsize, 8);
 
1173
                        pixel.a = PixelFormat::convert((c & header.pf.amask) >> ashift, asize, 8);
928
1174
 
929
1175
                        img->pixel(x, y) = pixel;
930
1176
                }
934
1180
void DirectDrawSurface::readBlockImage(Image * img)
935
1181
{
936
1182
 
937
 
        // set image format: RGB or ARGB
938
 
        if (header.pf.fourcc == FOURCC_RXGB ||
939
 
                header.pf.fourcc == FOURCC_ATI1 ||
940
 
                header.pf.fourcc == FOURCC_ATI2 ||
941
 
                header.pf.flags & DDPF_NORMAL)
942
 
        {
943
 
                img->setFormat(Image::Format_RGB);
944
 
        }
945
 
        else
946
 
        {
947
 
                img->setFormat(Image::Format_ARGB);
948
 
        }
949
 
 
950
1183
        const uint w = img->width();
951
1184
        const uint h = img->height();
952
1185
        
988
1221
 
989
1222
void DirectDrawSurface::readBlock(ColorBlock * rgba)
990
1223
{
991
 
        if (header.pf.fourcc == FOURCC_DXT1)
 
1224
        uint fourcc = header.pf.fourcc;
 
1225
 
 
1226
        // Map DX10 block formats to fourcc codes.
 
1227
        if (header.hasDX10Header())
 
1228
        {
 
1229
                if (header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM) fourcc = FOURCC_DXT1;
 
1230
                if (header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM) fourcc = FOURCC_DXT3;
 
1231
                if (header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM) fourcc = FOURCC_DXT5;
 
1232
                if (header.header10.dxgiFormat == DXGI_FORMAT_BC4_UNORM) fourcc = FOURCC_ATI1;
 
1233
                if (header.header10.dxgiFormat == DXGI_FORMAT_BC5_UNORM) fourcc = FOURCC_ATI2;
 
1234
        }
 
1235
 
 
1236
 
 
1237
        if (fourcc == FOURCC_DXT1)
992
1238
        {
993
1239
                BlockDXT1 block;
994
1240
                mem_read(stream, block);
995
1241
                block.decodeBlock(rgba);
996
1242
        }
997
 
        else if (header.pf.fourcc == FOURCC_DXT2 ||
 
1243
        else if (fourcc == FOURCC_DXT2 ||
998
1244
            header.pf.fourcc == FOURCC_DXT3)
999
1245
        {
1000
1246
                BlockDXT3 block;
1001
1247
                mem_read(stream, block);
1002
1248
                block.decodeBlock(rgba);
1003
1249
        }
1004
 
        else if (header.pf.fourcc == FOURCC_DXT4 ||
 
1250
        else if (fourcc == FOURCC_DXT4 ||
1005
1251
            header.pf.fourcc == FOURCC_DXT5 ||
1006
1252
            header.pf.fourcc == FOURCC_RXGB)
1007
1253
        {
1009
1255
                mem_read(stream, block);
1010
1256
                block.decodeBlock(rgba);
1011
1257
                
1012
 
                if (header.pf.fourcc == FOURCC_RXGB)
 
1258
                if (fourcc == FOURCC_RXGB)
1013
1259
                {
1014
1260
                        // Swap R & A.
1015
1261
                        for (int i = 0; i < 16; i++)
1021
1267
                        }
1022
1268
                }
1023
1269
        }
1024
 
        else if (header.pf.fourcc == FOURCC_ATI1)
 
1270
        else if (fourcc == FOURCC_ATI1)
1025
1271
        {
1026
1272
                BlockATI1 block;
1027
1273
                mem_read(stream, block);
1028
1274
                block.decodeBlock(rgba);
1029
1275
        }
1030
 
        else if (header.pf.fourcc == FOURCC_ATI2)
 
1276
        else if (fourcc == FOURCC_ATI2)
1031
1277
        {
1032
1278
                BlockATI2 block;
1033
1279
                mem_read(stream, block);
1037
1283
        // If normal flag set, convert to normal.
1038
1284
        if (header.pf.flags & DDPF_NORMAL)
1039
1285
        {
1040
 
                if (header.pf.fourcc == FOURCC_ATI2)
 
1286
                if (fourcc == FOURCC_ATI2)
1041
1287
                {
1042
1288
                        for (int i = 0; i < 16; i++)
1043
1289
                        {
1045
1291
                                c = buildNormal(c.r, c.g);
1046
1292
                        }
1047
1293
                }
1048
 
                else if (header.pf.fourcc == FOURCC_DXT5)
 
1294
                else if (fourcc == FOURCC_DXT5)
1049
1295
                {
1050
1296
                        for (int i = 0; i < 16; i++)
1051
1297
                        {
1071
1317
                case FOURCC_RXGB:
1072
1318
                case FOURCC_ATI2:
1073
1319
                        return 16;
 
1320
                case FOURCC_DX10:
 
1321
                        switch(header.header10.dxgiFormat)
 
1322
                        {
 
1323
                                case DXGI_FORMAT_BC1_TYPELESS:
 
1324
                                case DXGI_FORMAT_BC1_UNORM:
 
1325
                                case DXGI_FORMAT_BC1_UNORM_SRGB:
 
1326
                                case DXGI_FORMAT_BC4_TYPELESS:
 
1327
                                case DXGI_FORMAT_BC4_UNORM:
 
1328
                                case DXGI_FORMAT_BC4_SNORM:
 
1329
                                        return 8;
 
1330
                                case DXGI_FORMAT_BC2_TYPELESS:
 
1331
                                case DXGI_FORMAT_BC2_UNORM:
 
1332
                                case DXGI_FORMAT_BC2_UNORM_SRGB:
 
1333
                                case DXGI_FORMAT_BC3_TYPELESS:
 
1334
                                case DXGI_FORMAT_BC3_UNORM:
 
1335
                                case DXGI_FORMAT_BC3_UNORM_SRGB:
 
1336
                                case DXGI_FORMAT_BC5_TYPELESS:
 
1337
                                case DXGI_FORMAT_BC5_UNORM:
 
1338
                                case DXGI_FORMAT_BC5_SNORM:
 
1339
                                        return 16;
 
1340
                        };
1074
1341
        };
1075
1342
 
1076
1343
        // Not a block image.
1097
1364
                h = (h + 3) / 4;
1098
1365
                return blockSize() * w * h;
1099
1366
        }
1100
 
        else if (header.pf.flags & DDPF_RGB)
 
1367
        else if (header.pf.flags & DDPF_RGB || (header.pf.flags & DDPF_LUMINANCE))
1101
1368
        {
1102
 
                // Align pixels to bytes.
1103
 
                uint byteCount = (header.pf.bitcount + 7) / 8;
1104
 
                
1105
 
                // Align pitch to 4 bytes.
1106
 
                uint pitch = 4 * ((w * byteCount + 3) / 4);
1107
 
                
 
1369
        uint pitch = computePitch(w, header.pf.bitcount, 8); // Asuming 8 bit alignment, which is the same D3DX expects.
 
1370
        
1108
1371
                return pitch * h * d;
1109
1372
        }
1110
1373
        else {
1128
1391
 
1129
1392
uint DirectDrawSurface::offset(const uint face, const uint mipmap)
1130
1393
{
1131
 
        uint size = 128; //sizeof(DDSHeader);
 
1394
        uint size = 128; // sizeof(DDSHeader);
1132
1395
        
1133
1396
        if (header.hasDX10Header())
1134
1397
        {
1151
1414
 
1152
1415
void DirectDrawSurface::printInfo() const
1153
1416
{
1154
 
        /* printf("FOURCC: %c%c%c%c\n", ((unsigned char *)&header.fourcc)[0], ((unsigned char *)&header.fourcc)[1], ((unsigned char *)&header.fourcc)[2], ((unsigned char *)&header.fourcc)[3]); */
1155
1417
        printf("Flags: 0x%.8X\n", header.flags);
1156
1418
        if (header.flags & DDSD_CAPS) printf("\tDDSD_CAPS\n");
1157
1419
        if (header.flags & DDSD_PIXELFORMAT) printf("\tDDSD_PIXELFORMAT\n");
1162
1424
        if (header.flags & DDSD_LINEARSIZE) printf("\tDDSD_LINEARSIZE\n");
1163
1425
        if (header.flags & DDSD_MIPMAPCOUNT) printf("\tDDSD_MIPMAPCOUNT\n");
1164
1426
 
1165
 
        printf("Height: %d\n", header.height);
1166
 
        printf("Width: %d\n", header.width);
1167
 
        printf("Depth: %d\n", header.depth);
1168
 
        if (header.flags & DDSD_PITCH) printf("Pitch: %d\n", header.pitch);
1169
 
        else if (header.flags & DDSD_LINEARSIZE) printf("Linear size: %d\n", header.pitch);
1170
 
        printf("Mipmap count: %d\n", header.mipmapcount);
 
1427
        printf("Height: %u\n", header.height);
 
1428
        printf("Width: %u\n", header.width);
 
1429
        printf("Depth: %u\n", header.depth);
 
1430
        if (header.flags & DDSD_PITCH) printf("Pitch: %u\n", header.pitch);
 
1431
        else if (header.flags & DDSD_LINEARSIZE) printf("Linear size: %u\n", header.pitch);
 
1432
        printf("Mipmap count: %u\n", header.mipmapcount);
1171
1433
        
1172
1434
        printf("Pixel Format:\n");
1173
 
        /* printf("\tSize: %d\n", header.pf.size); */
1174
1435
        printf("\tFlags: 0x%.8X\n", header.pf.flags);
1175
1436
        if (header.pf.flags & DDPF_RGB) printf("\t\tDDPF_RGB\n");
 
1437
    if (header.pf.flags & DDPF_LUMINANCE) printf("\t\tDDPF_LUMINANCE\n");
1176
1438
        if (header.pf.flags & DDPF_FOURCC) printf("\t\tDDPF_FOURCC\n");
1177
1439
        if (header.pf.flags & DDPF_ALPHAPIXELS) printf("\t\tDDPF_ALPHAPIXELS\n");
1178
1440
        if (header.pf.flags & DDPF_ALPHA) printf("\t\tDDPF_ALPHA\n");
1183
1445
        if (header.pf.flags & DDPF_ALPHAPREMULT) printf("\t\tDDPF_ALPHAPREMULT\n");
1184
1446
        if (header.pf.flags & DDPF_NORMAL) printf("\t\tDDPF_NORMAL\n");
1185
1447
        
1186
 
        printf("\tFourCC: '%c%c%c%c'\n",
1187
 
                ((header.pf.fourcc >> 0) & 0xFF),
1188
 
                ((header.pf.fourcc >> 8) & 0xFF),
1189
 
                ((header.pf.fourcc >> 16) & 0xFF),
1190
 
                ((header.pf.fourcc >> 24) & 0xFF));
1191
 
        if ((header.pf.fourcc & DDPF_FOURCC) && (header.pf.bitcount != 0))
 
1448
    if (header.pf.fourcc != 0) { 
 
1449
        // Display fourcc code even when DDPF_FOURCC flag not set.
 
1450
        printf("\tFourCC: '%c%c%c%c' (0x%.8X)\n",
 
1451
                        ((header.pf.fourcc >> 0) & 0xFF),
 
1452
                        ((header.pf.fourcc >> 8) & 0xFF),
 
1453
                        ((header.pf.fourcc >> 16) & 0xFF),
 
1454
            ((header.pf.fourcc >> 24) & 0xFF), 
 
1455
            header.pf.fourcc);
 
1456
    }
 
1457
 
 
1458
    if ((header.pf.flags & DDPF_FOURCC) && (header.pf.bitcount != 0))
1192
1459
        {
1193
 
                printf("\tSwizzle: '%c%c%c%c'\n", 
 
1460
        printf("\tSwizzle: '%c%c%c%c' (0x%.8X)\n", 
1194
1461
                        (header.pf.bitcount >> 0) & 0xFF,
1195
1462
                        (header.pf.bitcount >> 8) & 0xFF,
1196
1463
                        (header.pf.bitcount >> 16) & 0xFF,
1197
 
                        (header.pf.bitcount >> 24) & 0xFF);
 
1464
            (header.pf.bitcount >> 24) & 0xFF,
 
1465
            header.pf.bitcount);
1198
1466
        }
1199
1467
        else
1200
1468
        {
1201
 
                printf("\tBit count: %d\n", header.pf.bitcount);
 
1469
                printf("\tBit count: %u\n", header.pf.bitcount);
1202
1470
        }
 
1471
 
1203
1472
        printf("\tRed mask: 0x%.8X\n", header.pf.rmask);
1204
1473
        printf("\tGreen mask: 0x%.8X\n", header.pf.gmask);
1205
1474
        printf("\tBlue mask: 0x%.8X\n", header.pf.bmask);
1239
1508
                printf("\tArray size: %u\n", header.header10.arraySize);
1240
1509
        }
1241
1510
        
1242
 
        if (header.reserved[9] == MAKEFOURCC('N', 'V', 'T', 'T'))
 
1511
    if (header.reserved[9] == FOURCC_NVTT)
1243
1512
        {
1244
1513
                int major = (header.reserved[10] >> 16) & 0xFF;
1245
1514
                int minor = (header.reserved[10] >> 8) & 0xFF;
1248
1517
                printf("Version:\n");
1249
1518
                printf("\tNVIDIA Texture Tools %d.%d.%d\n", major, minor, revision);
1250
1519
        }
 
1520
 
 
1521
    if (header.reserved[7] == FOURCC_UVER)
 
1522
    {
 
1523
        printf("User Version: %u\n", header.reserved[8]);
 
1524
    }
1251
1525
}
1252
1526