image_display.cpp

00001 
00002 /***************************************************************************
00003  *  image_display.cpp - widget to display an image based on SDL
00004  *
00005  *  Created: Mon Nov 05 14:19:26 2007
00006  *  Copyright  2007  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version. A runtime exception applies to
00014  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00022  */
00023 
00024 #include <fvwidgets/image_display.h>
00025 
00026 #include <fvwidgets/sdl_keeper.h>
00027 #include <SDL.h>
00028 
00029 #include <core/exception.h>
00030 #include <fvutils/color/conversions.h>
00031 #include <fvutils/color/yuv.h>
00032 
00033 using namespace fawkes;
00034 
00035 namespace firevision {
00036 #if 0 /* just to make Emacs auto-indent happy */
00037 }
00038 #endif
00039 
00040 /** @class ImageDisplay <fvwidgets/image_display.h>
00041  * Simple image display.
00042  * This is a simple thin wrapper around the SDL to display images in a standalone
00043  * window. Use this for instance for easy verification of vision results.
00044  * @author Tim Niemueller
00045  */
00046 
00047 /** Constructor.
00048  * @param width width of image
00049  * @param height height of image
00050  * @param title window title
00051  */
00052 ImageDisplay::ImageDisplay(unsigned int width, unsigned int height, const char* title)
00053 {
00054 
00055   SDLKeeper::init(SDL_INIT_VIDEO);
00056   if (title) SDL_WM_SetCaption (title, NULL);
00057 
00058   _width  = width;
00059   _height = height;
00060 
00061   int bpp = SDL_VideoModeOK(_width, _height, 16, SDL_ANYFORMAT);
00062   _surface = SDL_SetVideoMode(width, height, bpp, /* flags */ SDL_HWSURFACE | SDL_ANYFORMAT);
00063   if ( ! _surface ) {
00064     throw Exception("SDL: cannot create surface");
00065   }
00066 
00067   // SDL_UYVY_OVERLAY
00068   _overlay = SDL_CreateYUVOverlay(width, height, SDL_UYVY_OVERLAY, _surface);
00069   if ( ! _overlay ) {
00070     throw Exception("Cannot create overlay");
00071   }
00072 
00073   _rect = new SDL_Rect;
00074 
00075   _rect->x = 0;
00076   _rect->y = 0;
00077   _rect->w = _width;
00078   _rect->h = _height;
00079 }
00080 
00081 
00082 /** Destructor. */
00083 ImageDisplay::~ImageDisplay()
00084 {
00085   delete _rect;
00086 
00087   SDL_FreeYUVOverlay(_overlay);
00088   SDL_FreeSurface(_surface);
00089 
00090   SDLKeeper::quit();
00091 }
00092 
00093 
00094 /** Show image from given colorspace.
00095  * @param colorspace colorspace of the supplied buffer
00096  * @param buffer image buffer
00097  */
00098 void
00099 ImageDisplay::show(colorspace_t colorspace, unsigned char *buffer)
00100 {
00101   SDL_LockYUVOverlay(_overlay);
00102   convert(colorspace, YUV422_PACKED, buffer, _overlay->pixels[0], _width, _height);
00103   SDL_UnlockYUVOverlay(_overlay);
00104   SDL_DisplayYUVOverlay(_overlay, _rect);
00105 }
00106 
00107 
00108 /** Show image from YUV422_PLANAR colorspace.
00109  * @param yuv422_planar_buffer YUV422_PLANAR encoded image.
00110  */
00111 void
00112 ImageDisplay::show(unsigned char *yuv422_planar_buffer)
00113 {
00114   SDL_LockYUVOverlay(_overlay);
00115 
00116   yuv422planar_to_yuv422packed(yuv422_planar_buffer, _overlay->pixels[0],
00117                                _width, _height);
00118 
00119   SDL_UnlockYUVOverlay(_overlay);
00120   SDL_DisplayYUVOverlay(_overlay, _rect);
00121 }
00122 
00123 /** Process a few SDL events.
00124  * @param max_num_events maximum number of events to process.
00125  */
00126 void
00127 ImageDisplay::process_events(unsigned int max_num_events)
00128 {
00129   unsigned int proc = 0;
00130   SDL_Event event;
00131   while ( (proc++ < max_num_events) && (SDL_PollEvent(&event)) ) {
00132     // nothing to do here
00133   }
00134 }
00135 
00136 
00137 /** Process SDL events until quit.
00138  * Process SDL events and keeps the window responsive until either
00139  * the key "q" or "Esc" are pressed.
00140  */
00141 void
00142 ImageDisplay::loop_until_quit()
00143 {
00144   bool quit = false;
00145   while (! quit) {
00146     SDL_Event event;
00147     if ( SDL_WaitEvent(&event) ) {
00148       switch (event.type) {
00149       case SDL_QUIT:
00150         quit = true;
00151         break;
00152       case SDL_KEYUP:
00153         if ( (event.key.keysym.sym == SDLK_ESCAPE) ||
00154              (event.key.keysym.sym == SDLK_q) ) {
00155           quit = true;
00156         }
00157         break;
00158       }
00159     }
00160   }
00161 }
00162 
00163 } // end namespace firevision