📄 qimage.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.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 GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qimage.h"#include "qdatastream.h"#include "qbuffer.h"#include "qmap.h"#include "qmatrix.h"#include "qtransform.h"#include "qimagereader.h"#include "qimagewriter.h"#include "qstringlist.h"#include "qvariant.h"#include <ctype.h>#include <stdlib.h>#include <limits.h>#include <math.h>#include <private/qdrawhelper_p.h>#include <private/qpixmap_p.h>#include <private/qimagescale_p.h>#include <qhash.h>#ifdef QT_RASTER_IMAGEENGINE#include <private/qpaintengine_raster_p.h>#else#include <qpaintengine.h>#endif#include <private/qimage_p.h>#ifdef Q_WS_QWS#include <qscreen_qws.h> //### for qt_conv...#elsestatic inline ushort qt_convRgbTo16(QRgb c){ return ((c >> 8) & 0xf800) | ((c >> 5) & 0x07e0) | ((c >> 3) & 0x1f);}static inline QRgb qt_conv16ToRgb(ushort c){ QRgb r = (((c) << 3) & 0xf8) | (((c) << 5) & 0xfc00) | (((c) << 8) & 0xf80000); r |= (r >> 5) & 0x70007; r |= (r >> 6) & 0x300; return r | 0xff000000;}#endif#if defined(Q_CC_DEC) && defined(__alpha) && (__DECCXX_VER-0 >= 50190001)#pragma message disable narrowptr#endif#define QIMAGE_SANITYCHECK_MEMORY(image) \ if ((image).isNull()) { \ qWarning("QImage: out of memory, returning null image"); \ return QImage(); \ }// ### Qt 5: removetypedef void (*_qt_image_cleanup_hook)(int);Q_GUI_EXPORT _qt_image_cleanup_hook qt_image_cleanup_hook = 0;// ### Qt 5: renametypedef void (*_qt_image_cleanup_hook_64)(qint64);Q_GUI_EXPORT _qt_image_cleanup_hook_64 qt_image_cleanup_hook_64 = 0;static QImage rotated90(const QImage &src);static QImage rotated180(const QImage &src);static QImage rotated270(const QImage &src);// ### Qt 5: removeQ_GUI_EXPORT qint64 qt_image_id(const QImage &image){ return image.cacheKey();}const QVector<QRgb> *qt_image_colortable(const QImage &image){ return (image.d->format <= QImage::Format_Indexed8 && !image.d->colortable.isEmpty()) ? &image.d->colortable : 0;}extern int qt_defaultDpi();extern int qt_defaultDpiX();extern int qt_defaultDpiY();QBasicAtomic qimage_serial_number = Q_ATOMIC_INIT(1);QImageData::QImageData(){ ser_no = qimage_serial_number.fetchAndAdd(1); detach_no = 0; ref = 0; width = height = depth = 0; nbytes = 0; data = 0; own_data = true; ro_data = false; has_alpha_clut = false;#ifdef QT3_SUPPORT jumptable = 0;#endif bytes_per_line = 0; format = QImage::Format_ARGB32; // ### Qt 4.4: remove #ifdef#ifdef Q_WS_QWS dpmx = qt_defaultDpiX()*100./2.54; dpmy = qt_defaultDpiY()*100./2.54;#else dpmx = qt_defaultDpi()*100./2.54; dpmy = qt_defaultDpi()*100./2.54;#endif offset = QPoint(0,0); paintEngine = 0;}static int depthForFormat(QImage::Format format){ int depth = 0; switch(format) { case QImage::Format_Invalid: case QImage::NImageFormats: Q_ASSERT(false); case QImage::Format_Mono: case QImage::Format_MonoLSB: depth = 1; break; case QImage::Format_Indexed8: depth = 8; break; case QImage::Format_RGB32: case QImage::Format_ARGB32: case QImage::Format_ARGB32_Premultiplied: depth = 32; break; case QImage::Format_RGB16: depth = 16; break; } return depth;}QImageData * QImageData::create(const QSize &size, QImage::Format format, int numColors){ if (!size.isValid() || numColors < 0 || format == QImage::Format_Invalid) return 0; // invalid parameter(s) uint width = size.width(); uint height = size.height(); uint depth = 0; switch(format) { case QImage::NImageFormats: case QImage::Format_Invalid: Q_ASSERT(false); case QImage::Format_Mono: case QImage::Format_MonoLSB: depth = 1; numColors = 2; break; case QImage::Format_Indexed8: depth = 8; numColors = qMin(numColors, 256); numColors = qMax(0, numColors); break; case QImage::Format_RGB32: case QImage::Format_ARGB32: case QImage::Format_ARGB32_Premultiplied: depth = 32; numColors = 0; break; case QImage::Format_RGB16: depth = 16; numColors = 0; break; } const int bytes_per_line = ((width * depth + 31) >> 5) << 2; // bytes per scanline (must be multiple of 8) // sanity check for potential overflows if (INT_MAX/depth < width || bytes_per_line <= 0 || INT_MAX/uint(bytes_per_line) < height || INT_MAX/sizeof(uchar *) < uint(height)) return 0; QImageData *d = new QImageData; d->colortable.resize(numColors); if (depth == 1) { d->colortable[0] = QColor(Qt::black).rgba(); d->colortable[1] = QColor(Qt::white).rgba(); } else { for (int i = 0; i < numColors; ++i) d->colortable[i] = 0; } d->width = width; d->height = height; d->depth = depth; d->format = format; d->has_alpha_clut = false; d->bytes_per_line = bytes_per_line; d->nbytes = d->bytes_per_line*height; d->data = (uchar *)malloc(d->nbytes); if (!d->data) { delete d; return 0; } d->ref.ref(); return d;}QImageData::~QImageData(){ if (qt_image_cleanup_hook_64) qt_image_cleanup_hook_64((((qint64) ser_no) << 32) | ((qint64) detach_no)); delete paintEngine; if (data && own_data) free(data);#ifdef QT3_SUPPORT if (jumptable) free(jumptable); jumptable = 0;#endif data = 0;}/*! \class QImage \ingroup multimedia \ingroup shared \mainclass \brief The QImage class provides a hardware-independent image representation that allows direct access to the pixel data, and can be used as a paint device. Qt provides four classes for handling image data: QImage, QPixmap, QBitmap and QPicture. QImage is designed and optimized for I/O, and for direct pixel access and manipulation, while QPixmap is designed and optimized for showing images on screen. QBitmap is only a convenience class that inherits QPixmap, ensuring a depth of 1. Finally, the QPicture class is a paint device that records and replays QPainter commands. Because QImage is a QPaintDevice subclass, QPainter can be used to draw directly onto images. When using QPainter on a QImage, the painting can be performed in another thread than the current GUI thread, that is except rendering text (because QFont is GUI dependent). To render text in another thread, the text must first be derived as a QPainterPath in the GUI thread. The QImage class supports several image formats described by the \l Format enum. These include monochrome, 8-bit, 32-bit and alpha-blended images which are available in all versions of Qt 4.x. In addition, QImage supports several formats that are specific to \l {Qtopia Core}. QImage provides a collection of functions that can be used to obtain a variety of information about the image. There are also several functions that enables transformation of the image. QImage objects can be passed around by value since the QImage class uses \l{Implicit Data Sharing}{implicit data sharing}. QImage objects can also be streamed and compared. \tableofcontents \section1 Reading and Writing Image Files QImage provides several ways of loading an image file: The file can be loaded when constructing the QImage object, or by using the load() or loadFromData() functions later on. QImage also provides the static fromData() function, constructing a QImage from the given data. When loading an image, the file name can either refer to an actual file on disk or to one of the application's embedded resources. See \l{The Qt Resource System} overview for details on how to embed images and other resource files in the application's executable. Simply call the save() function to save a QImage object. The complete list of supported file formats are available through the QImageReader::supportedImageFormats() and QImageWriter::supportedImageFormats() functions. New file formats can be added as plugins. By default, Qt supports the following formats: \table \header \o Format \o Description \o Qt's support \row \o BMP \o Windows Bitmap \o Read/write \row \o GIF \o Graphic Interchange Format (optional) \o Read \row \o JPG \o Joint Photographic Experts Group \o Read/write \row \o JPEG \o Joint Photographic Experts Group \o Read/write \row \o PNG \o Portable Network Graphics \o Read/write \row \o PBM \o Portable Bitmap \o Read \row \o PGM \o Portable Graymap \o Read \row \o PPM \o Portable Pixmap \o Read/write \row \o TIFF \o Tagged Image File Format \o Read/write \row \o XBM \o X11 Bitmap \o Read/write \row \o XPM \o X11 Pixmap \o Read/write \endtable (To configure Qt with GIF support, pass \c -qt-gif to the \c configure script or check the appropriate option in the graphical installer.) \section1 Image Information QImage provides a collection of functions that can be used to obtain a variety of information about the image: \table \header \o \o Available Functions \row \o Geometry \o The size(), width(), height(), dotsPerMeterX(), and dotsPerMeterY() functions provide information about the image size and aspect ratio. The rect() function returns the image's enclosing rectangle. The valid() function tells if a given pair of coordinates is within this rectangle. The offset() function returns the number of pixels by which the image is intended to be offset by when positioned relative to other images, which also can be manipulated using the setOffset() function. \row \o Colors \o The color of a pixel can be retrieved by passing its coordinates to the pixel() function. The pixel() function returns the color as a QRgb value indepedent of the image's format. In case of monochrome and 8-bit images, the numColors() and colorTable() functions provide information about the color components used to store the image data: The colorTable() function returns the image's entire color table. To obtain a single entry, use the pixelIndex() function to retrieve the pixel index for a given pair of coordinates, then use the color() function to retrieve the color. Note that if you create an 8-bit image manually, you have to set a valid color table on the image as well. The hasAlphaChannel() function tells if the image's format respects the alpha channel, or not. The allGray() and isGrayscale() functions tell whether an image's colors are all shades of gray. See also the \l {QImage#Pixel Manipulation}{Pixel Manipulation} and \l {QImage#Image Transformations}{Image Transformations} sections. \row \o Text \o The text() function returns the image text associated with the given text key. An image's text keys can be retrieved using the textKeys() function. Use the setText() function to alter an image's text. \row \o Low-level information \o The depth() function returns the depth of the image. The supported depths are 1 (monochrome), 8 and 32 (for more information see the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -