PageRenderTime 183ms CodeModel.GetById 80ms app.highlight 8ms RepoModel.GetById 92ms app.codeStats 0ms

/src/libtomahawk/infosystem/infoplugins/unix/imageconverter.cpp

http://github.com/tomahawk-player/tomahawk
C++ | 109 lines | 63 code | 16 blank | 30 comment | 3 complexity | edd99403eb223a9e8dfad7e318b4c8cc MD5 | raw file
  1/*
  2   Copyright (C) 2009 by Aur?Šlien G??teau <aurelien.gateau@canonical.com>
  3
  4   This program is free software; you can redistribute it and/or modify
  5   it under the terms of the GNU General Public License as published by
  6   the Free Software Foundation; either version 2, or (at your option)
  7   any later version.
  8
  9   This program is distributed in the hope that it will be useful,
 10   but WITHOUT ANY WARRANTY; without even the implied warranty of
 11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12   GNU General Public License for more details.
 13
 14   You should have received a copy of the GNU General Public License
 15   along with this program; if not, write to the Free Software
 16   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 17
 18 */
 19#include "imageconverter.h"
 20
 21#include <QtDBus/QDBusArgument>
 22#include <QtDBus/QDBusMetaType>
 23#include <QtGui/QImage>
 24
 25#include "utils/logger.h"
 26
 27namespace ImageConverter
 28{
 29
 30/**
 31 * A structure representing an image which can be marshalled to fit the
 32 * notification spec.
 33 */
 34struct SpecImage
 35{
 36	int width, height, rowStride;
 37	bool hasAlpha;
 38	int bitsPerSample, channels;
 39	QByteArray data;
 40};
 41
 42QDBusArgument &operator<<(QDBusArgument &argument, const SpecImage &image)
 43{
 44	argument.beginStructure();
 45	argument << image.width << image.height << image.rowStride << image.hasAlpha;
 46	argument << image.bitsPerSample << image.channels << image.data;
 47	argument.endStructure();
 48	return argument;
 49}
 50
 51const QDBusArgument &operator>>(const QDBusArgument &argument, SpecImage &image)
 52{
 53	argument.beginStructure();
 54	argument >> image.width >> image.height >> image.rowStride >> image.hasAlpha;
 55	argument >> image.bitsPerSample >> image.channels >> image.data;
 56	argument.endStructure();
 57	return argument;
 58}
 59
 60} // namespace
 61
 62// This must be before the QVariant::fromValue below (#211726)
 63Q_DECLARE_METATYPE(ImageConverter::SpecImage)
 64
 65namespace ImageConverter
 66{
 67QVariant variantForImage(const QImage &_image)
 68{
 69	qDBusRegisterMetaType<SpecImage>();
 70
 71	QImage image = _image.convertToFormat(QImage::Format_ARGB32);
 72
 73	int rowStride = image.width() * 4;
 74
 75	// Notification spec stores pixels in R,G,B,A order, regardless of
 76	// endianess
 77	// Qt represents pixels as 32 bit unsigned int. So the order depend on
 78	// endianess:
 79	// - In big endian the order is A,R,G,B
 80	// - In little endian the order is B,G,R,A
 81	QByteArray data;
 82	data.resize(rowStride * image.height());
 83	char* dst = data.data();
 84	for (int y=0; y<image.height(); ++y) {
 85		QRgb* src = (QRgb*)image.scanLine(y);
 86		QRgb* end = src + image.width();
 87		for (;src != end; ++src) {
 88			// Probably slow, but free of endianess issues
 89			*dst++ = qRed(*src);
 90			*dst++ = qGreen(*src);
 91			*dst++ = qBlue(*src);
 92			*dst++ = qAlpha(*src);
 93		}
 94	}
 95
 96	SpecImage specImage;
 97	specImage.width = image.width();
 98	specImage.height = image.height();
 99	specImage.rowStride = rowStride;
100	specImage.hasAlpha = true;
101	specImage.bitsPerSample = 8;
102	specImage.channels = 4;
103	specImage.data = data;
104
105	return QVariant::fromValue(specImage);
106}
107
108} // namespace
109