about summary refs log tree commit diff
path: root/src/engine/external/glfw/lib/tga.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/external/glfw/lib/tga.c')
-rw-r--r--src/engine/external/glfw/lib/tga.c405
1 files changed, 405 insertions, 0 deletions
diff --git a/src/engine/external/glfw/lib/tga.c b/src/engine/external/glfw/lib/tga.c
new file mode 100644
index 00000000..51e73844
--- /dev/null
+++ b/src/engine/external/glfw/lib/tga.c
@@ -0,0 +1,405 @@
+//========================================================================

+// GLFW - An OpenGL framework

+// File:        tga.c

+// Platform:    Any

+// API version: 2.6

+// WWW:         http://glfw.sourceforge.net

+//------------------------------------------------------------------------

+// Copyright (c) 2002-2006 Camilla Berglund

+//

+// This software is provided 'as-is', without any express or implied

+// warranty. In no event will the authors be held liable for any damages

+// arising from the use of this software.

+//

+// Permission is granted to anyone to use this software for any purpose,

+// including commercial applications, and to alter it and redistribute it

+// freely, subject to the following restrictions:

+//

+// 1. The origin of this software must not be misrepresented; you must not

+//    claim that you wrote the original software. If you use this software

+//    in a product, an acknowledgment in the product documentation would

+//    be appreciated but is not required.

+//

+// 2. Altered source versions must be plainly marked as such, and must not

+//    be misrepresented as being the original software.

+//

+// 3. This notice may not be removed or altered from any source

+//    distribution.

+//

+//========================================================================

+

+//========================================================================

+// Description:

+//

+// TGA format image file loader. This module supports version 1 Targa

+// images, with these restrictions:

+//  - Pixel format may only be 8, 24 or 32 bits

+//  - Colormaps must be no longer than 256 entries

+//

+//========================================================================

+

+

+#include "internal.h"

+

+

+//************************************************************************

+//****            GLFW internal functions & declarations              ****

+//************************************************************************

+

+//========================================================================

+// TGA file header information

+//========================================================================

+

+typedef struct {

+    int idlen;                 // 1 byte

+    int cmaptype;              // 1 byte

+    int imagetype;             // 1 byte

+    int cmapfirstidx;          // 2 bytes

+    int cmaplen;               // 2 bytes

+    int cmapentrysize;         // 1 byte

+    int xorigin;               // 2 bytes

+    int yorigin;               // 2 bytes

+    int width;                 // 2 bytes

+    int height;                // 2 bytes

+    int bitsperpixel;          // 1 byte

+    int imageinfo;             // 1 byte

+    int _alphabits;            // (derived from imageinfo)

+    int _origin;               // (derived from imageinfo)

+} _tga_header_t;

+

+#define _TGA_CMAPTYPE_NONE      0

+#define _TGA_CMAPTYPE_PRESENT   1

+

+#define _TGA_IMAGETYPE_NONE     0

+#define _TGA_IMAGETYPE_CMAP     1

+#define _TGA_IMAGETYPE_TC       2

+#define _TGA_IMAGETYPE_GRAY     3

+#define _TGA_IMAGETYPE_CMAP_RLE 9

+#define _TGA_IMAGETYPE_TC_RLE   10

+#define _TGA_IMAGETYPE_GRAY_RLE 11

+

+#define _TGA_IMAGEINFO_ALPHA_MASK   0x0f

+#define _TGA_IMAGEINFO_ALPHA_SHIFT  0

+#define _TGA_IMAGEINFO_ORIGIN_MASK  0x30

+#define _TGA_IMAGEINFO_ORIGIN_SHIFT 4

+

+#define _TGA_ORIGIN_BL 0

+#define _TGA_ORIGIN_BR 1

+#define _TGA_ORIGIN_UL 2

+#define _TGA_ORIGIN_UR 3

+

+

+//========================================================================

+// _glfwReadTGAHeader() - Read TGA file header (and check that it is

+// valid)

+//========================================================================

+

+static int _glfwReadTGAHeader( _GLFWstream *s, _tga_header_t *h )

