From 459b257e56d3ed045941cc9eb3ed747813c5025b Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Tue, 28 Apr 2015 13:56:39 +0300 Subject: [PATCH 01/46] Edward Rudd's version --- mojodds.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- mojodds.h | 5 +++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/mojodds.c b/mojodds.c index 7da86f0..9900242 100644 --- a/mojodds.c +++ b/mojodds.c @@ -59,6 +59,7 @@ typedef uint32_t uint32; #define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 #define GL_BGR 0x80E0 #define GL_BGRA 0x80E1 +#define GL_LUMINANCE_ALPHA 0x190A typedef struct { @@ -222,7 +223,14 @@ static int parse_dds(MOJODDS_Header *header, const uint8 **ptr, size_t *len, calcSizeFlag = DDSD_PITCH; calcSize = ((width * header->ddspf.dwRGBBitCount) + 7) / 8; - } // else if + } + else if (header->ddspf.dwFlags & (DDPF_LUMINANCE | DDPF_ALPHA) ) + { + *_glfmt = GL_LUMINANCE_ALPHA; + + calcSizeFlag = DDSD_PITCH; + calcSize = ((width * header->ddspf.dwRGBBitCount) + 7) / 8; + } //else if (header->ddspf.dwFlags & DDPF_LUMINANCE) // !!! FIXME //else if (header->ddspf.dwFlags & DDPF_YUV) // !!! FIXME @@ -279,5 +287,54 @@ int MOJODDS_getTexture(const void *_ptr, const unsigned long _len, return 1; } // MOJODDS_getTexture +int MOJODDS_getMipMapTexture(unsigned int miplevel, unsigned int glfmt, + const void*_basetex, const unsigned long _basetexlen, + unsigned int w, unsigned h, + const void **_tex, unsigned long *_texlen, + unsigned int *_texw, unsigned int *_texh) +{ + int i; + const void* newtex; + unsigned long newtexlen; + unsigned int neww; + unsigned int newh; + + newtex = _basetex; + newtexlen = _basetexlen; + neww = w; + newh = h; + + // Calculate size of miplevel + for (i=0; i < miplevel; ++i) + { + // move position to next texture start + newtex += newtexlen; + // calculate texture size + newtexlen >>= 2; + neww >>= 1; + newh >>= 1; + if (neww < 1) neww = 1; + if (newh < 1) newh = 1; + switch (glfmt) { + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + if (newtexlen < 8) newtexlen = 8; + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + if (newtexlen < 16) newtexlen = 16; + break; + } // switch + } // for + + *_tex = newtex; + if (_texlen) { + *_texlen = newtexlen; + } + *_texw = neww; + *_texh = newh; + return 1; +} // MOJODDS_getMipMapTexture + + // end of mojodds.c ... diff --git a/mojodds.h b/mojodds.h index 63c848e..3c6b3e6 100644 --- a/mojodds.h +++ b/mojodds.h @@ -11,6 +11,11 @@ int MOJODDS_getTexture(const void *_ptr, const unsigned long _len, const void **_tex, unsigned long *_texlen, unsigned int *_glfmt, unsigned int *_w, unsigned int *_h, unsigned int *_miplevels); +int MOJODDS_getMipMapTexture(unsigned int miplevel, unsigned int glfmt, + const void*_basetex, const unsigned long _basetexlen, + unsigned int w, unsigned h, + const void **_tex, unsigned long *_texlen, + unsigned int *_texw, unsigned int *_texh); #ifdef __cplusplus } From 2041278768b983fc13bdbde60ed1768d05f434b1 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Tue, 28 Apr 2015 15:41:44 +0300 Subject: [PATCH 02/46] Add simple ddsinfo program --- Makefile | 21 ++++++++++++++++++++ ddsinfo.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 Makefile create mode 100644 ddsinfo.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3310d8a --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ + +CC?=gcc +CFLAGS?=-Wall -g -O -std=c99 +LDFLAGS?=-g + +.SUFFIXES: .o + +PROGRAMS:=ddsinfo + +.PHONY: all clean + +all: $(PROGRAMS) + +clean: + -rm $(PROGRAMS) *.o + + +ddsinfo: ddsinfo.o mojodds.o + $(CC) -o $@ $^ + + diff --git a/ddsinfo.c b/ddsinfo.c new file mode 100644 index 0000000..eb82636 --- /dev/null +++ b/ddsinfo.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include + +#include "mojodds.h" + + +int main(int argc, char *argv[]) { + if (argc != 2) { + printf("Usage: %s DDS-file\n", argv[0]); + return 0; + } + + FILE *f = fopen(argv[1], "rb"); + if (!f) { + printf("Error opening %s: %s (%d)\n", argv[1], strerror(errno), errno); + return 1; + } + + fseek(f, 0, SEEK_END); + long size = ftell(f); + fseek(f, 0, SEEK_SET); + + char *contents = malloc(size); + size_t readbytes = fread(contents, 1, size, f); + if (readbytes != size) { + printf("Only got %u of %ld bytes: %s\n", (unsigned int) readbytes, size, strerror(errno)); + free(contents); + fclose(f); + return 2; + } + + fclose(f); + + int isDDS = MOJODDS_isDDS(contents, size); + printf("isDDS: %d\n", isDDS); + if (isDDS) { + const void *tex = NULL; + unsigned long texlen = 0; + unsigned int glfmt = 0, w = 0, h = 0, miplevels = 0; + int retval = MOJODDS_getTexture(contents, size, &tex, &texlen, &glfmt, &w, &h, &miplevels); + + uintptr_t texoffset = ((const char *)(tex)) - contents; + printf("retval: %d\n", retval); + printf("texoffset: %u\n", (unsigned int)(texoffset)); + printf("texlen: %lu\n", texlen); + printf("glfmt: 0x%x\n", glfmt); + printf("width x height: %d x %d\n", w, h); + printf("miplevels: %d\n", miplevels); + } + + free(contents); + + return 0; +} From 16492e0dbf777d6ffb8b85988ff929194b42457f Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Wed, 29 Apr 2015 12:49:36 +0300 Subject: [PATCH 03/46] Add .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cd00d74 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.o +*~ +ddsinfo From 467597813b3cc624d99a87ef268e0b23b2c48c97 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Wed, 29 Apr 2015 13:45:53 +0300 Subject: [PATCH 04/46] ddsinfo now shows all miplevel sizes --- ddsinfo.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/ddsinfo.c b/ddsinfo.c index eb82636..dd982a5 100644 --- a/ddsinfo.c +++ b/ddsinfo.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -7,6 +8,12 @@ #include "mojodds.h" +// from http://graphics.stanford.edu/~seander/bithacks.html +static bool isPow2(unsigned int v) { + return v && !(v & (v - 1)); +} + + int main(int argc, char *argv[]) { if (argc != 2) { printf("Usage: %s DDS-file\n", argv[0]); @@ -43,12 +50,30 @@ int main(int argc, char *argv[]) { int retval = MOJODDS_getTexture(contents, size, &tex, &texlen, &glfmt, &w, &h, &miplevels); uintptr_t texoffset = ((const char *)(tex)) - contents; - printf("retval: %d\n", retval); + printf("MOJODDS_getTexture retval: %d\n", retval); printf("texoffset: %u\n", (unsigned int)(texoffset)); printf("texlen: %lu\n", texlen); printf("glfmt: 0x%x\n", glfmt); printf("width x height: %d x %d\n", w, h); printf("miplevels: %d\n", miplevels); + 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_getMipMapTexture(miplevel, glfmt, tex, texlen, 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("%4d x %4d %s", mipW, mipH, npot ? "NPOT " : " "); + printf("miptexoffset: %8u ", (unsigned int)(miptexoffset)); + printf("miptexlen: %8lu\n", miptexlen); + } } free(contents); From 25055ce2d9668798445f285eb798c050fcdef82f Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Wed, 29 Apr 2015 17:02:44 +0300 Subject: [PATCH 05/46] Aaron Melcher's version --- mojodds.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++----- mojodds.h | 12 +++++++++- 2 files changed, 73 insertions(+), 6 deletions(-) diff --git a/mojodds.c b/mojodds.c index 7da86f0..5a321cc 100644 --- a/mojodds.c +++ b/mojodds.c @@ -22,6 +22,8 @@ typedef uint8_t uint8; typedef uint32_t uint32; #endif +#include "mojodds.h" + #define STATICARRAYLEN(x) ( (sizeof ((x))) / (sizeof ((x)[0])) ) #define DDS_MAGIC 0x20534444 // 'DDS ' in littleendian. @@ -40,6 +42,14 @@ typedef uint32_t uint32; #define DDSCAPS_COMPLEX 0x8 #define DDSCAPS_MIPMAP 0x400000 #define DDSCAPS_TEXTURE 0x1000 +#define DDSCAPS2_CUBEMAP 0x200 +#define DDSCAPS2_CUBEMAP_POSITIVEX 0x400 +#define DDSCAPS2_CUBEMAP_NEGATIVEX 0x800 +#define DDSCAPS2_CUBEMAP_POSITIVEY 0x1000 +#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x2000 +#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x4000 +#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x8000 +#define DDSCAPS2_VOLUME 0x200000 #define DDPF_ALPHAPIXELS 0x1 #define DDPF_ALPHA 0x2 #define DDPF_FOURCC 0x4 @@ -60,6 +70,8 @@ typedef uint32_t uint32; #define GL_BGR 0x80E0 #define GL_BGRA 0x80E1 +#define MAX( a, b ) ((a) > (b) ? (a) : (b)) + typedef struct { uint32 dwSize; @@ -108,13 +120,17 @@ static uint32 readui32(const uint8 **_ptr, size_t *_len) } // readui32 static int parse_dds(MOJODDS_Header *header, const uint8 **ptr, size_t *len, - unsigned int *_glfmt, unsigned int *_miplevels) + unsigned int *_glfmt, unsigned int *_miplevels, + unsigned int *_cubemapfacelen, + MOJODDS_textureType *_textureType) { const uint32 pitchAndLinear = (DDSD_PITCH | DDSD_LINEARSIZE); uint32 width = 0; uint32 height = 0; uint32 calcSize = 0; uint32 calcSizeFlag = DDSD_LINEARSIZE; + uint32 blockDim = 1; + uint32 blockSize = 0; int i; // Files start with magic value... @@ -161,8 +177,6 @@ static int parse_dds(MOJODDS_Header *header, const uint8 **ptr, size_t *len, return 0; else if ((header->dwCaps & DDSCAPS_TEXTURE) == 0) return 0; - else if (header->dwCaps2 != 0) // !!! FIXME (non-zero with other bits in dwCaps set) - return 0; else if ((header->dwFlags & pitchAndLinear) == pitchAndLinear) return 0; // can't specify both. @@ -176,16 +190,22 @@ static int parse_dds(MOJODDS_Header *header, const uint8 **ptr, size_t *len, *_glfmt = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; calcSize = ((width ? ((width + 3) / 4) : 1) * 8) * (height ? ((height + 3) / 4) : 1); + blockDim = 4; + blockSize = 8; break; case FOURCC_DXT3: *_glfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; calcSize = ((width ? ((width + 3) / 4) : 1) * 16) * (height ? ((height + 3) / 4) : 1); + blockDim = 4; + blockSize = 16; break; case FOURCC_DXT5: *_glfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; calcSize = ((width ? ((width + 3) / 4) : 1) * 16) * (height ? ((height + 3) / 4) : 1); + blockDim = 4; + blockSize = 16; break; // !!! FIXME: DX10 is an extended header, introduced by DirectX 10. @@ -212,12 +232,14 @@ static int parse_dds(MOJODDS_Header *header, const uint8 **ptr, size_t *len, (header->ddspf.dwABitMask != 0xFF000000) ) return 0; // unsupported. *_glfmt = GL_BGRA; + blockSize = 4; } // if else { if (header->ddspf.dwRGBBitCount != 24) return 0; // unsupported. *_glfmt = GL_BGR; + blockSize = 3; } // else calcSizeFlag = DDSD_PITCH; @@ -245,6 +267,39 @@ static int parse_dds(MOJODDS_Header *header, const uint8 **ptr, size_t *len, header->dwFlags |= calcSizeFlag; } // if + *_textureType = MOJODDS_TEXTURE_2D; + { // figure out texture type. + if (header->dwCaps & DDSCAPS_COMPLEX && + header->dwCaps2 & DDSCAPS2_CUBEMAP && + header->dwCaps2 & DDSCAPS2_CUBEMAP_POSITIVEX && + header->dwCaps2 & DDSCAPS2_CUBEMAP_NEGATIVEX && + header->dwCaps2 & DDSCAPS2_CUBEMAP_POSITIVEY && + header->dwCaps2 & DDSCAPS2_CUBEMAP_NEGATIVEY && + header->dwCaps2 & DDSCAPS2_CUBEMAP_POSITIVEZ && + header->dwCaps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ) + { + *_textureType = MOJODDS_TEXTURE_CUBE; + } + else if (header->dwCaps2 & DDSCAPS2_VOLUME) + { + *_textureType = MOJODDS_TEXTURE_VOLUME; + } + } + + // figure out how much memory makes up a single face mip chain. + if (*_textureType == MOJODDS_TEXTURE_CUBE) + { + uint32 wd = header->dwWidth; + uint32 ht = header->dwHeight; + *_cubemapfacelen = 0; + for (i = 0; i < (int)*_miplevels; i++) + { + *_cubemapfacelen += ((MAX( wd, blockDim ) / blockDim) * (MAX( ht, blockDim ) / blockDim)) * blockSize; + wd >>= 1; + ht >>= 1; + } + } + return 1; } // parse_dds @@ -260,12 +315,14 @@ 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, unsigned int *_glfmt, unsigned int *_w, - unsigned int *_h, unsigned int *_miplevels) + unsigned int *_h, unsigned int *_miplevels, + unsigned int *_cubemapfacelen, + MOJODDS_textureType *_textureType) { size_t len = (size_t) _len; const uint8 *ptr = (const uint8 *) _ptr; MOJODDS_Header header; - if (!parse_dds(&header, &ptr, &len, _glfmt, _miplevels)) + if (!parse_dds(&header, &ptr, &len, _glfmt, _miplevels, _cubemapfacelen, _textureType)) return 0; *_tex = (const void *) ptr; diff --git a/mojodds.h b/mojodds.h index 63c848e..91f9177 100644 --- a/mojodds.h +++ b/mojodds.h @@ -6,11 +6,21 @@ extern "C" { #endif +typedef enum MOJODDS_textureType +{ + MOJODDS_TEXTURE_NONE, + MOJODDS_TEXTURE_2D, + MOJODDS_TEXTURE_CUBE, + MOJODDS_TEXTURE_VOLUME +} MOJODDS_textureType; + 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, unsigned int *_glfmt, unsigned int *_w, - unsigned int *_h, unsigned int *_miplevels); + unsigned int *_h, unsigned int *_miplevels, + unsigned int *_cubemapfacelen, + MOJODDS_textureType *_textureType); #ifdef __cplusplus } From ada40594e8860fb20165392d80551591d04e39fb Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Wed, 29 Apr 2015 14:52:49 +0300 Subject: [PATCH 06/46] Add glddstest example program --- .gitignore | 2 + Makefile | 11 +++- glddstest.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 glddstest.c diff --git a/.gitignore b/.gitignore index cd00d74..24680e2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ *.o *~ +*.trace ddsinfo +glddstest diff --git a/Makefile b/Makefile index 3310d8a..9e3a02a 100644 --- a/Makefile +++ b/Makefile @@ -3,9 +3,16 @@ CC?=gcc CFLAGS?=-Wall -g -O -std=c99 LDFLAGS?=-g +CFLAGS+=$(shell sdl2-config --cflags) +CFLAGS+=$(shell pkg-config glew --cflags) + +LDLIBS+=$(shell sdl2-config --libs) +LDLIBS+=$(shell pkg-config glew --libs) + + .SUFFIXES: .o -PROGRAMS:=ddsinfo +PROGRAMS:=ddsinfo glddstest .PHONY: all clean @@ -19,3 +26,5 @@ ddsinfo: ddsinfo.o mojodds.o $(CC) -o $@ $^ +glddstest: glddstest.o mojodds.o + $(CC) -o $@ $^ $(LDLIBS) diff --git a/glddstest.c b/glddstest.c new file mode 100644 index 0000000..4c86ded --- /dev/null +++ b/glddstest.c @@ -0,0 +1,153 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "mojodds.h" + + +// example how to use mojodds with OpenGL +// this program doesn't actually draw anything +// use apitrace, vogl or similar tool to see what it does + + +int main(int argc, char *argv[]) { + if (argc != 2) { + printf("Usage: %s DDS-file\n", argv[0]); + return 0; + } + + FILE *f = fopen(argv[1], "rb"); + if (!f) { + printf("Error opening %s: %s (%d)\n", argv[1], strerror(errno), errno); + return 1; + } + + fseek(f, 0, SEEK_END); + long size = ftell(f); + fseek(f, 0, SEEK_SET); + + char *contents = malloc(size); + size_t readbytes = fread(contents, 1, size, f); + if (readbytes != size) { + printf("Only got %u of %ld bytes: %s\n", (unsigned int) readbytes, size, strerror(errno)); + free(contents); + fclose(f); + return 2; + } + + fclose(f); + + int isDDS = MOJODDS_isDDS(contents, size); + printf("isDDS: %d\n", isDDS); + if (isDDS) { + SDL_Init(SDL_INIT_VIDEO); + SDL_Window *window = SDL_CreateWindow("OpenGL DDS test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 0, 0, SDL_WINDOW_OPENGL); + if (window == NULL) { + printf("Could not create window: %s\n", SDL_GetError()); + free(contents); + return 3; + } + + SDL_GLContext context = SDL_GL_CreateContext(window); + if (context == NULL) { + printf("Could not create GL context: %s\n", SDL_GetError()); + SDL_DestroyWindow(window); + free(contents); + return 4; + } + + // clear and swap to get better traces + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + SDL_GL_SwapWindow(window); + + glewInit(); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + SDL_GL_SwapWindow(window); + + // glewInit might raise errors if we got an OpenGL 3.0 context + // ignore them + // in this case glGetError is simpler than fooling around with callbacks + GLenum err = GL_NO_ERROR; + while ((err = glGetError()) != GL_NO_ERROR) { } + + const void *tex = NULL; + unsigned long texlen = 0; + unsigned int glfmt = 0, w = 0, h = 0, miplevels = 0; + int retval = MOJODDS_getTexture(contents, size, &tex, &texlen, &glfmt, &w, &h, &miplevels); + + bool isCompressed = true; + GLenum internalFormat = glfmt; + if (glfmt == GL_BGRA || glfmt == GL_BGR) { + isCompressed = false; + if (glfmt == GL_BGR) { + internalFormat = GL_RGB8; + } else { + internalFormat = GL_RGBA8; + } + } + + GLuint texId = 0; + // we leak this but don't care + glGenTextures(1, &texId); + glBindTexture(GL_TEXTURE_2D, texId); + + for (unsigned int miplevel = 0; miplevel < miplevels; miplevel++) { + const void *miptex = NULL; + unsigned long miptexlen = 0; + unsigned int mipW = 0, mipH = 0; + retval = MOJODDS_getMipMapTexture(miplevel, glfmt, tex, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH); + if (!retval) { + printf("MOJODDS_getMipMapTexture(%u) error: %d\n", miplevel, retval); + continue; + } + + if (isCompressed) { + glCompressedTexImage2D(GL_TEXTURE_2D, miplevel, glfmt, mipW, mipH, 0, miptexlen, miptex); + } else { + glTexImage2D(GL_TEXTURE_2D, miplevel, internalFormat, mipW, mipH, 0, glfmt, GL_UNSIGNED_BYTE, miptex); + } + } + + // and now the same with ARB_texture_storage if it's available + if (GLEW_ARB_texture_storage) { + glGenTextures(1, &texId); + glBindTexture(GL_TEXTURE_2D, texId); + glTexStorage2D(GL_TEXTURE_2D, miplevels, internalFormat, w, h); + + for (unsigned int miplevel = 0; miplevel < miplevels; miplevel++) { + const void *miptex = NULL; + unsigned long miptexlen = 0; + unsigned int mipW = 0, mipH = 0; + retval = MOJODDS_getMipMapTexture(miplevel, glfmt, tex, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH); + if (!retval) { + printf("MOJODDS_getMipMapTexture(%u) error: %d\n", miplevel, retval); + continue; + } + + if (isCompressed) { + glCompressedTexSubImage2D(GL_TEXTURE_2D, miplevel, 0, 0, mipW, mipH, glfmt, miptexlen, miptex); + } else { + glTexSubImage2D(GL_TEXTURE_2D, miplevel, 0, 0, mipW, mipH, glfmt, GL_UNSIGNED_BYTE, miptex); + } + } + } + + // one last clear and swap for clean trace end + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + SDL_GL_SwapWindow(window); + + SDL_GL_DeleteContext(context); + SDL_DestroyWindow(window); + } + + free(contents); + + return 0; +} From b3f9b4648c9151a676b4c629316ae124597b2d54 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Wed, 29 Apr 2015 15:56:10 +0300 Subject: [PATCH 07/46] Show GL errors in standard out --- glddstest.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/glddstest.c b/glddstest.c index 4c86ded..bd925b5 100644 --- a/glddstest.c +++ b/glddstest.c @@ -16,6 +16,26 @@ // use apitrace, vogl or similar tool to see what it does +static void pumpGLErrors() { + GLenum err; + while ((err = glGetError()) != GL_NO_ERROR) { + switch (err) { + case GL_INVALID_ENUM: + printf("GL error GL_INVALID_ENUM\n"); + break; + + case GL_INVALID_VALUE: + printf("GL error GL_INVALID_VALUE\n"); + break; + + default: + printf("Unknown GL error %04x\n", err); + break; + } + } +} + + int main(int argc, char *argv[]) { if (argc != 2) { printf("Usage: %s DDS-file\n", argv[0]); @@ -113,6 +133,7 @@ int main(int argc, char *argv[]) { } else { glTexImage2D(GL_TEXTURE_2D, miplevel, internalFormat, mipW, mipH, 0, glfmt, GL_UNSIGNED_BYTE, miptex); } + pumpGLErrors(); } // and now the same with ARB_texture_storage if it's available @@ -120,6 +141,7 @@ int main(int argc, char *argv[]) { glGenTextures(1, &texId); glBindTexture(GL_TEXTURE_2D, texId); glTexStorage2D(GL_TEXTURE_2D, miplevels, internalFormat, w, h); + pumpGLErrors(); for (unsigned int miplevel = 0; miplevel < miplevels; miplevel++) { const void *miptex = NULL; @@ -136,6 +158,7 @@ int main(int argc, char *argv[]) { } else { glTexSubImage2D(GL_TEXTURE_2D, miplevel, 0, 0, mipW, mipH, glfmt, GL_UNSIGNED_BYTE, miptex); } + pumpGLErrors(); } } From 17ace64713fa506c6ee985f0cc984bf19d652d55 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Wed, 29 Apr 2015 16:07:00 +0300 Subject: [PATCH 08/46] More informative error messages --- glddstest.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/glddstest.c b/glddstest.c index bd925b5..ddc8478 100644 --- a/glddstest.c +++ b/glddstest.c @@ -1,3 +1,5 @@ +#define _GNU_SOURCE + #include #include #include @@ -16,23 +18,34 @@ // use apitrace, vogl or similar tool to see what it does -static void pumpGLErrors() { +static void pumpGLErrors(const char *format, ...) { + va_list args; + + va_start(args, format); + + char *tempStr = NULL; + vasprintf(&tempStr, format, args); + + va_end(args); + GLenum err; while ((err = glGetError()) != GL_NO_ERROR) { switch (err) { case GL_INVALID_ENUM: - printf("GL error GL_INVALID_ENUM\n"); + printf("GL error GL_INVALID_ENUM in \"%s\"\n", tempStr); break; case GL_INVALID_VALUE: - printf("GL error GL_INVALID_VALUE\n"); + printf("GL error GL_INVALID_VALUE in \"%s\"\n", tempStr); break; default: - printf("Unknown GL error %04x\n", err); + printf("Unknown GL error %04x in \"%s\"\n", err, tempStr); break; } } + + free(tempStr); } @@ -130,10 +143,11 @@ int main(int argc, char *argv[]) { if (isCompressed) { glCompressedTexImage2D(GL_TEXTURE_2D, miplevel, glfmt, mipW, mipH, 0, miptexlen, miptex); + pumpGLErrors("glCompressedTexImage2D %u 0x%04x %ux%u %u", miplevel, glfmt, mipW, mipH, miptexlen); } else { glTexImage2D(GL_TEXTURE_2D, miplevel, internalFormat, mipW, mipH, 0, glfmt, GL_UNSIGNED_BYTE, miptex); + pumpGLErrors("glTexImage2D %u 0x%04x %ux%u 0x%04x", miplevel, internalFormat, mipW, mipH, glfmt); } - pumpGLErrors(); } // and now the same with ARB_texture_storage if it's available @@ -141,7 +155,7 @@ int main(int argc, char *argv[]) { glGenTextures(1, &texId); glBindTexture(GL_TEXTURE_2D, texId); glTexStorage2D(GL_TEXTURE_2D, miplevels, internalFormat, w, h); - pumpGLErrors(); + pumpGLErrors("glTexStorage2D %u 0x%04x %ux%u", miplevels, internalFormat, w, h); for (unsigned int miplevel = 0; miplevel < miplevels; miplevel++) { const void *miptex = NULL; @@ -155,10 +169,11 @@ int main(int argc, char *argv[]) { if (isCompressed) { glCompressedTexSubImage2D(GL_TEXTURE_2D, 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_2D, miplevel, 0, 0, mipW, mipH, glfmt, GL_UNSIGNED_BYTE, miptex); + pumpGLErrors("glTexSubImage2D %u %ux%u 0x%04x", miplevel, mipW, mipH, glfmt); } - pumpGLErrors(); } } From 68c8cbaa0718aa405eb2c66dba137cee60494a4c Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 30 Apr 2015 12:43:19 +0300 Subject: [PATCH 09/46] Fix non-POW2 compressed formats --- mojodds.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/mojodds.c b/mojodds.c index 9900242..d765c76 100644 --- a/mojodds.c +++ b/mojodds.c @@ -298,6 +298,12 @@ int MOJODDS_getMipMapTexture(unsigned int miplevel, unsigned int glfmt, unsigned long newtexlen; unsigned int neww; unsigned int newh; + unsigned int blocksize = 16; + + if (glfmt == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) + { + blocksize = 8; + } newtex = _basetex; newtexlen = _basetexlen; @@ -310,20 +316,11 @@ int MOJODDS_getMipMapTexture(unsigned int miplevel, unsigned int glfmt, // move position to next texture start newtex += newtexlen; // calculate texture size - newtexlen >>= 2; neww >>= 1; newh >>= 1; if (neww < 1) neww = 1; if (newh < 1) newh = 1; - switch (glfmt) { - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - if (newtexlen < 8) newtexlen = 8; - break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - if (newtexlen < 16) newtexlen = 16; - break; - } // switch + newtexlen = ((neww + 3) / 4) * ((newh + 3) / 4) * blocksize; } // for *_tex = newtex; From 8a4feaf3c01c5cc372175aff0ce941cbd67ce5fd Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 30 Apr 2015 13:08:44 +0300 Subject: [PATCH 10/46] Store filename in a helper variable --- ddsinfo.c | 5 +++-- glddstest.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ddsinfo.c b/ddsinfo.c index bd18b3d..f78819b 100644 --- a/ddsinfo.c +++ b/ddsinfo.c @@ -20,9 +20,10 @@ int main(int argc, char *argv[]) { return 0; } - FILE *f = fopen(argv[1], "rb"); + const char *filename = argv[1]; + FILE *f = fopen(filename, "rb"); if (!f) { - printf("Error opening %s: %s (%d)\n", argv[1], strerror(errno), errno); + printf("Error opening %s: %s (%d)\n", filename, strerror(errno), errno); return 1; } diff --git a/glddstest.c b/glddstest.c index ddc8478..f85c25b 100644 --- a/glddstest.c +++ b/glddstest.c @@ -55,9 +55,10 @@ int main(int argc, char *argv[]) { return 0; } - FILE *f = fopen(argv[1], "rb"); + const char *filename = argv[1]; + FILE *f = fopen(filename, "rb"); if (!f) { - printf("Error opening %s: %s (%d)\n", argv[1], strerror(errno), errno); + printf("Error opening %s: %s (%d)\n", filename, strerror(errno), errno); return 1; } From 497bd61b0610e22fa0caa6d06b5202ba26102d40 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 30 Apr 2015 13:09:56 +0300 Subject: [PATCH 11/46] Refactor ddsinfo by moving all interesting bits to a helper function --- ddsinfo.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/ddsinfo.c b/ddsinfo.c index f78819b..c7b5361 100644 --- a/ddsinfo.c +++ b/ddsinfo.c @@ -14,13 +14,7 @@ static bool isPow2(unsigned int v) { } -int main(int argc, char *argv[]) { - if (argc != 2) { - printf("Usage: %s DDS-file\n", argv[0]); - return 0; - } - - const char *filename = argv[1]; +static int ddsinfo(const char *filename) { FILE *f = fopen(filename, "rb"); if (!f) { printf("Error opening %s: %s (%d)\n", filename, strerror(errno), errno); @@ -83,3 +77,14 @@ int main(int argc, char *argv[]) { return 0; } + + +int main(int argc, char *argv[]) { + if (argc != 2) { + printf("Usage: %s DDS-file\n", argv[0]); + return 0; + } + + const char *filename = argv[1]; + return ddsinfo(filename); +} From ef72de30a9a0dae40b0769df5e40eb4c5874c576 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 30 Apr 2015 13:14:26 +0300 Subject: [PATCH 12/46] Refactor glddstest by moving OpenGL initialization earlier --- glddstest.c | 58 ++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/glddstest.c b/glddstest.c index f85c25b..f8a22d5 100644 --- a/glddstest.c +++ b/glddstest.c @@ -55,36 +55,10 @@ int main(int argc, char *argv[]) { return 0; } - const char *filename = argv[1]; - FILE *f = fopen(filename, "rb"); - if (!f) { - printf("Error opening %s: %s (%d)\n", filename, strerror(errno), errno); - return 1; - } - - fseek(f, 0, SEEK_END); - long size = ftell(f); - fseek(f, 0, SEEK_SET); - - char *contents = malloc(size); - size_t readbytes = fread(contents, 1, size, f); - if (readbytes != size) { - printf("Only got %u of %ld bytes: %s\n", (unsigned int) readbytes, size, strerror(errno)); - free(contents); - fclose(f); - return 2; - } - - fclose(f); - - int isDDS = MOJODDS_isDDS(contents, size); - printf("isDDS: %d\n", isDDS); - if (isDDS) { SDL_Init(SDL_INIT_VIDEO); SDL_Window *window = SDL_CreateWindow("OpenGL DDS test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 0, 0, SDL_WINDOW_OPENGL); if (window == NULL) { printf("Could not create window: %s\n", SDL_GetError()); - free(contents); return 3; } @@ -92,7 +66,6 @@ int main(int argc, char *argv[]) { if (context == NULL) { printf("Could not create GL context: %s\n", SDL_GetError()); SDL_DestroyWindow(window); - free(contents); return 4; } @@ -111,6 +84,31 @@ int main(int argc, char *argv[]) { GLenum err = GL_NO_ERROR; while ((err = glGetError()) != GL_NO_ERROR) { } + const char *filename = argv[1]; + FILE *f = fopen(filename, "rb"); + if (!f) { + printf("Error opening %s: %s (%d)\n", filename, strerror(errno), errno); + return 1; + } + + fseek(f, 0, SEEK_END); + long size = ftell(f); + fseek(f, 0, SEEK_SET); + + char *contents = malloc(size); + size_t readbytes = fread(contents, 1, size, f); + if (readbytes != size) { + printf("Only got %u of %ld bytes: %s\n", (unsigned int) readbytes, size, strerror(errno)); + free(contents); + fclose(f); + return 2; + } + + fclose(f); + + int isDDS = MOJODDS_isDDS(contents, size); + printf("isDDS: %d\n", isDDS); + if (isDDS) { const void *tex = NULL; unsigned long texlen = 0; unsigned int glfmt = 0, w = 0, h = 0, miplevels = 0; @@ -177,6 +175,9 @@ int main(int argc, char *argv[]) { } } } + } + + free(contents); // one last clear and swap for clean trace end glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -184,9 +185,6 @@ int main(int argc, char *argv[]) { SDL_GL_DeleteContext(context); SDL_DestroyWindow(window); - } - - free(contents); return 0; } From b9146c9daffd7c2a3ee6a4af8e85ee0aeedc3e66 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 30 Apr 2015 13:20:32 +0300 Subject: [PATCH 13/46] Move glddstest interesting bits to a helper function --- glddstest.c | 81 +++++++++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 37 deletions(-) diff --git a/glddstest.c b/glddstest.c index f8a22d5..c70bdd0 100644 --- a/glddstest.c +++ b/glddstest.c @@ -49,42 +49,7 @@ static void pumpGLErrors(const char *format, ...) { } -int main(int argc, char *argv[]) { - if (argc != 2) { - printf("Usage: %s DDS-file\n", argv[0]); - return 0; - } - - SDL_Init(SDL_INIT_VIDEO); - SDL_Window *window = SDL_CreateWindow("OpenGL DDS test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 0, 0, SDL_WINDOW_OPENGL); - if (window == NULL) { - printf("Could not create window: %s\n", SDL_GetError()); - return 3; - } - - SDL_GLContext context = SDL_GL_CreateContext(window); - if (context == NULL) { - printf("Could not create GL context: %s\n", SDL_GetError()); - SDL_DestroyWindow(window); - return 4; - } - - // clear and swap to get better traces - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - SDL_GL_SwapWindow(window); - - glewInit(); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - SDL_GL_SwapWindow(window); - - // glewInit might raise errors if we got an OpenGL 3.0 context - // ignore them - // in this case glGetError is simpler than fooling around with callbacks - GLenum err = GL_NO_ERROR; - while ((err = glGetError()) != GL_NO_ERROR) { } - - const char *filename = argv[1]; +static int glddstest(const char *filename) { FILE *f = fopen(filename, "rb"); if (!f) { printf("Error opening %s: %s (%d)\n", filename, strerror(errno), errno); @@ -179,6 +144,48 @@ int main(int argc, char *argv[]) { free(contents); + return 0; +} + + +int main(int argc, char *argv[]) { + if (argc != 2) { + printf("Usage: %s DDS-file\n", argv[0]); + return 0; + } + + SDL_Init(SDL_INIT_VIDEO); + SDL_Window *window = SDL_CreateWindow("OpenGL DDS test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 0, 0, SDL_WINDOW_OPENGL); + if (window == NULL) { + printf("Could not create window: %s\n", SDL_GetError()); + return 3; + } + + SDL_GLContext context = SDL_GL_CreateContext(window); + if (context == NULL) { + printf("Could not create GL context: %s\n", SDL_GetError()); + SDL_DestroyWindow(window); + return 4; + } + + // clear and swap to get better traces + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + SDL_GL_SwapWindow(window); + + glewInit(); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + SDL_GL_SwapWindow(window); + + // glewInit might raise errors if we got an OpenGL 3.0 context + // ignore them + // in this case glGetError is simpler than fooling around with callbacks + GLenum err = GL_NO_ERROR; + while ((err = glGetError()) != GL_NO_ERROR) { } + + const char *filename = argv[1]; + int retval = glddstest(filename); + // one last clear and swap for clean trace end glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); SDL_GL_SwapWindow(window); @@ -186,5 +193,5 @@ int main(int argc, char *argv[]) { SDL_GL_DeleteContext(context); SDL_DestroyWindow(window); - return 0; + return retval; } From 5f742bd6074bf3f682c139f9c1e625c8707edd79 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 30 Apr 2015 13:32:15 +0300 Subject: [PATCH 14/46] Support multiple files at once --- ddsinfo.c | 13 +++++++++---- glddstest.c | 16 ++++++++++------ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/ddsinfo.c b/ddsinfo.c index c7b5361..5e4aeb2 100644 --- a/ddsinfo.c +++ b/ddsinfo.c @@ -15,6 +15,8 @@ static bool isPow2(unsigned int v) { static int ddsinfo(const char *filename) { + printf("%s\n", filename); + FILE *f = fopen(filename, "rb"); if (!f) { printf("Error opening %s: %s (%d)\n", filename, strerror(errno), errno); @@ -80,11 +82,14 @@ static int ddsinfo(const char *filename) { int main(int argc, char *argv[]) { - if (argc != 2) { - printf("Usage: %s DDS-file\n", argv[0]); + if (argc < 2) { + printf("Usage: %s DDS-file ...\n", argv[0]); return 0; } - const char *filename = argv[1]; - return ddsinfo(filename); + for (int i = 1; i < argc; i++) { + ddsinfo(argv[i]); + } + + return 0; } diff --git a/glddstest.c b/glddstest.c index c70bdd0..6257a5a 100644 --- a/glddstest.c +++ b/glddstest.c @@ -50,6 +50,8 @@ static void pumpGLErrors(const char *format, ...) { static int glddstest(const char *filename) { + printf("%s\n", filename); + FILE *f = fopen(filename, "rb"); if (!f) { printf("Error opening %s: %s (%d)\n", filename, strerror(errno), errno); @@ -149,8 +151,8 @@ static int glddstest(const char *filename) { int main(int argc, char *argv[]) { - if (argc != 2) { - printf("Usage: %s DDS-file\n", argv[0]); + if (argc < 2) { + printf("Usage: %s DDS-file ...\n", argv[0]); return 0; } @@ -183,15 +185,17 @@ int main(int argc, char *argv[]) { GLenum err = GL_NO_ERROR; while ((err = glGetError()) != GL_NO_ERROR) { } - const char *filename = argv[1]; - int retval = glddstest(filename); + for (int i = 1; i < argc; i++) { + glddstest(argv[i]); + // clear and swap to make trace easier to parse - // one last clear and swap for clean trace end glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); SDL_GL_SwapWindow(window); + } + SDL_GL_DeleteContext(context); SDL_DestroyWindow(window); - return retval; + return 0; } From 3d36db00a9862427f606669caf94593a7fd5240a Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 30 Apr 2015 13:50:08 +0300 Subject: [PATCH 15/46] Check MOJODDS_getTexture return value and error out if it fails --- ddsinfo.c | 6 +++++- glddstest.c | 9 ++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ddsinfo.c b/ddsinfo.c index 5e4aeb2..6803ac9 100644 --- a/ddsinfo.c +++ b/ddsinfo.c @@ -47,9 +47,13 @@ static int ddsinfo(const char *filename) { unsigned int cubemapfacelen = 0; MOJODDS_textureType textureType = MOJODDS_TEXTURE_NONE; int retval = MOJODDS_getTexture(contents, size, &tex, &texlen, &glfmt, &w, &h, &miplevels, &cubemapfacelen, &textureType); + if (!retval) { + printf("MOJODDS_getTexture failed\n"); + free(contents); + return 3; + } uintptr_t texoffset = ((const char *)(tex)) - contents; - printf("MOJODDS_getTexture retval: %d\n", retval); printf("texoffset: %u\n", (unsigned int)(texoffset)); printf("texlen: %lu\n", texlen); printf("glfmt: 0x%x\n", glfmt); diff --git a/glddstest.c b/glddstest.c index 6257a5a..c0becc2 100644 --- a/glddstest.c +++ b/glddstest.c @@ -79,7 +79,14 @@ static int glddstest(const char *filename) { const void *tex = NULL; unsigned long texlen = 0; unsigned int glfmt = 0, w = 0, h = 0, miplevels = 0; - int retval = MOJODDS_getTexture(contents, size, &tex, &texlen, &glfmt, &w, &h, &miplevels); + unsigned int cubemapfacelen = 0; + MOJODDS_textureType textureType = MOJODDS_TEXTURE_NONE; + int retval = MOJODDS_getTexture(contents, size, &tex, &texlen, &glfmt, &w, &h, &miplevels, &cubemapfacelen, &textureType); + if (!retval) { + printf("MOJODDS_getTexture failed\n"); + free(contents); + return 3; + } bool isCompressed = true; GLenum internalFormat = glfmt; From 7875fb68070389de86311a5ebb0876909fe49688 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 30 Apr 2015 13:50:50 +0300 Subject: [PATCH 16/46] Add sanity check for miplevels Found with AFL --- mojodds.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mojodds.c b/mojodds.c index ff2949a..891e5da 100644 --- a/mojodds.c +++ b/mojodds.c @@ -183,6 +183,13 @@ static int parse_dds(MOJODDS_Header *header, const uint8 **ptr, size_t *len, *_miplevels = (header->dwCaps & DDSCAPS_MIPMAP) ? header->dwMipMapCount : 1; + if (*_miplevels > 32) + { + // too many mip levels, width and height would be larger than 32-bit int + // file is corrupted + return 0; + } + if (header->ddspf.dwFlags & DDPF_FOURCC) { switch (header->ddspf.dwFourCC) From b39b6570c881d32b41eda97e76a1b13c3fbdc3bc Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 30 Apr 2015 14:10:46 +0300 Subject: [PATCH 17/46] Add AFL helper program --- .gitignore | 1 + Makefile | 6 +++- afl-mojodds.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 afl-mojodds.c diff --git a/.gitignore b/.gitignore index 24680e2..b59e2c4 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ *.trace ddsinfo glddstest +afl-mojodds diff --git a/Makefile b/Makefile index 9e3a02a..d09ac14 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ LDLIBS+=$(shell pkg-config glew --libs) .SUFFIXES: .o -PROGRAMS:=ddsinfo glddstest +PROGRAMS:=ddsinfo glddstest afl-mojodds .PHONY: all clean @@ -28,3 +28,7 @@ ddsinfo: ddsinfo.o mojodds.o glddstest: glddstest.o mojodds.o $(CC) -o $@ $^ $(LDLIBS) + + +afl-mojodds: afl-mojodds.o mojodds.o + $(CC) -o $@ $^ diff --git a/afl-mojodds.c b/afl-mojodds.c new file mode 100644 index 0000000..becd3e7 --- /dev/null +++ b/afl-mojodds.c @@ -0,0 +1,79 @@ +#include +#include +#include +#include +#include +#include + +#include "mojodds.h" + + +// helper for fuzzing with AFL +// if you don't know what this is you don't need it + + +int main(int argc, char *argv[]) { + if (argc != 2) { + return 0; + } + + const char *filename = argv[1]; + + FILE *f = fopen(filename, "rb"); + if (!f) { + return 1; + } + + fseek(f, 0, SEEK_END); + long size = ftell(f); + fseek(f, 0, SEEK_SET); + + char *contents = malloc(size); + size_t readbytes = fread(contents, 1, size, f); + if (readbytes != size) { + free(contents); + fclose(f); + return 2; + } + + fclose(f); + + int isDDS = MOJODDS_isDDS(contents, size); + if (!isDDS) { + return 3; + } + + const void *tex = NULL; + unsigned long texlen = 0; + unsigned int glfmt = 0, w = 0, h = 0, miplevels = 0; + unsigned int cubemapfacelen = 0; + MOJODDS_textureType textureType = MOJODDS_TEXTURE_NONE; + int retval = MOJODDS_getTexture(contents, size, &tex, &texlen, &glfmt, &w, &h, &miplevels, &cubemapfacelen, &textureType); + if (!retval) { + free(contents); + return 4; + } + + uint32_t hash = 0x12345678; + for (unsigned int miplevel = 0; miplevel < miplevels; miplevel++) { + const void *miptex = NULL; + unsigned long miptexlen = 0; + unsigned int mipW = 0, mipH = 0; + retval = MOJODDS_getMipMapTexture(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]; + } + } + // do something the optimizer is not allowed to remove + printf("0x%08x\n", hash); + + free(contents); + + return 0; +} From df876b58636055b6303944e736487d96a6dfd22e Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 30 Apr 2015 14:51:13 +0300 Subject: [PATCH 18/46] Fix incorrect printf format strings --- ddsinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ddsinfo.c b/ddsinfo.c index 6803ac9..196b920 100644 --- a/ddsinfo.c +++ b/ddsinfo.c @@ -57,7 +57,7 @@ static int ddsinfo(const char *filename) { printf("texoffset: %u\n", (unsigned int)(texoffset)); printf("texlen: %lu\n", texlen); printf("glfmt: 0x%x\n", glfmt); - printf("width x height: %d x %d\n", w, h); + printf("width x height: %u x %u\n", w, h); printf("miplevels: %d\n", miplevels); printf("\n"); @@ -73,7 +73,7 @@ static int ddsinfo(const char *filename) { uintptr_t miptexoffset = ((const char *)(miptex)) - ((const char *)(tex)); bool npot = !(isPow2(mipW) || isPow2(mipH)); - printf("%4d x %4d %s", mipW, mipH, npot ? "NPOT " : " "); + printf("%4u x %4u %s", mipW, mipH, npot ? "NPOT " : " "); printf("miptexoffset: %8u ", (unsigned int)(miptexoffset)); printf("miptexlen: %8lu\n", miptexlen); } From f8b13ca28c980b968d6ceee44805037e80f724ce Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 30 Apr 2015 14:51:43 +0300 Subject: [PATCH 19/46] Check the file contains enough data if the header claims it does Found with AFL --- mojodds.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/mojodds.c b/mojodds.c index 891e5da..e730080 100644 --- a/mojodds.c +++ b/mojodds.c @@ -314,6 +314,24 @@ static int parse_dds(MOJODDS_Header *header, const uint8 **ptr, size_t *len, ht >>= 1; } } + else if (*_textureType == MOJODDS_TEXTURE_2D) + { + // check that file contains enough data like the header says + // TODO: also do this for other texture types + uint32 wd = header->dwWidth; + uint32 ht = header->dwHeight; + uint32 dataLen = 0; + for (i = 0; i < (int)*_miplevels; i++) + { + dataLen += MAX((wd + blockDim - 1) / blockDim, 1) * MAX((ht + blockDim - 1) / blockDim, 1) * blockSize; + wd >>= 1; + ht >>= 1; + } + + if (*len < dataLen) { + return 0; + } + } return 1; } // parse_dds From a72b41434ee6fe95cb8d4f237ba8bc7997db068b Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 30 Apr 2015 15:05:07 +0300 Subject: [PATCH 20/46] Fix crash when width * height would overflow uint32 Found with AFL --- mojodds.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mojodds.c b/mojodds.c index e730080..4019091 100644 --- a/mojodds.c +++ b/mojodds.c @@ -168,6 +168,12 @@ static int parse_dds(MOJODDS_Header *header, const uint8 **ptr, size_t *len, width = header->dwWidth; height = header->dwHeight; + // check for overflow in width * height + if (height > 0xFFFFFFFFU / width) + { + return 0; + } + header->dwCaps &= ~DDSCAPS_ALPHA; // we'll get this from the pixel format. if (header->dwSize != DDS_HEADERSIZE) // header size must be 124. From e84d41fc485f94b4e01e9e49a1a3010238e73a5a Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 30 Apr 2015 15:18:22 +0300 Subject: [PATCH 21/46] Fix crash when dwPitchOrLinearSize is incorrect --- mojodds.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mojodds.c b/mojodds.c index 4019091..9787667 100644 --- a/mojodds.c +++ b/mojodds.c @@ -339,6 +339,11 @@ static int parse_dds(MOJODDS_Header *header, const uint8 **ptr, size_t *len, } } + if (header->dwPitchOrLinearSize > *len) { + // dwPitchOrLinearSize is incorrect + return 0; + } + return 1; } // parse_dds From a097f058b554965163eea07c10e98dcdec7b4c85 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 30 Apr 2015 15:29:54 +0300 Subject: [PATCH 22/46] Fix division by zero --- mojodds.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mojodds.c b/mojodds.c index 9787667..593f281 100644 --- a/mojodds.c +++ b/mojodds.c @@ -168,6 +168,11 @@ static int parse_dds(MOJODDS_Header *header, const uint8 **ptr, size_t *len, width = header->dwWidth; height = header->dwHeight; + if (width == 0 || height == 0) + { + return 0; + } + // check for overflow in width * height if (height > 0xFFFFFFFFU / width) { From 88da12b12870da58cb9d8d3cb37d082a0e46efec Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 30 Apr 2015 15:45:14 +0300 Subject: [PATCH 23/46] Fix mip size calculation for uncompressed textures --- mojodds.c | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/mojodds.c b/mojodds.c index 593f281..173cf44 100644 --- a/mojodds.c +++ b/mojodds.c @@ -396,13 +396,40 @@ int MOJODDS_getMipMapTexture(unsigned int miplevel, unsigned int glfmt, unsigned long newtexlen; unsigned int neww; unsigned int newh; - unsigned int blocksize = 16; + uint32 blockDim = 1; + uint32 blockSize = 0; - if (glfmt == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) - { - blocksize = 8; + switch (glfmt) { + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + blockDim = 4; + blockSize = 8; + break; + + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + blockDim = 4; + blockSize = 16; + break; + + case GL_BGR: + blockSize = 3; + break; + + case GL_BGRA: + blockSize = 4; + break; + + case GL_LUMINANCE_ALPHA: + blockSize = 2; + break; + + default: + assert(!"unsupported GL format"); + break; } + assert(blockSize != 0); + newtex = _basetex; newtexlen = _basetexlen; neww = w; @@ -418,7 +445,7 @@ int MOJODDS_getMipMapTexture(unsigned int miplevel, unsigned int glfmt, newh >>= 1; if (neww < 1) neww = 1; if (newh < 1) newh = 1; - newtexlen = ((neww + 3) / 4) * ((newh + 3) / 4) * blocksize; + newtexlen = ((neww + blockDim - 1) / blockDim) * ((newh + blockDim - 1) / blockDim) * blockSize; } // for *_tex = newtex; From ec966a6c6b76f522e48e0b0a6b367437bd6f5bcd Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 30 Apr 2015 15:49:27 +0300 Subject: [PATCH 24/46] Also verify calculated size against data size --- mojodds.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mojodds.c b/mojodds.c index 173cf44..e2ce78d 100644 --- a/mojodds.c +++ b/mojodds.c @@ -349,6 +349,12 @@ static int parse_dds(MOJODDS_Header *header, const uint8 **ptr, size_t *len, return 0; } + if (calcSize > *len) { + // there's not enough data to contain the advertised images + // trying to read mips would fail + return 0; + } + return 1; } // parse_dds From 94b207260c78d2daf8aa4e3f35c0a5cb4ef78091 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 30 Apr 2015 16:17:19 +0300 Subject: [PATCH 25/46] Set blockSize when reading luminance-alpha format --- mojodds.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mojodds.c b/mojodds.c index e2ce78d..17bfd55 100644 --- a/mojodds.c +++ b/mojodds.c @@ -269,6 +269,7 @@ static int parse_dds(MOJODDS_Header *header, const uint8 **ptr, size_t *len, *_glfmt = GL_LUMINANCE_ALPHA; calcSizeFlag = DDSD_PITCH; + blockSize = 2; calcSize = ((width * header->ddspf.dwRGBBitCount) + 7) / 8; } From 2724eceda7992103ae65c4f6d05c8b3e91044f66 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 30 Apr 2015 16:17:46 +0300 Subject: [PATCH 26/46] Print textureType --- ddsinfo.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/ddsinfo.c b/ddsinfo.c index 196b920..b8adbcc 100644 --- a/ddsinfo.c +++ b/ddsinfo.c @@ -59,6 +59,26 @@ static int ddsinfo(const char *filename) { printf("glfmt: 0x%x\n", glfmt); printf("width x height: %u x %u\n", w, h); printf("miplevels: %d\n", miplevels); + printf("textureType: "); + switch (textureType) { + case MOJODDS_TEXTURE_NONE: + printf("none (bug?)\n"); + return 4; + break; + + 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++) { From 95c76f597c52853e0e7cf8318eeade300e247cff Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 30 Apr 2015 16:38:28 +0300 Subject: [PATCH 27/46] Cube maps must be square --- mojodds.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mojodds.c b/mojodds.c index 17bfd55..0694132 100644 --- a/mojodds.c +++ b/mojodds.c @@ -318,6 +318,11 @@ static int parse_dds(MOJODDS_Header *header, const uint8 **ptr, size_t *len, { uint32 wd = header->dwWidth; uint32 ht = header->dwHeight; + if (wd != ht) + { + // cube maps must be square + return 0; + } *_cubemapfacelen = 0; for (i = 0; i < (int)*_miplevels; i++) { From 891984e9db3dfdf45155e6b4220b218b9e50f9dd Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 30 Apr 2015 17:02:52 +0300 Subject: [PATCH 28/46] Fix LDFLAGS support in Makefile --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index d09ac14..c771bf5 100644 --- a/Makefile +++ b/Makefile @@ -23,12 +23,12 @@ clean: ddsinfo: ddsinfo.o mojodds.o - $(CC) -o $@ $^ + $(CC) $(LDFLAGS) -o $@ $^ glddstest: glddstest.o mojodds.o - $(CC) -o $@ $^ $(LDLIBS) + $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) afl-mojodds: afl-mojodds.o mojodds.o - $(CC) -o $@ $^ + $(CC) $(LDFLAGS) -o $@ $^ From 8b0dc7cd82f349d3fb6a990a3d91213719d90133 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Fri, 8 May 2015 15:40:13 +0300 Subject: [PATCH 29/46] Add support for fetching specific cube map faces --- afl-mojodds.c | 34 ++++++++++++++++++++++++ ddsinfo.c | 40 +++++++++++++++++++++-------- glddstest.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++ mojodds.c | 16 ++++++++++++ mojodds.h | 20 +++++++++++++++ 5 files changed, 170 insertions(+), 11 deletions(-) diff --git a/afl-mojodds.c b/afl-mojodds.c index becd3e7..a8df382 100644 --- a/afl-mojodds.c +++ b/afl-mojodds.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -55,6 +56,12 @@ int main(int argc, char *argv[]) { } 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 @@ int main(int argc, char *argv[]) { 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); diff --git a/ddsinfo.c b/ddsinfo.c index b8adbcc..1ec37e9 100644 --- a/ddsinfo.c +++ b/ddsinfo.c @@ -68,17 +68,6 @@ static int ddsinfo(const char *filename) { 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++) { @@ -96,6 +85,35 @@ static int ddsinfo(const char *filename) { printf("%4u x %4u %s", mipW, mipH, npot ? "NPOT " : " "); 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; + } } diff --git a/glddstest.c b/glddstest.c index c0becc2..79051d7 100644 --- a/glddstest.c +++ b/glddstest.c @@ -1,5 +1,6 @@ #define _GNU_SOURCE +#include #include #include #include @@ -102,6 +103,13 @@ static int glddstest(const char *filename) { 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 @@ static int glddstest(const char *filename) { } } } + 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); diff --git a/mojodds.c b/mojodds.c index 0694132..1e2a322 100644 --- a/mojodds.c +++ b/mojodds.c @@ -470,5 +470,21 @@ int MOJODDS_getMipMapTexture(unsigned int miplevel, unsigned int glfmt, } // 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 ... diff --git a/mojodds.h b/mojodds.h index 14402d8..711426e 100644 --- a/mojodds.h +++ b/mojodds.h @@ -14,6 +14,19 @@ typedef enum MOJODDS_textureType 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 @@ int MOJODDS_getMipMapTexture(unsigned int miplevel, unsigned int glfmt, 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 From 834d76a4899e53a749844aa1a9fcc39fb6908069 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Fri, 8 May 2015 15:45:13 +0300 Subject: [PATCH 30/46] Fix ddsinfo --- ddsinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddsinfo.c b/ddsinfo.c index 1ec37e9..32c1f08 100644 --- a/ddsinfo.c +++ b/ddsinfo.c @@ -96,7 +96,7 @@ static int ddsinfo(const char *filename) { 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); + retval = MOJODDS_getCubeFace(MOJODDS_CUBEFACE_POSITIVE_X, miplevel, glfmt, tex, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH); if (!retval) { printf("MOJODDS_getMipMapTexture(%u) error: %d\n", miplevel, retval); continue; From 9b78a497d40eca1a97d58ce4b39c819b381cc8e2 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Sat, 9 May 2015 16:36:53 +0300 Subject: [PATCH 31/46] Add support for AFL manual init --- afl-mojodds.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/afl-mojodds.c b/afl-mojodds.c index a8df382..1f7e063 100644 --- a/afl-mojodds.c +++ b/afl-mojodds.c @@ -13,11 +13,18 @@ // if you don't know what this is you don't need it +void __afl_manual_init(void); + + int main(int argc, char *argv[]) { if (argc != 2) { return 0; } +#ifdef __AFL_HAVE_MANUAL_INIT + __afl_manual_init(); +#endif // __AFL_HAVE_MANUAL_INIT + const char *filename = argv[1]; FILE *f = fopen(filename, "rb"); From 2e4959c359bbbca6fe9dfbaf7ae782a1c5d406c2 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Sat, 9 May 2015 16:57:50 +0300 Subject: [PATCH 32/46] Add filename to GL trace by using GREMEDY_string_marker --- glddstest.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/glddstest.c b/glddstest.c index 79051d7..b9dec0e 100644 --- a/glddstest.c +++ b/glddstest.c @@ -51,7 +51,10 @@ static void pumpGLErrors(const char *format, ...) { static int glddstest(const char *filename) { - printf("%s\n", filename); + printf("%s\n", filename); + if (GLEW_GREMEDY_string_marker) { + glStringMarkerGREMEDY(0, filename); + } FILE *f = fopen(filename, "rb"); if (!f) { From fd717d5df1b0570b47cdc137d90d5498b5b63d8e Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Sat, 9 May 2015 16:47:00 +0300 Subject: [PATCH 33/46] Avoid integer overflow and resulting crash when advertised texture size is too large --- mojodds.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/mojodds.c b/mojodds.c index 1e2a322..c5e8124 100644 --- a/mojodds.c +++ b/mojodds.c @@ -337,10 +337,15 @@ static int parse_dds(MOJODDS_Header *header, const uint8 **ptr, size_t *len, // TODO: also do this for other texture types uint32 wd = header->dwWidth; uint32 ht = header->dwHeight; - uint32 dataLen = 0; + uint32_t dataLen = 0; for (i = 0; i < (int)*_miplevels; i++) { - dataLen += MAX((wd + blockDim - 1) / blockDim, 1) * MAX((ht + blockDim - 1) / blockDim, 1) * blockSize; + uint32_t mipLen = MAX((wd + blockDim - 1) / blockDim, 1) * MAX((ht + blockDim - 1) / blockDim, 1) * blockSize; + if (UINT32_MAX - mipLen < dataLen) { + // data size would overflow 32-bit uint, invalid file + return 0; + } + dataLen += mipLen; wd >>= 1; ht >>= 1; } From 7094db7a952a4eabd31094cad4b5a5c44195439e Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Sat, 9 May 2015 17:30:02 +0300 Subject: [PATCH 34/46] Calculate miplevels from size if header says zero --- mojodds.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/mojodds.c b/mojodds.c index c5e8124..6d69be5 100644 --- a/mojodds.c +++ b/mojodds.c @@ -104,6 +104,25 @@ typedef struct } MOJODDS_Header; +//http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn +static const uint32_t MultiplyDeBruijnBitPosition[32] = +{ + 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 +}; + + +static uint32_t uintLog2(uint32_t v) { + v |= v >> 1; // first round down to one less than a power of 2 + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + + return MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27]; +} + + static uint32 readui32(const uint8 **_ptr, size_t *_len) { uint32 retval = 0; @@ -194,12 +213,18 @@ static int parse_dds(MOJODDS_Header *header, const uint8 **ptr, size_t *len, *_miplevels = (header->dwCaps & DDSCAPS_MIPMAP) ? header->dwMipMapCount : 1; + unsigned int calculatedMipLevels = uintLog2(MAX(width, height)) + 1; if (*_miplevels > 32) { // too many mip levels, width and height would be larger than 32-bit int // file is corrupted return 0; } + else if (*_miplevels == 0) + { + // invalid, calculate it ourselves from size + *_miplevels = calculatedMipLevels; + } if (header->ddspf.dwFlags & DDPF_FOURCC) { From 63430b0c9263b41fb2691545cc662263d36a86b0 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Sat, 9 May 2015 17:43:08 +0300 Subject: [PATCH 35/46] Also calculate mip level 0 size from width and height instead of trusting the header --- mojodds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mojodds.c b/mojodds.c index 6d69be5..ffbed55 100644 --- a/mojodds.c +++ b/mojodds.c @@ -473,9 +473,9 @@ int MOJODDS_getMipMapTexture(unsigned int miplevel, unsigned int glfmt, assert(blockSize != 0); newtex = _basetex; - newtexlen = _basetexlen; neww = w; newh = h; + newtexlen = ((neww + blockDim - 1) / blockDim) * ((newh + blockDim - 1) / blockDim) * blockSize; // Calculate size of miplevel for (i=0; i < miplevel; ++i) From e5a4ec314c20951944cf7a83f471e7f1786d003c Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Sat, 9 May 2015 17:54:16 +0300 Subject: [PATCH 36/46] Improve invalid miplevels calculation to too many mips relative to size --- mojodds.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mojodds.c b/mojodds.c index ffbed55..524bca6 100644 --- a/mojodds.c +++ b/mojodds.c @@ -214,17 +214,17 @@ static int parse_dds(MOJODDS_Header *header, const uint8 **ptr, size_t *len, *_miplevels = (header->dwCaps & DDSCAPS_MIPMAP) ? header->dwMipMapCount : 1; unsigned int calculatedMipLevels = uintLog2(MAX(width, height)) + 1; - if (*_miplevels > 32) - { - // too many mip levels, width and height would be larger than 32-bit int - // file is corrupted - return 0; - } - else if (*_miplevels == 0) + if (*_miplevels == 0) { // invalid, calculate it ourselves from size *_miplevels = calculatedMipLevels; } + else if (*_miplevels > calculatedMipLevels) + { + // too many mip levels, several would be 1x1 + // file is corrupted + return 0; + } if (header->ddspf.dwFlags & DDPF_FOURCC) { From 942bc98275460d074ec6b46a689925b233ded260 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Sat, 9 May 2015 17:57:24 +0300 Subject: [PATCH 37/46] GL_LUMINANCE_ALPHA is not a compressed format --- glddstest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glddstest.c b/glddstest.c index b9dec0e..6173dc1 100644 --- a/glddstest.c +++ b/glddstest.c @@ -94,7 +94,7 @@ static int glddstest(const char *filename) { bool isCompressed = true; GLenum internalFormat = glfmt; - if (glfmt == GL_BGRA || glfmt == GL_BGR) { + if (glfmt == GL_BGRA || glfmt == GL_BGR || glfmt == GL_LUMINANCE_ALPHA) { isCompressed = false; if (glfmt == GL_BGR) { internalFormat = GL_RGB8; From abd77b461fedac8c7413159d124fe2c290344f7f Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Sat, 9 May 2015 19:43:24 +0300 Subject: [PATCH 38/46] Validate cube map size --- mojodds.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/mojodds.c b/mojodds.c index 524bca6..64b6938 100644 --- a/mojodds.c +++ b/mojodds.c @@ -351,10 +351,20 @@ static int parse_dds(MOJODDS_Header *header, const uint8 **ptr, size_t *len, *_cubemapfacelen = 0; for (i = 0; i < (int)*_miplevels; i++) { - *_cubemapfacelen += ((MAX( wd, blockDim ) / blockDim) * (MAX( ht, blockDim ) / blockDim)) * blockSize; + uint32_t mipLen = MAX((wd + blockDim - 1) / blockDim, 1) * MAX((ht + blockDim - 1) / blockDim, 1) * blockSize; + if (UINT32_MAX - mipLen < *_cubemapfacelen) { + // data size would overflow 32-bit uint, invalid file + return 0; + } + *_cubemapfacelen += mipLen; wd >>= 1; ht >>= 1; } + + // 6 because cube faces + if (*len < (*_cubemapfacelen) * 6) { + return 0; + } } else if (*_textureType == MOJODDS_TEXTURE_2D) { From 22ab4b68a7b93b0544eac20971d116066bee9915 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Sat, 9 May 2015 19:52:46 +0300 Subject: [PATCH 39/46] Respect OpenGL maximum texture size --- glddstest.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/glddstest.c b/glddstest.c index 6173dc1..f2b6bac 100644 --- a/glddstest.c +++ b/glddstest.c @@ -92,6 +92,13 @@ static int glddstest(const char *filename) { return 3; } + GLint maxTexSize = 0; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize); + if (w > maxTexSize || h > maxTexSize) { + printf("Texture too large: %ux%u vs %d\n", w, h, maxTexSize); + return 4; + } + bool isCompressed = true; GLenum internalFormat = glfmt; if (glfmt == GL_BGRA || glfmt == GL_BGR || glfmt == GL_LUMINANCE_ALPHA) { From 196398290b39aae818f0a01032991094dafe0380 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Sat, 9 May 2015 20:14:55 +0300 Subject: [PATCH 40/46] Fix cubemap face offset calculation --- afl-mojodds.c | 4 ++-- ddsinfo.c | 5 +++-- glddstest.c | 8 ++++---- mojodds.c | 8 ++++---- mojodds.h | 4 ++-- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/afl-mojodds.c b/afl-mojodds.c index 1f7e063..8b5c1c7 100644 --- a/afl-mojodds.c +++ b/afl-mojodds.c @@ -73,7 +73,7 @@ int main(int argc, char *argv[]) { const void *miptex = NULL; unsigned long miptexlen = 0; unsigned int mipW = 0, mipH = 0; - retval = MOJODDS_getMipMapTexture(miplevel, glfmt, tex, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH); + retval = MOJODDS_getMipMapTexture(miplevel, glfmt, tex, w, h, &miptex, &miptexlen, &mipW, &mipH); if (!retval) { continue; } @@ -92,7 +92,7 @@ int main(int argc, char *argv[]) { 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); + retval = MOJODDS_getCubeFace(cubeFace, miplevel, glfmt, tex, cubemapfacelen, w, h, &miptex, &miptexlen, &mipW, &mipH); if (!retval) { continue; } diff --git a/ddsinfo.c b/ddsinfo.c index 32c1f08..e66a524 100644 --- a/ddsinfo.c +++ b/ddsinfo.c @@ -74,7 +74,7 @@ static int ddsinfo(const char *filename) { const void *miptex = NULL; unsigned long miptexlen = 0; unsigned int mipW = 0, mipH = 0; - retval = MOJODDS_getMipMapTexture(miplevel, glfmt, tex, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH); + retval = MOJODDS_getMipMapTexture(miplevel, glfmt, tex, w, h, &miptex, &miptexlen, &mipW, &mipH); if (!retval) { printf("MOJODDS_getMipMapTexture(%u) error: %d\n", miplevel, retval); continue; @@ -90,13 +90,14 @@ static int ddsinfo(const char *filename) { case MOJODDS_TEXTURE_CUBE: printf("cube\n"); + printf("cubemapfacelen: %u\n", cubemapfacelen); 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, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH); + retval = MOJODDS_getCubeFace(MOJODDS_CUBEFACE_POSITIVE_X, miplevel, glfmt, tex, cubemapfacelen, w, h, &miptex, &miptexlen, &mipW, &mipH); if (!retval) { printf("MOJODDS_getMipMapTexture(%u) error: %d\n", miplevel, retval); continue; diff --git a/glddstest.c b/glddstest.c index f2b6bac..62b5a81 100644 --- a/glddstest.c +++ b/glddstest.c @@ -126,7 +126,7 @@ static int glddstest(const char *filename) { const void *miptex = NULL; unsigned long miptexlen = 0; unsigned int mipW = 0, mipH = 0; - retval = MOJODDS_getMipMapTexture(miplevel, glfmt, tex, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH); + retval = MOJODDS_getMipMapTexture(miplevel, glfmt, tex, w, h, &miptex, &miptexlen, &mipW, &mipH); if (!retval) { printf("MOJODDS_getMipMapTexture(%u) error: %d\n", miplevel, retval); continue; @@ -152,7 +152,7 @@ static int glddstest(const char *filename) { const void *miptex = NULL; unsigned long miptexlen = 0; unsigned int mipW = 0, mipH = 0; - retval = MOJODDS_getMipMapTexture(miplevel, glfmt, tex, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH); + retval = MOJODDS_getMipMapTexture(miplevel, glfmt, tex, w, h, &miptex, &miptexlen, &mipW, &mipH); if (!retval) { printf("MOJODDS_getMipMapTexture(%u) error: %d\n", miplevel, retval); continue; @@ -178,7 +178,7 @@ static int glddstest(const char *filename) { 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); + retval = MOJODDS_getCubeFace(cubeFace, miplevel, glfmt, tex, cubemapfacelen, w, h, &miptex, &miptexlen, &mipW, &mipH); if (!retval) { printf("MOJODDS_getCubeFace(%u, %u) error: %d\n", cubeFace, miplevel, retval); continue; @@ -206,7 +206,7 @@ static int glddstest(const char *filename) { 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); + retval = MOJODDS_getCubeFace(cubeFace, miplevel, glfmt, tex, cubemapfacelen, w, h, &miptex, &miptexlen, &mipW, &mipH); if (!retval) { printf("MOJODDS_getCubeFace(%u, %u) error: %d\n", cubeFace, miplevel, retval); continue; diff --git a/mojodds.c b/mojodds.c index 64b6938..7d78d55 100644 --- a/mojodds.c +++ b/mojodds.c @@ -438,7 +438,7 @@ int MOJODDS_getTexture(const void *_ptr, const unsigned long _len, } // MOJODDS_getTexture int MOJODDS_getMipMapTexture(unsigned int miplevel, unsigned int glfmt, - const void*_basetex, const unsigned long _basetexlen, + const void*_basetex, unsigned int w, unsigned h, const void **_tex, unsigned long *_texlen, unsigned int *_texw, unsigned int *_texh) @@ -512,17 +512,17 @@ int MOJODDS_getMipMapTexture(unsigned int miplevel, unsigned int glfmt, int MOJODDS_getCubeFace(MOJODDS_cubeFace cubeFace, unsigned int miplevel, unsigned int glfmt, const void *_basetex, - unsigned long _basetexlen, unsigned int w, unsigned h, + unsigned long _cubemapfacelen, 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; + faceBaseTex = faceBaseTex + cubeFace * _cubemapfacelen; // call MOJODDS_getMipMapTexture to get offset in that face - return MOJODDS_getMipMapTexture(miplevel, glfmt, faceBaseTex, _basetexlen, w, h, _tex, _texlen, _texw, _texh); + return MOJODDS_getMipMapTexture(miplevel, glfmt, faceBaseTex, w, h, _tex, _texlen, _texw, _texh); } diff --git a/mojodds.h b/mojodds.h index 711426e..3f9adee 100644 --- a/mojodds.h +++ b/mojodds.h @@ -35,14 +35,14 @@ int MOJODDS_getTexture(const void *_ptr, const unsigned long _len, unsigned int *_cubemapfacelen, MOJODDS_textureType *_textureType); int MOJODDS_getMipMapTexture(unsigned int miplevel, unsigned int glfmt, - const void*_basetex, const unsigned long _basetexlen, + const void*_basetex, unsigned int w, unsigned h, 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, + unsigned long _cubemapfacelen, unsigned int w, unsigned h, const void **_tex, unsigned long *_texlen, unsigned int *_texw, unsigned int *_texh); From cad881f33f44143ee673ac6c593fb67fd7a48a7b Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Sat, 9 May 2015 23:24:53 +0300 Subject: [PATCH 41/46] Fix format strings --- ddsinfo.c | 2 +- glddstest.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ddsinfo.c b/ddsinfo.c index e66a524..a650227 100644 --- a/ddsinfo.c +++ b/ddsinfo.c @@ -58,7 +58,7 @@ static int ddsinfo(const char *filename) { printf("texlen: %lu\n", texlen); printf("glfmt: 0x%x\n", glfmt); printf("width x height: %u x %u\n", w, h); - printf("miplevels: %d\n", miplevels); + printf("miplevels: %u\n", miplevels); printf("textureType: "); switch (textureType) { case MOJODDS_TEXTURE_NONE: diff --git a/glddstest.c b/glddstest.c index 62b5a81..e66aafd 100644 --- a/glddstest.c +++ b/glddstest.c @@ -180,7 +180,7 @@ static int glddstest(const char *filename) { unsigned int mipW = 0, mipH = 0; retval = MOJODDS_getCubeFace(cubeFace, miplevel, glfmt, tex, cubemapfacelen, w, h, &miptex, &miptexlen, &mipW, &mipH); if (!retval) { - printf("MOJODDS_getCubeFace(%u, %u) error: %d\n", cubeFace, miplevel, retval); + printf("MOJODDS_getCubeFace(%d, %u) error: %d\n", cubeFace, miplevel, retval); continue; } @@ -208,7 +208,7 @@ static int glddstest(const char *filename) { unsigned int mipW = 0, mipH = 0; retval = MOJODDS_getCubeFace(cubeFace, miplevel, glfmt, tex, cubemapfacelen, w, h, &miptex, &miptexlen, &mipW, &mipH); if (!retval) { - printf("MOJODDS_getCubeFace(%u, %u) error: %d\n", cubeFace, miplevel, retval); + printf("MOJODDS_getCubeFace(%d, %u) error: %d\n", cubeFace, miplevel, retval); continue; } From 624b40126934b02a4890321a29bc086f1f3cf691 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Sat, 9 May 2015 23:26:03 +0300 Subject: [PATCH 42/46] Whitespace --- glddstest.c | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/glddstest.c b/glddstest.c index e66aafd..d9b98c5 100644 --- a/glddstest.c +++ b/glddstest.c @@ -244,34 +244,34 @@ int main(int argc, char *argv[]) { return 0; } - SDL_Init(SDL_INIT_VIDEO); - SDL_Window *window = SDL_CreateWindow("OpenGL DDS test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 0, 0, SDL_WINDOW_OPENGL); - if (window == NULL) { - printf("Could not create window: %s\n", SDL_GetError()); - return 3; - } + SDL_Init(SDL_INIT_VIDEO); + SDL_Window *window = SDL_CreateWindow("OpenGL DDS test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 0, 0, SDL_WINDOW_OPENGL); + if (window == NULL) { + printf("Could not create window: %s\n", SDL_GetError()); + return 3; + } - SDL_GLContext context = SDL_GL_CreateContext(window); - if (context == NULL) { - printf("Could not create GL context: %s\n", SDL_GetError()); - SDL_DestroyWindow(window); - return 4; - } + SDL_GLContext context = SDL_GL_CreateContext(window); + if (context == NULL) { + printf("Could not create GL context: %s\n", SDL_GetError()); + SDL_DestroyWindow(window); + return 4; + } - // clear and swap to get better traces - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - SDL_GL_SwapWindow(window); + // clear and swap to get better traces + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + SDL_GL_SwapWindow(window); - glewInit(); + glewInit(); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - SDL_GL_SwapWindow(window); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + SDL_GL_SwapWindow(window); - // glewInit might raise errors if we got an OpenGL 3.0 context - // ignore them - // in this case glGetError is simpler than fooling around with callbacks - GLenum err = GL_NO_ERROR; - while ((err = glGetError()) != GL_NO_ERROR) { } + // glewInit might raise errors if we got an OpenGL 3.0 context + // ignore them + // in this case glGetError is simpler than fooling around with callbacks + GLenum err = GL_NO_ERROR; + while ((err = glGetError()) != GL_NO_ERROR) { } for (int i = 1; i < argc; i++) { glddstest(argv[i]); @@ -282,8 +282,8 @@ int main(int argc, char *argv[]) { } - SDL_GL_DeleteContext(context); - SDL_DestroyWindow(window); + SDL_GL_DeleteContext(context); + SDL_DestroyWindow(window); return 0; } From 6b443298c6e88f3f79b999defad5a3061996d78b Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Sat, 9 May 2015 23:27:40 +0300 Subject: [PATCH 43/46] Pointer arithmetic on void pointers is not portable --- mojodds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mojodds.c b/mojodds.c index 7d78d55..08862a0 100644 --- a/mojodds.c +++ b/mojodds.c @@ -444,7 +444,7 @@ int MOJODDS_getMipMapTexture(unsigned int miplevel, unsigned int glfmt, unsigned int *_texw, unsigned int *_texh) { int i; - const void* newtex; + const char* newtex; unsigned long newtexlen; unsigned int neww; unsigned int newh; From fc2699d1d674113cd7790e778ea2ad4c31d4fd8e Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Sat, 9 May 2015 23:28:23 +0300 Subject: [PATCH 44/46] Remove useless variable --- glddstest.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/glddstest.c b/glddstest.c index d9b98c5..79e7650 100644 --- a/glddstest.c +++ b/glddstest.c @@ -270,8 +270,7 @@ int main(int argc, char *argv[]) { // glewInit might raise errors if we got an OpenGL 3.0 context // ignore them // in this case glGetError is simpler than fooling around with callbacks - GLenum err = GL_NO_ERROR; - while ((err = glGetError()) != GL_NO_ERROR) { } + while (glGetError() != GL_NO_ERROR) { } for (int i = 1; i < argc; i++) { glddstest(argv[i]); From 5b1cc930a8bf73c7417f15e3c20b3880722659e8 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Mon, 11 May 2015 16:00:15 +0300 Subject: [PATCH 45/46] Add AFL-generated test corpus --- .gitattributes | 1 + testcases/README.txt | 1 + .../afl/05db792f178c7e908a802283050abd98.dds | Bin 0 -> 660 bytes .../afl/0a11f64bcc401602e5e79a999df048d3.dds | Bin 0 -> 128 bytes .../afl/0c4202655d522702dcc67c77ea3cb191.dds | Bin 0 -> 488 bytes .../afl/0f2219fcb50ca9829fb77cce0ea44856.dds | Bin 0 -> 432 bytes .../afl/0fcb7b73d8186a898e0092e47654271a.dds | Bin 0 -> 8600 bytes .../afl/119624f5b1f58ea64a929d0ed64e01d0.dds | Bin 0 -> 432 bytes .../afl/163ea94aedbad4f49e005cdf993f6473.dds | Bin 0 -> 128 bytes .../afl/1703611c4b9b1a27d905c049e7576243.dds | Bin 0 -> 432 bytes .../afl/17bf5f29dba71bdb503b1aea6bdd9487.dds | 1 + .../afl/19fdce77858d232c279dcc51276eca8f.dds | Bin 0 -> 524 bytes .../afl/201a25cba9a0128190fa3585dfc424ea.dds | Bin 0 -> 432 bytes .../afl/203d983c68662fab32ff905a78a04eb1.dds | Bin 0 -> 998 bytes .../afl/218140160767b22cd56bc6364d65a1d6.dds | Bin 0 -> 5024 bytes .../afl/282a9f51de5889808aa01de3ce92b6be.dds | Bin 0 -> 128 bytes .../afl/30fe9c6da2d33787aa7da13a4034dfc7.dds | Bin 0 -> 128 bytes .../afl/37cdea783a0a14d1746b46f00d6b9d54.dds | Bin 0 -> 1277 bytes .../afl/395f4bca3c89d25157b3e29040b433bc.dds | Bin 0 -> 432 bytes .../afl/3c65c19da3979db609e9757ed7fe8306.dds | Bin 0 -> 128 bytes .../afl/431c2a342d19c4b14aefc1013841b296.dds | Bin 0 -> 592 bytes .../afl/433e71309e2ee38cde4bfb0a05b65b8a.dds | Bin 0 -> 128 bytes .../afl/46552713e1f2148581a6faeaa0ff561e.dds | Bin 0 -> 1616 bytes .../afl/477610a50263ec5fe9036d69ee136756.dds | Bin 0 -> 416 bytes .../afl/495127e29e0379740c47e842c6c6e072.dds | Bin 0 -> 432 bytes .../afl/4b6ded5b17e410c805f0f924da895939.dds | Bin 0 -> 432 bytes .../afl/593aab193a321351442164ca0ea559f4.dds | Bin 0 -> 128 bytes .../afl/5b6b2654798e2aa535abb193190b447f.dds | Bin 0 -> 128 bytes .../afl/5b74bbeec2c15508a0e80a69c379eb6d.dds | Bin 0 -> 432 bytes .../afl/5e64e3a18c4b85fce29bf9bd4d7c060c.dds | Bin 0 -> 432 bytes .../afl/5e7eaf737832efcb29a60e0d8ea82ff4.dds | Bin 0 -> 432 bytes .../afl/63f709a83c9a4a0c892ebbf82fd59cd2.dds | Bin 0 -> 432 bytes .../afl/6512e08aa5fcdc35e929be8ea9e8a6f7.dds | Bin 0 -> 128 bytes .../afl/83af34b71f5d6ad19bcbfe9acbf18f62.dds | Bin 0 -> 176 bytes .../afl/8409e8c0d571650e593874adef716c36.dds | Bin 0 -> 2480 bytes .../afl/8aabdcda9c673d260398c2f956272b6f.dds | Bin 0 -> 432 bytes .../afl/8c24243c4aeffb207ce44b48f1edc21a.dds | Bin 0 -> 128 bytes .../afl/909ec0f19d0f54106c321f1ce4c6630f.dds | Bin 0 -> 128 bytes .../afl/942bf17a52b646a17f8eefc1a95691fa.dds | Bin 0 -> 128 bytes .../afl/a465ae66f4cba041e621cb470b142020.dds | Bin 0 -> 128 bytes .../afl/aa0de39a8b690e4a7f38560987637e99.dds | Bin 0 -> 128 bytes .../afl/abb3923183d847dad7f69752b8960607.dds | Bin 0 -> 128 bytes .../afl/aca33cb76bd832d6fd5ff5708ceb7c38.dds | 1 + .../afl/b501178f35b85031e59e62fbe04e3a5e.dds | Bin 0 -> 9104 bytes .../afl/b5b6626ec9b59c058560c490921cd629.dds | Bin 0 -> 128 bytes .../afl/c03e46b50ad96266f24b74e89448eacf.dds | Bin 0 -> 656 bytes .../afl/c82d477cb9d4384e0f489e01e73d5cfc.dds | Bin 0 -> 632 bytes .../afl/c96844d2ab2ec78960109fee1b844d0f.dds | Bin 0 -> 1328 bytes .../afl/ce5cdf1a7c4a88f6b6d1a61569045f8f.dds | Bin 0 -> 6464 bytes .../afl/d5ea3bc6d102ea01263a194db3f9628b.dds | Bin 0 -> 520 bytes .../afl/d6561b29cff3a485b39d3679d313220a.dds | Bin 0 -> 4556 bytes .../afl/d87978191ffbf2e3515af8408669b61e.dds | Bin 0 -> 432 bytes .../afl/dc60891559a4ab701d363a3cd8abc4f4.dds | Bin 0 -> 128 bytes .../afl/dd3aaf127d6e950882e38217846fb8ca.dds | Bin 0 -> 432 bytes .../afl/e1cc2a66f59310774b8635077b586c7e.dds | Bin 0 -> 128 bytes .../afl/e849e96148e4917ed0264e5e5d760712.dds | Bin 0 -> 128 bytes .../afl/e92fc456c80b36caed51d32851941234.dds | Bin 0 -> 128 bytes .../afl/eaf30d2d753f2b3f598e660dbdae89ad.dds | Bin 0 -> 360 bytes .../afl/ef28a4f8e8ee11863f4f6c7a79c2ad0f.dds | Bin 0 -> 9488 bytes .../afl/f43e732021bd14d6b9e40174a16addbc.dds | Bin 0 -> 528 bytes .../afl/f8f64ac3c235a15101370b0ff8e480c4.dds | Bin 0 -> 728 bytes .../afl/fa15f384a8dfb780c694aebfceb9187c.dds | Bin 0 -> 432 bytes .../afl/fa7eb67ca7f68caff90135223a27036d.dds | Bin 0 -> 640 bytes .../afl/fb23381f7e8572945ea981a3ba28ee30.dds | Bin 0 -> 824 bytes .../afl/ff62989546bfc5218c33c7e9a7086b5c.dds | Bin 0 -> 608 bytes 65 files changed, 4 insertions(+) create mode 100644 .gitattributes create mode 100644 testcases/README.txt create mode 100644 testcases/afl/05db792f178c7e908a802283050abd98.dds create mode 100644 testcases/afl/0a11f64bcc401602e5e79a999df048d3.dds create mode 100644 testcases/afl/0c4202655d522702dcc67c77ea3cb191.dds create mode 100644 testcases/afl/0f2219fcb50ca9829fb77cce0ea44856.dds create mode 100644 testcases/afl/0fcb7b73d8186a898e0092e47654271a.dds create mode 100644 testcases/afl/119624f5b1f58ea64a929d0ed64e01d0.dds create mode 100644 testcases/afl/163ea94aedbad4f49e005cdf993f6473.dds create mode 100644 testcases/afl/1703611c4b9b1a27d905c049e7576243.dds create mode 100644 testcases/afl/17bf5f29dba71bdb503b1aea6bdd9487.dds create mode 100644 testcases/afl/19fdce77858d232c279dcc51276eca8f.dds create mode 100644 testcases/afl/201a25cba9a0128190fa3585dfc424ea.dds create mode 100644 testcases/afl/203d983c68662fab32ff905a78a04eb1.dds create mode 100644 testcases/afl/218140160767b22cd56bc6364d65a1d6.dds create mode 100644 testcases/afl/282a9f51de5889808aa01de3ce92b6be.dds create mode 100644 testcases/afl/30fe9c6da2d33787aa7da13a4034dfc7.dds create mode 100644 testcases/afl/37cdea783a0a14d1746b46f00d6b9d54.dds create mode 100644 testcases/afl/395f4bca3c89d25157b3e29040b433bc.dds create mode 100644 testcases/afl/3c65c19da3979db609e9757ed7fe8306.dds create mode 100644 testcases/afl/431c2a342d19c4b14aefc1013841b296.dds create mode 100644 testcases/afl/433e71309e2ee38cde4bfb0a05b65b8a.dds create mode 100644 testcases/afl/46552713e1f2148581a6faeaa0ff561e.dds create mode 100644 testcases/afl/477610a50263ec5fe9036d69ee136756.dds create mode 100644 testcases/afl/495127e29e0379740c47e842c6c6e072.dds create mode 100644 testcases/afl/4b6ded5b17e410c805f0f924da895939.dds create mode 100644 testcases/afl/593aab193a321351442164ca0ea559f4.dds create mode 100644 testcases/afl/5b6b2654798e2aa535abb193190b447f.dds create mode 100644 testcases/afl/5b74bbeec2c15508a0e80a69c379eb6d.dds create mode 100644 testcases/afl/5e64e3a18c4b85fce29bf9bd4d7c060c.dds create mode 100644 testcases/afl/5e7eaf737832efcb29a60e0d8ea82ff4.dds create mode 100644 testcases/afl/63f709a83c9a4a0c892ebbf82fd59cd2.dds create mode 100644 testcases/afl/6512e08aa5fcdc35e929be8ea9e8a6f7.dds create mode 100644 testcases/afl/83af34b71f5d6ad19bcbfe9acbf18f62.dds create mode 100644 testcases/afl/8409e8c0d571650e593874adef716c36.dds create mode 100644 testcases/afl/8aabdcda9c673d260398c2f956272b6f.dds create mode 100644 testcases/afl/8c24243c4aeffb207ce44b48f1edc21a.dds create mode 100644 testcases/afl/909ec0f19d0f54106c321f1ce4c6630f.dds create mode 100644 testcases/afl/942bf17a52b646a17f8eefc1a95691fa.dds create mode 100644 testcases/afl/a465ae66f4cba041e621cb470b142020.dds create mode 100644 testcases/afl/aa0de39a8b690e4a7f38560987637e99.dds create mode 100644 testcases/afl/abb3923183d847dad7f69752b8960607.dds create mode 100644 testcases/afl/aca33cb76bd832d6fd5ff5708ceb7c38.dds create mode 100644 testcases/afl/b501178f35b85031e59e62fbe04e3a5e.dds create mode 100644 testcases/afl/b5b6626ec9b59c058560c490921cd629.dds create mode 100644 testcases/afl/c03e46b50ad96266f24b74e89448eacf.dds create mode 100644 testcases/afl/c82d477cb9d4384e0f489e01e73d5cfc.dds create mode 100644 testcases/afl/c96844d2ab2ec78960109fee1b844d0f.dds create mode 100644 testcases/afl/ce5cdf1a7c4a88f6b6d1a61569045f8f.dds create mode 100644 testcases/afl/d5ea3bc6d102ea01263a194db3f9628b.dds create mode 100644 testcases/afl/d6561b29cff3a485b39d3679d313220a.dds create mode 100644 testcases/afl/d87978191ffbf2e3515af8408669b61e.dds create mode 100644 testcases/afl/dc60891559a4ab701d363a3cd8abc4f4.dds create mode 100644 testcases/afl/dd3aaf127d6e950882e38217846fb8ca.dds create mode 100644 testcases/afl/e1cc2a66f59310774b8635077b586c7e.dds create mode 100644 testcases/afl/e849e96148e4917ed0264e5e5d760712.dds create mode 100644 testcases/afl/e92fc456c80b36caed51d32851941234.dds create mode 100644 testcases/afl/eaf30d2d753f2b3f598e660dbdae89ad.dds create mode 100644 testcases/afl/ef28a4f8e8ee11863f4f6c7a79c2ad0f.dds create mode 100644 testcases/afl/f43e732021bd14d6b9e40174a16addbc.dds create mode 100644 testcases/afl/f8f64ac3c235a15101370b0ff8e480c4.dds create mode 100644 testcases/afl/fa15f384a8dfb780c694aebfceb9187c.dds create mode 100644 testcases/afl/fa7eb67ca7f68caff90135223a27036d.dds create mode 100644 testcases/afl/fb23381f7e8572945ea981a3ba28ee30.dds create mode 100644 testcases/afl/ff62989546bfc5218c33c7e9a7086b5c.dds diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..ff3657d --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.dds -text diff --git a/testcases/README.txt b/testcases/README.txt new file mode 100644 index 0000000..3e0e37e --- /dev/null +++ b/testcases/README.txt @@ -0,0 +1 @@ +This directory contains AFL-generated minimal test corpus. diff --git a/testcases/afl/05db792f178c7e908a802283050abd98.dds b/testcases/afl/05db792f178c7e908a802283050abd98.dds new file mode 100644 index 0000000000000000000000000000000000000000..325d3092af328c9a6b7acfd2c1135f09e7e9e3dd GIT binary patch literal 660 zcmZ>930A0KU|?W3;4930A0KU|?W300RaCAREFYom2qoWg$@;0DNf{LjV8( literal 0 HcmV?d00001 diff --git a/testcases/afl/0c4202655d522702dcc67c77ea3cb191.dds b/testcases/afl/0c4202655d522702dcc67c77ea3cb191.dds new file mode 100644 index 0000000000000000000000000000000000000000..2b53c4fb6b4b6bdd510d70ebff9842d0b5dd829a GIT binary patch literal 488 zcmZ>930A0KU|?W3;4)wW(gq;R2*f}D=7ShS0tKMnUr@CYKsE!ze;5LrXJAkdl!Y>h LG;>rLbwU6DlH^$I literal 0 HcmV?d00001 diff --git a/testcases/afl/0f2219fcb50ca9829fb77cce0ea44856.dds b/testcases/afl/0f2219fcb50ca9829fb77cce0ea44856.dds new file mode 100644 index 0000000000000000000000000000000000000000..2db4b9492dd30f90f466ffd146928581389bef8d GIT binary patch literal 432 zcmZ>930A0KU|?W3;4)wW(jaWW2*f}DWP)iBn;4(~RL=rb=n@fPicS50gHQv5|JYzK@!FX8rJ?C;IZPq| literal 0 HcmV?d00001 diff --git a/testcases/afl/119624f5b1f58ea64a929d0ed64e01d0.dds b/testcases/afl/119624f5b1f58ea64a929d0ed64e01d0.dds new file mode 100644 index 0000000000000000000000000000000000000000..333ab3b4f0ba0207bdaa783c5ffb4a0a2d9b7e0b GIT binary patch literal 432 zcmZ>930A0KU|?W3;4)wW(t<#2zzD=ZzzkxO02F}ge?!%S*bEH+VF=7IFbD$5l4K+a IwvP;@05FSAX#fBK literal 0 HcmV?d00001 diff --git a/testcases/afl/163ea94aedbad4f49e005cdf993f6473.dds b/testcases/afl/163ea94aedbad4f49e005cdf993f6473.dds new file mode 100644 index 0000000000000000000000000000000000000000..488083f4f0e811843c75a5e2f19bb2cc0ed0881a GIT binary patch literal 128 ncmZ>930A0KU|?W300RaCAREFYom2qo{f(rJf#E+4;WQHf!n_yv literal 0 HcmV?d00001 diff --git a/testcases/afl/1703611c4b9b1a27d905c049e7576243.dds b/testcases/afl/1703611c4b9b1a27d905c049e7576243.dds new file mode 100644 index 0000000000000000000000000000000000000000..82d0619f2c3668c91a4a15bb7a2084cae8a0d174 GIT binary patch literal 432 zcmZ>930A0KU|?W3;4)wW(%L|5zzD=-00p4lUr>D#KsE!ze;7hC4~a>J9V1-}0RAve A)&Kwi literal 0 HcmV?d00001 diff --git a/testcases/afl/17bf5f29dba71bdb503b1aea6bdd9487.dds b/testcases/afl/17bf5f29dba71bdb503b1aea6bdd9487.dds new file mode 100644 index 0000000..643e9cf --- /dev/null +++ b/testcases/afl/17bf5f29dba71bdb503b1aea6bdd9487.dds @@ -0,0 +1 @@ +DDS \ No newline at end of file diff --git a/testcases/afl/19fdce77858d232c279dcc51276eca8f.dds b/testcases/afl/19fdce77858d232c279dcc51276eca8f.dds new file mode 100644 index 0000000000000000000000000000000000000000..4f33f934b5fb8148688638f5dc804ee438aab6f1 GIT binary patch literal 524 zcmZ>930A0KU|?W3;4)wW(gq;R2*g0Z3}TZ26oBe~LDfqD*$fQ-VF+qYJy4b;BT2A* JR4Jt)005JxU#$QD literal 0 HcmV?d00001 diff --git a/testcases/afl/201a25cba9a0128190fa3585dfc424ea.dds b/testcases/afl/201a25cba9a0128190fa3585dfc424ea.dds new file mode 100644 index 0000000000000000000000000000000000000000..925abd785fca853167b1f211485da3420dac432c GIT binary patch literal 432 zcmZ>930A0KU|?W3;4)wW(o#TdzzD=Z0OEsaVu1os{cosZ5SxMFKMa961_nVuS(1z- J*6I930A0KU|?W3;4)wW(i4H$fDwp+0LTQ>AT}{T0jQoCrVy)M2cWDhOvNZY8Umvs IK$j2z0CZEgEdT%j literal 0 HcmV?d00001 diff --git a/testcases/afl/218140160767b22cd56bc6364d65a1d6.dds b/testcases/afl/218140160767b22cd56bc6364d65a1d6.dds new file mode 100644 index 0000000000000000000000000000000000000000..3025f13565c02e651dd9e18c6b96114fa01a9f42 GIT binary patch literal 5024 zcmeIu!3lsc5Jb^E2$tYACCtSRwgV$rjJ?NE&{MF1{J^rqW==12D`!N^k{0iK9G~a- u<@ffti~ExcdDOMnYucsO`{9NF0tg_000IagfB*srAb930A0KU|?W300RaCAREFYom2qoWdUk)i3l+zRyP2RMi!_5 literal 0 HcmV?d00001 diff --git a/testcases/afl/30fe9c6da2d33787aa7da13a4034dfc7.dds b/testcases/afl/30fe9c6da2d33787aa7da13a4034dfc7.dds new file mode 100644 index 0000000000000000000000000000000000000000..ff00724ee106e52f6627aa93b9e258ffbec45009 GIT binary patch literal 128 ocmZ>930A0KU|?W300RaCAREFYom2qo{f(rJf#E+GAqinH0lK&sxBvhE literal 0 HcmV?d00001 diff --git a/testcases/afl/37cdea783a0a14d1746b46f00d6b9d54.dds b/testcases/afl/37cdea783a0a14d1746b46f00d6b9d54.dds new file mode 100644 index 0000000000000000000000000000000000000000..f42fec5336c00a8431e0ef3dea1625e34c693252 GIT binary patch literal 1277 zcmZ>930A0KU|?W3;4)wW(hWdtzzD=Z0Azw`5StjF095}As!#%?nc+VSLCvWL%93Ox TG1iW%84ZEa5Eu;s(nA0MgJ$h2 literal 0 HcmV?d00001 diff --git a/testcases/afl/395f4bca3c89d25157b3e29040b433bc.dds b/testcases/afl/395f4bca3c89d25157b3e29040b433bc.dds new file mode 100644 index 0000000000000000000000000000000000000000..78620e0a6b32fdd67b2d6ace3080dac235d19916 GIT binary patch literal 432 zcmZ>930A0KU|?W3;4)wW(mq5(PX%0cxnLv DM*2?^ literal 0 HcmV?d00001 diff --git a/testcases/afl/3c65c19da3979db609e9757ed7fe8306.dds b/testcases/afl/3c65c19da3979db609e9757ed7fe8306.dds new file mode 100644 index 0000000000000000000000000000000000000000..1b76a32c32a9599ee1f7563bff8875e5fecbd42f GIT binary patch literal 128 UcmZ>9305$G0tO&}vFSwv0MtPjd;kCd literal 0 HcmV?d00001 diff --git a/testcases/afl/431c2a342d19c4b14aefc1013841b296.dds b/testcases/afl/431c2a342d19c4b14aefc1013841b296.dds new file mode 100644 index 0000000000000000000000000000000000000000..ab6d3cbc5ee22409959093a29d6f499b09659001 GIT binary patch literal 592 zcmZ>930A0KU|?W3;4%;d(jaWW2*g0Z1Y(l_6oBekfa+Z$LQJu1y95*_$w=(RjEWB0 G5C8z=No)xK literal 0 HcmV?d00001 diff --git a/testcases/afl/433e71309e2ee38cde4bfb0a05b65b8a.dds b/testcases/afl/433e71309e2ee38cde4bfb0a05b65b8a.dds new file mode 100644 index 0000000000000000000000000000000000000000..13018b6e9daae966e6fc7fe97227fe78351ea92b GIT binary patch literal 128 zcmZ>930A0KU|?W3;4(01U|;}a0|)>LGeDU{Q3^oyzo055K$;o;!w}e<{|5C22LDlw F0syu181(=E literal 0 HcmV?d00001 diff --git a/testcases/afl/46552713e1f2148581a6faeaa0ff561e.dds b/testcases/afl/46552713e1f2148581a6faeaa0ff561e.dds new file mode 100644 index 0000000000000000000000000000000000000000..725cd21800e938a390de39d16013276f71d335f1 GIT binary patch literal 1616 zcmZ>930A0KU|?W3;4%;d(jaWW2*g0Z0%DT@6oBekfa+Z$LJYBK`)?3xVDKNC%&6FC Q2#kinXb6mkz)%kX07@4vX8-^I literal 0 HcmV?d00001 diff --git a/testcases/afl/477610a50263ec5fe9036d69ee136756.dds b/testcases/afl/477610a50263ec5fe9036d69ee136756.dds new file mode 100644 index 0000000000000000000000000000000000000000..b0f0e77f81bb09704b7b896da01c2015a5fbfa0d GIT binary patch literal 416 xcmZ>930A0KU|?W3;4%;g(jctB$iQGg22cR%WdZ7Qi3l;ot(`2RaT_930A0KU|?W3;4)wW(jaWW2*f}DWP)iBn;4(~RR0UAPy(cx;Xe$4&G~OoZ(#7B L7?VcT;0gf%G`Ua; literal 0 HcmV?d00001 diff --git a/testcases/afl/4b6ded5b17e410c805f0f924da895939.dds b/testcases/afl/4b6ded5b17e410c805f0f924da895939.dds new file mode 100644 index 0000000000000000000000000000000000000000..749e3667208ee1e5c301c41aa866c13ebd971573 GIT binary patch literal 432 zcmZ>930A0KU|?W3;4)wW(t<#2zzD=Z0Azw`5StjF095}As!#%?nc+VSLCvWL%93Ox JG1iVKH2?{2PD=m) literal 0 HcmV?d00001 diff --git a/testcases/afl/593aab193a321351442164ca0ea559f4.dds b/testcases/afl/593aab193a321351442164ca0ea559f4.dds new file mode 100644 index 0000000000000000000000000000000000000000..b59d4f52cff2912c80b173d3411b084ffbb094a2 GIT binary patch literal 128 xcmZ>930A0KU|?W3;4&~UU|@h?AQK2UfZ`AqaijuJ{VqI8{~OdB82m?7003u@7zh9W literal 0 HcmV?d00001 diff --git a/testcases/afl/5b6b2654798e2aa535abb193190b447f.dds b/testcases/afl/5b6b2654798e2aa535abb193190b447f.dds new file mode 100644 index 0000000000000000000000000000000000000000..c85373a84f7f51123ad51c2262921b03afba4057 GIT binary patch literal 128 gcmZ>930A0KU|?W300RaCAREFYom2qo{Y|1a0IIncIsgCw literal 0 HcmV?d00001 diff --git a/testcases/afl/5b74bbeec2c15508a0e80a69c379eb6d.dds b/testcases/afl/5b74bbeec2c15508a0e80a69c379eb6d.dds new file mode 100644 index 0000000000000000000000000000000000000000..6a982a1f4195ae18f9f633670ca8d3c0a7b9f9fd GIT binary patch literal 432 zcmZ>930A0KU|?W3;4)wW(jaWW2*hLn1)$zvP<;|WHUq930A0KU|?W3;4)wW(jaWW2*hLn1)$#FP<930A0KU|?W3;4)wa(t<#2zzD=Z0Azw`5StjF095}Qsu09xVE7M1V2*)75KxvR LBZ;wgM5zG)Eptw1 literal 0 HcmV?d00001 diff --git a/testcases/afl/63f709a83c9a4a0c892ebbf82fd59cd2.dds b/testcases/afl/63f709a83c9a4a0c892ebbf82fd59cd2.dds new file mode 100644 index 0000000000000000000000000000000000000000..4f2068130dd19a026c7081dc71b3ba54a8e46522 GIT binary patch literal 432 zcmZ>930A0KU|?W3;4)wW(jaWW2*hLn1)yFQpgxy~5JPO*|APd<1UA`GF=9dh02q-^ A(EtDd literal 0 HcmV?d00001 diff --git a/testcases/afl/6512e08aa5fcdc35e929be8ea9e8a6f7.dds b/testcases/afl/6512e08aa5fcdc35e929be8ea9e8a6f7.dds new file mode 100644 index 0000000000000000000000000000000000000000..d612b228047b629a2845c56b96befdfa5f33ce07 GIT binary patch literal 128 icmZ>930A0KU|?W300RaCAREFYom2qom4a#`)))Y4nH9+Z literal 0 HcmV?d00001 diff --git a/testcases/afl/83af34b71f5d6ad19bcbfe9acbf18f62.dds b/testcases/afl/83af34b71f5d6ad19bcbfe9acbf18f62.dds new file mode 100644 index 0000000000000000000000000000000000000000..91247c06c80a57b9d0554cc39dcffadc7b416796 GIT binary patch literal 176 rcmZ>930A0KU|?W3Ffd>O(jW|Ek_8lidYNH5v6#aFlKT%+KpqVM1}z?) literal 0 HcmV?d00001 diff --git a/testcases/afl/8409e8c0d571650e593874adef716c36.dds b/testcases/afl/8409e8c0d571650e593874adef716c36.dds new file mode 100644 index 0000000000000000000000000000000000000000..91aba5f3d22aae5e9cb7738b922328d75c6ccea8 GIT binary patch literal 2480 zcmZ>930A0KU|?W3;4%;g(jaWW2*g0Z3}TZ26oBekfa+Z$LJYBK`)?3xVDKNC%&6FC a2#kinXb6mkz-S1JhQMeDjD`TN5C8zVz|V33 literal 0 HcmV?d00001 diff --git a/testcases/afl/8aabdcda9c673d260398c2f956272b6f.dds b/testcases/afl/8aabdcda9c673d260398c2f956272b6f.dds new file mode 100644 index 0000000000000000000000000000000000000000..c0aa645b2f7d4dca8eb48389e904389b3d83198d GIT binary patch literal 432 zcmZ>930A0KU|?W3;4)wW(jaWW2*f}DWP)iBn;4(~RL=xch(#}lfrEj;f0%+%nw$^- E0Do{zHvj+t literal 0 HcmV?d00001 diff --git a/testcases/afl/8c24243c4aeffb207ce44b48f1edc21a.dds b/testcases/afl/8c24243c4aeffb207ce44b48f1edc21a.dds new file mode 100644 index 0000000000000000000000000000000000000000..8609973a43fa70bd554619a7c194426c8da43cd0 GIT binary patch literal 128 VcmZ>9305$G0|o{I0}!Sk007p37kmH! literal 0 HcmV?d00001 diff --git a/testcases/afl/909ec0f19d0f54106c321f1ce4c6630f.dds b/testcases/afl/909ec0f19d0f54106c321f1ce4c6630f.dds new file mode 100644 index 0000000000000000000000000000000000000000..6a5cfdf610ac317a42b3bc71f69795f2dc4cfb81 GIT binary patch literal 128 scmZ>930A0KU|?W300RaCAREFYom2qoWdUk)i3l;prkevK_#agU0G3A=PXGV_ literal 0 HcmV?d00001 diff --git a/testcases/afl/942bf17a52b646a17f8eefc1a95691fa.dds b/testcases/afl/942bf17a52b646a17f8eefc1a95691fa.dds new file mode 100644 index 0000000000000000000000000000000000000000..c4adb01fdf8b8b6a9ac1d825be7ec473ea6f5c4a GIT binary patch literal 128 pcmZ>930A0KU|?W300RaCAREFYom2qo{SDOyVly!OhasG10syMq7gqoP literal 0 HcmV?d00001 diff --git a/testcases/afl/a465ae66f4cba041e621cb470b142020.dds b/testcases/afl/a465ae66f4cba041e621cb470b142020.dds new file mode 100644 index 0000000000000000000000000000000000000000..6040d3eab0c6c61f62eb7cf134f4603acd077589 GIT binary patch literal 128 xcmZ>930A0KU|?W3;4&}((qL==0YEMTlt~n&094NcROu2CVv1dZ15g;%NB{+L6+!?2 literal 0 HcmV?d00001 diff --git a/testcases/afl/aa0de39a8b690e4a7f38560987637e99.dds b/testcases/afl/aa0de39a8b690e4a7f38560987637e99.dds new file mode 100644 index 0000000000000000000000000000000000000000..65377276a76deca305a6e0209afbe4f7fdc4626d GIT binary patch literal 128 ncmZ>930A0KU|?W300RaCAREFYom2qo{e`5Bf#E+4;WQHf!i*R8 literal 0 HcmV?d00001 diff --git a/testcases/afl/abb3923183d847dad7f69752b8960607.dds b/testcases/afl/abb3923183d847dad7f69752b8960607.dds new file mode 100644 index 0000000000000000000000000000000000000000..f412ea983833b531982df198734589046b75688c GIT binary patch literal 128 ccmZ>930A0KU|=wS00sjD8!ALRr9g&W0GHtwm;e9( literal 0 HcmV?d00001 diff --git a/testcases/afl/aca33cb76bd832d6fd5ff5708ceb7c38.dds b/testcases/afl/aca33cb76bd832d6fd5ff5708ceb7c38.dds new file mode 100644 index 0000000..7e7ae9e --- /dev/null +++ b/testcases/afl/aca33cb76bd832d6fd5ff5708ceb7c38.dds @@ -0,0 +1 @@ +DDS 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/testcases/afl/b501178f35b85031e59e62fbe04e3a5e.dds b/testcases/afl/b501178f35b85031e59e62fbe04e3a5e.dds new file mode 100644 index 0000000000000000000000000000000000000000..a21d31561206c5a4b9267b94489af5c7f328937b GIT binary patch literal 9104 zcmeIuu?c`c3Zf zd-nXLmfAm`#hxSD`|eN6J+pneWQPC&0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk N1PBlyK!CtM1uktls-XY? literal 0 HcmV?d00001 diff --git a/testcases/afl/b5b6626ec9b59c058560c490921cd629.dds b/testcases/afl/b5b6626ec9b59c058560c490921cd629.dds new file mode 100644 index 0000000000000000000000000000000000000000..5d93c13ba93c12973c161b82cba0218d066ad704 GIT binary patch literal 128 lcmZ>930A0KU|?W300RaCAREFYom2qo{f(rJf#E+vvjDQU7kK~x literal 0 HcmV?d00001 diff --git a/testcases/afl/c03e46b50ad96266f24b74e89448eacf.dds b/testcases/afl/c03e46b50ad96266f24b74e89448eacf.dds new file mode 100644 index 0000000000000000000000000000000000000000..36d46283c7faa82aa7c79cdde58693756531cb8d GIT binary patch literal 656 zcmZ>930A0KU|?W3;4U99hl4K;zv{8D5ga7~v CzIJ^8 literal 0 HcmV?d00001 diff --git a/testcases/afl/c82d477cb9d4384e0f489e01e73d5cfc.dds b/testcases/afl/c82d477cb9d4384e0f489e01e73d5cfc.dds new file mode 100644 index 0000000000000000000000000000000000000000..fb5f19bbb08b1e9b631914eed886824afaf422b0 GIT binary patch literal 632 zcmZ>930A0KU|?W3;4930A0KU|?W3;4)wW(i4H$fDwp+0LTQ>AT}{T0jQn@sL&-M#2CAJ2cR%XMq)Q+ QRCF{1MnhmU1O^}k0J&oI930A0KU|?W3;4%;g(jaWW2*g0Z3}TZ26oBekfa+Z$LJYBMa{vmHWF&TDMn$O} F0sx3wUH||9 literal 0 HcmV?d00001 diff --git a/testcases/afl/d6561b29cff3a485b39d3679d313220a.dds b/testcases/afl/d6561b29cff3a485b39d3679d313220a.dds new file mode 100644 index 0000000000000000000000000000000000000000..4365531f4aad41ef3f5d5f9a8166acdd34311b71 GIT binary patch literal 4556 zcmeIuu?@g52t-lh6p_+-14g(Zyg`(0vb%!|Iydwm=>)~myfGgC%930A0KU|?W3;4)wW(jaWW2*hLn1)yFQpgxy~5L0a0|APd<1UA`GF=9dh03G#D A)c^nh literal 0 HcmV?d00001 diff --git a/testcases/afl/dc60891559a4ab701d363a3cd8abc4f4.dds b/testcases/afl/dc60891559a4ab701d363a3cd8abc4f4.dds new file mode 100644 index 0000000000000000000000000000000000000000..73bee14b222c85b4603030367cd678ff70140068 GIT binary patch literal 128 wcmZ>930A0KU|?W3;4(01U|;}a0|)>LGeDU{Q3^oyyYQ&|Z%}Vw@E=tH0ILufpa1{> literal 0 HcmV?d00001 diff --git a/testcases/afl/dd3aaf127d6e950882e38217846fb8ca.dds b/testcases/afl/dd3aaf127d6e950882e38217846fb8ca.dds new file mode 100644 index 0000000000000000000000000000000000000000..c2ea90ffe387ac218178368cb52329e8432d295d GIT binary patch literal 432 zcmZ>930A0KU|?W3;4)wW(jaWW2*f}DWP)iBn;4(~RL=rb=n@fPh)w-}gHQv5|JY930A0KU|?W300RaCAREFYom3!0F93w87H930A0KU|?W3;4930A0KU|?W300RaCAREFYom3#Gw;sb#0E#yjz5oCK literal 0 HcmV?d00001 diff --git a/testcases/afl/eaf30d2d753f2b3f598e660dbdae89ad.dds b/testcases/afl/eaf30d2d753f2b3f598e660dbdae89ad.dds new file mode 100644 index 0000000000000000000000000000000000000000..385589a0c8d89d64090ef19eb25968db3be46b5b GIT binary patch literal 360 zcmZ>930A0KU|?W3;4%;d(jaUA!a%?Tr9o_BfC5lG3s9j;M2I1F^$tMclh~z(xhMd{ C%0RmS literal 0 HcmV?d00001 diff --git a/testcases/afl/ef28a4f8e8ee11863f4f6c7a79c2ad0f.dds b/testcases/afl/ef28a4f8e8ee11863f4f6c7a79c2ad0f.dds new file mode 100644 index 0000000000000000000000000000000000000000..85c9f0aba4fa1c4a9c1c8e3367cfa92e95b7ca1d GIT binary patch literal 9488 zcmeIu!3}^Q3;;kLCa%E930A0KU|?W3;4%;d(jaWW2*hLn1)yFQpgxy~5L4XR$ub(ZaicO+4FLee24E!s literal 0 HcmV?d00001 diff --git a/testcases/afl/f8f64ac3c235a15101370b0ff8e480c4.dds b/testcases/afl/f8f64ac3c235a15101370b0ff8e480c4.dds new file mode 100644 index 0000000000000000000000000000000000000000..753a373b323565d938743ead2a55081371ea2c99 GIT binary patch literal 728 zcmZ>930A0KU|?W3;4)wW(i4H$fDwp+0LTQ>AT}{T0jQn@sL&-M#1OlB2cR%XMq)Q+ LRCF{12!sFt>8*ug literal 0 HcmV?d00001 diff --git a/testcases/afl/fa15f384a8dfb780c694aebfceb9187c.dds b/testcases/afl/fa15f384a8dfb780c694aebfceb9187c.dds new file mode 100644 index 0000000000000000000000000000000000000000..cad4d89b07f16b091a08a72d0da16eed91274cdf GIT binary patch literal 432 wcmZ>930A0KU|?W3;4930A0KU|?W3;4%;d(jaWW2*g0Z3SyH06oBekfa+Z$LX5F%a{vmHWF&TDMn#8B G2mk=sJ9Kye literal 0 HcmV?d00001 diff --git a/testcases/afl/fb23381f7e8572945ea981a3ba28ee30.dds b/testcases/afl/fb23381f7e8572945ea981a3ba28ee30.dds new file mode 100644 index 0000000000000000000000000000000000000000..5d24f01668895a2c16991606ab8cee20be8ab2af GIT binary patch literal 824 zcmZ>930A0KU|?W3;4)AE(jaWW1jInV24a%{Kzdn#>Rlp246$o-01A_2Bz9v)MMpzm HfI|QPYSWh% literal 0 HcmV?d00001 diff --git a/testcases/afl/ff62989546bfc5218c33c7e9a7086b5c.dds b/testcases/afl/ff62989546bfc5218c33c7e9a7086b5c.dds new file mode 100644 index 0000000000000000000000000000000000000000..0a2b9ce07b736d71f0a74f44ffa59a4a4b147877 GIT binary patch literal 608 zcmZ>930A0KU|?W3;4%;d(jaWW2*g0Z3}TZ26oBekfa+Z$LQJu1y95*_$w=(RjEWAK G5C8zd25$-g literal 0 HcmV?d00001 From 72c2778af0fc7c1313b1d96df35a086fddcab03f Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Tue, 2 Feb 2016 21:01:45 +0200 Subject: [PATCH 46/46] Remove MOJODDS_TEXTURE_NONE --- afl-mojodds.c | 6 +----- ddsinfo.c | 7 +------ glddstest.c | 6 +----- mojodds.h | 1 - 4 files changed, 3 insertions(+), 17 deletions(-) diff --git a/afl-mojodds.c b/afl-mojodds.c index 8b5c1c7..4099171 100644 --- a/afl-mojodds.c +++ b/afl-mojodds.c @@ -55,7 +55,7 @@ int main(int argc, char *argv[]) { unsigned long texlen = 0; unsigned int glfmt = 0, w = 0, h = 0, miplevels = 0; unsigned int cubemapfacelen = 0; - MOJODDS_textureType textureType = MOJODDS_TEXTURE_NONE; + MOJODDS_textureType textureType = 0; int retval = MOJODDS_getTexture(contents, size, &tex, &texlen, &glfmt, &w, &h, &miplevels, &cubemapfacelen, &textureType); if (!retval) { free(contents); @@ -64,10 +64,6 @@ int main(int argc, char *argv[]) { 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; diff --git a/ddsinfo.c b/ddsinfo.c index a650227..dc9f54d 100644 --- a/ddsinfo.c +++ b/ddsinfo.c @@ -45,7 +45,7 @@ static int ddsinfo(const char *filename) { unsigned long texlen = 0; unsigned int glfmt = 0, w = 0, h = 0, miplevels = 0; unsigned int cubemapfacelen = 0; - MOJODDS_textureType textureType = MOJODDS_TEXTURE_NONE; + MOJODDS_textureType textureType = 0; int retval = MOJODDS_getTexture(contents, size, &tex, &texlen, &glfmt, &w, &h, &miplevels, &cubemapfacelen, &textureType); if (!retval) { printf("MOJODDS_getTexture failed\n"); @@ -61,11 +61,6 @@ static int ddsinfo(const char *filename) { printf("miplevels: %u\n", miplevels); printf("textureType: "); switch (textureType) { - case MOJODDS_TEXTURE_NONE: - printf("none (bug?)\n"); - return 4; - break; - case MOJODDS_TEXTURE_2D: printf("2D\n"); printf("\n"); diff --git a/glddstest.c b/glddstest.c index 79e7650..01cda55 100644 --- a/glddstest.c +++ b/glddstest.c @@ -84,7 +84,7 @@ static int glddstest(const char *filename) { unsigned long texlen = 0; unsigned int glfmt = 0, w = 0, h = 0, miplevels = 0; unsigned int cubemapfacelen = 0; - MOJODDS_textureType textureType = MOJODDS_TEXTURE_NONE; + MOJODDS_textureType textureType = 0; int retval = MOJODDS_getTexture(contents, size, &tex, &texlen, &glfmt, &w, &h, &miplevels, &cubemapfacelen, &textureType); if (!retval) { printf("MOJODDS_getTexture failed\n"); @@ -115,10 +115,6 @@ static int glddstest(const char *filename) { 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); diff --git a/mojodds.h b/mojodds.h index 3f9adee..4bbaa48 100644 --- a/mojodds.h +++ b/mojodds.h @@ -8,7 +8,6 @@ extern "C" { typedef enum MOJODDS_textureType { - MOJODDS_TEXTURE_NONE, MOJODDS_TEXTURE_2D, MOJODDS_TEXTURE_CUBE, MOJODDS_TEXTURE_VOLUME