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) (ignore 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.cpp198
-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.cpp100
-rw-r--r--noncore/multimedia/camera/zcameraio.h11
9 files changed, 396 insertions, 36 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
@@ -1,23 +1,25 @@
MOC_DIR = ./moc
OBJECTS_DIR = ./obj
DESTDIR = $(OPIEDIR)/bin
TEMPLATE = app
CONFIG = qt warn_on debug
-HEADERS = zcameraio.h \
+HEADERS = imageio.h \
+ zcameraio.h \
previewwidget.h \
mainwindow.h
-SOURCES = zcameraio.cpp \
+SOURCES = imageio.cpp \
+ zcameraio.cpp \
previewwidget.cpp \
mainwindow.cpp \
main.cpp
INCLUDEPATH += $(OPIEDIR)/include
DEPENDPATH += $(OPIEDIR)/include
LIBS += -lqpe -lopie -lopiecore2
INTERFACES =
TARGET = opiecam
include ( $(OPIEDIR)/include.pro )
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
@@ -1,253 +1,435 @@
/**********************************************************************
** 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 "mainwindow.h"
#include "previewwidget.h"
#include "zcameraio.h"
+#include "imageio.h"
#include <qapplication.h>
#include <qaction.h>
#include <qvbox.h>
#include <qcombobox.h>
#include <qcursor.h>
#include <qdatastream.h>
#include <qfile.h>
#include <qimage.h>
#include <qlabel.h>
#include <qpopupmenu.h>
+#include <qprogressbar.h>
#include <qpushbutton.h>
#include <qmessagebox.h>
+#include <qlayout.h>
#include <qdirectpainter_qws.h>
#include <qpe/global.h>
#include <qpe/resource.h>
#include <qpe/qcopenvelope_qws.h>
#include <opie/ofiledialog.h>
#include <opie/odevice.h>
using namespace Opie;
-
#include <opie2/odebug.h>
#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 )
{
#ifdef QT_NO_DEBUG
if ( !ZCameraIO::instance()->isOpen() )
{
QVBox* v = new QVBox( this );
v->setMargin( 10 );
QLabel* l1 = new QLabel( v );
l1->setPixmap( Resource::loadPixmap( "camera/error" ) );
QLabel* l2 = new QLabel( v );
l2->setText( "<b>Sorry. could not detect your camera :-(</b><p>"
"* Is the sharpzdc_cs module loaded ?<br>"
"* Is /dev/sharpzdc read/writable ?<p>" );
connect( new QPushButton( "Exit", v ), SIGNAL( clicked() ), this, SLOT( close() ) );
setCentralWidget( v );
return;
}
#endif
init();
_rotation = 270; //TODO: grab these from the actual settings
preview = new PreviewWidget( this, "camera preview widget" );
//setCentralWidget( preview ); <--- don't do this!
preview->resize( QSize( 240, 288 ) );
preview->show();
// construct a System Channel to receive setRotation messages
_sysChannel = new QCopChannel( "QPE/System", this );
connect( _sysChannel, SIGNAL( received( const QCString&, const QByteArray& ) ),
this, SLOT( systemMessage( const QCString&, const QByteArray& ) ) );
connect( preview, SIGNAL( contextMenuRequested() ), this, SLOT( showContextMenu() ) );
connect( ZCameraIO::instance(), SIGNAL( shutterClicked() ), this, SLOT( shutterClicked() ) );
+
+ updateCaption();
+
};
CameraMainWindow::~CameraMainWindow()
{
}
void CameraMainWindow::init()
{
// TODO: Save this stuff in config
+ flip = 'A'; // auto
quality = 50;
zoom = 1;
captureX = 640;
captureY = 480;
captureFormat = "JPEG";
resog = new QActionGroup( 0, "reso", true );
resog->setToggleAction( true );
new QAction( " 64 x 48", 0, 0, resog, 0, true );
new QAction( "128 x 96", 0, 0, resog, 0, true );
new QAction( "192 x 144", 0, 0, resog, 0, true );
new QAction( "256 x 192", 0, 0, resog, 0, true );
new QAction( "320 x 240", 0, 0, resog, 0, true );
new QAction( "384 x 288", 0, 0, resog, 0, true );
new QAction( "448 x 336", 0, 0, resog, 0, true );
new QAction( "512 x 384", 0, 0, resog, 0, true );
new QAction( "576 x 432", 0, 0, resog, 0, true );
( new QAction( "640 x 480", 0, 0, resog, 0, true ) )->setOn( true );
qualityg = new QActionGroup( 0, "quality", true );
qualityg->setToggleAction( true );
new QAction( " 0 (minimal)", 0, 0, qualityg, 0, true );
new QAction( " 25 (low)", 0, 0, qualityg, 0, true );
( new QAction( " 50 (good)", 0, 0, qualityg, 0, true ) )->setOn( true );
new QAction( " 75 (better)", 0, 0, qualityg, 0, true );
new QAction( "100 (best)", 0, 0, qualityg, 0, true );
zoomg = new QActionGroup( 0, "zoom", true );
zoomg->setToggleAction( true );
( new QAction( "x 1", 0, 0, zoomg, 0, true ) )->setOn( true );
new QAction( "x 2", 0, 0, zoomg, 0, true );
+ 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 );
outputg->setToggleAction( true );
( new QAction( "JPEG", 0, 0, outputg, 0, true ) )->setOn( true );
new QAction( "PNG", 0, 0, outputg, 0, true );
new QAction( "BMP", 0, 0, outputg, 0, true );
+ new QAction( "AVI", 0, 0, outputg, 0, true );
connect( resog, SIGNAL( selected(QAction*) ), this, SLOT( resoMenuItemClicked(QAction*) ) );
connect( qualityg, SIGNAL( selected(QAction*) ), this, SLOT( qualityMenuItemClicked(QAction*) ) );
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*) ) );
+
}
void CameraMainWindow::systemMessage( const QCString& msg, const QByteArray& data )
{
QDataStream stream( data, IO_ReadOnly );
odebug << "received system message: " << msg << oendl;
if ( msg == "setCurrentRotation(int)" )
{
stream >> _rotation;
odebug << "received setCurrentRotation(" << _rotation << ")" << oendl;
switch ( _rotation )
{
case 270: preview->resize( QSize( 240, 288 ) ); break;
case 180: preview->resize( QSize( 320, 208 ) ); break;
default: QMessageBox::warning( this, "opie-camera",
"This rotation is not supported.\n"
"Supported are 180° and 270°" );
}
}
}
void CameraMainWindow::changeZoom( int zoom )
{
int z;
switch ( zoom )
{
case 0: z = 128; break;
case 1: z = 256; break;
case 2: z = 512; break;
default: assert( 0 ); break;
}
ZCameraIO::instance()->setCaptureFrame( 240, 160, z );
}
+
void CameraMainWindow::showContextMenu()
{
QPopupMenu reso;
reso.setCheckable( true );
resog->addTo( &reso );
QPopupMenu quality;
quality.setCheckable( true );
qualityg->addTo( &quality );
+ QPopupMenu flip;
+ flip.setCheckable( true );
+ flipg->addTo( &flip );
+
QPopupMenu zoom;
zoom.setCheckable( true );
zoomg->addTo( &zoom );
QPopupMenu output;
output.setCheckable( true );
outputg->addTo( &output );
QPopupMenu m( this );
m.insertItem( "&Resolution", &reso );
m.insertItem( "&Zoom", &zoom );
+ m.insertItem( "&Flip", &flip );
m.insertItem( "&Quality", &quality );
m.insertItem( "&Output As", &output );
m.exec( QCursor::pos() );
}
void CameraMainWindow::resoMenuItemClicked( QAction* a )
{
captureX = a->text().left(3).toInt();
captureY = a->text().right(3).toInt();
odebug << "Capture Resolution now: " << captureX << ", " << captureY << oendl;
+ updateCaption();
}
void CameraMainWindow::qualityMenuItemClicked( QAction* a )
{
quality = a->text().left(3).toInt();
odebug << "Quality now: " << quality << oendl;
+ updateCaption();
}
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();
}
void CameraMainWindow::outputMenuItemClicked( QAction* a )
{
captureFormat = a->text();
odebug << "Output format now: " << captureFormat << oendl;
+ updateCaption();
}
void CameraMainWindow::shutterClicked()
{
- Global::statusMessage( "CAPTURING..." );
- qApp->processEvents();
+ if ( captureFormat != "AVI" ) // capture one photo per shutterClick
+ {
+ Global::statusMessage( "CAPTURING..." );
+ qApp->processEvents();
- odebug << "Shutter has been pressed" << oendl;
- ODevice::inst()->touchSound();
+ odebug << "Shutter has been pressed" << oendl;
+ 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;
name.sprintf( "/tmp/image-%d_%d_%d_q%d.%s", _pics++, captureX, captureY, quality, (const char*) captureFormat.lower() );
QImage i;
ZCameraIO::instance()->captureFrame( captureX, captureY, zoom, &i );
QImage im = i.convertDepth( 32 );
- bool result = im.save( name, captureFormat, quality );
+ bool result = im.save( name, format, quality );
if ( !result )
{
oerr << "imageio-Problem while writing." << oendl;
Global::statusMessage( "Error!" );
}
else
{
odebug << captureFormat << "-image has been successfully captured" << oendl;
Global::statusMessage( "Ok." );
}
}
+
+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
@@ -1,73 +1,92 @@
/**********************************************************************
** 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 MAINWINDOW_H
#define MAINWINDOW_H
#include <qmainwindow.h>
#include <qdatetime.h>
#include <qimage.h>
#include <qpixmap.h>
+#include <qdatetime.h>
class QAction;
class QActionGroup;
class QIconSet;
+class QTimerEvent;
class QToolButton;
class QLabel;
class MainWindowBase;
class QCopChannel;
class PreviewWidget;
class CameraMainWindow: public QMainWindow
{
Q_OBJECT
public:
CameraMainWindow( QWidget * parent = 0, const char * name = "mainwindow", WFlags f = 0 );
virtual ~CameraMainWindow();
public slots:
void changeZoom( int );
void systemMessage( const QCString&, const QByteArray& );
void showContextMenu();
void resoMenuItemClicked( QAction* );
void qualityMenuItemClicked( QAction* );
void zoomMenuItemClicked( QAction* );
+ void flipMenuItemClicked( QAction* );
void outputMenuItemClicked( QAction* );
void shutterClicked();
+ void updateCaption();
+
protected:
void init();
+ void startVideoCapture();
+ void stopVideoCapture();
+ void postProcessVideo();
+ void performCapture( const QString& );
+
+ virtual void timerEvent( QTimerEvent* );
private:
PreviewWidget* preview;
int _rotation;
QCopChannel* _sysChannel;
QActionGroup* resog;
QActionGroup* qualityg;
QActionGroup* zoomg;
+ QActionGroup* flipg;
QActionGroup* outputg;
+ QString flip;
int quality;
int zoom;
int captureX;
int captureY;
QString captureFormat;
+ bool _capturing;
int _pics;
+
+ QTime _time;
+ int _videopics;
+ int _capturefd;
+ unsigned char* _capturebuf;
};
#endif
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
@@ -1,74 +1,88 @@
/**********************************************************************
** 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 "previewwidget.h"
#include "zcameraio.h"
#include <opie2/odebug.h>
#include <assert.h>
PreviewWidget::PreviewWidget( QWidget * parent, const char * name, WFlags f )
:QLabel( parent, name, f )
{
#ifndef QT_NO_DEBUG
setBackgroundColor( QColor( 255, 0, 0 ) );
#else
setBackgroundMode( NoBackground );
#endif
#ifndef QT_NO_DEBUG
if ( ZCameraIO::instance()->isOpen() ) startTimer( 1500 );
#else
if ( ZCameraIO::instance()->isOpen() ) startTimer( 200 );
#endif
};
PreviewWidget::~PreviewWidget()
{
}
void PreviewWidget::resizeEvent( QResizeEvent* e )
{
QLabel::resizeEvent( e );
int w = e->size().width();
int h = e->size().height();
ZCameraIO::instance()->setCaptureFrame( e->size().width(),
e->size().height(),
256,
w < h );
}
void PreviewWidget::timerEvent( QTimerEvent* )
{
//QDirectPainter fb( this );
//ZCameraIO::instance()->snapshot( fb.frameBuffer() );
if ( ZCameraIO::instance()->snapshot( &i ) )
{
p.convertFromImage( i );
setPixmap( p );
}
}
void PreviewWidget::mousePressEvent( QMouseEvent* )
{
emit contextMenuRequested();
}
+
+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
@@ -1,47 +1,50 @@
/**********************************************************************
** 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 PREVIEWWIDGET_H
#define PREVIEWWIDGET_H
#include <qlabel.h>
#include <qimage.h>
#include <qpixmap.h>
class QTimerEvent;
class QResizeEvent;
class PreviewWidget: public QLabel
{
Q_OBJECT
public:
PreviewWidget( QWidget * parent = 0, const char * name = 0, WFlags f = 0 );
virtual ~PreviewWidget();
+ void setRefreshingRate( int ms );
+ void refresh();
+
protected:
virtual void timerEvent( QTimerEvent* );
virtual void resizeEvent( QResizeEvent* );
virtual void mousePressEvent( QMouseEvent* );
signals:
void contextMenuRequested();
private:
QPixmap p;
QImage i;
};
#endif
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
@@ -1,264 +1,318 @@
/**********************************************************************
** 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 "zcameraio.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <qimage.h>
#include <qdatetime.h>
#include <opie2/odebug.h>
#define SHARPZDC "/dev/sharp_zdc"
ZCameraIO* ZCameraIO::_instance = 0;
ZCameraIO* ZCameraIO::instance()
{
if ( !ZCameraIO::_instance )
{
odebug << "Creating ZCameraIO::_instance" << oendl;
ZCameraIO::_instance = new ZCameraIO();
}
return 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 )
+
{
_driver = ::open( SHARPZDC, O_RDWR );
if ( _driver == -1 )
oerr << "Can't open camera driver: " << strerror(errno) << oendl;
else
init();
}
void ZCameraIO::init()
{
if ( ZCameraIO::_instance )
ofatal << "Don't create more than one ZCameraIO instances." << oendl;
else
{
_timer = new QTime();
setReadMode( STATUS );
}
}
ZCameraIO::~ZCameraIO()
{
if ( _driver != -1 )
{
setReadMode( 0 );
::close( _driver );
}
}
bool ZCameraIO::isOpen() const
{
return _driver != -1;
}
bool ZCameraIO::isShutterPressed()
{
- if ( _timer->elapsed() < 1000 ) //TODO: make this customizable?
- {
- clearShutterLatch();
- return false;
- }
if ( _status[0] == 'S' )
{
- _timer->restart();
- clearShutterLatch();
- return true;
+ if ( !_pressed ) // wasn't pressed before, but is now!
+ {
+ _pressed = true;
+ _timer->start();
+ return true;
+ }
+
+ if ( _timer->elapsed() > 2000 ) // the press is pretty old now
+ {
+ clearShutterLatch();
+ _status[0] = 's';
+ _pressed = false;
+ }
}
- else return false;
+
+ return false;
}
bool ZCameraIO::isFinderReversed() const
{
return _status[1] == 'M';
}
bool ZCameraIO::isCapturing() const
{
return _status[2] == 'C';
}
bool ZCameraIO::isAvailable() const
{
return _status[3] == 'A';
}
bool ZCameraIO::setCaptureFrame( int width, int height, int zoom, bool rot )
{
odebug << "setCaptureFrame( " << width << ", " << height << ", " << zoom << ", " << rot << " )" << oendl;
char b[100];
sprintf( b, "%c=%d,%d,%d,%d", rot ? 'R':'S', width, height, zoom, width*2 );
if ( write( b ) )
{
_width = width;
_height = height;
_zoom = zoom;
_rot = rot;
_readlen = 2 * _width * _height; // camera is fixed @ 16 bits per pixel
return true;
}
return false;
}
bool ZCameraIO::setZoom( int zoom )
{
return setCaptureFrame( _width, _height, zoom*256, _rot );
}
void ZCameraIO::setReadMode( int mode )
{
char b[10];
sprintf( b, "M=%d", mode );
write( b, mode <= 9 ? 3 : 4 );
if ( mode & STATUS ) // STATUS bit is set
{
read( _status, 4 );
- if ( isShutterPressed() ) emit shutterClicked();
+ if ( isShutterPressed() )
+ {
+ emit shutterClicked();
+ }
}
}
+void ZCameraIO::setFlip( int flip )
+{
+ _flip = flip;
+}
+
+
void ZCameraIO::clearShutterLatch()
{
write( "B", 1 );
}
bool ZCameraIO::read( char* b, int len )
{
#ifndef NO_TIMING
QTime t;
t.start();
#endif
int rlen = ::read( _driver, b, len );
#ifndef NO_TIMING
int time = t.elapsed();
#else
int time = -1;
#endif
if ( rlen )
odebug << "read " << rlen << " ('" << b[0] << b[1] << b[2] << b[3] << "') [" << time << " ms] from driver." << oendl;
else
odebug << "read nothing from driver." << oendl;
return rlen == len;
}
bool ZCameraIO::write( char* buf, int len )
{
if ( !len )
len = strlen( buf );
odebug << "writing '" << buf << "' to driver." << oendl;
return ::write( _driver, buf, len ) == len;
}
bool ZCameraIO::snapshot( QImage* image )
{
setReadMode( STATUS );
odebug << "finder reversed = " << isFinderReversed() << oendl;
odebug << "rotation = " << _rot << oendl;
- if ( _rot ) // Portrait
+ int readmode;
+ if ( _flip == -1 ) // AUTO
{
- setReadMode( IMAGE | isFinderReversed() ? XFLIP | YFLIP : 0 );
+ if ( _rot ) // Portrait
+ {
+ readmode = IMAGE | isFinderReversed() ? XFLIP | YFLIP : 0;
+ }
+ else // Landscape
+ {
+ readmode = IMAGE | XFLIP | YFLIP;
+ }
}
- else // Landscape
+ else // OVERRIDE
{
- setReadMode( IMAGE | XFLIP | YFLIP ); //isFinderReversed() ? 0 : XFLIP );
+ readmode = IMAGE | _flip;
}
+ setReadMode( readmode );
+
char buf[_readlen];
char* bp = buf;
unsigned char* p;
read( bp, _readlen );
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++;
}
}
return true;
}
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;
}
void ZCameraIO::captureFrame( int w, int h, int zoom, QImage* image )
{
int pw = _width;
int ph = _height;
if ( _rot )
setCaptureFrame( h, w, zoom*256, true );
else
setCaptureFrame( w, h, zoom*256, false );
snapshot( image );
setCaptureFrame( pw, ph, _zoom, _rot );
}
+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
@@ -1,81 +1,86 @@
/**********************************************************************
** 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 ZCAMERAIO_H
#define ZCAMERAIO_H
#include <qobject.h>
class QImage;
class QTime;
class ZCameraIO : public QObject
{
Q_OBJECT
public:
virtual ~ZCameraIO();
enum ReadMode
{
IMAGE = 0, STATUS = 1,
FASTER = 0, BETTER = 2,
XNOFLIP = 0, XFLIP = 4,
- YNOFLIP = 0, YFLIP = 8
+ YNOFLIP = 0, YFLIP = 8,
+ AUTOMATICFLIP = -1
};
// low level interface
bool setCaptureFrame( int w, int h, int zoom = 256, bool rot = true );
bool setZoom( int zoom = 0 );
void setReadMode( int = IMAGE | XFLIP | YFLIP );
+ void setFlip( int flip );
bool isShutterPressed(); // not const, because it calls clearShutterLatch
bool isAvailable() const;
bool isCapturing() const;
bool isFinderReversed() const;
- bool snapshot( unsigned char* );
- bool snapshot( QImage* );
+ bool snapshot( QImage* image );
+ bool snapshot( unsigned char* buf );
// high level interface
bool isOpen() const;
static ZCameraIO* instance();
void captureFrame( int w, int h, int zoom, QImage* image );
+ void captureFrame( int w, int h, int zoom, unsigned char* buf );
protected:
ZCameraIO();
void clearShutterLatch();
void init();
bool read( char*, int );
bool write( char*, int = 0 );
signals:
void shutterClicked();
private:
int _driver;
char _status[4];
+ bool _pressed;
static ZCameraIO* _instance;
int _height;
int _width;
int _zoom;
+ int _flip;
bool _rot;
int _readlen;
QTime* _timer;
};
#endif