Changeset 561 for trunk/src/plugins/imageformats/ico
- Timestamp:
- Feb 11, 2010, 11:19:06 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
Property svn:mergeinfo
set to (toggle deleted branches)
/branches/vendor/nokia/qt/4.6.1 merged eligible /branches/vendor/nokia/qt/current merged eligible /branches/vendor/trolltech/qt/current 3-149
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/plugins/imageformats/ico/ico.pro
r2 r561 11 11 target.path += $$[QT_INSTALL_PLUGINS]/imageformats 12 12 INSTALLS += target 13 14 symbian:TARGET.UID3=0x2001E616 -
trunk/src/plugins/imageformats/ico/main.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the plugins of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** -
trunk/src/plugins/imageformats/ico/qicohandler.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the plugins of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 58 58 typedef struct 59 59 { 60 quint8 61 quint8 62 quint8 63 quint8 64 quint16 65 quint16 66 quint32 67 quint32 60 quint8 bWidth; // Width of the image 61 quint8 bHeight; // Height of the image (times 2) 62 quint8 bColorCount; // Number of colors in image (0 if >=8bpp) [ not ture ] 63 quint8 bReserved; // Reserved 64 quint16 wPlanes; // Color Planes 65 quint16 wBitCount; // Bits per pixel 66 quint32 dwBytesInRes; // how many bytes in this resource? 67 quint32 dwImageOffset; // where in the file is this image 68 68 } ICONDIRENTRY, *LPICONDIRENTRY; 69 69 #define ICONDIRENTRY_SIZE 16 … … 71 71 typedef struct 72 72 { 73 quint16 74 quint16 75 quint16 76 ICONDIRENTRY 73 quint16 idReserved; // Reserved 74 quint16 idType; // resource type (1 for icons) 75 quint16 idCount; // how many images? 76 ICONDIRENTRY idEntries[1]; // the entries for each image 77 77 } ICONDIR, *LPICONDIR; 78 78 #define ICONDIR_SIZE 6 // Exclude the idEntries field 79 79 80 typedef struct { 81 quint32 biSize;// size of this struct82 quint32 biWidth;// pixmap width83 quint32 biHeight; // pixmap height84 quint16 biPlanes;// should be 185 quint16 biBitCount;// number of bits per pixel86 quint32 biCompression;// compression method87 quint32 biSizeImage;// size of image88 quint32 biXPelsPerMeter;// horizontal resolution89 quint32 biYPelsPerMeter;// vertical resolution90 quint32 biClrUsed;// number of colors used91 quint32 biClrImportant;// number of important colors80 typedef struct { // BMP information header 81 quint32 biSize; // size of this struct 82 quint32 biWidth; // pixmap width 83 quint32 biHeight; // pixmap height (specifies the combined height of the XOR and AND masks) 84 quint16 biPlanes; // should be 1 85 quint16 biBitCount; // number of bits per pixel 86 quint32 biCompression; // compression method 87 quint32 biSizeImage; // size of image 88 quint32 biXPelsPerMeter; // horizontal resolution 89 quint32 biYPelsPerMeter; // vertical resolution 90 quint32 biClrUsed; // number of colors used 91 quint32 biClrImportant; // number of important colors 92 92 } BMP_INFOHDR ,*LPBMP_INFOHDR; 93 93 #define BMP_INFOHDR_SIZE 40 … … 109 109 bool readIconEntry(int index, ICONDIRENTRY * iconEntry); 110 110 111 bool readBMPHeader( ICONDIRENTRY & iconEntry, BMP_INFOHDR * header);111 bool readBMPHeader(quint32 imageOffset, BMP_INFOHDR * header); 112 112 void findColorInfo(QImage & image); 113 113 void readColorTable(QImage & image); … … 255 255 { 256 256 if (readHeader()) 257 257 return iconDir.idCount; 258 258 return 0; 259 259 } … … 269 269 qint64 readBytes = ICONDIR_SIZE; 270 270 if (readIconDirEntry(iodev, &ikonDir.idEntries[0])) { 271 272 273 274 275 276 277 278 279 280 281 271 readBytes += ICONDIRENTRY_SIZE; 272 // ICO format does not have a magic identifier, so we read 6 different values, which will hopefully be enough to identify the file. 273 if ( ikonDir.idReserved == 0 274 && ikonDir.idType == 1 275 && ikonDir.idEntries[0].bReserved == 0 276 && ikonDir.idEntries[0].wPlanes <= 1 277 && ikonDir.idEntries[0].wBitCount <= 32 // Bits per pixel 278 && ikonDir.idEntries[0].dwBytesInRes >= 40 // Must be over 40, since sizeof (infoheader) == 40 279 ) { 280 isProbablyICO = true; 281 } 282 282 283 283 if (iodev->isSequential()) { … … 324 324 iodev->ungetChar(tmp & 0xff); 325 325 } 326 327 } 326 } 328 327 if (!iodev->isSequential()) iodev->seek(oldPos); 329 328 } … … 335 334 { 336 335 if (iod && !headerRead) { 337 338 339 340 341 336 startpos = iod->pos(); 337 if (readIconDir(iod, &iconDir)) { 338 if (iconDir.idReserved == 0 || iconDir.idType == 1) 339 headerRead = true; 340 } 342 341 } 343 342 … … 345 344 } 346 345 347 bool ICOReader::readIconEntry(int index, ICONDIRENTRY * 346 bool ICOReader::readIconEntry(int index, ICONDIRENTRY *iconEntry) 348 347 { 349 348 if (iod) { 350 351 349 if (iod->seek(startpos + ICONDIR_SIZE + (index * ICONDIRENTRY_SIZE))) { 350 return readIconDirEntry(iod, iconEntry); 352 351 } 353 352 } … … 357 356 358 357 359 bool ICOReader::readBMPHeader(ICONDIRENTRY & iconEntry, BMP_INFOHDR * header) 360 { 361 memset(&icoAttrib, 0, sizeof(IcoAttrib)); 358 bool ICOReader::readBMPHeader(quint32 imageOffset, BMP_INFOHDR * header) 359 { 362 360 if (iod) { 363 if (iod->seek(startpos + iconEntry.dwImageOffset)) { 364 if (readBMPInfoHeader(iod, header)) { 365 366 icoAttrib.nbits = header->biBitCount ? header->biBitCount : iconEntry.wBitCount; 367 icoAttrib.h = header->biHeight / 2; // this height is always double the iconEntry height (for the mask) 368 icoAttrib.w = header->biWidth; 369 370 switch (icoAttrib.nbits) { 371 case 32: 372 case 24: 373 case 16: 374 icoAttrib.depth = 32; 375 break; 376 case 8: 377 case 4: 378 icoAttrib.depth = 8; 379 break; 380 default: 381 icoAttrib.depth = 1; 382 } 383 384 if ( icoAttrib.depth == 32 ) // there's no colormap 385 icoAttrib.ncolors = 0; 386 else // # colors used 387 icoAttrib.ncolors = header->biClrUsed ? header->biClrUsed : 1 << icoAttrib.nbits; 388 //qDebug() << "Bits:" << icoAttrib.nbits << "Depth:" << icoAttrib.depth << "Ncols:" << icoAttrib.ncolors; 389 return TRUE; 390 } 391 } 361 if (iod->seek(startpos + imageOffset)) { 362 if (readBMPInfoHeader(iod, header)) { 363 return TRUE; 364 } 365 } 392 366 } 393 367 return FALSE; … … 396 370 void ICOReader::findColorInfo(QImage & image) 397 371 { 398 if (icoAttrib.ncolors > 0) { 399 372 if (icoAttrib.ncolors > 0) { // set color table 373 readColorTable(image); 400 374 } else if (icoAttrib.nbits == 16) { // don't support RGB values for 15/16 bpp 401 375 image = QImage(); 402 376 } 403 377 } … … 406 380 { 407 381 if (iod) { 408 image.set NumColors(icoAttrib.ncolors);409 410 411 412 413 414 415 416 382 image.setColorCount(icoAttrib.ncolors); 383 uchar rgb[4]; 384 for (int i=0; i<icoAttrib.ncolors; i++) { 385 if (iod->read((char*)rgb, 4) != 4) { 386 image = QImage(); 387 break; 388 } 389 image.setColor(i, qRgb(rgb[2],rgb[1],rgb[0])); 390 } 417 391 } else { 418 392 image = QImage(); 419 393 } 420 394 } … … 422 396 void ICOReader::readBMP(QImage & image) 423 397 { 424 if (icoAttrib.nbits == 1) { 425 426 } else if (icoAttrib.nbits == 4) { 427 398 if (icoAttrib.nbits == 1) { // 1 bit BMP image 399 read1BitBMP(image); 400 } else if (icoAttrib.nbits == 4) { // 4 bit BMP image 401 read4BitBMP(image); 428 402 } else if (icoAttrib.nbits == 8) { 429 403 read8BitBMP(image); 430 404 } else if (icoAttrib.nbits == 16 || icoAttrib.nbits == 24 || icoAttrib.nbits == 32 ) { // 16,24,32 bit BMP image 431 405 read16_24_32BMP(image); 432 406 } 433 407 } … … 443 417 if (iod) { 444 418 445 446 447 448 449 450 451 452 453 419 int h = image.height(); 420 int bpl = image.bytesPerLine(); 421 422 while (--h >= 0) { 423 if (iod->read((char*)image.scanLine(h),bpl) != bpl) { 424 image = QImage(); 425 break; 426 } 427 } 454 428 } else { 455 429 image = QImage(); 456 430 } 457 431 } … … 461 435 if (iod) { 462 436 463 464 465 466 467 468 469 470 471 472 473 474 475 for (int i=0; i<icoAttrib.w/2; i++) {// convert nibbles to bytes476 477 478 479 if (icoAttrib.w & 1)// the last nibble480 481 482 483 437 int h = icoAttrib.h; 438 int buflen = ((icoAttrib.w+7)/8)*4; 439 uchar *buf = new uchar[buflen]; 440 Q_CHECK_PTR(buf); 441 442 while (--h >= 0) { 443 if (iod->read((char*)buf,buflen) != buflen) { 444 image = QImage(); 445 break; 446 } 447 register uchar *p = image.scanLine(h); 448 uchar *b = buf; 449 for (int i=0; i<icoAttrib.w/2; i++) { // convert nibbles to bytes 450 *p++ = *b >> 4; 451 *p++ = *b++ & 0x0f; 452 } 453 if (icoAttrib.w & 1) // the last nibble 454 *p = *b >> 4; 455 } 456 457 delete [] buf; 484 458 485 459 } else { 486 460 image = QImage(); 487 461 } 488 462 } … … 492 466 if (iod) { 493 467 494 495 496 497 498 499 500 501 502 468 int h = icoAttrib.h; 469 int bpl = image.bytesPerLine(); 470 471 while (--h >= 0) { 472 if (iod->read((char *)image.scanLine(h), bpl) != bpl) { 473 image = QImage(); 474 break; 475 } 476 } 503 477 } else { 504 478 image = QImage(); 505 479 } 506 480 } … … 509 483 { 510 484 if (iod) { 511 512 int h = icoAttrib.h; 513 register QRgb *p; 514 QRgb *end; 515 uchar *buf = new uchar[image.bytesPerLine()]; 516 int bpl = ((icoAttrib.w*icoAttrib.nbits+31)/32)*4; 517 uchar *b; 518 519 while (--h >= 0) { 520 p = (QRgb *)image.scanLine(h); 521 end = p + icoAttrib.w; 522 if (iod->read((char *)buf, bpl) != bpl) { 523 image = QImage(); 524 break; 525 } 526 b = buf; 527 while (p < end) { 485 int h = icoAttrib.h; 486 register QRgb *p; 487 QRgb *end; 488 uchar *buf = new uchar[image.bytesPerLine()]; 489 int bpl = ((icoAttrib.w*icoAttrib.nbits+31)/32)*4; 490 uchar *b; 491 492 while (--h >= 0) { 493 p = (QRgb *)image.scanLine(h); 494 end = p + icoAttrib.w; 495 if (iod->read((char *)buf, bpl) != bpl) { 496 image = QImage(); 497 break; 498 } 499 b = buf; 500 while (p < end) { 528 501 if (icoAttrib.nbits == 24) 529 502 *p++ = qRgb(*(b+2), *(b+1), *b); 530 503 else if (icoAttrib.nbits == 32) 531 504 *p++ = qRgba(*(b+2), *(b+1), *b, *(b+3)); 532 533 534 535 536 505 b += icoAttrib.nbits/8; 506 } 507 } 508 509 delete[] buf; 537 510 538 511 } else { 539 512 image = QImage(); 540 513 } 541 514 } … … 550 523 if (readIconEntry(index, &iconEntry)) { 551 524 525 static const uchar pngMagicData[] = { 137, 80, 78, 71, 13, 10, 26, 10 }; 526 527 iod->seek(iconEntry.dwImageOffset); 528 529 const QByteArray pngMagic = QByteArray::fromRawData((char*)pngMagicData, sizeof(pngMagicData)); 530 const bool isPngImage = (iod->read(pngMagic.size()) == pngMagic); 531 532 if (isPngImage) { 533 iod->seek(iconEntry.dwImageOffset); 534 return QImage::fromData(iod->read(iconEntry.dwBytesInRes), "png"); 535 } 536 552 537 BMP_INFOHDR header; 553 if (readBMPHeader(iconEntry, &header)) { 538 if (readBMPHeader(iconEntry.dwImageOffset, &header)) { 539 icoAttrib.nbits = header.biBitCount ? header.biBitCount : iconEntry.wBitCount; 540 541 switch (icoAttrib.nbits) { 542 case 32: 543 case 24: 544 case 16: 545 icoAttrib.depth = 32; 546 break; 547 case 8: 548 case 4: 549 icoAttrib.depth = 8; 550 break; 551 default: 552 icoAttrib.depth = 1; 553 } 554 if (icoAttrib.depth == 32) // there's no colormap 555 icoAttrib.ncolors = 0; 556 else // # colors used 557 icoAttrib.ncolors = header.biClrUsed ? header.biClrUsed : 1 << icoAttrib.nbits; 558 icoAttrib.w = iconEntry.bWidth; 559 icoAttrib.h = iconEntry.bHeight; 554 560 555 561 QImage::Format format = QImage::Format_ARGB32; … … 569 575 QImage mask(image.width(), image.height(), QImage::Format_Mono); 570 576 if (!mask.isNull()) { 571 mask.set NumColors(2);577 mask.setColorCount(2); 572 578 mask.setColor(0, qRgba(255,255,255,0xff)); 573 579 mask.setColor(1, qRgba(0 ,0 ,0 ,0xff)); … … 606 612 607 613 ICOReader reader(device); 608 for (int i =0; i<reader.count(); i++)609 614 for (int i = 0; i < reader.count(); i++) 615 images += reader.iconAt(i); 610 616 611 617 return images; … … 660 666 maskImage = maskImage.convertToFormat(QImage::Format_Mono); 661 667 662 int 663 int 668 int nbits = 32; 669 int bpl_bmp = ((image.width()*nbits+31)/32)*4; 664 670 665 671 entries[i].bColorCount = 0; … … 671 677 + (maskImage.bytesPerLine() * maskImage.height()); 672 678 entries[i].wPlanes = 1; 673 if (i ==0)679 if (i == 0) 674 680 entries[i].dwImageOffset = origOffset + ICONDIR_SIZE 675 681 + (id.idCount * ICONDIRENTRY_SIZE); … … 696 702 memset( buf, 0, bpl_bmp ); 697 703 int y; 698 for (y =image.height()-1; y>=0; y--) {// write the image bits704 for (y = image.height() - 1; y >= 0; y--) { // write the image bits 699 705 // 32 bits 700 706 QRgb *p = (QRgb *)image.scanLine(y); … … 718 724 maskImage.invertPixels(); // seems as though it needs this 719 725 // NOTE! !! The mask is only flipped vertically - not horizontally !! 720 for (y =maskImage.height()-1; y>=0; y--)726 for (y = maskImage.height() - 1; y >= 0; y--) 721 727 buffer.write((char*)maskImage.scanLine(y), maskImage.bytesPerLine()); 722 723 } 724 725 728 } 726 729 727 730 if (writeIconDir(device, id)) { … … 732 735 } 733 736 if (bOK) { 734 for (i =0; i<id.idCount && bOK; i++) {737 for (i = 0; i < id.idCount && bOK; i++) { 735 738 bOK = writeBMPInfoHeader(device, bmpHeaders[i]); 736 739 bOK &= (device->write(imageData[i]) == (int) imageData[i].size()); -
trunk/src/plugins/imageformats/ico/qicohandler.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the plugins of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 **
Note:
See TracChangeset
for help on using the changeset viewer.