Panda3D
pnmImage.h
Go to the documentation of this file.
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 pnmImage.h
10  * @author drose
11  * @date 2000-06-14
12  */
13 
14 #ifndef PNMIMAGE_H
15 #define PNMIMAGE_H
16 
17 #include "pandabase.h"
18 
19 #include "pnmImageHeader.h"
20 #include "pnmBrush.h"
21 #include "stackedPerlinNoise2.h"
22 #include "convert_srgb.h"
23 #include "luse.h"
24 
25 class PNMReader;
26 class PNMWriter;
27 class PNMFileType;
28 
29 /**
30  * The name of this class derives from the fact that we originally implemented
31  * it as a layer on top of the "pnm library", based on netpbm, which was built
32  * to implement pbm, pgm, and pbm files, and is the underlying support of a
33  * number of public-domain image file converters. Nowadays we are no longer
34  * derived directly from the pnm library, mainly to allow support of C++
35  * iostreams instead of the C stdio FILE interface.
36  *
37  * Conceptually, a PNMImage is a two-dimensional array of xels, which are the
38  * PNM-defined generic pixel type. Each xel may have a red, green, and blue
39  * component, or (if the image is grayscale) a gray component. The image may
40  * be read in, the individual xels manipulated, and written out again, or a
41  * black image may be constructed from scratch.
42  *
43  * A PNMImage has a color space and a maxval, the combination of which defines
44  * how a floating-point linear color value is encoded as an integer value in
45  * memory. The functions ending in _val operate on encoded colors, whereas
46  * the regular ones work with linear floating-point values. All operations
47  * are color space correct unless otherwise specified.
48  *
49  * The image is of size XSize() by YSize() xels, numbered from top to bottom,
50  * left to right, beginning at zero.
51  *
52  * Files can be specified by filename, or by an iostream pointer. The
53  * filename "-" refers to stdin or stdout.
54  *
55  * This class is not inherently thread-safe; use it from a single thread or
56  * protect access using a mutex.
57  */
58 class EXPCL_PANDA_PNMIMAGE PNMImage : public PNMImageHeader {
59 PUBLISHED:
60  INLINE PNMImage();
61  explicit PNMImage(const Filename &filename, PNMFileType *type = nullptr);
62  INLINE explicit PNMImage(int x_size, int y_size, int num_channels = 3,
63  xelval maxval = 255, PNMFileType *type = nullptr,
64  ColorSpace color_space = CS_linear);
65  INLINE PNMImage(const PNMImage &copy);
66  INLINE void operator = (const PNMImage &copy);
67 
68  INLINE ~PNMImage();
69 
70  INLINE xelval clamp_val(int input_value) const;
71  INLINE xel to_val(const LRGBColorf &input_value) const;
72  INLINE xelval to_val(float input_value) const;
73  INLINE xelval to_alpha_val(float input_value) const;
74  INLINE LRGBColorf from_val(const xel &input_value) const;
75  INLINE float from_val(xelval input_value) const;
76  INLINE float from_alpha_val(xelval input_value) const;
77 
78  void clear();
79  void clear(int x_size, int y_size, int num_channels = 3,
80  xelval maxval = 255, PNMFileType *type = nullptr,
81  ColorSpace color_space = CS_linear);
82 
83  void copy_from(const PNMImage &copy);
84  void copy_channel(const PNMImage &copy, int src_channel, int dest_channel);
85  void copy_channel_bits(const PNMImage &copy, int src_channel, int dest_channel, xelval src_mask, int right_shift);
86  void copy_header_from(const PNMImageHeader &header);
87  void take_from(PNMImage &orig);
88 
89  INLINE void fill(float red, float green, float blue);
90  INLINE void fill(float gray = 0.0);
91 
92  void fill_val(xelval red, xelval green, xelval blue);
93  INLINE void fill_val(xelval gray = 0);
94 
95  INLINE void alpha_fill(float alpha = 0.0);
96  void alpha_fill_val(xelval alpha = 0);
97 
98  INLINE void set_read_size(int x_size, int y_size);
99  INLINE void clear_read_size();
100  INLINE bool has_read_size() const;
101  INLINE int get_read_x_size() const;
102  INLINE int get_read_y_size() const;
103  INLINE ColorSpace get_color_space() const;
104 
105  BLOCKING bool read(const Filename &filename, PNMFileType *type = nullptr,
106  bool report_unknown_type = true);
107  BLOCKING bool read(std::istream &data, const std::string &filename = std::string(),
108  PNMFileType *type = nullptr,
109  bool report_unknown_type = true);
110  BLOCKING bool read(PNMReader *reader);
111 
112  BLOCKING bool write(const Filename &filename, PNMFileType *type = nullptr) const;
113  BLOCKING bool write(std::ostream &data, const std::string &filename = std::string(),
114  PNMFileType *type = nullptr) const;
115  BLOCKING bool write(PNMWriter *writer) const;
116 
117  INLINE bool is_valid() const;
118 
119  INLINE void set_num_channels(int num_channels);
120  void set_color_type(ColorType color_type);
121  void set_color_space(ColorSpace color_space);
122 
123  INLINE void add_alpha();
124  INLINE void remove_alpha();
125  INLINE void make_grayscale();
126  void make_grayscale(float rc, float gc, float bc);
127  INLINE void make_rgb();
128 
129  BLOCKING void premultiply_alpha();
130  BLOCKING void unpremultiply_alpha();
131 
132  BLOCKING void reverse_rows();
133  BLOCKING void flip(bool flip_x, bool flip_y, bool transpose);
134 
135  BLOCKING void set_maxval(xelval maxval);
136 
137  // The *_val() functions return or set the color values in the range
138  // [0..get_maxval()]. This range may be different for different images!
139  // Use the corresponding functions (without _val()) to work in the
140  // normalized range [0..1]. These return values in the image's stored color
141  // space.
142 
143  INLINE xel &get_xel_val(int x, int y);
144  INLINE xel get_xel_val(int x, int y) const;
145  INLINE void set_xel_val(int x, int y, const xel &value);
146  INLINE void set_xel_val(int x, int y, xelval r, xelval g, xelval b);
147  INLINE void set_xel_val(int x, int y, xelval gray);
148 
149  INLINE xelval get_red_val(int x, int y) const;
150  INLINE xelval get_green_val(int x, int y) const;
151  INLINE xelval get_blue_val(int x, int y) const;
152  INLINE xelval get_gray_val(int x, int y) const;
153  INLINE xelval get_alpha_val(int x, int y) const;
154 
155  INLINE void set_red_val(int x, int y, xelval r);
156  INLINE void set_green_val(int x, int y, xelval g);
157  INLINE void set_blue_val(int x, int y, xelval b);
158  INLINE void set_gray_val(int x, int y, xelval gray);
159  INLINE void set_alpha_val(int x, int y, xelval a);
160 
161  xelval get_channel_val(int x, int y, int channel) const;
162  void set_channel_val(int x, int y, int channel, xelval value);
163  float get_channel(int x, int y, int channel) const;
164  void set_channel(int x, int y, int channel, float value);
165 
166  PixelSpec get_pixel(int x, int y) const;
167  void set_pixel(int x, int y, const PixelSpec &pixel);
168 
169  // The corresponding get_xel(), set_xel(), get_red(), etc. functions
170  // automatically scale their values by get_maxval() into the range [0..1],
171  // and into the linear color space.
172 
173  INLINE LRGBColorf get_xel(int x, int y) const;
174  INLINE void set_xel(int x, int y, const LRGBColorf &value);
175  INLINE void set_xel(int x, int y, float r, float g, float b);
176  INLINE void set_xel(int x, int y, float gray);
177 
178  INLINE LColorf get_xel_a(int x, int y) const;
179  INLINE void set_xel_a(int x, int y, const LColorf &value);
180  INLINE void set_xel_a(int x, int y, float r, float g, float b, float a);
181 
182  INLINE float get_red(int x, int y) const;
183  INLINE float get_green(int x, int y) const;
184  INLINE float get_blue(int x, int y) const;
185  INLINE float get_gray(int x, int y) const;
186  INLINE float get_alpha(int x, int y) const;
187 
188  INLINE void set_red(int x, int y, float r);
189  INLINE void set_green(int x, int y, float g);
190  INLINE void set_blue(int x, int y, float b);
191  INLINE void set_gray(int x, int y, float gray);
192  INLINE void set_alpha(int x, int y, float a);
193 
194  INLINE float get_bright(int x, int y) const;
195  INLINE float get_bright(int x, int y, float rc, float gc,
196  float bc) const;
197  INLINE float get_bright(int x, int y, float rc, float gc,
198  float bc, float ac) const;
199 
200  INLINE void blend(int x, int y, const LRGBColorf &val, float alpha);
201  void blend(int x, int y, float r, float g, float b, float alpha);
202 
203  void copy_sub_image(const PNMImage &copy, int xto, int yto,
204  int xfrom = 0, int yfrom = 0,
205  int x_size = -1, int y_size = -1);
206  void blend_sub_image(const PNMImage &copy, int xto, int yto,
207  int xfrom = 0, int yfrom = 0,
208  int x_size = -1, int y_size = -1,
209  float pixel_scale = 1.0);
210  void add_sub_image(const PNMImage &copy, int xto, int yto,
211  int xfrom = 0, int yfrom = 0,
212  int x_size = -1, int y_size = -1,
213  float pixel_scale = 1.0);
214  void mult_sub_image(const PNMImage &copy, int xto, int yto,
215  int xfrom = 0, int yfrom = 0,
216  int x_size = -1, int y_size = -1,
217  float pixel_scale = 1.0);
218  void darken_sub_image(const PNMImage &copy, int xto, int yto,
219  int xfrom = 0, int yfrom = 0,
220  int x_size = -1, int y_size = -1,
221  float pixel_scale = 1.0);
222  void lighten_sub_image(const PNMImage &copy, int xto, int yto,
223  int xfrom = 0, int yfrom = 0,
224  int x_size = -1, int y_size = -1,
225  float pixel_scale = 1.0);
226  void threshold(const PNMImage &select_image, int channel, float threshold,
227  const PNMImage &lt, const PNMImage &ge);
228  BLOCKING void fill_distance_inside(const PNMImage &mask, float threshold, int radius, bool shrink_from_border);
229  BLOCKING void fill_distance_outside(const PNMImage &mask, float threshold, int radius);
230 
231  void indirect_1d_lookup(const PNMImage &index_image, int channel,
232  const PNMImage &pixel_values);
233 
234  void rescale(float min_val, float max_val);
235 
236  void copy_channel(const PNMImage &copy, int xto, int yto, int cto,
237  int xfrom = 0, int yfrom = 0, int cfrom = 0,
238  int x_size = -1, int y_size = -1);
239 
240  void render_spot(const LColorf &fg, const LColorf &bg,
241  float min_radius, float max_radius);
242 
243  void expand_border(int left, int right, int bottom, int top,
244  const LColorf &color);
245 
246  // The bodies for the non-inline *_filter() functions can be found in the
247  // file pnm-image-filter.cxx.
248 
249  BLOCKING INLINE void box_filter(float radius = 1.0);
250  BLOCKING INLINE void gaussian_filter(float radius = 1.0);
251 
252  BLOCKING void unfiltered_stretch_from(const PNMImage &copy);
253  BLOCKING void box_filter_from(float radius, const PNMImage &copy);
254  BLOCKING void gaussian_filter_from(float radius, const PNMImage &copy);
255  BLOCKING void quick_filter_from(const PNMImage &copy,
256  int xborder = 0, int yborder = 0);
257 
258  void make_histogram(Histogram &hist);
259  void quantize(size_t max_colors);
260  BLOCKING void perlin_noise_fill(float sx, float sy, int table_size = 256,
261  unsigned long seed = 0);
262  void perlin_noise_fill(StackedPerlinNoise2 &perlin);
263 
264  void remix_channels(const LMatrix4 &conv);
265  BLOCKING INLINE void gamma_correct(float from_gamma, float to_gamma);
266  BLOCKING INLINE void gamma_correct_alpha(float from_gamma, float to_gamma);
267  BLOCKING INLINE void apply_exponent(float gray_exponent);
268  BLOCKING INLINE void apply_exponent(float gray_exponent, float alpha_exponent);
269  BLOCKING INLINE void apply_exponent(float red_exponent, float green_exponent, float blue_exponent);
270  BLOCKING void apply_exponent(float red_exponent, float green_exponent, float blue_exponent, float alpha_exponent);
271 
272  LRGBColorf get_average_xel() const;
273  LColorf get_average_xel_a() const;
274  float get_average_gray() const;
275 
276  void do_fill_distance(int xi, int yi, int d);
277 
278 PUBLISHED:
279  // Provides an accessor for reading or writing the contents of one row of
280  // the image in-place.
281  class EXPCL_PANDA_PNMIMAGE Row {
282  PUBLISHED:
283  INLINE size_t size() const;
284  INLINE LColorf operator[](int x) const;
285 #ifdef HAVE_PYTHON
286  INLINE void __setitem__(int x, const LColorf &v);
287 #endif
288  INLINE xel &get_xel_val(int x);
289  INLINE void set_xel_val(int x, const xel &v);
290  INLINE xelval get_alpha_val(int x) const;
291  INLINE void set_alpha_val(int x, xelval v);
292 
293  public:
294  INLINE Row(PNMImage &image, int y);
295 
296  private:
297  PNMImage &_image;
298  int _y;
299  };
300 
301  // Provides an accessor for reading the contents of one row of the image in-
302  // place.
303  class EXPCL_PANDA_PNMIMAGE CRow {
304  PUBLISHED:
305  INLINE size_t size() const;
306  INLINE LColorf operator[](int x) const;
307  INLINE xel get_xel_val(int x) const;
308  INLINE xelval get_alpha_val(int x) const;
309 
310  public:
311  INLINE CRow(const PNMImage &image, int y);
312 
313  private:
314  const PNMImage &_image;
315  int _y;
316  };
317 
318  INLINE Row operator [] (int y);
319  INLINE CRow operator [] (int y) const;
320 
321 public:
322  // Know what you are doing if you access the underlying data arrays
323  // directly.
324  INLINE xel *get_array();
325  INLINE const xel *get_array() const;
326  INLINE xelval *get_alpha_array();
327  INLINE const xelval *get_alpha_array() const;
328 
329  INLINE xel *take_array();
330  INLINE xelval *take_alpha_array();
331  void set_array(xel *array);
332  void set_alpha_array(xelval *alpha);
333 
334 private:
335  INLINE void allocate_array();
336  INLINE void allocate_alpha();
337 
338  INLINE xel *row(int row) const;
339  INLINE xelval *alpha_row(int row) const;
340 
341  INLINE void setup_sub_image(const PNMImage &copy, int &xto, int &yto,
342  int &xfrom, int &yfrom, int &x_size, int &y_size,
343  int &xmin, int &ymin, int &xmax, int &ymax);
344 
345  INLINE static void compute_spot_pixel(LColorf &c, float d2,
346  float min_radius, float max_radius,
347  const LColorf &fg, const LColorf &bg);
348 
349  void setup_rc();
350  void setup_encoding();
351 
352  void r_quantize(pmap<xel, xel> &color_map, size_t max_colors,
353  xel *colors, size_t num_colors);
354 
355 PUBLISHED:
356  PNMImage operator ~() const;
357 
358  INLINE PNMImage operator + (const PNMImage &other) const;
359  INLINE PNMImage operator + (const LColorf &other) const;
360  INLINE PNMImage operator - (const PNMImage &other) const;
361  INLINE PNMImage operator - (const LColorf &other) const;
362  INLINE PNMImage operator * (const PNMImage &other) const;
363  INLINE PNMImage operator * (float multiplier) const;
364  INLINE PNMImage operator * (const LColorf &other) const;
365  void operator += (const PNMImage &other);
366  void operator += (const LColorf &other);
367  void operator -= (const PNMImage &other);
368  void operator -= (const LColorf &other);
369  void operator *= (const PNMImage &other);
370  void operator *= (float multiplier);
371  void operator *= (const LColorf &other);
372 
373 private:
374  friend class Row;
375  friend class Texture;
376 
377  xel *_array;
378  xelval *_alpha;
379  float _default_rc, _default_gc, _default_bc;
380 
381  int _read_x_size, _read_y_size;
382  bool _has_read_size;
383 
384  // The reciprocal of _maxval, as an optimization for from_val.
385  float _inv_maxval;
386 
387  // These method pointers contain the implementation for to_val and from_val,
388  // respectively, dependent on the maxval and color space.
389  ColorSpace _color_space;
390 
391  // The following enum determines which code path we should take in the
392  // set_xel and get_xel methods.
393  enum XelEncoding {
394  XE_generic,
395  XE_generic_alpha,
396  XE_generic_sRGB,
397  XE_generic_sRGB_alpha,
398  XE_uchar_sRGB,
399  XE_uchar_sRGB_alpha,
400  XE_uchar_sRGB_sse2,
401  XE_uchar_sRGB_alpha_sse2,
402  XE_scRGB,
403  XE_scRGB_alpha
404  } _xel_encoding;
405 };
406 
407 #include "pnmImage.I"
408 
409 #endif
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
This is the base class of a family of classes that represent particular image file types that PNMImag...
Definition: pnmFileType.h:32
This is the base class of PNMImage, PNMReader, and PNMWriter.
get_color_space
Returns the color space that the image is encoded in, or CS_unspecified if unknown.
The name of this class derives from the fact that we originally implemented it as a layer on top of t...
Definition: pnmImage.h:58
This is an abstract base class that defines the interface for reading image files of various types.
Definition: pnmReader.h:27
This is an abstract base class that defines the interface for writing image files of various types.
Definition: pnmWriter.h:27
Implements a multi-layer PerlinNoise, with one or more high-frequency noise functions added to a lowe...
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
Definition: texture.h:71
This is our own Panda specialization on the default STL map.
Definition: pmap.h:49
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.