Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <stdint.h>
- #include <limits.h>
- #include <errno.h>
- #include <time.h>
- struct BMPFileHeader {
- // "BM"
- uint16_t type;
- // size of file in bytes
- uint32_t size;
- // reserved, unused, must be 0
- uint16_t reserved1;
- uint16_t reserved2;
- // offset to start pixel data
- // or rahter... file offset for the start of the actual image data
- uint32_t offset_bits;
- };
- struct BMPImageHeader {
- // 40
- uint32_t header_size;
- // width and height of the image, in pixels
- uint32_t width;
- uint32_t height;
- // always 1 plane
- uint16_t planes;
- // go for 24bit-true-color
- // R G B
- // 00000000 00000000 00000000
- uint16_t bit_count;
- // 0, no compression
- uint32_t compression;
- // image size. May be zero for uncompressed images
- uint32_t image_size;
- // 0, no preference
- uint32_t x_pixels_per_meter;
- uint32_t y_pixels_per_meter;
- // number of color map entries actually used
- // 0 for 24bit true color
- uint32_t color_maps_used;
- // number of significant colors in the color table
- // set to 0 for default (a lot), no color table anyway
- uint32_t color_important;
- };
- int sort_cmp(const void *a, const void *b)
- {
- return *(uint8_t *)a - *(uint8_t *)b;
- }
- int32_t getPositive32bit(const char *num)
- {
- int res;
- char *endptr;
- res = strtol(num, &endptr, 10);
- if (errno == ERANGE || res == LONG_MIN || res == LONG_MAX) {
- return -1;
- }
- if (*endptr != '\0') {
- return -1;
- }
- if (res <= 0) {
- return -1;
- }
- if (res > 2147483647) {
- return -1;
- }
- return res;
- }
- int write_file(int f, struct BMPFileHeader *fh, struct BMPImageHeader *ih, uint8_t *img)
- {
- // file header
- write(f, &fh->type, 2);
- write(f, &fh->size, 4);
- write(f, &fh->reserved1, 2);
- write(f, &fh->reserved2, 2);
- write(f, &fh->offset_bits, 4);
- // img header
- write(f, &ih->header_size, 4);
- write(f, &ih->width, 4);
- write(f, &ih->height, 4);
- write(f, &ih->planes, 2);
- write(f, &ih->bit_count, 2);
- write(f, &ih->compression, 4);
- write(f, &ih->image_size, 4);
- write(f, &ih->x_pixels_per_meter, 4);
- write(f, &ih->y_pixels_per_meter, 4);
- write(f, &ih->color_maps_used, 4);
- write(f, &ih->color_important, 4);
- // image data
- write(f, img, ih->width * ih->height * 3);
- return 0;
- }
- struct BMPImageHeader *makeBMPImageHeader(uint32_t width, uint32_t height)
- {
- struct BMPImageHeader *image_header = calloc(1, sizeof(struct BMPImageHeader));
- image_header->header_size = 40;
- image_header->width = width;
- image_header->height = height;
- image_header->planes = 1;
- image_header->bit_count = 24;
- return image_header;
- }
- struct BMPFileHeader *makeBMPFileHeader(struct BMPImageHeader *ih)
- {
- struct BMPFileHeader *file_header = calloc(1, sizeof(struct BMPFileHeader));
- file_header->type |= 'M' << 8;
- file_header->type |= 'B';
- file_header->size = 54 + (ih->width * ih->height * 3);
- file_header->offset_bits = 54;
- return file_header;
- }
- uint8_t *makeBMPImageData(struct BMPImageHeader *image_header)
- {
- int i;
- int j;
- uint8_t r;
- size_t size;
- uint8_t *data;
- uint8_t *dptr;
- size = image_header->height * image_header->width;
- data = calloc(1, size * 3);
- dptr = data;
- for (i = 0; i < size; i++) {
- // write 1 pixel to buffer (3 bytes per pixel)
- for (j = 0; j < 3; j++, dptr++) {
- r = rand() & 0x000000FF;
- *dptr = r;
- }
- }
- qsort(data, size, 3, sort_cmp);
- return data;
- }
- void seed_rng(void)
- {
- long int seed;
- int fp = open("/dev/urandom", O_RDONLY);
- read(fp, (char *)&seed, sizeof(seed));
- srand(seed);
- close(fp);
- }
- int main(int argc, char *argv[])
- {
- int f;
- int32_t width;
- int32_t height;
- uint8_t *data;
- struct BMPImageHeader *image_header;
- struct BMPFileHeader *file_header;
- if (argc < 4) {
- fprintf(stderr, "Usage: %s width height filename\n", argv[0]);
- return -1;
- }
- seed_rng();
- width = getPositive32bit(argv[1]);
- if (width == -1) {
- fprintf(stderr, "Invalid width %s\n", argv[1]);
- return -1;
- }
- height = getPositive32bit(argv[2]);
- if (height == -1) {
- fprintf(stderr, "Invalid height %s\n", argv[2]);
- return -1;
- }
- f = open(argv[3], O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IXUSR);
- if (f == -1) {
- fprintf(stderr, "Could not open file for writing: %s\n", argv[3]);
- return -1;
- }
- image_header = makeBMPImageHeader(width, height);
- file_header = makeBMPFileHeader(image_header);
- data = makeBMPImageData(image_header);
- write_file(f, file_header, image_header, data);
- close(f);
- free(image_header);
- free(file_header);
- free(data);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement