/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

/*! 
    \class QMovie

    \brief The QMovie class is a convenience class for playing movies
    with QImageReader.

    \ingroup painting

    This class is used to show simple animations without sound. If you want
    to display video and media content, use the \l{Phonon Module}{Phonon}
    multimedia framework instead.

    First, create a QMovie object by passing either the name of a file or a
    pointer to a QIODevice containing an animated image format to QMovie's
    constructor. You can call isValid() to check if the image data is valid,
    before starting the movie. To start the movie, call start(). QMovie will
    enter \l Running state, and emit started() and stateChanged(). To get the
    current state of the movie, call state().

    To display the movie in your application, you can pass your QMovie object
    to QLabel::setMovie(). Example:

    \snippet doc/src/snippets/code/src_gui_image_qmovie.cpp 0

    Whenever a new frame is available in the movie, QMovie will emit
    updated(). If the size of the frame changes, resized() is emitted. You can
    call currentImage() or currentPixmap() to get a copy of the current
    frame. When the movie is done, QMovie emits finished(). If any error
    occurs during playback (i.e, the image file is corrupt), QMovie will emit
    error().

    You can control the speed of the movie playback by calling setSpeed(),
    which takes the percentage of the original speed as an argument. Pause the
    movie by calling setPaused(true). QMovie will then enter \l Paused state
    and emit stateChanged(). If you call setPaused(false), QMovie will reenter
    \l Running state and start the movie again. To stop the movie, call
    stop().

    Certain animation formats allow you to set the background color. You can
    call setBackgroundColor() to set the color, or backgroundColor() to
    retrieve the current background color.

    currentFrameNumber() returns the sequence number of the current frame. The
    first frame in the animation has the sequence number 0. frameCount()
    returns the total number of frames in the animation, if the image format
    supports this. You can call loopCount() to get the number of times the
    movie should loop before finishing. nextFrameDelay() returns the number of
    milliseconds the current frame should be displayed.

    QMovie can be instructed to cache frames of an animation by calling
    setCacheMode().

    Call supportedFormats() for a list of formats that QMovie supports.

    \sa QLabel, QImageReader, {Movie Example}
*/

/*! \enum QMovie::MovieState

    This enum describes the different states of QMovie.

    \value NotRunning The movie is not running. This is QMovie's initial
    state, and the state it enters after stop() has been called or the movie
    is finished.

    \value Paused The movie is paused, and QMovie stops emitting updated() or
    resized(). This state is entered after calling pause() or
    setPaused(true). The current frame number it kept, and the movie will
    continue with the next frame when unpause() or setPaused(false) is called.

    \value Running The movie is running.
*/

/*! \enum QMovie::CacheMode

    This enum describes the different cache modes of QMovie.

    \value CacheNone No frames are cached (the default).

    \value CacheAll All frames are cached.
*/

/*! \fn void QMovie::started()

    This signal is emitted after QMovie::start() has been called, and QMovie
    has entered QMovie::Running state.
*/

/*! \fn void QMovie::resized(const QSize &size)

    This signal is emitted when the current frame has been resized to \a
    size. This effect is sometimes used in animations as an alternative to
    replacing the frame. You can call currentImage() or currentPixmap() to get a
    copy of the updated frame.
*/

/*! \fn void QMovie::updated(const QRect &rect)

    This signal is emitted when the rect \a rect in the current frame has been
    updated. You can call currentImage() or currentPixmap() to get a copy of the
    updated frame.
*/

/*! \fn void QMovie::frameChanged(int frameNumber)
    \since 4.1

    This signal is emitted when the frame number has changed to
    \a frameNumber.  You can call currentImage() or currentPixmap() to get a
    copy of the frame.
*/

/*! 
    \fn void QMovie::stateChanged(QMovie::MovieState state)

    This signal is emitted every time the state of the movie changes. The new
    state is specified by \a state.

    \sa QMovie::state()
*/

/*! \fn void QMovie::error(QImageReader::ImageReaderError error)

    This signal is emitted by QMovie when the error \a error occurred during
    playback.  QMovie will stop the movie, and enter QMovie::NotRunning state.
*/

/*! \fn void QMovie::finished()

    This signal is emitted when the movie has finished.

    \sa QMovie::stop()
*/

#include "qglobal.h"

#ifndef QT_NO_MOVIE

#include "qmovie.h"
#include "qimage.h"
#include "qimagereader.h"
#include "qpixmap.h"
#include "qrect.h"
#include "qdatetime.h"
#include "qtimer.h"
#include "qpair.h"
#include "qmap.h"
#include "qlist.h"
#include "qbuffer.h"
#include "qdir.h"
#include "private/qobject_p.h"

#define QMOVIE_INVALID_DELAY -1

QT_BEGIN_NAMESPACE

class QFrameInfo
{
public:
    QPixmap pixmap;
    int delay;
    bool endMark;
    inline QFrameInfo(bool endMark)
        : pixmap(QPixmap()), delay(QMOVIE_INVALID_DELAY), endMark(endMark)
    { }
    
    inline QFrameInfo()
        : pixmap(QPixmap()), delay(QMOVIE_INVALID_DELAY), endMark(false)
    { }
    
    inline QFrameInfo(const QPixmap &pixmap, int delay)
        : pixmap(pixmap), delay(delay), endMark(false)
    { }
    
    inline bool isValid()
    {
        return endMark || !(pixmap.isNull() && (delay == QMOVIE_INVALID_DELAY));
    }
    
    inline bool isEndMarker()
    { return endMark; }
    
    static inline QFrameInfo endMarker()
    { return QFrameInfo(true); }
};

class QMoviePrivate : public QObjectPrivate
{
    Q_DECLARE_PUBLIC(QMovie)

public:
    QMoviePrivate(QMovie *qq);
    bool isDone();
    bool next();
    int speedAdjustedDelay(int delay) const;
    bool isValid() const;
    bool jumpToFrame(int frameNumber);
    int frameCount() const;
    bool jumpToNextFrame();
    QFrameInfo infoForFrame(int frameNumber);
    void reset();

    inline void enterState(QMovie::MovieState newState) {
        movieState = newState;
        emit q_func()->stateChanged(newState);
    }

    // private slots
    void _q_loadNextFrame();
    void _q_loadNextFrame(bool starting);

    QImageReader *reader;
    int speed;
    QMovie::MovieState movieState;
    QRect frameRect;
    QPixmap currentPixmap;
    int currentFrameNumber;
    int nextFrameNumber;
    int greatestFrameNumber;
    int nextDelay;
    int playCounter;
    qint64 initialDevicePos;
    QMovie::CacheMode cacheMode;
    bool haveReadAll;
    bool isFirstIteration;
    QMap<int, QFrameInfo> frameMap;
    QString absoluteFilePath;

    QTimer nextImageTimer;
};

/*! \internal
 */
QMoviePrivate::QMoviePrivate(QMovie *qq)
    : reader(0), speed(100), movieState(QMovie::NotRunning),
      currentFrameNumber(-1), nextFrameNumber(0), greatestFrameNumber(-1),
      nextDelay(0), playCounter(-1),
      cacheMode(QMovie::CacheNone), haveReadAll(false), isFirstIteration(true)
{
    q_ptr = qq;
    nextImageTimer.setSingleShot(true);
}

/*! \internal
 */
void QMoviePrivate::reset()
{
    nextImageTimer.stop();
    if (reader->device())
        initialDevicePos = reader->device()->pos();
    currentFrameNumber = -1;
    nextFrameNumber = 0;
    greatestFrameNumber = -1;
    nextDelay = 0;
    playCounter = -1;
    haveReadAll = false;
    isFirstIteration = true;
    frameMap.clear();
}

/*! \internal
 */
bool QMoviePrivate::isDone()
{
    return (playCounter == 0);
}

/*!
    \internal

    Given the original \a delay, this function returns the
    actual number of milliseconds to delay according to
    the current speed. E.g. if the speed is 200%, the
    result will be half of the original delay.
*/
int QMoviePrivate::speedAdjustedDelay(int delay) const
{
    return int( (qint64(delay) * qint64(100) ) / qint64(speed) );
}

/*!
    \internal

    Returns the QFrameInfo for the given \a frameNumber.

    If the frame number is invalid, an invalid QFrameInfo is
    returned.

    If the end of the animation has been reached, a
    special end marker QFrameInfo is returned.

*/
QFrameInfo QMoviePrivate::infoForFrame(int frameNumber)
{
    if (frameNumber < 0)
        return QFrameInfo(); // Invalid

    if (haveReadAll && (frameNumber > greatestFrameNumber)) {
        if (frameNumber == greatestFrameNumber+1)
            return QFrameInfo::endMarker();
        return QFrameInfo(); // Invalid
    }

    if (cacheMode == QMovie::CacheNone) {
        if (frameNumber != currentFrameNumber+1) {
            // Non-sequential frame access
            if (!reader->jumpToImage(frameNumber)) {
                if (frameNumber == 0) {
                    // Special case: Attempt to "rewind" so we can loop
                    // ### This could be implemented as QImageReader::rewind()
                    if (reader->device()->isSequential())
                        return QFrameInfo(); // Invalid
                    QString fileName = reader->fileName();
                    QByteArray format = reader->format();
                    QIODevice *device = reader->device();
                    QColor bgColor = reader->backgroundColor();
                    QSize scaledSize = reader->scaledSize();
                    delete reader;
                    if (fileName.isEmpty())
                        reader = new QImageReader(device, format);
                    else
                        reader = new QImageReader(absoluteFilePath, format);
                    (void)reader->canRead(); // Provoke a device->open() call
                    reader->device()->seek(initialDevicePos);
                    reader->setBackgroundColor(bgColor);
                    reader->setScaledSize(scaledSize);
                } else {
                    return QFrameInfo(); // Invalid
                }
            }
        }
        if (reader->canRead()) {
            // reader says we can read. Attempt to actually read image
            QImage anImage = reader->read();
            if (anImage.isNull()) {
                // Reading image failed.
                return QFrameInfo(); // Invalid
            }
            if (frameNumber > greatestFrameNumber)
                greatestFrameNumber = frameNumber;
            QPixmap aPixmap = QPixmap::fromImage(anImage);
            int aDelay = reader->nextImageDelay();
            return QFrameInfo(aPixmap, aDelay);
        } else {
            // We've read all frames now. Return an end marker
            haveReadAll = true;
            return QFrameInfo::endMarker();
        }
    }

    // CacheMode == CacheAll
    if (frameNumber > greatestFrameNumber) {
        // Frame hasn't been read from file yet. Try to do it
        for (int i = greatestFrameNumber + 1; i <= frameNumber; ++i) {
            if (reader->canRead()) {
                // reader says we can read. Attempt to actually read image
                QImage anImage = reader->read();
                if (anImage.isNull()) {
                    // Reading image failed.
                    return QFrameInfo(); // Invalid
                }
                greatestFrameNumber = i;
                QPixmap aPixmap = QPixmap::fromImage(anImage);
                int aDelay = reader->nextImageDelay();
                QFrameInfo info(aPixmap, aDelay);
                // Cache it!
                frameMap.insert(i, info);
                if (i == frameNumber) {
                    return info;
                }
            } else {
                // We've read all frames now. Return an end marker
                haveReadAll = true;
                return QFrameInfo::endMarker();
            }
        }
    }
    // Return info for requested (cached) frame
    return frameMap.value(frameNumber);
}

