-1

I'm very new in C programming and I am trying make a program that reads a text file and makes a black and white bmp out of it. I think my code is almost done, but I only get a black image.

What am I missing or what'ss wrong?

0000000000

0000110000 

0001111000

0011111100

0111111110

1111111111

0111111110

0011111100

0001111000

0000110000

Here is code:

#include <stdio.h>
#include <strings.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

 int k = 0;

#pragma pack(1)
    typedef struct{
     uint16_t bfType;
     uint32_t bfSize;
 uint16_t bfReserved1;
 uint16_t bfReserved2;
 uint32_t bfOffBits;
} BMPFH;
#pragma pack()

#pragma pack(1)
typedef struct{
uint32_t biSize;
int32_t biWidth;
int32_t biHeight;
uint16_t  biPlanes;
uint16_t biBitCount;
uint32_t biCompression;
uint32_t bisizeImage;
int32_t biXPelsPerMeter;
int32_t biYPelsPerMeter;
uint32_t biClrUsed;
uint32_t biClrImportant;
} BMIH;
#pragma pack()

#pragma pack(1)
typedef struct {
BMPFH BMPFH;
BMIH BMIH;
} bitmap;
#pragma pack()

int main() {
 FILE * input = fopen("/Users/JosPaduaA/desktop/dibujo1.txt", "r");
        char txt[100];
        int bmp[2400] = {0};
        int j = 0, i = 0;
        fread(txt, 100, 1, input);
        fclose(input);
        while(i < 100){
                if(txt[i] == '1'){
                        for(j = 0; j < 24; j++){
                                bmp[k] = 1;
                                k++;
                        }
                }
                else{
                        k += 24;
                }
        i++;
        }
BMPFH fh;
BMIH ih;
FILE* file = fopen("out.bmp","wb");

memcpy(&fh.bfType,"BM",2);
fh.bfSize = 14+40+320; //ERROR
fh.bfOffBits = 14+40;
fh.bfReserved1 = 0;
fh.bfReserved2 = 0;

ih.biSize = 40;
ih.biWidth = 10;
ih.biHeight = 10;
ih.biPlanes = 1;
ih.biBitCount = 24;
ih.biCompression = 0;
ih.bisizeImage = 0;
ih.biXPelsPerMeter = 0;
ih.biYPelsPerMeter = 0;
ih.biClrUsed = 0;
ih.biClrImportant = 0;

fwrite(&fh,sizeof(fh),1,file);
fwrite(&ih,sizeof(ih),1,file);
unsigned int data_size = fh.bfSize - sizeof(bitmap);
uint8_t *pixelbuffer = (uint8_t*)malloc(data_size);
bitmap *pbitmap  = (bitmap*)calloc(1,sizeof(bitmap));
memset(pixelbuffer, 0, data_size);
fwrite(pixelbuffer, 1, data_size, file);
fclose(file);
free(pixelbuffer);
return 0;
}
Unheilig
  • 16,196
  • 193
  • 68
  • 98
  • 1
    It is always good idea to read code aloud - line by line and explain each line. You can talk to yourself or use [rubber duck](https://en.wikipedia.org/wiki/Rubber_duck_debugging). Usually error reveals itself magically - just don't lie to yourself and really *read the code* and not what you *think* is written there. – Alexei Levenkov Nov 07 '15 at 03:37
  • Are you able to ignore input completely and write a white bmp? If yes, now print all the pixels you write to bmp. – Mohit Jain Nov 07 '15 at 05:37
  • regarding the calls to `malloc()` and `calloc()` 1) in C, the returned value is a `void*` so can be assigned to any other pointer. Casting the returned value just clutters the code, and is a major headache when debugging and performing maintenance. 2) always check (!=NULL) the returned value to assure the operation was successful – user3629249 Nov 07 '15 at 08:30
  • the pointer to allocated memory `pbitmap` is not passed to `free()`, resulting in a memory leak. – user3629249 Nov 07 '15 at 08:31
  • when calling the function `fwrite()`, always check the returned value to assure the operation was successful. When calling the function: `fopen()`, always check the returned value to assure the operation was successful. regarding this kind of line: `fwrite(&fh,sizeof(fh),1,file);`, it is easy to compare with 1 when checking the validity. however, this kind of line: `fwrite(pixelbuffer, 1, data_size, file);` the returned value must be checked against `data_size` when checking the success of the operaiton – user3629249 Nov 07 '15 at 08:36
  • A .bmp file has a specific format. as documented at: ; and even better in: /en.wikipedia.org/wiki/BMP_file_format > Suggest reading/understaning that web page. Then pattern your code to output that format. When writing a .bmp file, it is usually best to define it as arrays of char. then place the data into those arrays, Taking into account that the endianness of the data must be correct, even if the underlying architecture is the opposite endianness – user3629249 Nov 07 '15 at 08:44
  • on a .bmp file, the width of each row has to be a multiple of 4, which 10 is not. Each pixel is (typically) 3 or 4 bytes consisting of red, blue, green and transparency. That is not the way the posted code is defining the pixels, where each item in the pixel is 1 byte wide, so a complete pixel is either 3 or 4 bytes wide – user3629249 Nov 07 '15 at 08:50
  • I have printed all operation values and checked binary files as output they seem correct. Regarding the multiple of 4 thing, the array bmp has 2400 item where each the idea is that each number of mi text file is passed to a 3byte value. So bmp has the encoded data for a 240x10 array. – EmptyPhysicist Nov 07 '15 at 16:18
  • the posted code does not agree with the sizing given in your last comment. your comment indicates the image is 80 pixels wide by 10 pixels high. However, the values in the posted code is only 10 pixels wide and the malloc() for the image no where near 2400 bytes. – user3629249 Nov 07 '15 at 18:19
  • Oh, I think I see what you mean... I designed my code to make a bit array. You are saying that it should be a byte array right? – EmptyPhysicist Nov 07 '15 at 18:41

1 Answers1

0

this line:

memset(pixelbuffer, 0, data_size);

is setting all the pixel values to 0x00 0x00 0x00 , which is black

user3629249
  • 16,402
  • 1
  • 16
  • 17
  • Thank you I had not realized that... What could be a correct line? – EmptyPhysicist Nov 07 '15 at 16:14
  • before setting any pixel value, have enough space for all the pixels. Since every pixel will be initialized by the image, there is no need to initialize the data. However, since the actual number of bytes in a line may not be a multiple of 4, there may be some trailing bytes on each line that should be set to 0x00. Since each pixel is (per your comment) 24 bits (3 bytes) The malloc for the image needs to be 80 *3*10 = 2400 bytes not 200...400 bytes. – user3629249 Nov 07 '15 at 18:23