Last active
February 24, 2021 20:02
-
-
Save vipyne/c463301a07bd348510707bfbc1e7ad5a to your computer and use it in GitHub Desktop.
write a TARGA image file in C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// vanessa writes a targa file | |
// compiling and running this file will produce a targa file | |
// a lot of this is based on Grant Emery's file https://www.tjhsst.edu/~dhyatt/superap/code/targa.c thanks dude | |
// author: vanessa pyne --- github.com/vipyne | |
#include <stdio.h> | |
#define BYTE_RANGE 256; | |
////// targa file header | |
typedef struct { | |
char id_length; // length of id field (number of bytes - max 255) | |
char map_type; // colormap field (0 or 1; no map or 256 entry palette) | |
char image_type; // ( 0 - no image data included | |
// 1 - uncompressed, color mapped image | |
// 2 - uncompressed, RGB image | |
// 3 - uncompressed, black & white image | |
// 9 - run-length encoded(RLE-lossless compression),color mapped image | |
// 10 - RLE, RGB image | |
// 11 - compressed, black & white image ) | |
int map_first; // first entry index for color map | |
int map_length; // total number of entries in color map | |
char map_entry_size; // number of bits per entry | |
int x; // x cooridinate of origin | |
int y; // y cooridinate of origin | |
int width; // width in pixels | |
int height; // height in pixels | |
char bits_per_pixel; // number of bits per pixel | |
char misc; // srsly? "scan origin and alpha bits" this example uses scan origin | |
// honestly, don't know what's going on here. we pass in a hex value | |
// :shrug_emoji: | |
} targa_header; | |
int little_endianify (int number) | |
{ | |
return number % BYTE_RANGE; | |
} | |
int big_endianify (int number) | |
{ | |
return number / BYTE_RANGE; | |
} | |
////// write header function | |
void write_header (targa_header header, FILE *tga) | |
{ | |
fputc( header.id_length, tga ); | |
fputc( header.map_type, tga ); | |
fputc( header.image_type, tga ); | |
fputc( little_endianify(header.map_first), tga ); | |
fputc( big_endianify(header.map_first), tga ); | |
fputc( little_endianify(header.map_length), tga ); | |
fputc( big_endianify(header.map_length), tga ); | |
fputc( header.map_entry_size, tga ); | |
fputc( little_endianify(header.x), tga ); | |
fputc( big_endianify(header.x), tga ); | |
fputc( little_endianify(header.y), tga ); | |
fputc( big_endianify(header.y), tga ); | |
fputc( little_endianify(header.width), tga ); | |
fputc( big_endianify(header.width), tga ); | |
fputc( little_endianify(header.height), tga ); | |
fputc( big_endianify(header.height), tga ); | |
fputc( header.bits_per_pixel, tga ); | |
fputc( header.misc, tga ); | |
} | |
////// MAIN | |
int main (void) | |
{ | |
FILE *tga; // pointer to file that we will write | |
targa_header header; // variable of targa_header type | |
int x, y; // coordinates for `for` loops to pass in | |
// correct number of values | |
// set header values | |
header.id_length = 0; | |
header.map_type = 0; | |
header.image_type = 2; // uncompressed RGB image | |
header.map_first = 0; | |
header.map_length = 0; | |
header.map_entry_size = 0; | |
header.x = 0; | |
header.y = 0; | |
header.width = 500; | |
header.height = 500; | |
header.bits_per_pixel = 24; | |
header.misc = 0x20; // scan from upper left corner, wut dude | |
// start to write file | |
tga = fopen("vanessa-writes-a.tga", "wb"); | |
write_header(header, tga); | |
//// magic happens here -- write the pixels | |
for (y = 0; y < 500; ++y) | |
for (x = 0; x < 500; ++x) | |
{ | |
// B G R order | |
fputc(170, tga); | |
fputc(200, tga); | |
fputc(20, tga); | |
} | |
//// magic ends here | |
fclose(tga); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Neat, but doesn't this just write the bytes to the disk byte by byte? Why not write the image to an array and then write it to the disk? I would send code but I don't have any idea how to do so