Qt 4.8
Classes | Public Functions | Static Public Functions | Private Functions | Properties | List of all members
ICOReader Class Reference

Classes

struct  IcoAttrib
 

Public Functions

int count ()
 
QImage iconAt (int index)
 
 ICOReader (QIODevice *iodevice)
 

Static Public Functions

static bool canRead (QIODevice *iodev)
 
static QList< QImageread (QIODevice *device)
 Reads all the icons from the given device, and returns them as a list of QImage objects. More...
 
static bool write (QIODevice *device, const QList< QImage > &images)
 Writes all the QImages in the images list to the given device. More...
 

Private Functions

void findColorInfo (QImage &image)
 
void read16_24_32BMP (QImage &image)
 
void read1BitBMP (QImage &image)
 
void read4BitBMP (QImage &image)
 
void read8BitBMP (QImage &image)
 
void readBMP (QImage &image)
 
bool readBMPHeader (quint32 imageOffset, BMP_INFOHDR *header)
 
void readColorTable (QImage &image)
 
bool readHeader ()
 
bool readIconEntry (int index, ICONDIRENTRY *iconEntry)
 

Properties

bool headerRead
 
struct ICOReader::IcoAttrib icoAttrib
 
ICONDIR iconDir
 
QIODeviceiod
 
qint64 startpos
 

Detailed Description

Definition at line 102 of file qicohandler.cpp.

Constructors and Destructors

◆ ICOReader()

ICOReader::ICOReader ( QIODevice iodevice)

Definition at line 253 of file qicohandler.cpp.

Referenced by QtIcoHandler::QtIcoHandler().

254 : iod(iodevice)
255 , startpos(0)
256 , headerRead(false)
257 {
258 }
qint64 startpos
bool headerRead
QIODevice * iod

Functions

◆ canRead()

bool ICOReader::canRead ( QIODevice iodev)
static

Definition at line 268 of file qicohandler.cpp.

Referenced by QtIcoHandler::canRead().

269 {
270  bool isProbablyICO = false;
271  if (iodev) {
272  qint64 oldPos = iodev->pos();
273 
274  ICONDIR ikonDir;
275  if (readIconDir(iodev, &ikonDir)) {
276  qint64 readBytes = ICONDIR_SIZE;
277  if (readIconDirEntry(iodev, &ikonDir.idEntries[0])) {
278  readBytes += ICONDIRENTRY_SIZE;
279  // ICO format does not have a magic identifier, so we read 6 different values, which will hopefully be enough to identify the file.
280  if ( ikonDir.idReserved == 0
281  && ikonDir.idType == 1
282  && ikonDir.idEntries[0].bReserved == 0
283  && ikonDir.idEntries[0].wPlanes <= 1
284  && ikonDir.idEntries[0].wBitCount <= 32 // Bits per pixel
285  && ikonDir.idEntries[0].dwBytesInRes >= 40 // Must be over 40, since sizeof (infoheader) == 40
286  ) {
287  isProbablyICO = true;
288  }
289 
290  if (iodev->isSequential()) {
291  // Our structs might be padded due to alignment, so we need to fetch each member before we ungetChar() !
292  quint32 tmp = ikonDir.idEntries[0].dwImageOffset;
293  iodev->ungetChar((tmp >> 24) & 0xff);
294  iodev->ungetChar((tmp >> 16) & 0xff);
295  iodev->ungetChar((tmp >> 8) & 0xff);
296  iodev->ungetChar(tmp & 0xff);
297 
298  tmp = ikonDir.idEntries[0].dwBytesInRes;
299  iodev->ungetChar((tmp >> 24) & 0xff);
300  iodev->ungetChar((tmp >> 16) & 0xff);
301  iodev->ungetChar((tmp >> 8) & 0xff);
302  iodev->ungetChar(tmp & 0xff);
303 
304  tmp = ikonDir.idEntries[0].wBitCount;
305  iodev->ungetChar((tmp >> 8) & 0xff);
306  iodev->ungetChar(tmp & 0xff);
307 
308  tmp = ikonDir.idEntries[0].wPlanes;
309  iodev->ungetChar((tmp >> 8) & 0xff);
310  iodev->ungetChar(tmp & 0xff);
311 
312  iodev->ungetChar(ikonDir.idEntries[0].bReserved);
313  iodev->ungetChar(ikonDir.idEntries[0].bColorCount);
314  iodev->ungetChar(ikonDir.idEntries[0].bHeight);
315  iodev->ungetChar(ikonDir.idEntries[0].bWidth);
316  }
317  }
318 
319  if (iodev->isSequential()) {
320  // Our structs might be padded due to alignment, so we need to fetch each member before we ungetChar() !
321  quint32 tmp = ikonDir.idCount;
322  iodev->ungetChar((tmp >> 8) & 0xff);
323  iodev->ungetChar(tmp & 0xff);
324 
325  tmp = ikonDir.idType;
326  iodev->ungetChar((tmp >> 8) & 0xff);
327  iodev->ungetChar(tmp & 0xff);
328 
329  tmp = ikonDir.idReserved;
330  iodev->ungetChar((tmp >> 8) & 0xff);
331  iodev->ungetChar(tmp & 0xff);
332  }
333  }
334  if (!iodev->isSequential()) iodev->seek(oldPos);
335  }
336 
337  return isProbablyICO;
338 }
quint32 dwBytesInRes
Definition: qicohandler.cpp:73
#define ICONDIR_SIZE
Definition: qicohandler.cpp:85
quint8 bHeight
Definition: qicohandler.cpp:68
virtual qint64 pos() const
For random-access devices, this function returns the position that data is written to or read from...
Definition: qiodevice.cpp:624
quint8 bColorCount
Definition: qicohandler.cpp:69
ICONDIRENTRY idEntries[1]
Definition: qicohandler.cpp:83
quint16 wBitCount
Definition: qicohandler.cpp:72
void ungetChar(char c)
Puts the character c back into the device, and decrements the current position unless the position is...
Definition: qiodevice.cpp:1462
static bool readIconDir(QIODevice *iodev, ICONDIR *iconDir)
#define ICONDIRENTRY_SIZE
Definition: qicohandler.cpp:76
quint16 idReserved
Definition: qicohandler.cpp:80
quint16 wPlanes
Definition: qicohandler.cpp:71
__int64 qint64
Definition: qglobal.h:942
virtual bool isSequential() const
Returns true if this device is sequential; otherwise returns false.
Definition: qiodevice.cpp:454
quint8 bReserved
Definition: qicohandler.cpp:70
unsigned int quint32
Definition: qglobal.h:938
static bool readIconDirEntry(QIODevice *iodev, ICONDIRENTRY *iconDirEntry)
quint16 idType
Definition: qicohandler.cpp:81
virtual bool seek(qint64 pos)
For random-access devices, this function sets the current position to pos, returning true on success...
Definition: qiodevice.cpp:659
quint16 idCount
Definition: qicohandler.cpp:82
quint32 dwImageOffset
Definition: qicohandler.cpp:74

◆ count()

int ICOReader::count ( )

Definition at line 261 of file qicohandler.cpp.

Referenced by iconAt(), and read().

262 {
263  if (readHeader())
264  return iconDir.idCount;
265  return 0;
266 }
bool readHeader()
ICONDIR iconDir
quint16 idCount
Definition: qicohandler.cpp:82

◆ findColorInfo()

void ICOReader::findColorInfo ( QImage image)
private

Definition at line 377 of file qicohandler.cpp.

Referenced by iconAt().

378 {
379  if (icoAttrib.ncolors > 0) { // set color table
380  readColorTable(image);
381  } else if (icoAttrib.nbits == 16) { // don't support RGB values for 15/16 bpp
382  image = QImage();
383  }
384 }
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
void readColorTable(QImage &image)
struct ICOReader::IcoAttrib icoAttrib

◆ iconAt()

QImage ICOReader::iconAt ( int  index)

Definition at line 523 of file qicohandler.cpp.

Referenced by read().

524 {
525  QImage img;
526 
527  if (count() > index) { // forces header to be read
528 
529  ICONDIRENTRY iconEntry;
530  if (readIconEntry(index, &iconEntry)) {
531 
532  static const uchar pngMagicData[] = { 137, 80, 78, 71, 13, 10, 26, 10 };
533 
534  iod->seek(iconEntry.dwImageOffset);
535 
536  const QByteArray pngMagic = QByteArray::fromRawData((char*)pngMagicData, sizeof(pngMagicData));
537  const bool isPngImage = (iod->read(pngMagic.size()) == pngMagic);
538 
539  if (isPngImage) {
540  iod->seek(iconEntry.dwImageOffset);
541  return QImage::fromData(iod->read(iconEntry.dwBytesInRes), "png");
542  }
543 
544  BMP_INFOHDR header;
545  if (readBMPHeader(iconEntry.dwImageOffset, &header)) {
546  icoAttrib.nbits = header.biBitCount ? header.biBitCount : iconEntry.wBitCount;
547 
548  switch (icoAttrib.nbits) {
549  case 32:
550  case 24:
551  case 16:
552  icoAttrib.depth = 32;
553  break;
554  case 8:
555  case 4:
556  icoAttrib.depth = 8;
557  break;
558  default:
559  icoAttrib.depth = 1;
560  }
561  if (icoAttrib.depth == 32) // there's no colormap
562  icoAttrib.ncolors = 0;
563  else // # colors used
564  icoAttrib.ncolors = header.biClrUsed ? header.biClrUsed : 1 << icoAttrib.nbits;
565  if (icoAttrib.ncolors > 256) //color table can't be more than 256
566  return img;
567  icoAttrib.w = iconEntry.bWidth;
568  if (icoAttrib.w == 0)
569  icoAttrib.w = header.biWidth;
570  icoAttrib.h = iconEntry.bHeight;
571  if (icoAttrib.h == 0)
572  icoAttrib.h = header.biHeight/2;
573 
575  if (icoAttrib.nbits == 24)
576  format = QImage::Format_RGB32;
577  else if (icoAttrib.ncolors == 2)
578  format = QImage::Format_Mono;
579  else if (icoAttrib.ncolors > 0)
580  format = QImage::Format_Indexed8;
581 
582  QImage image(icoAttrib.w, icoAttrib.h, format);
583  if (!image.isNull()) {
584  findColorInfo(image);
585  if (!image.isNull()) {
586  readBMP(image);
587  if (!image.isNull()) {
588  QImage mask(image.width(), image.height(), QImage::Format_Mono);
589  if (!mask.isNull()) {
590  mask.setColorCount(2);
591  mask.setColor(0, qRgba(255,255,255,0xff));
592  mask.setColor(1, qRgba(0 ,0 ,0 ,0xff));
593  read1BitBMP(mask);
594  if (!mask.isNull()) {
595  img = QImage(image.width(), image.height(), QImage::Format_ARGB32 );
596  img = image;
597  img.setAlphaChannel(mask);
598  // (Luckily, it seems that setAlphaChannel() does not ruin the alpha values
599  // of partially transparent pixels in those icons that have that)
600  }
601  }
602  }
603  }
604  }
605  }
606  }
607  }
608 
609  return img;
610 }
quint32 dwBytesInRes
Definition: qicohandler.cpp:73
Format
The following image formats are available in Qt.
Definition: qimage.h:91
void readBMP(QImage &image)
quint8 bHeight
Definition: qicohandler.cpp:68
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
quint16 wBitCount
Definition: qicohandler.cpp:72
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read...
Definition: qiodevice.cpp:791
unsigned char uchar
Definition: qglobal.h:994
void setColorCount(int)
Resizes the color table to contain colorCount entries.
Definition: qimage.cpp:2275
Q_GUI_EXPORT_INLINE QRgb qRgba(int r, int g, int b, int a)
Definition: qrgb.h:72
static QByteArray fromRawData(const char *, int size)
Constructs a QByteArray that uses the first size bytes of the data array.
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
void findColorInfo(QImage &image)
struct ICOReader::IcoAttrib icoAttrib
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
quint16 index
bool readIconEntry(int index, ICONDIRENTRY *iconEntry)
void setAlphaChannel(const QImage &alphaChannel)
Sets the alpha channel of this image to the given alphaChannel.
Definition: qimage.cpp:6329
bool readBMPHeader(quint32 imageOffset, BMP_INFOHDR *header)
virtual bool seek(qint64 pos)
For random-access devices, this function sets the current position to pos, returning true on success...
Definition: qiodevice.cpp:659
static QImage fromData(const uchar *data, int size, const char *format=0)
Constructs a QImage from the first size bytes of the given binary data.
Definition: qimage.cpp:5313
QIODevice * iod
void read1BitBMP(QImage &image)
quint32 dwImageOffset
Definition: qicohandler.cpp:74