/*!
    \internal

    Attempts to advance the animation to the next frame.
    If successful, currentFrameNumber, currentPixmap and
    nextDelay are updated accordingly, and true is returned.
    Otherwise, false is returned.
    When false is returned, isDone() can be called to
    determine whether the animation ended gracefully or
    an error occurred when reading the frame.
*/
bool QMoviePrivate::next()
{
    QTime time;
    time.start();
    QFrameInfo info = infoForFrame(nextFrameNumber);
    if (!info.isValid())
        return false;
    if (info.isEndMarker()) {
        // We reached the end of the animation.
        if (isFirstIteration) {
            if (nextFrameNumber == 0) {
                // No frames could be read at all (error).
                return false;
            }
            // End of first iteration. Initialize play counter
            playCounter = reader->loopCount();
            isFirstIteration = false;
        }
        // Loop as appropriate
        if (playCounter != 0) {
            if (playCounter != -1) // Infinite?
                playCounter--;     // Nope
            nextFrameNumber = 0;
            return next();
        }
        // Loop no more. Done
        return false;
    }
    // Image and delay OK, update internal state
    currentFrameNumber = nextFrameNumber++;
    QSize scaledSize = reader->scaledSize();
    if (scaledSize.isValid() && (scaledSize != info.pixmap.size()))
        currentPixmap = QPixmap::fromImage( info.pixmap.toImage().scaled(scaledSize) );
    else
        currentPixmap = info.pixmap;
    nextDelay = speedAdjustedDelay(info.delay);
    // Adjust delay according to the time it took to read the frame
    int processingTime = time.elapsed();
    if (processingTime > nextDelay)
        nextDelay = 0;
    else
        nextDelay = nextDelay - processingTime;
    return true;
}

/*! \internal
 */
void QMoviePrivate::_q_loadNextFrame()
{
    _q_loadNextFrame(false);
}

void QMoviePrivate::_q_loadNextFrame(bool starting)
{
    Q_Q(QMovie);
    if (next()) {
        if (starting && movieState == QMovie::NotRunning) {
            enterState(QMovie::Running);
            emit q->started();
        }

        if (frameRect.size() != currentPixmap.rect().size()) {
            frameRect = currentPixmap.rect();
            emit q->resized(frameRect.size());
        }

        emit q->updated(frameRect);
        emit q->frameChanged(currentFrameNumber);

        if (movieState == QMovie::Running)
            nextImageTimer.start(nextDelay);
    } else {
        // Could not read another frame
        if (!isDone()) {
            emit q->error(reader->error());
        }

        // Graceful finish
        if (movieState != QMovie::Paused) {
            nextFrameNumber = 0;
            isFirstIteration = true;
            playCounter = -1;
            enterState(QMovie::NotRunning);
            emit q->finished();
        }
    }
}

/*!
    \internal
*/
bool QMoviePrivate::isValid() const
{
    return (greatestFrameNumber >= 0) // have we seen valid data
        || reader->canRead(); // or does the reader see valid data
}

/*!
    \internal
*/
bool QMoviePrivate::jumpToFrame(int frameNumber)
{
    if (frameNumber < 0)
        return false;
    if (currentFrameNumber == frameNumber)
        return true;
    nextFrameNumber = frameNumber;
    if (movieState == QMovie::Running)
        nextImageTimer.stop();
    _q_loadNextFrame();
    return (nextFrameNumber == currentFrameNumber+1);
}

/*!
    \internal
*/
int QMoviePrivate::frameCount() const
{
    int result;
    if ((result = reader->imageCount()) != 0)
        return result;
    if (haveReadAll)
        return greatestFrameNumber+1;
    return 0; // Don't know
}

/*!
    \internal
*/
bool QMoviePrivate::jumpToNextFrame()
{
    return jumpToFrame(currentFrameNumber+1);
}

/*!
    Constructs a QMovie object, passing the \a parent object to QObject's
    constructor.

    \sa setFileName(), setDevice(), setFormat()
 */
QMovie::QMovie(QObject *parent)
    : QObject(*new QMoviePrivate(this), parent)
{
    Q_D(QMovie);
    d->reader = new QImageReader;
    connect(&d->nextImageTimer, SIGNAL(timeout()), this, SLOT(_q_loadNextFrame()));
}

