home *** CD-ROM | disk | FTP | other *** search
/ Quark 3 / Quark3.iso / KATALOG / ARCHIV / TOOL / T001.ZIP / SOURCE.ZIP / targa.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-05-03  |  11.1 KB  |  236 lines

  1. #include "system.h"
  2. #include "DiskIO.h"
  3. #include "Targa.h"
  4.  
  5. typedef unsigned char byte;
  6.  
  7. struct TargaHeader {
  8.         unsigned char   id_length, colormap_type, image_type;
  9.         unsigned short  colormap_index, colormap_length;
  10.         unsigned char   colormap_size;
  11.         unsigned short  x_origin, y_origin, width, height;
  12.         unsigned char   pixel_size, attributes;
  13. };
  14.  
  15. void Error (char *error, ...);
  16. void Debug (char *error, ...);
  17.  
  18. struct wordByte
  19. {
  20.     unsigned char byte1;
  21.     unsigned char byte2;
  22. };
  23.  
  24. union wordByteUnion
  25. {
  26.     short word;
  27.     wordByte b;
  28. };
  29.  
  30. /*
  31. =======
  32. accepts RGB format data in pixels and writes it uncompressed into file
  33. =======
  34. */
  35.  
  36. void writeTGA( char *name, byte *pixels, int width, int height)
  37. {
  38.     TargaHeader             targa_header;
  39.     FILE *fin;
  40.  
  41.     fin = fopen( name, "wb" );
  42.     if (!fin) {
  43.        Debug( "Coulnd't open file for writing" );
  44.        return;
  45.     }
  46.     
  47.     memset( &targa_header, 0, sizeof( TargaHeader ) );       
  48.  
  49.     fputc( 0, fin ); //targa_header.id_length = 0;
  50.     fputc( 0, fin ); //targa_header.colormap_type = 0;
  51.     fputc( 2, fin ); //targa_header.image_type = 2;
  52.     put16( 0, fin ); //targa_header.colormap_index = 0;
  53.     put16( 0, fin ); //targa_header.colormap_length = 0;
  54.     fputc( 0, fin );               //targa_header.colormap_size = 0;
  55.     put16( 0,fin ); //targa_header.x_origin = 0; 
  56.     put16( 0, fin ); //targa_header.y_origin = 0;
  57.     put16( width, fin ); 
  58.     put16( height,fin );
  59.     fputc( 24, fin ); //targa_header.pixel_size = 24 ;
  60.     fputc( 0, fin );  //targa_header.attributes = 0;
  61.         
  62.     for (int i = 0; i < width*height*3; i+= 3)
  63.     {
  64.         fputc( (int)pixels[i+2], fin );
  65.         fputc( (int)pixels[i+1], fin );
  66.         fputc( (int)pixels[i], fin );
  67.     }
  68.  
  69.     fclose(fin);
  70. }
  71.  
  72.         
  73.     
  74. bool loadTGA (char *name, byte **pixels, unsigned int *width, unsigned int *height, unsigned int *format)
  75. {
  76.         int                             columns, rows, numPixels;
  77.         byte                    *pixbuf;
  78.         int                             row, column;
  79.         FILE                    *fin;
  80.         byte                    *targa_rgba;
  81.         TargaHeader             targa_header;
  82.  
  83.         fin = fopen (name, "rb");
  84.         if (!fin) //Debug( "Couldn't read textures" );
  85.             return false;
  86.  
  87.         targa_header.id_length = fgetc(fin);
  88.         targa_header.colormap_type = fgetc(fin);
  89.         targa_header.image_type = fgetc(fin);
  90.         
  91.         targa_header.colormap_index = get16(fin);
  92.         targa_header.colormap_length = get16(fin);
  93.         targa_header.colormap_size = fgetc(fin);
  94.         targa_header.x_origin = get16(fin);
  95.         targa_header.y_origin = get16(fin);
  96.         targa_header.width = get16(fin);
  97.         targa_header.height = get16(fin);
  98.         targa_header.pixel_size = fgetc(fin);
  99.         targa_header.attributes = fgetc(fin);
  100.  
  101.         if (targa_header.image_type!=2 
  102.                 && targa_header.image_type!=10)
  103.                 Error ("LoadTGA: Only type 2 and 10 targa RGB images supported\n");
  104.  
  105.         if (targa_header.colormap_type !=0 
  106.                 || (targa_header.pixel_size!=32 && targa_header.pixel_size!=24))
  107.                 Error ("Texture_LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
  108.  
  109.         *format = targa_header.pixel_size;
  110.  
  111.         columns = targa_header.width;
  112.         rows = targa_header.height;
  113.         numPixels = columns * rows;
  114.  
  115.         if (width)
  116.                 *width = columns;
  117.         if (height)
  118.                 *height = rows;
  119.         targa_rgba = new unsigned char[numPixels*4];
  120.         *pixels = targa_rgba;
  121.  
  122.         if (targa_header.id_length != 0)
  123.                 fseek(fin, targa_header.id_length, SEEK_CUR);  // skip TARGA image comment
  124.         
  125.         if (targa_header.image_type==2) {  // Uncompressed, RGB images
  126.                 for(row=rows-1; row>=0; row--) {
  127.                         pixbuf = targa_rgba + row*columns*4;
  128.                         for(column=0; column<columns; column++) {
  129.                                 unsigned char red,green,blue,alphabyte;
  130.                                 switch (targa_header.pixel_size) {
  131.                                         case 24:
  132.                                                         
  133.                                                         blue = getc(fin);
  134.                                                         green = getc(fin);
  135.                                                         red = getc(fin);
  136.                                                         *pixbuf++ = red;
  137.                                                         *pixbuf++ = green;
  138.                                                         *pixbuf++ = blue;
  139.                                                         *pixbuf++ = 255;
  140.                                                         break;
  141.                                         case 32:
  142.                                                         blue = getc(fin);
  143.                                                         green = getc(fin);
  144.                                                         red = getc(fin);
  145.                                                         alphabyte = getc(fin);
  146.                                                         *pixbuf++ = red;
  147.                                                         *pixbuf++ = green;
  148.                                                         *pixbuf++ = blue;
  149.                                                         *pixbuf++ = alphabyte;
  150.                                                         break;
  151.                                 }
  152.                         }
  153.                 }
  154.         }
  155.         else if (targa_header.image_type==10) {   // Runlength encoded RGB images
  156.                 unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
  157.                 for(row=rows-1; row>=0; row--) {
  158.                         pixbuf = targa_rgba + row*columns*4;
  159.                         for(column=0; column<columns; ) {
  160.                                 packetHeader=getc(fin);
  161.                                 packetSize = 1 + (packetHeader & 0x7f);
  162.                                 if (packetHeader & 0x80) {        // run-length packet
  163.                                         switch (targa_header.pixel_size) {
  164.                                                 case 24:
  165.                                                                 blue = getc(fin);
  166.                                                                 green = getc(fin);
  167.                                                                 red = getc(fin);
  168.                                                                 alphabyte = 255;
  169.                                                                 break;
  170.                                                 case 32:
  171.                                                                 blue = getc(fin);
  172.                                                                 green = getc(fin);
  173.                                                                 red = getc(fin);
  174.                                                                 alphabyte = getc(fin);
  175.                                                                 break;
  176.                                         }
  177.         
  178.                                         for(j=0;j<packetSize;j++) {
  179.                                                 *pixbuf++=red;
  180.                                                 *pixbuf++=green;
  181.                                                 *pixbuf++=blue;
  182.                                                 *pixbuf++=alphabyte;
  183.                                                 column++;
  184.                                                 if (column==columns) { // run spans across rows
  185.                                                         column=0;
  186.                                                         if (row>0)
  187.                                                                 row--;
  188.                                                         else
  189.                                                                 goto breakOut;
  190.                                                         pixbuf = targa_rgba + row*columns*4;
  191.                                                 }
  192.                                         }
  193.                                 }
  194.                                 else {                            // non run-length packet
  195.                                         for(j=0;j<packetSize;j++) {
  196.                                                 switch (targa_header.pixel_size) {
  197.                                                         case 24:                                                        
  198.                                                                         blue = getc(fin);
  199.                                                                         green = getc(fin);
  200.                                                                         red = getc(fin);
  201.                                                                         *pixbuf++ = red;
  202.                                                                         *pixbuf++ = green;
  203.                                                                         *pixbuf++ = blue;
  204.                                                                         *pixbuf++ = 255;
  205.                                                                         break;
  206.                                                         case 32:
  207.                                                                         blue = getc(fin);
  208.                                                                         green = getc(fin);
  209.                                                                         red = getc(fin);
  210.                                                                         alphabyte = getc(fin);
  211.                                                                         *pixbuf++ = red;
  212.                                                                         *pixbuf++ = green;
  213.                                                                         *pixbuf++ = blue;
  214.                                                                         *pixbuf++ = alphabyte;
  215.                                                                         break;
  216.                                                 }
  217.                                                 column++;
  218.                                                 if (column==columns) { // pixel packet run spans across rows
  219.                                                         column=0;
  220.                                                         if (row>0)
  221.                                                                 row--;
  222.                                                         else
  223.                                                                 goto breakOut;
  224.                                                         pixbuf = targa_rgba + row*columns*4;
  225.                                                 }                                               
  226.                                         }
  227.                                 }
  228.                         }
  229.                         breakOut:;
  230.                 }
  231.         }
  232.         
  233.         fclose(fin);
  234.         return true;
  235. }
  236.