1//
2// Book:      OpenGL(R) ES 2.0 Programming Guide
3// Authors:   Aaftab Munshi, Dan Ginsburg, Dave Shreiner
4// ISBN-10:   0321502795
5// ISBN-13:   9780321502797
6// Publisher: Addison-Wesley Professional
7// URLs:      http://safari.informit.com/9780321563835
8//            http://www.opengles-book.com
9//
10
11// esUtil_TGA.c
12//
13//    This file contains the Win32 implementation of a TGA image loader
14
15#include <windows.h>
16#include <stdio.h>
17#include <stdlib.h>
18
19///
20//  Macros
21//
22#define INVERTED_BIT            (1 << 5)
23
24///
25//  Types
26//
27#pragma pack(push,x1)                            // Byte alignment (8-bit)
28#pragma pack(1)
29
30typedef struct
31{
32   unsigned char  IdSize,
33                  MapType,
34                  ImageType;
35   unsigned short PaletteStart,
36                  PaletteSize;
37   unsigned char  PaletteEntryDepth;
38   unsigned short X,
39                  Y,
40                  Width,
41                  Height;
42   unsigned char  ColorDepth,
43                  Descriptor;
44
45} TGA_HEADER;
46
47#pragma pack(pop,x1)
48
49////////////////////////////////////////////////////////////////////////////////////
50//
51//  Private Functions
52//
53
54////////////////////////////////////////////////////////////////////////////////////
55//
56//  Public Functions
57//
58//
59
60
61///
62//  WinTGALoad()
63//
64int WinTGALoad( const char *fileName, char **buffer, int *width, int *height )
65{
66   FILE        *fp;
67   TGA_HEADER   Header;
68
69   if ( fopen_s ( &fp, fileName, "rb" ) != 0 )
70   {
71      return FALSE;
72   }
73
74   if ( fp == NULL )
75   {
76      return FALSE;
77   }
78
79   fread ( &Header, sizeof(TGA_HEADER), 1, fp );
80
81   *width = Header.Width;
82   *height = Header.Height;
83
84   if ( Header.ColorDepth == 24 )
85   {
86      RGBTRIPLE *Buffer24;
87
88      Buffer24= (RGBTRIPLE*)malloc(sizeof(RGBTRIPLE) * (*width) * (*height));
89
90      if(Buffer24)
91      {
92         int i=0;
93         int x,
94             y;
95
96         fread(Buffer24, sizeof(RGBTRIPLE), (*width) * (*height), fp);
97
98         *buffer= (LPSTR) malloc(3 * (*width) * (*height));
99
100         for ( y = 0; y < *height; y++ )
101            for( x = 0; x < *width; x++ )
102            {
103               int Index= y * (*width) + x;
104
105               if(!(Header.Descriptor & INVERTED_BIT))
106                  Index= ((*height) - 1 - y) * (*width) + x;
107
108               (*buffer)[(i * 3)]=      Buffer24[Index].rgbtRed;
109               (*buffer)[(i * 3) + 1]=  Buffer24[Index].rgbtGreen;
110               (*buffer)[(i * 3) + 2]=  Buffer24[Index].rgbtBlue;
111
112               i++;
113            }
114
115         fclose(fp);
116         free(Buffer24);
117         return(TRUE);
118      }
119   }
120
121   return(FALSE);
122}
123