+{

+    unsigned char buf[ 18 ];

+    int pos;

+

+    // Read TGA file header from file

+    pos = _glfwTellStream( s );

+    _glfwReadStream( s, buf, 18 );

+

+    // Interpret header (endian independent parsing)

+    h->idlen         = (int) buf[0];

+    h->cmaptype      = (int) buf[1];

+    h->imagetype     = (int) buf[2];

+    h->cmapfirstidx  = (int) buf[3] | (((int) buf[4]) << 8);

+    h->cmaplen       = (int) buf[5] | (((int) buf[6]) << 8);

+    h->cmapentrysize = (int) buf[7];

+    h->xorigin       = (int) buf[8] | (((int) buf[9]) << 8);

+    h->yorigin       = (int) buf[10] | (((int) buf[11]) << 8);

+    h->width         = (int) buf[12] | (((int) buf[13]) << 8);

+    h->height        = (int) buf[14] | (((int) buf[15]) << 8);

+    h->bitsperpixel  = (int) buf[16];

+    h->imageinfo     = (int) buf[17];

+

+    // Extract alphabits and origin information

+    h->_alphabits = (int) (h->imageinfo & _TGA_IMAGEINFO_ALPHA_MASK) >>

+                     _TGA_IMAGEINFO_ALPHA_SHIFT;

+    h->_origin    = (int) (h->imageinfo & _TGA_IMAGEINFO_ORIGIN_MASK) >>

+                     _TGA_IMAGEINFO_ORIGIN_SHIFT;

+

+    // Validate TGA header (is this a TGA file?)

+    if( (h->cmaptype == 0 || h->cmaptype == 1) &&

+        ((h->imagetype >= 1 && h->imagetype <= 3) ||

+         (h->imagetype >= 9 && h->imagetype <= 11)) &&

+         (h->bitsperpixel == 8 || h->bitsperpixel == 24 ||

+          h->bitsperpixel == 32) )

+    {

+        // Skip the ID field

+        _glfwSeekStream( s, h->idlen, SEEK_CUR );

+

+        // Indicate that the TGA header was valid

+        return GL_TRUE;

+    }

+    else

+    {

+        // Restore file position

+        _glfwSeekStream( s, pos, SEEK_SET );

+

+        // Indicate that the TGA header was invalid

+        return GL_FALSE;

+    }

+}

+

+//========================================================================

+// _glfwReadTGA_RLE() - Read Run-Length Encoded data

+//========================================================================

+

+static void _glfwReadTGA_RLE( unsigned char *buf, int size, int bpp,

+    _GLFWstream *s )

+{

+    int repcount, bytes, k, n;

+    unsigned char pixel[ 4 ];

+    char c;

+

+    // Dummy check

+    if( bpp > 4 )

+    {

+        return;

+    }

+

+    while( size > 0 )

+    {

+        // Get repetition count

+	_glfwReadStream( s, &c, 1 );

+        repcount = (unsigned int) c;

+        bytes = ((repcount & 127) + 1) * bpp;

+        if( size < bytes )

+        {

+            bytes = size;

+        }

+

+        // Run-Length packet?

+        if( repcount & 128 )

+        {

+            _glfwReadStream( s, pixel, bpp );

+            for( n = 0; n < (repcount & 127) + 1; n ++ )

+            {

+                for( k = 0; k < bpp; k ++ )

+                {

+                    *buf ++ = pixel[ k ];

+                }

+            }

+        }

+        else

+        {

+            // It's a Raw packet

+            _glfwReadStream( s, buf, bytes );

+            buf += bytes;

+        }

+

+        size -= bytes;

+    }

+}

+

+

+//========================================================================

+// _glfwReadTGA() - Read a TGA image from a file

+//========================================================================

+

+int _glfwReadTGA( _GLFWstream *s, GLFWimage *img, int flags )

