Panda3D
|
00001 // Filename: pnmImage.h 00002 // Created by: drose (14Jun00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #ifndef PNMIMAGE_H 00016 #define PNMIMAGE_H 00017 00018 #include "pandabase.h" 00019 00020 #include "pnmImageHeader.h" 00021 #include "pnmBrush.h" 00022 00023 #include "luse.h" 00024 00025 class PNMReader; 00026 class PNMWriter; 00027 class PNMFileType; 00028 class StackedPerlinNoise2; 00029 00030 //////////////////////////////////////////////////////////////////// 00031 // Class : PNMImage 00032 // Description : The name of this class derives from the fact that we 00033 // originally implemented it as a layer on top of the 00034 // "pnm library", based on netpbm, which was built to 00035 // implement pbm, pgm, and pbm files, and is the 00036 // underlying support of a number of public-domain image 00037 // file converters. Nowadays we are no longer derived 00038 // directly from the pnm library, mainly to allow 00039 // support of C++ iostreams instead of the C stdio FILE 00040 // interface. 00041 // 00042 // Conceptually, a PNMImage is a two-dimensional array 00043 // of xels, which are the PNM-defined generic pixel 00044 // type. Each xel may have a red, green, and blue 00045 // component, or (if the image is grayscale) a gray 00046 // component. The image may be read in, the individual 00047 // xels manipulated, and written out again, or a black 00048 // image may be constructed from scratch. 00049 // 00050 // The image is of size XSize() by YSize() xels, 00051 // numbered from top to bottom, left to right, beginning 00052 // at zero. 00053 // 00054 // Files can be specified by filename, or by an iostream 00055 // pointer. The filename "-" refers to stdin or stdout. 00056 //////////////////////////////////////////////////////////////////// 00057 class EXPCL_PANDA_PNMIMAGE PNMImage : public PNMImageHeader { 00058 PUBLISHED: 00059 INLINE PNMImage(); 00060 PNMImage(const Filename &filename, PNMFileType *type = NULL); 00061 INLINE PNMImage(int x_size, int y_size, int num_channels = 3, 00062 xelval maxval = 255, PNMFileType *type = NULL); 00063 INLINE PNMImage(const PNMImage ©); 00064 INLINE void operator = (const PNMImage ©); 00065 00066 INLINE ~PNMImage(); 00067 00068 INLINE xelval clamp_val(int input_value) const; 00069 INLINE xelval to_val(double input_value) const; 00070 INLINE double from_val(xelval input_value) const; 00071 00072 void clear(); 00073 void clear(int x_size, int y_size, int num_channels = 3, 00074 xelval maxval = 255, PNMFileType *type = NULL); 00075 00076 void copy_from(const PNMImage ©); 00077 void copy_channel(const PNMImage ©, int src_channel, int dest_channel); 00078 void copy_header_from(const PNMImageHeader &header); 00079 void take_from(PNMImage &orig); 00080 00081 INLINE void fill(double red, double green, double blue); 00082 INLINE void fill(double gray = 0.0); 00083 00084 void fill_val(xelval red, xelval green, xelval blue); 00085 INLINE void fill_val(xelval gray = 0); 00086 00087 INLINE void alpha_fill(double alpha = 0.0); 00088 void alpha_fill_val(xelval alpha = 0); 00089 00090 INLINE void set_read_size(int x_size, int y_size); 00091 INLINE void clear_read_size(); 00092 INLINE bool has_read_size() const; 00093 INLINE int get_read_x_size() const; 00094 INLINE int get_read_y_size() const; 00095 00096 BLOCKING bool read(const Filename &filename, PNMFileType *type = NULL, 00097 bool report_unknown_type = true); 00098 BLOCKING bool read(istream &data, const string &filename = string(), 00099 PNMFileType *type = NULL, 00100 bool report_unknown_type = true); 00101 BLOCKING bool read(PNMReader *reader); 00102 00103 BLOCKING bool write(const Filename &filename, PNMFileType *type = NULL) const; 00104 BLOCKING bool write(ostream &data, const string &filename = string(), 00105 PNMFileType *type = NULL) const; 00106 BLOCKING bool write(PNMWriter *writer) const; 00107 00108 INLINE bool is_valid() const; 00109 00110 INLINE void set_num_channels(int num_channels); 00111 void set_color_type(ColorType color_type); 00112 00113 INLINE void add_alpha(); 00114 INLINE void remove_alpha(); 00115 INLINE void make_grayscale(); 00116 void make_grayscale(double rc, double gc, double bc); 00117 INLINE void make_rgb(); 00118 00119 BLOCKING void reverse_rows(); 00120 00121 BLOCKING void set_maxval(xelval maxval); 00122 00123 // The *_val() functions return or set the color values in the range 00124 // [0..get_maxval()]. This range may be different for different 00125 // images! Use the corresponding functions (without _val()) to work 00126 // in the normalized range [0..1]. 00127 00128 INLINE const xel &get_xel_val(int x, int y) const; 00129 INLINE void set_xel_val(int x, int y, const xel &value); 00130 INLINE void set_xel_val(int x, int y, xelval r, xelval g, xelval b); 00131 INLINE void set_xel_val(int x, int y, xelval gray); 00132 00133 INLINE xelval get_red_val(int x, int y) const; 00134 INLINE xelval get_green_val(int x, int y) const; 00135 INLINE xelval get_blue_val(int x, int y) const; 00136 INLINE xelval get_gray_val(int x, int y) const; 00137 INLINE xelval get_alpha_val(int x, int y) const; 00138 00139 INLINE void set_red_val(int x, int y, xelval r); 00140 INLINE void set_green_val(int x, int y, xelval g); 00141 INLINE void set_blue_val(int x, int y, xelval b); 00142 INLINE void set_gray_val(int x, int y, xelval gray); 00143 INLINE void set_alpha_val(int x, int y, xelval a); 00144 00145 xelval get_channel_val(int x, int y, int channel) const; 00146 void set_channel_val(int x, int y, int channel, xelval value); 00147 00148 PixelSpec get_pixel(int x, int y) const; 00149 void set_pixel(int x, int y, const PixelSpec &pixel); 00150 00151 // The corresponding get_xel(), set_xel(), get_red(), etc. functions 00152 // automatically scale their values by get_maxval() into the range 00153 // [0..1]. 00154 00155 INLINE LRGBColord get_xel(int x, int y) const; 00156 INLINE void set_xel(int x, int y, const LRGBColord &value); 00157 INLINE void set_xel(int x, int y, double r, double g, double b); 00158 INLINE void set_xel(int x, int y, double gray); 00159 00160 INLINE LColord get_xel_a(int x, int y) const; 00161 INLINE void set_xel_a(int x, int y, const LColord &value); 00162 INLINE void set_xel_a(int x, int y, double r, double g, double b, double a); 00163 00164 INLINE double get_red(int x, int y) const; 00165 INLINE double get_green(int x, int y) const; 00166 INLINE double get_blue(int x, int y) const; 00167 INLINE double get_gray(int x, int y) const; 00168 INLINE double get_alpha(int x, int y) const; 00169 00170 INLINE void set_red(int x, int y, double r); 00171 INLINE void set_green(int x, int y, double g); 00172 INLINE void set_blue(int x, int y, double b); 00173 INLINE void set_gray(int x, int y, double gray); 00174 INLINE void set_alpha(int x, int y, double a); 00175 00176 INLINE double get_channel(int x, int y, int channel) const; 00177 INLINE void set_channel(int x, int y, int channel, double value); 00178 00179 INLINE double get_bright(int x, int y) const; 00180 INLINE double get_bright(int x, int y, double rc, double gc, 00181 double bc) const; 00182 INLINE double get_bright(int x, int y, double rc, double gc, 00183 double bc, double ac) const; 00184 00185 INLINE void blend(int x, int y, const LRGBColord &val, double alpha); 00186 void blend(int x, int y, double r, double g, double b, double alpha); 00187 00188 // If you're used to the NetPBM library and like working with a 2-d 00189 // array of xels, and using the PNM macros to access their components, 00190 // you may treat the PNMImage as such directly. 00191 00192 INLINE xel *operator [] (int y); 00193 INLINE const xel *operator [] (int y) const; 00194 00195 void copy_sub_image(const PNMImage ©, int xto, int yto, 00196 int xfrom = 0, int yfrom = 0, 00197 int x_size = -1, int y_size = -1); 00198 void blend_sub_image(const PNMImage ©, int xto, int yto, 00199 int xfrom = 0, int yfrom = 0, 00200 int x_size = -1, int y_size = -1, 00201 double pixel_scale = 1.0); 00202 void darken_sub_image(const PNMImage ©, int xto, int yto, 00203 int xfrom = 0, int yfrom = 0, 00204 int x_size = -1, int y_size = -1, 00205 double pixel_scale = 1.0); 00206 void lighten_sub_image(const PNMImage ©, int xto, int yto, 00207 int xfrom = 0, int yfrom = 0, 00208 int x_size = -1, int y_size = -1, 00209 double pixel_scale = 1.0); 00210 void threshold(const PNMImage &select_image, int channel, double threshold, 00211 const PNMImage <, const PNMImage &ge); 00212 00213 void copy_channel(const PNMImage ©, int xto, int yto, int cto, 00214 int xfrom = 0, int yfrom = 0, int cfrom = 0, 00215 int x_size = -1, int y_size = -1); 00216 00217 void render_spot(const LColord &fg, const LColord &bg, 00218 double min_radius, double max_radius); 00219 00220 void expand_border(int left, int right, int bottom, int top, 00221 const LColord &color); 00222 00223 // The bodies for the non-inline *_filter() functions can be found 00224 // in the file pnm-image-filter.cxx. 00225 00226 INLINE void box_filter(double radius = 1.0); 00227 INLINE void gaussian_filter(double radius = 1.0); 00228 00229 void box_filter_from(double radius, const PNMImage ©); 00230 void gaussian_filter_from(double radius, const PNMImage ©); 00231 void quick_filter_from(const PNMImage ©, 00232 int xborder = 0, int yborder = 0); 00233 00234 void make_histogram(Histogram &hist); 00235 void perlin_noise_fill(double sx, double sy, int table_size = 256, 00236 unsigned long seed = 0); 00237 void perlin_noise_fill(StackedPerlinNoise2 &perlin); 00238 00239 void remix_channels(const LMatrix4 &conv); 00240 INLINE void gamma_correct(double from_gamma, double to_gamma); 00241 INLINE void gamma_correct_alpha(double from_gamma, double to_gamma); 00242 INLINE void apply_exponent(double gray_exponent); 00243 INLINE void apply_exponent(double gray_exponent, double alpha_exponent); 00244 INLINE void apply_exponent(double red_exponent, double green_exponent, double blue_exponent); 00245 void apply_exponent(double red_exponent, double green_exponent, double blue_exponent, double alpha_exponent); 00246 00247 LRGBColord get_average_xel() const; 00248 LColord get_average_xel_a() const; 00249 double get_average_gray() const; 00250 00251 private: 00252 INLINE void allocate_array(); 00253 INLINE void allocate_alpha(); 00254 00255 INLINE xel *row(int row) const; 00256 INLINE xelval *alpha_row(int row) const; 00257 00258 INLINE void setup_sub_image(const PNMImage ©, int &xto, int &yto, 00259 int &xfrom, int &yfrom, int &x_size, int &y_size, 00260 int &xmin, int &ymin, int &xmax, int &ymax); 00261 00262 INLINE static void compute_spot_pixel(LColord &c, double d2, 00263 double min_radius, double max_radius, 00264 const LColord &fg, const LColord &bg); 00265 00266 void setup_rc(); 00267 00268 PUBLISHED: 00269 PNMImage operator ~() const; 00270 00271 INLINE PNMImage operator + (const PNMImage &other) const; 00272 INLINE PNMImage operator + (const LColord &other) const; 00273 INLINE PNMImage operator - (const PNMImage &other) const; 00274 INLINE PNMImage operator - (const LColord &other) const; 00275 INLINE PNMImage operator * (const PNMImage &other) const; 00276 INLINE PNMImage operator * (double multiplier) const; 00277 void operator += (const PNMImage &other); 00278 void operator += (const LColord &other); 00279 void operator -= (const PNMImage &other); 00280 void operator -= (const LColord &other); 00281 void operator *= (const PNMImage &other); 00282 void operator *= (double multiplier); 00283 00284 private: 00285 xel *_array; 00286 xelval *_alpha; 00287 double _default_rc, _default_gc, _default_bc; 00288 00289 int _read_x_size, _read_y_size; 00290 bool _has_read_size; 00291 }; 00292 00293 #include "pnmImage.I" 00294 00295 #endif