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