00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef APPMEDIA_APP_IIV_C_DEFINED
00039 #define APPMEDIA_APP_IIV_C_DEFINED
00040
00041 #include "GUI/XWinManaged.H"
00042 #include "Image/ColorMap.H"
00043 #include "Image/ColorOps.H"
00044 #include "Image/Image.H"
00045 #include "Image/Pixels.H"
00046 #include "Image/ShapeOps.H"
00047 #include "Raster/GenericFrame.H"
00048 #include "Raster/Raster.H"
00049 #include "Util/log.H"
00050 #include "Util/sformat.H"
00051 #include "rutz/shared_ptr.h"
00052
00053 #include <X11/keysym.h>
00054 #include <iostream>
00055 #include <vector>
00056 #include <cstdio>
00057
00058 namespace
00059 {
00060 void usage(const char* argv0)
00061 {
00062 fprintf(stderr, "USAGE: %s [-d] [-geom WxH] [-w width] [-h height] [-crop l,t,r,b] [-cmapfile filename] imgfile1 [imgfile2 [imgfile3 ...]]\n", argv0);
00063 fprintf(stderr, " or: %s [-d] [-geom WxH] [-w width] [-h height] [-crop l,t,r,b] [-cmapfile filename] [-wait] -stdin-filenames\n", argv0);
00064 exit(1);
00065 }
00066
00067 Image<PixRGB<byte> > doRescale(const GenericFrame& in,
00068 const Rectangle& cropbox,
00069 const Dims& geom,
00070 const ColorMap& cmap)
00071 {
00072 Image<PixRGB<byte> > img =
00073 (cmap.initialized()
00074 && (in.nativeType() == GenericFrame::GRAY_U8
00075 || (in.nativeType() == GenericFrame::VIDEO
00076 && in.asVideo().getMode() == VIDFMT_GREY)))
00077 ? colorize(in.asGrayU8(), cmap)
00078 : in.asRgbU8();
00079
00080 if (cropbox.isValid())
00081 img = crop(img, cropbox.getOverlap(img.getBounds()));
00082
00083 const int w = img.getWidth();
00084 const int h = img.getHeight();
00085
00086 if (geom.w() != 0 && geom.h() != 0)
00087 return rescale(img, geom);
00088 else if (geom.w() != 0)
00089 return rescale(img,
00090 geom.w(),
00091 int(0.5 + geom.w() * double(h) / double(w)));
00092 else if (geom.h() != 0)
00093 return rescale(img,
00094 int(0.5 + geom.h() * double(w) / double(h)),
00095 geom.h());
00096
00097 return img;
00098 }
00099 }
00100
00101 int main(int argc, char** argv)
00102 {
00103 LOG_FLAGS &= ~LFATAL_PRINTS_ABORT;
00104 LOG_FLAGS &= ~LFATAL_THROWS;
00105
00106 MYLOGVERB = LOG_INFO;
00107
00108 if (argc == 1)
00109 {
00110 usage(argv[0]);
00111 }
00112
00113 std::vector<rutz::shared_ptr<XWinManaged> > windows;
00114
00115 bool wait = false;
00116 bool allowopts = true;
00117 Rectangle cropbox;
00118 Dims geom(0,0);
00119 ColorMap cmap;
00120
00121 for (int i = 1; i < argc; ++i)
00122 {
00123 if (allowopts && strcmp(argv[i], "-d") == 0)
00124 {
00125 MYLOGVERB = LOG_DEBUG;
00126 }
00127 else if (allowopts && strcmp(argv[i], "-crop") == 0)
00128 {
00129 ++i; if (i >= argc) usage(argv[0]);
00130 convertFromString(argv[i], cropbox);
00131 }
00132 else if (allowopts && strcmp(argv[i], "-geom") == 0)
00133 {
00134 ++i; if (i >= argc) usage(argv[0]);
00135 convertFromString(argv[i], geom);
00136 }
00137 else if (allowopts && strcmp(argv[i], "-w") == 0)
00138 {
00139 ++i; if (i >= argc) usage(argv[0]);
00140 geom = Dims(atoi(argv[i]), geom.h());
00141 }
00142 else if (allowopts && strcmp(argv[i], "-h") == 0)
00143 {
00144 ++i; if (i >= argc) usage(argv[0]);
00145 geom = Dims(geom.w(), atoi(argv[i]));
00146 }
00147 else if (allowopts && strcmp(argv[i], "-cmapfile") == 0)
00148 {
00149 ++i; if (i >= argc) usage(argv[0]);
00150 cmap = Raster::ReadRGB(argv[i]);
00151 }
00152 else if (allowopts && strcmp(argv[i], "-wait") == 0)
00153 {
00154
00155
00156 wait = true;
00157 }
00158 else if (allowopts && strcmp(argv[i], "--") == 0)
00159 {
00160 allowopts = false;
00161 }
00162 else if (allowopts && strcmp(argv[i], "-stdin-filenames") == 0)
00163 {
00164 std::string line;
00165 while (getline(std::cin, line))
00166 {
00167 if (line.empty())
00168 break;
00169
00170 const GenericFrame img = Raster::ReadFrame(line);
00171 const Image<PixRGB<byte> > rescaled =
00172 doRescale(img, cropbox, geom, cmap);
00173
00174 const int w = rescaled.getWidth();
00175 const int h = rescaled.getHeight();
00176 const std::string title = sformat("[%dx%d] %s", w, h, line.c_str());
00177
00178 if (windows.size() == 0)
00179 {
00180 rutz::shared_ptr<XWinManaged> win
00181 (new XWinManaged(rescaled, title.c_str()));
00182 windows.push_back(win);
00183 }
00184 else
00185 {
00186
00187 windows.back()->setDims(rescaled.getDims());
00188 windows.back()->drawImage(rescaled);
00189 windows.back()->setTitle(title.c_str());
00190 }
00191
00192 if (wait)
00193 {
00194 fprintf(stderr, "%s\n", line.c_str());
00195
00196
00197 while (windows.back()->getLastKeyPress() == -1)
00198 usleep(10000);
00199 }
00200 }
00201
00202
00203 return 0;
00204 }
00205 else
00206 {
00207 if (!Raster::fileExists(argv[i]))
00208 {
00209 if (allowopts)
00210 fprintf(stderr, "%s is neither a valid option "
00211 "nor a valid image filename\n", argv[i]);
00212 else
00213 fprintf(stderr, "%s is not a valid image filename\n",
00214 argv[i]);
00215 usage(argv[0]);
00216 }
00217
00218 const GenericFrame img = Raster::ReadFrame(argv[i]);
00219 const Image<PixRGB<byte> > rescaled =
00220 doRescale(img, cropbox, geom, cmap);
00221 const int w = rescaled.getWidth();
00222 const int h = rescaled.getHeight();
00223 const std::string title = sformat("[%dx%d] %s", w, h, argv[i]);
00224 rutz::shared_ptr<XWinManaged> win
00225 (new XWinManaged(rescaled, title.c_str()));
00226 windows.push_back(win);
00227 }
00228 }
00229
00230 if (windows.size() == 0)
00231 usage(argv[0]);
00232
00233 bool keepgoing = true;
00234
00235 while (keepgoing)
00236 {
00237 for (uint i = 0; i < windows.size(); ++i)
00238 {
00239 if (windows[i]->pressedCloseButton())
00240 { keepgoing = false; break; }
00241
00242 const KeySym sym = windows[i]->getLastKeySym();
00243
00244 if (sym == XK_Escape || sym == XK_Q || sym == XK_q)
00245 { keepgoing = false; break; }
00246 }
00247
00248 usleep(10000);
00249 }
00250
00251 return 0;
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261 #endif // APPMEDIA_APP_IIV_C_DEFINED