hi,
i wrote the following piece code to create a new bitmap file with random RGB values. I wanted to copy the header from the input file.
the problem is it adds two additional bytes to 3rd and 4th (just after the magic number). i can't figure out why.
// img.magic.magic[2] = 'G';
// img.magic.magic[3] = 'Y';
if i uncomment the above lines. those bytes will be replaced by 'G' and 'Y'.
can anyone please explain me what's going on here?
thanks in advance.
#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <stdlib.h>
#include <inttypes.h>
#include <sys/types.h>
#include <unistd.h>
typedef struct bmpfile_magic {
uint8_t magic[2];
} MAGIC;
typedef struct bmpfile_header {
uint32_t filesz;
uint16_t creator1;
uint16_t creator2;
uint32_t bmp_offset;
} BITMAPHEADER;
typedef struct {
uint32_t header_sz;
int32_t width;
int32_t height;
uint16_t nplanes;
uint16_t bitspp;
uint32_t compress_type;
uint32_t bmp_bytesz;
int32_t hres;
int32_t vres;
uint32_t ncolors;
uint32_t nimpcolors;
} BITMAPINFOHEADER;
typedef struct {
MAGIC magic;
BITMAPHEADER head;
BITMAPINFOHEADER infohead;
int ***pixel;
} image;
int
main (int argc, char **argv)
{
int fd;
fd = open(argv[1], O_RDONLY);
image img;
ssize_t n;
int val;
// grabbing the header
// magic numbers
uint8_t v1;
n = read(fd, &v1, 1);
img.magic.magic[0] = v1;
printf ("filetype: %c", img.magic.magic[0]);
n = read(fd, &v1, 1);
img.magic.magic[1] = v1;
printf ("%c\n", img.magic.magic[1]);
// img.magic.magic[2] = 'G';
// img.magic.magic[3] = 'Y';
// file size
n = read(fd, &val, 4);
img.head.filesz = val;
printf ("file size: %"PRIu32"\n", img.head.filesz);
// creator 1
n = read(fd, &val, 2);
img.head.creator1 = val;
printf ("creator1: %d\n", img.head.creator1);
// creator 2
n = read(fd, &val, 2);
img.head.creator2 = val;
printf ("creator2: %d\n", img.head.creator2);
// bitmap offset
n = read(fd, &val, 4);
img.head.bmp_offset = val;
printf ("bitmap offset: %d\n", img.head.bmp_offset);
// header size
n = read(fd, &val, 4);
img.infohead.header_sz = val;
printf ("header size: %d\n", img.infohead.header_sz);
// width
n = read(fd, &val, 4);
img.infohead.width = val;
printf ("width: %d\n", img.infohead.width);
// height
n = read(fd, &val, 4);
img.infohead.height = val;
printf ("height: %d\n", img.infohead.height);
// planes
n = read(fd, &val, 2);
img.infohead.nplanes = val;
printf ("planes: %d\n", img.infohead.nplanes);
// bits per pixel
n = read(fd, &val, 2);
img.infohead.bitspp = val;
printf ("bits per pixel: %d\n", img.infohead.bitspp);
// compression type
n = read(fd, &val, 4);
img.infohead.compress_type = val;
printf ("compression type: %d\n", img.infohead.compress_type);
// size of raw data including padding
n = read(fd, &val, 4);
img.infohead.bmp_bytesz = val;
printf ("size of raw data(including padding): %d\n", img.infohead.bmp_bytesz);
// horizontal resolution
n = read(fd, &val, 4);
img.infohead.hres = val;
printf ("horizontal resolution: %d\n", img.infohead.hres);
// vertical resolution
n = read(fd, &val, 4);
img.infohead.vres = val;
printf ("horizontal resolution: %d\n", img.infohead.vres);
// number of colors on the palette
n = read(fd, &val, 4);
img.infohead.ncolors = val;
printf ("number of colors on the palette: %d\n", img.infohead.ncolors);
// important colors
n = read(fd, &val, 4);
img.infohead.nimpcolors = val;
printf ("important colors: %d\n", img.infohead.nimpcolors);
// allocating memory dynamically
img.pixel = malloc(img.infohead.height * sizeof(int *));
int row, col, c, colors;
// bits per pixel
if (img.infohead.bitspp == 24) colors = 3; else colors = 4;
// padding size
int padding;
padding = (img.infohead.bmp_bytesz - img.infohead.height*img.infohead.width*colors)/img.infohead.height;
printf ("padding: %d\n", padding);
for (row = 0; row < img.infohead.height; row++)
{
img.pixel[row] = malloc(img.infohead.width * sizeof(int *));
}
for (row = 0; row < img.infohead.height; row++)
for (col = 0; col < img.infohead.width; col++)
{
img.pixel[row][col] = malloc(colors * sizeof(int *));
}
// reading data
off_t pos = lseek(fd, img.head.bmp_offset, SEEK_SET);
for (row = img.infohead.height-1; row >= 0; row--)
for (col = 0; col < img.infohead.width; col++)
for (c = 0; c < colors; c++)
{
img.pixel[row][col][c] = (rand () % 255) + 0;
}
// write the new file
FILE *fp2;
fp2 = fopen(argv[2], "w");
ssize_t nn;
//nn = write(fd2, &img, img.head.bmp_offset-1);
fwrite(&img, img.head.bmp_offset, 1, fp2);
for (row = 0; row < img.infohead.height; row++)
for (col = 0; col < img.infohead.width; col++)
for (c = 0; c < colors; c++)
{
printf ("img.pixel[%d][%d][%d]: %d\n", row, col, c, img.pixel[row][col][c]);
}
close(fd);
fclose(fp2);
exit(EXIT_SUCCESS);
}