1 | #include "BMPImageLoaderImpl.h" |
---|
2 | #include "Image.h" |
---|
3 | #include <stdio.h> |
---|
4 | #include <memory.h> |
---|
5 | #include <stdlib.h> |
---|
6 | |
---|
7 | BMPImageLoaderImpl::BMPImageLoaderImpl() |
---|
8 | { |
---|
9 | } |
---|
10 | |
---|
11 | BMPImageLoaderImpl::~BMPImageLoaderImpl() |
---|
12 | { |
---|
13 | } |
---|
14 | |
---|
15 | // I referred to cjbackhouse@hotmail.com www.backhouse.tk |
---|
16 | Image* BMPImageLoaderImpl::load(const char* fileName) |
---|
17 | { |
---|
18 | printf("BMP loader\n"); |
---|
19 | fflush(stdout); |
---|
20 | Image* image = 0; |
---|
21 | |
---|
22 | printf("opening image file \"%s\"\n", fileName); |
---|
23 | FILE* f = fopen(fileName, "rb"); |
---|
24 | |
---|
25 | if (!f) { |
---|
26 | printf("File not found\n"); |
---|
27 | return 0; |
---|
28 | } |
---|
29 | |
---|
30 | char header[54]; |
---|
31 | if (fread(&header, 54, 1, f) != 1) { |
---|
32 | printf("can't read header of BMP file\n"); |
---|
33 | return 0; |
---|
34 | }; |
---|
35 | |
---|
36 | if (header[0] != 'B' || header[1] != 'M') { |
---|
37 | printf("File is not BMP format\n"); |
---|
38 | return 0; |
---|
39 | } |
---|
40 | |
---|
41 | //it seems gimp sometimes makes its headers small, so we have to do |
---|
42 | //this. hence all the fseeks |
---|
43 | int offset=*(unsigned int*)(header+10); |
---|
44 | |
---|
45 | const unsigned int width =*(int*) (header+18); |
---|
46 | const unsigned int height =*(int*) (header+22); |
---|
47 | |
---|
48 | int bits=int(header[28]); //colourdepth |
---|
49 | |
---|
50 | printf("image width = %d height = %d bits=%d\n", width, height, bits); |
---|
51 | fflush(stdout); |
---|
52 | |
---|
53 | image = new Image(width, height, _targetImageFormat, |
---|
54 | Image::IMG_UNSIGNED_BYTE, 0); |
---|
55 | |
---|
56 | printf("image created\n"); |
---|
57 | fflush(stdout); |
---|
58 | |
---|
59 | unsigned char* bytes = (unsigned char*) image->getImageBuffer(); |
---|
60 | memset(bytes, 0, sizeof(unsigned char) * width * height * _targetImageFormat); |
---|
61 | |
---|
62 | printf("reset image buffer\n"); |
---|
63 | fflush(stdout); |
---|
64 | |
---|
65 | unsigned int x,y; |
---|
66 | unsigned char cols[256*4]; //colourtable |
---|
67 | switch(bits) { |
---|
68 | case 24: |
---|
69 | fseek(f,offset,SEEK_SET); |
---|
70 | if (_targetImageFormat == Image::IMG_RGB) { |
---|
71 | if (fread(bytes,width*height*3,1,f) != 1) { |
---|
72 | fprintf(stderr, "can't read image data\n"); |
---|
73 | } |
---|
74 | for(x=0;x<width*height*3;x+=3) { //except the format is BGR, grr |
---|
75 | unsigned char temp = bytes[x]; |
---|
76 | bytes[x] = bytes[x+2]; |
---|
77 | bytes[x+2] = temp; |
---|
78 | } |
---|
79 | } else if (_targetImageFormat == Image::IMG_RGBA) { |
---|
80 | char* buff = (char*) malloc(width * height * sizeof(unsigned char) * 3); |
---|
81 | if (fread(buff,width*height*3,1,f) != 1) { |
---|
82 | fprintf(stderr, "can't read BMP image data\n"); |
---|
83 | } |
---|
84 | for(x=0, y = 0;x<width*height*3;x+=3, y+=4) { //except the format is BGR, grr |
---|
85 | bytes[y] = buff[x+2]; |
---|
86 | bytes[y+2] = buff[x]; |
---|
87 | bytes[y+3] = 255; |
---|
88 | } |
---|
89 | free(buff); |
---|
90 | } |
---|
91 | break; |
---|
92 | case 8: |
---|
93 | if (fread(cols,256 * 4,1,f) != 1) { |
---|
94 | fprintf(stderr, "can't read colortable from BMP file\n"); |
---|
95 | } |
---|
96 | fseek(f,offset,SEEK_SET); |
---|
97 | for(y=0;y<height;++y) { //(Notice 4bytes/col for some reason) |
---|
98 | for(x=0;x<width;++x) { |
---|
99 | unsigned char byte; |
---|
100 | if (fread(&byte,1,1,f) != 1) { |
---|
101 | fprintf(stderr, "error reading BMP file\n"); |
---|
102 | } |
---|
103 | for(int c=0; c< 3; ++c) { |
---|
104 | //bytes[(y*width+x)*3+c] = cols[byte*4+2-c]; //and look up in the table |
---|
105 | bytes[(y*width+x)*_targetImageFormat + c] = cols[byte*4+2-c]; //and look up in the table |
---|
106 | } |
---|
107 | } |
---|
108 | } |
---|
109 | break; |
---|
110 | /* |
---|
111 | case(4): |
---|
112 | fread(cols,16*4,1,f); |
---|
113 | fseek(f,offset,SEEK_SET); |
---|
114 | for(y=0;y<256;++y) |
---|
115 | for(x=0;x<256;x+=2) |
---|
116 | { |
---|
117 | BYTE byte; |
---|
118 | fread(&byte,1,1,f); //as above, but need to exract two |
---|
119 | |
---|
120 | for(c=0;c<_targetImageFormat;++c) //pixels from each byte |
---|
121 | bmp.pixel(x,y,c)=cols[byte/16*4+2-c]; |
---|
122 | |
---|
123 | for(c=0;c<_targetImageFormat;++c) |
---|
124 | bmp.pixel(x+1,y,c)=cols[byte%16*4+2-c]; |
---|
125 | */ |
---|
126 | } |
---|
127 | |
---|
128 | printf("image initialized\n"); |
---|
129 | fflush(stdout); |
---|
130 | return image; |
---|
131 | } |
---|