summaryrefslogtreecommitdiff
authormickeyl <mickeyl>2003-04-19 00:40:00 (UTC)
committer mickeyl <mickeyl>2003-04-19 00:40:00 (UTC)
commit724bb4ef15cd02a360e49de9c67847a19d5ca832 (patch) (side-by-side diff)
tree0fc5f2aab63c005aa2cfd36f7517547c0aa62e1d
parent6e7112a3610c4e562f991ba6d6f33ca2fe0c605d (diff)
downloadopie-724bb4ef15cd02a360e49de9c67847a19d5ca832.zip
opie-724bb4ef15cd02a360e49de9c67847a19d5ca832.tar.gz
opie-724bb4ef15cd02a360e49de9c67847a19d5ca832.tar.bz2
- fix shutter handling
- include manually overriding xflip and yflip - prepare video capturing mode - use caption to indicate current settings
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--noncore/multimedia/camera/camera.pro6
-rw-r--r--noncore/multimedia/camera/imageio.cpp55
-rw-r--r--noncore/multimedia/camera/imageio.h26
-rw-r--r--noncore/multimedia/camera/mainwindow.cpp190
-rw-r--r--noncore/multimedia/camera/mainwindow.h19
-rw-r--r--noncore/multimedia/camera/previewwidget.cpp14
-rw-r--r--noncore/multimedia/camera/previewwidget.h3
-rw-r--r--noncore/multimedia/camera/zcameraio.cpp92
-rw-r--r--noncore/multimedia/camera/zcameraio.h11
9 files changed, 388 insertions, 28 deletions
diff --git a/noncore/multimedia/camera/camera.pro b/noncore/multimedia/camera/camera.pro
index ffd5f37..8aedcea 100644
--- a/noncore/multimedia/camera/camera.pro
+++ b/noncore/multimedia/camera/camera.pro
@@ -6,3 +6,4 @@ CONFIG = qt warn_on debug
-HEADERS = zcameraio.h \
+HEADERS = imageio.h \
+ zcameraio.h \
previewwidget.h \
@@ -10,3 +11,4 @@ HEADERS = zcameraio.h \
-SOURCES = zcameraio.cpp \
+SOURCES = imageio.cpp \
+ zcameraio.cpp \
previewwidget.cpp \
diff --git a/noncore/multimedia/camera/imageio.cpp b/noncore/multimedia/camera/imageio.cpp
new file mode 100644
index 0000000..f8f5dd0
--- a/dev/null
+++ b/noncore/multimedia/camera/imageio.cpp
@@ -0,0 +1,55 @@
+/**********************************************************************
+** Copyright (C) 2002 Michael 'Mickey' Lauer. All rights reserved.
+**
+** This file is part of Opie Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+**********************************************************************/
+
+#include "imageio.h"
+
+#include <opie2/odebug.h>
+#include <qimage.h>
+
+
+void bufferToImage( int _width, int _height, unsigned char* bp, QImage* image )
+{
+ unsigned char* p;
+
+ image->create( _width, _height, 16 );
+ for ( int i = 0; i < _height; ++i )
+ {
+ p = image->scanLine( i );
+ for ( int j = 0; j < _width; j++ )
+ {
+ *p = *bp;
+ p++;
+ bp++;
+ *p = *bp;
+ p++;
+ bp++;
+ }
+ }
+}
+
+
+void imageToFile( QImage* i, const QString& name, const QString& format, int quality )
+{
+ QImage im = i->convertDepth( 32 );
+ bool result = im.save( name, format, quality );
+ if ( !result )
+ {
+ oerr << "imageio-Problem while writing." << oendl;
+ }
+ else
+ {
+ odebug << format << "-image has been successfully captured" << oendl;
+ }
+} \ No newline at end of file
diff --git a/noncore/multimedia/camera/imageio.h b/noncore/multimedia/camera/imageio.h
new file mode 100644
index 0000000..8dba2ed
--- a/dev/null
+++ b/noncore/multimedia/camera/imageio.h
@@ -0,0 +1,26 @@
+/**********************************************************************
+** Copyright (C) 2003 Michael 'Mickey' Lauer. All rights reserved.
+**
+** This file is part of Opie Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+**********************************************************************/
+
+#ifndef IMAGEIO_H
+#define IMAGEIO_H
+
+#include <qstring.h>
+
+class QImage;
+
+void bufferToImage( int _width, int height, unsigned char* bp, QImage* image );
+void imageToFile( QImage* i, const QString& name, const QString& format, int quality );
+
+#endif
diff --git a/noncore/multimedia/camera/mainwindow.cpp b/noncore/multimedia/camera/mainwindow.cpp
index 8e89039..6141fd1 100644
--- a/noncore/multimedia/camera/mainwindow.cpp
+++ b/noncore/multimedia/camera/mainwindow.cpp
@@ -18,2 +18,3 @@
#include "zcameraio.h"
+#include "imageio.h"
@@ -29,4 +30,6 @@
#include <qpopupmenu.h>
+#include <qprogressbar.h>
#include <qpushbutton.h>
#include <qmessagebox.h>
+#include <qlayout.h>
#include <qdirectpainter_qws.h>
@@ -38,3 +41,2 @@
using namespace Opie;
-
#include <opie2/odebug.h>
@@ -42,5 +44,13 @@ using namespace Opie;
#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#define CAPTUREFILE "/tmp/capture.dat"
CameraMainWindow::CameraMainWindow( QWidget * parent, const char * name, WFlags f )
- :QMainWindow( parent, name, f ), _pics( 0 )
+ :QMainWindow( parent, name, f ), _capturing( false ), _pics( 0 )
{
@@ -80,2 +90,5 @@ CameraMainWindow::CameraMainWindow( QWidget * parent, const char * name, WFlags
connect( ZCameraIO::instance(), SIGNAL( shutterClicked() ), this, SLOT( shutterClicked() ) );
+
+ updateCaption();
+
};
@@ -91,2 +104,3 @@ void CameraMainWindow::init()
// TODO: Save this stuff in config
+ flip = 'A'; // auto
quality = 50;
@@ -123,2 +137,10 @@ void CameraMainWindow::init()
+ flipg = new QActionGroup( 0, "flip", true );
+ flipg->setToggleAction( true );
+ ( new QAction( "Auto (recommended)", 0, 0, flipg, 0, true ) )->setOn( true );
+ new QAction( "0 (always off)", 0, 0, flipg, 0, true );
+ new QAction( "X (always horizontal)", 0, 0, flipg, 0, true );
+ new QAction( "Y (always vertical)", 0, 0, flipg, 0, true );
+ new QAction( "* (always both)", 0, 0, flipg, 0, true );
+
outputg = new QActionGroup( 0, "output", true );
@@ -128,2 +150,3 @@ void CameraMainWindow::init()
new QAction( "BMP", 0, 0, outputg, 0, true );
+ new QAction( "AVI", 0, 0, outputg, 0, true );
@@ -132,3 +155,5 @@ void CameraMainWindow::init()
connect( zoomg, SIGNAL( selected(QAction*) ), this, SLOT( zoomMenuItemClicked(QAction*) ) );
+ connect( flipg, SIGNAL( selected(QAction*) ), this, SLOT( flipMenuItemClicked(QAction*) ) );
connect( outputg, SIGNAL( selected(QAction*) ), this, SLOT( outputMenuItemClicked(QAction*) ) );
+
}
@@ -171,2 +196,3 @@ void CameraMainWindow::changeZoom( int zoom )
+
void CameraMainWindow::showContextMenu()
@@ -181,2 +207,6 @@ void CameraMainWindow::showContextMenu()
+ QPopupMenu flip;
+ flip.setCheckable( true );
+ flipg->addTo( &flip );
+
QPopupMenu zoom;
@@ -192,2 +222,3 @@ void CameraMainWindow::showContextMenu()
m.insertItem( "&Zoom", &zoom );
+ m.insertItem( "&Flip", &flip );
m.insertItem( "&Quality", &quality );
@@ -203,2 +234,3 @@ void CameraMainWindow::resoMenuItemClicked( QAction* a )
odebug << "Capture Resolution now: " << captureX << ", " << captureY << oendl;
+ updateCaption();
}
@@ -210,2 +242,3 @@ void CameraMainWindow::qualityMenuItemClicked( QAction* a )
odebug << "Quality now: " << quality << oendl;
+ updateCaption();
}
@@ -215,5 +248,25 @@ void CameraMainWindow::zoomMenuItemClicked( QAction* a )
{
- zoom = QString( a->text()[2] ).toInt();
+ zoom = QString( a->text().at(2) ).toInt();
odebug << "Zoom now: " << zoom << oendl;
ZCameraIO::instance()->setZoom( zoom );
+ updateCaption();
+}
+
+
+void CameraMainWindow::flipMenuItemClicked( QAction* a )
+{
+ flip = QString( a->text().at(0) );
+ odebug << "Flip now: " << flip << oendl;
+ if ( flip == "A" )
+ ZCameraIO::instance()->setFlip( ZCameraIO::AUTOMATICFLIP );
+ else if ( flip == "0" )
+ ZCameraIO::instance()->setFlip( ZCameraIO::XNOFLIP | ZCameraIO::YNOFLIP );
+ else if ( flip == "X" )
+ ZCameraIO::instance()->setFlip( ZCameraIO::XFLIP );
+ else if ( flip == "Y" )
+ ZCameraIO::instance()->setFlip( ZCameraIO::YFLIP );
+ else if ( flip == "*" )
+ ZCameraIO::instance()->setFlip( ZCameraIO::XFLIP | ZCameraIO::YFLIP );
+
+ updateCaption();
}
@@ -225,2 +278,3 @@ void CameraMainWindow::outputMenuItemClicked( QAction* a )
odebug << "Output format now: " << captureFormat << oendl;
+ updateCaption();
}
@@ -230,2 +284,4 @@ void CameraMainWindow::shutterClicked()
{
+ if ( captureFormat != "AVI" ) // capture one photo per shutterClick
+ {
Global::statusMessage( "CAPTURING..." );
@@ -235,2 +291,14 @@ void CameraMainWindow::shutterClicked()
ODevice::inst()->touchSound();
+
+ performCapture( captureFormat );
+ }
+ else // capture video! start with one shutter click and stop with the next
+ {
+ !_capturing ? startVideoCapture() : stopVideoCapture();
+ }
+}
+
+
+void CameraMainWindow::performCapture( const QString& format )
+{
QString name;
@@ -240,3 +308,3 @@ void CameraMainWindow::shutterClicked()
QImage im = i.convertDepth( 32 );
- bool result = im.save( name, captureFormat, quality );
+ bool result = im.save( name, format, quality );
if ( !result )
@@ -253 +321,115 @@ void CameraMainWindow::shutterClicked()
+
+void CameraMainWindow::startVideoCapture()
+{
+ //ODevice::inst()->touchSound();
+ ODevice::inst()->setLedState( Led_Mail, Led_BlinkSlow );
+
+ _capturefd = ::open( CAPTUREFILE, O_WRONLY | O_CREAT );
+ if ( _capturefd == -1 )
+ {
+ owarn << "can't open capture file: " << strerror(errno) << oendl;
+ return;
+ }
+
+ _capturebuf = new unsigned char[captureX*captureY*2];
+ _capturing = true;
+ _videopics = 0;
+ updateCaption();
+ _time.start();
+ preview->setRefreshingRate( 1000 );
+ startTimer( 100 ); // too fast but that is ok
+}
+
+
+void CameraMainWindow::timerEvent( QTimerEvent* )
+{
+ if ( !_capturing )
+ {
+ owarn << "timer event in CameraMainWindow without capturing video ?" << oendl;
+ return;
+ }
+
+ ZCameraIO::instance()->captureFrame( captureX, captureY, zoom, _capturebuf );
+ _videopics++;
+ ::write( _capturefd, _capturebuf, captureX*captureY*2 );
+ setCaption( QString().sprintf( "Capturing %dx%d @ %.2f fps %d",
+ captureX, captureY, 1000.0 / (_time.elapsed()/_videopics), _videopics ) );
+}
+
+
+void CameraMainWindow::stopVideoCapture()
+{
+ killTimers();
+ //ODevice::inst()->touchSound();
+ ODevice::inst()->setLedState( Led_Mail, Led_Off );
+ _capturing = false;
+ updateCaption();
+ ::close( _capturefd );
+
+ //postProcessVideo();
+
+ #ifndef QT_NO_DEBUG
+ preview->setRefreshingRate( 1500 );
+ #else
+ preview->setRefreshingRate( 200 );
+ #endif
+
+ //delete[] _capturebuf; //FIXME: close memory leak
+}
+
+void CameraMainWindow::postProcessVideo()
+{
+ preview->setRefreshingRate( 0 );
+
+ /*
+
+ QDialog* fr = new QDialog( this, "splash" ); //, false, QWidget::WStyle_NoBorder | QWidget::WStyle_Customize );
+ fr->setCaption( "Please wait..." );
+ QVBoxLayout* box = new QVBoxLayout( fr, 2, 2 );
+ QProgressBar* bar = new QProgressBar( fr );
+ bar->setCenterIndicator( true );
+ bar->setTotalSteps( _videopics-1 );
+ QLabel* label = new QLabel( "Post processing frame bla/bla", fr );
+ box->addWidget( bar );
+ box->addWidget( label );
+ fr->show();
+ qApp->processEvents();
+
+ for ( int i = 0; i < _videopics; ++i )
+ {
+ label->setText( QString().sprintf( "Post processing frame %d / %d", i+1, _videopics ) );
+ bar->setProgress( i );
+ qApp->processEvents();
+ }
+
+ */
+
+ int infd = ::open( CAPTUREFILE, O_RDONLY );
+ if ( infd == -1 )
+ {
+ owarn << "couldn't open capture file: " << strerror(errno) << oendl;
+ return;
+ }
+
+ int outfd = ::open( "/tmp/output.avi", O_WRONLY );
+ if ( outfd == -1 )
+ {
+ owarn << "couldn't open output file: " << strerror(errno) << oendl;
+ return;
+ }
+
+
+
+
+}
+
+void CameraMainWindow::updateCaption()
+{
+ if ( !_capturing )
+ setCaption( QString().sprintf( "Opie-Camera: %dx%d %s q%d z%d (%s)", captureX, captureY, (const char*) captureFormat.lower(), quality, zoom, (const char*) flip ) );
+ else
+ setCaption( "Opie-Camera: => CAPTURING <=" );
+}
+
+
diff --git a/noncore/multimedia/camera/mainwindow.h b/noncore/multimedia/camera/mainwindow.h
index 7a12452..ad8d1b1 100644
--- a/noncore/multimedia/camera/mainwindow.h
+++ b/noncore/multimedia/camera/mainwindow.h
@@ -22,2 +22,3 @@
#include <qpixmap.h>
+#include <qdatetime.h>
@@ -26,2 +27,3 @@ class QActionGroup;
class QIconSet;
+class QTimerEvent;
class QToolButton;
@@ -47,2 +49,3 @@ class CameraMainWindow: public QMainWindow
void zoomMenuItemClicked( QAction* );
+ void flipMenuItemClicked( QAction* );
void outputMenuItemClicked( QAction* );
@@ -50,4 +53,12 @@ class CameraMainWindow: public QMainWindow
+ void updateCaption();
+
protected:
void init();
+ void startVideoCapture();
+ void stopVideoCapture();
+ void postProcessVideo();
+ void performCapture( const QString& );
+
+ virtual void timerEvent( QTimerEvent* );
@@ -61,4 +72,6 @@ class CameraMainWindow: public QMainWindow
QActionGroup* zoomg;
+ QActionGroup* flipg;
QActionGroup* outputg;
+ QString flip;
int quality;
@@ -69,3 +82,9 @@ class CameraMainWindow: public QMainWindow
+ bool _capturing;
int _pics;
+
+ QTime _time;
+ int _videopics;
+ int _capturefd;
+ unsigned char* _capturebuf;
};
diff --git a/noncore/multimedia/camera/previewwidget.cpp b/noncore/multimedia/camera/previewwidget.cpp
index f87dcc9..08330d0 100644
--- a/noncore/multimedia/camera/previewwidget.cpp
+++ b/noncore/multimedia/camera/previewwidget.cpp
@@ -74 +74,15 @@ void PreviewWidget::mousePressEvent( QMouseEvent* )
+
+void PreviewWidget::setRefreshingRate( int ms )
+{
+ killTimers();
+ if ( ms )
+ startTimer( ms );
+}
+
+
+void PreviewWidget::refresh()
+{
+ QTimerEvent t( 10 ); // event id is meaningless in this case
+ timerEvent( &t );
+}
diff --git a/noncore/multimedia/camera/previewwidget.h b/noncore/multimedia/camera/previewwidget.h
index dada301..d37f80f 100644
--- a/noncore/multimedia/camera/previewwidget.h
+++ b/noncore/multimedia/camera/previewwidget.h
@@ -33,2 +33,5 @@ class PreviewWidget: public QLabel
+ void setRefreshingRate( int ms );
+ void refresh();
+
protected:
diff --git a/noncore/multimedia/camera/zcameraio.cpp b/noncore/multimedia/camera/zcameraio.cpp
index 9af0c25..1c449e7 100644
--- a/noncore/multimedia/camera/zcameraio.cpp
+++ b/noncore/multimedia/camera/zcameraio.cpp
@@ -46,3 +46,5 @@ ZCameraIO* ZCameraIO::instance()
ZCameraIO::ZCameraIO()
- :_height( 0 ), _width( 0 ), _zoom( 0 ), _rot( 0 ), _readlen( 0 )
+ : _pressed( false ), _height( 0 ), _width( 0 ), _zoom( 0 ),
+ _flip( -1 ), _rot( 0 ), _readlen( 0 )
+
{
@@ -86,14 +88,20 @@ bool ZCameraIO::isShutterPressed()
{
- if ( _timer->elapsed() < 1000 ) //TODO: make this customizable?
+ if ( _status[0] == 'S' )
{
- clearShutterLatch();
- return false;
+ if ( !_pressed ) // wasn't pressed before, but is now!
+ {
+ _pressed = true;
+ _timer->start();
+ return true;
}
- if ( _status[0] == 'S' )
+
+ if ( _timer->elapsed() > 2000 ) // the press is pretty old now
{
- _timer->restart();
clearShutterLatch();
- return true;
+ _status[0] = 's';
+ _pressed = false;
+ }
}
- else return false;
+
+ return false;
}
@@ -151,5 +159,14 @@ void ZCameraIO::setReadMode( int mode )
read( _status, 4 );
- if ( isShutterPressed() ) emit shutterClicked();
+ if ( isShutterPressed() )
+ {
+ emit shutterClicked();
}
}
+}
+
+
+void ZCameraIO::setFlip( int flip )
+{
+ _flip = flip;
+}
@@ -200,5 +217,8 @@ bool ZCameraIO::snapshot( QImage* image )
+ int readmode;
+ if ( _flip == -1 ) // AUTO
+ {
if ( _rot ) // Portrait
{
- setReadMode( IMAGE | isFinderReversed() ? XFLIP | YFLIP : 0 );
+ readmode = IMAGE | isFinderReversed() ? XFLIP | YFLIP : 0;
}
@@ -206,5 +226,12 @@ bool ZCameraIO::snapshot( QImage* image )
{
- setReadMode( IMAGE | XFLIP | YFLIP ); //isFinderReversed() ? 0 : XFLIP );
+ readmode = IMAGE | XFLIP | YFLIP;
+ }
+ }
+ else // OVERRIDE
+ {
+ readmode = IMAGE | _flip;
}
+ setReadMode( readmode );
+
char buf[_readlen];
@@ -236,14 +263,27 @@ bool ZCameraIO::snapshot( unsigned char* buf )
{
- setReadMode( IMAGE | XFLIP | YFLIP );
+ setReadMode( STATUS );
- read( (char*) buf, _readlen );
+ odebug << "finder reversed = " << isFinderReversed() << oendl;
+ odebug << "rotation = " << _rot << oendl;
- /* //TESTCODE
- int fd = open( "/tmp/cam", O_RDONLY );
- if ( ::read( fd, (char*) buf, 76800 ) != 76800 )
- owarn << "Couldn't read image from /dev/sharp_zdc" << oendl;
- // TESTCODE */
+ int readmode;
+ if ( _flip == -1 ) // AUTO
+ {
+ if ( _rot ) // Portrait
+ {
+ readmode = IMAGE | isFinderReversed() ? XFLIP | YFLIP : 0;
+ }
+ else // Landscape
+ {
+ readmode = IMAGE | XFLIP | YFLIP;
+ }
+ }
+ else // OVERRIDE
+ {
+ readmode = IMAGE | _flip;
+ }
+ setReadMode( readmode );
+ read( (char*) buf, _readlen );
- return true;
}
@@ -264 +304,15 @@ void ZCameraIO::captureFrame( int w, int h, int zoom, QImage* image )
+void ZCameraIO::captureFrame( int w, int h, int zoom, unsigned char* buf )
+{
+ //FIXME: this is too slow
+ int pw = _width;
+ int ph = _height;
+ if ( _rot )
+ setCaptureFrame( h, w, zoom*256, true );
+ else
+ setCaptureFrame( w, h, zoom*256, false );
+
+ snapshot( buf );
+ setCaptureFrame( pw, ph, _zoom, _rot );
+}
+
diff --git a/noncore/multimedia/camera/zcameraio.h b/noncore/multimedia/camera/zcameraio.h
index edce143..3352a5e 100644
--- a/noncore/multimedia/camera/zcameraio.h
+++ b/noncore/multimedia/camera/zcameraio.h
@@ -35,3 +35,4 @@ class ZCameraIO : public QObject
XNOFLIP = 0, XFLIP = 4,
- YNOFLIP = 0, YFLIP = 8
+ YNOFLIP = 0, YFLIP = 8,
+ AUTOMATICFLIP = -1
};
@@ -43,2 +44,3 @@ class ZCameraIO : public QObject
void setReadMode( int = IMAGE | XFLIP | YFLIP );
+ void setFlip( int flip );
@@ -49,4 +51,4 @@ class ZCameraIO : public QObject
- bool snapshot( unsigned char* );
- bool snapshot( QImage* );
+ bool snapshot( QImage* image );
+ bool snapshot( unsigned char* buf );
@@ -56,2 +58,3 @@ class ZCameraIO : public QObject
void captureFrame( int w, int h, int zoom, QImage* image );
+ void captureFrame( int w, int h, int zoom, unsigned char* buf );
@@ -70,2 +73,3 @@ class ZCameraIO : public QObject
char _status[4];
+ bool _pressed;
static ZCameraIO* _instance;
@@ -74,2 +78,3 @@ class ZCameraIO : public QObject
int _zoom;
+ int _flip;
bool _rot;