colorful rat Ratfactor.com > Dave's Repos

tga.zig

Writes a TGA file with Zig
git clone http://ratfactor.com/repos/tga.zig/tga.zig.git

tga.zig/tga.zig

Download raw file: tga.zig

1 // Writes a pretty color gradient to a totally real TGA file. 2 // 3 const std = @import("std"); 4 5 pub fn main() !void { 6 const file = try std.fs.cwd().createFile("foo.tga", .{ .read = true }); 7 defer file.close(); 8 9 const width: u16 = 300; 10 const height: u16 = 200; 11 12 // https://stackoverflow.com/a/49658800/695615 13 // https://en.wikipedia.org/wiki/Truevision_TGA 14 // http://paulbourke.net/dataformats/tga/ 15 // Note that all multi-byte values are little-endian. 16 const header: [18]u8 = .{ 17 0, // 1 - No ID field (length of 0) 18 0, // 2 - No color map 19 2, // 3 - Uncompressed true-color image 20 0, // 4 \ 21 0, // 5 | 22 0, // 6 | Color map information (none) 23 0, // 7 | 24 0, // 8 / 25 0, // 9 \ Origin X (16 bits) 26 0, // 10 / 27 0, // 11 \ Origin Y (16 bits) 28 0, // 12 / 29 width & 255, // 13 \ Width (px) mask last 8 bits 30 (width >> 8) & 255, // 14 / Width (px) right shift and mask to get first 8 bits 31 height & 255, // 15 \ Height (px) last 32 (height >> 8) & 255, // 16 / Height (px) first 33 24, // 17 - Bits per pixel (3 colors, 8 bits each) 34 0b00100000, // 18 - Image descriptor (Bits 4,5 are origin. Set to "top left".) 35 }; 36 37 try file.writeAll(&header); 38 39 40 // Scale from image dimensions to color min and max. 41 var w_scale: f32 = 255 / @as(f32, width); 42 var h_scale: f32 = 255 / @as(f32, height); 43 44 // Buffer one row's worth of pixels (makes a huge difference on huge images). 45 var out_buffer: [3 * width]u8 = undefined; 46 47 var w: u32 = 0; // Pixel counter per row (width) 48 var h: u32 = 0; // Row counter (height) 49 50 // For height's worth of rows... 51 while (h < height) : (h += 1) { 52 53 // Reset row pixel counter 54 w = 0; 55 56 // Fill row buffer 57 while (w < width) : (w += 1) { 58 // IMPORTANT: TGA stores in BGR order, not RGB. 59 const pixel_r = w * 3 + 2; 60 const pixel_g = w * 3 + 1; 61 const pixel_b = w * 3; 62 63 out_buffer[pixel_r] = @floatToInt(u8, @intToFloat(f32, w) * w_scale); // increase across 64 out_buffer[pixel_g] = @floatToInt(u8, @intToFloat(f32, h) * h_scale); // increase down 65 out_buffer[pixel_b] = @floatToInt(u8, @intToFloat(f32, width-w) * w_scale); // decrease across 66 } 67 68 // Write row 69 try file.writeAll(&out_buffer); 70 } 71 }