/*!
    Constructs a QMovie object. QMovie will use read image data from \a
    device, which it assumes is open and readable. If \a format is not empty,
    QMovie will use the image format \a format for decoding the image
    data. Otherwise, QMovie will attempt to guess the format.

    The \a parent object is passed to QObject's constructor.
 */
QMovie::QMovie(QIODevice *device, const QByteArray &format, QObject *parent)
    : QObject(*new QMoviePrivate(this), parent)
{
    Q_D(QMovie);
    d->reader = new QImageReader(device, format);
    d->initialDevicePos = device->pos();
    connect(&d->nextImageTimer, SIGNAL(timeout()), this, SLOT(_q_loadNextFrame()));
}

/*!
    Constructs a QMovie object. QMovie will use read image data from \a
    fileName. If \a format is not empty, QMovie will use the image format \a
    format for decoding the image data. Otherwise, QMovie will attempt to
    guess the format.

    The \a parent object is passed to QObject's constructor.
 */
QMovie::QMovie(const QString &fileName, const QByteArray &format, QObject *parent)
    : QObject(*new QMoviePrivate(this), parent)
{
    Q_D(QMovie);
    d->absoluteFilePath = QDir(fileName).absolutePath();
    d->reader = new QImageReader(fileName, format);
    if (d->reader->device())
        d->initialDevicePos = d->reader->device()->pos();
    connect(&d->nextImageTimer, SIGNAL(timeout()), this, SLOT(_q_loadNextFrame()));
}

/*!
    Destructs the QMovie object.
*/
QMovie::~QMovie()
{
    Q_D(QMovie);
    delete d->reader;
}

/*!
    Sets the current device to \a device. QMovie will read image data from
    this device when the movie is running.

    \sa device(), setFormat()
*/
void QMovie::setDevice(QIODevice *device)
{
    Q_D(QMovie);
    d->reader->setDevice(device);
    d->reset();
}

/*!
    Returns the device QMovie reads image data from. If no device has
    currently been assigned, 0 is returned.

    \sa setDevice(), fileName()
*/
QIODevice *QMovie::device() const
{
    Q_D(const QMovie);
    return d->reader->device();
}

/*!
    Sets the name of the file that QMovie reads image data from, to \a
    fileName.

    \sa fileName(), setDevice(), setFormat()
*/
void QMovie::setFileName(const QString &fileName)
{
    Q_D(QMovie);
    d->absoluteFilePath = QDir(fileName).absolutePath();
    d->reader->setFileName(fileName);
    d->reset();
}

/*!
    Returns the name of the file that QMovie reads image data from. If no file
    name has been assigned, or if the assigned device is not a file, an empty
    QString is returned.

    \sa setFileName(), device()
*/
QString QMovie::fileName() const
{
    Q_D(const QMovie);
    return d->reader->fileName();
}

/*!
    Sets the format that QMovie will use when decoding image data, to \a
    format. By default, QMovie will attempt to guess the format of the image
    data.

    You can call supportedFormats() for the full list of formats
    QMovie supports.

    \sa QImageReader::supportedImageFormats()
*/
void QMovie::setFormat(const QByteArray &format)
{
    Q_D(QMovie);
    d->reader->setFormat(format);
}

/*!
    Returns the format that QMovie uses when decoding image data. If no format
    has been assigned, an empty QByteArray() is returned.

    \sa setFormat()
*/
QByteArray QMovie::format() const
{
    Q_D(const QMovie);
    return d->reader->format();
}

/*!
    For image formats that support it, this function sets the background color
    to \a color.

    \sa backgroundColor()
*/
void QMovie::setBackgroundColor(const QColor &color)
{
    Q_D(QMovie);
    d->reader->setBackgroundColor(color);
}

/*!
    Returns the background color of the movie. If no background color has been
    assigned, an invalid QColor is returned.

    \sa setBackgroundColor()
*/
QColor QMovie::backgroundColor() const
{
    Q_D(const QMovie);
    return d->reader->backgroundColor();
}

/*!
    Returns the current state of QMovie.

    \sa MovieState, stateChanged()
*/
QMovie::MovieState QMovie::state() const
{
    Q_D(const QMovie);
    return d->movieState;
}

/*!
    Returns the rect of the last frame. If no frame has yet been updated, an
    invalid QRect is returned.

    \sa currentImage(), currentPixmap()
*/
QRect QMovie::frameRect() const
{
    Q_D(const QMovie);
    return d->frameRect;
}

/*! \fn QImage QMovie::framePixmap() const

    Use currentPixmap() instead.
*/

/*! \fn void QMovie::pause()

    Use setPaused(true) instead.
*/

/*! \fn void QMovie::unpause()

    Use setPaused(false) instead.
*/

/*!
    Returns the current frame as a QPixmap.

    \sa currentImage(), updated()
*/
QPixmap QMovie::currentPixmap() const
{
    Q_D(const QMovie);
    return d->currentPixmap;
}

/*! \fn QImage QMovie::frameImage() const

    Use currentImage() instead.
*/

/*!
    Returns the current frame as a QImage.

    \sa currentPixmap(), updated()
*/
QImage QMovie::currentImage() const
{
    Q_D(const QMovie);
    return d->currentPixmap.toImage();
}

/*!
    Returns true if the movie is valid (e.g., the image data is readable and
    the image format is supported); otherwise returns false.
*/
bool QMovie::isValid() const
{
    Q_D(const QMovie);
    return d->isValid();
}

/*! \fn bool QMovie::running() const

    Use state() instead.
*/

/*! \fn bool QMovie::isNull() const

    Use isValid() instead.
*/

/*! \fn int QMovie::frameNumber() const

    Use currentFrameNumber() instead.
*/

/*! \fn bool QMovie::paused() const

    Use state() instead.
*/

/*! \fn bool QMovie::finished() const

    Use state() instead.
*/

/*! \fn void QMovie::restart()

    Use stop() and start() instead.
*/

/*!
    \fn void QMovie::step()

    Use jumpToNextFrame() instead.
*/

/*!
    Returns the number of frames in the movie.

    Certain animation formats do not support this feature, in which
    case 0 is returned.
*/
int QMovie::frameCount() const
{
    Q_D(const QMovie);
    return d->frameCount();
}

/*!
    Returns the number of milliseconds QMovie will wait before updating the
    next frame in the animation.
*/
int QMovie::nextFrameDelay() const
{
    Q_D(const QMovie);
    return d->nextDelay;
}

/*!
    Returns the sequence number of the current frame. The number of the first
    frame in the movie is 0.
*/
int QMovie::currentFrameNumber() const
{
    Q_D(const QMovie);
    return d->currentFrameNumber;
}

/*!
    Jumps to the next frame. Returns true on success; otherwise returns false.
*/
bool QMovie::jumpToNextFrame()
{
    Q_D(QMovie);
    return d->jumpToNextFrame();
}

/*!
    Jumps to frame number \a frameNumber. Returns true on success; otherwise
    returns false.
*/
bool QMovie::jumpToFrame(int frameNumber)
{
    Q_D(QMovie);
    return d->jumpToFrame(frameNumber);
}

/*!
    Returns the number of times the movie will loop before it finishes.
    If the movie will only play once (no looping), loopCount returns 0.
    If the movie loops forever, loopCount returns -1.

    Note that, if the image data comes from a sequential device (e.g. a
    socket), QMovie can only loop the movie if the cacheMode is set to
    QMovie::CacheAll.
*/
int QMovie::loopCount() const
{
    Q_D(const QMovie);
    return d->reader->loopCount();
}

/*!
    If \a paused is true, QMovie will enter \l Paused state and emit
    stateChanged(Paused); otherwise it will enter \l Running state and emit
    stateChanged(Running).

    \sa state()
*/
void QMovie::setPaused(bool paused)
{
    Q_D(QMovie);
    if (paused) {
        if (d->movieState == NotRunning)
            return;
        d->enterState(Paused);
        d->nextImageTimer.stop();
    } else {
        if (d->movieState == Running)
            return;
        d->enterState(Running);
        d->nextImageTimer.start(nextFrameDelay());
    }
}

/*!
    \property QMovie::speed
    \brief the movie's speed

    The speed is measured in percentage of the original movie speed.
    The default speed is 100%.
    Example:

    \snippet doc/src/snippets/code/src_gui_image_qmovie.cpp 1
*/
void QMovie::setSpeed(int percentSpeed)
{
    Q_D(QMovie);
    d->speed = percentSpeed;
}

int QMovie::speed() const
{
    Q_D(const QMovie);
    return d->speed;
}

/*!
    Starts the movie. QMovie will enter \l Running state, and start emitting
    updated() and resized() as the movie progresses.

    If QMovie is in the \l Paused state, this function is equivalent
    to calling setPaused(false). If QMovie is already in the \l
    Running state, this function does nothing.

    \sa stop(), setPaused()
*/
void QMovie::start()
{
    Q_D(QMovie);
    if (d->movieState == NotRunning) {
        d->_q_loadNextFrame(true);
    } else if (d->movieState == Paused) {
        setPaused(false);
    }
}

/*!
    Stops the movie. QMovie enters \l NotRunning state, and stops emitting
    updated() and resized(). If start() is called again, the movie will
    restart from the beginning.

    If QMovie is already in the \l NotRunning state, this function
    does nothing.

    \sa start(), setPaused()
*/
void QMovie::stop()
{
    Q_D(QMovie);
    if (d->movieState == NotRunning)
        return;
    d->enterState(NotRunning);
    d->nextImageTimer.stop();
    d->nextFrameNumber = 0;
}

/*!
    \since 4.1

    Returns the scaled size of frames.

    \sa QImageReader::scaledSize()
*/
QSize QMovie::scaledSize()
{
    Q_D(QMovie);
    return d->reader->scaledSize();
}

/*!
    \since 4.1

    Sets the scaled frame size to \a size.

    \sa QImageReader::setScaledSize()
*/
void QMovie::setScaledSize(const QSize &size)
{
    Q_D(QMovie);
    d->reader->setScaledSize(size);
}

/*!
    \since 4.1

    Returns the list of image formats supported by QMovie.

    \sa QImageReader::supportedImageFormats()
*/
QList<QByteArray> QMovie::supportedFormats()
{
    QList<QByteArray> list = QImageReader::supportedImageFormats();
    QMutableListIterator<QByteArray> it(list);
    QBuffer buffer;
    buffer.open(QIODevice::ReadOnly);
    while (it.hasNext()) {
        QImageReader reader(&buffer, it.next());
        if (!reader.supportsAnimation())
            it.remove();
    }
    return list;
}

/*!
    \property QMovie::cacheMode
    \brief the movie's cache mode

    Caching frames can be useful when the underlying animation format handler
    that QMovie relies on to decode the animation data does not support
    jumping to particular frames in the animation, or even "rewinding" the
    animation to the beginning (for looping). Furthermore, if the image data
    comes from a sequential device, it is not possible for the underlying
    animation handler to seek back to frames whose data has already been read
    (making looping altogether impossible).

    To aid in such situations, a QMovie object can be instructed to cache the
    frames, at the added memory cost of keeping the frames in memory for the
    lifetime of the object.

    By default, this property is set to \l CacheNone.

    \sa QMovie::CacheMode
*/

QMovie::CacheMode QMovie::cacheMode() const
{
    Q_D(const QMovie);
    return d->cacheMode;
}

void QMovie::setCacheMode(CacheMode cacheMode)
{
    Q_D(QMovie);
    d->cacheMode = cacheMode;
}

/*!
  \internal
*/
QMovie::CacheMode QMovie::cacheMode()
{
    Q_D(QMovie);
    return d->cacheMode;
}

QT_END_NAMESPACE

#include "moc_qmovie.cpp"

#endif // QT_NO_MOVIE
