QPixmap QPixmap::fromImage(const QImage &img, Qt::ImageConversionFlags flags) { QPixmap pixmap; if(img.isNull()) { qWarning("QPixmap::convertFromImage: Cannot convert a null image"); return pixmap; } QImage image = img; int d = image.depth(); int dd = defaultDepth(); bool force_mono = (dd == 1 || (flags & Qt::ColorMode_Mask)==Qt::MonoOnly); if(force_mono) { // must be monochrome if(d != 1) { image = image.convertToFormat(QImage::Format_MonoLSB, flags); // dither d = 1; } } else { // can be both bool conv8 = false; if(d > 8 && dd <= 8) { // convert to 8 bit if((flags & Qt::DitherMode_Mask) == Qt::AutoDither) flags = (flags & ~Qt::DitherMode_Mask) | Qt::PreferDither; conv8 = true; } else if((flags & Qt::ColorMode_Mask) == Qt::ColorOnly) { conv8 = d == 1; // native depth wanted } else if(d == 1) { if(image.numColors() == 2) { QRgb c0 = image.color(0); // Auto: convert to best QRgb c1 = image.color(1); conv8 = qMin(c0,c1) != qRgb(0,0,0) || qMax(c0,c1) != qRgb(255,255,255); } else { // eg. 1-color monochrome images (they do exist). conv8 = true; } } if(conv8) { image = image.convertToFormat(QImage::Format_Indexed8, flags); d = 8; } } if(image.depth()==1) { image.setColor(0, QColor(Qt::color0).rgba()); image.setColor(1, QColor(Qt::color1).rgba()); } if (d == 16) { QImage im = image.convertToFormat(QImage::Format_RGB32, flags); return fromImage(im); } int w = image.width(); int h = image.height(); // different size or depth, make a new pixmap if (d == 1) pixmap = QBitmap(w, h); else pixmap = QPixmap(w, h); quint32 *dptr = pixmap.data->pixels, *drow; const uint dbpr = pixmap.data->nbytes / h; const QImage::Format sfmt = image.format(); const unsigned short sbpr = image.bytesPerLine(); uchar *sptr = image.bits(), *srow; for(int y=0;y<h;y++) { drow = dptr + (y * (dbpr / 4)); srow = sptr + (y * sbpr); switch(sfmt) { case QImage::Format_MonoLSB: case QImage::Format_Mono:{ for(int x=0;x<w;++x) { char one_bit = *(srow + (x / 8)); if(sfmt == QImage::Format_Mono) one_bit = one_bit >> (7 - (x % 8)); else one_bit = one_bit >> (x % 8); if((one_bit & 0x01)) *(drow+x) = 0x00000000; else *(drow+x) = 0xFFFFFFFF; } break; } case QImage::Format_Indexed8: for(int x=0;x<w;++x) { *(drow+x) = PREMUL(image.color(*(srow + x))); } break; case QImage::Format_RGB32: for(int x=0;x<w;++x) *(drow+x) = *(((quint32*)srow) + x) | 0xFF000000; break; case QImage::Format_ARGB32: case QImage::Format_ARGB32_Premultiplied: for(int x=0;x<w;++x) { if(sfmt == QImage::Format_RGB32) *(drow+x) = 0xFF000000 | (*(((quint32*)srow) + x) & 0x00FFFFFF); else if(sfmt == QImage::Format_ARGB32_Premultiplied) *(drow+x) = *(((quint32*)srow) + x); else *(drow+x) = PREMUL(*(((quint32*)srow) + x)); } break; default: qWarning("Qt: internal: Oops: Forgot a format [%d] %s:%d", sfmt, __FILE__, __LINE__); break; } }
int QBBScreen::depth() const { return defaultDepth(); }