Move endian integers to qendian_p.h
The endian integers have more use than just in QJson, and is already used separately by QtDeclarative. This patch moves q_littleendian out of qjson_p.h and matches it with a corresponding q_bigendian, and puts it to use in simplifying endian handling in the ico image handler. Change-Id: I975bb701a089256db8ced3cb53b4bd62cdfb02dd Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>bb10
parent
4d70e03002
commit
e5e1fac136
|
|
@ -9,6 +9,7 @@ HEADERS += \
|
|||
global/qprocessordetection.h \
|
||||
global/qnamespace.h \
|
||||
global/qendian.h \
|
||||
global/qendian_p.h \
|
||||
global/qnumeric_p.h \
|
||||
global/qnumeric.h \
|
||||
global/qfloat16_p.h \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,141 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtCore 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 The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QENDIAN_P_H
|
||||
#define QENDIAN_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qendian.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
template<class S>
|
||||
class QSpecialInteger
|
||||
{
|
||||
typedef typename S::StorageType T;
|
||||
T val;
|
||||
public:
|
||||
QSpecialInteger() = default;
|
||||
explicit Q_DECL_CONSTEXPR QSpecialInteger(T i) : val(S::toSpecial(i)) {}
|
||||
|
||||
QSpecialInteger &operator =(T i) { val = S::toSpecial(i); return *this; }
|
||||
operator T() const { return S::fromSpecial(val); }
|
||||
|
||||
bool operator ==(QSpecialInteger<S> i) const { return val == i.val; }
|
||||
bool operator !=(QSpecialInteger<S> i) const { return val != i.val; }
|
||||
|
||||
QSpecialInteger &operator +=(T i)
|
||||
{ return (*this = S::fromSpecial(val) + i); }
|
||||
QSpecialInteger &operator -=(T i)
|
||||
{ return (*this = S::fromSpecial(val) - i); }
|
||||
QSpecialInteger &operator *=(T i)
|
||||
{ return (*this = S::fromSpecial(val) * i); }
|
||||
QSpecialInteger &operator >>=(T i)
|
||||
{ return (*this = S::fromSpecial(val) >> i); }
|
||||
QSpecialInteger &operator <<=(T i)
|
||||
{ return (*this = S::fromSpecial(val) << i); }
|
||||
QSpecialInteger &operator /=(T i)
|
||||
{ return (*this = S::fromSpecial(val) / i); }
|
||||
QSpecialInteger &operator %=(T i)
|
||||
{ return (*this = S::fromSpecial(val) % i); }
|
||||
QSpecialInteger &operator |=(T i)
|
||||
{ return (*this = S::fromSpecial(val) | i); }
|
||||
QSpecialInteger &operator &=(T i)
|
||||
{ return (*this = S::fromSpecial(val) & i); }
|
||||
QSpecialInteger &operator ^=(T i)
|
||||
{ return (*this = S::fromSpecial(val) ^ i); }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class QLittleEndianStorageType {
|
||||
public:
|
||||
typedef T StorageType;
|
||||
static Q_DECL_CONSTEXPR T toSpecial(T source) { return qToLittleEndian(source); }
|
||||
static Q_DECL_CONSTEXPR T fromSpecial(T source) { return qFromLittleEndian(source); }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class QBigEndianStorageType {
|
||||
public:
|
||||
typedef T StorageType;
|
||||
static Q_DECL_CONSTEXPR T toSpecial(T source) { return qToBigEndian(source); }
|
||||
static Q_DECL_CONSTEXPR T fromSpecial(T source) { return qFromBigEndian(source); }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using QLEInteger = QSpecialInteger<QLittleEndianStorageType<T>>;
|
||||
|
||||
template<typename T>
|
||||
using QBEInteger = QSpecialInteger<QBigEndianStorageType<T>>;
|
||||
|
||||
template <typename T>
|
||||
class QTypeInfo<QLEInteger<T> >
|
||||
: public QTypeInfoMerger<QLEInteger<T>, T> {};
|
||||
|
||||
template <typename T>
|
||||
class QTypeInfo<QBEInteger<T> >
|
||||
: public QTypeInfoMerger<QBEInteger<T>, T> {};
|
||||
|
||||
typedef QLEInteger<qint16> qint16_le;
|
||||
typedef QLEInteger<qint32> qint32_le;
|
||||
typedef QLEInteger<qint64> qint64_le;
|
||||
typedef QLEInteger<quint16> quint16_le;
|
||||
typedef QLEInteger<quint32> quint32_le;
|
||||
typedef QLEInteger<quint64> quint64_le;
|
||||
|
||||
typedef QBEInteger<qint16> qint16_be;
|
||||
typedef QBEInteger<qint32> qint32_be;
|
||||
typedef QBEInteger<qint64> qint64_be;
|
||||
typedef QBEInteger<quint16> quint16_be;
|
||||
typedef QBEInteger<quint32> quint32_be;
|
||||
typedef QBEInteger<quint64> quint64_be;
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QENDIAN_P_H
|
||||
|
|
@ -45,15 +45,8 @@ QT_BEGIN_NAMESPACE
|
|||
namespace QJsonPrivate
|
||||
{
|
||||
|
||||
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
||||
#define Q_TO_LITTLE_ENDIAN(x) (x)
|
||||
#else
|
||||
#define Q_TO_LITTLE_ENDIAN(x) ( ((x & 0xff) << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | ((x & 0xff000000) >> 24) )
|
||||
#endif
|
||||
|
||||
static const Base emptyArray = { { Q_TO_LITTLE_ENDIAN(sizeof(Base)) }, { 0 }, { 0 } };
|
||||
static const Base emptyObject = { { Q_TO_LITTLE_ENDIAN(sizeof(Base)) }, { 0 }, { 0 } };
|
||||
|
||||
static Q_CONSTEXPR Base emptyArray = { { qle_uint(sizeof(Base)) }, { 0 }, { qle_uint(0) } };
|
||||
static Q_CONSTEXPR Base emptyObject = { { qle_uint(sizeof(Base)) }, { 0 }, { qle_uint(0) } };
|
||||
|
||||
void Data::compact()
|
||||
{
|
||||
|
|
@ -394,7 +387,7 @@ int Value::requiredStorage(QJsonValue &v, bool *compressed)
|
|||
v.d->compact();
|
||||
v.base = static_cast<QJsonPrivate::Base *>(v.d->header->root());
|
||||
}
|
||||
return v.base ? v.base->size : sizeof(QJsonPrivate::Base);
|
||||
return v.base ? uint(v.base->size) : sizeof(QJsonPrivate::Base);
|
||||
case QJsonValue::Undefined:
|
||||
case QJsonValue::Null:
|
||||
case QJsonValue::Bool:
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@
|
|||
#include <qendian.h>
|
||||
#include <qnumeric.h>
|
||||
|
||||
#include "private/qendian_p.h"
|
||||
#include "private/qsimd_p.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
|
@ -131,42 +132,7 @@ class Value;
|
|||
class Entry;
|
||||
|
||||
template<typename T>
|
||||
class q_littleendian
|
||||
{
|
||||
public:
|
||||
T val;
|
||||
|
||||
q_littleendian &operator =(T i) { val = qToLittleEndian(i); return *this; }
|
||||
operator T() const { return qFromLittleEndian(val); }
|
||||
|
||||
bool operator ==(T i) { return qFromLittleEndian(val) == i; }
|
||||
bool operator !=(T i) { return qFromLittleEndian(val) != i; }
|
||||
bool operator ==(q_littleendian<T> i) { return val == i.val; }
|
||||
bool operator !=(q_littleendian<T> i) { return val != i.val; }
|
||||
bool operator <(T i) { return qFromLittleEndian(val) < i; }
|
||||
bool operator >(T i) { return qFromLittleEndian(val) > i; }
|
||||
bool operator <=(T i) { return qFromLittleEndian(val) <= i; }
|
||||
bool operator >=(T i) { return qFromLittleEndian(val) >= i; }
|
||||
q_littleendian &operator +=(T i) {
|
||||
val = qToLittleEndian(qFromLittleEndian(val) + i);
|
||||
return *this;
|
||||
}
|
||||
q_littleendian &operator |=(T i) {
|
||||
val = qToLittleEndian(qFromLittleEndian(val) | i);
|
||||
return *this;
|
||||
}
|
||||
q_littleendian &operator &=(T i) {
|
||||
val = qToLittleEndian(qFromLittleEndian(val) & i);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
} // namespace QJsonPrivate
|
||||
|
||||
template <typename T>
|
||||
class QTypeInfo<QJsonPrivate::q_littleendian<T> >
|
||||
: public QTypeInfoMerger<QJsonPrivate::q_littleendian<T>, T> {};
|
||||
|
||||
namespace QJsonPrivate {
|
||||
using q_littleendian = QLEInteger<T>;
|
||||
|
||||
typedef q_littleendian<short> qle_short;
|
||||
typedef q_littleendian<unsigned short> qle_ushort;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include <private/qdrawhelper_p.h>
|
||||
#include <private/qguiapplication_p.h>
|
||||
#include <private/qcolorprofile_p.h>
|
||||
#include <private/qendian_p.h>
|
||||
#include <private/qsimd_p.h>
|
||||
#include <private/qimage_p.h>
|
||||
#include <qendian.h>
|
||||
|
|
@ -341,10 +342,10 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32(quint32 *dest_data, con
|
|||
|
||||
// Handle 4 pixels at a time 12 bytes input to 16 bytes output.
|
||||
for (; pixel + 3 < len; pixel += 4) {
|
||||
const quint32 *src_packed = (const quint32 *) src_data;
|
||||
const quint32 src1 = qFromBigEndian(src_packed[0]);
|
||||
const quint32 src2 = qFromBigEndian(src_packed[1]);
|
||||
const quint32 src3 = qFromBigEndian(src_packed[2]);
|
||||
const quint32_be *src_packed = reinterpret_cast<const quint32_be *>(src_data);
|
||||
const quint32 src1 = src_packed[0];
|
||||
const quint32 src2 = src_packed[1];
|
||||
const quint32 src3 = src_packed[2];
|
||||
|
||||
dest_data[0] = 0xff000000 | (src1 >> 8);
|
||||
dest_data[1] = 0xff000000 | (src1 << 16) | (src2 >> 16);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ TARGET = qico
|
|||
HEADERS += main.h qicohandler.h
|
||||
SOURCES += main.cpp qicohandler.cpp
|
||||
OTHER_FILES += ico.json
|
||||
QT += core-private
|
||||
|
||||
PLUGIN_TYPE = imageformats
|
||||
PLUGIN_CLASS_NAME = QICOPlugin
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
|
||||
#include "qicohandler.h"
|
||||
#include <QtCore/qendian.h>
|
||||
#include <private/qendian_p.h>
|
||||
#include <QtGui/QImage>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QBuffer>
|
||||
|
|
@ -63,34 +64,34 @@ typedef struct
|
|||
quint8 bHeight; // Height of the image (actual height, not times 2)
|
||||
quint8 bColorCount; // Number of colors in image (0 if >=8bpp) [ not ture ]
|
||||
quint8 bReserved; // Reserved
|
||||
quint16 wPlanes; // Color Planes
|
||||
quint16 wBitCount; // Bits per pixel
|
||||
quint32 dwBytesInRes; // how many bytes in this resource?
|
||||
quint32 dwImageOffset; // where in the file is this image
|
||||
quint16_le wPlanes; // Color Planes
|
||||
quint16_le wBitCount; // Bits per pixel
|
||||
quint32_le dwBytesInRes; // how many bytes in this resource?
|
||||
quint32_le dwImageOffset; // where in the file is this image
|
||||
} ICONDIRENTRY, *LPICONDIRENTRY;
|
||||
#define ICONDIRENTRY_SIZE 16
|
||||
|
||||
typedef struct
|
||||
{
|
||||
quint16 idReserved; // Reserved
|
||||
quint16 idType; // resource type (1 for icons, 2 for cursors)
|
||||
quint16 idCount; // how many images?
|
||||
quint16_le idReserved; // Reserved
|
||||
quint16_le idType; // resource type (1 for icons, 2 for cursors)
|
||||
quint16_le idCount; // how many images?
|
||||
ICONDIRENTRY idEntries[1]; // the entries for each image
|
||||
} ICONDIR, *LPICONDIR;
|
||||
#define ICONDIR_SIZE 6 // Exclude the idEntries field
|
||||
|
||||
typedef struct { // BMP information header
|
||||
quint32 biSize; // size of this struct
|
||||
quint32 biWidth; // pixmap width
|
||||
quint32 biHeight; // pixmap height (specifies the combined height of the XOR and AND masks)
|
||||
quint16 biPlanes; // should be 1
|
||||
quint16 biBitCount; // number of bits per pixel
|
||||
quint32 biCompression; // compression method
|
||||
quint32 biSizeImage; // size of image
|
||||
quint32 biXPelsPerMeter; // horizontal resolution
|
||||
quint32 biYPelsPerMeter; // vertical resolution
|
||||
quint32 biClrUsed; // number of colors used
|
||||
quint32 biClrImportant; // number of important colors
|
||||
quint32_le biSize; // size of this struct
|
||||
quint32_le biWidth; // pixmap width
|
||||
quint32_le biHeight; // pixmap height (specifies the combined height of the XOR and AND masks)
|
||||
quint16_le biPlanes; // should be 1
|
||||
quint16_le biBitCount; // number of bits per pixel
|
||||
quint32_le biCompression; // compression method
|
||||
quint32_le biSizeImage; // size of image
|
||||
quint32_le biXPelsPerMeter; // horizontal resolution
|
||||
quint32_le biYPelsPerMeter; // vertical resolution
|
||||
quint32_le biClrUsed; // number of colors used
|
||||
quint32_le biClrImportant; // number of important colors
|
||||
} BMP_INFOHDR ,*LPBMP_INFOHDR;
|
||||
#define BMP_INFOHDR_SIZE 40
|
||||
|
||||
|
|
@ -140,108 +141,43 @@ private:
|
|||
// Data readers and writers that takes care of alignment and endian stuff.
|
||||
static bool readIconDirEntry(QIODevice *iodev, ICONDIRENTRY *iconDirEntry)
|
||||
{
|
||||
if (iodev) {
|
||||
uchar tmp[ICONDIRENTRY_SIZE];
|
||||
if (iodev->read((char*)tmp, ICONDIRENTRY_SIZE) == ICONDIRENTRY_SIZE) {
|
||||
iconDirEntry->bWidth = tmp[0];
|
||||
iconDirEntry->bHeight = tmp[1];
|
||||
iconDirEntry->bColorCount = tmp[2];
|
||||
iconDirEntry->bReserved = tmp[3];
|
||||
|
||||
iconDirEntry->wPlanes = qFromLittleEndian<quint16>(&tmp[4]);
|
||||
iconDirEntry->wBitCount = qFromLittleEndian<quint16>(&tmp[6]);
|
||||
iconDirEntry->dwBytesInRes = qFromLittleEndian<quint32>(&tmp[8]);
|
||||
iconDirEntry->dwImageOffset = qFromLittleEndian<quint32>(&tmp[12]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (iodev)
|
||||
return (iodev->read((char*)iconDirEntry, ICONDIRENTRY_SIZE) == ICONDIRENTRY_SIZE);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool writeIconDirEntry(QIODevice *iodev, const ICONDIRENTRY &iconEntry)
|
||||
{
|
||||
if (iodev) {
|
||||
uchar tmp[ICONDIRENTRY_SIZE];
|
||||
tmp[0] = iconEntry.bWidth;
|
||||
tmp[1] = iconEntry.bHeight;
|
||||
tmp[2] = iconEntry.bColorCount;
|
||||
tmp[3] = iconEntry.bReserved;
|
||||
qToLittleEndian<quint16>(iconEntry.wPlanes, &tmp[4]);
|
||||
qToLittleEndian<quint16>(iconEntry.wBitCount, &tmp[6]);
|
||||
qToLittleEndian<quint32>(iconEntry.dwBytesInRes, &tmp[8]);
|
||||
qToLittleEndian<quint32>(iconEntry.dwImageOffset, &tmp[12]);
|
||||
return iodev->write((char*)tmp, ICONDIRENTRY_SIZE) == ICONDIRENTRY_SIZE;
|
||||
}
|
||||
|
||||
if (iodev)
|
||||
return iodev->write((char*)&iconEntry, ICONDIRENTRY_SIZE) == ICONDIRENTRY_SIZE;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool readIconDir(QIODevice *iodev, ICONDIR *iconDir)
|
||||
{
|
||||
if (iodev) {
|
||||
uchar tmp[ICONDIR_SIZE];
|
||||
if (iodev->read((char*)tmp, ICONDIR_SIZE) == ICONDIR_SIZE) {
|
||||
iconDir->idReserved = qFromLittleEndian<quint16>(&tmp[0]);
|
||||
iconDir->idType = qFromLittleEndian<quint16>(&tmp[2]);
|
||||
iconDir->idCount = qFromLittleEndian<quint16>(&tmp[4]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (iodev)
|
||||
return (iodev->read((char*)iconDir, ICONDIR_SIZE) == ICONDIR_SIZE);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool writeIconDir(QIODevice *iodev, const ICONDIR &iconDir)
|
||||
{
|
||||
if (iodev) {
|
||||
uchar tmp[6];
|
||||
qToLittleEndian(iconDir.idReserved, tmp);
|
||||
qToLittleEndian(iconDir.idType, &tmp[2]);
|
||||
qToLittleEndian(iconDir.idCount, &tmp[4]);
|
||||
return iodev->write((char*)tmp, 6) == 6;
|
||||
}
|
||||
if (iodev)
|
||||
return iodev->write((char*)&iconDir, 6) == 6;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool readBMPInfoHeader(QIODevice *iodev, BMP_INFOHDR *pHeader)
|
||||
{
|
||||
if (iodev) {
|
||||
uchar header[BMP_INFOHDR_SIZE];
|
||||
if (iodev->read((char*)header, BMP_INFOHDR_SIZE) == BMP_INFOHDR_SIZE) {
|
||||
pHeader->biSize = qFromLittleEndian<quint32>(&header[0]);
|
||||
pHeader->biWidth = qFromLittleEndian<quint32>(&header[4]);
|
||||
pHeader->biHeight = qFromLittleEndian<quint32>(&header[8]);
|
||||
pHeader->biPlanes = qFromLittleEndian<quint16>(&header[12]);
|
||||
pHeader->biBitCount = qFromLittleEndian<quint16>(&header[14]);
|
||||
pHeader->biCompression = qFromLittleEndian<quint32>(&header[16]);
|
||||
pHeader->biSizeImage = qFromLittleEndian<quint32>(&header[20]);
|
||||
pHeader->biXPelsPerMeter = qFromLittleEndian<quint32>(&header[24]);
|
||||
pHeader->biYPelsPerMeter = qFromLittleEndian<quint32>(&header[28]);
|
||||
pHeader->biClrUsed = qFromLittleEndian<quint32>(&header[32]);
|
||||
pHeader->biClrImportant = qFromLittleEndian<quint32>(&header[36]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (iodev)
|
||||
return (iodev->read((char*)pHeader, BMP_INFOHDR_SIZE) == BMP_INFOHDR_SIZE);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool writeBMPInfoHeader(QIODevice *iodev, const BMP_INFOHDR &header)
|
||||
{
|
||||
if (iodev) {
|
||||
uchar tmp[BMP_INFOHDR_SIZE];
|
||||
qToLittleEndian<quint32>(header.biSize, &tmp[0]);
|
||||
qToLittleEndian<quint32>(header.biWidth, &tmp[4]);
|
||||
qToLittleEndian<quint32>(header.biHeight, &tmp[8]);
|
||||
qToLittleEndian<quint16>(header.biPlanes, &tmp[12]);
|
||||
qToLittleEndian<quint16>(header.biBitCount, &tmp[14]);
|
||||
qToLittleEndian<quint32>(header.biCompression, &tmp[16]);
|
||||
qToLittleEndian<quint32>(header.biSizeImage, &tmp[20]);
|
||||
qToLittleEndian<quint32>(header.biXPelsPerMeter, &tmp[24]);
|
||||
qToLittleEndian<quint32>(header.biYPelsPerMeter, &tmp[28]);
|
||||
qToLittleEndian<quint32>(header.biClrUsed, &tmp[32]);
|
||||
qToLittleEndian<quint32>(header.biClrImportant, &tmp[36]);
|
||||
|
||||
return iodev->write((char*)tmp, BMP_INFOHDR_SIZE) == BMP_INFOHDR_SIZE;
|
||||
}
|
||||
if (iodev)
|
||||
return iodev->write((char*)&header, BMP_INFOHDR_SIZE) == BMP_INFOHDR_SIZE;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -561,7 +497,7 @@ QImage ICOReader::iconAt(int index)
|
|||
if (icoAttrib.depth == 32) // there's no colormap
|
||||
icoAttrib.ncolors = 0;
|
||||
else // # colors used
|
||||
icoAttrib.ncolors = header.biClrUsed ? header.biClrUsed : 1 << icoAttrib.nbits;
|
||||
icoAttrib.ncolors = header.biClrUsed ? uint(header.biClrUsed) : 1 << icoAttrib.nbits;
|
||||
if (icoAttrib.ncolors > 256) //color table can't be more than 256
|
||||
return img;
|
||||
icoAttrib.w = iconEntry.bWidth;
|
||||
|
|
|
|||
Loading…
Reference in New Issue