Advertisement
TerusTheBird

masker: tga_v4.c

Jan 7th, 2025
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 15.20 KB | Source Code | 0 0
  1. #ifndef __TGAC
  2. #define __TGAC
  3.  
  4. #include "tga_v4.h"
  5.  
  6. uint8_t* tga_new_pixelbuffer( uint16_t w, uint16_t h, uint8_t bpp ) {
  7.     uint32_t length;
  8.     if(w == 0 || h == 0) return NULL;
  9.     length = w; length *= h;
  10.     switch( bpp ) {
  11.         case  8: return (uint8_t*)malloc( length );
  12.         case 24: return (uint8_t*)malloc( length * 3U );
  13.         case 32: return (uint8_t*)malloc( length * 4U );
  14.         default: return NULL;
  15.     }
  16.     return NULL; // this should never happen
  17. }
  18.  
  19. void* tga_free_pixelbuffer( void* buf ) {
  20.     if( !buf ) return NULL;
  21.     free( buf ); buf = NULL;
  22.     return NULL;
  23. }
  24.  
  25. tga_t* tga_new( uint16_t w, uint16_t h, uint8_t bpp ) {
  26.     tga_t* t;
  27.     if( w == 0 || h == 0 || (bpp != 24 && bpp != 32 && bpp != 8) ) return NULL;
  28.     t = (tga_t*)malloc( sizeof(tga_t) );
  29.     if( !t ) return NULL;
  30.     t->pixels = tga_new_pixelbuffer( w, h, bpp );
  31.     if( !t->pixels ) {
  32.         free( t );
  33.         return NULL;
  34.     }
  35.     // I guess its worth noting that I do not clear the pixel buffer here
  36.     t->ext_pixels = 0;
  37.     t->inverted = 0;
  38.    
  39.     t->w = w;
  40.     t->h = h;
  41.     t->bpp = bpp;
  42.    
  43.     t->refcount = 1;
  44.     return t;
  45. }
  46.  
  47. tga_t* tga_new_internal1( uint16_t w, uint16_t h, uint8_t bpp, uint8_t inverted ) {
  48.     tga_t* temp;
  49.     temp = tga_new( w, h, bpp );
  50.     if( !temp ) return NULL;
  51.     temp->inverted = inverted;
  52.     return temp;
  53. }
  54.  
  55. tga_t* tga_new_formatted( uint16_t w, uint16_t h, tga_t* tga_ref ) {
  56.     if( !tga_ref ) return NULL;
  57.     if( w == 0 ) w = tga_ref->w;
  58.     if( h == 0 ) h = tga_ref->h;
  59.     return tga_new_internal1( w, h, tga_ref->bpp, tga_ref->inverted );
  60. }
  61.  
  62. tga_t* tga_new_from_data( uint16_t w, uint16_t h, uint8_t bpp, uint8_t inverted, uint8_t* data ) {
  63.     tga_t* t;
  64.     if( !data ) return NULL;
  65.     if( w == 0 || h == 0 || (bpp != 24 && bpp != 32 && bpp != 8) ) return NULL;
  66.     t = (tga_t*)malloc( sizeof(tga_t) );
  67.     if( !t ) return NULL;
  68.     t->ext_pixels = 1;
  69.     t->inverted = inverted;
  70.     t->pixels = data;
  71.     t->w = w;
  72.     t->h = h;
  73.     t->bpp = bpp;
  74.     t->refcount = 1;
  75.     return t;
  76. }
  77.  
  78. tga_t* tga_free( tga_t* t ) {
  79.     if( t == NULL ) return NULL;
  80.     if( t->refcount > 0 ) --t->refcount;
  81.     if( t->refcount > 0 ) return NULL;
  82.     if( !t->ext_pixels )
  83.         if( t->pixels )
  84.             free( t->pixels );
  85.     free( t ); t = NULL;
  86.     return NULL;
  87. }
  88.  
  89.  
  90. color_t tga_pixel_get( tga_t* t, uint16_t x, uint16_t y ) {
  91.     uint32_t pos; color_t c;
  92.     if( !t ) return 0;
  93.     if( !t->pixels || x >= t->w || y >= t->h ) return 0;
  94.     if( t->inverted ) y = ( t->h - 1 ) - y;
  95.     pos = y; pos *= t->w; pos += x;
  96.     switch( t->bpp ) {
  97.         case  8: { // Y
  98.             c = t->pixels[ pos ];
  99.             c = ( c << 24 ) | ( c << 16 ) | ( c << 8 ) | 0xFF;
  100.             return c;
  101.         } break;
  102.         case 24: { // BGR
  103.             c  = (uint32_t)t->pixels[ (pos*3U)+0U ] <<  8U;
  104.             c |= (uint32_t)t->pixels[ (pos*3U)+1U ] << 16U;
  105.             c |= (uint32_t)t->pixels[ (pos*3U)+2U ] << 24U;
  106.             c |= 0xFF;
  107.             return c;
  108.         } break;
  109.         case 32: { // BGRA
  110.             c  = (uint32_t)t->pixels[ (pos*4U)+0U ] <<  8U;
  111.             c |= (uint32_t)t->pixels[ (pos*4U)+1U ] << 16U;
  112.             c |= (uint32_t)t->pixels[ (pos*4U)+2U ] << 24U;
  113.             c |= (uint32_t)t->pixels[ (pos*4U)+3U ];
  114.             return c;
  115.         } break;
  116.         default: return 0;
  117.     }
  118.     return 0; // this should never happen
  119. }
  120.  
  121. uint8_t tga_pixel_get8( tga_t* t, uint16_t x, uint32_t y ) {
  122.     if( !t ) return 0;
  123.     if( x >= t->w || y >= t->h ) return 0;
  124.     if( t->bpp != 8 ) {
  125.         return tga_pixel_get( t, x, y ) >> 16;
  126.     }
  127.     y *= t->w; y += x;
  128.     return ((uint8_t*)(t->pixels))[ y ];
  129. }
  130.  
  131. void tga_pixel_set8( tga_t* t, uint16_t x, uint32_t y, uint8_t c ) {
  132.     if( !t ) return;
  133.     if( x >= t->w || y >= t->h ) return;
  134.     if( t->bpp != 8 ) {
  135.         color_t c32;
  136.         c32 = c; c32 <<= 8; c32 |= c; c32 <<= 8; c32 |= c; c32 <<= 8; c32 |= 255U;
  137.         tga_pixel_set( t, x, y, c32 );
  138.         return;
  139.     }
  140.     y *= t->w; y += x;
  141.     ((uint8_t*)(t->pixels))[ y ] = c;
  142. }
  143.  
  144. void tga_pixel_set( tga_t* t, uint16_t x, uint16_t y, color_t c ) {
  145.     uint32_t pos;
  146.     if( !t ) return;
  147.     if( !t->pixels || x >= t->w || y >= t->h ) return;
  148.     if( t->inverted ) y = ( t->h - 1 ) - y;
  149.     pos = y; pos *= t->w; pos += x;
  150.     switch( t->bpp ) {
  151.         case  8: { // Y
  152.             // use the green channel
  153.             t->pixels[ pos ] = c >> 16U;
  154.         } break;
  155.         case 24: { // BGR
  156.             t->pixels[ (pos*3)+0 ] = c >>  8U;
  157.             t->pixels[ (pos*3)+1 ] = c >> 16U;
  158.             t->pixels[ (pos*3)+2 ] = c >> 24U;
  159.         } break;
  160.         case 32: { // BGRA
  161.             t->pixels[ (pos*4)+0 ] = c >>  8U;
  162.             t->pixels[ (pos*4)+1 ] = c >> 16U;
  163.             t->pixels[ (pos*4)+2 ] = c >> 24U;
  164.             t->pixels[ (pos*4)+3 ] = c;
  165.         } break;
  166.         default: break;
  167.     }
  168. }
  169.  
  170. color_t tga_new_color_from_shade( uint8_t s ) {
  171.     color_t r;
  172.     r = s; r <<= 8;
  173.     r |= s; r <<= 8;
  174.     r |= s; r <<= 8;
  175.     r |= 0xFF;
  176.     return r;
  177. }
  178.  
  179.  
  180. void tga_line( int32_t x0, int32_t y0, int32_t x1, int32_t y1, color_t color, tga_t* tga ) {
  181.     int32_t dx, dy, sx, sy, err, e2;
  182.     dx = x1 - x0;
  183.     if( dx < 0 ) dx = -dx;
  184.     dy = y1 - y0;
  185.     if( dy < 0 ) dy = -dy;
  186.    
  187.     sx = (x0<x1 ? 1 : -1);
  188.     sy = (y0<y1 ? 1 : -1);
  189.     err = ((dx>dy ? dx : -dy)/2);
  190.     while(1){
  191.         tga_pixel_set( tga, (uint16_t)x0, (uint16_t)y0, color );
  192.         if( x0==x1 && y0==y1 ) break;
  193.         e2 = err;
  194.         if( e2 >-dx ) {err -= dy; x0 += sx;}
  195.         if( e2 < dy ) {err += dx; y0 += sy;}
  196.     }
  197. }
  198.  
  199. void tga_line_thick( int32_t x0, int32_t y0, int32_t x1, int32_t y1, color_t color, tga_t* tga ) {
  200.     int32_t kx, ky, c, i, dx, dy;
  201.     dx = x1 - x0;
  202.     kx = 0;
  203.     if( dx > 0 ) kx = +1;
  204.     if( dx < 0 ) { kx = -1; dx = -dx; }
  205.     dx++;
  206.  
  207.     dy = y1 - y0;
  208.     ky = 0;
  209.     if( dy > 0 ) ky = +1;
  210.     if( dy < 0 ) { ky = -1; dy = -dy; }
  211.     dy++;
  212.  
  213.     if( dx >= dy ) {
  214.         for( c = dx, i = 0; i < dx; i++, x0 += kx ) {
  215.             tga_pixel_set( tga, (uint16_t)x0, (uint16_t)y0, color );
  216.             c -= dy;
  217.             if( c <= 0 ) {
  218.                 if( i != dx - 1 ) {
  219.                     ;//tga_pixel_set( tga, (uint16_t)(x0 + kx), (uint16_t)y0, color );
  220.                 }
  221.                 c += dx;
  222.                 y0 += ky;
  223.                 if( i != dx - 1 ) {
  224.                     tga_pixel_set( tga, (uint16_t)x0, (uint16_t)y0, color );
  225.                 }
  226.             }
  227.         }
  228.     } else {
  229.         for( c = dy, i = 0; i < dy; i++, y0 += ky ) {
  230.             tga_pixel_set( tga, (uint16_t)x0, (uint16_t)y0, color );
  231.             c -= dx;
  232.             if( c <= 0 ) {
  233.                 if( i != dy - 1 ) {
  234.                     ;//tga_pixel_set( tga, (uint16_t)x0, (uint16_t)(y0 + ky), color );
  235.                 }
  236.                 c += dy;
  237.                 x0 += kx;
  238.                 if( i != dy - 1 ) {
  239.                     tga_pixel_set( tga, (uint16_t)x0, (uint16_t)y0, color );
  240.                 }
  241.             }
  242.         }
  243.     }
  244. }
  245.  
  246. void tga_circle_filled( tga_t* tga, int x0, int y0, int radius, color_t color ) {
  247.     int x, y, x_change, y_change, radius_error, i;
  248.     if( !tga ) return;
  249.     x = radius;
  250.     y = 0;
  251.     x_change = 1 - ( radius << 1 );
  252.     y_change = 0;
  253.     radius_error = 0;
  254.  
  255.     while( x >= y ) {
  256.         for( i = x0 - x; i <= x0 + x; i++ ) {
  257.             tga_pixel_set( tga, i, y0 + y, color );
  258.             tga_pixel_set( tga, i, y0 - y, color );
  259.         }
  260.         for( i = x0 - y; i <= x0 + y; i++ ) {
  261.             tga_pixel_set( tga, i, y0 + x, color );
  262.             tga_pixel_set( tga, i, y0 - x, color );
  263.         }
  264.  
  265.         y++;
  266.         radius_error += y_change;
  267.         y_change += 2;
  268.         if( ( ( radius_error << 1 ) + x_change ) > 0 ) {
  269.             x--;
  270.             radius_error += x_change;
  271.             x_change += 2;
  272.         }
  273.     }
  274. }
  275.  
  276. void tga_circle( tga_t* tga, int x0, int y0, int radius, color_t color ) {
  277.     int x, y, x_change, y_change, radius_error;
  278.     if( !tga ) return;
  279.     x = radius;
  280.     y = 0;
  281.     x_change = 1 - ( radius << 1 );
  282.     y_change = 0;
  283.     radius_error = 0;
  284.  
  285.     while( x >= y ) {
  286.         tga_pixel_set( tga, x0 + x, y0 + y, color );
  287.         tga_pixel_set( tga, x0 + x, y0 - y, color );
  288.         tga_pixel_set( tga, x0 - x, y0 + y, color );
  289.         tga_pixel_set( tga, x0 - x, y0 - y, color );
  290.         tga_pixel_set( tga, x0 + y, y0 + x, color );
  291.         tga_pixel_set( tga, x0 + y, y0 - x, color );
  292.         tga_pixel_set( tga, x0 - y, y0 + x, color );
  293.         tga_pixel_set( tga, x0 - y, y0 - x, color );
  294.  
  295.         y++;
  296.         radius_error += y_change;
  297.         y_change += 2;
  298.         if( ( ( radius_error << 1 ) + x_change ) > 0 ) {
  299.             x--;
  300.             radius_error += x_change;
  301.             x_change += 2;
  302.         }
  303.     }
  304. }
  305.  
  306.  
  307. #define _min( n1, n2 ) ( (n1) < (n2) ? (n1) : (n2) )
  308. #define _max( n1, n2 ) ( (n1) > (n2) ? (n1) : (n2) )
  309.  
  310. // dest rect does not use w or h for anything
  311. int tga_blit( tga_t* source, tga_t* dest, tga_rect_t rect_src, tga_rect_t rect_dest ) {
  312.     uint16_t x, y, w, h;
  313.     if( source == NULL ) return -1;
  314.     if( dest   == NULL ) return -2;
  315.     x = y = 0;
  316.     w = rect_src.w; // size only matters for source rect
  317.     h = rect_src.h;
  318.    
  319.     for( y = 0; y < h; ++y ) {
  320.         for( x = 0; x < w; ++x ) {
  321.             uint16_t inx, iny, outx, outy;
  322.             color_t c;
  323.             inx  = x + (uint16_t)(rect_src.x);
  324.             iny  = y + (uint16_t)(rect_src.y);
  325.             outx = x + (uint16_t)(rect_dest.x);
  326.             outy = y + (uint16_t)(rect_dest.y);
  327.             c = tga_pixel_get( source, inx, iny );
  328.             tga_pixel_set( dest, outx, outy, c );
  329.         }
  330.     }
  331.     return 0;
  332. }
  333.  
  334. int tga_blit_simple( tga_t* source, tga_t* dest, int dest_x, int dest_y ) {
  335.     tga_rect_t rs, rd;
  336.     if( !source ) return -1;
  337.     if( !dest ) return -2;
  338.     rs.w = source->w;
  339.     rs.h = source->h;
  340.     rs.x = 0;
  341.     rs.y = 0;
  342.     rd.x = dest_x;
  343.     rd.y = dest_y;
  344.     return tga_blit( source, dest, rs, rd );
  345. }
  346.  
  347. int tga_blit_simple_fast( tga_t* source, tga_t* dest ) {
  348.     // the goal here is to be stupid-fast
  349.     // but it only does 1 thing
  350.     uint8_t* px_offset_dest;
  351.     uint8_t* px_offset_source;
  352.     int y, h, source_pitch, dest_pitch;
  353.     if( !source || !dest ) return -1;
  354.     if( source->w > dest->w ) return -2;
  355.     if( source->bpp != dest->bpp ) return -3;
  356.     h = ( dest->h > source->h ) ? source->h : dest->h;
  357.    
  358.     px_offset_dest = dest->pixels;
  359.     px_offset_source = source->pixels;
  360.     source_pitch = source->w * ( source->bpp >> 3 );
  361.     dest_pitch = dest->w * ( source->bpp >> 3 );
  362.    
  363.     for( y = 0; y < h; ++y ) {
  364.         memcpy( px_offset_dest, px_offset_source, source_pitch );
  365.         px_offset_dest += dest_pitch;
  366.         px_offset_source += source_pitch;
  367.     }
  368.    
  369.     return 0;
  370. }
  371.  
  372.  
  373. void tga_copy( tga_t* source, tga_t* dest ) {
  374.     uint16_t x, y, w, h;
  375.     if( !source || !dest ) return;
  376.     w = _min( source->w, dest->w );
  377.     h = _min( source->h, dest->h );
  378.     for( y = 0; y < h; ++y )
  379.         for( x = 0; x < w; ++x )
  380.             tga_pixel_set( dest, x, y, tga_pixel_get( source, x, y ) );
  381. }
  382.  
  383. int tga_rect_fill( tga_t* img, tga_rect_t rect, color_t c ) {
  384.     int32_t x, y;
  385.     if( !img ) return -1;
  386.     if( rect.w == 0 || rect.h == 0 ) return 0;
  387.     for( y = rect.y; y < (rect.h + rect.y); ++y )
  388.         for( x = rect.x; x < (rect.w + rect.x); ++x ) {
  389.             tga_pixel_set( img, x, y, c );
  390.     }
  391.     return 0;
  392. }
  393.  
  394. int tga_fill( tga_t* img, color_t c ) {
  395.     uint32_t x, y;
  396.     if( !img ) return -1;
  397.     if( !img->pixels ) return -1;
  398.     for( y = 0; y < img->h; ++y ) {
  399.         for( x = 0; x < img->w; ++x ) {
  400.             tga_pixel_set( img, x, y, c );
  401.         }
  402.     }
  403.     return 0;
  404. }
  405.  
  406. int tga_fill8( tga_t* img, uint8_t c ) {
  407.     uint64_t len;
  408.     if( !img ) return -1;
  409.     if( img->bpp != 8 ) return -2;
  410.     len = img->w; len *= img->h;
  411.     memset( img->pixels, c, len );
  412.     return 0;
  413. }
  414.  
  415. void tga_vflip( tga_t* t ) {
  416.     tga_t* temp;
  417.     if( !t ) return;
  418.     if( t->h < 2 ) return;
  419.     temp = tga_new_formatted( 0, 0, t );
  420.     if( !temp ) return;
  421.     temp->inverted = 0;
  422.     tga_copy( t, temp );
  423.     free( t->pixels );
  424.     t->pixels = temp->pixels;
  425.     temp->ext_pixels = 1;
  426.     temp = tga_free( temp );
  427.     t->inverted = 0;
  428. #if __TGAH_verbose
  429.     fputs( "Flipped TGA\n", stdout );
  430. #endif
  431. }
  432.  
  433. tga_t* tga_load( char* fname ) {
  434.     tga_t* t; FILE* fp; uint64_t len;
  435.     uint16_t w, h, x, y; uint8_t bpp, pixelformat; uint8_t inverted;
  436.     //_Bool tga_is_color;
  437.     _Bool FU; // TGA format unsupported
  438.     if(fname == NULL) return NULL;
  439.     fp = fopen(fname, "rb");
  440.     if(fp == NULL) {
  441.         printf("The file %s does not exist\n", fname);
  442.         return NULL;
  443.     }
  444.     fseek(fp, 0x2  ,SEEK_SET);
  445.     fread(&pixelformat, sizeof(uint8_t), 1, fp);
  446.     fseek(fp, 0x8  ,SEEK_SET);
  447.     fread(&x, sizeof(uint16_t), 1, fp);
  448.     fseek(fp, 0xA  ,SEEK_SET);
  449.     fread(&y, sizeof(uint16_t), 1, fp);
  450.     fseek(fp, 0xC  ,SEEK_SET);
  451.     fread(&w, sizeof(uint16_t), 1, fp);
  452.     fseek(fp, 0xE  ,SEEK_SET);
  453.     fread(&h, sizeof(uint16_t), 1, fp);
  454.     fseek(fp, 0x10 ,SEEK_SET);
  455.     bpp = fgetc(fp);
  456.     inverted = ( ~fgetc( fp ) >> 5 ) & 1;
  457.  
  458. #if __TGAH_verbose
  459.     printf("X%u  Y%u  W%u  H%u  BPP%u\n", x, y, w, h, bpp);
  460. #endif
  461.  
  462.     FU = 0;
  463.     if( pixelformat == 2 ) { // color
  464.         if( bpp != 24 && bpp != 32 ) {
  465.             FU = 1;
  466.         }
  467.         //tga_is_color = 1;
  468.     } else if( pixelformat == 3 ) { // grayscale
  469.         if( bpp != 8 ) {
  470.             FU = 1;
  471.         }
  472.     } else {
  473.         FU = 1;
  474.     }
  475.    
  476.     if( FU ) {
  477.         fputs( "I don't support the format of this TGA!\n", stdout );
  478.         fclose(fp);
  479.         fflush(stdout);
  480.         return NULL;
  481.     }
  482.    
  483.     if( w == 0 || h == 0 ) {
  484.         fclose( fp );
  485.         fputs( "This TGA has zero pixels\n", stdout );
  486.         fflush( stdout );
  487.         return NULL;
  488.     }
  489.    
  490.     len = w; len *= h;
  491.    
  492.     t = tga_new(w, h, bpp);
  493.     if(t == NULL) {
  494.         fclose(fp);
  495.         printf("Could not create TGA from %s\n", fname);
  496.         return NULL;
  497.     }
  498.     if(t->pixels == NULL) {
  499.         free((void*)t);
  500.         fclose(fp);
  501.         return NULL;
  502.     }
  503.     t->ext_pixels = 0;
  504.    
  505.     switch( t->bpp ) {
  506.         case  8: fread( t->pixels, 1U, len, fp ); break;
  507.         case 24: fread( t->pixels, 3U, len, fp ); break;
  508.         case 32: fread( t->pixels, 4U, len, fp ); break;
  509.         default: break;
  510.     }
  511.    
  512.     fclose(fp);
  513.    
  514.     t->inverted = inverted;
  515.     // if( inverted ) tga_vflip( t );
  516.  
  517. #if __TGAH_verbose
  518.     printf("TGA Pixel buffer: %p\n", t->pixels);
  519. #endif
  520.  
  521.     t->refcount = 1;
  522.     return t;
  523. }
  524.  
  525. uint16_t fp_read_u16( FILE* fp ) {
  526.     uint16_t r1, r2;
  527.     if( !fp ) return 0;
  528.     r1 = fgetc( fp ) & 255U;
  529.     r2 = fgetc( fp ) & 255U;
  530.     return ( r2 << 8 ) | r1;
  531. }
  532.  
  533. tga_info_t tga_load_info( char* fname ) {
  534.     FILE* fp;
  535.     tga_info_t info;
  536.     memset( &info, 0, sizeof(tga_info_t) );
  537.     if( !fname ) return info;
  538.     fp = fopen( fname, "rb" );
  539.     if( !fp ) return info;
  540.    
  541.     fseek( fp, 2, SEEK_SET );
  542.     info.pixel_type = fgetc( fp );
  543.     fseek( fp, 8, SEEK_SET );
  544.     info.rect.x = fp_read_u16( fp );
  545.     info.rect.y = fp_read_u16( fp );
  546.     info.rect.w = fp_read_u16( fp );
  547.     info.rect.h = fp_read_u16( fp );
  548.     info.bits_per_pixel = fgetc( fp );
  549.     info.bits_per_alpha = fgetc( fp );
  550.     fclose( fp ); fp = NULL;
  551.     info.inverted = ( info.bits_per_alpha >> 5 ) & 1U;
  552.     info.bits_per_alpha &= 15U;
  553.     return info;
  554. }
  555.  
  556. void tga_save( char* fname, tga_t* t ) {
  557.     FILE* fp;
  558.     uint8_t filler[ 8 ]; uint8_t bpa, pixel_type; uint64_t len;
  559.     if( !t || !fname ) return;
  560.     if( !t->pixels || t->w == 0 || t->h == 0 || (t->bpp != 24 && t->bpp != 32 && t->bpp != 8) ) return;
  561.    
  562.     {int i;for(i=0;i<8;++i)filler[i]=0;}
  563.    
  564.     fp = fopen( fname, "wb" );
  565.     if( !fp ) return;
  566.    
  567.     // calculate the bits-per-alpha value/bitflag
  568.     bpa = t->bpp; bpa -= 24; bpa &= 15; // yes this works with 8bpp
  569.     bpa |= ( !t->inverted ) << 5;
  570.    
  571.    
  572.     if( t->bpp == 24 || t->bpp == 32 ) pixel_type = 2; // color RGB
  573.     if( t->bpp == 8 ) pixel_type = 3; // grayscale
  574.    
  575.     len = t->w; len *= t->h;
  576.    
  577.     fwrite( filler, 1, 2, fp ); // write two 0-bytes
  578.     fputc( pixel_type, fp ); // pixel format
  579.    
  580.     // 5 0-bytes, and then 0 for the X origin
  581.     fwrite( filler, 1, 7, fp );
  582.    
  583.     // write the Y-origin
  584.     if( t->inverted ) fwrite( filler, 1, 2, fp );
  585.     else fwrite( &(t->h), sizeof(uint16_t), 1, fp );
  586.    
  587.     // the image dimensions
  588.     fwrite( &(t->w), sizeof(uint16_t), 1, fp );
  589.     fwrite( &(t->h), sizeof(uint16_t), 1, fp );
  590.    
  591.     // more pixel format
  592.     fputc( t->bpp, fp ); // bits per pixel
  593.     fputc( bpa, fp ); // bits per alpha
  594.    
  595.     switch( t->bpp ) {
  596.         case  8: fwrite( t->pixels, 1U, len, fp ); break;
  597.         case 24: fwrite( t->pixels, 3U, len, fp ); break;
  598.         case 32: fwrite( t->pixels, 4U, len, fp ); break;
  599.         default: break;
  600.     }
  601.    
  602.     fclose( fp );
  603. }
  604.  
  605. void print_tga_info( tga_t* t ) {
  606.     if( !t ) {
  607.         fputs("TGA pointer is null\n", stdout);
  608.         fflush(stdout);
  609.         return;
  610.     }
  611.     fprintf(stdout, "TGA width: %u  height: %u  bits per pixel: %u  references: %u\n",
  612.         t->w, t->h, (uint16_t)t->bpp, (unsigned)t->refcount);
  613.     fflush(stdout);
  614. }
  615.  
  616. #endif
  617.  
  618.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement