예제 #1
0
Image Image::convertedToFormat (PixelFormat newFormat) const
{
    if (image == nullptr || newFormat == image->pixelFormat)
        return *this;

    const int w = image->width, h = image->height;

    const ScopedPointer<ImageType> type (image->createType());
    Image newImage (type->create (newFormat, w, h, false));

    if (newFormat == SingleChannel)
    {
        if (! hasAlphaChannel())
        {
            newImage.clear (getBounds(), Colours::black);
        }
        else
        {
            const BitmapData destData (newImage, 0, 0, w, h, BitmapData::writeOnly);
            const BitmapData srcData (*this, 0, 0, w, h);

            for (int y = 0; y < h; ++y)
            {
                const PixelARGB* const src = (const PixelARGB*) srcData.getLinePointer (y);
                uint8* const dst = destData.getLinePointer (y);

                for (int x = 0; x < w; ++x)
                    dst[x] = src[x].getAlpha();
            }
        }
    }
    else if (image->pixelFormat == SingleChannel && newFormat == Image::ARGB)
    {
        const BitmapData destData (newImage, 0, 0, w, h, BitmapData::writeOnly);
        const BitmapData srcData (*this, 0, 0, w, h);

        for (int y = 0; y < h; ++y)
        {
            const PixelAlpha* const src = (const PixelAlpha*) srcData.getLinePointer (y);
            PixelARGB* const dst = (PixelARGB*) destData.getLinePointer (y);

            for (int x = 0; x < w; ++x)
                dst[x].set (src[x]);
        }
    }
    else
    {
        if (hasAlphaChannel())
            newImage.clear (getBounds());

        Graphics g (newImage);
        g.drawImageAt (*this, 0, 0);
    }

    return newImage;
}
예제 #2
0
void Image::multiplyAllAlphas (const float amountToMultiplyBy)
{
    jassert (hasAlphaChannel());

    const BitmapData destData (*this, 0, 0, getWidth(), getHeight(), BitmapData::readWrite);
    performPixelOp (destData, AlphaMultiplyOp (amountToMultiplyBy));
}
QPaintEngine* QX11GLPixmapData::paintEngine() const
{
    // We need to create the context before beginPaint - do it here:
    if (!ctx) {
        ctx = new QGLContext(glFormat());
        if (ctx->d_func()->eglContext == 0)
            ctx->d_func()->eglContext = new QEglContext();
        ctx->d_func()->eglContext->openDisplay(0); // ;-)
        ctx->d_func()->eglContext->setApi(QEgl::OpenGL);
        ctx->d_func()->eglContext->setContext(hasAlphaChannel() ? qPixmapARGBSharedEglContext
                                                                : qPixmapRGBSharedEglContext);
    }

    if (!qt_gl2_engine_for_pixmaps)
        qt_gl2_engine_for_pixmaps = new QGL2PaintEngineEx();

    // Support multiple painters on multiple pixmaps simultaniously
    if (qt_gl2_engine_for_pixmaps->isActive()) {
        qWarning("Pixmap paint engine already active");
        QPaintEngine* engine = new QGL2PaintEngineEx();
        engine->setAutoDestruct(true);
        return engine;
    }

    return qt_gl2_engine_for_pixmaps;
}
예제 #4
0
QImage QDirectFBPixmapData::toImage() const
{
    if (!dfbSurface)
        return QImage();

#if 0
    // In later versions of DirectFB one can set a flag to tell
    // DirectFB not to move the surface to videomemory. When that
    // happens we can use this (hopefully faster) codepath
#ifndef QT_NO_DIRECTFB_PREALLOCATED
    QImage ret(w, h, QDirectFBScreen::getImageFormat(dfbSurface));
    if (IDirectFBSurface *imgSurface = screen->createDFBSurface(ret, QDirectFBScreen::DontTrackSurface)) {
        if (hasAlphaChannel()) {
            imgSurface->SetBlittingFlags(imgSurface, DSBLIT_BLEND_ALPHACHANNEL);
            imgSurface->Clear(imgSurface, 0, 0, 0, 0);
        } else {
            imgSurface->SetBlittingFlags(imgSurface, DSBLIT_NOFX);
        }
        imgSurface->Blit(imgSurface, dfbSurface, 0, 0, 0);
#if (Q_DIRECTFB_VERSION >= 0x010000)
        imgSurface->ReleaseSource(imgSurface);
#endif
        imgSurface->Release(imgSurface);
        return ret;
    }
#endif
#endif

    QDirectFBPixmapData *that = const_cast<QDirectFBPixmapData*>(this);
    const QImage *img = that->buffer();
    return img->copy();
}
예제 #5
0
void QBlittablePlatformPixmap::fill(const QColor &color)
{
    if (blittable()->capabilities() & QBlittable::AlphaFillRectCapability) {
        blittable()->unlock();
        blittable()->alphaFillRect(QRectF(0,0,w,h),color,QPainter::CompositionMode_Source);
    } else if (color.alpha() == 255 && blittable()->capabilities() & QBlittable::SolidRectCapability) {
        blittable()->unlock();
        blittable()->fillRect(QRectF(0,0,w,h),color);
    } else {
        // Need to be backed with an alpha channel now. It would be nice
        // if we could just change the format, e.g. when going from
        // RGB32 -> ARGB8888.
        if (color.alpha() != 255 && !hasAlphaChannel()) {
            m_blittable.reset(0);
            m_engine.reset(0);
            m_alpha = true;
        }

        uint pixel = PREMUL(color.rgba());
        const QPixelLayout *layout = &qPixelLayouts[blittable()->lock()->format()];
        Q_ASSERT(layout->convertFromARGB32PM);
        layout->convertFromARGB32PM(&pixel, &pixel, 1, layout, 0);

        //so premultiplied formats are supported and ARGB32 and RGB32
        blittable()->lock()->fill(pixel);
    }

}
예제 #6
0
파일: juce_Image.cpp 프로젝트: EQ4/editor
Image Image::convertedToFormat (PixelFormat newFormat) const
{
    if (image == nullptr || newFormat == image->format)
        return *this;

    const int w = image->width, h = image->height;
    Image newImage (newFormat, w, h, false, image->getType());

    if (newFormat == SingleChannel)
    {
        if (! hasAlphaChannel())
        {
            newImage.clear (getBounds(), Colours::black);
        }
        else
        {
            const BitmapData destData (newImage, 0, 0, w, h, BitmapData::writeOnly);
            const BitmapData srcData (*this, 0, 0, w, h);

            for (int y = 0; y < h; ++y)
            {
                const PixelARGB* src = (const PixelARGB*) srcData.getLinePointer(y);
                uint8* dst = destData.getLinePointer (y);

                for (int x = w; --x >= 0;)
                {
                    *dst++ = src->getAlpha();
                    ++src;
                }
            }
        }
    }
    else
    {
        if (hasAlphaChannel())
            newImage.clear (getBounds());

        Graphics g (newImage);
        g.drawImageAt (*this, 0, 0);
    }

    return newImage;
}
예제 #7
0
void Image::multiplyAlphaAt (const int x, const int y, const float multiplier)
{
    if (isPositiveAndBelow (x, getWidth()) && isPositiveAndBelow (y, getHeight())
         && hasAlphaChannel())
    {
        const BitmapData destData (*this, x, y, 1, 1, BitmapData::readWrite);

        if (isARGB())
            ((PixelARGB*) destData.data)->multiplyAlpha (multiplier);
        else
            *(destData.data) = (uint8) (*(destData.data) * multiplier);
    }
}
예제 #8
0
파일: juce_Image.cpp 프로젝트: EQ4/editor
Image Image::rescaled (const int newWidth, const int newHeight, const Graphics::ResamplingQuality quality) const
{
    if (image == nullptr || (image->width == newWidth && image->height == newHeight))
        return *this;

    Image newImage (image->format, newWidth, newHeight, hasAlphaChannel(), image->getType());

    Graphics g (newImage);
    g.setImageResamplingQuality (quality);
    g.drawImage (*this, 0, 0, newWidth, newHeight, 0, 0, image->width, image->height, false);

    return newImage;
}
예제 #9
0
Image Image::rescaled (const int newWidth, const int newHeight, const Graphics::ResamplingQuality quality) const
{
    if (image == nullptr || (image->width == newWidth && image->height == newHeight))
        return *this;

    const ScopedPointer<ImageType> type (image->createType());
    Image newImage (type->create (image->pixelFormat, newWidth, newHeight, hasAlphaChannel()));

    Graphics g (newImage);
    g.setImageResamplingQuality (quality);
    g.drawImage (*this, 0, 0, newWidth, newHeight, 0, 0, image->width, image->height, false);

    return newImage;
}
예제 #10
0
void QDirectFBPixmapData::fill(const QColor &color)
{
    if (!serialNumber())
        return;

    Q_ASSERT(surface);

    if (color.alpha() < 255 && !hasAlphaChannel()) {
        // convert to surface supporting alpha channel
        DFBSurfacePixelFormat format;
        surface->GetPixelFormat(surface, &format);
        switch (format) {
        case DSPF_YUY2:
        case DSPF_UYVY:
            format = DSPF_AYUV;
            break;
#if (Q_DIRECTFB_VERSION >= 0x010100)
        case DSPF_RGB444:
            format = DSPF_ARGB4444;
            break;
        case DSPF_RGB555:
#endif
        case DSPF_RGB18:
            format = DSPF_ARGB6666;
            break;
        default:
            format = DSPF_ARGB;
            break;
        }

        DFBSurfaceDescription description;
        description.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH |
                                                       DSDESC_HEIGHT |
                                                       DSDESC_PIXELFORMAT);
        surface->GetSize(surface, &description.width, &description.height);
        description.pixelformat = format;
        surface->Release(surface); // release old surface

        IDirectFB *fb = QDirectFBScreen::instance()->dfb();
        DFBResult result = fb->CreateSurface(fb, &description, &surface);
        if (result != DFB_OK) {
            DirectFBError("QDirectFBPixmapData::fill()", result);
            setSerialNumber(0);
            return;
        }
    }

    surface->Clear(surface, color.red(), color.green(), color.blue(),
                   color.alpha());
}
예제 #11
0
void Image::createSolidAreaMask (RectangleList& result, const float alphaThreshold) const
{
    if (hasAlphaChannel())
    {
        const uint8 threshold = (uint8) jlimit (0, 255, roundToInt (alphaThreshold * 255.0f));
        SparseSet<int> pixelsOnRow;

        const BitmapData srcData (*this, 0, 0, getWidth(), getHeight());

        for (int y = 0; y < srcData.height; ++y)
        {
            pixelsOnRow.clear();
            const uint8* lineData = srcData.getLinePointer (y);

            if (isARGB())
            {
                for (int x = 0; x < srcData.width; ++x)
                {
                    if (((const PixelARGB*) lineData)->getAlpha() >= threshold)
                        pixelsOnRow.addRange (Range<int> (x, x + 1));

                    lineData += srcData.pixelStride;
                }
            }
            else
            {
                for (int x = 0; x < srcData.width; ++x)
                {
                    if (*lineData >= threshold)
                        pixelsOnRow.addRange (Range<int> (x, x + 1));

                    lineData += srcData.pixelStride;
                }
            }

            for (int i = 0; i < pixelsOnRow.getNumRanges(); ++i)
            {
                const Range<int> range (pixelsOnRow.getRange (i));
                result.add (Rectangle<int> (range.getStart(), y, range.getLength(), 1));
            }

            result.consolidate();
        }
    }
    else
    {
        result.add (0, 0, getWidth(), getHeight());
    }
}
예제 #12
0
void QBlittablePixmapData::fill(const QColor &color)
{
    if (blittable()->capabilities() & QBlittable::AlphaFillRectCapability) {
        blittable()->unlock();
        blittable()->alphaFillRect(QRectF(0,0,w,h),color,QPainter::CompositionMode_Source);
    } else if (color.alpha() == 255 && blittable()->capabilities() & QBlittable::SolidRectCapability) {
        blittable()->unlock();
        blittable()->fillRect(QRectF(0,0,w,h),color);
    } else {
        // Need to be backed with an alpha channel now. It would be nice
        // if we could just change the format, e.g. when going from
        // RGB32 -> ARGB8888.
        if (color.alpha() != 255 && !hasAlphaChannel()) {
            m_blittable.reset(0);
            m_engine.reset(0);
            m_alpha = true;
        }

        uint pixel;
        switch (blittable()->lock()->format()) {
        case QImage::Format_ARGB32_Premultiplied:
            pixel = PREMUL(color.rgba());
            break;
        case QImage::Format_ARGB8565_Premultiplied:
            pixel = qargb8565(color.rgba()).rawValue();
            break;
        case QImage::Format_ARGB8555_Premultiplied:
            pixel = qargb8555(color.rgba()).rawValue();
            break;
        case QImage::Format_ARGB6666_Premultiplied:
            pixel = qargb6666(color.rgba()).rawValue();
            break;
        case QImage::Format_ARGB4444_Premultiplied:
            pixel = qargb4444(color.rgba()).rawValue();
            break;
        default:
            pixel = color.rgba();
            break;
        }
        //so premultiplied formats are supported and ARGB32 and RGB32
        blittable()->lock()->fill(pixel);
    }

}
void GoodThumbSource::generate(base::binary_guard &&guard) {
	if (!guard) {
		return;
	}
	const auto data = _document->data();
	const auto isWallPaper = _document->isWallPaper();
	auto location = _document->location().isEmpty()
		? nullptr
		: std::make_unique<FileLocation>(_document->location());
	if (data.isEmpty() && !location) {
		_empty = true;
		return;
	}
	crl::async([
		=,
		guard = std::move(guard),
		location = std::move(location)
	]() mutable {
		const auto filepath = (location && location->accessEnable())
			? location->name()
			: QString();
		auto result = Prepare(filepath, data, isWallPaper);
		auto bytes = QByteArray();
		if (!result.isNull()) {
			auto buffer = QBuffer(&bytes);
			const auto format = (isWallPaper && result.hasAlphaChannel())
				? "PNG"
				: "JPG";
			result.save(&buffer, format, kGoodThumbQuality);
		}
		if (!filepath.isEmpty()) {
			location->accessDisable();
		}
		const auto bytesSize = bytes.size();
		ready(
			std::move(guard),
			std::move(result),
			bytesSize,
			std::move(bytes));
	});
}
예제 #14
0
파일: juce_Image.cpp 프로젝트: EQ4/editor
void Image::multiplyAllAlphas (const float amountToMultiplyBy)
{
    if (hasAlphaChannel())
    {
        const BitmapData destData (*this, 0, 0, getWidth(), getHeight(), BitmapData::readWrite);

        if (isARGB())
        {
            for (int y = 0; y < destData.height; ++y)
            {
                uint8* p = destData.getLinePointer (y);

                for (int x = 0; x < destData.width; ++x)
                {
                    ((PixelARGB*) p)->multiplyAlpha (amountToMultiplyBy);
                    p += destData.pixelStride;
                }
            }
        }
        else
        {
            for (int y = 0; y < destData.height; ++y)
            {
                uint8* p = destData.getLinePointer (y);

                for (int x = 0; x < destData.width; ++x)
                {
                    *p = (uint8) (*p * amountToMultiplyBy);
                    p += destData.pixelStride;
                }
            }
        }
    }
    else
    {
        jassertfalse; // can't do this without an alpha-channel!
    }
}