Panda3D
 All Classes Functions Variables Enumerations
imageTrans.cxx
00001 // Filename: imageTrans.cxx
00002 // Created by:  drose (19Jun00)
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 #include "imageTrans.h"
00016 #include "string_utils.h"
00017 #include "pystub.h"
00018 
00019 ////////////////////////////////////////////////////////////////////
00020 //     Function: ImageTrans::Constructor
00021 //       Access: Public
00022 //  Description:
00023 ////////////////////////////////////////////////////////////////////
00024 ImageTrans::
00025 ImageTrans() : ImageFilter(true) {
00026   set_program_description
00027     ("This program reads an image file and writes a similar "
00028      "image file to the output.  It can implicitly convert from one image "
00029      "file format to another; it uses the extension of the output filename "
00030      "to specify the destination file format.");
00031 
00032   add_option
00033     ("chan", "channels", 50,
00034      "Elevate (or truncate) the image to the indicated number of channels.  "
00035      "This may be 1, 2, 3, or 4.  You may also specify one of the keywords "
00036      "l, la, rgb, or rgba, respectively, or any of the keywords r, g, b, or "
00037      "a to extract out just the indicated channel as a single grayscale "
00038      "image.",
00039      &ImageTrans::dispatch_channels, NULL, &_channels);
00040 
00041   add_option
00042     ("cscale", "r,g,b[,a]", 50,
00043      "Apply the indicated color scale to each pixel of the image.",
00044      &ImageTrans::dispatch_color, &_has_color_scale, &_color_scale);
00045 
00046   _channels = C_default;
00047   _color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
00048 }
00049 
00050 ////////////////////////////////////////////////////////////////////
00051 //     Function: ImageTrans::run
00052 //       Access: Public
00053 //  Description:
00054 ////////////////////////////////////////////////////////////////////
00055 void ImageTrans::
00056 run() {
00057   switch (_channels) {
00058   case C_default:
00059     break;
00060 
00061   case C_l:
00062   case C_la:
00063   case C_rgb:
00064   case C_rgba:
00065     _image.set_num_channels((int)_channels);
00066     break;
00067     
00068   case C_r:
00069     _image.make_grayscale(1.0, 0.0, 0.0);
00070     _image.remove_alpha();
00071     break;
00072 
00073   case C_g:
00074     _image.make_grayscale(0.0, 1.0, 0.0);
00075     _image.remove_alpha();
00076     break;
00077 
00078   case C_b:
00079     _image.make_grayscale(0.0, 0.0, 1.0);
00080     _image.remove_alpha();
00081     break;
00082 
00083   case C_a:
00084     extract_alpha();
00085     break;
00086   }
00087 
00088   if (_has_color_scale) {
00089     if (_color_scale[0] != 1.0f ||
00090         _color_scale[1] != 1.0f ||
00091         _color_scale[2] != 1.0f) {
00092       for (int yi = 0; yi < _image.get_y_size(); ++yi) {
00093         for (int xi = 0; xi < _image.get_x_size(); ++xi) {
00094           LRGBColord rgb = _image.get_xel(xi, yi);
00095           _image.set_xel(xi, yi, 
00096                          rgb[0] * _color_scale[0],
00097                          rgb[1] * _color_scale[1],
00098                          rgb[2] * _color_scale[2]);
00099         }
00100       }
00101     }
00102     if (_image.has_alpha() && _color_scale[3] != 1.0f) {
00103       for (int yi = 0; yi < _image.get_y_size(); ++yi) {
00104         for (int xi = 0; xi < _image.get_x_size(); ++xi) {
00105           PN_stdfloat a = _image.get_alpha(xi, yi);
00106           _image.set_alpha(xi, yi, a * _color_scale[3]);
00107         }
00108       }
00109     }
00110   }
00111 
00112   write_image();
00113 }
00114 
00115 ////////////////////////////////////////////////////////////////////
00116 //     Function: ImageTrans::dispatch_channels
00117 //       Access: Private, Static
00118 //  Description: Interprets the -chan parameter.
00119 ////////////////////////////////////////////////////////////////////
00120 bool ImageTrans::
00121 dispatch_channels(const string &opt, const string &arg, void *var) {
00122   Channels *ip = (Channels *)var;
00123   if (cmp_nocase(arg, "l") == 0) {
00124     (*ip) = C_l;
00125   } else if (cmp_nocase(arg, "la") == 0) {
00126     (*ip) = C_la;
00127   } else if (cmp_nocase(arg, "rgb") == 0) {
00128     (*ip) = C_rgb;
00129   } else if (cmp_nocase(arg, "rgba") == 0) {
00130     (*ip) = C_rgba;
00131   } else if (cmp_nocase(arg, "r") == 0) {
00132     (*ip) = C_r;
00133   } else if (cmp_nocase(arg, "g") == 0) {
00134     (*ip) = C_g;
00135   } else if (cmp_nocase(arg, "b") == 0) {
00136     (*ip) = C_b;
00137   } else if (cmp_nocase(arg, "a") == 0) {
00138     (*ip) = C_a;
00139   } else {
00140     int value;
00141     if (!string_to_int(arg, value)) {
00142       nout << "Invalid parameter for -" << opt << ": "
00143            << arg << "\n";
00144       return false;
00145     }
00146     if (value < 1 || value > 4) {
00147       nout << "Number of channels must be one of 1, 2, 3, or 4.\n";
00148       return false;
00149     }
00150     (*ip) = (Channels)value;
00151   }
00152 
00153   return true;
00154 }
00155 
00156 ////////////////////////////////////////////////////////////////////
00157 //     Function: ImageTrans::extract_alpha
00158 //       Access: Private
00159 //  Description: Extracts out just the alpha channel and stores it as
00160 //               a grayscale image.
00161 ////////////////////////////////////////////////////////////////////
00162 void ImageTrans::
00163 extract_alpha() {
00164   if (!_image.has_alpha()) {
00165     nout << "Source image does not have an alpha channel!\n";
00166     _image.make_grayscale();
00167     _image.fill();
00168     return;
00169   }
00170 
00171   _image.make_grayscale();
00172   for (int y = 0; y < _image.get_y_size(); y++) {
00173     for (int x = 0; x < _image.get_x_size(); x++) {
00174       _image.set_gray_val(x, y, _image.get_alpha_val(x, y));
00175     }
00176   }
00177   _image.remove_alpha();
00178 }
00179 
00180 
00181 int main(int argc, char *argv[]) {
00182   // A call to pystub() to force libpystub.so to be linked in.
00183   pystub();
00184 
00185   ImageTrans prog;
00186   prog.parse_command_line(argc, argv);
00187   prog.run();
00188   return 0;
00189 }
 All Classes Functions Variables Enumerations