00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "zcameraio.h"
00017
00018 #include <sys/types.h>
00019 #include <sys/stat.h>
00020 #include <errno.h>
00021 #include <string.h>
00022 #include <fcntl.h>
00023 #include <unistd.h>
00024 #include <stdio.h>
00025
00026 #include <qimage.h>
00027 #include <qdatetime.h>
00028
00029 #include <opie2/odebug.h>
00030
00031 #define SHARPZDC "/dev/sharp_zdc"
00032
00033 using namespace Opie::Core;
00034
00035 ZCameraIO* ZCameraIO::_instance = 0;
00036
00037 ZCameraIO* ZCameraIO::instance()
00038 {
00039 if ( !ZCameraIO::_instance )
00040 {
00041 odebug << "Creating ZCameraIO::_instance" << oendl;
00042 ZCameraIO::_instance = new ZCameraIO();
00043 }
00044 return ZCameraIO::_instance;
00045 }
00046
00047
00048 ZCameraIO::ZCameraIO()
00049 : _pressed( false ), _height( 0 ), _width( 0 ), _zoom( 0 ),
00050 _flip( -1 ), _rot( 0 ), _readlen( 0 )
00051
00052 {
00053 _driver = ::open( SHARPZDC, O_RDWR );
00054 if ( _driver == -1 )
00055 oerr << "Can't open camera driver: " << strerror(errno) << oendl;
00056 else
00057 init();
00058 }
00059
00060
00061 void ZCameraIO::init()
00062 {
00063 if ( ZCameraIO::_instance )
00064 ofatal << "Don't create more than one ZCameraIO instances." << oendl;
00065 else
00066 {
00067 _timer = new QTime();
00068 setReadMode( STATUS );
00069 }
00070 }
00071
00072
00073 ZCameraIO::~ZCameraIO()
00074 {
00075 if ( _driver != -1 )
00076 {
00077 setReadMode( 0 );
00078 ::close( _driver );
00079 }
00080 }
00081
00082
00083 bool ZCameraIO::isOpen() const
00084 {
00085 return _driver != -1;
00086 }
00087
00088
00089 bool ZCameraIO::isShutterPressed()
00090 {
00091 if ( _status[0] == 'S' )
00092 {
00093 if ( !_pressed )
00094 {
00095 _pressed = true;
00096 _timer->start();
00097 return true;
00098 }
00099
00100 if ( _timer->elapsed() > 2000 )
00101 {
00102 clearShutterLatch();
00103 _status[0] = 's';
00104 _pressed = false;
00105 }
00106 }
00107
00108 return false;
00109 }
00110
00111
00112 bool ZCameraIO::isFinderReversed() const
00113 {
00114 return _status[1] == 'M';
00115 }
00116
00117
00118 bool ZCameraIO::isCapturing() const
00119 {
00120 return _status[2] == 'C';
00121 }
00122
00123
00124 bool ZCameraIO::isAvailable() const
00125 {
00126 return _status[3] == 'A';
00127 }
00128
00129
00130 bool ZCameraIO::setCaptureFrame( int width, int height, int zoom, bool rot )
00131 {
00132 odebug << "setCaptureFrame( " << width << ", " << height << ", " << zoom << ", " << rot << " )" << oendl;
00133 char b[100];
00134 sprintf( b, "%c=%d,%d,%d,%d", rot ? 'R':'S', width, height, zoom, width*2 );
00135 if ( write( b ) )
00136 {
00137 _width = width;
00138 _height = height;
00139 _zoom = zoom;
00140 _rot = rot;
00141 _readlen = 2 * _width * _height;
00142 return true;
00143 }
00144 owarn << "couldn't write to driver" << oendl;
00145 return false;
00146 }
00147
00148
00149 bool ZCameraIO::setZoom( int zoom )
00150 {
00151 return setCaptureFrame( _width, _height, zoom*256, _rot );
00152 }
00153
00154
00155 void ZCameraIO::setReadMode( int mode )
00156 {
00157 char b[10];
00158 sprintf( b, "M=%d", mode );
00159 write( b, mode <= 9 ? 3 : 4 );
00160 if ( mode & STATUS )
00161 {
00162 read( _status, 4 );
00163 if ( isShutterPressed() )
00164 {
00165 emit shutterClicked();
00166 }
00167 }
00168 }
00169
00170
00171 void ZCameraIO::setFlip( int flip )
00172 {
00173 _flip = flip;
00174 }
00175
00176
00177 void ZCameraIO::clearShutterLatch()
00178 {
00179 write( "B", 1 );
00180 }
00181
00182
00183 bool ZCameraIO::read( char* b, int len )
00184 {
00185 #ifndef NO_TIMING
00186 QTime t;
00187 t.start();
00188 #endif
00189 int rlen = ::read( _driver, b, len );
00190 #ifndef NO_TIMING
00191 int time = t.elapsed();
00192 #else
00193 int time = -1;
00194 #endif
00195 if ( rlen )
00196 odebug << "read " << rlen << " ('" << b[0] << b[1] << b[2] << b[3] << "') [" << time << " ms] from driver." << oendl;
00197 else
00198 odebug << "read nothing from driver." << oendl;
00199 return rlen == len;
00200 }
00201
00202
00203 bool ZCameraIO::write( char* buf, int len )
00204 {
00205 if ( !len )
00206 len = strlen( buf );
00207
00208 odebug << "writing '" << buf << "' to driver." << oendl;
00209
00210 return ::write( _driver, buf, len ) == len;
00211 }
00212
00213
00214 bool ZCameraIO::snapshot( QImage* image )
00215 {
00216 setReadMode( STATUS );
00217
00218 odebug << "finder reversed = " << isFinderReversed() << oendl;
00219 odebug << "rotation = " << _rot << oendl;
00220
00221 odebug << "w=" << _width << " h= " << _height << " readlen= " << _readlen << oendl;
00222
00223 int readmode;
00224 if ( _flip == -1 )
00225 {
00226 if ( _rot )
00227 {
00228 readmode = IMAGE | isFinderReversed() ? XFLIP | YFLIP : 0;
00229 }
00230 else
00231 {
00232 readmode = IMAGE | XFLIP | YFLIP;
00233 }
00234 }
00235 else
00236 {
00237 readmode = IMAGE | _flip;
00238 }
00239
00240 setReadMode( readmode );
00241
00242 char buf[_readlen];
00243 char* bp = buf;
00244 unsigned char* p;
00245
00246 read( bp, _readlen );
00247
00248 image->create( _width, _height, 16 );
00249 for ( int i = 0; i < _height; ++i )
00250 {
00251 p = image->scanLine( i );
00252 for ( int j = 0; j < _width; j++ )
00253 {
00254 *p = *bp;
00255 p++;
00256 bp++;
00257 *p = *bp;
00258 p++;
00259 bp++;
00260 }
00261 }
00262
00263 return true;
00264 }
00265
00266
00267 bool ZCameraIO::snapshot( unsigned char* buf )
00268 {
00269 setReadMode( STATUS );
00270
00271 odebug << "finder reversed = " << isFinderReversed() << oendl;
00272 odebug << "rotation = " << _rot << oendl;
00273
00274 int readmode;
00275 if ( _flip == -1 )
00276 {
00277 if ( _rot )
00278 {
00279 readmode = IMAGE | isFinderReversed() ? XFLIP | YFLIP : 0;
00280 }
00281 else
00282 {
00283 readmode = IMAGE | XFLIP | YFLIP;
00284 }
00285 }
00286 else
00287 {
00288 readmode = IMAGE | _flip;
00289 }
00290
00291 setReadMode( readmode );
00292 read( (char*) buf, _readlen );
00293
00294 }
00295
00296
00297 void ZCameraIO::captureFrame( int w, int h, int zoom, QImage* image )
00298 {
00299 int prot = _rot;
00300 int pw = _width;
00301 int ph = _height;
00302 setCaptureFrame( w, h, zoom*256, w<h );
00303 snapshot( image );
00304 setCaptureFrame( pw, ph, _zoom, prot );
00305 }
00306
00307
00308 void ZCameraIO::captureFrame( int w, int h, int zoom, unsigned char* buf )
00309 {
00310
00311 int pw = _width;
00312 int ph = _height;
00313 setCaptureFrame( w, h, zoom*256, _rot );
00314 snapshot( buf );
00315 setCaptureFrame( pw, ph, _zoom, _rot );
00316 }
00317