Browse Source

*** empty log message ***

David Rose 24 years ago
parent
commit
1cb8444cf8
3 changed files with 107 additions and 26 deletions
  1. 38 10
      panda/src/gobj/pixelBuffer.I
  2. 65 14
      panda/src/gobj/pixelBuffer.cxx
  3. 4 2
      panda/src/gobj/pixelBuffer.h

+ 38 - 10
panda/src/gobj/pixelBuffer.I

@@ -311,39 +311,67 @@ set_uchar_rgb_texel(const uchar color[3], int x, int y, int width)
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: PixelBuffer::store_unsigned_byte
+//     Function: PixelBuffer::store_unscaled_byte
 //       Access: Private
 //  Description: This is used by load() to store the next consecutive
 //               component value into the indicated element of the
 //               array, which is taken to be an array of unsigned
-//               bytes.
+//               bytes.  The value is assumed to be in the range
+//               0-255.
 ////////////////////////////////////////////////////////////////////
 INLINE void PixelBuffer::
-store_unsigned_byte(int &index, double value) {
-  nassertv(index >= 0 && index < (int)_image.size());
-  _image[index++] = (uchar)(value * 255.0);
+store_unscaled_byte(int &index, int value) {
+  _image[index++] = (uchar)value;
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: PixelBuffer::store_unsigned_short
+//     Function: PixelBuffer::store_unscaled_short
 //       Access: Private
 //  Description: This is used by load() to store the next consecutive
 //               component value into the indicated element of the
 //               array, which is taken to be an array of unsigned
-//               shorts.
+//               shorts.  The value is assumed to be in the range
+//               0-65535.
 ////////////////////////////////////////////////////////////////////
 INLINE void PixelBuffer::
-store_unsigned_short(int &index, double value) {
-  nassertv(index >= 0 && index+1 < (int)_image.size());
+store_unscaled_short(int &index, int value) {
   union {
     ushort us;
     uchar uc[2];
   } v;
-  v.us = (ushort)(value * 65535.0);
+  v.us = (ushort)value;
   _image[index++] = v.uc[0];
   _image[index++] = v.uc[1];
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: PixelBuffer::store_scaled_byte
+//       Access: Private
+//  Description: This is used by load() to store the next consecutive
+//               component value into the indicated element of the
+//               array, which is taken to be an array of unsigned
+//               bytes.  The value will be scaled by the indicated
+//               factor before storing it.
+////////////////////////////////////////////////////////////////////
+INLINE void PixelBuffer::
+store_scaled_byte(int &index, int value, double scale) {
+  store_unscaled_byte(index, (int)(value * scale));
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PixelBuffer::store_scaled_short
+//       Access: Private
+//  Description: This is used by load() to store the next consecutive
+//               component value into the indicated element of the
+//               array, which is taken to be an array of unsigned
+//               shorts.  The value will be scaled by the indicated
+//               factor before storing it.
+////////////////////////////////////////////////////////////////////
+INLINE void PixelBuffer::
+store_scaled_short(int &index, int value, double scale) {
+  store_unscaled_short(index, (int)(value * scale));
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: PixelBuffer::get_unsigned_byte
 //       Access: Private

+ 65 - 14
panda/src/gobj/pixelBuffer.cxx

@@ -111,8 +111,31 @@ bool PixelBuffer::load(const PNMImage& pnmimage)
   bool has_alpha = pnmimage.has_alpha();
   bool is_grayscale = pnmimage.is_grayscale();
 
-  if (maxval > 255) {
-    // Wide pixels; we need to use a short for each component.
+  if (maxval == 255) {
+    // Most common case: one byte per pixel, and the source image
+    // shows a maxval of 255.  No scaling is necessary.
+    _type = T_unsigned_byte;
+    _image = PTA_uchar(_xsize * _ysize * _components);
+    int idx = 0;
+    
+    for (int j = _ysize-1; j >= 0; j--) {
+      for (int i = 0; i < _xsize; i++) {
+	if (is_grayscale) {
+	  store_unscaled_byte(idx, pnmimage.get_gray_val(i, j));
+	} else {
+	  store_unscaled_byte(idx, pnmimage.get_red_val(i, j));
+	  store_unscaled_byte(idx, pnmimage.get_green_val(i, j));
+	  store_unscaled_byte(idx, pnmimage.get_blue_val(i, j));
+	}
+	if (has_alpha) {
+	  store_unscaled_byte(idx, pnmimage.get_alpha_val(i, j));
+	}
+      }
+    }
+
+  } else if (maxval == 65535) {
+    // Another possible case: two bytes per pixel, and the source
+    // image shows a maxval of 65535.  Again, no scaling is necessary.
     _type = T_unsigned_short;
     _image = PTA_uchar(_xsize * _ysize * _components * 2);
     int idx = 0;
@@ -120,34 +143,62 @@ bool PixelBuffer::load(const PNMImage& pnmimage)
     for (int j = _ysize-1; j >= 0; j--) {
       for (int i = 0; i < _xsize; i++) {
 	if (is_grayscale) {
-	  store_unsigned_short(idx, pnmimage.get_gray(i, j));
+	  store_unscaled_short(idx, pnmimage.get_gray_val(i, j));
 	} else {
-	  store_unsigned_short(idx, pnmimage.get_red(i, j));
-	  store_unsigned_short(idx, pnmimage.get_green(i, j));
-	  store_unsigned_short(idx, pnmimage.get_blue(i, j));
+	  store_unscaled_short(idx, pnmimage.get_red_val(i, j));
+	  store_unscaled_short(idx, pnmimage.get_green_val(i, j));
+	  store_unscaled_short(idx, pnmimage.get_blue_val(i, j));
 	}
 	if (has_alpha) {
-	  store_unsigned_short(idx, pnmimage.get_alpha(i, j));
+	  store_unscaled_short(idx, pnmimage.get_alpha_val(i, j));
 	}
       }
     }
-  } else {
-    // Normal pixels: a byte per component will do.
+
+  } else if (maxval <= 255) {
+    // A less common case: one byte per pixel, but the maxval is
+    // something other than 255.  In this case, we should scale the
+    // pixel values up to the appropriate amount.
     _type = T_unsigned_byte;
     _image = PTA_uchar(_xsize * _ysize * _components);
     int idx = 0;
+    double scale = 255.0 / (double)maxval;
+    
+    for (int j = _ysize-1; j >= 0; j--) {
+      for (int i = 0; i < _xsize; i++) {
+	if (is_grayscale) {
+	  store_scaled_byte(idx, pnmimage.get_gray_val(i, j), scale);
+	} else {
+	  store_scaled_byte(idx, pnmimage.get_red_val(i, j), scale);
+	  store_scaled_byte(idx, pnmimage.get_green_val(i, j), scale);
+	  store_scaled_byte(idx, pnmimage.get_blue_val(i, j), scale);
+	}
+	if (has_alpha) {
+	  store_scaled_byte(idx, pnmimage.get_alpha_val(i, j), scale);
+	}
+      }
+    }
+
+  } else {
+    // Another uncommon case: two bytes per pixel, and the maxval is
+    // something other than 65535.  Again, we must scale the pixel
+    // values.
+    _type = T_unsigned_short;
+    _image = PTA_uchar(_xsize * _ysize * _components * 2);
+    int idx = 0;
+    double scale = 65535.0 / (double)maxval;
     
     for (int j = _ysize-1; j >= 0; j--) {
       for (int i = 0; i < _xsize; i++) {
 	if (is_grayscale) {
-	  store_unsigned_byte(idx, pnmimage.get_gray(i, j));
+	  store_scaled_short(idx, pnmimage.get_gray_val(i, j), scale);
 	} else {
-	  store_unsigned_byte(idx, pnmimage.get_red(i, j));
-	  store_unsigned_byte(idx, pnmimage.get_green(i, j));
-	  store_unsigned_byte(idx, pnmimage.get_blue(i, j));
+	  store_scaled_short(idx, pnmimage.get_red_val(i, j), scale);
+	  store_scaled_short(idx, pnmimage.get_green_val(i, j), scale);
+	  store_scaled_short(idx, pnmimage.get_blue_val(i, j), scale);
 	}
 	if (has_alpha) {
-	  store_unsigned_byte(idx, pnmimage.get_alpha(i, j));
+	  store_scaled_short(idx, pnmimage.get_alpha_val(i, j), scale);
 	}
       }
     }

+ 4 - 2
panda/src/gobj/pixelBuffer.h

@@ -112,8 +112,10 @@ public:
                   int x, int y, int width);
 
 private:
-  INLINE void store_unsigned_byte(int &index, double value);
-  INLINE void store_unsigned_short(int &index, double value);
+  INLINE void store_unscaled_byte(int &index, int value);
+  INLINE void store_unscaled_short(int &index, int value);
+  INLINE void store_scaled_byte(int &index, int value, double scale);
+  INLINE void store_scaled_short(int &index, int value, double scale);
   INLINE double get_unsigned_byte(int &index) const;
   INLINE double get_unsigned_short(int &index) const;