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