stb_image
| Language | C (usable from C++) |
|---|---|
| License | public domain or MIT, your choice |
| Repository | github.com/nothings/stb |
| Documentation | comments at the top of stb_image.h and stb_image_write.h |
| Depends on | nothing |
| Read / write | yes (stb_image.h) / yes (stb_image_write.h, 8-bit gray, gray+alpha, RGB, RGBA, RLE or raw) |
stb_image.h loads TGA, PNG, JPEG, BMP, GIF, PSD, HDR, PIC and PNM from a file or memory into an 8-bit buffer, top row first, converted to the channel count you ask for. It handles palette, grayscale, 15/16/24/32-bit and RLE TGA files and respects the origin bit. stb_image_write.h writes TGA with RLE compression by default.
These headers are the usual way to load TGA textures in games and graphics demos. They ignore the TGA 2.0 extension area (metadata, thumbnail, attributes type) and aren’t hardened against malicious files: the header itself says it’s unsure what subset of TGA it covers.
Installation#
Copy stb_image.h (and stb_image_write.h to save) into your project. In exactly one .c or .cpp file, define the implementation macros before the includes:
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
Other files include the headers without the macros. It’s also available as vcpkg install stb.
Basic usage: load and save a TGA#
#include "stb_image.h"
#include "stb_image_write.h"
#include <stdio.h>
int main(void) {
int w, h, channels;
// 4: always return RGBA; 0 keeps the file's channel count
unsigned char *pixels = stbi_load("in.tga", &w, &h, &channels, 4);
if (!pixels) {
printf("load failed: %s\n", stbi_failure_reason());
return 1;
}
printf("%d x %d, %d channels in file\n", w, h, channels);
// pixels are RGBA, top row first; the writer converts to BGRA for TGA
if (!stbi_write_tga("out.tga", w, h, 4, pixels)) {
printf("write failed\n");
}
stbi_image_free(pixels);
return 0;
}
How to get TGA width and height without decoding#
int w, h, channels;
if (stbi_info("in.tga", &w, &h, &channels)) {
printf("%d x %d, %d channels\n", w, h, channels);
}
How to write an uncompressed TGA#
stbi_write_tga uses RLE unless you clear a global flag. Some old tools only read uncompressed TGA:
stbi_write_tga_with_rle = 0; // global, default 1
stbi_write_tga("raw.tga", w, h, 4, pixels);
How to load a TGA texture for OpenGL#
OpenGL expects the bottom row first. Ask stb_image to flip on load:
stbi_set_flip_vertically_on_load(1);
int w, h, n;
unsigned char *pixels = stbi_load("texture.tga", &w, &h, &n, 4);
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
stbi_image_free(pixels);
How to convert TGA to PNG#
int w, h, n;
unsigned char *pixels = stbi_load("in.tga", &w, &h, &n, 0); // keep channel count
if (pixels) {
stbi_write_png("out.png", w, h, n, pixels, w * n);
stbi_image_free(pixels);
}
How to load a TGA from memory#
// data/len: TGA file contents, e.g. read from a game archive
int w, h, n;
unsigned char *pixels = stbi_load_from_memory(data, (int)len, &w, &h, &n, 4);
Tips#
- TGA has no magic number.
stbi_loadchecks other formats first and tries TGA last using header sanity checks, so a corrupt file of another type can be misread as TGA. stbi_write_tga_to_funcwrites into a callback instead of a file, e.g. to build a TGA in memory.