24 static RGB from(
const QRgb color)
37 void setColor(
int i,
const QRgb color)
45 QRgb color(
int i)
const
47 return qRgb(rgb[i].r, rgb[i].g, rgb[i].b);
58 inline int width()
const
60 return (XMax - XMin) + 1;
62 inline int height()
const
64 return (YMax - YMin) + 1;
66 inline bool isCompressed()
const
68 return (Encoding == 1);
76 inline bool isValid()
const
78 return Manufacturer == 10 && BytesPerLine != 0;
84 inline bool isSupported()
const
91 if (Bpp == 1 && NPlanes == 1) {
93 }
else if (Bpp == 1 && NPlanes == 4) {
95 }
else if (Bpp == 4 && NPlanes == 1) {
97 }
else if (Bpp == 8 && NPlanes == 1) {
99 }
else if (Bpp == 8 && NPlanes == 3) {
128 quint16 BytesPerLine;
159 for (
int i = 0; i < 16; ++i) {
172 s >> m >> ver >> enc >> bpp;
181 s >> xmin >> ymin >> xmax >> ymax;
194 s >> colorMap >> res >> np;
195 ph.ColorMap = colorMap;
198 quint16 bytesperline;
200 ph.BytesPerLine = bytesperline;
203 ph.PaletteInfo = paletteinfo;
207 ph.HScreenSize = hscreensize;
209 ph.VScreenSize = vscreensize;
212 for (
size_t i = 0, n =
sizeof(ph.unused); i < n; ++i) {
221 s << rgb.r << rgb.g << rgb.b;
228 for (
int i = 0; i < 16; ++i) {
237 s << ph.Manufacturer;
241 s << ph.XMin << ph.YMin << ph.XMax << ph.YMax;
242 s << ph.HDpi << ph.YDpi;
246 s << ph.BytesPerLine;
251 for (
size_t i = 0, n =
sizeof(ph.unused); i < n; ++i) {
258PCXHEADER::PCXHEADER()
267bool peekHeader(
QIODevice *d, PCXHEADER& h)
269 auto head = d->
peek(
sizeof(PCXHEADER));
270 if (
size_t(head.size()) <
sizeof(PCXHEADER)) {
284 quint32 size = buf.
size();
288 if (header.isCompressed()) {
297 while (count-- && i < size) {
316 img = imageAlloc(header.width(), header.height(), header.format());
320 qWarning() <<
"Failed to allocate image, invalid dimensions?" <<
QSize(header.width(), header.height());
324 for (
int y = 0; y < header.height(); ++y) {
329 if (!readLine(s, buf, header)) {
334 unsigned int bpl = qMin((quint16)((header.width() + 7) / 8), header.BytesPerLine);
335 for (
unsigned int x = 0; x < bpl; ++x) {
342 img.
setColor(1, qRgb(255, 255, 255));
352 img = imageAlloc(header.width(), header.height(), header.format());
355 qWarning() <<
"Failed to allocate image, invalid dimensions?" <<
QSize(header.width(), header.height());
359 if (header.BytesPerLine < (header.width() + 7) / 8) {
360 qWarning() <<
"PCX image has invalid BytesPerLine value";
364 for (
int y = 0; y < header.height(); ++y) {
370 if (!readLine(s, buf, header)) {
374 for (
int i = 0; i < 4; i++) {
375 quint32 offset = i * header.BytesPerLine;
376 for (
int x = 0; x < header.width(); ++x) {
377 if (buf[offset + (x / 8)] & (128 >> (x % 8))) {
378 pixbuf[x] = (int)(pixbuf[x]) + (1 << i);
385 qWarning() <<
"Failed to get scanline for" << y <<
"might be out of bounds";
387 for (
int x = 0; x < header.width(); ++x) {
393 for (
int i = 0; i < 16; ++i) {
394 img.
setColor(i, header.ColorMap.color(i));
404 img = imageAlloc(header.width(), header.height(), header.format());
408 qWarning() <<
"Failed to allocate image, invalid dimensions?" <<
QSize(header.width(), header.height());
412 for (
int y = 0; y < header.height(); ++y) {
417 if (!readLine(s, buf, header)) {
426 const unsigned int bpl = std::min(header.BytesPerLine,
static_cast<quint16
>(header.width() / 2));
427 for (
unsigned int x = 0; x < bpl; ++x) {
428 p[x * 2] = (buf[x] & 240) >> 4;
429 p[x * 2 + 1] = buf[x] & 15;
434 for (
int i = 0; i < 16; ++i) {
435 img.
setColor(i, header.ColorMap.color(i));
445 img = imageAlloc(header.width(), header.height(), header.format());
449 qWarning() <<
"Failed to allocate image, invalid dimensions?" <<
QSize(header.width(), header.height());
453 for (
int y = 0; y < header.height(); ++y) {
458 if (!readLine(s, buf, header)) {
467 unsigned int bpl = qMin(header.BytesPerLine, (quint16)header.width());
468 for (
unsigned int x = 0; x < bpl; ++x) {
475 if (
auto device = s.
device()) {
476 if (device->isSequential()) {
482 device->seek(device->size() - 769);
488 if (flag == 12 && (header.Version == 5 || header.Version == 2)) {
493 for (
int i = 0; i < 256; ++i) {
508 img = imageAlloc(header.width(), header.height(), header.format());
511 qWarning() <<
"Failed to allocate image, invalid dimensions?" <<
QSize(header.width(), header.height());
515 const unsigned int bpl = std::min(header.BytesPerLine,
static_cast<quint16
>(header.width()));
517 for (
int y = 0; y < header.height(); ++y) {
522 if (!readLine(s, r_buf, header)) {
525 if (!readLine(s, g_buf, header)) {
528 if (!readLine(s, b_buf, header)) {
534 for (
unsigned int x = 0; x < bpl; ++x) {
535 p[x] = qRgb(r_buf[x], g_buf[x], b_buf[x]);
545 quint32 size = buf.
size();
554 while ((i < size) && (
byte == buf[i]) && (count < 63)) {
561 if (count > 1 || data >= 0xc0) {
579 auto rgb = img.
color(0);
580 auto minIsBlack = (qRed(rgb) + qGreen(rgb) + qBlue(rgb)) / 3 < 127;
585 if (header.BytesPerLine == 0) {
593 for (
int y = 0; y < header.height(); ++y) {
597 for (
int i = 0; i < header.BytesPerLine; ++i) {
598 buf[i] = minIsBlack ? p[i] : ~p[i];
601 if (!writeLine(s, buf)) {
612 header.BytesPerLine = header.width() / 8;
613 if (header.BytesPerLine == 0) {
617 for (
int i = 0; i < 16; ++i) {
618 header.ColorMap.setColor(i, img.
color(i));
625 for (
int i = 0; i < 4; ++i) {
626 buf[i].
resize(header.BytesPerLine);
629 for (
int y = 0; y < header.height(); ++y) {
632 for (
int i = 0; i < 4; ++i) {
636 for (
int x = 0; x < header.width(); ++x) {
637 for (
int i = 0; i < 4; ++i) {
638 if (*(p + x) & (1 << i)) {
639 buf[i][x / 8] = (int)(buf[i][x / 8]) | 1 << (7 - x % 8);
644 for (
int i = 0; i < 4; ++i) {
645 if (!writeLine(s, buf[i])) {
658 if (header.BytesPerLine == 0) {
666 for (
int y = 0; y < header.height(); ++y) {
669 for (
int i = 0; i < header.BytesPerLine; ++i) {
673 if (!writeLine(s, buf)) {
683 for (
int i = 0; i < 256; ++i) {
684 s << RGB::from(img.
color(i));
694 header.BytesPerLine = header.width();
695 if (header.BytesPerLine == 0) {
712 for (
int y = 0; y < header.height(); ++y) {
715 for (
int x = 0; x < header.width(); ++x) {
717 r_buf[x] = qRed(rgb);
718 g_buf[x] = qGreen(rgb);
719 b_buf[x] = qBlue(rgb);
722 if (!writeLine(s, r_buf)) {
725 if (!writeLine(s, g_buf)) {
728 if (!writeLine(s, b_buf)) {
736class PCXHandlerPrivate
739 PCXHandlerPrivate() {}
740 ~PCXHandlerPrivate() {}
745PCXHandler::PCXHandler()
747 , d(new PCXHandlerPrivate)
751bool PCXHandler::canRead()
const
753 if (canRead(device())) {
760bool PCXHandler::read(
QImage *outImage)
769 auto&& header = d->m_header;
776 if (!header.isSupported()) {
782 if (header.Bpp == 1 && header.NPlanes == 1) {
783 ok = readImage1(img, s, header);
784 }
else if (header.Bpp == 1 && header.NPlanes == 4) {
785 ok = readImage4(img, s, header);
786 }
else if (header.Bpp == 4 && header.NPlanes == 1) {
787 ok = readImage4v2(img, s, header);
788 }
else if (header.Bpp == 8 && header.NPlanes == 1) {
789 ok = readImage8(img, s, header);
790 }
else if (header.Bpp == 8 && header.NPlanes == 3) {
791 ok = readImage24(img, s, header);
794 if (img.
isNull() || !ok) {
804bool PCXHandler::write(
const QImage &image)
811 const int w = img.
width();
812 const int h = img.
height();
814 if (w > 65536 || h > 65536) {
820 header.Manufacturer = 10;
830 header.PaletteInfo = 1;
833 if (img.
depth() == 1) {
834 ok = writeImage1(img, s, header);
836 ok = writeImage4(img, s, header);
837 }
else if (img.
depth() == 8) {
838 ok = writeImage8(img, s, header);
839 }
else if (img.
depth() >= 24) {
840 ok = writeImage24(img, s, header);
846bool PCXHandler::supportsOption(ImageOption option)
const
857QVariant PCXHandler::option(ImageOption option)
const
862 auto&& header = d->m_header;
863 if (header.isSupported()) {
865 }
else if (
auto dev = device()) {
866 if (peekHeader(dev, header) && header.isSupported()) {
873 auto&& header = d->m_header;
874 if (header.isSupported()) {
876 }
else if (
auto dev = device()) {
877 if (peekHeader(dev, header) && header.isSupported()) {
886bool PCXHandler::canRead(
QIODevice *device)
889 qWarning(
"PCXHandler::canRead() called with no device");
894 if (!peekHeader(device, header)) {
897 return header.isSupported();
902 if (format ==
"pcx") {
913 if (device->
isReadable() && PCXHandler::canRead(device)) {
930#include "moc_pcx_p.cpp"
KCALENDARCORE_EXPORT QDataStream & operator>>(QDataStream &in, const KCalendarCore::Alarm::Ptr &)
QFlags< Capability > Capabilities
KTEXTEDITOR_EXPORT QDebug operator<<(QDebug s, const MovingCursor &cursor)
QByteArray & fill(char ch, qsizetype size)
bool isEmpty() const const
void resize(qsizetype newSize, char c)
qsizetype size() const const
QIODevice * device() const const
void setByteOrder(ByteOrder bo)
Status status() const const
qsizetype bytesPerLine() const const
QRgb color(int i) const const
int colorCount() const const
int dotsPerMeterX() const const
int dotsPerMeterY() const const
bool isNull() const const
void setColor(int index, QRgb colorValue)
void setColorCount(int colorCount)
void setDotsPerMeterX(int x)
void setDotsPerMeterY(int y)
void setDevice(QIODevice *device)
bool isOpen() const const
bool isReadable() const const
bool isWritable() const const
QByteArray peek(qint64 maxSize)
virtual qint64 size() const const
QVariant fromValue(T &&value)