I'm currently learning C and I started to write a BMP image reader and writer, to make some operations with basic images.
I'm reading the BMP image and saving it into a struct, then just write a copy to ensure that the flow is working, but, when I write the image I get the following result
Where the left one is the original and the right one the copy, I don't know if I'm not saving enough memory or if I'm not writing in the right way the data.
I have the header file and the implementation, where I wrote two functions readImage
and writeImage
, both receive the filename and the Image struct described in the header file.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdbool.h>
typedef uint16_t ImageType;
typedef struct
{
uint32_t size;
uint16_t additionalFeature;
uint16_t copy;
uint32_t offset;
} ImageHeader;
typedef struct
{
uint32_t headerSize;
int width;
int height;
uint16_t colorSpaces;
uint16_t bitsPerPixel;
uint32_t compression;
uint32_t size;
int verticalResolution;
int horizontalResolution;
uint32_t totalColors;
uint32_t importantColors;
} ImageMetadata;
typedef struct {
int red;
int green;
int blue;
int reserved;
} ImageColors;
typedef unsigned char *ImagePixels;
typedef struct {
ImageType type;
ImageHeader header;
ImageMetadata metadata;
ImagePixels pixels;
} Image;
ImageType BMP_IMAGE_TYPE = 0x4D42;
void readImage(char *filename, Image *image);
void writeImage(char *filename, Image *image);
void fragmentImage(Image *image);
#include "bmp.h"
void readImage(char *filename, Image *image)
{
FILE *imageFile = fopen(filename, "r");
if (!imageFile)
{
perror("ReadImageFileException");
fclose(imageFile);
exit(EXIT_FAILURE);
}
fread(&(image->type), sizeof(ImageType), 1, imageFile);
if (image->type != BMP_IMAGE_TYPE)
{
fprintf(stderr, "%hu", image->type);
perror("ReadImageTypeException");
fclose(imageFile);
exit(EXIT_FAILURE);
}
fread(&(image->header), sizeof(ImageHeader), 1, imageFile);
fread(&(image->metadata), sizeof(ImageMetadata), 1, imageFile);
image->pixels = (unsigned char *)malloc(image->metadata.width * image->metadata.height);
if (!image->pixels)
{
perror("ReadImagePixelsException");
fclose(imageFile);
exit(EXIT_FAILURE);
}
fseek(imageFile, image->header.offset, SEEK_SET);
fread(image->pixels, sizeof(char) * image->metadata.width * image->metadata.height, 1, imageFile);
fclose(imageFile);
}
void writeImage(char *filename, Image *image)
{
FILE *imageFile = fopen(filename, "w+");
if (!imageFile)
{
perror("WriteImageFileException");
fclose(imageFile);
exit(EXIT_FAILURE);
}
int typeWritten = fwrite(&(image->type), sizeof(image->type), 1, imageFile);
if (typeWritten == 0)
{
perror("WriteImageTypeException");
fclose(imageFile);
exit(EXIT_FAILURE);
}
int headerWritten = fwrite(&(image->header), sizeof(image->header), 1, imageFile);
if (headerWritten == 0)
{
perror("WriteImageHeaderException");
fclose(imageFile);
exit(EXIT_FAILURE);
}
int metadataWritten = fwrite(&(image->metadata), sizeof(image->metadata), 1, imageFile);
if (metadataWritten == 0)
{
perror("WriteImageMetadataException");
fclose(imageFile);
exit(EXIT_FAILURE);
}
fseek(imageFile, image->header.offset, SEEK_SET);
int pixelsWritten = fwrite(image->pixels, sizeof(char) * image->metadata.width * image->metadata.height, 1, imageFile);
if (pixelsWritten == 0)
{
perror("WriteImagePixelsException");
fclose(imageFile);
exit(EXIT_FAILURE);
}
fclose(imageFile);
}
In the main file, I declare the image data structure and pass it to both functions
#include "bmp.c"
int main() {
Image image;
readImage("image.bmp", &image);
writeImage("image-copy.bmp", &image);
return 0;
}
?Someone could help to identify what I'm doing wrong? I already try to allocate more memory or calculate the size of the data structure that saves the pixels with the header that saves the image size, but it didn't work.
question from:
https://stackoverflow.com/questions/65840161/write-bmp-image