00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <sofa/helper/io/ImageBMP.h>
00028 #include <sofa/helper/system/FileRepository.h>
00029 #include <cstdio>
00030 #include <iostream>
00031
00032 namespace sofa
00033 {
00034
00035 namespace helper
00036 {
00037
00038 namespace io
00039 {
00040
00041
00042
00043 SOFA_DECL_CLASS(ImageBMP)
00044
00045 Creator<Image::FactoryImage,ImageBMP> ImageBMPClass("bmp");
00046
00047 bool ImageBMP::load(std::string filename)
00048 {
00049 if (!sofa::helper::system::DataRepository.findFile(filename))
00050 {
00051 std::cerr << "File " << filename << " not found " << std::endl;
00052 return false;
00053 }
00054 unsigned short int bfType;
00055 long int bfOffBits;
00056 short int biPlanes;
00057 short int biBitCount;
00058 long int biSizeImage;
00059 FILE *file;
00060
00061 if ((file = fopen(filename.c_str(), "rb")) == NULL)
00062 {
00063 std::cerr << "File not found : " << filename << std::endl;
00064 return false;
00065 }
00066
00067 if(!fread(&bfType, sizeof(short int), 1, file))
00068 {
00069 std::cerr << "Error reading file!" << std::endl;
00070 return false;
00071 }
00072
00073
00074 if (bfType != 19778)
00075 {
00076 std::cerr << "Not a Bitmap-File!\n";
00077 return false;
00078 }
00079
00080
00081 fseek(file, 8, SEEK_CUR);
00082
00083 if (!fread(&bfOffBits, sizeof(long int), 1, file))
00084 {
00085 std::cerr << "Error reading file!\n";
00086 return false;
00087 }
00088
00089
00090 fseek(file, 4, SEEK_CUR);
00091
00092 fread(&width, sizeof(int), 1, file);
00093 if (width < 0) width = -width;
00094
00095
00096 fread(&height, sizeof(int), 1, file);
00097 bool upsidedown = false;
00098 if (height < 0) { height = -height; upsidedown = true; }
00099
00100
00101 fread(&biPlanes, sizeof(short int), 1, file);
00102 if (biPlanes != 1)
00103 {
00104 std::cerr << "Error: number of Planes not 1!\n";
00105 return false;
00106 }
00107
00108 if (!fread(&biBitCount, sizeof(short int), 1, file))
00109 {
00110 std::cerr << "Error reading file!\n";
00111 return false;
00112 }
00113
00114 if (biBitCount != 24 && biBitCount != 32 && biBitCount != 8)
00115 {
00116 std::cerr << "Bits per Pixel not supported\n";
00117 return false;
00118 }
00119 nbBits = biBitCount;
00120 int nc = ((nbBits+7)/8);
00121
00122 biSizeImage = width * height * nc;
00123
00124
00125 data = (unsigned char*) malloc(biSizeImage);
00126
00127 fseek(file, bfOffBits, SEEK_SET);
00128
00129 if (((width*nc)%4)==0 && !upsidedown)
00130 {
00131 if (!fread(data, biSizeImage, 1, file))
00132 {
00133 std::cerr << "Error loading file!\n";
00134 return false;
00135 }
00136 }
00137 else
00138 {
00139 int pad = (4-((width*nc)%4))%4;
00140 char buf[3];
00141 for (int y=0;y<height;y++)
00142 {
00143 if (!fread(data+(upsidedown?height-1-y:y)*width*nc, width*nc, 1, file))
00144 {
00145 std::cerr << "Error loading file!\n";
00146 return false;
00147 }
00148 if (pad && !fread(buf, 4-((width*nc)%4), 1, file))
00149 {
00150 std::cerr << "Error loading file!\n";
00151 return false;
00152 }
00153 }
00154 }
00155
00156 if (nc == 3 || nc == 4)
00157 {
00158 int i;
00159 unsigned char temp;
00160
00161 for (i = 0; i < width*height*nc; i += nc)
00162 {
00163 temp = data[i];
00164 data[i] = data[i + 2];
00165 data[i + 2] = temp;
00166 }
00167 }
00168
00169 fclose(file);
00170 return true;
00171 }
00172
00173 static bool fwriteW(FILE* file, unsigned short data)
00174 {
00175 return fwrite(&data,sizeof(data),1,file)!=0;
00176 }
00177
00178 static bool fwriteDW(FILE* file, unsigned long data)
00179 {
00180 return fwrite(&data,sizeof(data),1,file)!=0;
00181 }
00182
00183 bool ImageBMP::save(std::string filename, int)
00184 {
00185 FILE *file;
00186
00187 if ((file = fopen(filename.c_str(), "wb")) == NULL)
00188 {
00189 std::cerr << "File write access failed : " << filename << std::endl;
00190 return false;
00191 }
00192
00193 unsigned long lineSizeIn = ((nbBits+7)/8)*width;
00194 unsigned long lineSizeOut = ((lineSizeIn+3)/4)*4;
00195 unsigned long biSizeImage = lineSizeOut*height;
00196
00197
00198 if (!fwriteW(file, (unsigned short)'B' | ((unsigned short)'M' << 8))) return false;
00199 if (!fwriteDW(file, 14+40+biSizeImage)) return false;
00200 if (!fwriteW(file, 0)) return false;
00201 if (!fwriteW(file, 0)) return false;
00202 if (!fwriteDW(file, 14+40)) return false;
00203
00204
00205 if (!fwriteDW(file, 40)) return false;
00206 if (!fwriteDW(file, width)) return false;
00207 if (!fwriteDW(file, height)) return false;
00208 if (!fwriteW(file, 1)) return false;
00209 if (!fwriteW(file, nbBits)) return false;
00210 if (!fwriteDW(file, 0)) return false;
00211 if (!fwriteDW(file, biSizeImage)) return false;
00212 if (!fwriteDW(file, 2825)) return false;
00213 if (!fwriteDW(file, 2825)) return false;
00214 if (!fwriteDW(file, 0)) return false;
00215 if (!fwriteDW(file, 0)) return false;
00216
00217 if(nbBits==24)
00218 {
00219 unsigned char temp;
00220
00221 for (int i = 0; i < width*height*3; i += 3)
00222 {
00223 temp = data[i];
00224 data[i] = data[i + 2];
00225 data[i + 2] = temp;
00226 }
00227 }
00228 if (lineSizeIn == lineSizeOut)
00229 {
00230 if (!fwrite(data, biSizeImage, 1, file)) return false;
00231 }
00232 else
00233 {
00234 for (int y=0;y<height;y++)
00235 {
00236 if (!fwrite(data+y*lineSizeIn, lineSizeIn, 1, file)) return false;
00237 char buf[3]={0,0,0};
00238 if (!fwrite(buf, lineSizeOut-lineSizeIn, 1, file)) return false;
00239 }
00240 }
00241 if(nbBits==24)
00242 {
00243 int i;
00244 unsigned char temp;
00245
00246 for (i = 0; i < width*height*3; i += 3)
00247 {
00248 temp = data[i];
00249 data[i] = data[i + 2];
00250 data[i + 2] = temp;
00251 }
00252 }
00253
00254 fclose(file);
00255 return true;
00256 }
00257
00258 }
00259
00260 }
00261
00262 }
00263