/****************************************************************************
**
** 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$
**
****************************************************************************/

#include "qpicture.h"
#include <private/qpicture_p.h>

#ifndef QT_NO_PICTURE

#include <private/qfactoryloader_p.h>
#include <private/qpaintengine_pic_p.h>

#include "qdatastream.h"
#include "qfile.h"
#include "qimage.h"
#include "qmutex.h"
#include "qpainter.h"
#include "qpainterpath.h"
#include "qpixmap.h"
#include "qregion.h"
#include "qdebug.h"

QT_BEGIN_NAMESPACE

void qt_format_text(const QFont &fnt, const QRectF &_r,
                    int tf, const QTextOption *opt, const QString& str, QRectF *brect,
                    int tabstops, int *, int tabarraylen,
                    QPainter *painter);

/*!
    \class QPicture
    \brief The QPicture class is a paint device that records and
    replays QPainter commands.

    \ingroup painting
    \ingroup shared


    A picture serializes painter commands to an IO device in a
    platform-independent format. They are sometimes referred to as meta-files.

    Qt pictures use a proprietary binary format. Unlike native picture
    (meta-file) formats on many window systems, Qt pictures have no
    limitations regarding their contents. Everything that can be
    painted on a widget or pixmap (e.g., fonts, pixmaps, regions,
    transformed graphics, etc.)  can also be stored in a picture.

    QPicture is resolution independent, i.e. a QPicture can be
    displayed on different devices (for example svg, pdf, ps, printer
    and screen) looking the same. This is, for instance, needed for
    WYSIWYG print preview. QPicture runs in the default system dpi,
    and scales the painter to match differences in resolution
    depending on the window system.

    Example of how to record a picture:
    \snippet doc/src/snippets/picture/picture.cpp 0

    Note that the list of painter commands is reset on each call to
    the QPainter::begin() function.

    Example of how to replay a picture:
    \snippet doc/src/snippets/picture/picture.cpp 1

    Pictures can also be drawn using play(). Some basic data about a
    picture is available, for example, size(), isNull() and
    boundingRect().

    \sa QMovie
*/

const char  *qt_mfhdr_tag = "QPIC"; // header tag
static const quint16 mfhdr_maj = 11; // major version #
static const quint16 mfhdr_min = 0; // minor version #
Q_GUI_EXPORT extern int qt_defaultDpiX();
Q_GUI_EXPORT extern int qt_defaultDpiY();

/*!
    Constructs an empty picture.

    The \a formatVersion parameter may be used to \e create a QPicture
    that can be read by applications that are compiled with earlier
    versions of Qt.

    Note that the default formatVersion is -1 which signifies the
    current release, i.e. for Qt 4.0 a formatVersion of 7 is the same
    as the default formatVersion of -1.

    Reading pictures generated by earlier versions of Qt is not
    supported in Qt 4.0.
*/

QPicture::QPicture(int formatVersion)
    : QPaintDevice(),
      d_ptr(new QPicturePrivate)
{
    Q_D(QPicture);

    if (formatVersion == 0)
        qWarning("QPicture: invalid format version 0");

    // still accept the 0 default from before Qt 3.0.
    if (formatVersion > 0 && formatVersion != (int)mfhdr_maj) {
        d->formatMajor = formatVersion;
        d->formatMinor = 0;
        d->formatOk = false;
    } else {
        d->resetFormat();
    }
}

/*!
    Constructs a copy of \a pic.

    This constructor is fast thanks to \l{implicit sharing}.
*/

QPicture::QPicture(const QPicture &pic)
    : QPaintDevice(), d_ptr(pic.d_ptr)
{
}

/*! \internal */
QPicture::QPicture(QPicturePrivate &dptr)
    : QPaintDevice(),
      d_ptr(&dptr)
{
}

/*!
    Destroys the picture.
*/
QPicture::~QPicture()
{
}

/*!
  \internal
*/
int QPicture::devType() const
{
    return QInternal::Picture;
}

/*!
    \fn bool QPicture::isNull() const

    Returns true if the picture contains no data; otherwise returns
    false.
*/

/*!
    \fn uint QPicture::size() const

    Returns the size of the picture data.

    \sa data()
*/

/*!
    \fn const char* QPicture::data() const

    Returns a pointer to the picture data. The pointer is only valid
    until the next non-const function is called on this picture. The
    returned pointer is 0 if the picture contains no data.

    \sa size(), isNull()
*/


bool QPicture::isNull() const
{
    return d_func()->pictb.buffer().isNull();
}

uint QPicture::size() const
{
    return d_func()->pictb.buffer().size();
}

const char* QPicture::data() const
{
    return d_func()->pictb.buffer();
}

void QPicture::detach()
{
    d_ptr.detach();
}

bool QPicture::isDetached() const
{
    return d_func()->ref == 1;
}

/*!
    Sets the picture data directly from \a data and \a size. This
    function copies the input data.

    \sa data(), size()
*/

void QPicture::setData(const char* data, uint size)
{
    detach();
    d_func()->pictb.setData(data, size);
    d_func()->resetFormat();                                // we'll have to check
}


/*!
    Loads a picture from the file specified by \a fileName and returns
    true if successful; otherwise returns false.

    Please note that the \a format parameter has been deprecated and
    will have no effect.

    \sa save()
*/

bool QPicture::load(const QString &fileName, const char *format)
{
    QFile f(fileName);
    if (!f.open(QIODevice::ReadOnly))
        return false;
    return load(&f, format);
}

/*!
    \overload

    \a dev is the device to use for loading.
*/

bool QPicture::load(QIODevice *dev, const char *format)
{
    if(format) {
#ifndef QT_NO_PICTUREIO
        QPictureIO io(dev, format);
        bool result = io.read();
        if (result) {
            operator=(io.picture());

        } else if (format)
#else
            bool result = false;
#endif
        {
            qWarning("QPicture::load: No such picture format: %s", format);
        }
        return result;
    }

    detach();
    QByteArray a = dev->readAll();

    d_func()->pictb.setData(a);                        // set byte array in buffer
    return d_func()->checkFormat();
}

/*!
    Saves a picture to the file specified by \a fileName and returns
    true if successful; otherwise returns false.

    Please note that the \a format parameter has been deprecated and
    will have no effect.

    \sa load()
*/

bool QPicture::save(const QString &fileName, const char *format)
{
    if (paintingActive()) {
        qWarning("QPicture::save: still being painted on. "
                  "Call QPainter::end() first");
        return false;
    }


    if(format) {
#ifndef QT_NO_PICTUREIO
        QPictureIO io(fileName, format);
        bool result = io.write();
        if (result) {
            operator=(io.picture());
        } else if (format)
#else
        bool result = false;
#endif
        {
            qWarning("QPicture::save: No such picture format: %s", format);
        }
        return result;
    }

    QFile f(fileName);
    if (!f.open(QIODevice::WriteOnly))
        return false;
    return save(&f, format);
}

/*!
    \overload

    \a dev is the device to use for saving.
*/

bool QPicture::save(QIODevice *dev, const char *format)
{
    if (paintingActive()) {
        qWarning("QPicture::save: still being painted on. "
                  "Call QPainter::end() first");
        return false;
    }

    if(format) {
#ifndef QT_NO_PICTUREIO
        QPictureIO io(dev, format);
        bool result = io.write();
        if (result) {
            operator=(io.picture());
        } else if (format)
#else
        bool result = false;
#endif
        {
            qWarning("QPicture::save: No such picture format: %s", format);
        }
        return result;
    }

    dev->write(d_func()->pictb.buffer(), d_func()->pictb.buffer().size());
    return true;
}

/*!
    Returns the picture's bounding rectangle or an invalid rectangle
    if the picture contains no data.
*/

QRect QPicture::boundingRect() const
{
    Q_D(const QPicture);
    // Use override rect where possible.
    if (!d->override_rect.isEmpty())
        return d->override_rect;

    if (!d->formatOk)
        d_ptr->checkFormat();

    return d->brect;
}

/*!
    Sets the picture's bounding rectangle to \a r. The automatically
    calculated value is overridden.
*/

void QPicture::setBoundingRect(const QRect &r)
{
    d_func()->override_rect = r;
}

/*!
    Replays the picture using \a painter, and returns true if
    successful; otherwise returns false.

    This function does exactly the same as QPainter::drawPicture()
    with (x, y) = (0, 0).
*/

bool QPicture::play(QPainter *painter)
{
    Q_D(QPicture);

    if (d->pictb.size() == 0)                        // nothing recorded
        return true;

    if (!d->formatOk && !d->checkFormat())
        return false;

    d->pictb.open(QIODevice::ReadOnly);                // open buffer device
    QDataStream s;
    s.setDevice(&d->pictb);                        // attach data stream to buffer
    s.device()->seek(10);                        // go directly to the data
    s.setVersion(d->formatMajor == 4 ? 3 : d->formatMajor);

    quint8  c, clen;
    quint32 nrecords;
    s >> c >> clen;
    Q_ASSERT(c == QPicturePrivate::PdcBegin);
    // bounding rect was introduced in ver 4. Read in checkFormat().
    if (d->formatMajor >= 4) {
        qint32 dummy;
        s >> dummy >> dummy >> dummy >> dummy;
    }
    s >> nrecords;
    if (!exec(painter, s, nrecords)) {
        qWarning("QPicture::play: Format error");
        d->pictb.close();
        return false;
    }
    d->pictb.close();
    return true;                                // no end-command
}


//
// QFakeDevice is used to create fonts with a custom DPI
//
class QFakeDevice : public QPaintDevice
{
public:
    QFakeDevice() { dpi_x = qt_defaultDpiX(); dpi_y = qt_defaultDpiY(); }
    void setDpiX(int dpi) { dpi_x = dpi; }
    void setDpiY(int dpi) { dpi_y = dpi; }
    QPaintEngine *paintEngine() const { return 0; }
    int metric(PaintDeviceMetric m) const
    {
        switch(m) {
            case PdmPhysicalDpiX:
            case PdmDpiX:
                return dpi_x;
            case PdmPhysicalDpiY:
            case PdmDpiY:
                return dpi_y;
            default:
                return QPaintDevice::metric(m);
        }
    }

private:
    int dpi_x;
    int dpi_y;
};

/*!
  \internal
  Iterates over the internal picture data and draws the picture using
  \a painter.
*/

bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords)
{
    Q_D(QPicture);
#if defined(QT_DEBUG)
    int                strm_pos;
#endif
    quint8     c;                      // command id
    quint8     tiny_len;               // 8-bit length descriptor
    qint32     len;                    // 32-bit length descriptor
    qint16     i_16, i1_16, i2_16;     // parameters...
    qint8      i_8;
    quint32    ul;
    double     dbl;
    bool       bl;
    QByteArray  str1;
    QString     str;
    QPointF     p, p1, p2;
    QPoint      ip, ip1, ip2;
    QRect       ir;
    QRectF      r;
    QPolygonF   a;
    QPolygon    ia;
    QColor      color;
    QFont       font;
    QPen        pen;
    QBrush      brush;
    QRegion     rgn;
    QMatrix     wmatrix;
    QTransform  matrix;

    QTransform worldMatrix = painter->transform();
    worldMatrix.scale(qreal(painter->device()->logicalDpiX()) / qreal(qt_defaultDpiX()),
                      qreal(painter->device()->logicalDpiY()) / qreal(qt_defaultDpiY()));
    painter->setTransform(worldMatrix);

    while (nrecords-- && !s.atEnd()) {
        s >> c;                 // read cmd
        s >> tiny_len;          // read param length
        if (tiny_len == 255)    // longer than 254 bytes
            s >> len;
        else
            len = tiny_len;
#if defined(QT_DEBUG)
        strm_pos = s.device()->pos();
#endif
        switch (c) {            // exec cmd
        case QPicturePrivate::PdcNOP:
            break;
        case QPicturePrivate::PdcDrawPoint:
            if (d->formatMajor <= 5) {
                s >> ip;
                painter->drawPoint(ip);
            } else {
                s >> p;
                painter->drawPoint(p);
            }
            break;
        case QPicturePrivate::PdcDrawPoints:
// ## implement me in the picture paint engine
//                 s >> a >> i1_32 >> i2_32;
//                 painter->drawPoints(a.mid(i1_32, i2_32));
            break;
        case QPicturePrivate::PdcDrawPath: {
            QPainterPath path;
            s >> path;
            painter->drawPath(path);
            break;
        }
        case QPicturePrivate::PdcDrawLine:
            if (d->formatMajor <= 5) {
                s >> ip1 >> ip2;
                painter->drawLine(ip1, ip2);
            } else {
                s >> p1 >> p2;
                painter->drawLine(p1, p2);
            }
            break;
        case QPicturePrivate::PdcDrawRect:
            if (d->formatMajor <= 5) {
                s >> ir;
                painter->drawRect(ir);
            } else {
                s >> r;
                painter->drawRect(r);
            }
            break;
        case QPicturePrivate::PdcDrawRoundRect:
            if (d->formatMajor <= 5) {
                s >> ir >> i1_16 >> i2_16;
                painter->drawRoundedRect(ir, i1_16, i2_16, Qt::RelativeSize);
            } else {
                s >> r >> i1_16 >> i2_16;
                painter->drawRoundedRect(r, i1_16, i2_16, Qt::RelativeSize);
            }
            break;
        case QPicturePrivate::PdcDrawEllipse:
            if (d->formatMajor <= 5) {
                s >> ir;
                painter->drawEllipse(ir);
            } else {
                s >> r;
                painter->drawEllipse(r);
            }
            break;
        case QPicturePrivate::PdcDrawArc:
            if (d->formatMajor <= 5) {
                s >> ir;
                r = ir;
            } else {
                s >> r;
            }
            s >> i1_16 >> i2_16;
            painter->drawArc(r, i1_16, i2_16);
            break;
        case QPicturePrivate::PdcDrawPie:
            if (d->formatMajor <= 5) {
                s >> ir;
                r = ir;
            } else {
                s >> r;
            }
            s >> i1_16 >> i2_16;
            painter->drawPie(r, i1_16, i2_16);
            break;
        case QPicturePrivate::PdcDrawChord:
            if (d->formatMajor <= 5) {
                s >> ir;
                r = ir;
            } else {
                s >> r;
            }
            s >> i1_16 >> i2_16;
            painter->drawChord(r, i1_16, i2_16);
            break;
        case QPicturePrivate::PdcDrawLineSegments:
            s >> ia;
            painter->drawLines(ia);
            ia.clear();
            break;
        case QPicturePrivate::PdcDrawPolyline:
            if (d->formatMajor <= 5) {
                s >> ia;
                painter->drawPolyline(ia);
                ia.clear();
            } else {
                s >> a;
                painter->drawPolyline(a);
                a.clear();
            }
            break;
        case QPicturePrivate::PdcDrawPolygon:
            if (d->formatMajor <= 5) {
                s >> ia >> i_8;
                painter->drawPolygon(ia, i_8 ? Qt::WindingFill : Qt::OddEvenFill);
                a.clear();
            } else {
                s >> a >> i_8;
                painter->drawPolygon(a, i_8 ? Qt::WindingFill : Qt::OddEvenFill);
                a.clear();
            }
            break;
        case QPicturePrivate::PdcDrawCubicBezier: {
            s >> ia;
            QPainterPath path;
            Q_ASSERT(ia.size() == 4);
            path.moveTo(ia.at(0));
            path.cubicTo(ia.at(1), ia.at(2), ia.at(3));
            painter->strokePath(path, painter->pen());
            a.clear();
        }
            break;
        case QPicturePrivate::PdcDrawText:
            s >> ip >> str1;
            painter->drawText(ip, QString::fromLatin1(str1));
            break;
        case QPicturePrivate::PdcDrawTextFormatted:
            s >> ir >> i_16 >> str1;
            painter->drawText(ir, i_16, QString::fromLatin1(str1));
            break;
        case QPicturePrivate::PdcDrawText2:
            if (d->formatMajor <= 5) {
                s >> ip >> str;
                painter->drawText(ip, str);
            } else {
                s >> p >> str;
                painter->drawText(p, str);
            }
            break;
        case QPicturePrivate::PdcDrawText2Formatted:
            s >> ir;
            s >> i_16;
            s >> str;
            painter->drawText(ir, i_16, str);
            break;
        case QPicturePrivate::PdcDrawTextItem: {
            s >> p >> str >> font >> ul;

            // the text layout direction is not used here because it's already
            // aligned when QPicturePaintEngine::drawTextItem() serializes the
            // drawText() call, therefore ul is unsed in this context

            if (d->formatMajor >= 9) {
                s >> dbl;
                QFont fnt(font);
                if (dbl != 1.0) {
                    QFakeDevice fake;
                    fake.setDpiX(qRound(dbl*qt_defaultDpiX()));
                    fake.setDpiY(qRound(dbl*qt_defaultDpiY()));
                    fnt = QFont(font, &fake);
                }

                qreal justificationWidth;
                s >> justificationWidth;

                int flags = Qt::TextSingleLine | Qt::TextDontClip | Qt::TextForceLeftToRight;

                QSizeF size(1, 1);
                if (justificationWidth > 0) {
                    size.setWidth(justificationWidth);
                    flags |= Qt::TextJustificationForced;
                    flags |= Qt::AlignJustify;
                }

                QFontMetrics fm(fnt);
                QPointF pt(p.x(), p.y() - fm.ascent());
                qt_format_text(fnt, QRectF(pt, size), flags, /*opt*/0,
                               str, /*brect=*/0, /*tabstops=*/0, /*...*/0, /*tabarraylen=*/0, painter);
            } else {
                qt_format_text(font, QRectF(p, QSizeF(1, 1)), Qt::TextSingleLine | Qt::TextDontClip, /*opt*/0,
                               str, /*brect=*/0, /*tabstops=*/0, /*...*/0, /*tabarraylen=*/0, painter);
            }

            break;
        }
        case QPicturePrivate::PdcDrawPixmap: {
            QPixmap pixmap;
            if (d->formatMajor < 4) {
                s >> ip >> pixmap;
                painter->drawPixmap(ip, pixmap);
            } else if (d->formatMajor <= 5) {
                s >> ir >> pixmap;
                painter->drawPixmap(ir, pixmap);
            } else {
                QRectF sr;
                if (d->in_memory_only) {
                    int index;
                    s >> r >> index >> sr;
                    Q_ASSERT(index < d->pixmap_list.size());
                    pixmap = d->pixmap_list.at(index);
                } else {
                    s >> r >> pixmap >> sr;
                }
                painter->drawPixmap(r, pixmap, sr);
            }
        }
            break;
        case QPicturePrivate::PdcDrawTiledPixmap: {
            QPixmap pixmap;
            if (d->in_memory_only) {
                int index;
                s >> r >> index >> p;
                Q_ASSERT(index < d->pixmap_list.size());
                pixmap = d->pixmap_list.at(index);
            } else {
                s >> r >> pixmap >> p;
            }
            painter->drawTiledPixmap(r, pixmap, p);
        }
            break;
        case QPicturePrivate::PdcDrawImage: {
            QImage image;
            if (d->formatMajor < 4) {
                s >> p >> image;
                painter->drawImage(p, image);
            } else if (d->formatMajor <= 5){
                s >> ir >> image;
                painter->drawImage(ir, image, QRect(0, 0, ir.width(), ir.height()));
            } else {
                QRectF sr;
                if (d->in_memory_only) {
                    int index;
                    s >> r >> index >> sr >> ul;
                    Q_ASSERT(index < d->image_list.size());
                    image = d->image_list.at(index);
                } else {
                    s >> r >> image >> sr >> ul;
                }
                painter->drawImage(r, image, sr, Qt::ImageConversionFlags(ul));
            }
        }
            break;
        case QPicturePrivate::PdcBegin:
            s >> ul;                        // number of records
            if (!exec(painter, s, ul))
                return false;
            break;
        case QPicturePrivate::PdcEnd:
            if (nrecords == 0)
                return true;
            break;
        case QPicturePrivate::PdcSave:
            painter->save();
            break;
        case QPicturePrivate::PdcRestore:
            painter->restore();
            break;
        case QPicturePrivate::PdcSetBkColor:
            s >> color;
            painter->setBackground(color);
            break;
        case QPicturePrivate::PdcSetBkMode:
            s >> i_8;
            painter->setBackgroundMode((Qt::BGMode)i_8);
            break;
        case QPicturePrivate::PdcSetROP: // NOP
            s >> i_8;
            break;
        case QPicturePrivate::PdcSetBrushOrigin:
            if (d->formatMajor <= 5) {
                s >> ip;
                painter->setBrushOrigin(ip);
            } else {
                s >> p;
                painter->setBrushOrigin(p);
            }
            break;
        case QPicturePrivate::PdcSetFont:
            s >> font;
            painter->setFont(font);
            break;
        case QPicturePrivate::PdcSetPen:
            if (d->in_memory_only) {
                int index;
                s >> index;
                Q_ASSERT(index < d->pen_list.size());
                pen = d->pen_list.at(index);
            } else {
                s >> pen;
            }
            painter->setPen(pen);
            break;
        case QPicturePrivate::PdcSetBrush:
            if (d->in_memory_only) {
                int index;
                s >> index;
                Q_ASSERT(index < d->brush_list.size());
                brush = d->brush_list.at(index);
            } else {
                s >> brush;
            }
            painter->setBrush(brush);
            break;
// #ifdef Q_Q3PAINTER
//         case QPicturePrivate::PdcSetTabStops:
//                 s >> i_16;
//                 painter->setTabStops(i_16);
//                 break;
//             case QPicturePrivate::PdcSetTabArray:
//                 s >> i_16;
//                 if (i_16 == 0) {
//                     painter->setTabArray(0);
//                 } else {
//                     int *ta = new int[i_16];
//                     for (int i=0; i<i_16; i++) {
//                         s >> i1_16;
//                         ta[i] = i1_16;
//                     }
//                     painter->setTabArray(ta);
//                     delete [] ta;
//                 }
//                 break;
// #endif
        case QPicturePrivate::PdcSetVXform:
            s >> i_8;
            painter->setViewTransformEnabled(i_8);
            break;
        case QPicturePrivate::PdcSetWindow:
            if (d->formatMajor <= 5) {
                s >> ir;
                painter->setWindow(ir);
            } else {
                s >> r;
                painter->setWindow(r.toRect());
            }
            break;
        case QPicturePrivate::PdcSetViewport:
            if (d->formatMajor <= 5) {
                s >> ir;
                painter->setViewport(ir);
            } else {
                s >> r;
                painter->setViewport(r.toRect());
            }
            break;
        case QPicturePrivate::PdcSetWXform:
            s >> i_8;
            painter->setMatrixEnabled(i_8);
            break;
        case QPicturePrivate::PdcSetWMatrix:
            if (d->formatMajor >= 8) {
                s >> matrix >> i_8;
            } else {
                s >> wmatrix >> i_8;
                matrix = QTransform(wmatrix);
            }
            // i_8 is always false due to updateXForm() in qpaintengine_pic.cpp
            painter->setTransform(matrix * worldMatrix, i_8);
            break;
// #ifdef Q_Q3PAINTER
//             case QPicturePrivate::PdcSaveWMatrix:
//                 painter->saveWorldMatrix();
//                 break;
//             case QPicturePrivate::PdcRestoreWMatrix:
//                 painter->restoreWorldMatrix();
//                 break;
// #endif
        case QPicturePrivate::PdcSetClip:
            s >> i_8;
            painter->setClipping(i_8);
            break;
        case QPicturePrivate::PdcSetClipRegion:
            s >> rgn >> i_8;
            if (d->formatMajor >= 9) {
                painter->setClipRegion(rgn, Qt::ClipOperation(i_8));
            } else {
                painter->setClipRegion(rgn);
            }
            break;
        case QPicturePrivate::PdcSetClipPath:
            {
                QPainterPath path;
                s >> path >> i_8;
                painter->setClipPath(path, Qt::ClipOperation(i_8));
                break;
            }
        case QPicturePrivate::PdcSetRenderHint:
            s >> ul;
            painter->setRenderHint(QPainter::Antialiasing,
                                   bool(ul & QPainter::Antialiasing));
            painter->setRenderHint(QPainter::SmoothPixmapTransform,
                                   bool(ul & QPainter::SmoothPixmapTransform));
            break;
        case QPicturePrivate::PdcSetCompositionMode:
            s >> ul;
            painter->setCompositionMode((QPainter::CompositionMode)ul);
            break;
        case QPicturePrivate::PdcSetClipEnabled:
            s >> bl;
            painter->setClipping(bl);
            break;
        case QPicturePrivate::PdcSetOpacity:
            s >> dbl;
            painter->setOpacity(qreal(dbl));
            break;
        default:
            qWarning("QPicture::play: Invalid command %d", c);
            if (len)                        // skip unknown command
                s.device()->seek(s.device()->pos()+len);
        }
#if defined(QT_DEBUG)
        //qDebug("device->at(): %i, strm_pos: %i len: %i", (int)s.device()->pos(), strm_pos, len);
        Q_ASSERT(qint32(s.device()->pos() - strm_pos) == len);
#endif
    }
    return false;
}

/*!
    \internal

    Internal implementation of the virtual QPaintDevice::metric()
    function.

    A picture has the following hard-coded values: numcolors=16777216
    and depth=24.

    \a m is the metric to get.
*/

int QPicture::metric(PaintDeviceMetric m) const
{
    int val;
    QRect brect = boundingRect();
    switch (m) {
        case PdmWidth:
            val = brect.width();
            break;
        case PdmHeight:
            val = brect.height();
            break;
        case PdmWidthMM:
            val = int(25.4/qt_defaultDpiX()*brect.width());
            break;
        case PdmHeightMM:
            val = int(25.4/qt_defaultDpiY()*brect.height());
            break;
        case PdmDpiX:
        case PdmPhysicalDpiX:
            val = qt_defaultDpiX();
            break;
        case PdmDpiY:
        case PdmPhysicalDpiY:
            val = qt_defaultDpiY();
            break;
        case PdmNumColors:
            val = 16777216;
            break;
        case PdmDepth:
            val = 24;
            break;
        default:
            val = 0;
            qWarning("QPicture::metric: Invalid metric command");
    }
    return val;
}

/*!
    \fn void QPicture::detach()
    \internal
    Detaches from shared picture data and makes sure that this picture
    is the only one referring to the data.

    If multiple pictures share common data, this picture makes a copy
    of the data and detaches itself from the sharing mechanism.
    Nothing is done if there is just a single reference.
*/

/*! \fn bool QPicture::isDetached() const
\internal
*/

/*! \internal
### Qt 5 - remove me
 */
void QPicture::detach_helper()
{
    // QExplicitelySharedDataPointer takes care of cloning using
    // QPicturePrivate's copy constructor. Do not call detach_helper() anymore
    // and remove in Qt 5, please.
    Q_ASSERT_X(false, "QPicture::detach_helper()", "Do not call this function");
}

/*!
    Assigns picture \a p to this picture and returns a reference to
    this picture.
*/
QPicture& QPicture::operator=(const QPicture &p)
{
    d_ptr = p.d_ptr;
    return *this;
}

/*!
  \internal

  Constructs a QPicturePrivate
*/
QPicturePrivate::QPicturePrivate()
    : in_memory_only(false)
{
}

/*!
  \internal

  Copy-Constructs a QPicturePrivate. Needed when detaching.
*/
QPicturePrivate::QPicturePrivate(const QPicturePrivate &other)
    : trecs(other.trecs),
      formatOk(other.formatOk),
      formatMinor(other.formatMinor),
      brect(other.brect),
      override_rect(other.override_rect),
      in_memory_only(false)
{
    pictb.setData(other.pictb.data(), other.pictb.size());
    if (other.pictb.isOpen()) {
        pictb.open(other.pictb.openMode());
        pictb.seek(other.pictb.pos());
    }
}

/*!
  \internal

  Sets formatOk to false and resets the format version numbers to default
*/

void QPicturePrivate::resetFormat()
{
    formatOk = false;
    formatMajor = mfhdr_maj;
    formatMinor = mfhdr_min;
}


/*!
  \internal

  Checks data integrity and format version number. Set formatOk to
  true on success, to false otherwise. Returns the resulting formatOk
  value.
*/
bool QPicturePrivate::checkFormat()
{
    resetFormat();

    // can't check anything in an empty buffer
    if (pictb.size() == 0 || pictb.isOpen())
        return false;

    pictb.open(QIODevice::ReadOnly);                        // open buffer device
    QDataStream s;
    s.setDevice(&pictb);                        // attach data stream to buffer

    char mf_id[4];                                // picture header tag
    s.readRawData(mf_id, 4);                        // read actual tag
    if (memcmp(mf_id, qt_mfhdr_tag, 4) != 0) {         // wrong header id
        qWarning("QPicturePaintEngine::checkFormat: Incorrect header");
        pictb.close();
        return false;
    }

    int cs_start = sizeof(quint32);                // pos of checksum word
    int data_start = cs_start + sizeof(quint16);
    quint16 cs,ccs;
    QByteArray buf = pictb.buffer();        // pointer to data

    s >> cs;                                // read checksum
    ccs = (quint16) qChecksum(buf.constData() + data_start, buf.size() - data_start);
    if (ccs != cs) {
        qWarning("QPicturePaintEngine::checkFormat: Invalid checksum %x, %x expected",
                  ccs, cs);
        pictb.close();
        return false;
    }

    quint16 major, minor;
    s >> major >> minor;                        // read version number
    if (major > mfhdr_maj) {                // new, incompatible version
        qWarning("QPicturePaintEngine::checkFormat: Incompatible version %d.%d",
                  major, minor);
        pictb.close();
        return false;
    }
    s.setVersion(major != 4 ? major : 3);

    quint8  c, clen;
    s >> c >> clen;
    if (c == QPicturePrivate::PdcBegin) {
        if (!(major >= 1 && major <= 3)) {
            qint32 l, t, w, h;
            s >> l >> t >> w >> h;
            brect = QRect(l, t, w, h);
        }
    } else {
        qWarning("QPicturePaintEngine::checkFormat: Format error");
        pictb.close();
        return false;
    }
    pictb.close();

    formatOk = true;                        // picture seems to be ok
    formatMajor = major;
    formatMinor = minor;
    return true;
}

/*! \internal */
QPaintEngine *QPicture::paintEngine() const
{
    if (!d_func()->paintEngine)
        const_cast<QPicture*>(this)->d_func()->paintEngine.reset(new QPicturePaintEngine);
    return d_func()->paintEngine.data();
}

/*****************************************************************************
  QPicture stream functions
 *****************************************************************************/

#ifndef QT_NO_DATASTREAM
/*!
    \relates QPicture

    Writes picture \a r to the stream \a s and returns a reference to
    the stream.
*/

QDataStream &operator<<(QDataStream &s, const QPicture &r)
{
    quint32 size = r.d_func()->pictb.buffer().size();
    s << size;
    // null picture ?
    if (size == 0)
        return s;
    // just write the whole buffer to the stream
    s.writeRawData (r.d_func()->pictb.buffer(), r.d_func()->pictb.buffer().size());
    return s;
}

/*!
    \relates QPicture

    Reads a picture from the stream \a s into picture \a r and returns
    a reference to the stream.
*/

QDataStream &operator>>(QDataStream &s, QPicture &r)
{
    QDataStream sr;

    // "init"; this code is similar to the beginning of QPicture::cmd()
    sr.setDevice(&r.d_func()->pictb);
    sr.setVersion(r.d_func()->formatMajor);
    quint32 len;
    s >> len;
    QByteArray data;
    if (len > 0) {
        data.resize(len);
        s.readRawData(data.data(), len);
    }

    r.d_func()->pictb.setData(data);
    r.d_func()->resetFormat();
    return s;
}
#endif // QT_NO_DATASTREAM


