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
pandabase.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pmap
This is our own Panda specialization on the default STL map.
Definition: pmap.h:49
pnmImageHeader.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PNMImageHeader::Histogram
Definition: pnmImageHeader.h:167
PNMImage::CRow
Definition: pnmImage.h:303
pnmBrush.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Texture
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
PNMImage
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
PNMImage::Row
Definition: pnmImage.h:281
pnmImage.I
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PNMImageHeader
This is the base class of PNMImage, PNMReader, and PNMWriter.
Definition: pnmImageHeader.h:40
PNMImageHeader::PixelSpec
Definition: pnmImageHeader.h:115
luse.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
StackedPerlinNoise2
Implements a multi-layer PerlinNoise, with one or more high-frequency noise functions added to a lowe...
Definition: stackedPerlinNoise2.h:25
PNMReader
This is an abstract base class that defines the interface for reading image files of various types.
Definition: pnmReader.h:27
convert_srgb.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
stackedPerlinNoise2.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pixel
Definition: pnmimage_base.h:41
PNMWriter
This is an abstract base class that defines the interface for writing image files of various types.
Definition: pnmWriter.h:27
PNMImageHeader::get_color_space
get_color_space
Returns the color space that the image is encoded in, or CS_unspecified if unknown.
Definition: pnmImageHeader.h:71
PNMFileType
This is the base class of a family of classes that represent particular image file types that PNMImag...
Definition: pnmFileType.h:32
Filename
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39