memcpy

bmpgen

May 10th, 2012
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.87 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5.  
  6. #define BYTES_PER_LINE(width) (3 * ((width) + 1) / 4) * 4
  7.  
  8. typedef unsigned char pix_t;
  9. typedef unsigned int coord_t;
  10.  
  11. struct bmp_hdr {
  12.     char bmp_propietary[2];
  13.     int bmp_filesize;
  14.     int bmp_reserved;
  15.     int bmp_hdr_size;
  16.     int bmp_info_size;
  17.     int bmp_width;
  18.     int bmp_height;
  19.     short bmp_planes;
  20.     short bmp_bits;
  21.     int bmp_compression;
  22.     int bmp_size_bytes;
  23.     int bmp_x_res;
  24.     int bmp_y_res;
  25.     int bmp_colors;
  26.     int bmp_imp_colors;
  27. } __attribute__((__packed__));
  28.  
  29. struct bmp {
  30.     struct bmp_hdr header;
  31.     unsigned char *data;
  32.    
  33.     unsigned int height;
  34.     unsigned int width;
  35.     unsigned int bpl;
  36.    
  37.     char filename[128];
  38.     FILE *handle;
  39. };
  40.  
  41.  
  42. struct bmp *bmp_new (const char *filename, int width, int height);
  43. struct bmp *bmp_open (const char *filename);
  44.  
  45.  
  46. void bmp_close (struct bmp *bmp);
  47. int bmp_save (struct bmp *bmp);
  48.  
  49.  
  50. void bmp_set_pixel (struct bmp *bmp, pix_t r, pix_t g, pix_t b,
  51.             coord_t x, coord_t y);
  52. void bmp_get_pixel (struct bmp *bmp, pix_t *r, pix_t *g, pix_t *b,
  53.             coord_t x, coord_t y);
  54.  
  55. struct bmp *bmp_new (const char *filename, int width, int height)
  56. {
  57.     int bpl = BYTES_PER_LINE(width);
  58.     struct bmp *bmp = malloc(sizeof(*bmp));
  59.    
  60.     bmp->height = height;
  61.     bmp->width = width;
  62.    
  63.     bmp->data = malloc(bpl * (height + 1));
  64.    
  65.     bmp->bpl = bpl;
  66.    
  67.     bmp->header.bmp_propietary[0] = 'B';
  68.     bmp->header.bmp_propietary[1] = 'M';
  69.     bmp->header.bmp_hdr_size = 54;
  70.     bmp->header.bmp_filesize = bmp->header.bmp_hdr_size + bpl * height;
  71.     bmp->header.bmp_reserved = 0;
  72.     bmp->header.bmp_info_size = 40;
  73.     bmp->header.bmp_width = width;
  74.     bmp->header.bmp_height = height;
  75.     bmp->header.bmp_planes = 1;
  76.     bmp->header.bmp_bits = 24;
  77.     bmp->header.bmp_compression = 0;
  78.     bmp->header.bmp_size_bytes = bpl * height;
  79.     bmp->header.bmp_x_res = 2835;
  80.     bmp->header.bmp_y_res = 2835;
  81.     bmp->header.bmp_colors = 0;      
  82.     bmp->header.bmp_imp_colors = 0;  
  83.    
  84.     strncpy(bmp->filename, filename, 128);
  85.    
  86.     bmp->handle = fopen(filename, "wb+");
  87.     if (!bmp->handle) {
  88.         perror("File open");
  89.         free(bmp->data);
  90.         free(bmp);
  91.         return NULL;
  92.     }
  93.    
  94.     fwrite(&bmp->header, sizeof(struct bmp_hdr), 1, bmp->handle);
  95.    
  96.     return bmp;
  97. }
  98.  
  99. struct bmp *bmp_open (const char *filename)
  100. {
  101.     struct bmp *bmp = malloc(sizeof(*bmp));
  102.     int x, y, ipos, pos;
  103.     unsigned char *buffer;
  104.    
  105.     strncpy(bmp->filename, filename, 128);
  106.    
  107.     bmp->handle = fopen(filename, "r+b");
  108.     if (!bmp->handle) {
  109.         perror("File open");
  110.         free(bmp);
  111.         return NULL;
  112.     }
  113.    
  114.     fread(&bmp->header, sizeof(struct bmp_hdr), 1, bmp->handle);
  115.    
  116.     bmp->height = bmp->header.bmp_height;
  117.     bmp->width = bmp->header.bmp_width;
  118.    
  119.     bmp->bpl = BYTES_PER_LINE(bmp->width);
  120.     bmp->data = malloc((bmp->bpl * bmp->height) + 1);
  121.    
  122.     if (!(buffer = malloc(bmp->bpl * bmp->height + 1))) {
  123.         perror("Buffer allocation");
  124.         return NULL;
  125.     }
  126.    
  127.     fread(buffer, 1, (bmp->bpl * bmp->height), bmp->handle);
  128.    
  129.     pos = 0;
  130.    
  131.     for (y = 0; y < bmp->height; y++) {
  132.         for (x = 0; x < bmp->width; x++) {
  133.             ipos = 3 * ((bmp->height * y) + x);
  134.             bmp->data[ipos + 0] = buffer[pos++];
  135.             bmp->data[ipos + 1] = buffer[pos++];
  136.             bmp->data[ipos + 2] = buffer[pos++];
  137.         }
  138.         pos += (-pos) & 3;
  139.     }
  140.    
  141.     free(buffer);
  142.    
  143.     return bmp;
  144. }
  145.  
  146. int bmp_save (struct bmp *bmp)
  147. {
  148.     int x, y, ipos, pos;
  149.     unsigned char *buffer;
  150.    
  151.     if (!(buffer = malloc(bmp->bpl * bmp->height + 1))) {
  152.         perror("Buffer allocation");
  153.         return -1;
  154.     }
  155.    
  156.     pos = 0;
  157.    
  158.     for (y = 0; y < bmp->height; y++) {
  159.         for (x = 0; x < bmp->width; x++) {
  160.             ipos = 3 * ((bmp->height * y) + x);
  161.             buffer[pos++] = bmp->data[ipos + 0];
  162.             buffer[pos++] = bmp->data[ipos + 1];
  163.             buffer[pos++] = bmp->data[ipos + 2];
  164.         }
  165.         pos += (-pos) & 3;
  166.     }
  167.    
  168.     fseek(bmp->handle, sizeof(struct bmp_hdr), SEEK_SET);
  169.     fwrite(buffer, 1, pos, bmp->handle);
  170.    
  171.     free(buffer);
  172.    
  173.     return 0;
  174. }
  175.  
  176.  
  177. void bmp_close (struct bmp *bmp)
  178. {
  179.     fclose(bmp->handle);
  180.     free(bmp->data);
  181.     free(bmp);
  182. }
  183.  
  184. void bmp_set_pixel (struct bmp *bmp, pix_t r, pix_t g, pix_t b,
  185.             coord_t x, coord_t y)
  186. {
  187.     if (x > bmp->width)
  188.         x = bmp->width;
  189.     if (y > bmp->height)
  190.         y = bmp->height;
  191.    
  192.     coord_t index = 3 * ((bmp->height * y) + x);
  193.    
  194.     bmp->data[index + 2] = r;
  195.     bmp->data[index + 1] = g;
  196.     bmp->data[index + 0] = b;
  197. }
  198.  
  199. void bmp_get_pixel (struct bmp *bmp, pix_t *r, pix_t *g, pix_t *b,
  200.             coord_t x, coord_t y)
  201. {
  202.     if (x > bmp->width)
  203.         x = bmp->width;
  204.     if (y > bmp->height)
  205.         y = bmp->height;
  206.    
  207.     coord_t index = 3 * ((bmp->height * y) + x);
  208.    
  209.     (*r) = bmp->data[index + 2];
  210.     (*g) = bmp->data[index + 1];
  211.     (*b) = bmp->data[index + 0];
  212. }
  213.  
  214. int main (int argc, const char * argv[])
  215. {
  216.     struct bmp *bmp = bmp_new("/file.bmp", 1024, 1024);
  217.     int x, y;
  218.  
  219.     for (y = 0; y < bmp->height; y++) {
  220.         for (x = 0; x < bmp->width; x++) {
  221.             bmp_set_pixel(bmp, x & y, x ^ y, x | y, x, y);
  222.         }
  223.     }
  224.    
  225.     bmp_save (bmp);
  226.     bmp_close(bmp);
  227.    
  228.     return 0;
  229. }
Advertisement
Add Comment
Please, Sign In to add comment