23quint32 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,
43 quint32 MagicNumber = 0;
49 quint32 ColorMapType = 0;
50 quint32 ColorMapLength = 0;
58 s >> head.MagicNumber;
64 s >> head.ColorMapType;
65 s >> head.ColorMapLength;
77static bool IsSupported(
const RasHeader &head)
80 if (head.MagicNumber != rasMagicBigEndian) {
84 if (head.Depth != 1 && head.Depth != 8 && head.Depth != 24 && head.Depth != 32) {
87 if (head.Width == 0 || head.Height == 0) {
93 if (!(head.Type == RAS_TYPE_STANDARD || head.Type == RAS_TYPE_RGB_FORMAT || head.Type == RAS_TYPE_BYTE_ENCODED)) {
101 if (header.ColorMapType == RAS_COLOR_MAP_TYPE_RGB) {
104 if (header.Depth == 8 && header.ColorMapType == RAS_COLOR_MAP_TYPE_NONE) {
107 if (header.Depth == 1) {
116 LineDecoder(
QIODevice *d,
const RasHeader &ras)
126 if (header.Type != RAS_TYPE_BYTE_ENCODED) {
127 return device->read(size);
152 for (qsizetype psz = 0, ptr = 0; uncBuffer.size() < size;) {
153 rleBuffer.append(device->read(std::min(qint64(32768), size)));
154 qsizetype sz = rleBuffer.size();
158 auto data =
reinterpret_cast<uchar *
>(rleBuffer.data());
160 auto flag = data[ptr++];
166 auto cnt = data[ptr++];
168 uncBuffer.append(
char(0x80));
170 }
else if (ptr >= sz) {
174 auto val = data[ptr++];
175 uncBuffer.append(
QByteArray(1 + cnt,
char(val)));
177 uncBuffer.append(
char(flag));
181 rleBuffer.remove(0, ptr);
184 psz = rleBuffer.size();
186 if (uncBuffer.size() < size) {
189 auto line = uncBuffer.
mid(0, size);
190 uncBuffer.
remove(0, line.size());
208 auto rasLineSize = (qint64(ras.Width) * ras.Depth + 7) / 8;
211 if (rasLineSize > kMaxQVectorSize) {
212 qWarning() <<
"LoadRAS() unsupported line size" << rasLineSize;
217 img = imageAlloc(ras.Width, ras.Height, imageFormat(ras));
223 if (ras.ColorMapType == RAS_COLOR_MAP_TYPE_RGB) {
225 if (ras.ColorMapLength > 768) {
229 for (quint32 i = 0; i < ras.ColorMapLength; ++i) {
236 for (quint32 i = 0, n = ras.ColorMapLength / 3; i < n; ++i) {
237 colorTable << qRgb(palette.at(i), palette.at(i + n), palette.at(i + 2 * n));
239 for (; colorTable.
size() < 256;) {
240 colorTable << qRgb(255, 255, 255);
246 auto bytesPerLine = std::min(img.
bytesPerLine(), qsizetype(rasLineSize));
247 for (quint32 y = 0; y < ras.Height; ++y) {
249 if (rasLine.size() != rasLineSize) {
250 qWarning() <<
"LoadRAS() unable to read line" << y <<
": the seems corrupted!";
255 if (ras.ColorMapType == RAS_COLOR_MAP_TYPE_NONE && (ras.Depth == 1 || ras.Depth == 8)) {
256 for (
auto &&b : rasLine) {
259 std::memcpy(img.
scanLine(y), rasLine.constData(), bytesPerLine);
264 if (ras.ColorMapType == RAS_COLOR_MAP_TYPE_RGB && (ras.Depth == 1 || ras.Depth == 8)) {
265 std::memcpy(img.
scanLine(y), rasLine.constData(), bytesPerLine);
270 if (ras.ColorMapType == RAS_COLOR_MAP_TYPE_NONE && ras.Depth == 24 && (ras.Type == RAS_TYPE_STANDARD || ras.Type == RAS_TYPE_BYTE_ENCODED)) {
274 auto scanLine =
reinterpret_cast<QRgb *
>(img.
scanLine(y));
275 for (quint32 x = 0; x < ras.Width; x++) {
276 red = rasLine.at(x * 3 + 2);
277 green = rasLine.at(x * 3 + 1);
278 blue = rasLine.at(x * 3);
279 *(scanLine + x) = qRgb(red, green, blue);
285 if (ras.ColorMapType == RAS_COLOR_MAP_TYPE_NONE && ras.Depth == 24 && ras.Type == RAS_TYPE_RGB_FORMAT) {
289 auto scanLine =
reinterpret_cast<QRgb *
>(img.
scanLine(y));
290 for (quint32 x = 0; x < ras.Width; x++) {
291 red = rasLine.at(x * 3);
292 green = rasLine.at(x * 3 + 1);
293 blue = rasLine.at(x * 3 + 2);
294 *(scanLine + x) = qRgb(red, green, blue);
300 if (ras.ColorMapType == RAS_COLOR_MAP_TYPE_NONE && ras.Depth == 32 && (ras.Type == RAS_TYPE_STANDARD || ras.Type == RAS_TYPE_BYTE_ENCODED)) {
304 auto scanLine =
reinterpret_cast<QRgb *
>(img.
scanLine(y));
305 for (quint32 x = 0; x < ras.Width; x++) {
306 red = rasLine.at(x * 4 + 3);
307 green = rasLine.at(x * 4 + 2);
308 blue = rasLine.at(x * 4 + 1);
309 *(scanLine + x) = qRgb(red, green, blue);
316 if (ras.ColorMapType == RAS_COLOR_MAP_TYPE_NONE && ras.Depth == 32 && ras.Type == RAS_TYPE_RGB_FORMAT) {
320 auto scanLine =
reinterpret_cast<QRgb *
>(img.
scanLine(y));
321 for (quint32 x = 0; x < ras.Width; x++) {
322 red = rasLine.at(x * 4 + 1);
323 green = rasLine.at(x * 4 + 2);
324 blue = rasLine.at(x * 4 + 3);
325 *(scanLine + x) = qRgb(red, green, blue);
330 qWarning() <<
"LoadRAS() unsupported format!"
331 <<
"ColorMapType:" << ras.ColorMapType <<
"Type:" << ras.Type <<
"Depth:" << ras.Depth;
339class RASHandlerPrivate
342 RASHandlerPrivate() {}
343 ~RASHandlerPrivate() {}
349RASHandler::RASHandler()
351 , d(new RASHandlerPrivate)
355bool RASHandler::canRead()
const
357 if (canRead(device())) {
364bool RASHandler::canRead(
QIODevice *device)
367 qWarning(
"RASHandler::canRead() called with no device");
376 qint64 oldPos = device->
pos();
378 int readBytes = head.
size();
380 device->
seek(oldPos);
382 if (readBytes < RasHeader::SIZE) {
390 return IsSupported(ras);
393bool RASHandler::read(
QImage *outImage)
399 auto&& ras = d->m_header;
402 if (ras.ColorMapLength > kMaxQVectorSize) {
403 qWarning() <<
"LoadRAS() unsupported image color map length in file header" << ras.ColorMapLength;
408 if (!IsSupported(ras)) {
414 bool result = LoadRAS(s, ras, img);
416 if (result ==
false) {
425bool RASHandler::supportsOption(ImageOption option)
const
436QVariant RASHandler::option(ImageOption option)
const
441 auto&& header = d->m_header;
442 if (IsSupported(header)) {
445 else if (
auto dev = device()) {
447 dev->startTransaction();
448 auto ba = dev->read(RasHeader::SIZE);
449 dev->rollbackTransaction();
461 auto&& header = d->m_header;
462 if (IsSupported(header)) {
465 else if (
auto dev = device()) {
467 dev->startTransaction();
468 auto ba = dev->read(RasHeader::SIZE);
469 dev->rollbackTransaction();
485 if (format ==
"im1" || format ==
"im8" || format ==
"im24" || format ==
"im32" || format ==
"ras" || format ==
"sun") {
496 if (device->
isReadable() && RASHandler::canRead(device)) {
510#include "moc_ras_p.cpp"
KCALENDARCORE_EXPORT QDataStream & operator>>(QDataStream &in, const KCalendarCore::Alarm::Ptr &)
QFlags< Capability > Capabilities
bool isEmpty() const const
QByteArray mid(qsizetype pos, qsizetype len) const const
QByteArray & remove(qsizetype pos, qsizetype len)
qsizetype size() const const
QIODevice * device() const const
void setByteOrder(ByteOrder bo)
Status status() const const
qsizetype bytesPerLine() const const
bool isNull() const const
void setColorTable(const QList< QRgb > &colors)
void setDevice(QIODevice *device)
bool isOpen() const const
bool isReadable() const const
virtual bool isSequential() const const
virtual qint64 pos() const const
QByteArray read(qint64 maxSize)
virtual bool seek(qint64 pos)
qsizetype size() const const
QTextStream & dec(QTextStream &stream)
QString readLine(qint64 maxlen)
QVariant fromValue(T &&value)