#ifndef QT_NO_PICTUREIO

QT_BEGIN_INCLUDE_NAMESPACE
#include "qregexp.h"
#include "qapplication.h"
#include "qpictureformatplugin.h"
QT_END_INCLUDE_NAMESPACE

/*!
    \obsolete

    Returns a string that specifies the picture format of the file \a
    fileName, or 0 if the file cannot be read or if the format is not
    recognized.

    \sa load() save()
*/

const char* QPicture::pictureFormat(const QString &fileName)
{
    return QPictureIO::pictureFormat(fileName);
}

/*!
    \obsolete

    Returns a list of picture formats that are supported for picture
    input.

    \sa outputFormats() inputFormatList() QPictureIO
*/
QList<QByteArray> QPicture::inputFormats()
{
    return QPictureIO::inputFormats();
}

static QStringList qToStringList(const QList<QByteArray> arr)
{
    QStringList list;
    for (int i = 0; i < arr.count(); ++i)
        list.append(QString::fromLatin1(arr.at(i)));
    return list;
}

/*!
    \obsolete

    Returns a list of picture formats that are supported for picture
    input.

    Note that if you want to iterate over the list, you should iterate
    over a copy, e.g.
    \snippet doc/src/snippets/picture/picture.cpp 2

    \sa outputFormatList() inputFormats() QPictureIO
*/
QStringList QPicture::inputFormatList()
{
    return qToStringList(QPictureIO::inputFormats());
}


/*!
    \obsolete

    Returns a list of picture formats that are supported for picture
    output.

    Note that if you want to iterate over the list, you should iterate
    over a copy, e.g.
    \snippet doc/src/snippets/picture/picture.cpp 3

    \sa inputFormatList() outputFormats() QPictureIO
*/
QStringList QPicture::outputFormatList()
{
    return qToStringList(QPictureIO::outputFormats());
}

/*!
    \obsolete

    Returns a list of picture formats that are supported for picture
    output.

    \sa inputFormats() outputFormatList() QPictureIO
*/
QList<QByteArray> QPicture::outputFormats()
{
    return QPictureIO::outputFormats();
}

/*****************************************************************************
  QPictureIO member functions
 *****************************************************************************/

/*!
    \obsolete

    \class QPictureIO

    \brief The QPictureIO class contains parameters for loading and
    saving pictures.

    \ingroup painting
    \ingroup io

    QPictureIO contains a QIODevice object that is used for picture data
    I/O. The programmer can install new picture file formats in addition
    to those that Qt provides.

    You don't normally need to use this class; QPicture::load(),
    QPicture::save().

    \sa QPicture QPixmap QFile
*/

struct QPictureIOData
{
    QPicture        pi;                                // picture
    int                iostat;                                // IO status
    QByteArray        frmt;                                // picture format
    QIODevice  *iodev;                                // IO device
    QString        fname;                                // file name
    QString     descr;                                // picture description
    const char *parameters;
    int quality;
    float gamma;
};

/*!
    Constructs a QPictureIO object with all parameters set to zero.
*/

QPictureIO::QPictureIO()
{
    init();
}

/*!
    Constructs a QPictureIO object with the I/O device \a ioDevice and a
    \a format tag.
*/

QPictureIO::QPictureIO(QIODevice *ioDevice, const char *format)
{
    init();
    d->iodev = ioDevice;
    d->frmt = format;
}

/*!
    Constructs a QPictureIO object with the file name \a fileName and a
    \a format tag.
*/

QPictureIO::QPictureIO(const QString &fileName, const char* format)
{
    init();
    d->frmt = format;
    d->fname = fileName;
}

/*!
    Contains initialization common to all QPictureIO constructors.
*/

void QPictureIO::init()
{
    d = new QPictureIOData();
    d->parameters = 0;
    d->quality = -1; // default quality of the current format
    d->gamma=0.0f;
    d->iostat = 0;
    d->iodev  = 0;
}

/*!
    Destroys the object and all related data.
*/

QPictureIO::~QPictureIO()
{
    if (d->parameters)
        delete [] (char*)d->parameters;
    delete d;
}


/*****************************************************************************
  QPictureIO picture handler functions
 *****************************************************************************/

class QPictureHandler
{
public:
    QPictureHandler(const char *f, const char *h, const QByteArray& fl,
                     picture_io_handler r, picture_io_handler w);
    QByteArray              format;                        // picture format
    QRegExp              header;                        // picture header pattern
    enum TMode { Untranslated=0, TranslateIn, TranslateInOut } text_mode;
    picture_io_handler  read_picture;                // picture read function
    picture_io_handler  write_picture;                // picture write function
    bool              obsolete;                        // support not "published"
};

QPictureHandler::QPictureHandler(const char *f, const char *h, const QByteArray& fl,
                              picture_io_handler r, picture_io_handler w)
    : format(f), header(QString::fromLatin1(h))
{
    text_mode = Untranslated;
    if (fl.contains('t'))
        text_mode = TranslateIn;
    else if (fl.contains('T'))
        text_mode = TranslateInOut;
    obsolete = fl.contains('O');
    read_picture  = r;
    write_picture = w;
}

typedef QList<QPictureHandler *> QPHList;
Q_GLOBAL_STATIC(QPHList, pictureHandlers)

#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC(QMutex, mutex)
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, factoryLoader,
                          (QPictureFormatInterface_iid,
                           QLatin1String("/pictureformats")))
#endif
void qt_init_picture_plugins()
{
#ifndef QT_NO_LIBRARY
    QMutexLocker locker(mutex());
    QFactoryLoader *loader = factoryLoader();
    QStringList keys = loader->keys();
    for (int i = 0; i < keys.count(); ++i)
        if (QPictureFormatInterface *format = qobject_cast<QPictureFormatInterface*>(loader->instance(keys.at(i))))
            format->installIOHandler(keys.at(i));
#endif
}

static void cleanup()
{
    // make sure that picture handlers are delete before plugin manager
    if (QPHList *list = pictureHandlers()) {
        qDeleteAll(*list);
        list->clear();
    }
}

void qt_init_picture_handlers()                // initialize picture handlers
{
    static QBasicAtomicInt done = Q_BASIC_ATOMIC_INITIALIZER(0);
    if (done.testAndSetRelaxed(0, 1)) {
        qAddPostRoutine(cleanup);
    }
}

