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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <stdlib.h>
00042 #include <stdio.h>
00043
00044 #include "OSGConfig.h"
00045
00046 #include <iostream>
00047 #include <fstream>
00048
00049 #include <OSGLog.h>
00050
00051 #include "OSGPNMImageFileType.h"
00052
00053 #ifdef OSG_SGI_STL
00054
00055
00056 #ifndef INT_MAX
00057 #define INT_MAX numeric_limits<int>::max()
00058 #endif
00059 #else
00060 #include <limits.h>
00061 #endif
00062 OSG_USING_NAMESPACE
00063
00064
00077
00078
00079
00080
00081 static const Char8 *suffixArray[] =
00082 {
00083 "pnm", "pbm", "pgm", "ppm"
00084 };
00085
00086
00087 PNMImageFileType PNMImageFileType::_the("pnm",
00088 suffixArray, sizeof(suffixArray),
00089 OSG_READ_SUPPORTED |
00090 OSG_WRITE_SUPPORTED);
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00104 PNMImageFileType& PNMImageFileType::the (void)
00105 {
00106 return _the;
00107 }
00108
00109
00110
00111
00112
00113
00118 bool PNMImageFileType::read(ImagePtr &image, const Char8 *fileName)
00119 {
00120 bool isBinary = true;
00121 Int16 type = 0, width, height, lineSize, maxValue=0, value, x, y;
00122 UInt32 i, n;
00123 UChar8 *imageData = 0;
00124 UInt8 id, commentKey = '#';
00125 std::ifstream in(fileName, std::ios::in | std::ios::binary);
00126
00127 if(in.rdbuf()->is_open())
00128 {
00129 in >> id >> type;
00130 in.ignore(INT_MAX, '\n');
00131 while(in.peek() == commentKey)
00132 in.ignore(INT_MAX, '\n');
00133 in >> width >> height;
00134 isBinary = ((type > 3) && (type < 7)) ? true : false;
00135 }
00136 else
00137 {
00138 FWARNING(("Error opening PNM file %s!\n", fileName));
00139 return false;
00140 }
00141
00142 switch(type)
00143 {
00144 case 1:
00145 case 4:
00146 maxValue = 1;
00147 image->set(Image::OSG_L_PF, width, height);
00148 break;
00149 case 2:
00150 case 5:
00151 maxValue = 0;
00152 image->set(Image::OSG_L_PF, width, height);
00153 break;
00154 case 3:
00155 case 6:
00156 maxValue = 0;
00157 image->set(Image::OSG_RGB_PF, width, height);
00158 break;
00159 case 7:
00160 FWARNING (("Read PNM type %d: LA-ascii extention\n",type ));
00161 maxValue = 0;
00162 image->set(Image::OSG_LA_PF, width, height);
00163 break;
00164 case 8:
00165 FWARNING (("Read PNM type %d: RGBA-ascii extention\n",type ));
00166 maxValue = 0;
00167 image->set(Image::OSG_RGBA_PF, width, height);
00168 break;
00169 default:
00170 SWARNING <<
00171 "unknown image format type " <<
00172 type <<
00173 " in " <<
00174 fileName <<
00175 std::endl;
00176 break;
00177 }
00178
00179 if(!maxValue)
00180 {
00181 in >> maxValue;
00182 if(maxValue != 255)
00183 {
00184 SWARNING <<
00185 "unknown max value " <<
00186 maxValue <<
00187 " in " <<
00188 fileName <<
00189 ", can't read the image" <<
00190 std::endl;
00191 maxValue = 0;
00192 }
00193 }
00194
00195
00196 in.ignore(INT_MAX, '\n');
00197
00198 if(maxValue && (imageData = image->getData()))
00199 {
00200 SINFO <<
00201 "Read pnm file of type " <<
00202 type <<
00203 ", " <<
00204 width <<
00205 "x" <<
00206 height <<
00207 std::endl;
00208
00209 lineSize = width * image->getBpp();
00210 if(isBinary)
00211 {
00212 for(y = height - 1; y >= 0; y--)
00213 {
00214 in.read((Char8 *) &(imageData[y * lineSize]), lineSize);
00215 }
00216 }
00217 else
00218 {
00219 for(y = height - 1; y >= 0; y--)
00220 {
00221 for(x = 0; x < lineSize; x++)
00222 {
00223 in >> value;
00224 imageData[y * lineSize + x] = UChar8(value);
00225 }
00226 }
00227 }
00228
00229 if(maxValue == 1)
00230 {
00231 n = image->getSize();
00232 for(i = 0; i < n; i++)
00233 imageData[0] *= 255;
00234 }
00235 }
00236
00237 return true;
00238 }
00239
00240
00245 bool PNMImageFileType::write(const ImagePtr &image, const Char8 *fileName)
00246 {
00247 Int16 p, y, x, lineSize;
00248 std::ofstream out(fileName, std::ios::out | std::ios::binary);
00249 UInt16 bpp = image->getBpp();
00250 UInt8 *data = 0;
00251
00252 if(out.rdbuf()->is_open())
00253 {
00254 switch(bpp)
00255 {
00256 case 1:
00257 case 2:
00258 out << "P5" << std::endl;
00259 break;
00260 case 3:
00261 case 4:
00262 out << "P6" << std::endl;
00263 break;
00264 }
00265
00266 out << "# PNMImageFileType write" << std::endl;
00267 out << image->getWidth() << " " << image->getHeight() << std::endl;
00268 out << "255" << std::endl;
00269
00270 if(bpp & 1)
00271 {
00272
00273 lineSize = image->getBpp() * image->getWidth();
00274 for(y = image->getHeight() - 1; y >= 0; y--)
00275 {
00276 out.write((char *) (image->getData() + (lineSize * y)),
00277 lineSize);
00278 }
00279 }
00280 else
00281 {
00282
00283 lineSize = image->getBpp() * image->getWidth();
00284 for(y = image->getHeight() - 1; y >= 0; y--)
00285 {
00286 data = (UInt8 *) (image->getData() + (lineSize * y));
00287 for(x = 0; x < image->getWidth(); x++)
00288 {
00289 for(p = bpp - 1; p--;)
00290 out << *data++;
00291 data++;
00292 }
00293 }
00294 }
00295
00296 out.close();
00297 }
00298
00299 return data ? true : false;
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00320
00324 PNMImageFileType::PNMImageFileType(const Char8 *mimeType,
00325 const Char8 *suffixArray[],
00326 UInt16 suffixByteCount,
00327 UInt32 flags) :
00328 ImageFileType(mimeType,suffixArray, suffixByteCount, flags)
00329 {
00330 return;
00331 }
00332
00333
00337 PNMImageFileType::PNMImageFileType(const PNMImageFileType &obj) :
00338 ImageFileType(obj)
00339 {
00340 return;
00341 }
00342
00343
00347 PNMImageFileType::~PNMImageFileType(void)
00348 {
00349 return;
00350 }