00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pnmImageHeader.h"
00020 #include "pnmFileTypeRegistry.h"
00021 #include "pnmFileType.h"
00022 #include "pnmReader.h"
00023 #include "config_pnmimage.h"
00024 #include "config_express.h"
00025 #include "virtualFileSystem.h"
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 bool PNMImageHeader::
00037 read_header(const Filename &filename, PNMFileType *type) {
00038 PNMReader *reader = make_reader(filename, type);
00039 if (reader != (PNMReader *)NULL) {
00040 (*this) = (*reader);
00041 _type = reader->get_type();
00042 delete reader;
00043 return true;
00044 }
00045
00046 return false;
00047 }
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 PNMReader *PNMImageHeader::
00063 make_reader(const Filename &filename, PNMFileType *type) const {
00064 if (pnmimage_cat.is_debug()) {
00065 pnmimage_cat.debug()
00066 << "Reading image from " << filename << "\n";
00067 }
00068 bool owns_file = false;
00069 istream *file = (istream *)NULL;
00070
00071 if (filename == "-") {
00072 owns_file = false;
00073 file = &cin;
00074
00075 if (pnmimage_cat.is_debug()) {
00076 pnmimage_cat.debug()
00077 << "(reading standard input)\n";
00078 }
00079
00080 } else {
00081 if (use_vfs) {
00082 VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
00083 owns_file = true;
00084 file = vfs->open_read_file(filename);
00085
00086 } else {
00087 ifstream *new_istream = new ifstream;
00088 Filename actual_name = Filename::binary_filename(filename);
00089 if (!actual_name.open_read(*new_istream)) {
00090 delete new_istream;
00091
00092 } else {
00093 owns_file = true;
00094 file = new_istream;
00095 }
00096 }
00097 }
00098
00099 if (file == (istream *)NULL) {
00100 if (pnmimage_cat.is_debug()) {
00101 pnmimage_cat.debug()
00102 << "Unable to open file.\n";
00103 }
00104 return NULL;
00105 }
00106
00107 return make_reader(file, owns_file, filename, string(), type);
00108 }
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 PNMReader *PNMImageHeader::
00141 make_reader(istream *file, bool owns_file, const Filename &filename,
00142 string magic_number, PNMFileType *type) const {
00143 if (type == (PNMFileType *)NULL) {
00144 if (!read_magic_number(file, magic_number, 2)) {
00145
00146 if (pnmimage_cat.is_debug()) {
00147 pnmimage_cat.debug()
00148 << "Image file appears to be empty.\n";
00149 }
00150 if (owns_file) {
00151 delete file;
00152 }
00153 return NULL;
00154 }
00155
00156 type = PNMFileTypeRegistry::get_ptr()->
00157 get_type_from_magic_number(magic_number);
00158
00159 if (pnmimage_cat.is_debug()) {
00160 if (type != (PNMFileType *)NULL) {
00161 pnmimage_cat.debug()
00162 << "By magic number, image file appears to be type "
00163 << type->get_name() << ".\n";
00164 } else {
00165 pnmimage_cat.debug()
00166 << "Unable to determine image file type from magic number.\n";
00167 }
00168 }
00169 }
00170
00171 if (type == (PNMFileType *)NULL && !filename.empty()) {
00172
00173
00174 type = PNMFileTypeRegistry::get_ptr()->get_type_from_extension(filename);
00175
00176 if (pnmimage_cat.is_debug()) {
00177 if (type != (PNMFileType *)NULL) {
00178 pnmimage_cat.debug()
00179 << "From its extension, image file is probably type "
00180 << type->get_name() << ".\n";
00181 } else {
00182 pnmimage_cat.debug()
00183 << "Unable to guess image file type from its extension.\n";
00184 }
00185 }
00186 }
00187
00188 if (type == (PNMFileType *)NULL) {
00189
00190 type = _type;
00191
00192 if (pnmimage_cat.is_debug() && type != (PNMFileType *)NULL) {
00193 pnmimage_cat.debug()
00194 << "Assuming image file type is " << type->get_name() << ".\n";
00195 }
00196 }
00197
00198 if (type == (PNMFileType *)NULL) {
00199
00200 if (pnmimage_cat.is_error()) {
00201 pnmimage_cat.error()
00202 << "Cannot determine type of image file " << filename << ".\n"
00203 << "Currently supported image types:\n";
00204 PNMFileTypeRegistry::get_ptr()->
00205 write_types(pnmimage_cat.error(false), 2);
00206 }
00207 if (owns_file) {
00208 delete file;
00209 }
00210 return NULL;
00211 }
00212
00213 PNMReader *reader = type->make_reader(file, owns_file, magic_number);
00214 if (reader == NULL && owns_file) {
00215 delete file;
00216 }
00217
00218 if (!reader->is_valid()) {
00219 delete reader;
00220 reader = NULL;
00221 }
00222
00223 return reader;
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 PNMWriter *PNMImageHeader::
00240 make_writer(const Filename &filename, PNMFileType *type) const {
00241 if (pnmimage_cat.is_debug()) {
00242 pnmimage_cat.debug()
00243 << "Writing image to " << filename << "\n";
00244 }
00245 bool owns_file = false;
00246 ostream *file = (ostream *)NULL;
00247
00248 if (filename == "-") {
00249 owns_file = false;
00250 file = &cout;
00251
00252 if (pnmimage_cat.is_debug()) {
00253 pnmimage_cat.debug()
00254 << "(writing to standard output)\n";
00255 }
00256
00257 } else {
00258 ofstream *new_ostream = new ofstream;
00259 Filename actual_name = Filename::binary_filename(filename);
00260 if (!actual_name.open_write(*new_ostream)) {
00261 delete new_ostream;
00262
00263 } else {
00264 owns_file = true;
00265 file = new_ostream;
00266 }
00267 }
00268
00269 if (file == (ostream *)NULL) {
00270 if (pnmimage_cat.is_debug()) {
00271 pnmimage_cat.debug()
00272 << "Unable to write to file.\n";
00273 }
00274 return NULL;
00275 }
00276
00277 return make_writer(file, owns_file, filename, type);
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 PNMWriter *PNMImageHeader::
00305 make_writer(ostream *file, bool owns_file, const Filename &filename,
00306 PNMFileType *type) const {
00307 if (type == (PNMFileType *)NULL && !filename.empty()) {
00308
00309
00310 type = PNMFileTypeRegistry::get_ptr()->get_type_from_extension(filename);
00311
00312 if (pnmimage_cat.is_debug()) {
00313 if (type != (PNMFileType *)NULL) {
00314 pnmimage_cat.debug()
00315 << "From its extension, image file is intended to be type "
00316 << type->get_name() << ".\n";
00317 } else {
00318 pnmimage_cat.debug()
00319 << "Unable to guess image file type from its extension.\n";
00320 }
00321 }
00322 }
00323
00324 if (type == (PNMFileType *)NULL) {
00325
00326 type = _type;
00327
00328 if (pnmimage_cat.is_debug() && type != (PNMFileType *)NULL) {
00329 pnmimage_cat.debug()
00330 << "Assuming image file type is " << type->get_name() << ".\n";
00331 }
00332 }
00333
00334 if (type == (PNMFileType *)NULL) {
00335
00336 if (pnmimage_cat.is_debug()) {
00337 pnmimage_cat.debug()
00338 << "Cannot determine type of image file " << filename << ".\n";
00339 }
00340 if (owns_file) {
00341 delete file;
00342 }
00343 return NULL;
00344 }
00345
00346 PNMWriter *writer = type->make_writer(file, owns_file);
00347 if (writer == NULL && owns_file) {
00348 delete file;
00349 }
00350
00351 return writer;
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 bool PNMImageHeader::
00365 read_magic_number(istream *file, string &magic_number, int num_bytes) {
00366 while ((int)magic_number.size() < num_bytes) {
00367 int ch = file->get();
00368 if (file->eof() || file->fail()) {
00369 return false;
00370 }
00371 magic_number += (char)ch;
00372 }
00373
00374 return true;
00375 }
00376
00377
00378
00379
00380
00381
00382 void PNMImageHeader::
00383 output(ostream &out) const {
00384 out << "image: " << _x_size << " by " << _y_size << " pixels, "
00385 << _num_channels << " channels, " << _maxval << " maxval.";
00386 }