static QPictureHandler *get_picture_handler(const char *format)
{                                                // get pointer to handler
    qt_init_picture_handlers();
    qt_init_picture_plugins();
    if (QPHList *list = pictureHandlers()) {
        for (int i = 0; i < list->size(); ++i) {
            if (list->at(i)->format == format)
                return list->at(i);
        }
    }
    return 0;                                        // no such handler
}


/*!
    Defines a picture I/O handler for the picture format called \a
    format, which is recognized using the regular
    expression defined in \a header, read using \a readPicture and
    written using \a writePicture.

    \a flags is a string of single-character flags for this format.
    The only flag defined currently is T (upper case), so the only
    legal value for \a flags are "T" and the empty string. The "T"
    flag means that the picture file is a text file, and Qt should treat
    all newline conventions as equivalent. (XPM files and some PPM
    files are text files for example.)

    \a format is used to select a handler to write a QPicture; \a header
    is used to select a handler to read an picture file.

    If \a readPicture is a null pointer, the QPictureIO will not be able
    to read pictures in \a format. If \a writePicture is a null pointer,
    the QPictureIO will not be able to write pictures in \a format. If
    both are null, the QPictureIO object is valid but useless.

    Example:
    \snippet doc/src/snippets/picture/picture.cpp 6
    \codeline
    \snippet doc/src/snippets/picture/picture.cpp 7
    \codeline
    \snippet doc/src/snippets/picture/picture.cpp 8

    Before the regular expression test, all the 0 bytes in the file header are
    converted to 1 bytes. This is done because when Qt was ASCII-based, QRegExp
    could not handle 0 bytes in strings.

    The regexp is only applied on the first 14 bytes of the file.

    (Note that if one handlerIO supports writing a format and another
    supports reading it, Qt supports both reading and writing. If two
    handlers support the same operation, Qt chooses one arbitrarily.)
*/

void QPictureIO::defineIOHandler(const char *format,
                                 const char *header,
                                 const char *flags,
                                 picture_io_handler readPicture,
                                 picture_io_handler writePicture)
{
    qt_init_picture_handlers();
    if (QPHList *list = pictureHandlers()) {
        QPictureHandler *p;
        p = new QPictureHandler(format, header, QByteArray(flags), readPicture, writePicture);
        list->prepend(p);
    }
}


/*****************************************************************************
  QPictureIO normal member functions
 *****************************************************************************/

/*!
    Returns the picture currently set.

    \sa setPicture()
*/
const QPicture &QPictureIO::picture() const { return d->pi; }

/*!
    Returns the picture's IO status. A non-zero value indicates an
    error, whereas 0 means that the IO operation was successful.

    \sa setStatus()
*/
int QPictureIO::status() const { return d->iostat; }

/*!
    Returns the picture format string or 0 if no format has been
    explicitly set.
*/
const char *QPictureIO::format() const { return d->frmt; }

/*!
    Returns the IO device currently set.

    \sa setIODevice()
*/
QIODevice *QPictureIO::ioDevice() const { return d->iodev; }

/*!
    Returns the file name currently set.

    \sa setFileName()
*/
QString QPictureIO::fileName() const { return d->fname; }


/*!
    Returns the picture description string.

    \sa setDescription()
*/
QString QPictureIO::description() const { return d->descr; }

/*!
    Sets the picture to \a picture.

    \sa picture()
*/
void QPictureIO::setPicture(const QPicture &picture)
{
    d->pi = picture;
}

/*!
    Sets the picture IO status to \a status. A non-zero value indicates
    an error, whereas 0 means that the IO operation was successful.

    \sa status()
*/
void QPictureIO::setStatus(int status)
{
    d->iostat = status;
}

/*!
    Sets the picture format to \a format for the picture to be read or
    written.

    It is necessary to specify a format before writing an picture, but
    it is not necessary to specify a format before reading an picture.

    If no format has been set, Qt guesses the picture format before
    reading it. If a format is set the picture will only be read if it
    has that format.

    \sa read() write() format()
*/
void QPictureIO::setFormat(const char *format)
{
    d->frmt = format;
}

/*!
    Sets the IO device to be used for reading or writing an picture.

    Setting the IO device allows pictures to be read/written to any
    block-oriented QIODevice.

    If \a ioDevice is not null, this IO device will override file name
    settings.

    \sa setFileName()
*/
void QPictureIO::setIODevice(QIODevice *ioDevice)
{
    d->iodev = ioDevice;
}

/*!
    Sets the name of the file to read or write an picture from to \a
    fileName.

    \sa setIODevice()
*/
void QPictureIO::setFileName(const QString &fileName)
{
    d->fname = fileName;
}

/*!
    Returns the quality of the written picture, related to the
    compression ratio.

    \sa setQuality() QPicture::save()
*/
int QPictureIO::quality() const
{
    return d->quality;
}

/*!
    Sets the quality of the written picture to \a q, related to the
    compression ratio.

    \a q must be in the range -1..100. Specify 0 to obtain small
    compressed files, 100 for large uncompressed files. (-1 signifies
    the default compression.)

    \sa quality() QPicture::save()
*/

void QPictureIO::setQuality(int q)
{
    d->quality = q;
}

/*!
    Returns the picture's parameters string.

    \sa setParameters()
*/

const char *QPictureIO::parameters() const
{
    return d->parameters;
}

/*!
    Sets the picture's parameter string to \a parameters. This is for
    picture handlers that require special parameters.

    Although the current picture formats supported by Qt ignore the
    parameters string, it may be used in future extensions or by
    contributions (for example, JPEG).

    \sa parameters()
*/

void QPictureIO::setParameters(const char *parameters)
{
    if (d->parameters)
        delete [] (char*)d->parameters;
    d->parameters = qstrdup(parameters);
}

/*!
    Sets the gamma value at which the picture will be viewed to \a
    gamma. If the picture format stores a gamma value for which the
    picture is intended to be used, then this setting will be used to
    modify the picture. Setting to 0.0 will disable gamma correction
    (i.e. any specification in the file will be ignored).

    The default value is 0.0.

    \sa gamma()
*/
void QPictureIO::setGamma(float gamma)
{
    d->gamma=gamma;
}

/*!
    Returns the gamma value at which the picture will be viewed.

    \sa setGamma()
*/
float QPictureIO::gamma() const
{
    return d->gamma;
}

/*!
    Sets the picture description string for picture handlers that support
    picture descriptions to \a description.

    Currently, no picture format supported by Qt uses the description
    string.
*/

void QPictureIO::setDescription(const QString &description)
{
    d->descr = description;
}


