Fawkes API Fawkes Development Version
|
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