Cannot find fourCC format of a .DDS texture

1.1k Views Asked by At

I am trying to create a function that will load texture files with .DDS format. The problem seems to occur when my program tries to detect the FourCC format of the file. It does not return true neither with FOURCC_DXT1, neither with FOURCC_DXT3, neither with FOURCC_DXT5. I have tried many textures some of which are DXT1 according to the source which i took them from, however the problem still persists.

GLuint loadDDS(const char * imagepath) {

    unsigned char header[124];

    FILE *fp;
    // open texture data
    fopen_s(&fp, imagepath, "rb");
    if (fp == NULL) return 0;

    std::cout << "file: " << fp << '\n';

    // get the surface desc 
    fread(&header, 124, 1, fp);

    // header data
    unsigned int height = *(unsigned int*)&(header[8]);
    unsigned int width = *(unsigned int*)&(header[12]);
    unsigned int linearSize = *(unsigned int*)&(header[16]);
    unsigned int mipMapCount = *(unsigned int*)&(header[24]);
    unsigned int fourCC = *(unsigned int*)&(header[80]);

    // allocate buffer
    data = (unsigned char*)malloc(width * height * 4);

    // file data
    unsigned char * buffer;
    unsigned int bufsize;

    // how big is it going to be including all mipmaps? 
    bufsize = mipMapCount > 1 ? linearSize * 2 : linearSize;
    buffer = (unsigned char*)malloc(bufsize * sizeof(unsigned char));
    fread(buffer, 1, bufsize, fp);

    // close the file pointer 
    fclose(fp);

    unsigned int components = (fourCC == FOURCC_DXT1) ? 3 : 4;
    unsigned int format;

    // here is where the problem occurs. Switch returns the default case. 
    //At this point fourCC has the value of 4.
    switch (fourCC)
    {
    case FOURCC_DXT1:
        format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
        break;
    case FOURCC_DXT3:
        format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
        break;
    case FOURCC_DXT5:
        format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
        break;
    default:
        std::cout << "Error when trying to read header of texture. Could not find FOURCC component" << '\n';
        free(data);
        return 0;
    }
    // Create one OpenGL texture
    GLuint textureID;
    glGenTextures(1, &textureID);

    // "Bind" the newly created texture : all future texture functions will modify this texture
    glBindTexture(GL_TEXTURE_2D, textureID);

    unsigned int blockSize = (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16;
    unsigned int offset = 0;

    // load the mipmaps 
    for (unsigned int level = 0; level < mipMapCount && (width || height); ++level)
    {
        unsigned int size = ((width + 3) / 4)*((height + 3) / 4)*blockSize;
        glCompressedTexImage2D(GL_TEXTURE_2D, level, format, width, height,
            0, size, data + offset);

        offset += size;
        width /= 2;
        height /= 2;
    }
    free(data);

    return textureID;
1

There are 1 best solutions below

0
On

Too lazy to debug your code ... and as this type of questions are off topic here so do not handle this as an answer (more like comment but as comment this would be not readable nor possible).

Here is what I use for loading DDS into my OpenGL engine:

//------------------------------------------------------------------------------
//--- DDS library ver: 1.03 ----------------------------------------------------
//------------------------------------------------------------------------------
#ifndef _dds_h
#define _dds_h
//------------------------------------------------------------------------------
namespace DDS {
//------------------------------------------------------------------------------
AnsiString _errorlog="";
const DWORD DDS_MAGIC                   =0x20534444;

const DWORD DDSD_CAPS                   =0x00000001;
const DWORD DDSD_HEIGHT                 =0x00000002;
const DWORD DDSD_WIDTH                  =0x00000004;
const DWORD DDSD_PITCH                  =0x00000008;
const DWORD DDSD_PIXELFORMAT            =0x00001000;
const DWORD DDSD_MIPMAPCOUNT            =0x00020000;
const DWORD DDSD_LINEARSIZE             =0x00080000;
const DWORD DDSD_DEPTH                  =0x00800000;

const DWORD DDPF_ALPHAPIXELS            =0x00000001;
const DWORD DDPF_FOURCC                 =0x00000004;
const DWORD DDPF_INDEXED                =0x00000020;
const DWORD DDPF_RGB                    =0x00000040;

const DWORD DDSCAPS_COMPLEX             =0x00000008;
const DWORD DDSCAPS_TEXTURE             =0x00001000;
const DWORD DDSCAPS_MIPMAP              =0x00400000;

const DWORD DDSCAPS2_CUBEMAP            =0x00000200;
const DWORD DDSCAPS2_CUBEMAP_POSITIVEX  =0x00000400;
const DWORD DDSCAPS2_CUBEMAP_NEGATIVEX  =0x00000800;
const DWORD DDSCAPS2_CUBEMAP_POSITIVEY  =0x00001000;
const DWORD DDSCAPS2_CUBEMAP_NEGATIVEY  =0x00002000;
const DWORD DDSCAPS2_CUBEMAP_POSITIVEZ  =0x00004000;
const DWORD DDSCAPS2_CUBEMAP_NEGATIVEZ  =0x00008000;
const DWORD DDSCAPS2_VOLUME             =0x00200000;

const DWORD D3DFMT_DXT1                 ='1TXD';
const DWORD D3DFMT_DXT2                 ='2TXD';
const DWORD D3DFMT_DXT3                 ='3TXD';
const DWORD D3DFMT_DXT4                 ='4TXD';
const DWORD D3DFMT_DXT5                 ='5TXD';
//------------------------------------------------------------------------------
#define PF_IS_DXT1(pf) \
  ((pf.dwFlags & DDPF_FOURCC) && \
   (pf.dwFourCC == D3DFMT_DXT1))

#define PF_IS_DXT3(pf) \
  ((pf.dwFlags & DDPF_FOURCC) && \
   (pf.dwFourCC == D3DFMT_DXT3))

#define PF_IS_DXT5(pf) \
  ((pf.dwFlags & DDPF_FOURCC) && \
   (pf.dwFourCC == D3DFMT_DXT5))

#define PF_IS_BGRA8(pf) \
  ((pf.dwFlags & DDPF_RGB) && \
   (pf.dwFlags & DDPF_ALPHAPIXELS) && \
   (pf.dwRGBBitCount == 32) && \
   (pf.dwRBitMask == 0xff0000) && \
   (pf.dwGBitMask == 0xff00) && \
   (pf.dwBBitMask == 0xff) && \
   (pf.dwAlphaBitMask == 0xff000000U))

#define PF_IS_RGBA8(pf) \
  ((pf.dwFlags & DDPF_RGB) && \
   (pf.dwFlags & DDPF_ALPHAPIXELS) && \
   (pf.dwRGBBitCount == 32) && \
   (pf.dwRBitMask == 0xff) && \
   (pf.dwGBitMask == 0xff00) && \
   (pf.dwBBitMask == 0xff0000) && \
   (pf.dwAlphaBitMask == 0xff000000U))

#define PF_IS_BGR8(pf) \
  ((pf.dwFlags & DDPF_RGB) && \
  !(pf.dwFlags & DDPF_ALPHAPIXELS) && \
   (pf.dwRGBBitCount == 24) && \
   (pf.dwRBitMask == 0xff0000) && \
   (pf.dwGBitMask == 0xff00) && \
   (pf.dwBBitMask == 0xff))

#define PF_IS_RGB8(pf) \
  ((pf.dwFlags & DDPF_RGB) && \
  !(pf.dwFlags & DDPF_ALPHAPIXELS) && \
   (pf.dwRGBBitCount == 24) && \
   (pf.dwRBitMask == 0xff) && \
   (pf.dwGBitMask == 0xff00) && \
   (pf.dwBBitMask == 0xff0000))

#define PF_IS_BGR5(pf) \
  ((pf.dwFlags & DDPF_RGB) && \
  !(pf.dwFlags & DDPF_ALPHAPIXELS) && \
   (pf.dwRGBBitCount == 16) && \
   (pf.dwRBitMask == 0x00007c00) && \
   (pf.dwGBitMask == 0x000003e0) && \
   (pf.dwBBitMask == 0x0000001f) && \
   (pf.dwAlphaBitMask == 0x00000000))

#define PF_IS_BGR5A1(pf) \
  ((pf.dwFlags & DDPF_RGB) && \
   (pf.dwFlags & DDPF_ALPHAPIXELS) && \
   (pf.dwRGBBitCount == 16) && \
   (pf.dwRBitMask == 0x00007c00) && \
   (pf.dwGBitMask == 0x000003e0) && \
   (pf.dwBBitMask == 0x0000001f) && \
   (pf.dwAlphaBitMask == 0x00008000))

#define PF_IS_BGR565(pf) \
  ((pf.dwFlags & DDPF_RGB) && \
  !(pf.dwFlags & DDPF_ALPHAPIXELS) && \
   (pf.dwRGBBitCount == 16) && \
   (pf.dwRBitMask == 0x0000f800) && \
   (pf.dwGBitMask == 0x000007e0) && \
   (pf.dwBBitMask == 0x0000001f))

#define PF_IS_INDEX8(pf) \
  ((pf.dwFlags & DDPF_INDEXED) && \
   (pf.dwRGBBitCount == 8))
//------------------------------------------------------------------------------
#pragma pack(1)
union DDS_header
    {
    struct
        {
        DWORD dwMagic;
        DWORD dwSize;
        DWORD dwFlags;
        DWORD dwHeight;
        DWORD dwWidth;
        DWORD dwPitchOrLinearSize;
        DWORD dwDepth;
        DWORD dwMipMapCount;
        DWORD dwReserved1[ 11 ];

        //  DDPIXELFORMAT
        struct
            {
            DWORD dwSize;
            DWORD dwFlags;
            DWORD dwFourCC;
            DWORD dwRGBBitCount;
            DWORD dwRBitMask;
            DWORD dwGBitMask;
            DWORD dwBBitMask;
            DWORD dwAlphaBitMask;
            } sPixelFormat;

        //  DDCAPS2
        struct
            {
            DWORD dwCaps1;
            DWORD dwCaps2;
            DWORD dwDDSX;
            DWORD dwReserved;
            } sCaps;
        DWORD dwReserved2;
        };
    BYTE data[128];
    };
#pragma pack()
//------------------------------------------------------------------------------
void load(Graphics::TBitmap *bmp,AnsiString name)
    {
    int hnd,siz,adr;
    BYTE *dat;
    int xs,ys,x,y,i;
    DWORD **p;
    DDS_header hdr;

    hnd=FileOpen(name,fmOpenRead); if (hnd<0) return;
    siz=FileSeek(hnd,0,2);
        FileSeek(hnd,0,0);
    FileRead(hnd,&hdr,sizeof(hdr));


    if (hdr.dwSize!=124) { FileClose(hnd); return; }
    if (hdr.dwMagic!=DDS_MAGIC) { FileClose(hnd); return; }
    if (DWORD(hdr.dwFlags&DDSD_CAPS)==0) { FileClose(hnd); return; }
    if (DWORD(hdr.dwFlags&DDSD_PIXELFORMAT)==0) { FileClose(hnd); return; }

    xs=hdr.dwWidth;
    ys=hdr.dwHeight;
    bmp->Width=xs;
    bmp->Height=ys;
    bmp->PixelFormat=pf32bit;
    bmp->HandleType=bmDIB;
    p=new DWORD*[ys]; if (p==NULL) { FileClose(hnd); return; }
    #ifdef _mmap_h
    if (p) mmap_new('DDS',p,ys*sizeof(DWORD*));
    #endif
    for (y=0;y<ys;y++) p[y]=(DWORD*)bmp->ScanLine[y];
    dat=new BYTE[siz];
    if (dat==NULL)
        {
        #ifdef _mmap_h
        mmap_del('DDS',p);
        #endif
        delete[] p;
        FileClose(hnd);
        return;
        }
    #ifdef _mmap_h
    if (dat) mmap_new('DDS',dat,siz*sizeof(BYTE));
    #endif
    FileRead(hnd,dat,siz);
    FileClose(hnd);

    if (PF_IS_DXT1  (hdr.sPixelFormat))
        {
        BYTE c[4][4];
        WORD *ptr=(WORD*)(void*)dat;
        DWORD q,a0,a1;
        adr=0;
        ys&=0xFFFFFFFF-3;
        xs&=0xFFFFFFFF-3;
        for (y=0;y<ys;y+=4)
         for (x=xs-1;x>=0;)
            {
            q=ptr[adr]; adr++;
            c[0][0]=(q<<3)&248;
            c[0][1]=(q>>3)&248;
            c[0][2]=(q>>8)&248;
            c[0][3]=0;
            q=ptr[adr]; adr++;
            c[1][0]=(q<<3)&248;
            c[1][1]=(q>>3)&248;
            c[1][2]=(q>>8)&248;
            c[1][3]=0;
            for (i=0;i<4;i++)
                {
                a0=c[0][i];
                a1=c[1][i];
                if (c[0]<c[1])
                    {
                    c[2][i]=DWORD((a0+a0+a1)/3);
                    c[3][i]=DWORD((a0+a1+a1)/3);
                    }
                else{
                    c[2][i]=DWORD((a0+a1)/2);
                    c[3][i]=0;
                    }
                }
            q=ptr[adr]; adr++;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]; x+=3; y++;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]; x+=3; y++;
            q=ptr[adr]; adr++;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]; x+=3; y++;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]; x--;  y-=3;
            }
        }
    else if (PF_IS_DXT3  (hdr.sPixelFormat))
        {
        BYTE c[4][4];
        WORD *ptr=(WORD*)(void*)dat;
        DWORD q,a[16],a0,a1;
        adr=0;
        ys&=0xFFFFFFFF-3;
        xs&=0xFFFFFFFF-3;
        for (y=0;y<ys;y+=4)
         for (x=xs-1;x>=0;)
            {
            for (i=0;i<16;)
                {
                q=ptr[adr]; adr++; q<<=16;
                a[i]=q&0x0F0000000; q<<=4; i++;
                a[i]=q&0x0F0000000; q<<=4; i++;
                a[i]=q&0x0F0000000; q<<=4; i++;
                a[i]=q&0x0F0000000; q<<=4; i++;
                }
            q=ptr[adr]; adr++;
            c[0][0]=(q<<3)&248;
            c[0][1]=(q>>3)&248;
            c[0][2]=(q>>8)&248;
            c[0][3]=0;
            q=ptr[adr]; adr++;
            c[1][0]=(q<<3)&248;
            c[1][1]=(q>>3)&248;
            c[1][2]=(q>>8)&248;
            c[1][3]=0;
            for (i=0;i<4;i++)
                {
                a0=c[0][i];
                a1=c[1][i];
                if (c[0]<c[1])
                    {
                    c[2][i]=DWORD((a0+a0+a1)/3);
                    c[3][i]=DWORD((a0+a1+a1)/3);
                    }
                else{
                    c[2][i]=DWORD((a0+a1)/2);
                    c[3][i]=0;
                    }
                }
            q=ptr[adr]; adr++;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[ 0]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[ 1]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[ 2]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[ 3]; x+=3; y++;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[ 4]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[ 5]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[ 6]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[ 7]; x+=3; y++;
            q=ptr[adr]; adr++;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[ 8]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[ 9]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[10]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[11]; x+=3; y++;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[12]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[13]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[14]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[15]; x--;  y-=3;
            }
        }
    else if (PF_IS_DXT5  (hdr.sPixelFormat))
        {
        BYTE c[4][4];
        WORD *ptr=(WORD*)(void*)dat;
        DWORD q,ca[8],a[16],a0,a1;
        adr=0;
        ys&=0xFFFFFFFF-3;
        xs&=0xFFFFFFFF-3;
        for (y=0;y<ys;y+=4)
         for (x=xs-1;x>=0;)
            {
            q=ptr[adr]; adr++;
            a0=(q>>8)&255; ca[0]=a0;
            a1=(q   )&255; ca[1]=a1;
            if (a0<a1)
                {
                ca[2]=((6*a0)+(  a1))/7;
                ca[3]=((5*a0)+(2*a1))/7;
                ca[4]=((4*a0)+(3*a1))/7;
                ca[5]=((3*a0)+(4*a1))/7;
                ca[6]=((2*a0)+(5*a1))/7;
                ca[7]=((  a0)+(6*a1))/7;
                }
            else{
                ca[2]=((4*a0)+(  a1))/5;
                ca[3]=((3*a0)+(2*a1))/5;
                ca[4]=((2*a0)+(3*a1))/5;
                ca[5]=((  a0)+(4*a1))/5;
                ca[6]=0;
                ca[7]=255;
                }
            for (i=0;i<8;i++) ca[i]=(ca[i]<<24)&0x00FF000000;
            i=0;
            q=ptr[adr]; adr++;
            a0=q&7; q>>=3; a[i]=ca[a0]; i++;
            a0=q&7; q>>=3; a[i]=ca[a0]; i++;
            a0=q&7; q>>=3; a[i]=ca[a0]; i++;
            a0=q&7; q>>=3; a[i]=ca[a0]; i++;
            a0=q&7; q>>=3; a[i]=ca[a0]; i++;
            a0=q&1;
            q=ptr[adr]; adr++;
            a0|=(q<<1)&6; q>>=2; a[i]=ca[a0]; i++;
            a0=q&7; q>>=3; a[i]=ca[a0]; i++;
            a0=q&7; q>>=3; a[i]=ca[a0]; i++;
            a0=q&7; q>>=3; a[i]=ca[a0]; i++;
            a0=q&7; q>>=3; a[i]=ca[a0]; i++;
            a0=q&3;
            q=ptr[adr]; adr++;
            a0|=(q<<2)&4; q>>=1; a[i]=ca[a0]; i++;
            a0=q&7; q>>=3; a[i]=ca[a0]; i++;
            a0=q&7; q>>=3; a[i]=ca[a0]; i++;
            a0=q&7; q>>=3; a[i]=ca[a0]; i++;
            a0=q&7; q>>=3; a[i]=ca[a0]; i++;
            a0=q&7; q>>=3; a[i]=ca[a0]; i++;
            q=ptr[adr]; adr++;
            c[0][0]=(q<<3)&248;
            c[0][1]=(q>>3)&248;
            c[0][2]=(q>>8)&248;
            c[0][3]=0;
            q=ptr[adr]; adr++;
            c[1][0]=(q<<3)&248;
            c[1][1]=(q>>3)&248;
            c[1][2]=(q>>8)&248;
            c[1][3]=0;
            for (i=0;i<4;i++)
                {
                a0=c[0][i];
                a1=c[1][i];
                if (c[0]<c[1])
                    {
                    c[2][i]=DWORD((a0+a0+a1)/3);
                    c[3][i]=DWORD((a0+a1+a1)/3);
                    }
                else{
                    c[2][i]=DWORD((a0+a1)/2);
                    c[3][i]=0;
                    }
                }
            q=ptr[adr]; adr++;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[ 0]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[ 1]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[ 2]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[ 3]; x+=3; y++;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[ 4]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[ 5]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[ 6]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[ 7]; x+=3; y++;
            q=ptr[adr]; adr++;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[ 8]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[ 9]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[10]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[11]; x+=3; y++;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[12]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[13]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[14]; x--;
            a0=q&3; q>>=2; p[y][x]=((DWORD*)c)[a0]|a[15]; x--;  y-=3;
            }
        }
    else if (PF_IS_BGRA8 (hdr.sPixelFormat))
        {
        DWORD q,*ptr=(DWORD*)(void*)dat;
        adr=0;
        for (y=0;y<ys;y++)
         for (x=xs-1;x>=0;x--)
            {
            q=ptr[adr]; adr++;
            p[y][x]=q;
            }
        }
    else if (PF_IS_BGR8  (hdr.sPixelFormat))
        {
        struct _col { BYTE r,g,b; } *ptr=(_col*)(void*)dat;
        union { _col c; DWORD d; } dc;
        adr=0; dc.d=0;
        for (y=0;y<ys;y++)
         for (x=xs-1;x>=0;x--)
            {
            dc.c=ptr[adr]; adr++;
            p[y][x]=dc.d;
            }
        }
    else if (PF_IS_RGBA8 (hdr.sPixelFormat))
        {
        union { DWORD dd; BYTE db[4]; } w;
        adr=0; w.dd=0;
        for (y=0;y<ys;y++)
         for (x=xs-1;x>=0;x--)
            {
            w.db[2]=dat[adr]; adr++;
            w.db[1]=dat[adr]; adr++;
            w.db[0]=dat[adr]; adr++;
            w.db[3]=dat[adr]; adr++;
            p[y][x]=w.dd;
            }
        }
    else if (PF_IS_RGB8  (hdr.sPixelFormat))
        {
        union { DWORD dd; BYTE db[4]; } w;
        adr=0; w.dd=0;
        for (y=0;y<ys;y++)
         for (x=xs-1;x>=0;x--)
            {
            w.db[2]=dat[adr]; adr++;
            w.db[1]=dat[adr]; adr++;
            w.db[0]=dat[adr]; adr++;
            p[y][x]=w.dd;
            }
        }
    else if (PF_IS_BGR5(hdr.sPixelFormat))
        {
        union { DWORD dd; BYTE db[4]; } w,c;
        adr=0; w.dd=0; c.dd=0;
        for (y=0;y<ys;y++)
         for (x=xs-1;x>=0;x--)
            {
            w.db[1]=dat[adr]; adr++;
            w.db[0]=dat[adr]; adr++;
            c.db[0]=DWORD((w.dd    )&0x1F)<<3;  // B
            c.db[1]=DWORD((w.dd>> 5)&0x1F)<<3;  // G
            c.db[2]=DWORD((w.dd>>10)&0x1F)<<3;  // R
            p[y][x]=c.dd;
            }
        }
    else if (PF_IS_BGR5A1(hdr.sPixelFormat))
        {
        union { DWORD dd; BYTE db[4]; } w,c;
        adr=0; w.dd=0; c.dd=0;
        for (y=0;y<ys;y++)
         for (x=xs-1;x>=0;x--)
            {
            w.db[1]=dat[adr]; adr++;
            w.db[0]=dat[adr]; adr++;
            c.db[0]=DWORD((w.dd    )&0x1F)<<3;  // B
            c.db[1]=DWORD((w.dd>> 5)&0x1F)<<3;  // G
            c.db[2]=DWORD((w.dd>>10)&0x1F)<<3;  // R
            if (DWORD(w.dd&0x8000)) c.db[3]=255;// A
             else c.db[3]=0;
            p[y][x]=c.dd;
            }
        }
    else if (PF_IS_BGR565(hdr.sPixelFormat))
        {
        union { DWORD dd; BYTE db[4]; } w,c;
        adr=0; w.dd=0; c.dd=0;
        for (y=0;y<ys;y++)
         for (x=xs-1;x>=0;x--)
            {
            w.db[1]=dat[adr]; adr++;
            w.db[0]=dat[adr]; adr++;
            c.db[0]=DWORD((w.dd    )&0x1F)<<3;  // B
            c.db[1]=DWORD((w.dd>> 5)&0x3F)<<2;  // G
            c.db[2]=DWORD((w.dd>>11)&0x1F)<<3;  // R
            p[y][x]=c.dd;
            }
        }
//  else if (PF_IS_INDEX8(hdr.sPixelFormat));
    else _errorlog+="DDS::unsuported format \""+name+"\"\n";

    #ifdef _mmap_h
    mmap_del('DDS',dat);
    mmap_del('DDS',p);
    #endif
    delete[] dat;
    delete[] p;
    }
//---------------------------------------------------------------------------
#undef PF_IS_DXT1
#undef PF_IS_DXT3
#undef PF_IS_DXT5
#undef PF_IS_BGRA8
#undef PF_IS_RGBA8
#undef PF_IS_BGR8
#undef PF_IS_RGB8
#undef PF_IS_BGR5
#undef PF_IS_BGR5A1
#undef PF_IS_BGR565
#undef PF_IS_INDEX8
//---------------------------------------------------------------------------
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

Its C++/VCL based so you can extract/port this to detect the fileformat ... I wrote this quite a long ago if I remember correctly the only stuff used from VCL is Bitmap,file access and AnsiString. The AnsiString is self allocable string variable capable of string arithmetics. Beware its letters are accessed from 1. The bitmap use is described here:

And file access is straightforward so porting it should not pose any problem.

So either port/use this or compare with your detection to locate the bug of yours... As yo can see I do not support all the formats but its a working start point.