/*!
    Returns a string that specifies the picture format of the file \a
    fileName, or null if the file cannot be read or if the format is
    not recognized.
*/

QByteArray QPictureIO::pictureFormat(const QString &fileName)
{
    QFile file(fileName);
    QByteArray format;
    if (!file.open(QIODevice::ReadOnly))
        return format;
    format = pictureFormat(&file);
    file.close();
    return format;
}

/*!
    \overload

    Returns a string that specifies the picture format of the picture read
    from IO device \a d, or 0 if the device cannot be read or if the
    format is not recognized.

    Make sure that \a d is at the right position in the device (for
    example, at the beginning of the file).

    \sa QIODevice::at()
*/

QByteArray QPictureIO::pictureFormat(QIODevice *d)
{
    // if you change this change the documentation for defineIOHandler()
    const int buflen = 14;

    char buf[buflen];
    char buf2[buflen];
    qt_init_picture_handlers();
    qt_init_picture_plugins();
    int pos = d->pos();                      // save position
    int rdlen = d->read(buf, buflen);        // read a few bytes

    QByteArray format;
    if (rdlen != buflen)
        return format;

    memcpy(buf2, buf, buflen);

    for (int n = 0; n < rdlen; n++)
        if (buf[n] == '\0')
            buf[n] = '\001';
    if (rdlen > 0) {
        buf[rdlen - 1] = '\0';
        QString bufStr = QString::fromLatin1(buf);
        if (QPHList *list = pictureHandlers()) {
            for (int i = 0; i < list->size(); ++i) {
                if (list->at(i)->header.indexIn(bufStr) != -1) { // try match with headers
                    format = list->at(i)->format;
                    break;
                }
            }
        }
    }
    d->seek(pos);                                // restore position
    return format;
}

/*!
    Returns a sorted list of picture formats that are supported for
    picture input.
*/
QList<QByteArray> QPictureIO::inputFormats()
{
    QList<QByteArray> result;

    qt_init_picture_handlers();
    qt_init_picture_plugins();

    if (QPHList *list = pictureHandlers()) {
        for (int i = 0; i < list->size(); ++i) {
            QPictureHandler *p = list->at(i);
            if (p->read_picture && !p->obsolete  && !result.contains(p->format))
                result.append(p->format);
        }
    }
    qSort(result);

    return result;
}

/*!
    Returns a sorted list of picture formats that are supported for
    picture output.
*/
QList<QByteArray> QPictureIO::outputFormats()
{
    qt_init_picture_handlers();
    qt_init_picture_plugins();

    QList<QByteArray> result;
    if (QPHList *list = pictureHandlers()) {
        for (int i = 0; i < list->size(); ++i) {
            QPictureHandler *p = list->at(i);
            if (p->write_picture && !p->obsolete && !result.contains(p->format))
                result.append(p->format);
        }
    }
    return result;
}



/*!
    Reads an picture into memory and returns true if the picture was
    successfully read; otherwise returns false.

    Before reading an picture you must set an IO device or a file name.
    If both an IO device and a file name have been set, the IO device
    will be used.

    Setting the picture file format string is optional.

    Note that this function does \e not set the \link format()
    format\endlink used to read the picture. If you need that
    information, use the pictureFormat() static functions.

    Example:

    \snippet doc/src/snippets/picture/picture.cpp 4

    \sa setIODevice() setFileName() setFormat() write() QPixmap::load()
*/
bool QPictureIO::read()
{
    QFile           file;
    const char          *picture_format;
    QPictureHandler *h;

    if (d->iodev) {                                // read from io device
        // ok, already open
    } else if (!d->fname.isEmpty()) {                // read from file
        file.setFileName(d->fname);
        if (!file.open(QIODevice::ReadOnly))
            return false;                        // cannot open file
        d->iodev = &file;
    } else {                                        // no file name or io device
        return false;
    }
    if (d->frmt.isEmpty()) {
        // Try to guess format
        picture_format = pictureFormat(d->iodev);        // get picture format
        if (!picture_format) {
            if (file.isOpen()) {                        // unknown format
                file.close();
                d->iodev = 0;
            }
            return false;
        }
    } else {
        picture_format = d->frmt;
    }

    h = get_picture_handler(picture_format);
    if (file.isOpen()) {
#if !defined(Q_OS_UNIX)
        if (h && h->text_mode) {                // reopen in translated mode
            file.close();
            file.open(QIODevice::ReadOnly | QIODevice::Text);
        }
        else
#endif
            file.seek(0);                        // position to start
    }
    d->iostat = 1;                                        // assume error

    if (h && h->read_picture)
        (*h->read_picture)(this);

    if (file.isOpen()) {                        // picture was read using file
        file.close();
        d->iodev = 0;
    }
    return d->iostat == 0;                                // picture successfully read?
}


/*!
    Writes an picture to an IO device and returns true if the picture was
    successfully written; otherwise returns false.

    Before writing an picture you must set an IO device or a file name.
    If both an IO device and a file name have been set, the IO device
    will be used.

    The picture will be written using the specified picture format.

    Example:
    \snippet doc/src/snippets/picture/picture.cpp 5

    \sa setIODevice() setFileName() setFormat() read() QPixmap::save()
*/
bool QPictureIO::write()
{
    if (d->frmt.isEmpty())
        return false;
    QPictureHandler *h = get_picture_handler(d->frmt);
    if (!h || !h->write_picture) {
        qWarning("QPictureIO::write: No such picture format handler: %s",
                 format());
        return false;
    }
    QFile file;
    if (!d->iodev && !d->fname.isEmpty()) {
        file.setFileName(d->fname);
        bool translate = h->text_mode==QPictureHandler::TranslateInOut;
        QIODevice::OpenMode fmode = translate ? QIODevice::WriteOnly | QIODevice::Text : QIODevice::OpenMode(QIODevice::WriteOnly);
        if (!file.open(fmode))                // couldn't create file
            return false;
        d->iodev = &file;
    }
    d->iostat = 1;
    (*h->write_picture)(this);
    if (file.isOpen()) {                        // picture was written using file
        file.close();
        d->iodev = 0;
    }
    return d->iostat == 0;                                // picture successfully written?
}
#endif //QT_NO_PICTUREIO

/*!
    \fn QPicture QPicture::copy() const

    Use simple assignment instead.
*/

QT_END_NAMESPACE

#endif // QT_NO_PICTURE

/*!
    \typedef QPicture::DataPtr
    \internal
*/

/*!
    \fn DataPtr &QPicture::data_ptr()
    \internal
*/
