# HG changeset patch # User John Tsiombikas # Date 1515480196 -7200 # Node ID ed40258af7adab480d6af518abf173139ffe8d3d # Parent f941fd7128c52a13c4c02a820dd0abdb1dd08bb0 added format enumeration and cleaned up the code diff -r f941fd7128c5 -r ed40258af7ad main.c --- a/main.c Tue Jan 09 08:15:12 2018 +0200 +++ b/main.c Tue Jan 09 08:43:16 2018 +0200 @@ -20,6 +20,9 @@ void reshape(int x, int y); void keyb(unsigned char key, int x, int y); void gen_image(unsigned char *pixels, int xsz, int ysz); +unsigned char *load_compressed_image(const char *fname, int *cszptr, int *xszptr, int *yszptr); +int dump_compressed_image(const char *fname, unsigned char *data, int size, int w, int h); +void print_compressed_formats(void); unsigned int tex, comp_tex; const char *texfile; @@ -57,36 +60,14 @@ int ysz = 512; int is_comp = 0; int comp_size = 0; - int start, tmp; - FILE *fp; + int tmp; + + print_compressed_formats(); if(texfile) { - if(!(fp = fopen(texfile, "rb"))) { - fprintf(stderr, "failed to open compressed texture file: %s: %s\n", texfile, strerror(errno)); + if(!(pixels = load_compressed_image(texfile, &comp_size, &xsz, &ysz))) { return -1; } - - if(fread(&xsz, sizeof xsz, 1, fp) < 1 || fread(&ysz, sizeof ysz, 1, fp) < 1) { - fprintf(stderr, "failed to read compressed texture file header: %s: %s\n", texfile, strerror(errno)); - fclose(fp); - return -1; - } - start = ftell(fp); - fseek(fp, 0, SEEK_END); - comp_size = ftell(fp) - start; - fseek(fp, start, SEEK_SET); - - if(!(pixels = malloc(comp_size))) { - abort(); - } - if(fread(pixels, 1, comp_size, fp) < comp_size) { - fprintf(stderr, "failed to read compressed texture file: %s: %s\n", texfile, strerror(errno)); - fclose(fp); - free(pixels); - return -1; - } - fclose(fp); - printf("loaded compressed texture file: %s (%dx%d)\n", texfile, xsz, ysz); } else { @@ -101,17 +82,7 @@ } printf("compressed texture is %d bytes (uncompressed was: %d)\n", comp_size, xsz * ysz * 3); - /* dump compressed texture */ - if(!(fp = fopen("compressed_texture", "wb"))) { - fprintf(stderr, "failed to open compressed texture dump file: %s\n", strerror(errno)); - } else { - if(fwrite(&xsz, sizeof xsz, 1, fp) < 1 || - fwrite(&ysz, sizeof ysz, 1, fp) < 1 || - fwrite(pixels, 1, comp_size, fp) < comp_size) { - fprintf(stderr, "failed to dump compressed texture: %s\n", strerror(errno)); - } - fclose(fp); - } + dump_compressed_image("compressed_texture", pixels, comp_size, xsz, ysz); } glGenTextures(1, &tex); @@ -143,9 +114,9 @@ if(memcmp(pixels, buf, comp_size) != 0) { fprintf(stderr, "submitted and retrieved pixel data differ!\n"); - return -1; + } else { + printf("submitted and retrieved sizes match (%d bytes)\n", comp_size); } - printf("submitted and retrieved sizes match (%d bytes)\n", comp_size); free(buf); free(pixels); @@ -229,3 +200,122 @@ } } } + +unsigned char *load_compressed_image(const char *fname, int *cszptr, int *xszptr, int *yszptr) +{ + unsigned char *pixels; + long start, comp_size; + int xsz, ysz; + FILE *fp; + + if(!(fp = fopen(texfile, "rb"))) { + fprintf(stderr, "failed to open compressed texture file: %s: %s\n", texfile, strerror(errno)); + return 0; + } + + if(fread(&xsz, sizeof xsz, 1, fp) < 1 || fread(&ysz, sizeof ysz, 1, fp) < 1) { + fprintf(stderr, "failed to read compressed texture file header: %s: %s\n", texfile, strerror(errno)); + fclose(fp); + return 0; + } + start = ftell(fp); + fseek(fp, 0, SEEK_END); + comp_size = ftell(fp) - start; + fseek(fp, start, SEEK_SET); + + if(!(pixels = malloc(comp_size))) { + perror("failed to allocate pixel buffer"); + return 0; + } + if(fread(pixels, 1, comp_size, fp) < comp_size) { + fprintf(stderr, "failed to read compressed texture file: %s: %s\n", texfile, strerror(errno)); + fclose(fp); + free(pixels); + return 0; + } + fclose(fp); + + *cszptr = comp_size; + *xszptr = xsz; + *yszptr = ysz; + return pixels; +} + +int dump_compressed_image(const char *fname, unsigned char *data, int size, int w, int h) +{ + FILE *fp; + + if(!(fp = fopen(fname, "wb"))) { + fprintf(stderr, "failed to open compressed texture dump file: %s: %s\n", fname, strerror(errno)); + return -1; + } + + if(fwrite(&w, sizeof w, 1, fp) < 1 || + fwrite(&h, sizeof h, 1, fp) < 1 || + fwrite(data, 1, size, fp) < size) { + fprintf(stderr, "failed to dump compressed texture: %s\n", strerror(errno)); + } + fclose(fp); + return 0; +} + +const char *fmtstr(int fmt) +{ + switch(fmt) { + case 0x86b0: return "GL_COMPRESSED_RGB_FXT1_3DFX"; + case 0x86b1: return "GL_COMPRESSED_RGBA_FXT1_3DFX"; + case 0x8dbb: return "GL_COMPRESSED_RED_RGTC1"; + case 0x8dbc: return "GL_COMPRESSED_SIGNED_RED_RGTC1"; + case 0x8dbd: return "GL_COMPRESSED_RG_RGTC2"; + case 0x8dbe: return "GL_COMPRESSED_SIGNED_RG_RGTC2"; + case 0x8e8c: return "GL_COMPRESSED_RGBA_BPTC_UNORM"; + case 0x8e8d: return "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM"; + case 0x8e8e: return "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT"; + case 0x8e8f: return "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT"; + case 0x9274: return "GL_COMPRESSED_RGB8_ETC2"; + case 0x9275: return "GL_COMPRESSED_SRGB8_ETC2"; + case 0x9276: return "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2"; + case 0x9277: return "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2"; + case 0x9278: return "GL_COMPRESSED_RGBA8_ETC2_EAC"; + case 0x9279: return "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC"; + case 0x9270: return "GL_COMPRESSED_R11_EAC"; + case 0x9271: return "GL_COMPRESSED_SIGNED_R11_EAC"; + case 0x9272: return "GL_COMPRESSED_RG11_EAC"; + case 0x9273: return "GL_COMPRESSED_SIGNED_RG11_EAC"; + case 0x83F0: return "GL_COMPRESSED_RGB_S3TC_DXT1_EXT"; + case 0x83F1: return "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT"; + case 0x83F2: return "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT"; + case 0x83F3: return "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT"; + case 0x8C48: return "GL_COMPRESSED_SRGB_EXT"; + case 0x8C49: return "GL_COMPRESSED_SRGB_ALPHA_EXT"; + case 0x8C4A: return "GL_COMPRESSED_SLUMINANCE_EXT"; + case 0x8C4B: return "GL_COMPRESSED_SLUMINANCE_ALPHA_EXT"; + case 0x8C4C: return "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT"; + case 0x8C4D: return "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT"; + case 0x8C4E: return "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT"; + case 0x8C4F: return "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT"; + default: + break; + } + return "unknown"; +} + +void print_compressed_formats(void) +{ + int i, num_fmt; + int *fmtlist; + + glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_fmt); + printf("%d generic compressed texture formats available:\n", num_fmt); + + if(!(fmtlist = malloc(num_fmt * sizeof *fmtlist))) { + fprintf(stderr, "failed to allocate texture formats enumeration buffer\n"); + return; + } + glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, fmtlist); + + for(i=0; i