00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "imageFile.h"
00020 #include "palettizer.h"
00021 #include "filenameUnifier.h"
00022 #include "paletteGroup.h"
00023
00024 #include "pnmImage.h"
00025 #include "pnmFileType.h"
00026 #include "eggTexture.h"
00027 #include "datagram.h"
00028 #include "datagramIterator.h"
00029 #include "bamReader.h"
00030 #include "bamWriter.h"
00031
00032 TypeHandle ImageFile::_type_handle;
00033
00034
00035
00036
00037
00038
00039 ImageFile::
00040 ImageFile() {
00041 _alpha_file_channel = 0;
00042 _size_known = false;
00043 _x_size = 0;
00044 _y_size = 0;
00045 }
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 void ImageFile::
00057 make_shadow_image(const string &basename) {
00058 _properties._color_type = pal->_shadow_color_type;
00059 _properties._alpha_type = pal->_shadow_alpha_type;
00060
00061 set_filename(pal->_shadow_dirname, basename);
00062 }
00063
00064
00065
00066
00067
00068
00069
00070 bool ImageFile::
00071 is_size_known() const {
00072 return _size_known;
00073 }
00074
00075
00076
00077
00078
00079
00080
00081
00082 int ImageFile::
00083 get_x_size() const {
00084 nassertr(is_size_known(), 0);
00085 return _x_size;
00086 }
00087
00088
00089
00090
00091
00092
00093
00094
00095 int ImageFile::
00096 get_y_size() const {
00097 nassertr(is_size_known(), 0);
00098 return _y_size;
00099 }
00100
00101
00102
00103
00104
00105
00106
00107 bool ImageFile::
00108 has_num_channels() const {
00109 return _properties.has_num_channels();
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119 int ImageFile::
00120 get_num_channels() const {
00121 return _properties.get_num_channels();
00122 }
00123
00124
00125
00126
00127
00128
00129 const TextureProperties &ImageFile::
00130 get_properties() const {
00131 return _properties;
00132 }
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 void ImageFile::
00143 clear_basic_properties() {
00144 _properties.clear_basic();
00145 }
00146
00147
00148
00149
00150
00151
00152
00153 void ImageFile::
00154 update_properties(const TextureProperties &properties) {
00155 _properties.update_properties(properties);
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 void ImageFile::
00168 set_filename(PaletteGroup *group, const string &basename) {
00169
00170
00171 string dirname;
00172 string::iterator pi;
00173 pi = pal->_map_dirname.begin();
00174 while (pi != pal->_map_dirname.end()) {
00175 if (*pi == '%') {
00176 ++pi;
00177 switch (*pi) {
00178 case '%':
00179 dirname += '%';
00180 break;
00181
00182 case 'g':
00183 if (group != (PaletteGroup *)NULL) {
00184 dirname += group->get_dirname();
00185 }
00186 break;
00187 }
00188 } else {
00189 dirname += *pi;
00190 }
00191 ++pi;
00192 }
00193
00194 set_filename(dirname, basename);
00195 }
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 void ImageFile::
00207 set_filename(const string &dirname, const string &basename) {
00208 _filename = Filename(dirname, basename);
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 if (_properties._color_type != (PNMFileType *)NULL) {
00221 _filename.set_extension
00222 (_properties._color_type->get_suggested_extension());
00223 }
00224
00225 if (_properties._alpha_type != (PNMFileType *)NULL) {
00226 _alpha_filename = _filename.get_fullpath_wo_extension() + "_a.";
00227 _alpha_filename.set_extension
00228 (_properties._alpha_type->get_suggested_extension());
00229 }
00230 }
00231
00232
00233
00234
00235
00236
00237 const Filename &ImageFile::
00238 get_filename() const {
00239 return _filename;
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 const Filename &ImageFile::
00251 get_alpha_filename() const {
00252 return _alpha_filename;
00253 }
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 int ImageFile::
00266 get_alpha_file_channel() const {
00267 return _alpha_file_channel;
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277 bool ImageFile::
00278 exists() const {
00279 if (!_filename.exists()) {
00280 return false;
00281 }
00282 if (_properties._alpha_type != (PNMFileType *)NULL &&
00283 _properties.uses_alpha() &&
00284 !_alpha_filename.empty()) {
00285 if (!_alpha_filename.exists()) {
00286 return false;
00287 }
00288 }
00289
00290 return true;
00291 }
00292
00293
00294
00295
00296
00297
00298
00299
00300 bool ImageFile::
00301 read(PNMImage &image) const {
00302 nassertr(!_filename.empty(), false);
00303
00304 image.set_type(_properties._color_type);
00305 nout << "Reading " << FilenameUnifier::make_user_filename(_filename) << "\n";
00306 if (!image.read(_filename)) {
00307 nout << "Unable to read.\n";
00308 return false;
00309 }
00310
00311 if (!_alpha_filename.empty() && _alpha_filename.exists()) {
00312
00313 PNMImage alpha_image;
00314 alpha_image.set_type(_properties._alpha_type);
00315 nout << "Reading " << FilenameUnifier::make_user_filename(_alpha_filename) << "\n";
00316 if (!alpha_image.read(_alpha_filename)) {
00317 nout << "Unable to read.\n";
00318 return false;
00319 }
00320 if (image.get_x_size() != alpha_image.get_x_size() ||
00321 image.get_y_size() != alpha_image.get_y_size()) {
00322 return false;
00323 }
00324
00325 image.add_alpha();
00326
00327 if (_alpha_file_channel == 4 ||
00328 (_alpha_file_channel == 2 && alpha_image.get_num_channels() == 2)) {
00329
00330 for (int x = 0; x < image.get_x_size(); x++) {
00331 for (int y = 0; y < image.get_y_size(); y++) {
00332 image.set_alpha(x, y, alpha_image.get_alpha(x, y));
00333 }
00334 }
00335
00336 } else if (_alpha_file_channel >= 1 && _alpha_file_channel <= 3 &&
00337 alpha_image.get_num_channels() >= 3) {
00338
00339 for (int x = 0; x < image.get_x_size(); x++) {
00340 for (int y = 0; y < image.get_y_size(); y++) {
00341 image.set_alpha(x, y, alpha_image.get_channel_val(x, y, _alpha_file_channel - 1));
00342 }
00343 }
00344
00345 } else {
00346
00347 for (int x = 0; x < image.get_x_size(); x++) {
00348 for (int y = 0; y < image.get_y_size(); y++) {
00349 image.set_alpha(x, y, alpha_image.get_gray(x, y));
00350 }
00351 }
00352 }
00353 }
00354
00355 return true;
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365 bool ImageFile::
00366 write(const PNMImage &image) const {
00367 nassertr(!_filename.empty(), false);
00368
00369 if (!image.has_alpha() ||
00370 _properties._alpha_type == (PNMFileType *)NULL) {
00371 if (!_alpha_filename.empty() && _alpha_filename.exists()) {
00372 nout << "Deleting " << FilenameUnifier::make_user_filename(_alpha_filename) << "\n";
00373 _alpha_filename.unlink();
00374 }
00375 nout << "Writing " << FilenameUnifier::make_user_filename(_filename) << "\n";
00376 _filename.make_dir();
00377 if (!image.write(_filename, _properties._color_type)) {
00378 nout << "Unable to write.\n";
00379 return false;
00380 }
00381 return true;
00382 }
00383
00384
00385 PNMImage alpha_image(image.get_x_size(), image.get_y_size(), 1,
00386 image.get_maxval());
00387 for (int y = 0; y < image.get_y_size(); y++) {
00388 for (int x = 0; x < image.get_x_size(); x++) {
00389 alpha_image.set_gray_val(x, y, image.get_alpha_val(x, y));
00390 }
00391 }
00392
00393 PNMImage image_copy(image);
00394 image_copy.remove_alpha();
00395 nout << "Writing " << FilenameUnifier::make_user_filename(_filename) << "\n";
00396 _filename.make_dir();
00397 if (!image_copy.write(_filename, _properties._color_type)) {
00398 nout << "Unable to write.\n";
00399 return false;
00400 }
00401
00402 nout << "Writing " << FilenameUnifier::make_user_filename(_alpha_filename) << "\n";
00403 _alpha_filename.make_dir();
00404 if (!alpha_image.write(_alpha_filename, _properties._alpha_type)) {
00405 nout << "Unable to write.\n";
00406 return false;
00407 }
00408 return true;
00409 }
00410
00411
00412
00413
00414
00415
00416 void ImageFile::
00417 unlink() {
00418 if (!_filename.empty() && _filename.exists()) {
00419 nout << "Deleting " << FilenameUnifier::make_user_filename(_filename) << "\n";
00420 _filename.unlink();
00421 }
00422 if (!_alpha_filename.empty() && _alpha_filename.exists()) {
00423 nout << "Deleting " << FilenameUnifier::make_user_filename(_alpha_filename) << "\n";
00424 _alpha_filename.unlink();
00425 }
00426 }
00427
00428
00429
00430
00431
00432
00433 void ImageFile::
00434 update_egg_tex(EggTexture *egg_tex) const {
00435 nassertv(egg_tex != (EggTexture *)NULL);
00436
00437 egg_tex->set_filename(FilenameUnifier::make_egg_filename(_filename));
00438
00439 if (_properties.uses_alpha() &&
00440 !_alpha_filename.empty()) {
00441 egg_tex->set_alpha_filename(FilenameUnifier::make_egg_filename(_alpha_filename));
00442 egg_tex->set_alpha_file_channel(_alpha_file_channel);
00443 } else {
00444 egg_tex->clear_alpha_filename();
00445 egg_tex->clear_alpha_file_channel();
00446 }
00447
00448 _properties.update_egg_tex(egg_tex);
00449 }
00450
00451
00452
00453
00454
00455
00456
00457 void ImageFile::
00458 output_filename(ostream &out) const {
00459 out << FilenameUnifier::make_user_filename(_filename);
00460 if (_properties.uses_alpha() && !_alpha_filename.empty()) {
00461 out << " " << FilenameUnifier::make_user_filename(_alpha_filename);
00462 }
00463 }
00464
00465
00466
00467
00468
00469
00470
00471
00472 void ImageFile::
00473 write_datagram(BamWriter *writer, Datagram &datagram) {
00474 TypedWritable::write_datagram(writer, datagram);
00475 _properties.write_datagram(writer, datagram);
00476 datagram.add_string(FilenameUnifier::make_bam_filename(_filename));
00477 datagram.add_string(FilenameUnifier::make_bam_filename(_alpha_filename));
00478 datagram.add_uint8(_alpha_file_channel);
00479 datagram.add_bool(_size_known);
00480 datagram.add_int32(_x_size);
00481 datagram.add_int32(_y_size);
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493 int ImageFile::
00494 complete_pointers(TypedWritable **p_list, BamReader *manager) {
00495 int pi = TypedWritable::complete_pointers(p_list, manager);
00496
00497 pi += _properties.complete_pointers(p_list + pi, manager);
00498
00499 return pi;
00500 }
00501
00502
00503
00504
00505
00506
00507
00508
00509 void ImageFile::
00510 fillin(DatagramIterator &scan, BamReader *manager) {
00511 TypedWritable::fillin(scan, manager);
00512 _properties.fillin(scan, manager);
00513 _filename = FilenameUnifier::get_bam_filename(scan.get_string());
00514 _alpha_filename = FilenameUnifier::get_bam_filename(scan.get_string());
00515 if (Palettizer::_read_pi_version >= 10) {
00516 _alpha_file_channel = scan.get_uint8();
00517 } else {
00518 _alpha_file_channel = 0;
00519 }
00520 _size_known = scan.get_bool();
00521 _x_size = scan.get_int32();
00522 _y_size = scan.get_int32();
00523 }