00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <stdio.h>
00018 #include <stdlib.h>
00019
00020 #include <spl/types.h>
00021
00022 #ifdef _WINDOWS
00023 #include <spl/configwin32.h>
00024 #else
00025 #include <spl/autoconf/config.h>
00026 #endif
00027
00028 #ifdef HAVE_STRING_H
00029 #include <string.h>
00030 #endif
00031
00032 #include <spl/Image.h>
00033
00034 static unsigned int u32fread(FILE *);
00035 static unsigned int u16fread(FILE *);
00036 static unsigned int u8fread(FILE *);
00037
00038 static bool IsBMP(char const *name)
00039 {
00040 int len = (int)strlen(name);
00041 return name[len-1] == 'p' && name[len-2] == 'm' && name[len-3] == 'b' && name[len-4] == '.';
00042 }
00043
00044 Image *Image::GetImage(const char *name)
00045 {
00046 Image *im = new Image();
00047 if ( ! IsBMP(name) )
00048 {
00049 delete im;
00050 return NULL;
00051 }
00052
00053 unsigned int i, colors, offset, tmp, planes;
00054 FILE *fp;
00055
00056 fp = fopen(name, "rb");
00057 if(!fp)
00058 {
00059 delete im;
00060 return NULL;
00061 }
00062
00063 if(u16fread(fp) != 0x4d42)
00064 {
00065 fclose(fp);
00066 delete im;
00067 return NULL;
00068 }
00069
00070 u32fread(fp);
00071 u16fread(fp);
00072 u16fread(fp);
00073
00074 offset = u32fread(fp);
00075
00076 tmp = u32fread(fp);
00077 if(tmp == 40)
00078 {
00079 im->m_w = u32fread(fp);
00080 im->m_h = u32fread(fp);
00081 planes = u16fread(fp);
00082 im->m_bpp = u16fread(fp);
00083
00084 tmp = u32fread(fp);
00085 if(tmp != 0)
00086 {
00087 fclose(fp);
00088 delete im;
00089 return NULL;
00090 }
00091
00092 u32fread(fp);
00093 u32fread(fp);
00094 u32fread(fp);
00095 u32fread(fp);
00096 u32fread(fp);
00097
00098 colors = (offset - 54) / 4;
00099 for(i = 0; i < colors && i < 256; i++)
00100 {
00101 im->m_blue[i] = u8fread(fp) * 16;
00102 im->m_green[i] = u8fread(fp) * 16;
00103 im->m_red[i] = u8fread(fp) * 16;
00104 im->m_alpha[i] = 0;
00105 u8fread(fp);
00106 }
00107 }
00108 else if(tmp == 12)
00109 {
00110 im->m_w = u32fread(fp);
00111 im->m_h = u32fread(fp);
00112 planes = u16fread(fp);
00113 im->m_bpp = u16fread(fp);
00114
00115 colors = (offset - 26) / 3;
00116 for(i = 0; i < colors && i < 256; i++)
00117 {
00118 im->m_blue[i] = u8fread(fp);
00119 im->m_green[i] = u8fread(fp);
00120 im->m_red[i] = u8fread(fp);
00121 im->m_alpha[i] = 0;
00122 }
00123 }
00124 else
00125 {
00126 fclose(fp);
00127 delete im;
00128 return NULL;
00129 }
00130
00131
00132 for(i = colors; i < 256; i++)
00133 im->m_blue[i] = im->m_green[i] = im->m_red[i] = im->m_alpha[i] = 0;
00134
00135 im->m_depth = (im->m_bpp + 7) / 8;
00136
00137
00138 if(!im->m_w || im->m_w > 0x10000 || !im->m_h || im->m_h > 0x10000 || planes != 1)
00139 {
00140 fclose(fp);
00141 delete im;
00142 return NULL;
00143 }
00144
00145
00146 im->m_pixels = (byte *)malloc(im->m_w * im->m_h * im->m_depth);
00147 if(!im->m_pixels)
00148 {
00149 fclose(fp);
00150 delete im;
00151 return NULL;
00152 }
00153
00154 memset(im->m_pixels, 0, im->m_w * im->m_h * im->m_depth);
00155
00156
00157 for(i = im->m_h; i--; )
00158 {
00159 int j;
00160 unsigned int k, bits = 0;
00161
00162 switch(im->m_bpp)
00163 {
00164 case 1:
00165 for(j = 0; j < im->m_w; j++)
00166 {
00167 k = j % 32;
00168 if(k == 0)
00169 bits = u32fread(fp);
00170 im->m_pixels[im->m_w * i * im->m_depth + j] =
00171 (bits >> ((k & ~0xf) + 0xf - (k & 0xf))) & 0x1;
00172 }
00173 break;
00174 case 4:
00175 for(j = 0; j < im->m_w; j++)
00176 {
00177 k = j % 8;
00178 if(k == 0)
00179 bits = u32fread(fp);
00180 im->m_pixels[im->m_w * i * im->m_depth + j] =
00181 (bits >> (4 * ((k & ~0x1) + 0x1 - (k & 0x1)))) & 0xf;
00182 }
00183 break;
00184 default:
00185
00186 fread(im->m_pixels + im->m_w * i * im->m_depth, im->m_w * im->m_depth, 1, fp);
00187
00188 tmp = (im->m_w * im->m_depth) % 4;
00189 tmp = (4 - tmp) % 4;
00190 while(tmp--)
00191 u8fread(fp);
00192 break;
00193 }
00194 }
00195
00196 switch(im->m_depth)
00197 {
00198 case 3:
00199 im->m_rmask = 0xff0000;
00200 im->m_gmask = 0x00ff00;
00201 im->m_bmask = 0x0000ff;
00202 im->m_amask = 0x000000;
00203 break;
00204 case 2:
00205 im->m_rmask = 0x7c00;
00206 im->m_gmask = 0x03e0;
00207 im->m_bmask = 0x001f;
00208 im->m_amask = 0x0000;
00209 break;
00210 case 1:
00211 default:
00212 im->m_bpp = 8;
00213 im->m_rmask = im->m_gmask = im->m_bmask = im->m_amask = 0;
00214 break;
00215 }
00216 fclose(fp);
00217
00218 return im;
00219 }
00220
00221 Image::Image()
00222 : m_pixels(NULL)
00223 {
00224 }
00225
00226 Image::~Image()
00227 {
00228 if ( NULL != m_pixels )
00229 {
00230 free(m_pixels);
00231 }
00232 }
00233
00234 #ifdef DEBUG
00235 void Image::ValidateMem () const
00236 {
00237 ASSERT_PTR(m_pixels);
00238 }
00239
00240 void Image::CheckMem () const
00241 {
00242 DEBUG_NOTE_MEM(m_pixels);
00243 }
00244 #endif
00245
00246
00247 #if !defined(USE_IMLIB2)
00248 static unsigned int u32fread(FILE *fp)
00249 {
00250 unsigned char buffer[4];
00251 fread(buffer, 4, 1, fp);
00252 return ((unsigned int)buffer[3] << 24) | ((unsigned int)buffer[2] << 16)
00253 | ((unsigned int)buffer[1] << 8) | ((unsigned int)buffer[0]);
00254 }
00255
00256 static unsigned int u16fread(FILE *fp)
00257 {
00258 unsigned char buffer[2];
00259 fread(buffer, 2, 1, fp);
00260 return ((unsigned int)buffer[1] << 8) | ((unsigned int)buffer[0]);
00261 }
00262
00263 static unsigned int u8fread(FILE *fp)
00264 {
00265 unsigned char buffer;
00266 fread(&buffer, 1, 1, fp);
00267 return (unsigned int)buffer;
00268 }
00269 #endif
00270