Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdint.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdbool.h>
- #define errstop(s) fprintf(stderr, s); exit(-1);
- #define SUF "_BW"
- typedef struct {
- char name[2];
- uint32_t size, garbage, imgOffset;
- } BMPHeader;
- typedef struct {
- uint32_t size, width, height;
- uint16_t colorPlanes, bitPerPixel;
- uint32_t compression, imgSize, garbage[4];
- } DIBHeader;
- typedef struct {
- uint8_t red, green, blue;
- } Pixel;
- typedef struct {
- uint32_t height, width;
- Pixel **pixels;
- } Image;
- typedef struct {
- BMPHeader bmpHeader;
- DIBHeader dibHeader;
- Image img;
- } BMPFileData;
- void freeImg(Image *img) {
- for (int i = img->height - 1; i >= 0; i--) {
- free(img->pixels[i]);
- }
- free(img->pixels);
- }
- bool readImgDataInBMP(FILE *file, BMPFileData *bmpFileData) {
- bmpFileData->img = (Image){bmpFileData->dibHeader.height, bmpFileData->dibHeader.width, NULL};
- fseek(file, bmpFileData->bmpHeader.imgOffset, SEEK_SET);
- bmpFileData->img.pixels = (Pixel**)calloc(sizeof(void*), bmpFileData->img.height);
- if (bmpFileData->img.pixels == NULL) {
- perror("");
- fclose(file);
- exit(EXIT_FAILURE);
- }
- uint64_t sz = 0;
- for (int i = bmpFileData->img.height - 1; i >= 0; i--) {
- bmpFileData->img.pixels[i] = (Pixel*)calloc(sizeof(Pixel), bmpFileData->img.width);
- if (bmpFileData->img.pixels[i] == NULL) {
- freeImg(&bmpFileData->img);
- fclose(file);
- perror("");
- exit(EXIT_FAILURE);
- }
- sz += fread(bmpFileData->img.pixels[i], sizeof(Pixel), bmpFileData->img.width, file);
- }//*/
- return sz == 1ULL * bmpFileData->dibHeader.height * bmpFileData->dibHeader.width;
- }
- void pixelToGreyScale(Pixel *pixel) {
- uint8_t mean = (pixel->red + pixel->green + pixel->blue) / 3;
- pixel->red = pixel->green = pixel->blue = mean;
- }
- void imgToGreyScale(Image *img) {
- for (int i = 0; i < img->height; i++) {
- for (int j = 0; j < img->width; j++) {
- pixelToGreyScale(&img->pixels[i][j]);
- }
- }
- }
- void createBWimgBMPFile(BMPFileData bmpFileData, char path[]) {
- FILE *fout = fopen(path, "wb");
- if (fout == NULL) {
- free(path);
- freeImg(&bmpFileData.img);
- perror("");
- exit(EXIT_FAILURE);
- }
- imgToGreyScale(&bmpFileData.img);
- uint64_t sumw = 0;
- bool ok = true;
- ok &= fwrite(&bmpFileData.bmpHeader.name, sizeof(char), 2, fout) == 2;
- ok &= fwrite(&bmpFileData.bmpHeader.size, sizeof(uint32_t), 3, fout) == 3;
- ok &= fwrite(&bmpFileData.dibHeader, sizeof(DIBHeader), 1, fout) == 1;
- for (int i = bmpFileData.img.height - 1; i >= 0; i--) {
- sumw += fwrite(bmpFileData.img.pixels[i], sizeof(Pixel), bmpFileData.img.width, fout);
- }
- ok &= (sumw == 1ULL * bmpFileData.img.height * bmpFileData.img.width);
- if (!ok) {
- free(path);
- freeImg(&bmpFileData.img);//*/
- errstop("failed to create file!\n");
- }
- if (fclose(fout) == EOF) {
- perror("closing error");
- } else {
- puts("SUCCESS");
- }
- }
- bool readBMPHeader(BMPHeader *bmpHeader, FILE *fin) {
- int sz = 0;
- sz += fread(&bmpHeader->name, sizeof(char), 2, fin);
- sz += fread(&bmpHeader->size, sizeof(uint32_t), 3, fin);
- if (strncmp(bmpHeader->name, "BM", 2) || sz != 5) {
- return false;
- }
- return true;
- }
- bool readDIBHeadder(DIBHeader *dibHeader, FILE *fin) {
- const int WANTED_BPP = 24;
- bool ok = fread(dibHeader, sizeof(*dibHeader), 1, fin) == 1;
- ok &= (dibHeader->colorPlanes);
- ok &= (dibHeader->bitPerPixel == WANTED_BPP);
- return ok;
- }
- bool readBMPFile(BMPFileData *bmpFileData, const char path[]) {
- FILE *fin = fopen(path, "rb");
- if (fin == NULL) {
- perror("");
- exit(EXIT_FAILURE);
- }
- bool successRead = true;
- successRead &= readBMPHeader(&bmpFileData->bmpHeader, fin);
- successRead &= readDIBHeadder(&bmpFileData->dibHeader, fin);
- if (!successRead) {
- fclose(fin);
- return false;
- }
- bool sucReadImg = readImgDataInBMP(fin, bmpFileData);
- fclose(fin);
- return sucReadImg;
- }
- int main(int argc, char *argv[]) {
- if (argc == 1) {
- errstop("specify the file name!\n");
- }
- if (strcmp(strrchr(argv[1], '.'), ".bmp")) {
- errstop("wrong extension!\n");
- }
- BMPFileData bmpFileData;
- if (!readBMPFile(&bmpFileData, argv[1])) {
- errstop("corrupted/invalid file!\n");
- }
- int len = strlen(argv[1]);
- char *newName = (char*)calloc(sizeof(char), len + strlen(SUF) + 1);
- strcpy(newName, argv[1]);
- newName[strcspn(newName, ".")] = 0;
- strcat(newName, SUF);
- strcat(newName, ".bmp");
- createBWimgBMPFile(bmpFileData, newName);
- freeImg(&bmpFileData.img);
- free(newName);
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement