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());
206 auto rasLineSize = (qint64(ras.Width) * ras.Depth + 7) / 8;
209 if (rasLineSize > kMaxQVectorSize) {
210 qWarning() <<
"LoadRAS() unsupported line size" << rasLineSize;
215 img = imageAlloc(ras.Width, ras.Height, imageFormat(ras));
221 if (ras.ColorMapType == RAS_COLOR_MAP_TYPE_RGB) {
223 if (ras.ColorMapLength > 768) {
227 for (quint32 i = 0; i < ras.ColorMapLength; ++i) {
234 for (quint32 i = 0, n = ras.ColorMapLength / 3; i < n; ++i) {
235 colorTable << qRgb(palette.at(i), palette.at(i + n), palette.at(i + 2 * n));
237 for (; colorTable.
size() < 256;) {
238 colorTable << qRgb(255, 255, 255);
244 auto bytesPerLine = std::min(img.
bytesPerLine(), qsizetype(rasLineSize));
245 for (quint32 y = 0; y < ras.Height; ++y) {
247 if (rasLine.size() != rasLineSize) {
248 qWarning() <<
"LoadRAS() unable to read line" << y <<
": the seems corrupted!";
253 if (ras.ColorMapType == RAS_COLOR_MAP_TYPE_NONE && (ras.Depth == 1 || ras.Depth == 8)) {
254 for (
auto &&b : rasLine) {
257 std::memcpy(img.
scanLine(y), rasLine.constData(), bytesPerLine);
262 if (ras.ColorMapType == RAS_COLOR_MAP_TYPE_RGB && (ras.Depth == 1 || ras.Depth == 8)) {
263 std::memcpy(img.
scanLine(y), rasLine.constData(), bytesPerLine);
268 if (ras.ColorMapType == RAS_COLOR_MAP_TYPE_NONE && ras.Depth == 24 && (ras.Type == RAS_TYPE_STANDARD || ras.Type == RAS_TYPE_BYTE_ENCODED)) {
272 auto scanLine =
reinterpret_cast<QRgb *
>(img.
scanLine(y));
273 for (quint32 x = 0; x < ras.Width; x++) {
274 red = rasLine.at(x * 3 + 2);
275 green = rasLine.at(x * 3 + 1);
276 blue = rasLine.at(x * 3);
277 *(scanLine + x) = qRgb(red, green, blue);
283 if (ras.ColorMapType == RAS_COLOR_MAP_TYPE_NONE && ras.Depth == 24 && ras.Type == RAS_TYPE_RGB_FORMAT) {
287 auto scanLine =
reinterpret_cast<QRgb *
>(img.
scanLine(y));
288 for (quint32 x = 0; x < ras.Width; x++) {
289 red = rasLine.at(x * 3);
290 green = rasLine.at(x * 3 + 1);
291 blue = rasLine.at(x * 3 + 2);
292 *(scanLine + x) = qRgb(red, green, blue);
298 if (ras.ColorMapType == RAS_COLOR_MAP_TYPE_NONE && ras.Depth == 32 && (ras.Type == RAS_TYPE_STANDARD || ras.Type == RAS_TYPE_BYTE_ENCODED)) {
302 auto scanLine =
reinterpret_cast<QRgb *
>(img.
scanLine(y));
303 for (quint32 x = 0; x < ras.Width; x++) {
304 red = rasLine.at(x * 4 + 3);
305 green = rasLine.at(x * 4 + 2);
306 blue = rasLine.at(x * 4 + 1);
307 *(scanLine + x) = qRgb(red, green, blue);
314 if (ras.ColorMapType == RAS_COLOR_MAP_TYPE_NONE && ras.Depth == 32 && ras.Type == RAS_TYPE_RGB_FORMAT) {
318 auto scanLine =
reinterpret_cast<QRgb *
>(img.
scanLine(y));
319 for (quint32 x = 0; x < ras.Width; x++) {
320 red = rasLine.at(x * 4 + 1);
321 green = rasLine.at(x * 4 + 2);
322 blue = rasLine.at(x * 4 + 3);
323 *(scanLine + x) = qRgb(red, green, blue);
328 qWarning() <<
"LoadRAS() unsupported format!"
329 <<
"ColorMapType:" << ras.ColorMapType <<
"Type:" << ras.Type <<
"Depth:" << ras.Depth;
337class RASHandlerPrivate
340 RASHandlerPrivate() {}
341 ~RASHandlerPrivate() {}
347RASHandler::RASHandler()
349 , d(new RASHandlerPrivate)
353bool RASHandler::canRead()
const
355 if (canRead(device())) {
362bool RASHandler::canRead(
QIODevice *device)
365 qWarning(
"RASHandler::canRead() called with no device");
369 auto head = device->
peek(RasHeader::SIZE);
370 if (head.size() < RasHeader::SIZE) {
378 return IsSupported(ras);
381bool RASHandler::read(
QImage *outImage)
387 auto&& ras = d->m_header;
390 if (ras.ColorMapLength > kMaxQVectorSize) {
391 qWarning() <<
"LoadRAS() unsupported image color map length in file header" << ras.ColorMapLength;
396 if (!IsSupported(ras)) {
402 if (!LoadRAS(s, ras, img)) {
411bool RASHandler::supportsOption(ImageOption option)
const
422QVariant RASHandler::option(ImageOption option)
const
427 auto&& header = d->m_header;
428 if (IsSupported(header)) {
431 else if (
auto dev = device()) {
442 auto&& header = d->m_header;
443 if (IsSupported(header)) {
446 else if (
auto dev = device()) {
461 if (format ==
"im1" || format ==
"im8" || format ==
"im24" || format ==
"im32" || format ==
"ras" || format ==
"sun") {
472 if (device->
isReadable() && RASHandler::canRead(device)) {
486#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)
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
QByteArray peek(qint64 maxSize)
qsizetype size() const const
QTextStream & dec(QTextStream &stream)
QString readLine(qint64 maxlen)
QVariant fromValue(T &&value)