Turo Lamminen
2015-05-08 2963f4ff8f247bc65fd7db1728704d22abbfa957

Add support for fetching specific cube map faces

5 files modified
181 ■■■■■ changed files
afl-mojodds.c 34 ●●●●● patch | view | raw | blame | history
ddsinfo.c 40 ●●●● patch | view | raw | blame | history
glddstest.c 71 ●●●●● patch | view | raw | blame | history
mojodds.c 16 ●●●●● patch | view | raw | blame | history
mojodds.h 20 ●●●●● patch | view | raw | blame | history
afl-mojodds.c
@@ -1,3 +1,4 @@
#include <assert.h>
#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
@@ -55,6 +56,12 @@
    }
    uint32_t hash = 0x12345678;
    switch (textureType) {
    case MOJODDS_TEXTURE_NONE:
        assert(false);  // this is not supposed to happen
        break;
    case MOJODDS_TEXTURE_2D:
    for (unsigned int miplevel = 0; miplevel < miplevels; miplevel++) {
        const void *miptex = NULL;
        unsigned long miptexlen = 0;
@@ -70,6 +77,33 @@
            hash = (hash * 65537) ^ miptex_[i];
        }
    }
    break;
    case MOJODDS_TEXTURE_CUBE:
        for (MOJODDS_cubeFace cubeFace = MOJODDS_CUBEFACE_POSITIVE_X; cubeFace <= MOJODDS_CUBEFACE_NEGATIVE_Z; cubeFace++) {
            for (unsigned int miplevel = 0; miplevel < miplevels; miplevel++) {
                const void *miptex = NULL;
                unsigned long miptexlen = 0;
                unsigned int mipW = 0, mipH = 0;
                retval = MOJODDS_getCubeFace(cubeFace, miplevel, glfmt, tex, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH);
                if (!retval) {
                    continue;
                }
                // read every byte to make sure any buffer overflows actually overflow
                const char *miptex_ = (const char *) miptex;
                for (unsigned int i = 0; i < miptexlen; i++) {
                    hash = (hash * 65537) ^ miptex_[i];
                }
            }
        }
        break;
    case MOJODDS_TEXTURE_VOLUME:
        // TODO: do something with the data
        break;
    }
    // do something the optimizer is not allowed to remove
    printf("0x%08x\n", hash);
ddsinfo.c
@@ -68,17 +68,6 @@
        case MOJODDS_TEXTURE_2D:
            printf("2D\n");
            break;
        case MOJODDS_TEXTURE_CUBE:
            printf("cube\n");
            break;
        case MOJODDS_TEXTURE_VOLUME:
            printf("volume\n");
            break;
        }
        printf("\n");
        for (unsigned int miplevel = 0; miplevel < miplevels; miplevel++) {
@@ -97,6 +86,35 @@
            printf("miptexoffset: %8u  ", (unsigned int)(miptexoffset));
            printf("miptexlen: %8lu\n", miptexlen);
        }
            break;
        case MOJODDS_TEXTURE_CUBE:
            printf("cube\n");
            printf("\n");
            for (unsigned int miplevel = 0; miplevel < miplevels; miplevel++) {
                const void *miptex = NULL;
                unsigned long miptexlen = 0;
                unsigned int mipW = 0, mipH = 0;
                retval = MOJODDS_getCubeFace(MOJODDS_CUBEFACE_POSITIVE_X, miplevel, glfmt, tex, w, h, &miptex, &miptexlen, &mipW, &mipH);
                if (!retval) {
                    printf("MOJODDS_getMipMapTexture(%u) error: %d\n", miplevel, retval);
                    continue;
                }
                uintptr_t miptexoffset = ((const char *)(miptex)) - ((const char *)(tex));
                bool npot = !(isPow2(mipW) || isPow2(mipH));
                printf("%4u x %4u  %s", mipW, mipH, npot ? "NPOT  " : "      ");
                printf("miptexoffset: %8u  ", (unsigned int)(miptexoffset));
                printf("miptexlen: %8lu\n", miptexlen);
            }
            break;
        case MOJODDS_TEXTURE_VOLUME:
            printf("volume\n");
            break;
        }
    }
    free(contents);
