My new debugging technique is unstoppable.

Using bitmaps in C (really basic)

I don't like C, but sometimes I have to use it, and this was one of those times. Here's a quick explanation on how to read a 24 bit bitmap in C:

The code is here](bitmap.c), it takes a bitmap and prints it out as ASCII, like the picture at the right.

Header

Basically you want to open the file as binary for reading: `C fp = fopen(bmpFile,"rb")`c and find the useful values in the header. More information about the header can be found [here](http://www.fortunecity.com/skyscraper/windows/364/bmpffrmt.html).

Here's how I read through the header, somewhat awkwardly putting the bits I don't care about into a char* called junk:

  1. word filesize, width, height, bitsperpixel;
  2. fread(&filesize, 4, 1, fp);
  3. fread(junk,12,1,fp); //ignore some of the file
  4. fread(&width, 4, 1, fp);
  5. fread(&height, 4, 1, fp);
  6. fread(junk,2,1,fp); //ignore some of the file
  7. fread(&bitsperpixel, 2, 1, fp);
  8. fread(junk, 24, 1, fp);//ignore some of the file

Problems

The bitmap format has each row padded out with zeros to be a multiple of 4. As in: `C int padding = (4-((3*width) % 4))%4; `c, which I addded to the loop that reads the rows.

Also the rows are upside down. Which is annoying.

I only print out the bitmap, I assume you that if you need it, you know how to use `Cmalloc`c to proceed to actually do something with the picture. bitmap1.zip is a zip containing the source, some test BMPs and a compiled EXE.

Code

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <errno.h>
  4.  
  5. typedef unsigned char byte;
  6. typedef unsigned short word;
  7. typedef unsigned long dword;
  8.  
  9. int main(int argc, char *argv[]) {
  10. FILE *fp;
  11. char *bmpFile;
  12. char junk[255];
  13.  
  14. if(argc==2) {
  15. bmpFile = argv[1];
  16. } else {
  17. bmpFile = "t.bmp";
  18. }
  19.  
  20. if ((fp = fopen(bmpFile,"rb")) == NULL) {
  21. printf("Can't find file: %s.\n",bmpFile);
  22. exit(1);
  23. }
  24.  
  25. /* minor error handling */
  26. if (fgetc(fp)!='B' || fgetc(fp)!='M') {
  27. fclose(fp);
  28. printf("Invlaid file: %s.\n",bmpFile);
  29. exit(1);
  30. }
  31.  
  32. word filesize, width, height, bitsperpixel;
  33. word r,g,b,pixel;
  34. fread(&filesize, 4, 1, fp);
  35. fread(junk,12,1,fp); //ignore some of the file
  36. fread(&width, 4, 1, fp);
  37. fread(&height, 4, 1, fp);
  38. printf("Size: %d,[%dx%d]\n",filesize,width,height);
  39. fread(junk,2,1,fp); //ignore some of the file
  40. fread(&bitsperpixel, 2, 1, fp);
  41. if (bitsperpixel<24) {
  42. fclose(fp);
  43. printf("This is designed for 24 bit bitmaps, %s has %d.\n",bmpFile,bitsperpixel);
  44. exit(1);
  45. }
  46. fread(junk, 24, 1, fp);
  47.  
  48. int x,y;
  49. //the format pretends all rows are divisible by 4
  50. int padding = (4-((3*width) % 4))%4;
  51.  
  52. //the image is stored upside down:
  53. for(y=0;y<height;y++) {
  54. for(x=0;x<width;x++) {
  55. r=b=g=0;
  56. fread(&b, 1, 1, fp);
  57. fread(&g, 1, 1, fp);
  58. fread(&r, 1, 1, fp);
  59. pixel = g;
  60. if(pixel>200) printf("@");
  61. else if(pixel>150) printf("X");
  62. else if(pixel>100) printf("+");
  63. else if(pixel>50) printf(":");
  64. else printf(" ");
  65.  
  66. }
  67. fread(junk, padding,1,fp);
  68. printf("\n");
  69. }
  70.  
  71. }


Programming Math etc

What I've said lately

Loading feeds

More of me on the web