14 #include <QtGui/QImage>
15 #include <QtCore/QDataStream>
23 quint32 rasMagicBigEndian = 0x59a66a95;
28 RAS_TYPE_STANDARD = 0x1,
29 RAS_TYPE_BYTE_ENCODED = 0x2,
30 RAS_TYPE_RGB_FORMAT = 0x3,
31 RAS_TYPE_TIFF_FORMAT = 0x4,
32 RAS_TYPE_IFF_FORMAT = 0x5,
33 RAS_TYPE_EXPERIMENTAL = 0xFFFF
37 RAS_COLOR_MAP_TYPE_NONE = 0x0,
38 RAS_COLOR_MAP_TYPE_RGB = 0x1,
39 RAS_COLOR_MAP_TYPE_RAW = 0x2
50 quint32 ColorMapLength;
54 static QDataStream &
operator>> ( QDataStream & s, RasHeader & head )
56 s >> head.MagicNumber;
62 s >> head.ColorMapType;
63 s >> head.ColorMapLength;
78 if ( head.MagicNumber != rasMagicBigEndian) {
84 if ( ! ((head.Depth == 8 && head.ColorMapType == 1)
85 || head.Depth == 24 || head.Depth == 32) ){
91 if ( ! (head.Type == 1 || head.Type == 3) ){
102 static bool LoadRAS( QDataStream & s,
const RasHeader & ras, QImage &img )
104 s.device()->seek(RasHeader::SIZE);
107 if ( ras.ColorMapType == 1 ) {
108 for (quint32 i = 0; i < ras.ColorMapLength; ++i) { s >> palette[i]; }
113 int paddingrequired = (ras.Width*(ras.Depth/8) % 2);
120 while ( ! s.atEnd()) {
123 if ( paddingrequired && i != 0 && !(i % (ras.Width*(ras.Depth/8))) ) {
130 img = QImage(ras.Width, ras.Height, QImage::Format_ARGB32);
134 if ( ras.ColorMapType == 1 && ras.Depth == 8) {
135 quint8 red, green, blue;
136 for ( quint32 y = 0; y < ras.Height; y++ ){
137 for ( quint32 x = 0; x < ras.Width; x++ ) {
138 red = palette[(int)input[y*ras.Width + x]];
139 green = palette[(
int)input[y*ras.Width + x] + (ras.ColorMapLength/3)];
140 blue = palette[(
int)input[y*ras.Width + x] + 2*(ras.ColorMapLength/3)];
141 img.setPixel(x, y, qRgb(red, green, blue));
147 if ( ras.ColorMapType == 0 && ras.Depth == 24 && (ras.Type == 1 || ras.Type == 2)) {
148 quint8 red, green, blue;
149 for ( quint32 y = 0; y < ras.Height; y++ ){
150 for ( quint32 x = 0; x < ras.Width; x++ ) {
151 red = input[y*3*ras.Width + x*3 + 2];
152 green = input[y*3*ras.Width + x*3 + 1];
153 blue = input[y*3*ras.Width + x*3];
154 img.setPixel(x, y, qRgb(red, green, blue));
159 if ( ras.ColorMapType == 0 && ras.Depth == 24 && ras.Type == 3) {
160 quint8 red, green, blue;
161 for ( quint32 y = 0; y < ras.Height; y++ ){
162 for ( quint32 x = 0; x < ras.Width; x++ ) {
163 red = input[y*3*ras.Width + x*3];
164 green = input[y*3*ras.Width + x*3 + 1];
165 blue = input[y*3*ras.Width + x*3 + 2];
166 img.setPixel(x, y, qRgb(red, green, blue));
171 if ( ras.ColorMapType == 0 && ras.Depth == 32 && (ras.Type == 1 || ras.Type == 2)) {
172 quint8 red, green, blue;
173 for ( quint32 y = 0; y < ras.Height; y++ ){
174 for ( quint32 x = 0; x < ras.Width; x++ ) {
175 red = input[y*4*ras.Width + x*4 + 3];
176 green = input[y*4*ras.Width + x*4 + 2];
177 blue = input[y*4*ras.Width + x*4 + 1];
178 img.setPixel(x, y, qRgb(red, green, blue));
183 if ( ras.ColorMapType == 0 && ras.Depth == 32 && ras.Type == 3 ) {
184 quint8 red, green, blue;
185 for ( quint32 y = 0; y < ras.Height; y++ ){
186 for ( quint32 x = 0; x < ras.Width; x++ ) {
187 red = input[y*4*ras.Width + x*4 + 1];
188 green = input[y*4*ras.Width + x*4 + 2];
189 blue = input[y*4*ras.Width + x*4 + 3];
190 img.setPixel(x, y, qRgb(red, green, blue));
220 qWarning(
"RASHandler::canRead() called with no device");
224 if (device->isSequential()) {
225 qWarning(
"Reading ras files from sequential devices not supported");
229 qint64 oldPos = device->pos();
230 QByteArray head = device->read(RasHeader::SIZE);
231 int readBytes = head.size();
233 device->seek(oldPos);
235 if (readBytes < RasHeader::SIZE) {
239 QDataStream stream(head);
240 stream.setByteOrder(QDataStream::BigEndian);
248 QDataStream s( device() );
249 s.setByteOrder( QDataStream::BigEndian );
255 s.device()->seek( RasHeader::SIZE + ras.Length + ras.ColorMapLength );
258 if( !s.atEnd() && ras.Type != 2) {
259 kDebug(399) <<
"This RAS file is not valid, or an older version of the format.";
265 kDebug(399) <<
"This RAS file is not supported.";
270 bool result = LoadRAS(s, ras, img);
272 if( result ==
false ) {
273 kDebug(399) <<
"Error loading RAS file.";
285 class RASPlugin :
public QImageIOPlugin
288 QStringList keys()
const;
289 Capabilities capabilities(QIODevice *device,
const QByteArray &format)
const;
290 QImageIOHandler *create(QIODevice *device,
const QByteArray &format = QByteArray())
const;
293 QStringList RASPlugin::keys()
const
295 return QStringList() <<
"ras" <<
"RAS";
298 QImageIOPlugin::Capabilities RASPlugin::capabilities(QIODevice *device,
const QByteArray &format)
const
301 if (format ==
"ras" || format ==
"RAS")
302 return Capabilities(CanRead);
304 if (!format.isEmpty())
306 if (!device->isOpen())
312 if (device->isWritable())
317 QImageIOHandler *RASPlugin::create(QIODevice *device,
const QByteArray &format)
const
320 handler->setDevice(device);
321 handler->setFormat(format);
326 Q_EXPORT_STATIC_PLUGIN(RASPlugin)
327 Q_EXPORT_PLUGIN2(ras, RASPlugin)
static QDataStream & operator>>(QDataStream &s, DDSPixelFormat &pf)
static bool IsSupported(const DDSHeader &header)