Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #define BYTES_PER_LINE(width) (3 * ((width) + 1) / 4) * 4
- typedef unsigned char pix_t;
- typedef unsigned int coord_t;
- struct bmp_hdr {
- char bmp_propietary[2];
- int bmp_filesize;
- int bmp_reserved;
- int bmp_hdr_size;
- int bmp_info_size;
- int bmp_width;
- int bmp_height;
- short bmp_planes;
- short bmp_bits;
- int bmp_compression;
- int bmp_size_bytes;
- int bmp_x_res;
- int bmp_y_res;
- int bmp_colors;
- int bmp_imp_colors;
- } __attribute__((__packed__));
- struct bmp {
- struct bmp_hdr header;
- unsigned char *data;
- unsigned int height;
- unsigned int width;
- unsigned int bpl;
- char filename[128];
- FILE *handle;
- };
- struct bmp *bmp_new (const char *filename, int width, int height);
- struct bmp *bmp_open (const char *filename);
- void bmp_close (struct bmp *bmp);
- int bmp_save (struct bmp *bmp);
- void bmp_set_pixel (struct bmp *bmp, pix_t r, pix_t g, pix_t b,
- coord_t x, coord_t y);
- void bmp_get_pixel (struct bmp *bmp, pix_t *r, pix_t *g, pix_t *b,
- coord_t x, coord_t y);
- struct bmp *bmp_new (const char *filename, int width, int height)
- {
- int bpl = BYTES_PER_LINE(width);
- struct bmp *bmp = malloc(sizeof(*bmp));
- bmp->height = height;
- bmp->width = width;
- bmp->data = malloc(bpl * (height + 1));
- bmp->bpl = bpl;
- bmp->header.bmp_propietary[0] = 'B';
- bmp->header.bmp_propietary[1] = 'M';
- bmp->header.bmp_hdr_size = 54;
- bmp->header.bmp_filesize = bmp->header.bmp_hdr_size + bpl * height;
- bmp->header.bmp_reserved = 0;
- bmp->header.bmp_info_size = 40;
- bmp->header.bmp_width = width;
- bmp->header.bmp_height = height;
- bmp->header.bmp_planes = 1;
- bmp->header.bmp_bits = 24;
- bmp->header.bmp_compression = 0;
- bmp->header.bmp_size_bytes = bpl * height;
- bmp->header.bmp_x_res = 2835;
- bmp->header.bmp_y_res = 2835;
- bmp->header.bmp_colors = 0;
- bmp->header.bmp_imp_colors = 0;
- strncpy(bmp->filename, filename, 128);
- bmp->handle = fopen(filename, "wb+");
- if (!bmp->handle) {
- perror("File open");
- free(bmp->data);
- free(bmp);
- return NULL;
- }
- fwrite(&bmp->header, sizeof(struct bmp_hdr), 1, bmp->handle);
- return bmp;
- }
- struct bmp *bmp_open (const char *filename)
- {
- struct bmp *bmp = malloc(sizeof(*bmp));
- int x, y, ipos, pos;
- unsigned char *buffer;
- strncpy(bmp->filename, filename, 128);
- bmp->handle = fopen(filename, "r+b");
- if (!bmp->handle) {
- perror("File open");
- free(bmp);
- return NULL;
- }
- fread(&bmp->header, sizeof(struct bmp_hdr), 1, bmp->handle);
- bmp->height = bmp->header.bmp_height;
- bmp->width = bmp->header.bmp_width;
- bmp->bpl = BYTES_PER_LINE(bmp->width);
- bmp->data = malloc((bmp->bpl * bmp->height) + 1);
- if (!(buffer = malloc(bmp->bpl * bmp->height + 1))) {
- perror("Buffer allocation");
- return NULL;
- }
- fread(buffer, 1, (bmp->bpl * bmp->height), bmp->handle);
- pos = 0;
- for (y = 0; y < bmp->height; y++) {
- for (x = 0; x < bmp->width; x++) {
- ipos = 3 * ((bmp->height * y) + x);
- bmp->data[ipos + 0] = buffer[pos++];
- bmp->data[ipos + 1] = buffer[pos++];
- bmp->data[ipos + 2] = buffer[pos++];
- }
- pos += (-pos) & 3;
- }
- free(buffer);
- return bmp;
- }
- int bmp_save (struct bmp *bmp)
- {
- int x, y, ipos, pos;
- unsigned char *buffer;
- if (!(buffer = malloc(bmp->bpl * bmp->height + 1))) {
- perror("Buffer allocation");
- return -1;
- }
- pos = 0;
- for (y = 0; y < bmp->height; y++) {
- for (x = 0; x < bmp->width; x++) {
- ipos = 3 * ((bmp->height * y) + x);
- buffer[pos++] = bmp->data[ipos + 0];
- buffer[pos++] = bmp->data[ipos + 1];
- buffer[pos++] = bmp->data[ipos + 2];
- }
- pos += (-pos) & 3;
- }
- fseek(bmp->handle, sizeof(struct bmp_hdr), SEEK_SET);
- fwrite(buffer, 1, pos, bmp->handle);
- free(buffer);
- return 0;
- }
- void bmp_close (struct bmp *bmp)
- {
- fclose(bmp->handle);
- free(bmp->data);
- free(bmp);
- }
- void bmp_set_pixel (struct bmp *bmp, pix_t r, pix_t g, pix_t b,
- coord_t x, coord_t y)
- {
- if (x > bmp->width)
- x = bmp->width;
- if (y > bmp->height)
- y = bmp->height;
- coord_t index = 3 * ((bmp->height * y) + x);
- bmp->data[index + 2] = r;
- bmp->data[index + 1] = g;
- bmp->data[index + 0] = b;
- }
- void bmp_get_pixel (struct bmp *bmp, pix_t *r, pix_t *g, pix_t *b,
- coord_t x, coord_t y)
- {
- if (x > bmp->width)
- x = bmp->width;
- if (y > bmp->height)
- y = bmp->height;
- coord_t index = 3 * ((bmp->height * y) + x);
- (*r) = bmp->data[index + 2];
- (*g) = bmp->data[index + 1];
- (*b) = bmp->data[index + 0];
- }
- int main (int argc, const char * argv[])
- {
- struct bmp *bmp = bmp_new("/file.bmp", 1024, 1024);
- int x, y;
- for (y = 0; y < bmp->height; y++) {
- for (x = 0; x < bmp->width; x++) {
- bmp_set_pixel(bmp, x & y, x ^ y, x | y, x, y);
- }
- }
- bmp_save (bmp);
- bmp_close(bmp);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment