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 xelval to_val(float input_value) const;
72  INLINE xelval to_alpha_val(float input_value) const;
73  INLINE float from_val(xelval input_value) const;
74  INLINE float from_alpha_val(xelval input_value) const;
75 
76  void clear();
77  void clear(int x_size, int y_size, int num_channels = 3,
78  xelval maxval = 255, PNMFileType *type = nullptr,
79  ColorSpace color_space = CS_linear);
80 
81  void copy_from(const PNMImage &copy);
82  void copy_channel(const PNMImage &copy, int src_channel, int dest_channel);
83  void copy_channel_bits(const PNMImage &copy, int src_channel, int dest_channel, xelval src_mask, int right_shift);
84  void copy_header_from(const PNMImageHeader &header);
85  void take_from(PNMImage &orig);
86 
87  INLINE void fill(float red, float green, float blue);
88  INLINE void fill(float gray = 0.0);
89 
90  void fill_val(xelval red, xelval green, xelval blue);
91  INLINE void fill_val(xelval gray = 0);
92 
93  INLINE void alpha_fill(float alpha = 0.0);
94  void alpha_fill_val(xelval alpha = 0);
95 
96  INLINE void set_read_size(int x_size, int y_size);
97  INLINE void clear_read_size();
98  INLINE bool has_read_size() const;
99  INLINE int get_read_x_size() const;
100  INLINE int get_read_y_size() const;
101  INLINE ColorSpace get_color_space() const;
102 
103  BLOCKING bool read(const Filename &filename, PNMFileType *type = nullptr,
104  bool report_unknown_type = true);
105  BLOCKING bool read(std::istream &data, const std::string &filename = std::string(),
106  PNMFileType *type = nullptr,
107  bool report_unknown_type = true);
108  BLOCKING bool read(PNMReader *reader);
109 
110  BLOCKING bool write(const Filename &filename, PNMFileType *type = nullptr) const;
111  BLOCKING bool write(std::ostream &data, const std::string &filename = std::string(),
112  PNMFileType *type = nullptr) const;
113  BLOCKING bool write(PNMWriter *writer) const;
114 
115  INLINE bool is_valid() const;
116 
117  INLINE void set_num_channels(int num_channels);
118  void set_color_type(ColorType color_type);
119  void set_color_space(ColorSpace color_space);
120 
121  INLINE void add_alpha();
122  INLINE void remove_alpha();
123  INLINE void make_grayscale();
124  void make_grayscale(float rc, float gc, float bc);
125  INLINE void make_rgb();
126 
127  BLOCKING void premultiply_alpha();
128  BLOCKING void unpremultiply_alpha();
129 
130  BLOCKING void reverse_rows();
131  BLOCKING void flip(bool flip_x, bool flip_y, bool transpose);
132 
133  BLOCKING void set_maxval(xelval maxval);
134 
135  // The *_val() functions return or set the color values in the range
136  // [0..get_maxval()]. This range may be different for different images!
137  // Use the corresponding functions (without _val()) to work in the
138  // normalized range [0..1]. These return values in the image's stored color
139  // space.
140 
141  INLINE xel &get_xel_val(int x, int y);
142  INLINE xel get_xel_val(int x, int y) const;
143  INLINE void set_xel_val(int x, int y, const xel &value);
144  INLINE void set_xel_val(int x, int y, xelval r, xelval g, xelval b);
145  INLINE void set_xel_val(int x, int y, xelval gray);
146 
147  INLINE xelval get_red_val(int x, int y) const;
148  INLINE xelval get_green_val(int x, int y) const;
149  INLINE xelval get_blue_val(int x, int y) const;
150  INLINE xelval get_gray_val(int x, int y) const;
151  INLINE xelval get_alpha_val(int x, int y) const;
152 
153  INLINE void set_red_val(int x, int y, xelval r);
154  INLINE void set_green_val(int x, int y, xelval g);
155  INLINE void set_blue_val(int x, int y, xelval b);
156  INLINE void set_gray_val(int x, int y, xelval gray);
157  INLINE void set_alpha_val(int x, int y, xelval a);
158 
159  xelval get_channel_val(int x, int y, int channel) const;
160  void set_channel_val(int x, int y, int channel, xelval value);
161  float get_channel(int x, int y, int channel) const;
162  void set_channel(int x, int y, int channel, float value);
163 
164  PixelSpec get_pixel(int x, int y) const;
165  void set_pixel(int x, int y, const PixelSpec &pixel);
166 
167  // The corresponding get_xel(), set_xel(), get_red(), etc. functions
168  // automatically scale their values by get_maxval() into the range [0..1],
169  // and into the linear color space.
170 
171  INLINE LRGBColorf get_xel(int x, int y) const;
172  INLINE void set_xel(int x, int y, const LRGBColorf &value);
173  INLINE void set_xel(int x, int y, float r, float g, float b);
174  INLINE void set_xel(int x, int y, float gray);
175 
176  INLINE LColorf get_xel_a(int x, int y) const;
177  INLINE void set_xel_a(int x, int y, const LColorf &value);
178  INLINE void set_xel_a(int x, int y, float r, float g, float b, float a);
179 
180  INLINE float get_red(int x, int y) const;
181  INLINE float get_green(int x, int y) const;
182  INLINE float get_blue(int x, int y) const;
183  INLINE float get_gray(int x, int y) const;
184  INLINE float get_alpha(int x, int y) const;
185 
186  INLINE void set_red(int x, int y, float r);
187  INLINE void set_green(int x, int y, float g);
188  INLINE void set_blue(int x, int y, float b);
189  INLINE void set_gray(int x, int y, float gray);
190  INLINE void set_alpha(int x, int y, float a);
191 
192  INLINE float get_bright(int x, int y) const;
193  INLINE float get_bright(int x, int y, float rc, float gc,
194  float bc) const;
195  INLINE float get_bright(int x, int y, float rc, float gc,
196  float bc, float ac) const;
197 
198  INLINE void blend(int x, int y, const LRGBColorf &val, float alpha);
199  void blend(int x, int y, float r, float g, float b, float alpha);
200 
201  void copy_sub_image(const PNMImage &copy, int xto, int yto,
202  int xfrom = 0, int yfrom = 0,
203  int x_size = -1, int y_size = -1);
204  void blend_sub_image(const PNMImage &copy, int xto, int yto,
205  int xfrom = 0, int yfrom = 0,
206  int x_size = -1, int y_size = -1,
207  float pixel_scale = 1.0);
208  void add_sub_image(const PNMImage &copy, int xto, int yto,
209  int xfrom = 0, int yfrom = 0,
210  int x_size = -1, int y_size = -1,
211  float pixel_scale = 1.0);
212  void mult_sub_image(const PNMImage &copy, int xto, int yto,
213  int xfrom = 0, int yfrom = 0,
214  int x_size = -1, int y_size = -1,
215  float pixel_scale = 1.0);
216  void darken_sub_image(const PNMImage &copy, int xto, int yto,
217  int xfrom = 0, int yfrom = 0,
218  int x_size = -1, int y_size = -1,
219  float pixel_scale = 1.0);
220  void lighten_sub_image(const PNMImage &copy, int xto, int yto,
221  int xfrom = 0, int yfrom = 0,
222  int x_size = -1, int y_size = -1,
223  float pixel_scale = 1.0);
224  void threshold(const PNMImage &select_image, int channel, float threshold,
225  const PNMImage &lt, const PNMImage &ge);
226  BLOCKING void fill_distance_inside(const PNMImage &mask, float threshold, int radius, bool shrink_from_border);
227  BLOCKING void fill_distance_outside(const PNMImage &mask, float threshold, int radius);
228 
229  void indirect_1d_lookup(const PNMImage &index_image, int channel,
230  const PNMImage &pixel_values);
231 
232  void rescale(float min_val, float max_val);
233 
234  void copy_channel(const PNMImage &copy, int xto, int yto, int cto,
235  int xfrom = 0, int yfrom = 0, int cfrom = 0,
236  int x_size = -1, int y_size = -1);
237 
238  void render_spot(const LColorf &fg, const LColorf &bg,
239  float min_radius, float max_radius);
240 
241  void expand_border(int left, int right, int bottom, int top,
242  const LColorf &color);
243 
244  // The bodies for the non-inline *_filter() functions can be found in the
245  // file pnm-image-filter.cxx.
246 
247  BLOCKING INLINE void box_filter(float radius = 1.0);
248  BLOCKING INLINE void gaussian_filter(float radius = 1.0);
249 
250  BLOCKING void unfiltered_stretch_from(const PNMImage &copy);
251  BLOCKING void box_filter_from(float radius, const PNMImage &copy);
252  BLOCKING void gaussian_filter_from(float radius, const PNMImage &copy);
253  BLOCKING void quick_filter_from(const PNMImage &copy,
254  int xborder = 0, int yborder = 0);
255 
256  void make_histogram(Histogram &hist);
257  BLOCKING void perlin_noise_fill(float sx, float sy, int table_size = 256,
258  unsigned long seed = 0);
259  void perlin_noise_fill(StackedPerlinNoise2 &perlin);
260 
261  void remix_channels(const LMatrix4 &conv);
262  BLOCKING INLINE void gamma_correct(float from_gamma, float to_gamma);
263  BLOCKING INLINE void gamma_correct_alpha(float from_gamma, float to_gamma);
264  BLOCKING INLINE void apply_exponent(float gray_exponent);
265  BLOCKING INLINE void apply_exponent(float gray_exponent, float alpha_exponent);
266  BLOCKING INLINE void apply_exponent(float red_exponent, float green_exponent, float blue_exponent);
267  BLOCKING void apply_exponent(float red_exponent, float green_exponent, float blue_exponent, float alpha_exponent);
268 
269  LRGBColorf get_average_xel() const;
270  LColorf get_average_xel_a() const;
271  float get_average_gray() const;
272 
273  void do_fill_distance(int xi, int yi, int d);
274 
275 PUBLISHED:
276  // Provides an accessor for reading or writing the contents of one row of
277  // the image in-place.
278  class EXPCL_PANDA_PNMIMAGE Row {
279  PUBLISHED:
280  INLINE size_t size() const;
281  INLINE LColorf operator[](int x) const;
282 #ifdef HAVE_PYTHON
283  INLINE void __setitem__(int x, const LColorf &v);
284 #endif
285  INLINE xel &get_xel_val(int x);
286  INLINE void set_xel_val(int x, const xel &v);
287  INLINE xelval get_alpha_val(int x) const;
288  INLINE void set_alpha_val(int x, xelval v);
289 
290  public:
291  INLINE Row(PNMImage &image, int y);
292 
293  private:
294  PNMImage &_image;
295  int _y;
296  };
297 
298  // Provides an accessor for reading the contents of one row of the image in-
299  // place.
300  class EXPCL_PANDA_PNMIMAGE CRow {
301  PUBLISHED:
302  INLINE size_t size() const;
303  INLINE LColorf operator[](int x) const;
304  INLINE xel get_xel_val(int x) const;
305  INLINE xelval get_alpha_val(int x) const;
306 
307  public:
308  INLINE CRow(const PNMImage &image, int y);
309 
310  private:
311  const PNMImage &_image;
312  int _y;
313  };
314 
315  INLINE Row operator [] (int y);
316  INLINE CRow operator [] (int y) const;
317 
318 public:
319  // Know what you are doing if you access the underlying data arrays
320  // directly.
321  INLINE xel *get_array();
322  INLINE const xel *get_array() const;
323  INLINE xelval *get_alpha_array();
324  INLINE const xelval *get_alpha_array() const;
325 
326  INLINE xel *take_array();
327  INLINE xelval *take_alpha_array();
328  void set_array(xel *array);
329  void set_alpha_array(xelval *alpha);
330 
331 private:
332  INLINE void allocate_array();
333  INLINE void allocate_alpha();
334 
335  INLINE xel *row(int row) const;
336  INLINE xelval *alpha_row(int row) const;
337 
338  INLINE void setup_sub_image(const PNMImage &copy, int &xto, int &yto,
339  int &xfrom, int &yfrom, int &x_size, int &y_size,
340  int &xmin, int &ymin, int &xmax, int &ymax);
341 
342  INLINE static void compute_spot_pixel(LColorf &c, float d2,
343  float min_radius, float max_radius,
344  const LColorf &fg, const LColorf &bg);
345 
346  void setup_rc();
347  void setup_encoding();
348 
349 PUBLISHED:
350  PNMImage operator ~() const;
351 
352  INLINE PNMImage operator + (const PNMImage &other) const;
353  INLINE PNMImage operator + (const LColorf &other) const;
354  INLINE PNMImage operator - (const PNMImage &other) const;
355  INLINE PNMImage operator - (const LColorf &other) const;
356  INLINE PNMImage operator * (const PNMImage &other) const;
357  INLINE PNMImage operator * (float multiplier) const;
358  INLINE PNMImage operator * (const LColorf &other) const;
359  void operator += (const PNMImage &other);
360  void operator += (const LColorf &other);
361  void operator -= (const PNMImage &other);
362  void operator -= (const LColorf &other);
363  void operator *= (const PNMImage &other);
364  void operator *= (float multiplier);
365  void operator *= (const LColorf &other);
366 
367 private:
368  friend class Row;
369  friend class Texture;
370 
371  xel *_array;
372  xelval *_alpha;
373  float _default_rc, _default_gc, _default_bc;
374 
375  int _read_x_size, _read_y_size;
376  bool _has_read_size;
377 
378  // The reciprocal of _maxval, as an optimization for from_val.
379  float _inv_maxval;
380 
381  // These method pointers contain the implementation for to_val and from_val,
382  // respectively, dependent on the maxval and color space.
383  ColorSpace _color_space;
384 
385  // The following enum determines which code path we should take in the
386  // set_xel and get_xel methods.
387  enum XelEncoding {
388  XE_generic,
389  XE_generic_alpha,
390  XE_generic_sRGB,
391  XE_generic_sRGB_alpha,
392  XE_uchar_sRGB,
393  XE_uchar_sRGB_alpha,
394  XE_uchar_sRGB_sse2,
395  XE_uchar_sRGB_alpha_sse2,
396  XE_scRGB,
397  XE_scRGB_alpha
398  } _xel_encoding;
399 };
400 
401 #include "pnmImage.I"
402 
403 #endif
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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the base class of a family of classes that represent particular image file types that PNMImag...
Definition: pnmFileType.h:32
Implements a multi-layer PerlinNoise, with one or more high-frequency noise functions added to a lowe...
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the base class of PNMImage, PNMReader, and PNMWriter.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.