00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pixelBuffer.h"
00020 #include "config_gobj.h"
00021
00022
00023
00024
00025 TypeHandle PixelBuffer::_type_handle;
00026
00027
00028
00029
00030
00031
00032 PixelBuffer::
00033 PixelBuffer(void) : ImageBuffer()
00034 {
00035 _xsize = 0;
00036 _ysize = 0;
00037 _xorg = 0;
00038 _yorg = 0;
00039 _border = 0;
00040 _format = F_rgb;
00041 _type = T_unsigned_byte;
00042 _components = 3;
00043 _component_width = 1;
00044 _image = PTA_uchar();
00045
00046 _loaded = false;
00047 }
00048
00049
00050
00051
00052
00053
00054 PixelBuffer::
00055 PixelBuffer(int xsize, int ysize, int components, int component_width,
00056 Type type, Format format) :
00057 ImageBuffer()
00058 {
00059 _xsize = xsize;
00060 _ysize = ysize;
00061 _xorg = 0;
00062 _yorg = 0;
00063 _border = 0;
00064 _components = components;
00065 _component_width = component_width;
00066 _type = type;
00067 _format = format;
00068 _image = PTA_uchar::empty_array((unsigned int)(_xsize * _ysize * _components * _component_width));
00069 _loaded = true;
00070 }
00071
00072
00073
00074
00075
00076
00077 PixelBuffer::
00078 PixelBuffer(int xsize, int ysize, int components, int component_width, Type type, Format format,
00079 bool bAllocateRAM) : ImageBuffer()
00080 {
00081 _xsize = xsize;
00082 _ysize = ysize;
00083 _xorg = 0;
00084 _yorg = 0;
00085 _border = 0;
00086 _components = components;
00087 _component_width = component_width;
00088 _type = type;
00089 _format = format;
00090 if(bAllocateRAM)
00091 _image = PTA_uchar::empty_array((unsigned int)(_xsize * _ysize * _components * _component_width));
00092 else _image = PTA_uchar();
00093 _loaded = false;
00094 }
00095
00096
00097
00098
00099
00100
00101 PixelBuffer::
00102 PixelBuffer(const PixelBuffer ©) :
00103 _xsize(copy._xsize),
00104 _ysize(copy._ysize),
00105 _xorg(copy._xorg),
00106 _yorg(copy._yorg),
00107 _border(copy._border),
00108 _components(copy._components),
00109 _component_width(copy._component_width),
00110 _format(copy._format),
00111 _type(copy._type),
00112 _loaded(copy._loaded),
00113 _image(copy._image)
00114 {
00115 }
00116
00117
00118
00119
00120
00121
00122 void PixelBuffer::
00123 operator = (const PixelBuffer ©) {
00124 _xsize = copy._xsize;
00125 _ysize = copy._ysize;
00126 _xorg = copy._xorg;
00127 _yorg = copy._yorg;
00128 _border = copy._border;
00129 _components = copy._components;
00130 _component_width = copy._component_width;
00131 _format = copy._format;
00132 _type = copy._type;
00133 _loaded = copy._loaded;
00134 _image = copy._image;
00135 }
00136
00137
00138
00139
00140
00141
00142 void PixelBuffer::config(void)
00143 {
00144 ImageBuffer::config();
00145 }
00146
00147
00148
00149
00150
00151
00152 bool PixelBuffer::
00153 read(const Filename &name) {
00154 PNMImage pnmimage;
00155
00156 if (!pnmimage.read(name)) {
00157 gobj_cat.error()
00158 << "PixelBuffer::read() - couldn't read: " << name << endl;
00159 return false;
00160 }
00161
00162 set_name(name.get_basename_wo_extension());
00163 set_filename(name);
00164 clear_alpha_filename();
00165 return load(pnmimage);
00166 }
00167
00168
00169
00170
00171
00172
00173 bool PixelBuffer::
00174 write(const Filename &name) const {
00175 PNMImage pnmimage;
00176 if (!store(pnmimage)) {
00177 return false;
00178 }
00179
00180 Filename tname;
00181 if (name.empty()) {
00182 tname = get_filename();
00183 } else {
00184 tname = name;
00185 }
00186
00187 if (!pnmimage.write(tname)) {
00188 gobj_cat.error()
00189 << "PixelBuffer::write() - couldn't write: " << name << endl;
00190 return false;
00191 }
00192 return true;
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 bool PixelBuffer::load(const PNMImage& pnmimage)
00204 {
00205 int num_components = pnmimage.get_num_channels();
00206
00207 if (!_loaded || num_components != _components) {
00208
00209
00210
00211
00212 switch (pnmimage.get_color_type()) {
00213 case PNMImage::CT_grayscale:
00214 _format = F_luminance;
00215 break;
00216
00217 case PNMImage::CT_two_channel:
00218 _format = F_luminance_alpha;
00219 break;
00220
00221 case PNMImage::CT_color:
00222 _format = F_rgb;
00223 break;
00224
00225 case PNMImage::CT_four_channel:
00226 _format = F_rgba;
00227 break;
00228
00229 default:
00230
00231 nassertr(false, false);
00232 _format = F_rgb;
00233 };
00234 }
00235
00236 _xsize = pnmimage.get_x_size();
00237 _ysize = pnmimage.get_y_size();
00238 _components = num_components;
00239 _loaded = true;
00240
00241
00242
00243 bool has_alpha = pnmimage.has_alpha();
00244 bool is_grayscale = pnmimage.is_grayscale();
00245 xelval maxval = pnmimage.get_maxval();
00246
00247 if (maxval == 255) {
00248
00249
00250 _type = T_unsigned_byte;
00251 _image = PTA_uchar::empty_array((int)(_xsize * _ysize * _components));
00252 int idx = 0;
00253
00254 for (int j = _ysize-1; j >= 0; j--) {
00255 for (int i = 0; i < _xsize; i++) {
00256 if (is_grayscale) {
00257 store_unscaled_byte(idx, pnmimage.get_gray_val(i, j));
00258 } else {
00259 store_unscaled_byte(idx, pnmimage.get_blue_val(i, j));
00260 store_unscaled_byte(idx, pnmimage.get_green_val(i, j));
00261 store_unscaled_byte(idx, pnmimage.get_red_val(i, j));
00262 }
00263 if (has_alpha) {
00264 store_unscaled_byte(idx, pnmimage.get_alpha_val(i, j));
00265 }
00266 }
00267 }
00268
00269 } else if (maxval == 65535) {
00270
00271
00272 _type = T_unsigned_short;
00273
00274 int idx = 0;
00275
00276 for (int j = _ysize-1; j >= 0; j--) {
00277 for (int i = 0; i < _xsize; i++) {
00278 if (is_grayscale) {
00279 store_unscaled_short(idx, pnmimage.get_gray_val(i, j));
00280 } else {
00281 store_unscaled_short(idx, pnmimage.get_blue_val(i, j));
00282 store_unscaled_short(idx, pnmimage.get_green_val(i, j));
00283 store_unscaled_short(idx, pnmimage.get_red_val(i, j));
00284 }
00285 if (has_alpha) {
00286 store_unscaled_short(idx, pnmimage.get_alpha_val(i, j));
00287 }
00288 }
00289 }
00290
00291 } else if (maxval <= 255) {
00292
00293
00294
00295 _type = T_unsigned_byte;
00296 _image = PTA_uchar::empty_array(_xsize * _ysize * _components);
00297 int idx = 0;
00298 double scale = 255.0 / (double)maxval;
00299
00300 for (int j = _ysize-1; j >= 0; j--) {
00301 for (int i = 0; i < _xsize; i++) {
00302 if (is_grayscale) {
00303 store_scaled_byte(idx, pnmimage.get_gray_val(i, j), scale);
00304 } else {
00305 store_scaled_byte(idx, pnmimage.get_blue_val(i, j), scale);
00306 store_scaled_byte(idx, pnmimage.get_green_val(i, j), scale);
00307 store_scaled_byte(idx, pnmimage.get_red_val(i, j), scale);
00308 }
00309 if (has_alpha) {
00310 store_scaled_byte(idx, pnmimage.get_alpha_val(i, j), scale);
00311 }
00312 }
00313 }
00314
00315 } else {
00316
00317
00318
00319 _type = T_unsigned_short;
00320 _image = PTA_uchar::empty_array(_xsize * _ysize * _components * 2);
00321 int idx = 0;
00322 double scale = 65535.0 / (double)maxval;
00323
00324 for (int j = _ysize-1; j >= 0; j--) {
00325 for (int i = 0; i < _xsize; i++) {
00326 if (is_grayscale) {
00327 store_scaled_short(idx, pnmimage.get_gray_val(i, j), scale);
00328 } else {
00329 store_scaled_short(idx, pnmimage.get_blue_val(i, j), scale);
00330 store_scaled_short(idx, pnmimage.get_green_val(i, j), scale);
00331 store_scaled_short(idx, pnmimage.get_red_val(i, j), scale);
00332 }
00333 if (has_alpha) {
00334 store_scaled_short(idx, pnmimage.get_alpha_val(i, j), scale);
00335 }
00336 }
00337 }
00338 }
00339
00340 config();
00341 return true;
00342 }
00343
00344
00345
00346
00347
00348
00349
00350 bool PixelBuffer::
00351 store(PNMImage &pnmimage) const {
00352 if (_type == T_unsigned_byte) {
00353 pnmimage.clear(_xsize, _ysize, _components);
00354 bool has_alpha = pnmimage.has_alpha();
00355 bool is_grayscale = pnmimage.is_grayscale();
00356
00357 int idx = 0;
00358 for (int j = _ysize-1; j >= 0; j--) {
00359 for (int i = 0; i < _xsize; i++) {
00360 if (is_grayscale) {
00361 pnmimage.set_gray(i, j, get_unsigned_byte(idx));
00362 } else {
00363 pnmimage.set_blue(i, j, get_unsigned_byte(idx));
00364 pnmimage.set_green(i, j, get_unsigned_byte(idx));
00365 pnmimage.set_red(i, j, get_unsigned_byte(idx));
00366 }
00367 if (has_alpha)
00368 pnmimage.set_alpha(i, j, get_unsigned_byte(idx));
00369 }
00370 }
00371 return true;
00372
00373 } else if (_type == T_unsigned_short) {
00374 pnmimage.clear(_xsize, _ysize, _components, 65535);
00375 bool has_alpha = pnmimage.has_alpha();
00376 bool is_grayscale = pnmimage.is_grayscale();
00377
00378 int idx = 0;
00379 for (int j = _ysize-1; j >= 0; j--) {
00380 for (int i = 0; i < _xsize; i++) {
00381 if (is_grayscale) {
00382 pnmimage.set_gray(i, j, get_unsigned_short(idx));
00383 } else {
00384 pnmimage.set_blue(i, j, get_unsigned_short(idx));
00385 pnmimage.set_green(i, j, get_unsigned_short(idx));
00386 pnmimage.set_red(i, j, get_unsigned_short(idx));
00387 }
00388 if (has_alpha)
00389 pnmimage.set_alpha(i, j, get_unsigned_short(idx));
00390 }
00391 }
00392 return true;
00393 }
00394
00395 gobj_cat.error()
00396 << "Couldn't write image for " << get_name()
00397 << "; inappropriate type " << (int)_type << ".\n";
00398 return false;
00399 }
00400
00401
00402
00403
00404
00405
00406 void PixelBuffer::
00407 copy(const PixelBuffer *pb) {
00408 nassertv(pb != NULL);
00409 _xorg = pb->_xorg;
00410 _yorg = pb->_yorg;
00411 _xsize = pb->_xsize;
00412 _ysize = pb->_ysize;
00413 _border = pb->_border;
00414 _components = pb->_components;
00415 _format = pb->_format;
00416 _image = PTA_uchar::empty_array(0);
00417 if (!pb->_image.empty())
00418 _image.v() = pb->_image.v();
00419 }
00420
00421 void PixelBuffer::copy(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr) {
00422 gsg->copy_pixel_buffer(this, dr);
00423 }
00424
00425 void PixelBuffer::copy(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr,
00426 const RenderBuffer &rb) {
00427 gsg->copy_pixel_buffer(this, dr, rb);
00428 }
00429