source: trunk/src/gui/image/qmovie.cpp@ 439

Last change on this file since 439 was 2, checked in by Dmitry A. Kuminov, 17 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 28.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*!
43 \class QMovie
44
45 \brief The QMovie class is a convenience class for playing movies
46 with QImageReader.
47
48 \ingroup multimedia
49
50 First, create a QMovie object by passing either the name of a file or a
51 pointer to a QIODevice containing an animated image format to QMovie's
52 constructor. You can call isValid() to check if the image data is valid,
53 before starting the movie. To start the movie, call start(). QMovie will
54 enter \l Running state, and emit started() and stateChanged(). To get the
55 current state of the movie, call state().
56
57 To display the movie in your application, you can pass your QMovie object
58 to QLabel::setMovie(). Example:
59
60 \snippet doc/src/snippets/code/src_gui_image_qmovie.cpp 0
61
62 Whenever a new frame is available in the movie, QMovie will emit
63 updated(). If the size of the frame changes, resized() is emitted. You can
64 call currentImage() or currentPixmap() to get a copy of the current
65 frame. When the movie is done, QMovie emits finished(). If any error
66 occurs during playback (i.e, the image file is corrupt), QMovie will emit
67 error().
68
69 You can control the speed of the movie playback by calling setSpeed(),
70 which takes the percentage of the original speed as an argument. Pause the
71 movie by calling setPaused(true). QMovie will then enter \l Paused state
72 and emit stateChanged(). If you call setPaused(false), QMovie will reenter
73 \l Running state and start the movie again. To stop the movie, call
74 stop().
75
76 Certain animation formats allow you to set the background color. You can
77 call setBackgroundColor() to set the color, or backgroundColor() to
78 retrieve the current background color.
79
80 currentFrameNumber() returns the sequence number of the current frame. The
81 first frame in the animation has the sequence number 0. frameCount()
82 returns the total number of frames in the animation, if the image format
83 supports this. You can call loopCount() to get the number of times the
84 movie should loop before finishing. nextFrameDelay() returns the number of
85 milliseconds the current frame should be displayed.
86
87 QMovie can be instructed to cache frames of an animation by calling
88 setCacheMode().
89
90 Call supportedFormats() for a list of formats that QMovie supports.
91
92 \sa QLabel, QImageReader, {Movie Example}
93*/
94
95/*! \enum QMovie::MovieState
96
97 This enum describes the different states of QMovie.
98
99 \value NotRunning The movie is not running. This is QMovie's initial
100 state, and the state it enters after stop() has been called or the movie
101 is finished.
102
103 \value Paused The movie is paused, and QMovie stops emitting updated() or
104 resized(). This state is entered after calling pause() or
105 setPaused(true). The current frame number it kept, and the movie will
106 continue with the next frame when unpause() or setPaused(false) is called.
107
108 \value Running The movie is running.
109*/
110
111/*! \enum QMovie::CacheMode
112
113 This enum describes the different cache modes of QMovie.
114
115 \value CacheNone No frames are cached (the default).
116
117 \value CacheAll All frames are cached.
118*/
119
120/*! \fn void QMovie::started()
121
122 This signal is emitted after QMovie::start() has been called, and QMovie
123 has entered QMovie::Running state.
124*/
125
126/*! \fn void QMovie::resized(const QSize &size)
127
128 This signal is emitted when the current frame has been resized to \a
129 size. This effect is sometimes used in animations as an alternative to
130 replacing the frame. You can call currentImage() or currentPixmap() to get a
131 copy of the updated frame.
132*/
133
134/*! \fn void QMovie::updated(const QRect &rect)
135
136 This signal is emitted when the rect \a rect in the current frame has been
137 updated. You can call currentImage() or currentPixmap() to get a copy of the
138 updated frame.
139*/
140
141/*! \fn void QMovie::frameChanged(int frameNumber)
142 \since 4.1
143
144 This signal is emitted when the frame number has changed to
145 \a frameNumber. You can call currentImage() or currentPixmap() to get a
146 copy of the frame.
147*/
148
149/*!
150 \fn void QMovie::stateChanged(QMovie::MovieState state)
151
152 This signal is emitted every time the state of the movie changes. The new
153 state is specified by \a state.
154
155 \sa QMovie::state()
156*/
157
158/*! \fn void QMovie::error(QImageReader::ImageReaderError error)
159
160 This signal is emitted by QMovie when the error \a error occurred during
161 playback. QMovie will stop the movie, and enter QMovie::NotRunning state.
162*/
163
164/*! \fn void QMovie::finished()
165
166 This signal is emitted when the movie has finished.
167
168 \sa QMovie::stop()
169*/
170
171#include "qglobal.h"
172
173#ifndef QT_NO_MOVIE
174
175#include "qmovie.h"
176#include "qimage.h"
177#include "qimagereader.h"
178#include "qpixmap.h"
179#include "qrect.h"
180#include "qdatetime.h"
181#include "qtimer.h"
182#include "qpair.h"
183#include "qmap.h"
184#include "qlist.h"
185#include "qbuffer.h"
186#include "qdir.h"
187#include "private/qobject_p.h"
188
189#define QMOVIE_INVALID_DELAY -1
190
191QT_BEGIN_NAMESPACE
192
193class QFrameInfo
194{
195public:
196 QPixmap pixmap;
197 int delay;
198 bool endMark;
199 inline QFrameInfo(bool endMark)
200 : pixmap(QPixmap()), delay(QMOVIE_INVALID_DELAY), endMark(endMark)
201 { }
202
203 inline QFrameInfo()
204 : pixmap(QPixmap()), delay(QMOVIE_INVALID_DELAY), endMark(false)
205 { }
206
207 inline QFrameInfo(const QPixmap &pixmap, int delay)
208 : pixmap(pixmap), delay(delay), endMark(false)
209 { }
210
211 inline bool isValid()
212 {
213 return endMark || !(pixmap.isNull() && (delay == QMOVIE_INVALID_DELAY));
214 }
215
216 inline bool isEndMarker()
217 { return endMark; }
218
219 static inline QFrameInfo endMarker()
220 { return QFrameInfo(true); }
221};
222
223class QMoviePrivate : public QObjectPrivate
224{
225 Q_DECLARE_PUBLIC(QMovie)
226
227public:
228 QMoviePrivate(QMovie *qq);
229 bool isDone();
230 bool next();
231 int speedAdjustedDelay(int delay) const;
232 bool isValid() const;
233 bool jumpToFrame(int frameNumber);
234 int frameCount() const;
235 bool jumpToNextFrame();
236 QFrameInfo infoForFrame(int frameNumber);
237 void reset();
238
239 inline void enterState(QMovie::MovieState newState) {
240 movieState = newState;
241 emit q_func()->stateChanged(newState);
242 }
243
244 // private slots
245 void _q_loadNextFrame();
246 void _q_loadNextFrame(bool starting);
247
248 QImageReader *reader;
249 int speed;
250 QMovie::MovieState movieState;
251 QRect frameRect;
252 QPixmap currentPixmap;
253 int currentFrameNumber;
254 int nextFrameNumber;
255 int greatestFrameNumber;
256 int nextDelay;
257 int playCounter;
258 qint64 initialDevicePos;
259 QMovie::CacheMode cacheMode;
260 bool haveReadAll;
261 bool isFirstIteration;
262 QMap<int, QFrameInfo> frameMap;
263 QString absoluteFilePath;
264
265 QTimer nextImageTimer;
266};
267
268/*! \internal
269 */
270QMoviePrivate::QMoviePrivate(QMovie *qq)
271 : reader(0), speed(100), movieState(QMovie::NotRunning),
272 currentFrameNumber(-1), nextFrameNumber(0), greatestFrameNumber(-1),
273 nextDelay(0), playCounter(-1),
274 cacheMode(QMovie::CacheNone), haveReadAll(false), isFirstIteration(true)
275{
276 q_ptr = qq;
277 nextImageTimer.setSingleShot(true);
278}
279
280/*! \internal