#include <boost/shared_array.hpp>#include <errno.h>#include "image_v4linput.h"#include "colourspace.h"using namespace boost;using namespace std;namespace mimas {template<>void image_v4linput< rgba< unsigned char > >::read(image< rgba< unsigned char > > &img ) throw (mimasexception){// State-variable never becomes false. Input from video4linux only comes// to an end by an error.assert( state == true );shared_array< unsigned char > buffer;void *src = NULL;if ( map != MAP_FAILED ) {video_mmap vmap;vmap.frame = 0;vmap.width = win.width;vmap.height = win.height;vmap.format = pic.palette;MMERROR( xioctl( VIDIOCMCAPTURE, &vmap ) == 0, mimasexception, ,"Error initiating capture of image: " << strerror( errno ) );MMERROR( xioctl( VIDIOCSYNC, &vmap ) == 0, mimasexception, ,"Error on synchronising with capture of image: "<< strerror( errno ) );src = map;} else {int size;switch ( pic.palette ) {case VIDEO_PALETTE_RGB24:size = 3 * win.width * win.height;break;case VIDEO_PALETTE_YUV420P:size = win.width * win.height * 3 / 2;break;case VIDEO_PALETTE_UYVY:case VIDEO_PALETTE_YUV422:size = win.width * win.height * 2;break;default:assert( false );MMERROR( false, mimasexception, ,"Software error in colour-grabbing code. Encountered ""unsupported palette number " << pic.palette << "." );};buffer = shared_array< unsigned char >( new unsigned char[ size ] );src = (void *)buffer.get();MMERROR( ::read( fd, src, size ) != -1, mimasexception, ,"Error reading from device: " << strerror( errno ) );};img.init( win.width, win.height );#ifndef NDEBUGstd::cerr << img.rawData() << ' '<< img.getSize() << ' '<< img.getWidth() << ' ' << img.getHeight() << std::endl;#endifswitch ( pic.palette ) {case VIDEO_PALETTE_RGB24:rgb_to_rgba( (const char *)src, win.width, win.height,(char *)img.rawData() );break;case VIDEO_PALETTE_YUV420P:yuv420p_to_rgba( (const char *)src, win.width, win.height,(char *)img.rawData() );break;case VIDEO_PALETTE_UYVY:case VIDEO_PALETTE_YUV422:uyvy_to_rgba( (const char *)src, win.width, win.height,(char *)img.rawData() );break;default:assert( false );MMERROR( false, mimasexception, ,"Software error in colour-grabbing code. Encountered ""unsupported palette number " << pic.palette << "." );};}template<>void image_v4linput< rgba< unsigned char > >::selectPalette(void)throw(mimasexception){boost::array< __u16, 14 > palette;palette[ 0 ] = VIDEO_PALETTE_YUV420P;// ->RGBA supportedpalette[ 1 ] = VIDEO_PALETTE_UYVY;// ->RGBA supportedpalette[ 2 ] = VIDEO_PALETTE_YUV422;// -> RGBA supportedpalette[ 3 ] = VIDEO_PALETTE_RGB24;// ->RGBA supportedpalette[ 4 ] = VIDEO_PALETTE_HI240;palette[ 5 ] = VIDEO_PALETTE_RGB565;palette[ 6 ] = VIDEO_PALETTE_RGB555;palette[ 7 ] = VIDEO_PALETTE_RGB32;palette[ 8 ] = VIDEO_PALETTE_YUYV;palette[ 9 ] = VIDEO_PALETTE_YUV420;palette[ 10 ] = VIDEO_PALETTE_YUV411;palette[ 11 ] = VIDEO_PALETTE_RAW;palette[ 12 ] = VIDEO_PALETTE_YUV422P;palette[ 13 ] = VIDEO_PALETTE_YUV411P;pic.brightness = pic.hue = pic.colour = pic.contrast = pic.whiteness = 32767;pic.depth = 24;int selected = 0;while ( true ) {pic.palette = palette[ selected ];int r = xioctl( VIDIOCSPICT, &pic );if ( r == 0 ) {#ifndef NDEBUGstd::cerr << "Using " << ( selected + 1 ) << "th supported option."<< std::endl;#endifbreak;};selected++;MMERROR( selected < (signed)palette.size(),mimasexception, ,"Camera-driver doesn't offer a colour-video-palette known to ""mimas." );};MMERROR( selected < 4, mimasexception, ,"Colour-grabbing with video-palette "<< palette[ selected ] << " (kmando-index " << selected<< ") not supported by kmando. Please contact the developers." );}};