Advertisement
Guest User

vanjalolz

a guest
Dec 1st, 2007
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 14.39 KB | None | 0 0
  1. /*
  2.  *  tga.h
  3.  *
  4.  *
  5.  */
  6. #include "config.h"
  7. #ifdef __APPLE__
  8. #include <GLUT/glut.h>
  9. #else
  10. #include <GL/glut.h>
  11. #endif
  12.  
  13. GLuint
  14. loadTGATexture (const char *filename, GLuint texid = 0);
  15.  
  16. /*
  17.  *  tga.cpp
  18.  *
  19.  */
  20.  
  21. #include "tga.h"
  22.  
  23.  
  24. /*
  25.  * tga.c -- tga texture loader
  26.  * last modification: dec. 15, 2005
  27.  *
  28.  * Copyright (c) 2005 David HENRY
  29.  *
  30.  * Permission is hereby granted, free of charge, to any person
  31.  * obtaining a copy of this software and associated documentation
  32.  * files (the "Software"), to deal in the Software without
  33.  * restriction, including without limitation the rights to use,
  34.  * copy, modify, merge, publish, distribute, sublicense, and/or
  35.  * sell copies of the Software, and to permit persons to whom the
  36.  * Software is furnished to do so, subject to the following conditions:
  37.  *
  38.  * The above copyright notice and this permission notice shall be
  39.  * included in all copies or substantial portions of the Software.
  40.  *
  41.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  42.  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  43.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  44.  * NONINFRINGEMENT.
  45.  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
  46.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  47.  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  48.  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  49.  *
  50.  * gcc -Wall -ansi -L/usr/X11R6/lib -lGL -lGLU -lglut tga.c -o tga
  51.  */
  52.  
  53. #include <stdio.h>
  54. #include <stdlib.h>
  55.  
  56.  
  57. /* OpenGL texture info */
  58. typedef struct
  59. {
  60.     GLsizei width;
  61.     GLsizei height;
  62.    
  63.     GLenum format;
  64.     GLint   internalFormat;
  65.     GLuint id;
  66.    
  67.     GLubyte *texels;
  68.    
  69. } gl_texture_t;
  70.  
  71.  
  72. #pragma pack(push, 1)
  73. /* tga header */
  74. typedef struct
  75. {
  76.     GLubyte id_lenght;          /* size of image id */
  77.     GLubyte colormap_type;      /* 1 is has a colormap */
  78.     GLubyte image_type;         /* compression type */
  79.    
  80.     short   cm_first_entry;       /* colormap origin */
  81.     short   cm_length;            /* colormap length */
  82.     GLubyte cm_size;            /* colormap size */
  83.    
  84.     short   x_origin;             /* bottom left x coord origin */
  85.     short   y_origin;             /* bottom left y coord origin */
  86.    
  87.     short   width;                /* picture width (in pixels) */
  88.     short   height;               /* picture height (in pixels) */
  89.    
  90.     GLubyte pixel_depth;        /* bits per pixel: 8, 16, 24 or 32 */
  91.     GLubyte image_descriptor;   /* 24 bits = 0x00; 32 bits = 0x80 */
  92.    
  93. } tga_header_t;
  94. #pragma pack(pop)
  95.  
  96.  
  97. /* texture id for exemple */
  98. GLuint texId = 0;
  99.  
  100.  
  101. void
  102. GetTextureInfo (tga_header_t *header, gl_texture_t *texinfo)
  103. {
  104.     texinfo->width = header->width;
  105.     texinfo->height = header->height;
  106.    
  107.     switch (header->image_type)
  108.     {
  109.         case 3:  /* grayscale 8 bits */
  110.         case 11: /* grayscale 8 bits (RLE) */
  111.         {
  112.             if (header->pixel_depth == 8)
  113.             {
  114.                 texinfo->format = GL_LUMINANCE;
  115.                 texinfo->internalFormat = 1;
  116.             }
  117.             else /* 16 bits */
  118.             {
  119.                 texinfo->format = GL_LUMINANCE_ALPHA;
  120.                 texinfo->internalFormat = 2;
  121.             }
  122.            
  123.             break;
  124.         }
  125.            
  126.         case 1:  /* 8 bits color index */
  127.         case 2:  /* BGR 16-24-32 bits */
  128.         case 9:  /* 8 bits color index (RLE) */
  129.         case 10: /* BGR 16-24-32 bits (RLE) */
  130.         {
  131.             /* 8 bits and 16 bits images will be converted to 24 bits */
  132.             if (header->pixel_depth <= 24)
  133.             {
  134.                 texinfo->format = GL_RGB;
  135.                 texinfo->internalFormat = 3;
  136.             }
  137.             else /* 32 bits */
  138.             {
  139.                 texinfo->format = GL_RGBA;
  140.                 texinfo->internalFormat = 4;
  141.             }
  142.            
  143.             break;
  144.         }
  145.     }
  146. }
  147.  
  148.  
  149. void
  150. ReadTGA8bits (FILE *fp, GLubyte *colormap, gl_texture_t *texinfo)
  151. {
  152.     int i;
  153.     GLubyte color;
  154.    
  155.     for (i = 0; i < texinfo->width * texinfo->height; ++i)
  156.     {
  157.         /* read index color byte */
  158.         color = (GLubyte)fgetc (fp);
  159.        
  160.         /* convert to RGB 24 bits */
  161.         texinfo->texels[(i * 3) + 2] = colormap[(color * 3) + 0];
  162.         texinfo->texels[(i * 3) + 1] = colormap[(color * 3) + 1];
  163.         texinfo->texels[(i * 3) + 0] = colormap[(color * 3) + 2];
  164.     }
  165. }
  166.  
  167.  
  168. void
  169. ReadTGA16bits (FILE *fp, gl_texture_t *texinfo)
  170. {
  171.     int i;
  172.     unsigned short color;
  173.    
  174.     for (i = 0; i < texinfo->width * texinfo->height; ++i)
  175.     {
  176.         /* read color word */
  177.         color = fgetc (fp) + (fgetc (fp) << 8);
  178.        
  179.         /* convert BGR to RGB */
  180.         texinfo->texels[(i * 3) + 0] = (GLubyte)(((color & 0x7C00) >> 10) << 3);
  181.         texinfo->texels[(i * 3) + 1] = (GLubyte)(((color & 0x03E0) >>  5) << 3);
  182.         texinfo->texels[(i * 3) + 2] = (GLubyte)(((color & 0x001F) >>  0) << 3);
  183.     }
  184. }
  185.  
  186.  
  187. void
  188. ReadTGA24bits (FILE *fp, gl_texture_t *texinfo)
  189. {
  190.     int i;
  191.    
  192.     for (i = 0; i < texinfo->width * texinfo->height; ++i)
  193.     {
  194.         /* read and convert BGR to RGB */
  195.         texinfo->texels[(i * 3) + 2] = (GLubyte)fgetc (fp);
  196.         texinfo->texels[(i * 3) + 1] = (GLubyte)fgetc (fp);
  197.         texinfo->texels[(i * 3) + 0] = (GLubyte)fgetc (fp);
  198.     }
  199. }
  200.  
  201.  
  202. void
  203. ReadTGA32bits (FILE *fp, gl_texture_t *texinfo)
  204. {
  205.     int i;
  206.    
  207.     for (i = 0; i < texinfo->width * texinfo->height; ++i)
  208.     {
  209.         /* read and convert BGRA to RGBA */
  210.         texinfo->texels[(i * 4) + 2] = (GLubyte)fgetc (fp);
  211.         texinfo->texels[(i * 4) + 1] = (GLubyte)fgetc (fp);
  212.         texinfo->texels[(i * 4) + 0] = (GLubyte)fgetc (fp);
  213.         texinfo->texels[(i * 4) + 3] = (GLubyte)fgetc (fp);
  214.     }
  215. }
  216.  
  217.  
  218. void
  219. ReadTGAgray8bits (FILE *fp, gl_texture_t *texinfo)
  220. {
  221.     int i;
  222.    
  223.     for (i = 0; i < texinfo->width * texinfo->height; ++i)
  224.     {
  225.         /* read grayscale color byte */
  226.         texinfo->texels[i] = (GLubyte)fgetc (fp);
  227.     }
  228. }
  229.  
  230.  
  231. void
  232. ReadTGAgray16bits (FILE *fp, gl_texture_t *texinfo)
  233. {
  234.     int i;
  235.    
  236.     for (i = 0; i < texinfo->width * texinfo->height; ++i)
  237.     {
  238.         /* read grayscale color + alpha channel bytes */
  239.         texinfo->texels[(i * 2) + 0] = (GLubyte)fgetc (fp);
  240.         texinfo->texels[(i * 2) + 1] = (GLubyte)fgetc (fp);
  241.     }
  242. }
  243.  
  244.  
  245. void
  246. ReadTGA8bitsRLE (FILE *fp, GLubyte *colormap, gl_texture_t *texinfo)
  247. {
  248.     int i, size;
  249.     GLubyte color;
  250.     GLubyte packet_header;
  251.     GLubyte *ptr = texinfo->texels;
  252.    
  253.     while (ptr < texinfo->texels + (texinfo->width * texinfo->height) * 3)
  254.     {
  255.         /* read first byte */
  256.         packet_header = (GLubyte)fgetc (fp);
  257.         size = 1 + (packet_header & 0x7f);
  258.        
  259.         if (packet_header & 0x80)
  260.         {
  261.             /* run-length packet */
  262.             color = (GLubyte)fgetc (fp);
  263.            
  264.             for (i = 0; i < size; ++i, ptr += 3)
  265.             {
  266.                 ptr[0] = colormap[(color * 3) + 2];
  267.                 ptr[1] = colormap[(color * 3) + 1];
  268.                 ptr[2] = colormap[(color * 3) + 0];
  269.             }
  270.         }
  271.         else
  272.         {
  273.             /* non run-length packet */
  274.             for (i = 0; i < size; ++i, ptr += 3)
  275.             {
  276.                 color = (GLubyte)fgetc (fp);
  277.                
  278.                 ptr[0] = colormap[(color * 3) + 2];
  279.                 ptr[1] = colormap[(color * 3) + 1];
  280.                 ptr[2] = colormap[(color * 3) + 0];
  281.             }
  282.         }
  283.     }
  284. }
  285.  
  286.  
  287. void
  288. ReadTGA16bitsRLE (FILE *fp, gl_texture_t *texinfo)
  289. {
  290.     int i, size;
  291.     unsigned short color;
  292.     GLubyte packet_header;
  293.     GLubyte *ptr = texinfo->texels;
  294.    
  295.     while (ptr < texinfo->texels + (texinfo->width * texinfo->height) * 3)
  296.     {
  297.         /* read first byte */
  298.         packet_header = fgetc (fp);
  299.         size = 1 + (packet_header & 0x7f);
  300.        
  301.         if (packet_header & 0x80)
  302.         {
  303.             /* run-length packet */
  304.             color = fgetc (fp) + (fgetc (fp) << 8);
  305.            
  306.             for (i = 0; i < size; ++i, ptr += 3)
  307.             {
  308.                 ptr[0] = (GLubyte)(((color & 0x7C00) >> 10) << 3);
  309.                 ptr[1] = (GLubyte)(((color & 0x03E0) >>  5) << 3);
  310.                 ptr[2] = (GLubyte)(((color & 0x001F) >>  0) << 3);
  311.             }
  312.         }
  313.         else
  314.         {
  315.             /* non run-length packet */
  316.             for (i = 0; i < size; ++i, ptr += 3)
  317.             {
  318.                 color = fgetc (fp) + (fgetc (fp) << 8);
  319.                
  320.                 ptr[0] = (GLubyte)(((color & 0x7C00) >> 10) << 3);
  321.                 ptr[1] = (GLubyte)(((color & 0x03E0) >>  5) << 3);
  322.                 ptr[2] = (GLubyte)(((color & 0x001F) >>  0) << 3);
  323.             }
  324.         }
  325.     }
  326. }
  327.  
  328.  
  329. void
  330. ReadTGA24bitsRLE (FILE *fp, gl_texture_t *texinfo)
  331. {
  332.     int i, size;
  333.     GLubyte rgb[3];
  334.     GLubyte packet_header;
  335.     GLubyte *ptr = texinfo->texels;
  336.    
  337.     while (ptr < texinfo->texels + (texinfo->width * texinfo->height) * 3)
  338.     {
  339.         /* read first byte */
  340.         packet_header = (GLubyte)fgetc (fp);
  341.         size = 1 + (packet_header & 0x7f);
  342.        
  343.         if (packet_header & 0x80)
  344.         {
  345.             /* run-length packet */
  346.             fread (rgb, sizeof (GLubyte), 3, fp);
  347.            
  348.             for (i = 0; i < size; ++i, ptr += 3)
  349.             {
  350.                 ptr[0] = rgb[2];
  351.                 ptr[1] = rgb[1];
  352.                 ptr[2] = rgb[0];
  353.             }
  354.         }
  355.         else
  356.         {
  357.             /* non run-length packet */
  358.             for (i = 0; i < size; ++i, ptr += 3)
  359.             {
  360.                 ptr[2] = (GLubyte)fgetc (fp);
  361.                 ptr[1] = (GLubyte)fgetc (fp);
  362.                 ptr[0] = (GLubyte)fgetc (fp);
  363.             }
  364.         }
  365.     }
  366. }
  367.  
  368.  
  369. void
  370. ReadTGA32bitsRLE (FILE *fp, gl_texture_t *texinfo)
  371. {
  372.     int i, size;
  373.     GLubyte rgba[4];
  374.     GLubyte packet_header;
  375.     GLubyte *ptr = texinfo->texels;
  376.    
  377.     while (ptr < texinfo->texels + (texinfo->width * texinfo->height) * 4)
  378.     {
  379.         /* read first byte */
  380.         packet_header = (GLubyte)fgetc (fp);
  381.         size = 1 + (packet_header & 0x7f);
  382.        
  383.         if (packet_header & 0x80)
  384.         {
  385.             /* run-length packet */
  386.             fread (rgba, sizeof (GLubyte), 4, fp);
  387.            
  388.             for (i = 0; i < size; ++i, ptr += 4)
  389.             {
  390.                 ptr[0] = rgba[2];
  391.                 ptr[1] = rgba[1];
  392.                 ptr[2] = rgba[0];
  393.                 ptr[3] = rgba[3];
  394.             }
  395.         }
  396.         else
  397.         {
  398.             /* non run-length packet */
  399.             for (i = 0; i < size; ++i, ptr += 4)
  400.             {
  401.                 ptr[2] = (GLubyte)fgetc (fp);
  402.                 ptr[1] = (GLubyte)fgetc (fp);
  403.                 ptr[0] = (GLubyte)fgetc (fp);
  404.                 ptr[3] = (GLubyte)fgetc (fp);
  405.             }
  406.         }
  407.     }
  408. }
  409.  
  410.  
  411. void
  412. ReadTGAgray8bitsRLE (FILE *fp, gl_texture_t *texinfo)
  413. {
  414.     int i, size;
  415.     GLubyte color;
  416.     GLubyte packet_header;
  417.     GLubyte *ptr = texinfo->texels;
  418.    
  419.     while (ptr < texinfo->texels + (texinfo->width * texinfo->height))
  420.     {
  421.         /* read first byte */
  422.         packet_header = (GLubyte)fgetc (fp);
  423.         size = 1 + (packet_header & 0x7f);
  424.        
  425.         if (packet_header & 0x80)
  426.         {
  427.             /* run-length packet */
  428.             color = (GLubyte)fgetc (fp);
  429.            
  430.             for (i = 0; i < size; ++i, ptr++)
  431.                 *ptr = color;
  432.         }
  433.         else
  434.         {
  435.             /* non run-length packet */
  436.             for (i = 0; i < size; ++i, ptr++)
  437.                 *ptr = (GLubyte)fgetc (fp);
  438.         }
  439.     }
  440. }
  441.  
  442.  
  443. void
  444. ReadTGAgray16bitsRLE (FILE *fp, gl_texture_t *texinfo)
  445. {
  446.     int i, size;
  447.     GLubyte color, alpha;
  448.     GLubyte packet_header;
  449.     GLubyte *ptr = texinfo->texels;
  450.    
  451.     while (ptr < texinfo->texels + (texinfo->width * texinfo->height) * 2)
  452.     {
  453.         /* read first byte */
  454.         packet_header = (GLubyte)fgetc (fp);
  455.         size = 1 + (packet_header & 0x7f);
  456.        
  457.         if (packet_header & 0x80)
  458.         {
  459.             /* run-length packet */
  460.             color = (GLubyte)fgetc (fp);
  461.             alpha = (GLubyte)fgetc (fp);
  462.            
  463.             for (i = 0; i < size; ++i, ptr += 2)
  464.             {
  465.                 ptr[0] = color;
  466.                 ptr[1] = alpha;
  467.             }
  468.         }
  469.         else
  470.         {
  471.             /* non run-length packet */
  472.             for (i = 0; i < size; ++i, ptr += 2)
  473.             {
  474.                 ptr[0] = (GLubyte)fgetc (fp);
  475.                 ptr[1] = (GLubyte)fgetc (fp);
  476.             }
  477.         }
  478.     }
  479. }
  480.  
  481.  
  482. gl_texture_t *
  483. ReadTGAFile (const char *filename)
  484. {
  485.     FILE *fp;
  486.     gl_texture_t *texinfo;
  487.     tga_header_t header;
  488.     GLubyte *colormap = NULL;
  489.    
  490.     fp = fopen (filename, "rb");
  491.     if (!fp)
  492.     {
  493.         fprintf (stderr, "error: couldn't open \"%s\"!\n", filename);
  494.         return NULL;
  495.     }
  496.    
  497.     /* read header */
  498.     fread (&header, sizeof (tga_header_t), 1, fp);
  499.    
  500.     texinfo = (gl_texture_t *)malloc (sizeof (gl_texture_t));
  501.     GetTextureInfo (&header, texinfo);
  502.     fseek (fp, header.id_lenght, SEEK_CUR);
  503.    
  504.     /* memory allocation */
  505.     texinfo->texels = (GLubyte *)malloc (sizeof (GLubyte) *
  506.                                          texinfo->width * texinfo->height * texinfo->internalFormat);
  507.     if (!texinfo->texels)
  508.     {
  509.         free (texinfo);
  510.         return NULL;
  511.     }
  512.    
  513.     /* read color map */
  514.     if (header.colormap_type)
  515.     {
  516.         /* NOTE: color map is stored in BGR format */
  517.         colormap = (GLubyte *)malloc (sizeof (GLubyte)
  518.                                       * header.cm_length * (header.cm_size >> 3));
  519.         fread (colormap, sizeof (GLubyte), header.cm_length
  520.                * (header.cm_size >> 3), fp);
  521.     }
  522.    
  523.     /* read image data */
  524.     switch (header.image_type)
  525.     {
  526.         case 0:
  527.             /* no data */
  528.             break;
  529.            
  530.         case 1:
  531.             /* uncompressed 8 bits color index */
  532.             ReadTGA8bits (fp, colormap, texinfo);
  533.             break;
  534.            
  535.         case 2:
  536.             /* uncompressed 16-24-32 bits */
  537.             switch (header.pixel_depth)
  538.         {
  539.             case 16:
  540.                 ReadTGA16bits (fp, texinfo);
  541.                 break;
  542.                
  543.             case 24:
  544.                 ReadTGA24bits (fp, texinfo);
  545.                 break;
  546.                
  547.             case 32:
  548.                 ReadTGA32bits (fp, texinfo);
  549.                 break;
  550.         }
  551.            
  552.             break;
  553.            
  554.         case 3:
  555.             /* uncompressed 8 or 16 bits grayscale */
  556.             if (header.pixel_depth == 8)
  557.                 ReadTGAgray8bits (fp, texinfo);
  558.             else /* 16 */
  559.                 ReadTGAgray16bits (fp, texinfo);
  560.            
  561.             break;
  562.            
  563.             case 9:
  564.             /* RLE compressed 8 bits color index */
  565.             ReadTGA8bitsRLE (fp, colormap, texinfo);
  566.             break;
  567.            
  568.             case 10:
  569.             /* RLE compressed 16-24-32 bits */
  570.             switch (header.pixel_depth)
  571.         {
  572.             case 16:
  573.                 ReadTGA16bitsRLE (fp, texinfo);
  574.                 break;
  575.                
  576.             case 24:
  577.                 ReadTGA24bitsRLE (fp, texinfo);
  578.                 break;
  579.                
  580.             case 32:
  581.                 ReadTGA32bitsRLE (fp, texinfo);
  582.                 break;
  583.         }
  584.            
  585.             break;
  586.            
  587.             case 11:
  588.             /* RLE compressed 8 or 16 bits grayscale */
  589.             if (header.pixel_depth == 8)
  590.                 ReadTGAgray8bitsRLE (fp, texinfo);
  591.             else /* 16 */
  592.                 ReadTGAgray16bitsRLE (fp, texinfo);
  593.            
  594.             break;
  595.            
  596.             default:
  597.             /* image type is not correct */
  598.             fprintf (stderr, "error: unknown TGA image type %i!\n", header.image_type);
  599.             free (texinfo->texels);
  600.             free (texinfo);
  601.             texinfo = NULL;
  602.             break;
  603.     }
  604.    
  605.     /* no longer need colormap data */
  606.     if (colormap)
  607.         free (colormap);
  608.    
  609.     fclose (fp);
  610.     return texinfo;
  611. }
  612.  
  613.  
  614. GLuint
  615. loadTGATexture (const char *filename, GLuint texid)
  616. {
  617.     gl_texture_t *tga_tex = NULL;
  618.     GLuint tex_id = 0;
  619.    
  620.     tga_tex = ReadTGAFile (filename);
  621.    
  622.     if (tga_tex && tga_tex->texels)
  623.     {
  624.         /* generate texture */
  625.         if(!texid)
  626.             glGenTextures (1, &tga_tex->id);
  627.         else
  628.             tga_tex->id = texid;
  629.         glBindTexture (GL_TEXTURE_2D, tga_tex->id);
  630.        
  631.         /* setup some parameters for texture filters and mipmapping */
  632.         glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR/*_MIPMAP_LINEAR*/);
  633.         glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  634.        
  635.        
  636.         glTexImage2D (GL_TEXTURE_2D, 0, tga_tex->internalFormat,
  637.                       tga_tex->width, tga_tex->height, 0, tga_tex->format,
  638.                       GL_UNSIGNED_BYTE, tga_tex->texels);
  639.        
  640.         /*
  641.          gluBuild2DMipmaps (GL_TEXTURE_2D, tga_tex->internalFormat,
  642.          tga_tex->width, tga_tex->height,
  643.          tga_tex->format, GL_UNSIGNED_BYTE, tga_tex->texels);
  644.          */
  645.        
  646.         tex_id = tga_tex->id;
  647.        
  648.         /* OpenGL has its own copy of texture data */
  649.         free (tga_tex->texels);
  650.         free (tga_tex);
  651.     }
  652.    
  653.     return tex_id;
  654. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement