1037b3c26Smrg/* 2037b3c26Smrg * Copyright 2011 Luc Verhaegen <libv@codethink.co.uk> 3037b3c26Smrg * 4037b3c26Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5037b3c26Smrg * copy of this software and associated documentation files (the "Software"), 6037b3c26Smrg * to deal in the Software without restriction, including without limitation 7037b3c26Smrg * the rights to use, copy, modify, merge, publish, distribute, sub license, 8037b3c26Smrg * and/or sell copies of the Software, and to permit persons to whom the 9037b3c26Smrg * Software is furnished to do so, subject to the following conditions: 10037b3c26Smrg * 11037b3c26Smrg * The above copyright notice and this permission notice (including the 12037b3c26Smrg * next paragraph) shall be included in all copies or substantial portions 13037b3c26Smrg * of the Software. 14037b3c26Smrg * 15037b3c26Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16037b3c26Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17037b3c26Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18037b3c26Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19037b3c26Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20037b3c26Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21037b3c26Smrg * DEALINGS IN THE SOFTWARE. 22037b3c26Smrg * 23037b3c26Smrg */ 24037b3c26Smrg/* 25037b3c26Smrg * Quick 'n Dirty bitmap dumper. 26037b3c26Smrg */ 27037b3c26Smrg#include <stdio.h> 28037b3c26Smrg#include <unistd.h> 29037b3c26Smrg#include <sys/types.h> 30037b3c26Smrg#include <sys/stat.h> 31037b3c26Smrg#include <fcntl.h> 32037b3c26Smrg#include <string.h> 33037b3c26Smrg#include <errno.h> 34037b3c26Smrg 35037b3c26Smrg#include "write_bmp.h" 36037b3c26Smrg 37037b3c26Smrg#define FILENAME_SIZE 1024 38037b3c26Smrg 39037b3c26Smrgstruct bmp_header { 40037b3c26Smrg unsigned short magic; 41037b3c26Smrg unsigned int size; 42037b3c26Smrg unsigned int unused; 43037b3c26Smrg unsigned int start; 44037b3c26Smrg} __attribute__((__packed__)); 45037b3c26Smrg 46037b3c26Smrgstruct dib_header { 47037b3c26Smrg unsigned int size; 48037b3c26Smrg unsigned int width; 49037b3c26Smrg unsigned int height; 50037b3c26Smrg unsigned short planes; 51037b3c26Smrg unsigned short bpp; 52037b3c26Smrg unsigned int compression; 53037b3c26Smrg unsigned int data_size; 54037b3c26Smrg unsigned int h_res; 55037b3c26Smrg unsigned int v_res; 56037b3c26Smrg unsigned int colours; 57037b3c26Smrg unsigned int important_colours; 58037b3c26Smrg unsigned int red_mask; 59037b3c26Smrg unsigned int green_mask; 60037b3c26Smrg unsigned int blue_mask; 61037b3c26Smrg unsigned int alpha_mask; 62037b3c26Smrg unsigned int colour_space; 63037b3c26Smrg unsigned int unused[12]; 64037b3c26Smrg} __attribute__((__packed__)); 65037b3c26Smrg 6600a23bdaSmrgstatic void 67037b3c26Smrgbmp_header_write(int fd, int width, int height, int bgra, int noflip, int alpha) 68037b3c26Smrg{ 69037b3c26Smrg struct bmp_header bmp_header = { 70037b3c26Smrg .magic = 0x4d42, 71037b3c26Smrg .size = (width * height * 4) + 72037b3c26Smrg sizeof(struct bmp_header) + sizeof(struct dib_header), 73037b3c26Smrg .start = sizeof(struct bmp_header) + sizeof(struct dib_header), 74037b3c26Smrg }; 75037b3c26Smrg struct dib_header dib_header = { 76037b3c26Smrg .size = sizeof(struct dib_header), 77037b3c26Smrg .width = width, 78037b3c26Smrg .height = noflip ? -height : height, 79037b3c26Smrg .planes = 1, 80037b3c26Smrg .bpp = 32, 81037b3c26Smrg .compression = 3, 82037b3c26Smrg .data_size = 4 * width * height, 83037b3c26Smrg .h_res = 0xB13, 84037b3c26Smrg .v_res = 0xB13, 85037b3c26Smrg .colours = 0, 86037b3c26Smrg .important_colours = 0, 87037b3c26Smrg .red_mask = 0x000000FF, 88037b3c26Smrg .green_mask = 0x0000FF00, 89037b3c26Smrg .blue_mask = 0x00FF0000, 90037b3c26Smrg .alpha_mask = alpha ? 0xFF000000 : 0x00000000, 91037b3c26Smrg .colour_space = 0x57696E20, 92037b3c26Smrg }; 93037b3c26Smrg 94037b3c26Smrg if (bgra) { 95037b3c26Smrg dib_header.red_mask = 0x00FF0000; 96037b3c26Smrg dib_header.blue_mask = 0x000000FF; 97037b3c26Smrg } 98037b3c26Smrg 99037b3c26Smrg write(fd, &bmp_header, sizeof(struct bmp_header)); 100037b3c26Smrg write(fd, &dib_header, sizeof(struct dib_header)); 101037b3c26Smrg} 102037b3c26Smrg 103037b3c26Smrgvoid 104037b3c26Smrgbmp_dump32(char *buffer, unsigned width, unsigned height, bool bgra, const char *filename) 105037b3c26Smrg{ 106037b3c26Smrg int fd; 107037b3c26Smrg 108037b3c26Smrg fd = open(filename, O_WRONLY| O_TRUNC | O_CREAT, 0666); 109037b3c26Smrg if (fd == -1) { 110037b3c26Smrg printf("Failed to open %s: %s\n", filename, strerror(errno)); 111037b3c26Smrg return; 112037b3c26Smrg } 113037b3c26Smrg 114037b3c26Smrg bmp_header_write(fd, width, height, bgra, false, true); 115037b3c26Smrg 116037b3c26Smrg write(fd, buffer, width * height * 4); 117037b3c26Smrg} 118037b3c26Smrg 119037b3c26Smrgvoid 120037b3c26Smrgbmp_dump32_noflip(char *buffer, unsigned width, unsigned height, bool bgra, const char *filename) 121037b3c26Smrg{ 122037b3c26Smrg int fd; 123037b3c26Smrg 124037b3c26Smrg fd = open(filename, O_WRONLY| O_TRUNC | O_CREAT, 0666); 125037b3c26Smrg if (fd == -1) { 126037b3c26Smrg printf("Failed to open %s: %s\n", filename, strerror(errno)); 127037b3c26Smrg return; 128037b3c26Smrg } 129037b3c26Smrg 130037b3c26Smrg bmp_header_write(fd, width, height, bgra, true, true); 131037b3c26Smrg 132037b3c26Smrg write(fd, buffer, width * height * 4); 133037b3c26Smrg} 134037b3c26Smrg 135037b3c26Smrgvoid 136037b3c26Smrgbmp_dump32_ex(char *buffer, unsigned width, unsigned height, bool flip, bool bgra, bool alpha, const char *filename) 137037b3c26Smrg{ 138037b3c26Smrg int fd; 139037b3c26Smrg 140037b3c26Smrg fd = open(filename, O_WRONLY| O_TRUNC | O_CREAT, 0666); 141037b3c26Smrg if (fd == -1) { 142037b3c26Smrg printf("Failed to open %s: %s\n", filename, strerror(errno)); 143037b3c26Smrg return; 144037b3c26Smrg } 145037b3c26Smrg 146037b3c26Smrg bmp_header_write(fd, width, height, bgra, flip, alpha); 147037b3c26Smrg 148037b3c26Smrg write(fd, buffer, width * height * 4); 149037b3c26Smrg} 150