+{

+    _tga_header_t h;

+    unsigned char *cmap, *pix, tmp, *src, *dst;

+    int cmapsize, pixsize, pixsize2;

+    int bpp, bpp2, k, m, n, swapx, swapy;

+

+    // Read TGA header

+    if( !_glfwReadTGAHeader( s, &h ) )

+    {

+        return 0;

+    }

+

+    // Is there a colormap?

+    cmapsize = (h.cmaptype == _TGA_CMAPTYPE_PRESENT ? 1 : 0) * h.cmaplen *

+               ((h.cmapentrysize+7) / 8);

+    if( cmapsize > 0 )

+    {

+        // Is it a colormap that we can handle?

+        if( (h.cmapentrysize != 24 && h.cmapentrysize != 32) ||

+            h.cmaplen == 0 || h.cmaplen > 256 )

+        {

+            return 0;

+        }

+

+        // Allocate memory for colormap

+        cmap = (unsigned char *) malloc( cmapsize );

+        if( cmap == NULL )

+        {

+            return 0;

+        }

+

+        // Read colormap from file

+        _glfwReadStream( s, cmap, cmapsize );

+    }

+    else

+    {

+        cmap = NULL;

+    }

+

+    // Size of pixel data

+    pixsize = h.width * h.height * ((h.bitsperpixel + 7) / 8);

+

+    // Bytes per pixel (pixel data - unexpanded)

+    bpp = (h.bitsperpixel + 7) / 8;

+

+    // Bytes per pixel (expanded pixels - not colormap indeces)

+    if( cmap )

+    {

+        bpp2 = (h.cmapentrysize + 7) / 8;

+    }

+    else

+    {

+        bpp2 = bpp;

+    }

+

+    // For colormaped images, the RGB/RGBA image data may use more memory

+    // than the stored pixel data

+    pixsize2 = h.width * h.height * bpp2;

+

+    // Allocate memory for pixel data

+    pix = (unsigned char *) malloc( pixsize2 );

+    if( pix == NULL )

+    {

+        if( cmap )

+        {

+            free( cmap );

+        }

+        return 0;

+    }

+

+    // Read pixel data from file

+    if( h.imagetype >= _TGA_IMAGETYPE_CMAP_RLE )

+    {

+        _glfwReadTGA_RLE( pix, pixsize, bpp, s );

+    }

+    else

+    {

+        _glfwReadStream( s, pix, pixsize );

+    }

+

+    // If the image origin is not what we want, re-arrange the pixels

+    switch( h._origin )

+    {

+    default:

+    case _TGA_ORIGIN_UL:

+        swapx = 0;

+        swapy = 1;

+        break;

+

+    case _TGA_ORIGIN_BL:

+        swapx = 0;

+        swapy = 0;

+        break;

+

+    case _TGA_ORIGIN_UR:

+        swapx = 1;

+        swapy = 1;

+        break;

+

+    case _TGA_ORIGIN_BR:

+        swapx = 1;

+        swapy = 0;

+        break;

+    }

+    if( (swapy && !(flags & GLFW_ORIGIN_UL_BIT)) ||

+        (!swapy && (flags & GLFW_ORIGIN_UL_BIT)) )

+    {

+        src = pix;

+        dst = &pix[ (h.height-1)*h.width*bpp ];

+        for( n = 0; n < h.height/2; n ++ )

+        {

+            for( m = 0; m < h.width ; m ++ )

+            {

+                for( k = 0; k < bpp; k ++ )

+                {

+                    tmp     = *src;

+                    *src ++ = *dst;

+                    *dst ++ = tmp;

+                }

+            }

+            dst -= 2*h.width*bpp;

+        }

+    }

+    if( swapx )

+    {

+        src = pix;

+        dst = &pix[ (h.width-1)*bpp ];

+        for( n = 0; n < h.height; n ++ )

+        {

+            for( m = 0; m < h.width/2 ; m ++ )

+            {

+                for( k = 0; k < bpp; k ++ )

+                {

+                    tmp     = *src;

+                    *src ++ = *dst;

+                    *dst ++ = tmp;

+                }

+                dst -= 2*bpp;

+            }

+            src += ((h.width+1)/2)*bpp;

+            dst += ((3*h.width+1)/2)*bpp;

+        }

+    }

+

+    // Convert BGR/BGRA to RGB/RGBA, and optionally colormap indeces to

+    // RGB/RGBA values

+    if( cmap )

+    {

+        // Convert colormap pixel format (BGR -> RGB or BGRA -> RGBA)

+        if( bpp2 == 3 || bpp2 == 4 )

+        {

+            for( n = 0; n < h.cmaplen; n ++ )

+            {

+                tmp                = cmap[ n*bpp2 ];

+                cmap[ n*bpp2 ]     = cmap[ n*bpp2 + 2 ];

+                cmap[ n*bpp2 + 2 ] = tmp;

+            }

+        }

+

+        // Convert pixel data to RGB/RGBA data

+        for( m = h.width * h.height - 1; m >= 0; m -- )

+        {

+            n = pix[ m ];

+            for( k = 0; k < bpp2; k ++ )

+            {

+                pix[ m*bpp2 + k ] = cmap[ n*bpp2 + k ];

+            }

+        }

+

+        // Free memory for colormap (it's not needed anymore)

+        free( cmap );

+    }

+    else

+    {

+        // Convert image pixel format (BGR -> RGB or BGRA -> RGBA)

+        if( bpp2 == 3 || bpp2 == 4 )

+        {

+            src = pix;

+            dst = &pix[ 2 ];

+            for( n = 0; n < h.height * h.width; n ++ )

+            {

+                tmp  = *src;

+                *src = *dst;

+                *dst = tmp;

+                src += bpp2;

+                dst += bpp2;

+            }

+        }

+    }

+

+    // Fill out GLFWimage struct (the Format field will be set by

+    // glfwReadImage)

+    img->Width         = h.width;

+    img->Height        = h.height;

+    img->BytesPerPixel = bpp2;

+    img->Data          = pix;

+

+    return 1;

+}

+