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 for (quint32 i = 0; i < ras.ColorMapLength; ++i) {
229 for (quint32 i = 0, n = ras.ColorMapLength / 3; i < n; ++i) {
230 colorTable << qRgb(palette.at(i), palette.at(i + n), palette.at(i + 2 * n));
232 for (; colorTable.
size() < 256;) {
233 colorTable << qRgb(255, 255, 255);
242 auto bytesPerLine = std::min(img.
bytesPerLine(), qsizetype(rasLineSize));
243 for (quint32 y = 0; y < ras.Height; ++y) {
245 if (rasLine.size() != rasLineSize) {
246 qWarning() <<
"LoadRAS() unable to read line" << y <<
": the seems corrupted!";
251 if (ras.ColorMapType == RAS_COLOR_MAP_TYPE_NONE && (ras.Depth == 1 || ras.Depth == 8)) {
252 for (
auto &&b : rasLine) {
255 std::memcpy(img.
scanLine(y), rasLine.constData(), bytesPerLine);
260 if (ras.ColorMapType == RAS_COLOR_MAP_TYPE_RGB && (ras.Depth == 1 || ras.Depth == 8)) {
261 std::memcpy(img.
scanLine(y), rasLine.constData(), bytesPerLine);
266 if (ras.ColorMapType == RAS_COLOR_MAP_TYPE_NONE && ras.Depth == 24 && (ras.Type == RAS_TYPE_STANDARD || ras.Type == RAS_TYPE_BYTE_ENCODED)) {
270 auto scanLine =
reinterpret_cast<QRgb *
>(img.
scanLine(y));
271 for (quint32 x = 0; x < ras.Width; x++) {
272 red = rasLine.at(x * 3 + 2);
273 green = rasLine.at(x * 3 + 1);
274 blue = rasLine.at(x * 3);
275 *(scanLine + x) = qRgb(red, green, blue);
281 if (ras.ColorMapType == RAS_COLOR_MAP_TYPE_NONE && ras.Depth == 24 && ras.Type == RAS_TYPE_RGB_FORMAT) {
285 auto scanLine =
reinterpret_cast<QRgb *
>(img.
scanLine(y));
286 for (quint32 x = 0; x < ras.Width; x++) {
287 red = rasLine.at(x * 3);
288 green = rasLine.at(x * 3 + 1);
289 blue = rasLine.at(x * 3 + 2);
290 *(scanLine + x) = qRgb(red, green, blue);
296 if (ras.ColorMapType == RAS_COLOR_MAP_TYPE_NONE && ras.Depth == 32 && (ras.Type == RAS_TYPE_STANDARD || ras.Type == RAS_TYPE_BYTE_ENCODED)) {
300 auto scanLine =
reinterpret_cast<QRgb *
>(img.
scanLine(y));
301 for (quint32 x = 0; x < ras.Width; x++) {
302 red = rasLine.at(x * 4 + 3);
303 green = rasLine.at(x * 4 + 2);
304 blue = rasLine.at(x * 4 + 1);
305 *(scanLine + x) = qRgb(red, green, blue);
312 if (ras.ColorMapType == RAS_COLOR_MAP_TYPE_NONE && ras.Depth == 32 && ras.Type == RAS_TYPE_RGB_FORMAT) {
316 auto scanLine =
reinterpret_cast<QRgb *
>(img.
scanLine(y));
317 for (quint32 x = 0; x < ras.Width; x++) {
318 red = rasLine.at(x * 4 + 1);
319 green = rasLine.at(x * 4 + 2);
320 blue = rasLine.at(x * 4 + 3);
321 *(scanLine + x) = qRgb(red, green, blue);
326 qWarning() <<
"LoadRAS() unsupported format!"
327 <<
"ColorMapType:" << ras.ColorMapType <<
"Type:" << ras.Type <<
"Depth:" << ras.Depth;
335RASHandler::RASHandler()
339bool RASHandler::canRead()
const
341 if (canRead(device())) {
348bool RASHandler::canRead(
QIODevice *device)
351 qWarning(
"RASHandler::canRead() called with no device");
360 qint64 oldPos = device->
pos();
362 int readBytes = head.
size();
364 device->
seek(oldPos);
366 if (readBytes < RasHeader::SIZE) {
374 return IsSupported(ras);
377bool RASHandler::read(
QImage *outImage)
386 if (ras.ColorMapLength > kMaxQVectorSize) {
387 qWarning() <<
"LoadRAS() unsupported image color map length in file header" << ras.ColorMapLength;
392 if (!IsSupported(ras)) {
398 bool result = LoadRAS(s, ras, img);
400 if (result ==
false) {
409bool RASHandler::supportsOption(ImageOption option)
const
420QVariant RASHandler::option(ImageOption option)
const
425 if (
auto d = device()) {
427 d->startTransaction();
428 auto ba = d->read(RasHeader::SIZE);
429 d->rollbackTransaction();
444 if (
auto d = device()) {
446 d->startTransaction();
447 auto ba = d->read(RasHeader::SIZE);
448 d->rollbackTransaction();
467 if (format ==
"im1" || format ==
"im8" || format ==
"im24" || format ==
"im32" || format ==
"ras" || format ==
"sun") {
478 if (device->
isReadable() && RASHandler::canRead(device)) {
492#include "moc_ras_p.cpp"
KCALENDARCORE_EXPORT QDataStream & operator>>(QDataStream &in, const KCalendarCore::Alarm::Ptr &)
QFlags< Capability > Capabilities
QByteArray & append(QByteArrayView data)
bool isEmpty() const const
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)