/* tga.c : PUBLIC DOMAIN - Jon Mayo - August 24, 2006 * - You may remove any comments you wish, modify this code any way you wish, * and distribute any way you wish.*/ /* simple TGA save program. supports 8-bit color and grayscale * define STAND_ALONE to run the example routine */ #include #include #include /* WRite Little-Endian 16-bit value */ #define WR_LE16BIT(dest, offset, value) do { \ unsigned tmp=value; \ (dest)[offset]=tmp%256; \ (dest)[offset+1]=(tmp/256)%256; \ } while(0) /* saves an image to a TGA file. * palette points to an array of RGB values (with a pad on each entry) * pass palette as NULL to use a grayscale palette * nr_colors must be large enough for all pixels that were passed. */ static int tga_save(const char *filename, unsigned char *data, unsigned width, unsigned height, unsigned char palette[][4], unsigned nr_colors ) { unsigned y, c; FILE *f; unsigned char header[] = { 0, /* 00 - length of image identification field */ 1, /* 01 - color map type */ 1, /* 02 - image type code */ /* color map specification */ 0, 0, /* 03 - color map origin */ 0, 1, /* 05 - color map length */ 24, /* 07 - color map entry size (24-bit) */ /* image specification */ 0, 0, /* 08 - X origin */ 0, 0, /* 10 - Y origin */ 0, 0, /* 12 - width */ 0, 0, /* 14 - height */ 8, /* 16 - image pixel size */ 0, /* 17 - image description byte */ /* image identification field */ 0, /* 18 - empty */ }; assert(filename != NULL); assert(nr_colors > 0); assert(data != NULL); assert(width > 0 && height > 0); f=fopen(filename, "wb"); if(!f) { perror(filename); return 0; } WR_LE16BIT(header, 12, width); WR_LE16BIT(header, 14, height); WR_LE16BIT(header, 5, nr_colors); /* TODO: support smaller pixel size for reduced colors */ /* write header */ if(fwrite(header, sizeof header, 1, f)!=1) { perror(filename); fclose(f); return 0; } /* color map data */ if(palette) { /* write the palette */ for(c=0;c1) { switch(argc) { case 3: height=strtoul(argv[2], 0, 0); case 2: width=strtoul(argv[1], 0, 0); break; default: fprintf(stderr, "Usage: %s [width [height [colors]]]\n", argv[0]); return EXIT_FAILURE; } } /* buffer for our grayscale image */ data=malloc(width * height); for(y=0;y<256;y++) { palette[y][0]=y; palette[y][1]=255-y; palette[y][2]=~y; palette[y][3]=0; /* pad */ } /* fill in data with something intersting */ for(y=0;y