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