sourceTextureImage.cxx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /**
  2. * PANDA 3D SOFTWARE
  3. * Copyright (c) Carnegie Mellon University. All rights reserved.
  4. *
  5. * All use of this software is subject to the terms of the revised BSD
  6. * license. You should have received a copy of this license along
  7. * with this source code in a file named "LICENSE."
  8. *
  9. * @file sourceTextureImage.cxx
  10. * @author drose
  11. * @date 2000-11-29
  12. */
  13. #include "sourceTextureImage.h"
  14. #include "textureImage.h"
  15. #include "filenameUnifier.h"
  16. #include "pnmImageHeader.h"
  17. #include "datagram.h"
  18. #include "datagramIterator.h"
  19. #include "bamReader.h"
  20. #include "bamWriter.h"
  21. TypeHandle SourceTextureImage::_type_handle;
  22. /**
  23. * The default constructor is only for the convenience of the Bam reader.
  24. */
  25. SourceTextureImage::
  26. SourceTextureImage() {
  27. _texture = nullptr;
  28. _egg_count = 0;
  29. _read_header = false;
  30. _successfully_read_header = false;
  31. }
  32. /**
  33. *
  34. */
  35. SourceTextureImage::
  36. SourceTextureImage(TextureImage *texture, const Filename &filename,
  37. const Filename &alpha_filename, int alpha_file_channel) :
  38. _texture(texture)
  39. {
  40. _filename = filename;
  41. _alpha_filename = alpha_filename;
  42. _alpha_file_channel = alpha_file_channel;
  43. _egg_count = 0;
  44. _read_header = false;
  45. _successfully_read_header = false;
  46. }
  47. /**
  48. * Returns the particular texture that this image is one of the sources for.
  49. */
  50. TextureImage *SourceTextureImage::
  51. get_texture() const {
  52. return _texture;
  53. }
  54. /**
  55. * Increments by one the number of egg files that are known to reference this
  56. * SourceTextureImage.
  57. */
  58. void SourceTextureImage::
  59. increment_egg_count() {
  60. _egg_count++;
  61. }
  62. /**
  63. * Returns the number of egg files that share this SourceTextureImage.
  64. */
  65. int SourceTextureImage::
  66. get_egg_count() const {
  67. return _egg_count;
  68. }
  69. /**
  70. * Determines the size of the SourceTextureImage, if it is not already known.
  71. * Returns true if the size was successfully determined (or if was already
  72. * known), or false if the size could not be determined (for instance, because
  73. * the image file is missing). After this call returns true, get_x_size()
  74. * etc. may be safely called to return the size.
  75. */
  76. bool SourceTextureImage::
  77. get_size() {
  78. if (!_size_known) {
  79. return read_header();
  80. }
  81. return true;
  82. }
  83. /**
  84. * Reads the actual image header to determine the image properties, like its
  85. * size. Returns true if the image header is successfully read (or if has
  86. * previously been successfully read this session), false otherwise. After
  87. * this call returns true, get_x_size() etc. may be safely called to return
  88. * the newly determined size.
  89. */
  90. bool SourceTextureImage::
  91. read_header() {
  92. if (_read_header) {
  93. return _successfully_read_header;
  94. }
  95. _read_header = true;
  96. _successfully_read_header = false;
  97. PNMImageHeader header;
  98. if (!header.read_header(_filename)) {
  99. nout << "Warning: cannot read texture "
  100. << FilenameUnifier::make_user_filename(_filename) << "\n";
  101. return false;
  102. }
  103. set_header(header);
  104. return true;
  105. }
  106. /**
  107. * Sets the header information associated with this image, as if it were
  108. * loaded from the disk.
  109. */
  110. void SourceTextureImage::
  111. set_header(const PNMImageHeader &header) {
  112. _x_size = header.get_x_size();
  113. _y_size = header.get_y_size();
  114. int num_channels = header.get_num_channels();
  115. if (!_alpha_filename.empty() && _alpha_filename.exists()) {
  116. // Assume if we have an alpha filename, that we have an additional alpha
  117. // channel.
  118. if (num_channels == 1 || num_channels == 3) {
  119. num_channels++;
  120. }
  121. }
  122. _properties.set_num_channels(num_channels);
  123. _size_known = true;
  124. _successfully_read_header = true;
  125. }
  126. /**
  127. * Registers the current object as something that can be read from a Bam file.
  128. */
  129. void SourceTextureImage::
  130. register_with_read_factory() {
  131. BamReader::get_factory()->
  132. register_factory(get_class_type(), make_from_bam);
  133. }
  134. /**
  135. * Fills the indicated datagram up with a binary representation of the current
  136. * object, in preparation for writing to a Bam file.
  137. */
  138. void SourceTextureImage::
  139. write_datagram(BamWriter *writer, Datagram &datagram) {
  140. ImageFile::write_datagram(writer, datagram);
  141. writer->write_pointer(datagram, _texture);
  142. // We don't store _egg_count; instead, we count these up again each session.
  143. // We don't store _read_header or _successfully_read_header in the Bam file;
  144. // these are transitory and we need to reread the image header for each
  145. // session (in case the image files change between sessions).
  146. }
  147. /**
  148. * Called after the object is otherwise completely read from a Bam file, this
  149. * function's job is to store the pointers that were retrieved from the Bam
  150. * file for each pointer object written. The return value is the number of
  151. * pointers processed from the list.
  152. */
  153. int SourceTextureImage::
  154. complete_pointers(TypedWritable **p_list, BamReader *manager) {
  155. int pi = ImageFile::complete_pointers(p_list, manager);
  156. DCAST_INTO_R(_texture, p_list[pi++], pi);
  157. return pi;
  158. }
  159. /**
  160. * This method is called by the BamReader when an object of this type is
  161. * encountered in a Bam file; it should allocate and return a new object with
  162. * all the data read.
  163. */
  164. TypedWritable *SourceTextureImage::
  165. make_from_bam(const FactoryParams &params) {
  166. SourceTextureImage *me = new SourceTextureImage;
  167. DatagramIterator scan;
  168. BamReader *manager;
  169. parse_params(params, scan, manager);
  170. me->fillin(scan, manager);
  171. return me;
  172. }
  173. /**
  174. * Reads the binary data from the given datagram iterator, which was written
  175. * by a previous call to write_datagram().
  176. */
  177. void SourceTextureImage::
  178. fillin(DatagramIterator &scan, BamReader *manager) {
  179. ImageFile::fillin(scan, manager);
  180. manager->read_pointer(scan); // _texture
  181. }