glddstest.c
@@ -1,5 +1,6 @@
#define _GNU_SOURCE
#include <assert.h>
#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
@@ -102,6 +103,13 @@
        GLuint texId = 0;
        // we leak this but don't care
        glGenTextures(1, &texId);
        switch (textureType) {
        case MOJODDS_TEXTURE_NONE:
            assert(false);  // this is not supposed to happen
            break;
        case MOJODDS_TEXTURE_2D:
        glBindTexture(GL_TEXTURE_2D, texId);
        for (unsigned int miplevel = 0; miplevel < miplevels; miplevel++) {
@@ -149,6 +157,69 @@
                }
            }
        }
        glBindTexture(GL_TEXTURE_2D, 0);
        break;
        case MOJODDS_TEXTURE_CUBE:
            glBindTexture(GL_TEXTURE_CUBE_MAP, texId);
            for (MOJODDS_cubeFace cubeFace = MOJODDS_CUBEFACE_POSITIVE_X; cubeFace <= MOJODDS_CUBEFACE_NEGATIVE_Z; cubeFace++) {
                for (unsigned int miplevel = 0; miplevel < miplevels; miplevel++) {
                    const void *miptex = NULL;
                    unsigned long miptexlen = 0;
                    unsigned int mipW = 0, mipH = 0;
                    retval = MOJODDS_getCubeFace(cubeFace, miplevel, glfmt, tex, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH);
                    if (!retval) {
                        printf("MOJODDS_getCubeFace(%u, %u) error: %d\n", cubeFace, miplevel, retval);
                        continue;
                    }
                    if (isCompressed) {
                        glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace, miplevel, glfmt, mipW, mipH, 0, miptexlen, miptex);
                        pumpGLErrors("glCompressedTexImage2D %u 0x%04x %ux%u %u", miplevel, glfmt, mipW, mipH, miptexlen);
                    } else {
                        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace, miplevel, internalFormat, mipW, mipH, 0, glfmt, GL_UNSIGNED_BYTE, miptex);
                        pumpGLErrors("glTexImage2D %u 0x%04x %ux%u 0x%04x", miplevel, internalFormat, mipW, mipH, glfmt);
                    }
                }
            }
            // and now the same with ARB_texture_storage if it's available
            if (GLEW_ARB_texture_storage) {
                glGenTextures(1, &texId);
                glBindTexture(GL_TEXTURE_CUBE_MAP, texId);
                glTexStorage2D(GL_TEXTURE_CUBE_MAP, miplevels, internalFormat, w, h);
                pumpGLErrors("glTexStorage2D %u 0x%04x %ux%u", miplevels, internalFormat, w, h);
                for (MOJODDS_cubeFace cubeFace = MOJODDS_CUBEFACE_POSITIVE_X; cubeFace <= MOJODDS_CUBEFACE_NEGATIVE_Z; cubeFace++) {
                    for (unsigned int miplevel = 0; miplevel < miplevels; miplevel++) {
                        const void *miptex = NULL;
                        unsigned long miptexlen = 0;
                        unsigned int mipW = 0, mipH = 0;
                        retval = MOJODDS_getCubeFace(cubeFace, miplevel, glfmt, tex, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH);
                        if (!retval) {
                            printf("MOJODDS_getCubeFace(%u, %u) error: %d\n", cubeFace, miplevel, retval);
                            continue;
                        }
                        if (isCompressed) {
                            glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace, miplevel, 0, 0, mipW, mipH, glfmt, miptexlen, miptex);
                            pumpGLErrors("glCompressedTexSubImage2D %u %ux%u 0x%04x %u", miplevel, mipW, mipH, glfmt, miptexlen);
                        } else {
                            glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace, miplevel, 0, 0, mipW, mipH, glfmt, GL_UNSIGNED_BYTE, miptex);
                            pumpGLErrors("glTexSubImage2D %u %ux%u 0x%04x", miplevel, mipW, mipH, glfmt);
                        }
                    }
                }
            }
            glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
            break;
        case MOJODDS_TEXTURE_VOLUME:
            // TODO: do something with the data
            break;
        }
    }
    free(contents);
mojodds.c
@@ -470,5 +470,21 @@
} // MOJODDS_getMipMapTexture
int MOJODDS_getCubeFace(MOJODDS_cubeFace cubeFace, unsigned int miplevel,
                        unsigned int glfmt, const void *_basetex,
                        unsigned long _basetexlen, unsigned int w, unsigned h,
                        const void **_tex, unsigned long *_texlen,
                        unsigned int *_texw, unsigned int *_texh)
{
    // pick correct face
    const char *faceBaseTex = (const char *) _basetex;
    faceBaseTex = faceBaseTex + cubeFace * _basetexlen;
    // call MOJODDS_getMipMapTexture to get offset in that face
    return MOJODDS_getMipMapTexture(miplevel, glfmt, faceBaseTex, _basetexlen, w, h, _tex, _texlen, _texw, _texh);
}
// end of mojodds.c ...
mojodds.h
@@ -14,6 +14,19 @@
    MOJODDS_TEXTURE_VOLUME
} MOJODDS_textureType;
/* order and values for these matter, they are used for calculating offsets
   lucky for us both DDS and OpengGL order matches */
typedef enum MOJODDS_cubeFace {
    MOJODDS_CUBEFACE_POSITIVE_X,
    MOJODDS_CUBEFACE_NEGATIVE_X,
    MOJODDS_CUBEFACE_POSITIVE_Y,
    MOJODDS_CUBEFACE_NEGATIVE_Y,
    MOJODDS_CUBEFACE_POSITIVE_Z,
    MOJODDS_CUBEFACE_NEGATIVE_Z
} MOJODDS_cubeFace;
int MOJODDS_isDDS(const void *_ptr, const unsigned long _len);
int MOJODDS_getTexture(const void *_ptr, const unsigned long _len,
                       const void **_tex, unsigned long *_texlen,
@@ -27,6 +40,13 @@
                             const void **_tex, unsigned long *_texlen,
                             unsigned int *_texw, unsigned int *_texh);
int MOJODDS_getCubeFace(MOJODDS_cubeFace cubeFace, unsigned int miplevel,
                        unsigned int glfmt, const void*_basetex,
                        unsigned long _basetexlen, unsigned int w, unsigned h,
                        const void **_tex, unsigned long *_texlen,
                        unsigned int *_texw, unsigned int *_texh);
#ifdef __cplusplus
}
#endif