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