Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Add TGA loader

  • Loading branch information...
commit f6cd60b08f05bbbf32952276d951a8b9a7af3204 1 parent 27b07d0
Jari Vetoniemi authored
3  lib/glhck/CMakeLists.txt
@@ -17,7 +17,8 @@ SET(GLHCK_SRC
17 17 src/src/geometry/cube.c
18 18 src/src/render/OpenGL.c
19 19 src/src/import/import.c
20   - src/src/import/import_mmd.c)
  20 + src/src/import/import_mmd.c
  21 + src/src/import/import_tga.c)
21 22
22 23 SET(GLHCK_INC
23 24 src/include/GL/glhck.h)
154 lib/glhck/src/src/import/import_tga.c
... ... @@ -0,0 +1,154 @@
  1 +/* TGA loader taken from imlib2 */
  2 +
  3 +#include "../internal.h"
  4 +#include "import.h"
  5 +#include <stdio.h>
  6 +
  7 +#ifdef __APPLE__
  8 +# include <malloc/malloc.h>
  9 +#else
  10 +# include <malloc.h>
  11 +#endif
  12 +
  13 +#define GLHCK_CHANNEL GLHCK_CHANNEL_IMPORT
  14 +
  15 +#define TGA_SIGNATURE "TRUEVISION-XFILE"
  16 +
  17 +/* TGA pixel formats */
  18 +#define TGA_TYPE_MAPPED 1
  19 +#define TGA_TYPE_COLOR 2
  20 +#define TGA_TYPE_GRAY 3
  21 +#define TGA_TYPE_MAPPED_RLE 9
  22 +#define TGA_TYPE_COLOR_RLE 10
  23 +#define TGA_TYPE_GRAY_RLE 11
  24 +
  25 +/* TGA header flags */
  26 +#define TGA_DESC_ABITS 0x0f
  27 +#define TGA_DESC_HORIZONTAL 0x10
  28 +#define TGA_DESC_VERTICAL 0x20
  29 +
  30 +typedef struct {
  31 + unsigned char idLength;
  32 + unsigned char colorMapType;
  33 + unsigned char imageType;
  34 + unsigned char colorMapIndexLo, colorMapIndexHi;
  35 + unsigned char colorMapLengthLo, colorMapLengthHi;
  36 + unsigned char colorMapSize;
  37 + unsigned char xOriginLo, xOriginHi;
  38 + unsigned char yOriginLo, yOriginHi;
  39 + unsigned char widthLo, widthHi;
  40 + unsigned char heightLo, heightHi;
  41 + unsigned char bpp;
  42 + unsigned char descriptor;
  43 +} tga_header;
  44 +
  45 +typedef struct {
  46 + unsigned int extensionAreaOffset;
  47 + unsigned int developerDirectoryOffset;
  48 + char signature[16];
  49 + char dot;
  50 + char null;
  51 +} tga_footer;
  52 +
  53 +/* \brief import TGA images */
  54 +int _glhckImportTga(_glhckTexture *texture, const char *file, const unsigned int flags)
  55 +{
  56 + FILE *f;
  57 + void *seg = NULL, *data;
  58 + int bpp, vinverted = 0;
  59 + int rle = 0, footer_present = 0;
  60 + size_t size;
  61 + unsigned short w, h;
  62 + tga_header *header;
  63 + tga_footer *footer;
  64 +
  65 + CALL(0, "%p, %s, %d", texture, file, flags);
  66 +
  67 + if (!(f = fopen(file, "rb")))
  68 + goto read_fail;
  69 +
  70 + fseek(f, 0L, SEEK_END);
  71 + if ((size = ftell(f)) < sizeof(tga_header) + sizeof(tga_footer))
  72 + goto not_possible;
  73 +
  74 + if (!(seg = malloc(size)))
  75 + goto out_of_memory;
  76 +
  77 + fseek(f, 0L, SEEK_SET);
  78 + if (fread(seg, 1, size, f) != size)
  79 + goto fail;
  80 +
  81 + /* we don't need the file anymore */
  82 + fclose(f); f = NULL;
  83 +
  84 + data = seg;
  85 + header = (tga_header*)data;
  86 + footer = (tga_footer*)((char*)data+size-sizeof(tga_footer));
  87 +
  88 + /* is TGA v2.0? (stop storing the headers at EOF please) */
  89 + if (!memcmp(footer->signature, TGA_SIGNATURE, sizeof(footer->signature)))
  90 + footer_present = 1;
  91 +
  92 + /* skip over header */
  93 + data = (char*)data+sizeof(tga_header);
  94 +
  95 + /* skip over ID filed */
  96 + if (header->idLength)
  97 + data = (char*)data+header->idLength;
  98 +
  99 + vinverted = !(header->descriptor & TGA_DESC_VERTICAL);
  100 + switch (header->imageType) {
  101 + case TGA_TYPE_COLOR_RLE:
  102 + case TGA_TYPE_GRAY_RLE:
  103 + rle = 1;
  104 + break;
  105 +
  106 + case TGA_TYPE_COLOR:
  107 + case TGA_TYPE_GRAY:
  108 + rle = 0;
  109 + break;
  110 +
  111 + default:
  112 + goto unknown_type;
  113 + }
  114 +
  115 + bpp = header->bpp;
  116 + if (!((bpp == 32) || (bpp == 24) || (bpp == 8)))
  117 + goto invalid_bpp;
  118 +
  119 + /* endian safe for 16-bit dimensions */
  120 + w = (header->widthHi << 8) | header->widthLo;
  121 + h = (header->heightHi << 8) | header->heightLo;
  122 +
  123 + if (!_glhckIsValidImageDimension(w, h))
  124 + goto bad_dimensions;
  125 +
  126 + /* load image data here */
  127 + RET(0, "%d", RETURN_OK);
  128 + return RETURN_OK;
  129 +
  130 +read_fail:
  131 + DEBUG(GLHCK_DBG_ERROR, "Failed to open: %s", file);
  132 + goto fail;
  133 +not_possible:
  134 + DEBUG(GLHCK_DBG_ERROR, "Assumed TGA file '%s' has too small filesize", file);
  135 + goto fail;
  136 +out_of_memory:
  137 + DEBUG(GLHCK_DBG_ERROR, "Out of memory, won't load file: %s", file);
  138 + goto fail;
  139 +unknown_type:
  140 + DEBUG(GLHCK_DBG_ERROR, "Unknown TGA image type");
  141 + goto fail;
  142 +invalid_bpp:
  143 + DEBUG(GLHCK_DBG_ERROR, "TGA image is not either 32, 24 or 8 bpp");
  144 + goto fail;
  145 +bad_dimensions:
  146 + DEBUG(GLHCK_DBG_ERROR, "TGA image has invalid dimension %dx%d", w, h);
  147 +fail:
  148 + IFDO(fclose, f);
  149 + IFDO(free, seg);
  150 + RET(0, "%d", RETURN_FAIL);
  151 + return RETURN_FAIL;
  152 +}
  153 +
  154 +/* vim: set ts=8 sw=3 tw=0 :*/

0 comments on commit f6cd60b

Please sign in to comment.
Something went wrong with that request. Please try again.