◆ read()

QList< QImage > ICOReader::read ( QIODevice device)
static

Reads all the icons from the given device, and returns them as a list of QImage objects.

Each image has an alpha channel that represents the mask from the corresponding icon.

See also
write()

Definition at line 622 of file qicohandler.cpp.

623 {
624  QList<QImage> images;
625 
626  ICOReader reader(device);
627  for (int i = 0; i < reader.count(); i++)
628  images += reader.iconAt(i);
629 
630  return images;
631 }

◆ read16_24_32BMP()

void ICOReader::read16_24_32BMP ( QImage image)
private

Definition at line 489 of file qicohandler.cpp.

Referenced by readBMP().

490 {
491  if (iod) {
492  int h = icoAttrib.h;
493  register QRgb *p;
494  QRgb *end;
495  uchar *buf = new uchar[image.bytesPerLine()];
496  int bpl = ((icoAttrib.w*icoAttrib.nbits+31)/32)*4;
497  uchar *b;
498 
499  while (--h >= 0) {
500  p = (QRgb *)image.scanLine(h);
501  end = p + icoAttrib.w;
502  if (iod->read((char *)buf, bpl) != bpl) {
503  image = QImage();
504  break;
505  }
506  b = buf;
507  while (p < end) {
508  if (icoAttrib.nbits == 24)
509  *p++ = qRgb(*(b+2), *(b+1), *b);
510  else if (icoAttrib.nbits == 32)
511  *p++ = qRgba(*(b+2), *(b+1), *b, *(b+3));
512  b += icoAttrib.nbits/8;
513  }
514  }
515 
516  delete[] buf;
517 
518  } else {
519  image = QImage();
520  }
521 }
unsigned int QRgb
Definition: qrgb.h:53
int bytesPerLine() const
Returns the number of bytes per image scanline.
Definition: qimage.cpp:1812
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read...
Definition: qiodevice.cpp:791
unsigned char uchar
Definition: qglobal.h:994
Q_GUI_EXPORT_INLINE QRgb qRgba(int r, int g, int b, int a)
Definition: qrgb.h:72
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
struct ICOReader::IcoAttrib icoAttrib
Q_GUI_EXPORT_INLINE QRgb qRgb(int r, int g, int b)
Definition: qrgb.h:69
static const KeyPair *const end
QIODevice * iod
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
Definition: qimage.cpp:1886

◆ read1BitBMP()

void ICOReader::read1BitBMP ( QImage image)
private

NOTE: A 1 bit BMP is only flipped vertically, and not horizontally like all other color depths! (This is the same with the bitmask)

Definition at line 422 of file qicohandler.cpp.

Referenced by iconAt(), and readBMP().

423 {
424  if (iod) {
425 
426  int h = image.height();
427  int bpl = image.bytesPerLine();
428 
429  while (--h >= 0) {
430  if (iod->read((char*)image.scanLine(h),bpl) != bpl) {
431  image = QImage();
432  break;
433  }
434  }
435  } else {
436  image = QImage();
437  }
438 }
int bytesPerLine() const
Returns the number of bytes per image scanline.
Definition: qimage.cpp:1812
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read...
Definition: qiodevice.cpp:791
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
int height() const
Returns the height of the image.
Definition: qimage.cpp:1572
QIODevice * iod
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
Definition: qimage.cpp:1886

◆ read4BitBMP()

void ICOReader::read4BitBMP ( QImage image)
private

Definition at line 440 of file qicohandler.cpp.

Referenced by readBMP().

441 {
442  if (iod) {
443 
444  int h = icoAttrib.h;
445  int buflen = ((icoAttrib.w+7)/8)*4;
446  uchar *buf = new uchar[buflen];
447  Q_CHECK_PTR(buf);
448 
449  while (--h >= 0) {
450  if (iod->read((char*)buf,buflen) != buflen) {
451  image = QImage();
452  break;
453  }
454  register uchar *p = image.scanLine(h);
455  uchar *b = buf;
456  for (int i=0; i<icoAttrib.w/2; i++) { // convert nibbles to bytes
457  *p++ = *b >> 4;
458  *p++ = *b++ & 0x0f;
459  }
460  if (icoAttrib.w & 1) // the last nibble
461  *p = *b >> 4;
462  }
463 
464  delete [] buf;
465 
466  } else {
467  image = QImage();
468  }
469 }
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read...
Definition: qiodevice.cpp:791
unsigned char uchar
Definition: qglobal.h:994
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
#define Q_CHECK_PTR(p)
Definition: qglobal.h:1853
struct ICOReader::IcoAttrib icoAttrib
QIODevice * iod
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
Definition: qimage.cpp:1886

◆ read8BitBMP()

void ICOReader::read8BitBMP ( QImage image)
private

Definition at line 471 of file qicohandler.cpp.

Referenced by readBMP().

472 {
473  if (iod) {
474 
475  int h = icoAttrib.h;
476  int bpl = image.bytesPerLine();
477 
478  while (--h >= 0) {
479  if (iod->read((char *)image.scanLine(h), bpl) != bpl) {
480  image = QImage();
481  break;
482  }
483  }
484  } else {
485  image = QImage();
486  }
487 }
int bytesPerLine() const
Returns the number of bytes per image scanline.
Definition: qimage.cpp:1812
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read...
Definition: qiodevice.cpp:791
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
struct ICOReader::IcoAttrib icoAttrib
QIODevice * iod
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
Definition: qimage.cpp:1886

◆ readBMP()

void ICOReader::readBMP ( QImage image)
private

Definition at line 403 of file qicohandler.cpp.

Referenced by iconAt().

404 {
405  if (icoAttrib.nbits == 1) { // 1 bit BMP image
406  read1BitBMP(image);
407  } else if (icoAttrib.nbits == 4) { // 4 bit BMP image
408  read4BitBMP(image);
409  } else if (icoAttrib.nbits == 8) {
410  read8BitBMP(image);
411  } else if (icoAttrib.nbits == 16 || icoAttrib.nbits == 24 || icoAttrib.nbits == 32 ) { // 16,24,32 bit BMP image
412  read16_24_32BMP(image);
413  }
414 }
void read4BitBMP(QImage &image)
void read16_24_32BMP(QImage &image)
struct ICOReader::IcoAttrib icoAttrib
void read1BitBMP(QImage &image)
void read8BitBMP(QImage &image)

◆ readBMPHeader()

bool ICOReader::readBMPHeader ( quint32  imageOffset,
BMP_INFOHDR header 
)
private

Definition at line 365 of file qicohandler.cpp.

Referenced by iconAt().

366 {
367  if (iod) {
368  if (iod->seek(startpos + imageOffset)) {
369  if (readBMPInfoHeader(iod, header)) {
370  return TRUE;
371  }
372  }
373  }
374  return FALSE;
375 }
qint64 startpos
#define FALSE
Synonym for false.
Definition: qglobal.h:1019
static bool readBMPInfoHeader(QIODevice *iodev, BMP_INFOHDR *pHeader)
#define TRUE
Synonym for true.
Definition: qglobal.h:1018
virtual bool seek(qint64 pos)
For random-access devices, this function sets the current position to pos, returning true on success...
Definition: qiodevice.cpp:659
QIODevice * iod

◆ readColorTable()

void ICOReader::readColorTable ( QImage image)
private

Definition at line 386 of file qicohandler.cpp.

Referenced by findColorInfo().

387 {
388  if (iod) {
390  uchar rgb[4];
391  for (int i=0; i<icoAttrib.ncolors; i++) {
392  if (iod->read((char*)rgb, 4) != 4) {
393  image = QImage();
394  break;
395  }
396  image.setColor(i, qRgb(rgb[2],rgb[1],rgb[0]));
397  }
398  } else {
399  image = QImage();
400  }
401 }
void setColor(int i, QRgb c)
Sets the color at the given index in the color table, to the given to colorValue. ...
Definition: qimage.cpp:1850
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read...
Definition: qiodevice.cpp:791
unsigned char uchar
Definition: qglobal.h:994
void setColorCount(int)
Resizes the color table to contain colorCount entries.
Definition: qimage.cpp:2275
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
#define rgb(r, g, b)
Definition: qcolor_p.cpp:130
struct ICOReader::IcoAttrib icoAttrib
Q_GUI_EXPORT_INLINE QRgb qRgb(int r, int g, int b)
Definition: qrgb.h:69
QIODevice * iod

◆ readHeader()

bool ICOReader::readHeader ( )
private

Definition at line 340 of file qicohandler.cpp.

Referenced by count().

341 {
342  if (iod && !headerRead) {
343  startpos = iod->pos();
344  if (readIconDir(iod, &iconDir)) {
345  if (iconDir.idReserved == 0 || iconDir.idType == 1)
346  headerRead = true;
347  }
348  }
349 
350  return headerRead;
351 }
virtual qint64 pos() const
For random-access devices, this function returns the position that data is written to or read from...
Definition: qiodevice.cpp:624
static bool readIconDir(QIODevice *iodev, ICONDIR *iconDir)
quint16 idReserved
Definition: qicohandler.cpp:80
qint64 startpos
bool headerRead
ICONDIR iconDir
quint16 idType
Definition: qicohandler.cpp:81
QIODevice * iod

◆ readIconEntry()

bool ICOReader::readIconEntry ( int  index,
ICONDIRENTRY iconEntry 
)
private

Definition at line 353 of file qicohandler.cpp.

Referenced by iconAt().

354 {
355  if (iod) {
357  return readIconDirEntry(iod, iconEntry);
358  }
359  }
360  return false;
361 }
#define ICONDIR_SIZE
Definition: qicohandler.cpp:85
#define ICONDIRENTRY_SIZE
Definition: qicohandler.cpp:76
qint64 startpos
static bool readIconDirEntry(QIODevice *iodev, ICONDIRENTRY *iconDirEntry)
quint16 index
virtual bool seek(qint64 pos)
For random-access devices, this function sets the current position to pos, returning true on success...
Definition: qiodevice.cpp:659
QIODevice * iod

◆ write()

bool ICOReader::write ( QIODevice device,
const QList< QImage > &  images 
)
static

Writes all the QImages in the images list to the given device.

Returns true if the images are written successfully; otherwise returns false.

The first image in the list is stored as the first icon in the device, and is therefore used as the default icon by applications. The alpha channel of each image is converted to a mask for each corresponding icon.

See also
read()

Definition at line 646 of file qicohandler.cpp.

Referenced by QtIcoHandler::write().

647 {
648  bool retValue = false;
649 
650  if (images.count()) {
651 
652  qint64 origOffset = device->pos();
653 
654  ICONDIR id;
655  id.idReserved = 0;
656  id.idType = 1;
657  id.idCount = images.count();
658 
659  ICONDIRENTRY * entries = new ICONDIRENTRY[id.idCount];
660  BMP_INFOHDR * bmpHeaders = new BMP_INFOHDR[id.idCount];
661  QByteArray * imageData = new QByteArray[id.idCount];
662 
663  for (int i=0; i<id.idCount; i++) {
664 
665  QImage image = images[i];
666  // Scale down the image if it is larger than 128 pixels in either width or height
667  if (image.width() > 128 || image.height() > 128)
668  {
669  image = image.scaled(128, 128, Qt::KeepAspectRatio, Qt::SmoothTransformation);
670  }
671  QImage maskImage(image.width(), image.height(), QImage::Format_Mono);
672  image = image.convertToFormat(QImage::Format_ARGB32);
673 
674  if (image.hasAlphaChannel()) {
675  maskImage = image.createAlphaMask();
676  } else {
677  maskImage.fill(0xff);
678  }
679  maskImage = maskImage.convertToFormat(QImage::Format_Mono);
680 
681  int nbits = 32;
682  int bpl_bmp = ((image.width()*nbits+31)/32)*4;
683 
684  entries[i].bColorCount = 0;
685  entries[i].bReserved = 0;
686  entries[i].wBitCount = nbits;
687  entries[i].bHeight = image.height();
688  entries[i].bWidth = image.width();
689  entries[i].dwBytesInRes = BMP_INFOHDR_SIZE + (bpl_bmp * image.height())
690  + (maskImage.bytesPerLine() * maskImage.height());
691  entries[i].wPlanes = 1;
692  if (i == 0)
693  entries[i].dwImageOffset = origOffset + ICONDIR_SIZE
694  + (id.idCount * ICONDIRENTRY_SIZE);
695  else
696  entries[i].dwImageOffset = entries[i-1].dwImageOffset + entries[i-1].dwBytesInRes;
697 
698  bmpHeaders[i].biBitCount = entries[i].wBitCount;
699  bmpHeaders[i].biClrImportant = 0;
700  bmpHeaders[i].biClrUsed = entries[i].bColorCount;
701  bmpHeaders[i].biCompression = 0;
702  bmpHeaders[i].biHeight = entries[i].bHeight * 2; // 2 is for the mask
703  bmpHeaders[i].biPlanes = entries[i].wPlanes;
704  bmpHeaders[i].biSize = BMP_INFOHDR_SIZE;
705  bmpHeaders[i].biSizeImage = entries[i].dwBytesInRes - BMP_INFOHDR_SIZE;
706  bmpHeaders[i].biWidth = entries[i].bWidth;
707  bmpHeaders[i].biXPelsPerMeter = 0;
708  bmpHeaders[i].biYPelsPerMeter = 0;
709 
710  QBuffer buffer(&imageData[i]);
711  buffer.open(QIODevice::WriteOnly);
712 
713  uchar *buf = new uchar[bpl_bmp];
714  uchar *b;
715  memset( buf, 0, bpl_bmp );
716  int y;
717  for (y = image.height() - 1; y >= 0; y--) { // write the image bits
718  // 32 bits
719  QRgb *p = (QRgb *)image.scanLine(y);
720  QRgb *end = p + image.width();
721  b = buf;
722  int x = 0;
723  while (p < end) {
724  *b++ = qBlue(*p);
725  *b++ = qGreen(*p);
726  *b++ = qRed(*p);
727  *b++ = qAlpha(*p);
728  if (qAlpha(*p) > 0) // Even mostly transparent pixels must not be masked away
729  maskImage.setPixel(x, y, Qt::color1); // (i.e. createAlphaMask() takes away too much)
730  p++;
731  x++;
732  }
733  buffer.write((char*)buf, bpl_bmp);
734  }
735  delete[] buf;
736 
737  maskImage.invertPixels(); // seems as though it needs this
738  // NOTE! !! The mask is only flipped vertically - not horizontally !!
739  for (y = maskImage.height() - 1; y >= 0; y--)
740  buffer.write((char*)maskImage.scanLine(y), maskImage.bytesPerLine());
741  }
742 
743  if (writeIconDir(device, id)) {
744  int i;
745  bool bOK = true;
746  for (i = 0; i < id.idCount && bOK; i++) {
747  bOK = writeIconDirEntry(device, entries[i]);
748  }
749  if (bOK) {
750  for (i = 0; i < id.idCount && bOK; i++) {
751  bOK = writeBMPInfoHeader(device, bmpHeaders[i]);
752  bOK &= (device->write(imageData[i]) == (int) imageData[i].size());
753  }
754  retValue = bOK;
755  }
756  }
757 
758  delete [] entries;
759  delete [] bmpHeaders;
760  delete [] imageData;
761 
762  }
763  return retValue;
764 }
static bool writeIconDir(QIODevice *iodev, const ICONDIR &iconDir)
quint32 dwBytesInRes
Definition: qicohandler.cpp:73
unsigned int QRgb
Definition: qrgb.h:53
#define ICONDIR_SIZE
Definition: qicohandler.cpp:85
Q_GUI_EXPORT_INLINE int qAlpha(QRgb rgb)
Definition: qrgb.h:66
quint8 bHeight
Definition: qicohandler.cpp:68
qint32 biSize
Definition: qbmphandler_p.h:71
void fill(uint pixel)
Fills the entire image with the given pixelValue.
Definition: qimage.cpp:2032
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
#define BMP_INFOHDR_SIZE
virtual qint64 pos() const
For random-access devices, this function returns the position that data is written to or read from...
Definition: qiodevice.cpp:624
quint8 bColorCount
Definition: qicohandler.cpp:69
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
The QBuffer class provides a QIODevice interface for a QByteArray.
Definition: qbuffer.h:57
quint16 wBitCount
Definition: qicohandler.cpp:72
qint32 biSizeImage
Definition: qbmphandler_p.h:77
Q_GUI_EXPORT_INLINE int qRed(QRgb rgb)
Definition: qrgb.h:57
qint32 biWidth
Definition: qbmphandler_p.h:72
qint32 biClrUsed
Definition: qbmphandler_p.h:80
#define ICONDIRENTRY_SIZE
Definition: qicohandler.cpp:76
unsigned char uchar
Definition: qglobal.h:994
quint16 idReserved
Definition: qicohandler.cpp:80
qint32 biYPelsPerMeter
Definition: qbmphandler_p.h:79
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
quint16 wPlanes
Definition: qicohandler.cpp:71
QImage createAlphaMask(Qt::ImageConversionFlags flags=Qt::AutoColor) const
Builds and returns a 1-bpp mask from the alpha buffer in this image.
Definition: qimage.cpp:4720
__int64 qint64
Definition: qglobal.h:942
qint16 biBitCount
Definition: qbmphandler_p.h:75
Q_GUI_EXPORT_INLINE int qBlue(QRgb rgb)
Definition: qrgb.h:63
static const MacSpecialKey entries[NumEntries]
int width() const
Returns the width of the image.
Definition: qimage.cpp:1557
QImage convertToFormat(Format f, Qt::ImageConversionFlags flags=Qt::AutoColor) const Q_REQUIRED_RESULT
Returns a copy of the image in the given format.
Definition: qimage.cpp:3966
quint8 bReserved
Definition: qicohandler.cpp:70
qint32 biCompression
Definition: qbmphandler_p.h:76
int height() const
Returns the height of the image.
Definition: qimage.cpp:1572
Q_GUI_EXPORT_INLINE int qGreen(QRgb rgb)
Definition: qrgb.h:60
qint32 biClrImportant
Definition: qbmphandler_p.h:81
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
Definition: qiodevice.cpp:1342
QImage scaled(int w, int h, Qt::AspectRatioMode aspectMode=Qt::IgnoreAspectRatio, Qt::TransformationMode mode=Qt::FastTransformation) const
Definition: qimage.h:232
static const KeyPair *const end
static bool writeIconDirEntry(QIODevice *iodev, const ICONDIRENTRY &iconEntry)
qint32 biXPelsPerMeter
Definition: qbmphandler_p.h:78
static bool writeBMPInfoHeader(QIODevice *iodev, const BMP_INFOHDR &header)
qint16 biPlanes
Definition: qbmphandler_p.h:74
qint32 biHeight
Definition: qbmphandler_p.h:73
quint32 dwImageOffset
Definition: qicohandler.cpp:74

Properties

◆ headerRead

bool ICOReader::headerRead
private

Definition at line 139 of file qicohandler.cpp.

Referenced by readHeader().

◆ icoAttrib

struct ICOReader::IcoAttrib ICOReader::icoAttrib
private

◆ iconDir

ICONDIR ICOReader::iconDir
private

Definition at line 140 of file qicohandler.cpp.

Referenced by count(), and readHeader().

◆ iod

QIODevice* ICOReader::iod
private

◆ startpos

qint64 ICOReader::startpos
private

Definition at line 138 of file qicohandler.cpp.

Referenced by readBMPHeader(), readHeader(), and readIconEntry().


The documentation for this class was generated from the following file: