summaryrefslogtreecommitdiff
path: root/noncore/multimedia/camera
Unidiff
Diffstat (limited to 'noncore/multimedia/camera') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/multimedia/camera/camera.pro28
-rw-r--r--noncore/multimedia/camera/cmd/.cvsignore5
-rw-r--r--noncore/multimedia/camera/cmd/capture.cpp9
-rw-r--r--noncore/multimedia/camera/cmd/cmd.pro18
-rw-r--r--noncore/multimedia/camera/gui/.cvsignore5
-rw-r--r--noncore/multimedia/camera/lib/.cvsignore5
-rw-r--r--noncore/multimedia/camera/lib/avi.c (renamed from noncore/multimedia/camera/avi.c)0
-rw-r--r--noncore/multimedia/camera/lib/avi.h142
-rw-r--r--noncore/multimedia/camera/lib/imageio.cpp55
-rw-r--r--noncore/multimedia/camera/lib/imageio.h (renamed from noncore/multimedia/camera/main.cpp)20
-rw-r--r--noncore/multimedia/camera/lib/zcameraio.cpp (renamed from noncore/multimedia/camera/zcameraio.cpp)0
-rw-r--r--noncore/multimedia/camera/lib/zcameraio.h (renamed from noncore/multimedia/camera/zcameraio.h)0
-rw-r--r--noncore/multimedia/camera/mainwindow.cpp692
-rw-r--r--noncore/multimedia/camera/mainwindow.h107
-rw-r--r--noncore/multimedia/camera/opie-camera.control4
-rw-r--r--noncore/multimedia/camera/previewwidget.cpp88
-rw-r--r--noncore/multimedia/camera/previewwidget.h50
17 files changed, 252 insertions, 976 deletions
diff --git a/noncore/multimedia/camera/camera.pro b/noncore/multimedia/camera/camera.pro
index c0e6ca8..149ed8d 100644
--- a/noncore/multimedia/camera/camera.pro
+++ b/noncore/multimedia/camera/camera.pro
@@ -1,27 +1,3 @@
1MOC_DIR = ./moc 1TEMPLATE = subdirs
2OBJECTS_DIR = ./obj 2SUBDIRS = lib gui cmd
3DESTDIR = $(OPIEDIR)/bin
4TEMPLATE = app
5CONFIG = qt warn_on debug
6
7HEADERS = avi.h \
8 imageio.h \
9 zcameraio.h \
10 previewwidget.h \
11 mainwindow.h
12
13SOURCES = avi.c \
14 imageio.cpp \
15 zcameraio.cpp \
16 previewwidget.cpp \
17 mainwindow.cpp \
18 main.cpp
19
20INCLUDEPATH += $(OPIEDIR)/include
21DEPENDPATH += $(OPIEDIR)/include
22LIBS += -lqpe -lopie -lopiecore2
23INTERFACES =
24TARGET = opiecam
25
26include ( $(OPIEDIR)/include.pro )
27 3
diff --git a/noncore/multimedia/camera/cmd/.cvsignore b/noncore/multimedia/camera/cmd/.cvsignore
new file mode 100644
index 0000000..737c5b2
--- a/dev/null
+++ b/noncore/multimedia/camera/cmd/.cvsignore
@@ -0,0 +1,5 @@
1moc
2obj
3config.in
4Makefile
5
diff --git a/noncore/multimedia/camera/cmd/capture.cpp b/noncore/multimedia/camera/cmd/capture.cpp
new file mode 100644
index 0000000..e34c4e3
--- a/dev/null
+++ b/noncore/multimedia/camera/cmd/capture.cpp
@@ -0,0 +1,9 @@
1#include <stdio.h>
2
3int main( int argc, char** argv )
4{
5 printf( "Not yet implemented.\n" );
6 return 0;
7}
8
9
diff --git a/noncore/multimedia/camera/cmd/cmd.pro b/noncore/multimedia/camera/cmd/cmd.pro
new file mode 100644
index 0000000..68ee907
--- a/dev/null
+++ b/noncore/multimedia/camera/cmd/cmd.pro
@@ -0,0 +1,18 @@
1MOC_DIR = ./moc
2OBJECTS_DIR = ./obj
3DESTDIR = $(OPIEDIR)/bin
4TEMPLATE = app
5CONFIG = qt warn_on debug
6
7HEADERS =
8
9SOURCES = capture.cpp
10
11INCLUDEPATH += $(OPIEDIR)/include
12DEPENDPATH += $(OPIEDIR)/include
13LIBS += -lqpe -lopiecore2
14INTERFACES =
15TARGET = capture
16
17include ( $(OPIEDIR)/include.pro )
18
diff --git a/noncore/multimedia/camera/gui/.cvsignore b/noncore/multimedia/camera/gui/.cvsignore
new file mode 100644
index 0000000..737c5b2
--- a/dev/null
+++ b/noncore/multimedia/camera/gui/.cvsignore
@@ -0,0 +1,5 @@
1moc
2obj
3config.in
4Makefile
5
diff --git a/noncore/multimedia/camera/lib/.cvsignore b/noncore/multimedia/camera/lib/.cvsignore
new file mode 100644
index 0000000..737c5b2
--- a/dev/null
+++ b/noncore/multimedia/camera/lib/.cvsignore
@@ -0,0 +1,5 @@
1moc
2obj
3config.in
4Makefile
5
diff --git a/noncore/multimedia/camera/avi.c b/noncore/multimedia/camera/lib/avi.c
index 77aba33..77aba33 100644
--- a/noncore/multimedia/camera/avi.c
+++ b/noncore/multimedia/camera/lib/avi.c
diff --git a/noncore/multimedia/camera/lib/avi.h b/noncore/multimedia/camera/lib/avi.h
new file mode 100644
index 0000000..fbdc14a
--- a/dev/null
+++ b/noncore/multimedia/camera/lib/avi.h
@@ -0,0 +1,142 @@
1/**********************************************************************
2** Copyright (C) 2003 Michael 'Mickey' Lauer. All rights reserved.
3** Based on work from Andrew Tridgell and the jpegtoavi project
4**
5** This file is part of Opie Environment.
6**
7** This file may be distributed and/or modified under the terms of the
8** GNU General Public License version 2 as published by the Free Software
9** Foundation and appearing in the file LICENSE.GPL included in the
10** packaging of this file.
11**
12** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
13** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
14**
15**********************************************************************/
16
17#ifndef AVI_H
18#define AVI_H
19
20#include <unistd.h>
21#include <stdio.h>
22#include <sys/types.h>
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28typedef unsigned char u8;
29typedef unsigned short u16;
30typedef unsigned u32;
31
32// header flags
33
34const u32 AVIF_HASINDEX=0x00000010; /* index at end of file */
35const u32 AVIF_MUSTUSEINDEX=0x00000020;
36const u32 AVIF_ISINTERLEAVED=0x00000100;
37const u32 AVIF_TRUSTCKTYPE=0x00000800;
38const u32 AVIF_WASCAPTUREFILE=0x00010000;
39const u32 AVIF_COPYRIGHTED=0x00020000;
40
41// function prototypes
42
43void avi_start(int fd, int frame);
44void avi_add(int fd, u8 *buf, int size);
45void avi_end(int fd, int width, int height, int fps);
46void fprint_quartet(int fd, unsigned int i);
47
48// the following structures are ordered as they appear in a typical AVI
49
50struct riff_head {
51 char riff[4]; // chunk type = "RIFF"
52 u32 size; // chunk size
53 char avistr[4]; // avi magic = "AVI "
54};
55
56// the avih chunk contains a number of list chunks
57
58struct avi_head {
59 char avih[4]; // chunk type = "avih"
60 u32 size; // chunk size
61 u32 time; // microsec per frame == 1e6 / fps
62 u32 maxbytespersec; // = 1e6*(total size/frames)/per_usec)
63 u32 pad; // pad = 0
64 u32 flags; // e.g. AVIF_HASINDEX
65 u32 nframes; // total number of frames
66 u32 initialframes; // = 0
67 u32 numstreams; // = 1 for now (later = 2 because of audio)
68 u32 suggested_bufsize; // = 0 (no suggestion)
69 u32 width; // width
70 u32 height; // height
71 u32 reserved[4]; // reserved for future use = 0
72};
73
74
75// the LIST chunk contains a number (==#numstreams) of stream chunks
76
77struct list_head {
78 char list[4]; // chunk type = "LIST"
79 u32 size;
80 char type[4];
81};
82
83
84struct dmlh_head {
85 char dmlh[4]; // chunk type dmlh
86 u32 size; // 4
87 u32 nframes; // number of frames
88};
89
90
91struct stream_head {
92 char strh[4]; // chunk type = "strh"
93 u32 size; // chunk size
94 char vids[4]; // stream type = "vids"
95 char codec[4]; // codec name (for us, = "MJPG")
96 u32 flags; // contains AVIT_F* flags
97 u16 priority; // = 0
98 u16 language; // = 0
99 u32 initialframes; // = 0
100 u32 scale; // = usec per frame
101 u32 rate; // 1e6
102 u32 start; // = 0
103 u32 length; // number of frames
104 u32 suggested_bufsize; // = 0
105 u32 quality; // = 0 ?
106 u32 samplesize; // = 0 ?
107};
108
109
110struct db_head {
111 char db[4]; // "00db"
112 u32 size;
113};
114
115// a frame chunk contains one JPEG image
116
117struct frame_head {
118 char strf[4]; // chunk type = "strf"
119 u32 size; // sizeof chunk (big endian) ?
120 u32 size2; // sizeof chunk (little endian) ?
121 u32 width;
122 u32 height;
123 u16 planes; // 1 bitplane
124 u16 bitcount; // 24 bpl
125 char codec[4]; // MJPG (for us)
126 u32 unpackedsize; // = 3*w*h
127 u32 r1; // reserved
128 u32 r2; // reserved
129 u32 clr_used; // reserved
130 u32 clr_important; // reserved
131};
132
133struct idx1_head {
134 char idx1[4]; // chunk type = "idx1"
135 u32 size; // chunk size
136};
137
138#ifdef __cplusplus
139}
140#endif
141
142#endif
diff --git a/noncore/multimedia/camera/lib/imageio.cpp b/noncore/multimedia/camera/lib/imageio.cpp
new file mode 100644
index 0000000..ed0d39f
--- a/dev/null
+++ b/noncore/multimedia/camera/lib/imageio.cpp
@@ -0,0 +1,55 @@
1/**********************************************************************
2** Copyright (C) 2002 Michael 'Mickey' Lauer. All rights reserved.
3**
4** This file is part of Opie Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14**********************************************************************/
15
16#include "imageio.h"
17
18#include <opie2/odebug.h>
19#include <qimage.h>
20
21
22void bufferToImage( int _width, int _height, unsigned char* bp, QImage* image )
23{
24 unsigned char* p;
25
26 image->create( _width, _height, 16 );
27 for ( int i = 0; i < _height; ++i )
28 {
29 p = image->scanLine( i );
30 for ( int j = 0; j < _width; j++ )
31 {
32 *p = *bp;
33 p++;
34 bp++;
35 *p = *bp;
36 p++;
37 bp++;
38 }
39 }
40}
41
42
43void imageToFile( QImage* i, const QString& name, const QString& format, int quality )
44{
45 QImage im = i->convertDepth( 32 );
46 bool result = im.save( name, format, quality );
47 if ( !result )
48 {
49 oerr << "imageio-Problem while writing to " << name << oendl;
50 }
51 else
52 {
53 odebug << format << "-image has been successfully captured" << oendl;
54 }
55}
diff --git a/noncore/multimedia/camera/main.cpp b/noncore/multimedia/camera/lib/imageio.h
index f25475c..8dba2ed 100644
--- a/noncore/multimedia/camera/main.cpp
+++ b/noncore/multimedia/camera/lib/imageio.h
@@ -13,16 +13,14 @@
13** 13**
14**********************************************************************/ 14**********************************************************************/
15 15
16#include "mainwindow.h" 16#ifndef IMAGEIO_H
17#include <opie2/oapplication.h> 17#define IMAGEIO_H
18 18
19int main( int argc, char **argv ) 19#include <qstring.h>
20{
21 OApplication a( argc, argv, "Opie-Camera" );
22 CameraMainWindow* w = new CameraMainWindow();
23 a.showMainWidget( w );
24 a.exec();
25 delete w;
26 return 0;
27}
28 20
21class QImage;
22
23void bufferToImage( int _width, int height, unsigned char* bp, QImage* image );
24void imageToFile( QImage* i, const QString& name, const QString& format, int quality );
25
26#endif
diff --git a/noncore/multimedia/camera/zcameraio.cpp b/noncore/multimedia/camera/lib/zcameraio.cpp
index c940b45..c940b45 100644
--- a/noncore/multimedia/camera/zcameraio.cpp
+++ b/noncore/multimedia/camera/lib/zcameraio.cpp
diff --git a/noncore/multimedia/camera/zcameraio.h b/noncore/multimedia/camera/lib/zcameraio.h
index 3352a5e..3352a5e 100644
--- a/noncore/multimedia/camera/zcameraio.h
+++ b/noncore/multimedia/camera/lib/zcameraio.h
diff --git a/noncore/multimedia/camera/mainwindow.cpp b/noncore/multimedia/camera/mainwindow.cpp
deleted file mode 100644
index 49c7cbf..0000000
--- a/noncore/multimedia/camera/mainwindow.cpp
+++ b/dev/null
@@ -1,692 +0,0 @@
1/**********************************************************************
2** Copyright (C) 2002 Michael 'Mickey' Lauer. All rights reserved.
3**
4** This file is part of Opie Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14**********************************************************************/
15
16#include "mainwindow.h"
17#include "previewwidget.h"
18#include "zcameraio.h"
19#include "imageio.h"
20#include "avi.h"
21
22#include <qapplication.h>
23#include <qaction.h>
24#include <qvbox.h>
25#include <qcombobox.h>
26#include <qcursor.h>
27#include <qdatastream.h>
28#include <qdir.h>
29#include <qfile.h>
30#include <qimage.h>
31#include <qlabel.h>
32#include <qlineedit.h>
33#include <qpopupmenu.h>
34#include <qprogressbar.h>
35#include <qpushbutton.h>
36#include <qmessagebox.h>
37#include <qlayout.h>
38#include <qdirectpainter_qws.h>
39#include <qpe/global.h>
40#include <qpe/resource.h>
41#include <qpe/qcopenvelope_qws.h>
42#include <opie/ofiledialog.h>
43#include <opie/odevice.h>
44using namespace Opie;
45#include <opie2/odebug.h>
46
47#include <assert.h>
48#include <sys/types.h>
49#include <sys/stat.h>
50#include <fcntl.h>
51#include <string.h>
52#include <errno.h>
53#include <unistd.h>
54
55#define CAPTUREFILE "/tmp/capture.dat"
56#define OUTPUTFILE "/tmp/output.avi"
57
58#define OUTPUT_TO_CUSTOM 250
59#define OUTPUT_TO_DOCFOLDER 251
60
61CameraMainWindow::CameraMainWindow( QWidget * parent, const char * name, WFlags f )
62 :QMainWindow( parent, name, f ),
63 _rotation( 270 ), // FIXME: get this from current settings (ODevice?)
64 _capturing( false ),
65 _pics( 1 ), _videos( 1 )
66{
67 #ifdef QT_NO_DEBUG
68 if ( !ZCameraIO::instance()->isOpen() )
69 {
70 QVBox* v = new QVBox( this );
71 v->setMargin( 10 );
72 QLabel* l1 = new QLabel( v );
73 l1->setPixmap( Resource::loadPixmap( "camera/error" ) );
74 QLabel* l2 = new QLabel( v );
75 l2->setText( "<b>Sorry. could not detect your camera :-(</b><p>"
76 "* Is the sharpzdc_cs module loaded ?<br>"
77 "* Is /dev/sharpzdc read/writable ?<p>" );
78 connect( new QPushButton( "Exit", v ), SIGNAL( clicked() ), this, SLOT( close() ) );
79 setCentralWidget( v );
80 return;
81 }
82 #endif
83
84 init();
85
86 _rotation = 270; //TODO: grab these from the actual settings
87
88 preview = new PreviewWidget( this, "camera preview widget" );
89 //setCentralWidget( preview ); <--- don't do this!
90 preview->resize( QSize( 240, 288 ) );
91 preview->show();
92
93 // construct a System Channel to receive setRotation messages
94 _sysChannel = new QCopChannel( "QPE/System", this );
95 connect( _sysChannel, SIGNAL( received( const QCString&, const QByteArray& ) ),
96 this, SLOT( systemMessage( const QCString&, const QByteArray& ) ) );
97
98 connect( preview, SIGNAL( contextMenuRequested() ), this, SLOT( showContextMenu() ) );
99
100 connect( ZCameraIO::instance(), SIGNAL( shutterClicked() ), this, SLOT( shutterClicked() ) );
101
102 updateCaption();
103
104};
105
106
107CameraMainWindow::~CameraMainWindow()
108{
109}
110
111
112void CameraMainWindow::init()
113{
114 // TODO: Save this stuff in config
115 flip = 'A'; // auto
116 quality = 50;
117 zoom = 1;
118 captureX = 480;
119 captureY = 640;
120 captureFormat = "JPEG";
121 outputTo = "Documents Folder";
122 prefix = "Untitled";
123 appendSettings = true;
124
125 resog = new QActionGroup( 0, "reso", true );
126 resog->setToggleAction( true );
127 new QAction( " 64 x 48", 0, 0, resog, 0, true );
128 new QAction( "128 x 96", 0, 0, resog, 0, true );
129 new QAction( "192 x 144", 0, 0, resog, 0, true );
130 new QAction( "256 x 192", 0, 0, resog, 0, true );
131 new QAction( "320 x 240", 0, 0, resog, 0, true );
132 new QAction( "384 x 288", 0, 0, resog, 0, true );
133 new QAction( "448 x 336", 0, 0, resog, 0, true );
134 new QAction( "512 x 384", 0, 0, resog, 0, true );
135 new QAction( "576 x 432", 0, 0, resog, 0, true );
136 ( new QAction( "640 x 480", 0, 0, resog, 0, true ) )->setOn( true );
137
138 qualityg = new QActionGroup( 0, "quality", true );
139 qualityg->setToggleAction( true );
140 new QAction( " 0 (&minimal)", 0, 0, qualityg, 0, true );
141 new QAction( " 25 (&low)", 0, 0, qualityg, 0, true );
142 ( new QAction( " 50 (&good)", 0, 0, qualityg, 0, true ) )->setOn( true );
143 new QAction( " 75 (&better)", 0, 0, qualityg, 0, true );
144 new QAction( "100 (bes&t)", 0, 0, qualityg, 0, true );
145
146 zoomg = new QActionGroup( 0, "zoom", true );
147 zoomg->setToggleAction( true );
148 ( new QAction( "x 1", 0, 0, zoomg, 0, true ) )->setOn( true );
149 new QAction( "x 2", 0, 0, zoomg, 0, true );
150
151 flipg = new QActionGroup( 0, "flip", true );
152 flipg->setToggleAction( true );
153 ( new QAction( "Auto (recommended)", 0, 0, flipg, 0, true ) )->setOn( true );
154 new QAction( "0 (always off)", 0, 0, flipg, 0, true );
155 new QAction( "X (always horizontal)", 0, 0, flipg, 0, true );
156 new QAction( "Y (always vertical)", 0, 0, flipg, 0, true );
157 new QAction( "* (always both)", 0, 0, flipg, 0, true );
158
159 outputTog = new QActionGroup( 0, "output", true );
160 outputTog->setToggleAction( true );
161 new QAction( "/tmp/", 0, 0, outputTog, 0, true );
162 new QAction( "/mnt/card/", 0, 0, outputTog, 0, true );
163 new QAction( "/mnt/cf/", 0, 0, outputTog, 0, true );
164 docfolder = new QAction( "Documents Folder", 0, 0, outputTog, 0, true );
165 docfolder->setOn( true );
166 custom = new QAction( "&Custom...", 0, 0, outputTog, 0, true );
167
168 outputg = new QActionGroup( 0, "output", true );
169 outputg->setToggleAction( true );
170 ( new QAction( "JPEG", 0, 0, outputg, 0, true ) )->setOn( true );
171 new QAction( "PNG", 0, 0, outputg, 0, true );
172 new QAction( "BMP", 0, 0, outputg, 0, true );
173 new QAction( "AVI", 0, 0, outputg, 0, true );
174
175 connect( resog, SIGNAL( selected(QAction*) ), this, SLOT( resoMenuItemClicked(QAction*) ) );
176 connect( qualityg, SIGNAL( selected(QAction*) ), this, SLOT( qualityMenuItemClicked(QAction*) ) );
177 connect( zoomg, SIGNAL( selected(QAction*) ), this, SLOT( zoomMenuItemClicked(QAction*) ) );
178 connect( flipg, SIGNAL( selected(QAction*) ), this, SLOT( flipMenuItemClicked(QAction*) ) );
179 connect( outputTog, SIGNAL( selected(QAction*) ), this, SLOT( outputToMenuItemClicked(QAction*) ) );
180 connect( outputg, SIGNAL( selected(QAction*) ), this, SLOT( outputMenuItemClicked(QAction*) ) );
181
182}
183
184
185void CameraMainWindow::systemMessage( const QCString& msg, const QByteArray& data )
186{
187 int _newrotation;
188
189 QDataStream stream( data, IO_ReadOnly );
190 odebug << "received system message: " << msg << oendl;
191 if ( msg == "setCurrentRotation(int)" )
192 {
193 stream >> _newrotation;
194 odebug << "received setCurrentRotation(" << _newrotation << ")" << oendl;
195
196 switch ( _newrotation )
197 {
198 case 270: preview->resize( QSize( 240, 288 ) ); break;
199 case 180: preview->resize( QSize( 320, 208 ) ); break;
200 default: QMessageBox::warning( this, "opie-camera",
201 "This rotation is not supported.\n"
202 "Supported are 180° and 270°" );
203 }
204
205 if ( _newrotation != _rotation )
206 {
207 int tmp = captureX;
208 captureX = captureY;
209 captureY = tmp;
210 _rotation = _newrotation;
211 }
212
213 updateCaption();
214
215 }
216}
217
218
219void CameraMainWindow::changeZoom( int zoom )
220{
221 int z;
222 switch ( zoom )
223 {
224 case 0: z = 128; break;
225 case 1: z = 256; break;
226 case 2: z = 512; break;
227 default: assert( 0 ); break;
228 }
229
230 ZCameraIO::instance()->setCaptureFrame( 240, 160, z );
231}
232
233
234void CameraMainWindow::showContextMenu()
235{
236 QPopupMenu reso;
237 reso.setCheckable( true );
238 resog->addTo( &reso );
239
240 QPopupMenu quality;
241 quality.setCheckable( true );
242 qualityg->addTo( &quality );
243
244 QPopupMenu flip;
245 flip.setCheckable( true );
246 flipg->addTo( &flip );
247
248 QPopupMenu zoom;
249 zoom.setCheckable( true );
250 zoomg->addTo( &zoom );
251
252 QPopupMenu prefix;
253 prefix.insertItem( "&Choose...", this, SLOT( prefixItemChoosen() ) );
254 int id = prefix.insertItem( "&Append Settings", this, SLOT( appendSettingsChoosen() ) );
255 prefix.setItemChecked( id, appendSettings );
256
257 QPopupMenu outputTo;
258 outputTo.setCheckable( true );
259 outputTog->addTo( &outputTo );
260
261 QPopupMenu output;
262 output.setCheckable( true );
263 outputg->addTo( &output );
264
265 QPopupMenu m( this );
266 m.insertItem( "&Resolution", &reso );
267 m.insertItem( "&Zoom", &zoom );
268 m.insertItem( "&Flip", &flip );
269 m.insertItem( "&Quality", &quality );
270 m.insertSeparator();
271 m.insertItem( "&Prefix", &prefix );
272 m.insertItem( "Output &To", &outputTo );
273 m.insertItem( "&Output As", &output );
274
275 #ifndef QT_NO_DEBUG
276 m.insertItem( "&Debug!", this, SLOT( doSomething() ) );
277 #endif
278
279 m.exec( QCursor::pos() );
280}
281
282
283void CameraMainWindow::resoMenuItemClicked( QAction* a )
284{
285 switch ( _rotation )
286 {
287 case 270:
288 captureY = a->text().left(3).toInt();
289 captureX = a->text().right(3).toInt();
290 break;
291 case 180:
292 captureX = a->text().left(3).toInt();
293 captureY = a->text().right(3).toInt();
294 break;
295 default: QMessageBox::warning( this, "opie-camera",
296 "This rotation is not supported.\n"
297 "Supported are 180° and 270°" );
298 }
299 odebug << "Capture Resolution now: " << captureX << ", " << captureY << oendl;
300 updateCaption();
301}
302
303
304void CameraMainWindow::qualityMenuItemClicked( QAction* a )
305{
306 quality = a->text().left(3).toInt();
307 odebug << "Quality now: " << quality << oendl;
308 updateCaption();
309}
310
311
312void CameraMainWindow::zoomMenuItemClicked( QAction* a )
313{
314 zoom = QString( a->text().at(2) ).toInt();
315 odebug << "Zoom now: " << zoom << oendl;
316 ZCameraIO::instance()->setZoom( zoom );
317 updateCaption();
318}
319
320
321void CameraMainWindow::flipMenuItemClicked( QAction* a )
322{
323 flip = QString( a->text().at(0) );
324 odebug << "Flip now: " << flip << oendl;
325 if ( flip == "A" )
326 ZCameraIO::instance()->setFlip( ZCameraIO::AUTOMATICFLIP );
327 else if ( flip == "0" )
328 ZCameraIO::instance()->setFlip( ZCameraIO::XNOFLIP | ZCameraIO::YNOFLIP );
329 else if ( flip == "X" )
330 ZCameraIO::instance()->setFlip( ZCameraIO::XFLIP );
331 else if ( flip == "Y" )
332 ZCameraIO::instance()->setFlip( ZCameraIO::YFLIP );
333 else if ( flip == "*" )
334 ZCameraIO::instance()->setFlip( ZCameraIO::XFLIP | ZCameraIO::YFLIP );
335
336 updateCaption();
337}
338
339
340void CameraMainWindow::outputToMenuItemClicked( QAction* a )
341{
342 if ( a->text() == "&Custom..." )
343 {
344 QMap<QString, QStringList> map;
345 map.insert( tr("All"), QStringList() );
346 QStringList text;
347 text << "text/*";
348 map.insert(tr("Text"), text );
349 text << "*";
350 map.insert(tr("All"), text );
351
352 QString str;
353 str = OFileDialog::getSaveFileName( 2, "/", QString::null, map );
354 if ( str.isEmpty() || !QFileInfo(str).isDir() )
355 {
356 docfolder->setOn( true );
357 outputTo = "Documents Folder";
358 }
359 else
360 {
361 outputTo = str;
362 }
363 }
364 else
365 {
366 outputTo = a->text();
367 }
368 odebug << "Output to now: " << outputTo << oendl;
369}
370
371
372void CameraMainWindow::outputMenuItemClicked( QAction* a )
373{
374 captureFormat = a->text();
375 odebug << "Output format now: " << captureFormat << oendl;
376 updateCaption();
377}
378
379
380void CameraMainWindow::prefixItemChoosen()
381{
382 QDialog* d = new QDialog( this, "dialog", true );
383 d->setCaption( "Enter Prefix..." );
384 QVBoxLayout* v = new QVBoxLayout( d );
385 QLineEdit* le = new QLineEdit( prefix, d );
386 v->addWidget( le );
387 le->setFixedWidth( 150 ); //FIXME: 'tis a bit dirty
388 if ( d->exec() == QDialog::Accepted )
389 prefix = le->text();
390 odebug << "Prefix now: " << prefix << oendl;
391}
392
393
394void CameraMainWindow::appendSettingsChoosen()
395{
396 appendSettings = !appendSettings;
397 odebug << "appendSettings now: " << appendSettings << oendl;
398}
399
400
401void CameraMainWindow::shutterClicked()
402{
403 if ( captureFormat != "AVI" ) // capture one photo per shutterClick
404 {
405 Global::statusMessage( "CAPTURING..." );
406 qApp->processEvents();
407
408 odebug << "Shutter has been pressed" << oendl;
409 ODevice::inst()->touchSound();
410
411 performCapture( captureFormat );
412 }
413 else // capture video! start with one shutter click and stop with the next
414 {
415 !_capturing ? startVideoCapture() : stopVideoCapture();
416 }
417}
418
419
420void CameraMainWindow::performCapture( const QString& format )
421{
422 QString name;
423
424 if ( outputTo == "Documents Folder" )
425 {
426 name.sprintf( "%s/Documents/image/%s/", (const char*) QDir::homeDirPath(), (const char*) captureFormat.lower() );
427 if ( !QDir( name ).exists() )
428 {
429 odebug << "creating directory " << name << oendl;
430 QString msg = "mkdir -p " + name;
431 system( msg.latin1() );
432 }
433 }
434 else
435 name = outputTo;
436
437 name.append( prefix );
438 if ( appendSettings )
439 {
440 name.append( QString().sprintf( "_%d_%d_q%d", captureX, captureY, quality ) );
441 }
442 name.append( QString().sprintf( "-%d.%s", _pics++, (const char*) captureFormat.lower() ) );
443
444 QImage i;
445 ZCameraIO::instance()->captureFrame( captureX, captureY, zoom, &i );
446 QImage im = i.convertDepth( 32 );
447 bool result = im.save( name, format, quality );
448 if ( !result )
449 {
450 oerr << "imageio-Problem while writing." << oendl;
451 Global::statusMessage( "Error!" );
452 }
453 else
454 {
455 odebug << captureFormat << "-image has been successfully captured" << oendl;
456 Global::statusMessage( "Ok." );
457 }
458}
459
460
461void CameraMainWindow::startVideoCapture()
462{
463 //ODevice::inst()->touchSound();
464 ODevice::inst()->setLedState( Led_Mail, Led_BlinkSlow );
465
466 _capturefd = ::open( CAPTUREFILE, O_WRONLY | O_CREAT | O_TRUNC );
467 if ( _capturefd == -1 )
468 {
469 owarn << "can't open capture file: " << strerror(errno) << oendl;
470 return;
471 }
472
473 _capturebuf = new unsigned char[captureX*captureY*2];
474 _capturing = true;
475 _videopics = 0;
476 _framerate = 0;
477 updateCaption();
478 _time.start();
479 preview->setRefreshingRate( 1000 );
480 startTimer( 100 ); // too fast but that is ok
481}
482
483
484void CameraMainWindow::timerEvent( QTimerEvent* )
485{
486 if ( !_capturing )
487 {
488 odebug << "timer event in CameraMainWindow without capturing video ?" << oendl;
489 return;
490 }
491
492 odebug << "timer event during video - now capturing frame #" << _videopics+1 << oendl;
493
494 ZCameraIO::instance()->captureFrame( captureX, captureY, zoom, _capturebuf );
495 _videopics++;
496 ::write( _capturefd, _capturebuf, captureX*captureY*2 );
497 setCaption( QString().sprintf( "Capturing %dx%d @ %.2f fps %d",
498 captureX, captureY, 1000.0 / (_time.elapsed()/_videopics), _videopics ) );
499}
500
501
502void CameraMainWindow::stopVideoCapture()
503{
504 killTimers();
505 //ODevice::inst()->touchSound();
506 ODevice::inst()->setLedState( Led_Mail, Led_Off );
507 _capturing = false;
508 updateCaption();
509 ::close( _capturefd );
510 _framerate = 1000.0 / (_time.elapsed()/_videopics);
511
512 QString name;
513 if ( outputTo == "Documents Folder" )
514 {
515 name.sprintf( "%s/Documents/video/%s/", (const char*) QDir::homeDirPath(), (const char*) captureFormat.lower() );
516 if ( !QDir( name ).exists() )
517 {
518 odebug << "creating directory " << name << oendl;
519 QString msg = "mkdir -p " + name;
520 system( msg.latin1() );
521 }
522 }
523 else
524 name = outputTo;
525
526 name.append( "/" ); // sure is sure and safe is safe ;-)
527 name.append( prefix );
528 if ( appendSettings )
529 name.append( QString().sprintf( "_%d_%d_q%d_%dfps", captureX, captureY, quality, _framerate ) );
530 name.append( QString().sprintf( "-%d.%s", _videos++, (const char*) captureFormat.lower() ) );
531 postProcessVideo( CAPTUREFILE, name );
532
533 #ifndef QT_NO_DEBUG
534 preview->setRefreshingRate( 1500 );
535 #else
536 preview->setRefreshingRate( 200 );
537 #endif
538
539 //delete[] _capturebuf; //FIXME: close memory leak
540}
541
542void CameraMainWindow::postProcessVideo( const QString& infile, const QString& outfile )
543{
544 odebug << "post processing " << infile << " --> " << outfile << oendl;
545
546 preview->setRefreshingRate( 0 );
547
548 /*
549 unsigned char buf[153600];
550
551 int fd = ::open( "/var/compile/opie/noncore/multimedia/camera/capture-320x240.dat", O_RDONLY );
552 ::read( fd, &buf, 153600 );
553 QImage i;
554 bufferToImage( 240, 320, (unsigned char*) &buf, &i );
555 QPixmap p;
556 p.convertFromImage( i );
557 preview->setPixmap( p );
558 imageToFile( &i, "/tmp/tmpfile", "JPEG", 100 );
559 return;
560 */
561
562 QDialog* fr = new QDialog( this, "splash", false, QWidget::WStyle_StaysOnTop ); //, false, QWidget::WStyle_NoBorder | QWidget::WStyle_Customize );
563 fr->setCaption( "Please wait..." );
564 QVBoxLayout* box = new QVBoxLayout( fr, 2, 2 );
565 QProgressBar* bar = new QProgressBar( fr );
566 bar->setCenterIndicator( true );
567 bar->setTotalSteps( _videopics-1 );
568 QLabel* label = new QLabel( "Post processing frame bla/bla", fr );
569 box->addWidget( bar );
570 box->addWidget( label );
571 fr->show();
572 label->show();
573 bar->show();
574 fr->repaint();
575 qApp->processEvents();
576
577 // open files
578
579 int infd = ::open( (const char*) infile, O_RDONLY );
580 if ( infd == -1 )
581 {
582 owarn << "couldn't open capture file: " << strerror(errno) << oendl;
583 return;
584 }
585
586 int outfd = ::open( (const char*) outfile, O_CREAT | O_WRONLY | O_TRUNC, 0644 );
587 if ( outfd == -1 )
588 {
589 owarn << "couldn't open output file: " << strerror(errno) << oendl;
590 return;
591 }
592
593 int framesize = captureX*captureY*2;
594
595 unsigned char* inbuffer = new unsigned char[ framesize ];
596 QImage image;
597
598 avi_start( outfd, _videopics ); // write preambel
599
600 // post process
601
602 for ( int i = 0; i < _videopics; ++i )
603 {
604 odebug << "processing frame " << i << oendl;
605
606 // <gui>
607 label->setText( QString().sprintf( "Post processing frame %d / %d", i+1, _videopics ) );
608 bar->setProgress( i );
609 bar->repaint();
610 qApp->processEvents();
611 // </gui>
612
613 int read = ::read( infd, inbuffer, framesize );
614 odebug << "read " << read << " bytes" << oendl;
615 bufferToImage( captureX, captureY, inbuffer, &image );
616
617 QPixmap p;
618 p.convertFromImage( image );
619 preview->setPixmap( p );
620 preview->repaint();
621 qApp->processEvents();
622
623 #ifdef CAMERA_EXTRA_DEBUG
624 QString tmpfilename;
625 tmpfilename.sprintf( "/tmp/test/%04d.jpg", i );
626 #else
627 QString tmpfilename( "/tmp/tempfile" );
628 #endif
629
630 imageToFile( &image, tmpfilename, "JPEG", quality );
631
632 QFile framefile( tmpfilename );
633 if ( !framefile.open( IO_ReadOnly ) )
634 {
635 oerr << "can't process file: %s" << strerror(errno) << oendl;
636 return; // TODO: clean up temp ressources
637 }
638
639 int filesize = framefile.size();
640 odebug << "filesize for frame " << i << " = " << filesize << oendl;
641
642 unsigned char* tempbuffer = new unsigned char[ filesize ];
643 framefile.readBlock( (char*) tempbuffer, filesize );
644 avi_add( outfd, tempbuffer, filesize );
645 delete tempbuffer;
646 framefile.close();
647
648 }
649
650 avi_end( outfd, captureX, captureY, _framerate );
651 ::close( outfd );
652 ::close( infd );
653
654 label->setText( "deleting temp files..." );
655 qApp->processEvents();
656 odebug << "deleting temporary capturefile " << infile << oendl;
657 QFile::remove( infile );
658
659 fr->hide();
660 delete fr;
661
662 updateCaption();
663
664}
665
666
667void CameraMainWindow::updateCaption()
668{
669 if ( !_capturing )
670 setCaption( QString().sprintf( "Opie-Camera: %dx%d %s q%d z%d (%s)", captureX, captureY, (const char*) captureFormat.lower(), quality, zoom, (const char*) flip ) );
671 else
672 setCaption( "Opie-Camera: => CAPTURING <=" );
673 qApp->processEvents();
674}
675
676
677#ifndef QT_NO_DEBUG
678void CameraMainWindow::doSomething()
679{
680 captureX = 240;
681 captureY = 320;
682 _videopics = 50;
683 _framerate = 5;
684 postProcessVideo( "/var/compile/opie/noncore/multimedia/camera/capture.dat",
685 "/tmp/output.avi" );
686}
687#else
688void CameraMainWindow::doSomething()
689{
690}
691#endif
692
diff --git a/noncore/multimedia/camera/mainwindow.h b/noncore/multimedia/camera/mainwindow.h
deleted file mode 100644
index 451ad5f..0000000
--- a/noncore/multimedia/camera/mainwindow.h
+++ b/dev/null
@@ -1,107 +0,0 @@
1/**********************************************************************
2** Copyright (C) 2003 Michael 'Mickey' Lauer. All rights reserved.
3**
4** This file is part of Opie Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14**********************************************************************/
15
16#ifndef MAINWINDOW_H
17#define MAINWINDOW_H
18
19#include <qmainwindow.h>
20#include <qdatetime.h>
21#include <qimage.h>
22#include <qpixmap.h>
23#include <qdatetime.h>
24
25class QAction;
26class QActionGroup;
27class QIconSet;
28class QTimerEvent;
29class QToolButton;
30class QLabel;
31class MainWindowBase;
32class QCopChannel;
33class PreviewWidget;
34
35class CameraMainWindow: public QMainWindow
36{
37 Q_OBJECT
38
39 public:
40 CameraMainWindow( QWidget * parent = 0, const char * name = "mainwindow", WFlags f = 0 );
41 virtual ~CameraMainWindow();
42
43 public slots:
44 void changeZoom( int );
45 void systemMessage( const QCString&, const QByteArray& );
46 void showContextMenu();
47 void resoMenuItemClicked( QAction* );
48 void qualityMenuItemClicked( QAction* );
49 void zoomMenuItemClicked( QAction* );
50 void flipMenuItemClicked( QAction* );
51 void outputToMenuItemClicked( QAction* );
52 void outputMenuItemClicked( QAction* );
53 void prefixItemChoosen();
54 void appendSettingsChoosen();
55 void shutterClicked();
56
57 void updateCaption();
58
59 protected:
60 void init();
61 void startVideoCapture();
62 void stopVideoCapture();
63 void postProcessVideo( const QString&, const QString& );
64 void performCapture( const QString& );
65
66 virtual void timerEvent( QTimerEvent* );
67
68 protected slots:
69 void doSomething(); // solely for debugging purposes
70
71 private:
72 PreviewWidget* preview;
73 int _rotation;
74 QCopChannel* _sysChannel;
75
76 QActionGroup* resog;
77 QActionGroup* qualityg;
78 QActionGroup* zoomg;
79 QActionGroup* flipg;
80 QActionGroup* outputTog;
81 QAction* custom;
82 QAction* docfolder;
83 QActionGroup* outputg;
84
85 QString flip;
86 int quality;
87 int zoom;
88 int captureX;
89 int captureY;
90 QString captureFormat;
91
92 QString outputTo;
93 QString prefix;
94 bool appendSettings;
95
96 bool _capturing;
97 int _pics;
98 int _videos;
99
100 QTime _time;
101 int _videopics;
102 int _capturefd;
103 int _framerate;
104 unsigned char* _capturebuf;
105};
106
107#endif
diff --git a/noncore/multimedia/camera/opie-camera.control b/noncore/multimedia/camera/opie-camera.control
index 1731ad2..3769901 100644
--- a/noncore/multimedia/camera/opie-camera.control
+++ b/noncore/multimedia/camera/opie-camera.control
@@ -1,10 +1,10 @@
1Package: opie-camera 1Package: opie-camera
2Files: bin/opiecam pics/camera apps/Applications/camera.desktop 2Files: bin/opiecam bin/capture pics/camera apps/Applications/camera.desktop
3Priority: optional 3Priority: optional
4Section: opie/applications 4Section: opie/applications
5Maintainer: Michael 'Mickey' Lauer <mickeyl@handhelds.org> 5Maintainer: Michael 'Mickey' Lauer <mickeyl@handhelds.org>
6Architecture: arm 6Architecture: arm
7Version: 1.0 7Version: 1.0.1-$SUB_VERSION
8Depends: task-opie-minimal, libopie2 (1.8.1) 8Depends: task-opie-minimal, libopie2 (1.8.1)
9Description: A Camera Application 9Description: A Camera Application
10 A Camera Application to use with the Sharp CE-AG06. 10 A Camera Application to use with the Sharp CE-AG06.
diff --git a/noncore/multimedia/camera/previewwidget.cpp b/noncore/multimedia/camera/previewwidget.cpp
deleted file mode 100644
index 08330d0..0000000
--- a/noncore/multimedia/camera/previewwidget.cpp
+++ b/dev/null
@@ -1,88 +0,0 @@
1/**********************************************************************
2** Copyright (C) 2002 Michael 'Mickey' Lauer. All rights reserved.
3**
4** This file is part of Opie Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14**********************************************************************/
15
16#include "previewwidget.h"
17#include "zcameraio.h"
18
19#include <opie2/odebug.h>
20
21#include <assert.h>
22
23PreviewWidget::PreviewWidget( QWidget * parent, const char * name, WFlags f )
24 :QLabel( parent, name, f )
25{
26 #ifndef QT_NO_DEBUG
27 setBackgroundColor( QColor( 255, 0, 0 ) );
28 #else
29 setBackgroundMode( NoBackground );
30 #endif
31
32 #ifndef QT_NO_DEBUG
33 if ( ZCameraIO::instance()->isOpen() ) startTimer( 1500 );
34 #else
35 if ( ZCameraIO::instance()->isOpen() ) startTimer( 200 );
36 #endif
37};
38
39
40PreviewWidget::~PreviewWidget()
41{
42}
43
44
45void PreviewWidget::resizeEvent( QResizeEvent* e )
46{
47 QLabel::resizeEvent( e );
48 int w = e->size().width();
49 int h = e->size().height();
50 ZCameraIO::instance()->setCaptureFrame( e->size().width(),
51 e->size().height(),
52 256,
53 w < h );
54}
55
56
57void PreviewWidget::timerEvent( QTimerEvent* )
58{
59 //QDirectPainter fb( this );
60 //ZCameraIO::instance()->snapshot( fb.frameBuffer() );
61
62 if ( ZCameraIO::instance()->snapshot( &i ) )
63 {
64 p.convertFromImage( i );
65 setPixmap( p );
66 }
67}
68
69
70void PreviewWidget::mousePressEvent( QMouseEvent* )
71{
72 emit contextMenuRequested();
73}
74
75
76void PreviewWidget::setRefreshingRate( int ms )
77{
78 killTimers();
79 if ( ms )
80 startTimer( ms );
81}
82
83
84void PreviewWidget::refresh()
85{
86 QTimerEvent t( 10 ); // event id is meaningless in this case
87 timerEvent( &t );
88}
diff --git a/noncore/multimedia/camera/previewwidget.h b/noncore/multimedia/camera/previewwidget.h
deleted file mode 100644
index d37f80f..0000000
--- a/noncore/multimedia/camera/previewwidget.h
+++ b/dev/null
@@ -1,50 +0,0 @@
1/**********************************************************************
2** Copyright (C) 2003 Michael 'Mickey' Lauer. All rights reserved.
3**
4** This file is part of Opie Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14**********************************************************************/
15
16#ifndef PREVIEWWIDGET_H
17#define PREVIEWWIDGET_H
18
19#include <qlabel.h>
20#include <qimage.h>
21#include <qpixmap.h>
22
23class QTimerEvent;
24class QResizeEvent;
25
26class PreviewWidget: public QLabel
27{
28 Q_OBJECT
29
30 public:
31 PreviewWidget( QWidget * parent = 0, const char * name = 0, WFlags f = 0 );
32 virtual ~PreviewWidget();
33
34 void setRefreshingRate( int ms );
35 void refresh();
36
37 protected:
38 virtual void timerEvent( QTimerEvent* );
39 virtual void resizeEvent( QResizeEvent* );
40 virtual void mousePressEvent( QMouseEvent* );
41
42 signals:
43 void contextMenuRequested();
44
45 private:
46 QPixmap p;
47 QImage i;
48};
49
50#endif