diff --git a/src/gui/doc/images/qpixelformat-argb32buffer.png b/src/gui/doc/images/qpixelformat-argb32buffer.png new file mode 100644 index 0000000000..5888f0b03d Binary files /dev/null and b/src/gui/doc/images/qpixelformat-argb32buffer.png differ diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 3998bbf3ff..dda8894722 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -4508,4 +4508,273 @@ QDebug operator<<(QDebug dbg, const QImage &i) \sa textKeys() */ +static const QPixelFormat pixelformats[] = { + //QImage::Format_Invalid: + QPixelFormat(), + //QImage::Format_Mono: + QPixelFormat(QPixelFormat::GrayScale, + /*RED*/ 1, + /*GREEN*/ 0, + /*BLUE*/ 0, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedByte, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_MonoLSB: + QPixelFormat(QPixelFormat::GrayScale, + /*RED*/ 1, + /*GREEN*/ 0, + /*BLUE*/ 0, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedByte, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_Indexed8: + QPixelFormat(QPixelFormat::Indexed, + /*RED*/ 8, + /*GREEN*/ 0, + /*BLUE*/ 0, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedByte, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGB32: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_ARGB32: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_ARGB32_Premultiplied: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGB16: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 5, + /*GREEN*/ 6, + /*BLUE*/ 5, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedShort, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_ARGB8565_Premultiplied: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 5, + /*GREEN*/ 6, + /*BLUE*/ 5, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGB666: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 6, + /*GREEN*/ 6, + /*BLUE*/ 6, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_ARGB6666_Premultiplied: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 6, + /*GREEN*/ 6, + /*BLUE*/ 6, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 6, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGB555: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 5, + /*GREEN*/ 5, + /*BLUE*/ 5, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedShort, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_ARGB8555_Premultiplied: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 5, + /*GREEN*/ 5, + /*BLUE*/ 5, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGB888: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGB444: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 4, + /*GREEN*/ 4, + /*BLUE*/ 4, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedShort, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_ARGB4444_Premultiplied: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 4, + /*GREEN*/ 4, + /*BLUE*/ 4, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 4, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedShort, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGBX8888: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtEnd, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedByte, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGBA8888: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtEnd, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedByte, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGBA8888_Premultiplied: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtEnd, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedByte, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), +}; +Q_STATIC_ASSERT(sizeof(pixelformats) / sizeof(*pixelformats) == QImage::NImageFormats); + +/*! + Returns the QImage::Format as a QPixelFormat +*/ +QPixelFormat QImage::pixelFormat() const Q_DECL_NOTHROW +{ + return toPixelFormat(format()); +} + +/*! + Converts \a format into a QPixelFormat +*/ +QPixelFormat QImage::toPixelFormat(QImage::Format format) Q_DECL_NOTHROW +{ + Q_ASSERT(static_cast(format) < NImageFormats); + return pixelformats[format]; +} + +/*! + Converts \a format into a QImage::Format +*/ +QImage::Format QImage::toImageFormat(const QPixelFormat &format) Q_DECL_NOTHROW +{ + for (int i = 0; i < NImageFormats; i++) { + if (format == pixelformats[i]) + return Format(i); + } + return Format_Invalid; +} + QT_END_NAMESPACE diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h index 4326d5dbbc..365a7873a4 100644 --- a/src/gui/image/qimage.h +++ b/src/gui/image/qimage.h @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -305,6 +306,10 @@ public: QString text(const QString &key = QString()) const; void setText(const QString &key, const QString &value); + QPixelFormat pixelFormat() const Q_DECL_NOTHROW; + static QPixelFormat toPixelFormat(QImage::Format format) Q_DECL_NOTHROW; + static QImage::Format toImageFormat(const QPixelFormat &format) Q_DECL_NOTHROW; + #if QT_DEPRECATED_SINCE(5, 0) QT_DEPRECATED inline QString text(const char* key, const char* lang=0) const; QT_DEPRECATED inline QList textList() const; diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index e9e4a1d818..69568e2f4e 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -68,7 +68,8 @@ HEADERS += \ kernel/qplatformservices.h \ kernel/qplatformscreenpageflipper.h \ kernel/qplatformsystemtrayicon.h \ - kernel/qplatformsessionmanager.h + kernel/qplatformsessionmanager.h \ + kernel/qpixelformat.h SOURCES += \ kernel/qclipboard_qpa.cpp \ @@ -122,7 +123,8 @@ SOURCES += \ kernel/qplatformscreenpageflipper.cpp \ kernel/qplatformsystemtrayicon_qpa.cpp \ kernel/qplatformsessionmanager.cpp \ - kernel/qplatformmenu.cpp + kernel/qplatformmenu.cpp \ + kernel/qpixelformat.cpp contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) { HEADERS += \ diff --git a/src/gui/kernel/qpixelformat.cpp b/src/gui/kernel/qpixelformat.cpp new file mode 100644 index 0000000000..436694915f --- /dev/null +++ b/src/gui/kernel/qpixelformat.cpp @@ -0,0 +1,630 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qpixelformat.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QPixelFormat + \inmodule QtGui + \since 5.4 + \brief QPixelFormat is a class for describing different pixel + layouts in graphics buffers + + In Qt there is a often a need to represent the layout of the pixels in a + graphics buffer. Internally QPixelFormat stores everything in a 64 bit + datastructure. This gives performance but also some limitations. + + QPixelFormat can describe 5 color channels and 1 alpha channel, each can use + 6 bits to describe the size of the color channel. + + The position of the alpha channel is described with a separate enum. This is + to make it possible to describe QImage formats like ARGB32, and also + describe typical OpenGL formats like RBGA8888. + + How pixels are suppose to be read is determined by the TypeInterpretation + enum. It describes if color values are suppose to be read byte per byte, + or if a pixel is suppose to be read as a complete int and then masked. + \sa TypeInterpretation + + There is no support for describing YUV's macro pixels. Instead a list of YUV + formats has been made. When a QPixelFormat is describing a YUV format, the + bitsPerPixel value has been deduced by the YUV Layout enum. Also, the color + channels should all be set to zero except the fifth color channel that + should store the bitsPerPixel value. +*/ + +/*! + \enum QPixelFormat::ColorModel + + This enum type is used to describe the color model of the pixelformat. + + \value RGB The color model is RGB. + + \value BGR This is logically the opposite endian version of RGB. However, + for ease of use it has its own model. + + \value Indexed The color model uses a color palette. + + \value GrayScale The color model is GrayScale. + + \value CMYK The color model is CMYK. + + \value HSL The color model is HSL. + + \value HSV The color model is HSV. + + \value YUV The color model is YUV. +*/ + +/*! + \enum QPixelFormat::AlphaUsage + + This enum describes if the alpha channel is used or not. Sometimes the + pixelformat will have a size for the alpha channel, but the pixel format + does actually not use the alpha channel. For example RGB32 is such a + format. The RGB channels are 8 bits each, and there is no alpha channel. + But the complete size for each pixel is 32. Therefore the alpha channel size + is 8, but the alpha channel is ignored. Its important to note that in such + situations the position of the alpha channel is significant. + + \value IgnoresAlpha The alpha channel is not used. + + \value UsesAlpha The alpha channel is used. +*/ + +/*! + \enum QPixelFormat::AlphaPosition + + This enum type is used to describe the alpha channels position relative to the + color channels. + + \value AtBeginning The alpha channel will be put in front of the color + channels . E.g. ARGB. + + \value AtEnd The alpha channel will be put in the back of the color + channels. E.g. RGBA. +*/ + +/*! + \enum QPixelFormat::AlphaPremultiplied + + This enum type describes the boolean state if the alpha channel is multiplied + into the color channels or not. + + \value NotPremultiplied The alpha channel is not multiplied into the color channels. + + \value Premultiplied The alpha channel is multiplied into the color channels. +*/ + +/*! + \enum QPixelFormat::TypeInterpretation + + This enum describes how each pixel is interpreted. If a pixel is read as a + full 32 bit unsigned integer and then each channel is masked out, or if + each byte is read as unsigned char values. Typically QImage formats + interpret one pixel as an unsigned integer and then the color channels are + masked out. OpenGL on the other hand typically interpreted pixels "one byte + after the other", Ie. unsigned byte. + + QImage also have the format Format_RGBA8888 (and its derivatives), where + the pixels are interpreted as unsigned bytes. OpenGL has extensions that makes it + possible to upload pixel buffers in an unsigned integer format. + + \image qpixelformat-argb32buffer.png An unsigned integer ARGB32 pixel. + + The image above shows a ARGB pixel in memory read as an unsigned integer. + However, if this pixel was read byte for byte on a little endian system the + first byte would be the byte containing the B-channel. The next byte would + be the G-channel, then the R-channel and finally the A-channel. This shows + that on little endian systems, how each pixel is interpreted is significant + for integer formats. This is not the case on big endian systems. + + \value UnsignedInteger + \value UnsignedShort + \value UnsignedByte + \value FloatingPoint +*/ + +/*! + \enum QPixelFormat::ByteOrder + + This enum describes the ByteOrder of the pixel format. This enum is mostly + ignored but have some use cases for YUV formats. BGR formats have their own + color model, and should not be described by using the opposite endianness + on an RGB format. + + \value LittleEndian The byte order is little endian. + \value BigEndian The byte order is big endian. + \value CurrentSystemEndian This enum will not be stored, but is converted in + the constructor to the endian enum that matches + the enum of the current system. + +*/ + +/*! + \enum QPixelFormat::YUVLayout + + YUV is not represented by describing the size of the color channels. This is + because YUV often use macro pixels, making the concept of sperate color channels + invalid. Instead the different YUV layouts are described with this enum. + + \value YUV444 + \value YUV422 + \value YUV411 + \value YUV420P + \value YUV420SP + \value YV12 + \value UYVY + \value YUYV + \value NV12 + \value NV21 + \value IMC1 + \value IMC2 + \value IMC3 + \value IMC4 + \value Y8 + \value Y16 +*/ + +/*! + \fn QPixelFormat::QPixelFormat() + + Creates a null pixelformat. This format maps to QImage::Format_Invalid. +*/ + +/*! + \fn QPixelFormat::QPixelFormat(ColorModel colorModel, + uchar firstSize, + uchar secondSize, + uchar thirdSize, + uchar fourthSize, + uchar fifthSize, + uchar alphaSize, + AlphaUsage alphaUsage, + AlphaPosition alphaPosition, + AlphaPremultiplied premultiplied, + TypeInterpretation typeInterpretation, + ByteOrder byteOrder = CurrentSystemEndian, + uchar subEnum = 0) + + Creates a QPixelFormat which assigns its data to the attributes. + \a colorModel will be put into a buffer which is 4 bits long. + + \a firstSize \a secondSize \a thirdSize \a fourthSize \a fifthSize \a + alphaSize are all meant to represent the size of a channel. The channels will + be used for different uses dependent on the \a colorModel. For RGB the + firstSize will represent the Red channel. On CMYK it will represent the + value of the Cyan channel. + + \a alphaUsage represents if the alpha channel is used or not. + + \a alphaPosition is the position of the alpha channel. + + \a premultiplied represents if the alpha channel is already multiplied with + the color channels. + + \a typeInterpretation is how the pixel is interpreted. + + \a byteOrder represents the endianness of the pixelformat. This defaults to + CurrentSystemEndian. + + \a subEnum is used for colorModels that have to store some extra + information with supplying an extra enum. This is used by YUV to store the + YUV type The default value is 0. +*/ + +Q_STATIC_ASSERT(sizeof(QPixelFormatRgb) == sizeof(QPixelFormat)); + +/*! + \class QPixelFormatRgb + \inmodule QtGui + \since 5.4 + \brief QPixelFormatRgb is a helper class for creating pixel formats with + the rgb color model + + The size of QPixelFormatRgb is guaranteed to be the size of QPixelFormat. +*/ + +/*! + \fn QPixelFormatRgb::QPixelFormatRgb(uchar redSize, + uchar greenSize, + uchar blueSize, + uchar alphaSize, + AlphaUsage alphaUsage, + AlphaPosition alphaPosition, + AlphaPremultiplied premultiplied = NotPremultiplied, + TypeInterpretation typeInterpretation = UnsignedInteger) + + Constructor making an RGB pixelformat. \a redSize \a greenSize \a + blueSize represent the size of each color channel. \a alphaSize describes + the alpha channel size and its position is described with \a alphaPosition. + \a alphaUsage is used to determine if the alpha channel is used or not. + Setting the alpha channel size to 8 and alphaUsage to IgnoresAlpha is how + it is possible to create a 32 bit format where the rgb channels only use 24 + bits combined. \a premultiplied \a typeInterpretation are + accessible with accessors with the same name. + + \sa TypeInterpretation +*/ + +Q_STATIC_ASSERT(sizeof(QPixelFormatGrayScale) == sizeof(QPixelFormat)); +/*! + \class QPixelFormatGrayScale + \inmodule QtGui + \since 5.4 + \brief QPixelFormatGrayScale is a helper class for creating pixel formats with + the gray scale color model. + + The size of QPixelFormatGrayScale is guaranteed to be the size of QPixelFormat. +*/ + +/*! + \fn QPixelFormatGrayScale::QPixelFormatGrayScale(uchar channelSize, + TypeInterpretation typeInterpretation = UnsignedInteger) + + Constructor for creating a GrayScale format. Monochrome formats can be + described by passing 1 to \a channelSize. Its also possible to define very + accurate greyscale formats using doubles to describe each pixel by passing 8 + as \a channelSize and FloatingPoint as \a typeInterpretation. + + \sa TypeInterpretation +*/ + +Q_STATIC_ASSERT(sizeof(QPixelFormatCmyk) == sizeof(QPixelFormat)); +/*! + \class QPixelFormatCmyk + \inmodule QtGui + \since 5.4 + \brief QPixelFormatCmyk is a helper class for creating pixel formats with + the CMYK color model + + The size of QPixelFormatCmyk is guaranteed to be the size of QPixelFormat. +*/ + +/*! + \fn QPixelFormatCmyk::QPixelFormatCmyk(uchar channelSize, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + TypeInterpretation typeInterpretation = UnsignedInteger) + + Constructor for creating CMYK formats. The channel count will be 4 or + 5 depending on if \a alphaSize is bigger than zero or not. The CMYK color + channels will all be set to the value of \a channelSize. + + \a alphaUsage \a alphaPosition and \a typeInterpretation are all accessible with + the accessors with the same name. + + \sa TypeInterpretation +*/ + +Q_STATIC_ASSERT(sizeof(QPixelFormatHsl) == sizeof(QPixelFormat)); +/*! + \class QPixelFormatHsl + \inmodule QtGui + \since 5.4 + \brief QPixelFormatHsl is a helper class for creating pixel formats with + the HSL color model. + + The size of QPixelFormatHsl is guaranteed to be the size of QPixelFormat. +*/ + +/*! + \fn QPixelFormatHsl::QPixelFormatHsl(uchar channelSize, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + TypeInterpretation typeInterpretation = FloatingPoint) + + Constructor for creating HSL formats. The channel count will be 3 or 4 + depending on if \a alphaSize is bigger than 0. + + \a channelSize will set the hueSize saturationSize and lightnessSize to the same value. + + \a alphaUsage \a alphaPosition and \a typeInterpretation are all accessible with + the accessors with the same name. +*/ + +Q_STATIC_ASSERT(sizeof(QPixelFormatHsv) == sizeof(QPixelFormat)); +/*! + \class QPixelFormatHsv + \inmodule QtGui + \since 5.4 + \brief QPixelFormatHsv is a helper class for creating pixel formats with + the HSV color model. + + The size of QPixelFormatHsv is guaranteed to be the size of QPixelFormat. +*/ + +/*! + \fn QPixelFormatHsv::QPixelFormatHsv(uchar channelSize, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + TypeInterpretation typeInterpretation = FloatingPoint) + + Constructor for creating HSV formats. The channel count will be 3 or 4 + depending on if \a alphaSize is bigger than 0. + + \a channelSize will set the hueSize saturationSize and brightnessSize to the same value. + + \a alphaUsage \a alphaPosition and \a typeInterpretation are all accessible with + the accessors with the same name. +*/ + +Q_STATIC_ASSERT(sizeof(QPixelFormatYuv) == sizeof(QPixelFormat)); +/*! + \class QPixelFormatYuv + \inmodule QtGui + \since 5.4 + \brief QPixelFormatYuv is a helper class for creating pixel formats with + the YUV color model. + + The size of QPixelFormatYuv is guaranteed to be the size of QPixelFormat. +*/ + +/*! + \fn QPixelFormatYuv::QPixelFormatYuv(YUVLayout yuvLayout, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + AlphaPremultiplied premultiplied = NotPremultiplied, + TypeInterpretation typeInterpretation = UnsignedByte, + ByteOrder byteOrder = LittleEndian) + + Constructor for creating a QPixelFormat describing a YUV format with + \a yuvLayout. \a alphaSize describes the size of a potential alpha channel + and is position is described with \a alphaPosition. The "first" "second" .. + "fifth" channels are all set to 0. \a alphaUsage \a premultiplied \a + typeInterpretation and \a byteOrder will work as with other formats. +*/ + +/*! + \fn ColorModel QPixelFormat::colorModel() const + + Accessor function for getting the colorModel. +*/ + +/*! + \fn uchar QPixelFormat::channelCount() const + + Accessor function for getting the channelCount. Channel Count is deduced + by color channels with a size > 0 and if the size of the alpha channel is > 0. +*/ + +/*! + \fn uchar QPixelFormat::redSize() const + + Accessor function for the size of the red color channel. +*/ + +/*! + \fn uchar QPixelFormat::greenSize() const + + Accessor function for the size of the green color channel. +*/ + +/*! + \fn uchar QPixelFormat::blueSize() const + + Accessor function for the size of the blue color channel. +*/ + +/*! + \fn uchar QPixelFormat::cyanSize() const + + Accessor function for the cyan color channel. +*/ + +/*! + \fn uchar QPixelFormat::magentaSize() const + + Accessor function for the megenta color channel. +*/ + +/*! + \fn uchar QPixelFormat::yellowSize() const + + Accessor function for the yellow color channel. +*/ + +/*! + \fn uchar QPixelFormat::blackSize() const + + Accessor function for the black/key color channel. +*/ + +/*! + \fn uchar QPixelFormat::hueSize() const + + Accessor function for the hue channel size. +*/ + +/*! + \fn uchar QPixelFormat::saturationSize() const + + Accessor function for the saturation channel size. +*/ + +/*! + \fn uchar QPixelFormat::lightnessSize() const + + Accessor function for the lightness channel size. +*/ + +/*! + \fn uchar QPixelFormat::brightnessSize() const + + Accessor function for the brightness channel size. +*/ + +/*! + \fn uchar QPixelFormat::alphaSize() const + + Accessor function for the alpha channel size. +*/ + +/*! + \fn uchar QPixelFormat::bitsPerPixel() const + + Accessor function for the bits used per pixel. This function returns the + sum of the color channels + the size of the alpha channel. +*/ + +/*! + \fn AlphaPremultiplied QPixelFormat::premultiplied() const + + Accessor function for the AlphaPremultiplied enum. This indicates if the + alpha channel is multiplied in to the color channels. + +*/ + +/*! + \fn TypeInterpretation QPixelFormat::typeInterpretation() const + + Accessor function for the type representation of a color channel or a pixel. + + \sa TypeInterpretation +*/ + +/*! + \fn ByteOrder QPixelFormat::byteOrder() const + + The byte order is almost always set the the byte order of the current + system. However, it can be useful to describe some YUV formats. This + function should never return QPixelFormat::CurrentSystemEndian as this + value is translated to a endian value in the constructor. +*/ + +/*! + \fn AlphaUsage QPixelFormat::alphaUsage() const + + Accessor function for alphaUsage. +*/ + +/*! + \fn AlphaPosition QPixelFormat::alphaPosition() const + + Accessor function for alphaPosition. +*/ + +/*! + \fn YUVLayout QPixelFormat::yuvLayout() const + + Accessor function for the YUVLayout. It is difficult to describe the color + channels of a YUV pixel format since YUV color model uses macro pixels. + Instead the layout of the pixels are stored as an enum. +*/ + +/*! + \fn uchar QPixelFormat::subEnum() const + + Accessor for the datapart which contains subEnums + This is the same as the yuvLayout() function. + + \sa yuvLayout() + \internal +*/ + +Q_STATIC_ASSERT(sizeof(QPixelFormat) == sizeof(quint64)); + + +namespace QtPrivate { + QPixelFormat QPixelFormat_createYUV(QPixelFormat::YUVLayout yuvLayout, + uchar alphaSize, + QPixelFormat::AlphaUsage alphaUsage, + QPixelFormat::AlphaPosition alphaPosition, + QPixelFormat::AlphaPremultiplied premultiplied, + QPixelFormat::TypeInterpretation typeInterpretation, + QPixelFormat::ByteOrder byteOrder) + { + uchar bits_per_pixel = 0; + switch (yuvLayout) { + case QPixelFormat::YUV444: + bits_per_pixel = 24; + break; + case QPixelFormat::YUV422: + bits_per_pixel = 16; + break; + case QPixelFormat::YUV411: + case QPixelFormat::YUV420P: + case QPixelFormat::YUV420SP: + case QPixelFormat::YV12: + bits_per_pixel = 12; + break; + case QPixelFormat::UYVY: + case QPixelFormat::YUYV: + bits_per_pixel = 16; + break; + case QPixelFormat::NV12: + case QPixelFormat::NV21: + bits_per_pixel = 12; + break; + case QPixelFormat::IMC1: + case QPixelFormat::IMC2: + case QPixelFormat::IMC3: + case QPixelFormat::IMC4: + bits_per_pixel = 12; + break; + case QPixelFormat::Y8: + bits_per_pixel = 8; + break; + case QPixelFormat::Y16: + bits_per_pixel = 16; + break; + } + + return QPixelFormat(QPixelFormat::YUV, + 0, 0, 0, 0, + bits_per_pixel, + alphaSize, + alphaUsage, + alphaPosition, + premultiplied, + typeInterpretation, + byteOrder, + yuvLayout); + } +} + +QT_END_NAMESPACE diff --git a/src/gui/kernel/qpixelformat.h b/src/gui/kernel/qpixelformat.h new file mode 100644 index 0000000000..b020a53e6d --- /dev/null +++ b/src/gui/kernel/qpixelformat.h @@ -0,0 +1,452 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPIXELFORMAT_H +#define QPIXELFORMAT_H + +#include + +QT_BEGIN_NAMESPACE + +class QPixelFormat +{ +public: + enum ColorModel { + RGB, + BGR, + Indexed, + GrayScale, + CMYK, + HSL, + HSV, + YUV + }; + + enum AlphaUsage { + UsesAlpha, + IgnoresAlpha + }; + + enum AlphaPosition { + AtBeginning, + AtEnd + }; + + enum AlphaPremultiplied { + NotPremultiplied, + Premultiplied + }; + + enum TypeInterpretation { + UnsignedInteger, + UnsignedShort, + UnsignedByte, + FloatingPoint + }; + + enum YUVLayout { + YUV444, + YUV422, + YUV411, + YUV420P, + YUV420SP, + YV12, + UYVY, + YUYV, + NV12, + NV21, + IMC1, + IMC2, + IMC3, + IMC4, + Y8, + Y16 + }; + + enum ByteOrder { + LittleEndian, + BigEndian, + CurrentSystemEndian + }; + + Q_DECL_CONSTEXPR inline QPixelFormat() Q_DECL_NOTHROW; + Q_DECL_CONSTEXPR inline QPixelFormat(ColorModel colorModel, + uchar firstSize, + uchar secondSize, + uchar thirdSize, + uchar fourthSize, + uchar fifthSize, + uchar alphaSize, + AlphaUsage alphaUsage, + AlphaPosition alphaPosition, + AlphaPremultiplied premultiplied, + TypeInterpretation typeInterpretation, + ByteOrder byteOrder = CurrentSystemEndian, + uchar subEnum = 0) Q_DECL_NOTHROW; + + Q_DECL_CONSTEXPR inline ColorModel colorModel() const Q_DECL_NOTHROW { return ColorModel(model); } + Q_DECL_CONSTEXPR inline uchar channelCount() const Q_DECL_NOTHROW { return (first > 0) + + (second > 0) + + (third > 0) + + (fourth > 0) + + (fifth > 0) + + (alpha > 0); } + + Q_DECL_CONSTEXPR inline uchar redSize() const Q_DECL_NOTHROW { return first; } + Q_DECL_CONSTEXPR inline uchar greenSize() const Q_DECL_NOTHROW { return second; } + Q_DECL_CONSTEXPR inline uchar blueSize() const Q_DECL_NOTHROW { return third; } + + Q_DECL_CONSTEXPR inline uchar cyanSize() const Q_DECL_NOTHROW { return first; } + Q_DECL_CONSTEXPR inline uchar magentaSize() const Q_DECL_NOTHROW { return second; } + Q_DECL_CONSTEXPR inline uchar yellowSize() const Q_DECL_NOTHROW { return third; } + Q_DECL_CONSTEXPR inline uchar blackSize() const Q_DECL_NOTHROW { return fourth; } + + Q_DECL_CONSTEXPR inline uchar hueSize() const Q_DECL_NOTHROW { return first; } + Q_DECL_CONSTEXPR inline uchar saturationSize() const Q_DECL_NOTHROW { return second; } + Q_DECL_CONSTEXPR inline uchar lightnessSize() const Q_DECL_NOTHROW { return third; } + Q_DECL_CONSTEXPR inline uchar brightnessSize() const Q_DECL_NOTHROW { return third; } + + Q_DECL_CONSTEXPR inline uchar alphaSize() const Q_DECL_NOTHROW { return alpha; } + + Q_DECL_CONSTEXPR inline uchar bitsPerPixel() const Q_DECL_NOTHROW { return first + + second + + third + + fourth + + fifth + + alpha; } + + Q_DECL_CONSTEXPR inline AlphaUsage alphaUsage() const Q_DECL_NOTHROW { return AlphaUsage(alpha_usage); } + Q_DECL_CONSTEXPR inline AlphaPosition alphaPosition() const Q_DECL_NOTHROW { return AlphaPosition(alpha_position); } + Q_DECL_CONSTEXPR inline AlphaPremultiplied premultiplied() const Q_DECL_NOTHROW { return AlphaPremultiplied(premul); } + Q_DECL_CONSTEXPR inline TypeInterpretation typeInterpretation() const Q_DECL_NOTHROW { return TypeInterpretation(type_interpretation); } + Q_DECL_CONSTEXPR inline ByteOrder byteOrder() const Q_DECL_NOTHROW { return ByteOrder(byte_order); } + + Q_DECL_CONSTEXPR inline YUVLayout yuvLayout() const Q_DECL_NOTHROW { return YUVLayout(sub_enum); } + Q_DECL_CONSTEXPR inline uchar subEnum() const Q_DECL_NOTHROW { return sub_enum; } + +protected: + quint64 model : 4; + quint64 first : 6; + quint64 second : 6; + quint64 third : 6; + quint64 fourth : 6; + quint64 fifth : 6; + quint64 alpha : 6; + quint64 alpha_usage : 1; + quint64 alpha_position : 1; + quint64 premul: 1; + quint64 type_interpretation : 4; + quint64 byte_order : 2; + quint64 sub_enum : 6; + quint64 unused : 8; + + friend Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline bool operator==(const QPixelFormat &fmt1, const QPixelFormat &fmt2); + friend Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline bool operator!=(const QPixelFormat &fmt1, const QPixelFormat &fmt2); +}; +Q_DECLARE_TYPEINFO(QPixelFormat, Q_PRIMITIVE_TYPE); + +class QPixelFormatRgb : public QPixelFormat +{ +public: + Q_DECL_CONSTEXPR + inline QPixelFormatRgb(uchar redSize, + uchar greenSize, + uchar blueSize, + uchar alphaSize, + AlphaUsage alphaUsage, + AlphaPosition alphaPosition, + AlphaPremultiplied premultiplied = NotPremultiplied, + TypeInterpretation typeInterpretation = UnsignedInteger) Q_DECL_NOTHROW; +}; + +class QPixelFormatGrayScale : public QPixelFormat +{ +public: + Q_DECL_CONSTEXPR + inline QPixelFormatGrayScale(uchar bufferSize, + TypeInterpretation typeInterpretation = UnsignedInteger) Q_DECL_NOTHROW; +}; + +class QPixelFormatCmyk : public QPixelFormat +{ +public: + Q_DECL_CONSTEXPR + inline QPixelFormatCmyk(uchar channelSize, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + TypeInterpretation typeInterpretation = UnsignedInteger) Q_DECL_NOTHROW; +}; + +class QPixelFormatHsl : public QPixelFormat +{ +public: + Q_DECL_CONSTEXPR + inline QPixelFormatHsl(uchar channelSize, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + TypeInterpretation typeInterpretation = FloatingPoint) Q_DECL_NOTHROW; +}; + +class QPixelFormatHsv : public QPixelFormat +{ +public: + Q_DECL_CONSTEXPR + inline QPixelFormatHsv(uchar channelSize, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + TypeInterpretation typeInterpretation = FloatingPoint) Q_DECL_NOTHROW; +}; + +namespace QtPrivate { + QPixelFormat Q_GUI_EXPORT QPixelFormat_createYUV(QPixelFormat::YUVLayout yuvLayout, + uchar alphaSize, + QPixelFormat::AlphaUsage alphaUsage, + QPixelFormat::AlphaPosition alphaPosition, + QPixelFormat::AlphaPremultiplied premultiplied, + QPixelFormat::TypeInterpretation typeInterpretation, + QPixelFormat::ByteOrder byteOrder); +} + +class QPixelFormatYuv : public QPixelFormat +{ +public: + inline QPixelFormatYuv(YUVLayout yuvLayout, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + AlphaPremultiplied premultiplied = NotPremultiplied, + TypeInterpretation typeInterpretation = UnsignedByte, + ByteOrder byteOrder = LittleEndian); +}; + +Q_DECL_CONSTEXPR +QPixelFormat::QPixelFormat() Q_DECL_NOTHROW + : model(0) + , first(0) + , second(0) + , third(0) + , fourth(0) + , fifth(0) + , alpha(0) + , alpha_usage(0) + , alpha_position(0) + , premul(0) + , type_interpretation(0) + , byte_order(0) + , sub_enum(0) + , unused(0) +{ +} + +Q_DECL_CONSTEXPR +QPixelFormat::QPixelFormat(ColorModel mdl, + uchar firstSize, + uchar secondSize, + uchar thirdSize, + uchar fourthSize, + uchar fifthSize, + uchar alfa, + AlphaUsage usage, + AlphaPosition position, + AlphaPremultiplied premult, + TypeInterpretation typeInterp, + ByteOrder b_order, + uchar s_enum) Q_DECL_NOTHROW + : model(mdl) + , first(firstSize) + , second(secondSize) + , third(thirdSize) + , fourth(fourthSize) + , fifth(fifthSize) + , alpha(alfa) + , alpha_usage(usage) + , alpha_position(position) + , premul(premult) + , type_interpretation(typeInterp) +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + , byte_order(b_order == CurrentSystemEndian ? LittleEndian : b_order) +#else + , byte_order(b_order == CurrentSystemEndian ? BigEndian : b_order) +#endif + , sub_enum(s_enum) + , unused(0) +{ +} + +Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline bool operator==(const QPixelFormat &fmt1, const QPixelFormat &fmt2) +{ + return fmt1.model == fmt2.model + && fmt1.first == fmt2.first + && fmt1.second == fmt2.second + && fmt1.third == fmt2.third + && fmt1.fourth == fmt2.fourth + && fmt1.fifth == fmt2.fifth + && fmt1.alpha == fmt2.alpha + && fmt1.alpha_usage == fmt2.alpha_usage + && fmt1.alpha_position == fmt2.alpha_position + && fmt1.premul == fmt2.premul + && fmt1.type_interpretation == fmt2.type_interpretation + && fmt1.byte_order == fmt2.byte_order + && fmt1.sub_enum == fmt2.sub_enum + && fmt1.unused == fmt2.unused; +} + +Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline bool operator!=(const QPixelFormat &fmt1, const QPixelFormat &fmt2) +{ return !(fmt1 == fmt2); } + +Q_DECL_CONSTEXPR +QPixelFormatRgb::QPixelFormatRgb(uchar red, + uchar green, + uchar blue, + uchar alfa, + AlphaUsage usage, + AlphaPosition position, + AlphaPremultiplied pmul, + TypeInterpretation typeInt) Q_DECL_NOTHROW + : QPixelFormat(RGB, + red, + green, + blue, + 0, + 0, + alfa, + usage, + position, + pmul, + typeInt) +{ } + +Q_DECL_CONSTEXPR +QPixelFormatGrayScale::QPixelFormatGrayScale(uchar channelSize, + TypeInterpretation typeInt) Q_DECL_NOTHROW + : QPixelFormat(GrayScale, + channelSize, + 0, + 0, + 0, + 0, + 0, + IgnoresAlpha, + AtBeginning, + NotPremultiplied, + typeInt) +{ } + +Q_DECL_CONSTEXPR +QPixelFormatCmyk::QPixelFormatCmyk(uchar channelSize, + uchar alfa, + AlphaUsage usage, + AlphaPosition position, + TypeInterpretation typeInt) Q_DECL_NOTHROW + : QPixelFormat(CMYK, + channelSize, + channelSize, + channelSize, + channelSize, + 0, + alfa, + usage, + position, + NotPremultiplied, + typeInt) +{ } + +Q_DECL_CONSTEXPR +QPixelFormatHsl::QPixelFormatHsl(uchar channelSize, + uchar alfa, + AlphaUsage usage, + AlphaPosition position, + TypeInterpretation typeInt) Q_DECL_NOTHROW + : QPixelFormat(HSL, + channelSize, + channelSize, + channelSize, + 0, + 0, + alfa, + usage, + position, + NotPremultiplied, + typeInt) +{ } + +Q_DECL_CONSTEXPR +QPixelFormatHsv::QPixelFormatHsv(uchar channelSize, + uchar alfa, + AlphaUsage usage, + AlphaPosition position, + TypeInterpretation typeInt) Q_DECL_NOTHROW + : QPixelFormat(HSV, + channelSize, + channelSize, + channelSize, + 0, + 0, + alfa, + usage, + position, + NotPremultiplied, + typeInt) +{ } + +QPixelFormatYuv::QPixelFormatYuv(YUVLayout layout, + uchar alfa, + AlphaUsage usage, + AlphaPosition position, + AlphaPremultiplied p_mul, + TypeInterpretation typeInt, + ByteOrder b_order) + : QPixelFormat(QtPrivate::QPixelFormat_createYUV(layout, + alfa, + usage, + position, + p_mul, + typeInt, + b_order)) + +{ } + +QT_END_NAMESPACE + +#endif //QPIXELFORMAT_H diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 95a9b142ec..d2072e0e56 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -170,6 +170,10 @@ private slots: void scaled_QTBUG35972(); + void convertToPixelFormat(); + void convertToImageFormat_data(); + void convertToImageFormat(); + void cleanupFunctions(); }; @@ -2460,6 +2464,46 @@ void tst_QImage::scaled_QTBUG35972() QCOMPARE(pixels[i], 0xffffffff); } +void tst_QImage::convertToPixelFormat() +{ + QPixelFormat rgb565 = QPixelFormatRgb(5,6,5,0,QPixelFormat::IgnoresAlpha, QPixelFormat::AtBeginning, QPixelFormat::NotPremultiplied, QPixelFormat::UnsignedShort); + QPixelFormat rgb565ImageFormat = QImage::toPixelFormat(QImage::Format_RGB16); + QCOMPARE(rgb565, rgb565ImageFormat); +} + +void tst_QImage::convertToImageFormat_data() +{ + QTest::addColumn("image_format"); + QTest::newRow("Convert Format_Invalid") << QImage::Format_Invalid; + QTest::newRow("Convert Format_Mono") << QImage::Format_Mono; + //This ends up being a QImage::Format_Mono since we cant specify LSB in QPixelFormat + //QTest::newRow("Convert Format_MonoLSB") << QImage::Format_MonoLSB; + QTest::newRow("Convert Format_Indexed8") << QImage::Format_Indexed8; + QTest::newRow("Convert Format_RGB32") << QImage::Format_RGB32; + QTest::newRow("Convert Format_ARGB32") << QImage::Format_ARGB32; + QTest::newRow("Convert Format_ARGB32_Premultiplied") << QImage::Format_ARGB32_Premultiplied; + QTest::newRow("Convert Format_RGB16") << QImage::Format_RGB16; + QTest::newRow("Convert Format_ARGB8565_Premultiplied") << QImage::Format_ARGB8565_Premultiplied; + QTest::newRow("Convert Format_RGB666") << QImage::Format_RGB666; + QTest::newRow("Convert Format_ARGB6666_Premultiplied") << QImage::Format_ARGB6666_Premultiplied; + QTest::newRow("Convert Format_RGB555") << QImage::Format_RGB555; + QTest::newRow("Convert Format_ARGB8555_Premultiplied") << QImage::Format_ARGB8555_Premultiplied; + QTest::newRow("Convert Format_RGB888") << QImage::Format_RGB888; + QTest::newRow("Convert Format_RGB444") << QImage::Format_RGB444; + QTest::newRow("Convert Format_ARGB4444_Premultiplied") << QImage::Format_ARGB4444_Premultiplied; + QTest::newRow("Convert Format_RGBX8888") << QImage::Format_RGBX8888; + QTest::newRow("Convert Format_RGBA8888") << QImage::Format_RGBA8888; + QTest::newRow("Convert Format_RGBA8888_Premultiplied") << QImage::Format_RGBA8888_Premultiplied; +} +void tst_QImage::convertToImageFormat() +{ + QFETCH(QImage::Format, image_format); + + QPixelFormat pixel_format = QImage::toPixelFormat(image_format); + QImage::Format format = QImage::toImageFormat(pixel_format); + QCOMPARE(format, image_format); +} + static void cleanupFunction(void* info) { bool *called = static_cast(info); diff --git a/tests/auto/gui/kernel/kernel.pro b/tests/auto/gui/kernel/kernel.pro index e4d9ce9d27..bbcdd91ea3 100644 --- a/tests/auto/gui/kernel/kernel.pro +++ b/tests/auto/gui/kernel/kernel.pro @@ -20,6 +20,7 @@ SUBDIRS=\ qtouchevent \ qwindow \ qguiapplication \ + qpixelformat \ !qtHaveModule(widgets): SUBDIRS -= \ qmouseevent_modal \ diff --git a/tests/auto/gui/kernel/qpixelformat/qpixelformat.pro b/tests/auto/gui/kernel/qpixelformat/qpixelformat.pro new file mode 100644 index 0000000000..970e5c7c2d --- /dev/null +++ b/tests/auto/gui/kernel/qpixelformat/qpixelformat.pro @@ -0,0 +1,6 @@ +CONFIG += testcase +TARGET = tst_qpixelformat + +QT += gui testlib + +SOURCES += tst_qpixelformat.cpp diff --git a/tests/auto/gui/kernel/qpixelformat/tst_qpixelformat.cpp b/tests/auto/gui/kernel/qpixelformat/tst_qpixelformat.cpp new file mode 100644 index 0000000000..c3b19a3b44 --- /dev/null +++ b/tests/auto/gui/kernel/qpixelformat/tst_qpixelformat.cpp @@ -0,0 +1,243 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include + +#include + +class tst_QPixelFormat : public QObject +{ + Q_OBJECT + +private slots: + void testOperators(); + void testQVectorOfFormats(); + void testRGB(); + void testCMYK(); + void testHSLandHSV(); + void testYUV_data(); + void testYUV(); + void testEnums(); +}; + +void tst_QPixelFormat::testOperators() +{ + QPixelFormat first = QPixelFormatRgb(8,8,8,8,QPixelFormat::UsesAlpha, QPixelFormat::AtBeginning, QPixelFormat::Premultiplied); + QPixelFormat second = QPixelFormatRgb(8,8,8,8,QPixelFormat::UsesAlpha, QPixelFormat::AtBeginning, QPixelFormat::Premultiplied); + QVERIFY(first == second); + + QPixelFormat third = QPixelFormatRgb(8,8,8,8,QPixelFormat::UsesAlpha, QPixelFormat::AtEnd, QPixelFormat::NotPremultiplied); + QVERIFY(first != third); +} + +void tst_QPixelFormat::testQVectorOfFormats() +{ + QVector reallocedVector; + QVector reservedVector; + reservedVector.reserve(QImage::NImageFormats); + for (int i = 0; i < QImage::NImageFormats; i++) { + if (i == 0 || i == 2) // skip invalid and monolsb + continue; + QImage::Format image_format = static_cast(i); + QPixelFormat format = QImage::toPixelFormat(image_format); + reallocedVector.append(format); + reservedVector.append(format); + } + + for (int i = 0; i < reallocedVector.size(); i++) { + QCOMPARE(reallocedVector.at(i), reservedVector.at(i)); + } +} + +void tst_QPixelFormat::testRGB() +{ + QPixelFormat argb8888 = QPixelFormatRgb(8,8,8,8,QPixelFormat::UsesAlpha,QPixelFormat::AtBeginning, QPixelFormat::Premultiplied); + QCOMPARE(argb8888.redSize(), uchar(8)); + QCOMPARE(argb8888.greenSize(), uchar(8)); + QCOMPARE(argb8888.blueSize(), uchar(8)); + QCOMPARE(argb8888.alphaSize(), uchar(8)); + + QPixelFormat rgb565 = QPixelFormatRgb(5,6,5,0,QPixelFormat::IgnoresAlpha,QPixelFormat::AtBeginning, QPixelFormat::NotPremultiplied); + QCOMPARE(rgb565.redSize(), uchar(5)); + QCOMPARE(rgb565.greenSize(), uchar(6)); + QCOMPARE(rgb565.blueSize(), uchar(5)); + QCOMPARE(rgb565.alphaSize(), uchar(0)); + QCOMPARE(rgb565.bitsPerPixel(), uchar(16)); + + QPixelFormat rgba1235 = QPixelFormatRgb(1,2,3,5,QPixelFormat::IgnoresAlpha, QPixelFormat::AtEnd, QPixelFormat::Premultiplied); + QCOMPARE(rgba1235.redSize(), uchar(1)); + QCOMPARE(rgba1235.greenSize(), uchar(2)); + QCOMPARE(rgba1235.blueSize(), uchar(3)); + QCOMPARE(rgba1235.alphaSize(), uchar(5)); + QCOMPARE(rgba1235.bitsPerPixel(), uchar(1 + 2 + 3 + 5)); +} + +void tst_QPixelFormat::testCMYK() +{ + QPixelFormat cmyk6 = QPixelFormatCmyk(6); + QCOMPARE(cmyk6.cyanSize(), uchar(6)); + QCOMPARE(cmyk6.magentaSize(), uchar(6)); + QCOMPARE(cmyk6.yellowSize(), uchar(6)); + QCOMPARE(cmyk6.blackSize(), uchar(6)); + QCOMPARE(cmyk6.bitsPerPixel(), uchar(6*4)); + + QPixelFormat cmykWithAlpha = QPixelFormatCmyk(8,8); + QCOMPARE(cmykWithAlpha.bitsPerPixel(), uchar(8*5)); +} +void tst_QPixelFormat::testHSLandHSV() +{ + QPixelFormat hsl = QPixelFormatHsl(3,5); + + QCOMPARE(hsl.hueSize(), uchar(3)); + QCOMPARE(hsl.saturationSize(), uchar(3)); + QCOMPARE(hsl.lightnessSize(), uchar(3)); + QCOMPARE(hsl.bitsPerPixel(), uchar(3 * 3 + 5)); + + QPixelFormat hsv = QPixelFormatHsv(5,7); + + QCOMPARE(hsv.hueSize(), uchar(5)); + QCOMPARE(hsv.saturationSize(), uchar(5)); + QCOMPARE(hsv.brightnessSize(), uchar(5)); + QCOMPARE(hsv.bitsPerPixel(), uchar(5 * 3 + 7)); +} + +Q_DECLARE_METATYPE(QPixelFormat::YUVLayout) +void tst_QPixelFormat::testYUV_data() +{ + QTest::addColumn("yuv_layout"); + QTest::newRow("YUV Layout YUV444") << QPixelFormat::YUV444; + QTest::newRow("YUV Layout YUV422") << QPixelFormat::YUV422; + QTest::newRow("YUV Layout YUV411") << QPixelFormat::YUV411; + QTest::newRow("YUV Layout YUV420P") << QPixelFormat::YUV420P; + QTest::newRow("YUV Layout YUV420SP") << QPixelFormat::YUV420SP; + QTest::newRow("YUV Layout YV12") << QPixelFormat::YV12; + QTest::newRow("YUV Layout UYVY") << QPixelFormat::UYVY; + QTest::newRow("YUV Layout YUYV") << QPixelFormat::YUYV; + QTest::newRow("YUV Layout NV12") << QPixelFormat::NV12; + QTest::newRow("YUV Layout NV21") << QPixelFormat::NV21; + QTest::newRow("YUV Layout IMC1") << QPixelFormat::IMC1; + QTest::newRow("YUV Layout IMC2") << QPixelFormat::IMC2; + QTest::newRow("YUV Layout IMC3") << QPixelFormat::IMC3; + QTest::newRow("YUV Layout IMC4") << QPixelFormat::IMC4; + QTest::newRow("YUV Layout Y8") << QPixelFormat::Y8; + QTest::newRow("YUV Layout Y16") << QPixelFormat::Y16; +} + +void tst_QPixelFormat::testYUV() +{ + QFETCH(QPixelFormat::YUVLayout, yuv_layout); + + QPixelFormat format = QPixelFormatYuv(yuv_layout, 0); + + switch (yuv_layout) { + case QPixelFormat::YUV444: + QCOMPARE(format.bitsPerPixel(), uchar(24)); + break; + case QPixelFormat::YUV422: + QCOMPARE(format.bitsPerPixel(), uchar(16)); + break; + case QPixelFormat::YUV411: + case QPixelFormat::YUV420P: + case QPixelFormat::YUV420SP: + case QPixelFormat::YV12: + QCOMPARE(format.bitsPerPixel(), uchar(12)); + break; + case QPixelFormat::UYVY: + case QPixelFormat::YUYV: + QCOMPARE(format.bitsPerPixel(), uchar(16)); + break; + case QPixelFormat::NV12: + case QPixelFormat::NV21: + QCOMPARE(format.bitsPerPixel(), uchar(12)); + break; + case QPixelFormat::IMC1: + case QPixelFormat::IMC2: + case QPixelFormat::IMC3: + case QPixelFormat::IMC4: + QCOMPARE(format.bitsPerPixel(), uchar(12)); + break; + case QPixelFormat::Y8: + QCOMPARE(format.bitsPerPixel(), uchar(8)); + break; + case QPixelFormat::Y16: + QCOMPARE(format.bitsPerPixel(), uchar(16)); + break; + default: + QVERIFY(!"the value stored for the yuvLayout is wrong!"); + } + +} + +void tst_QPixelFormat::testEnums() +{ + QPixelFormat allSet = QPixelFormat(QPixelFormat::BGR,1,2,3,4,5,6, + QPixelFormat::UsesAlpha, + QPixelFormat::AtEnd, + QPixelFormat::Premultiplied, + QPixelFormat::FloatingPoint, + QPixelFormat::BigEndian, + (1 << 6) - 1); + + QCOMPARE(allSet.alphaUsage(), QPixelFormat::UsesAlpha); + QCOMPARE(allSet.alphaPosition(), QPixelFormat::AtEnd); + QCOMPARE(allSet.premultiplied(), QPixelFormat::Premultiplied); + QCOMPARE(allSet.byteOrder(), QPixelFormat::BigEndian); + QCOMPARE(allSet.typeInterpretation(), QPixelFormat::FloatingPoint); + QCOMPARE(allSet.byteOrder(), QPixelFormat::BigEndian); + QCOMPARE(allSet.subEnum(), uchar(63)); + + QPixelFormat nonSet = QPixelFormat(QPixelFormat::RGB,6,5,4,3,2,1, + QPixelFormat::IgnoresAlpha, + QPixelFormat::AtBeginning, + QPixelFormat::NotPremultiplied, + QPixelFormat::UnsignedInteger, + QPixelFormat::LittleEndian); + + QCOMPARE(nonSet.alphaUsage(), QPixelFormat::IgnoresAlpha); + QCOMPARE(nonSet.alphaPosition(), QPixelFormat::AtBeginning); + QCOMPARE(nonSet.premultiplied(), QPixelFormat::NotPremultiplied); + QCOMPARE(nonSet.byteOrder(), QPixelFormat::LittleEndian); + QCOMPARE(nonSet.typeInterpretation(), QPixelFormat::UnsignedInteger); + QCOMPARE(nonSet.byteOrder(), QPixelFormat::LittleEndian); + QCOMPARE(nonSet.subEnum(), uchar(0)); +} + +#include +QTEST_MAIN(tst_QPixelFormat);