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 == 1 && NPlanes == 3) {
97 }
else if (Bpp == 4 && NPlanes == 1) {
99 }
else if (Bpp == 2 && NPlanes == 1) {
101 }
else if (Bpp == 8 && NPlanes == 1) {
103 }
else if (Bpp == 8 && NPlanes == 3) {
105 }
else if (Bpp == 8 && NPlanes == 4) {
134 quint16 BytesPerLine;
165 for (
int i = 0; i < 16; ++i) {
178 s >> m >> ver >> enc >> bpp;
187 s >> xmin >> ymin >> xmax >> ymax;
200 s >> colorMap >> res >> np;
201 ph.ColorMap = colorMap;
204 quint16 bytesperline;
206 ph.BytesPerLine = bytesperline;
209 ph.PaletteInfo = paletteinfo;
213 ph.HScreenSize = hscreensize;
215 ph.VScreenSize = vscreensize;
218 for (
size_t i = 0, n =
sizeof(ph.unused); i < n; ++i) {
227 s << rgb.r << rgb.g << rgb.b;
234 for (
int i = 0; i < 16; ++i) {
243 s << ph.Manufacturer;
247 s << ph.XMin << ph.YMin << ph.XMax << ph.YMax;
248 s << ph.HDpi << ph.YDpi;
252 s << ph.BytesPerLine;
257 for (
size_t i = 0, n =
sizeof(ph.unused); i < n; ++i) {
264PCXHEADER::PCXHEADER()
273bool peekHeader(
QIODevice *d, PCXHEADER& h)
275 auto head = d->
peek(
sizeof(PCXHEADER));
276 if (
size_t(head.size()) <
sizeof(PCXHEADER)) {
290 quint32 size = buf.
size();
294 if (header.isCompressed()) {
303 while (count-- && i < size) {
322 img = imageAlloc(header.width(), header.height(), header.format());
326 qWarning() <<
"Failed to allocate image, invalid dimensions?" <<
QSize(header.width(), header.height());
330 for (
int y = 0; y < header.height(); ++y) {
335 if (!readLine(s, buf, header)) {
340 unsigned int bpl = qMin((quint16)((header.width() + 7) / 8), header.BytesPerLine);
341 for (
unsigned int x = 0; x < bpl; ++x) {
348 img.
setColor(1, qRgb(255, 255, 255));
355 QByteArray buf(header.BytesPerLine * header.NPlanes, 0);
358 img = imageAlloc(header.width(), header.height(), header.format());
361 qWarning() <<
"Failed to allocate image, invalid dimensions?" <<
QSize(header.width(), header.height());
365 if (header.BytesPerLine < (header.width() + 7) / 8) {
366 qWarning() <<
"PCX image has invalid BytesPerLine value";
370 for (
int y = 0; y < header.height(); ++y) {
376 if (!readLine(s, buf, header)) {
380 for (
int i = 0; i < header.NPlanes; i++) {
381 quint32 offset = i * header.BytesPerLine;
382 for (
int x = 0; x < header.width(); ++x) {
383 if (buf[offset + (x / 8)] & (128 >> (x % 8))) {
384 pixbuf[x] = (int)(pixbuf[x]) + (1 << i);
391 qWarning() <<
"Failed to get scanline for" << y <<
"might be out of bounds";
393 for (
int x = 0; x < header.width(); ++x) {
399 for (
int i = 0; i < 16; ++i) {
400 img.
setColor(i, header.ColorMap.color(i));
410 img = imageAlloc(header.width(), header.height(), header.format());
414 qWarning() <<
"Failed to allocate image, invalid dimensions?" <<
QSize(header.width(), header.height());
418 for (
int y = 0; y < header.height(); ++y) {
423 if (!readLine(s, buf, header)) {
432 const unsigned int bpl = std::min(header.BytesPerLine,
static_cast<quint16
>(header.width() / 4));
433 for (
unsigned int x = 0; x < bpl; ++x) {
434 p[x * 4] = (buf[x] >> 6) & 3;
435 p[x * 4 + 1] = (buf[x] >> 4) & 3;
436 p[x * 4 + 2] = (buf[x] >> 2) & 3;
437 p[x * 4 + 3] = buf[x] & 3;
442 for (
int i = 0; i < 4; ++i) {
443 img.
setColor(i, header.ColorMap.color(i));
453 img = imageAlloc(header.width(), header.height(), header.format());
457 qWarning() <<
"Failed to allocate image, invalid dimensions?" <<
QSize(header.width(), header.height());
461 for (
int y = 0; y < header.height(); ++y) {
466 if (!readLine(s, buf, header)) {
475 const unsigned int bpl = std::min(header.BytesPerLine,
static_cast<quint16
>(header.width() / 2));
476 for (
unsigned int x = 0; x < bpl; ++x) {
477 p[x * 2] = (buf[x] & 240) >> 4;
478 p[x * 2 + 1] = buf[x] & 15;
483 for (
int i = 0; i < 16; ++i) {
484 img.
setColor(i, header.ColorMap.color(i));
494 img = imageAlloc(header.width(), header.height(), header.format());
498 qWarning() <<
"Failed to allocate image, invalid dimensions?" <<
QSize(header.width(), header.height());
502 for (
int y = 0; y < header.height(); ++y) {
507 if (!readLine(s, buf, header)) {
516 unsigned int bpl = qMin(header.BytesPerLine, (quint16)header.width());
517 for (
unsigned int x = 0; x < bpl; ++x) {
524 if (
auto device = s.
device()) {
525 if (device->isSequential()) {
531 device->seek(device->size() - 769);
537 if (flag == 12 && (header.Version == 5 || header.Version == 2)) {
542 for (
int i = 0; i < 256; ++i) {
556 QByteArray a_buf(header.BytesPerLine,
char(0xFF));
558 img = imageAlloc(header.width(), header.height(), header.format());
561 qWarning() <<
"Failed to allocate image, invalid dimensions?" <<
QSize(header.width(), header.height());
565 const unsigned int bpl = std::min(header.BytesPerLine,
static_cast<quint16
>(header.width()));
567 for (
int y = 0; y < header.height(); ++y) {
572 if (!readLine(s, r_buf, header)) {
575 if (!readLine(s, g_buf, header)) {
578 if (!readLine(s, b_buf, header)) {
581 if (header.NPlanes == 4 && !readLine(s, a_buf, header)) {
585 auto p =
reinterpret_cast<QRgb *
>(img.
scanLine(y));
586 for (
unsigned int x = 0; x < bpl; ++x) {
587 p[x] = qRgba(r_buf[x], g_buf[x], b_buf[x], a_buf[x]);
597 quint32 size = buf.
size();
606 while ((i < size) && (
byte == buf[i]) && (count < 63)) {
613 if (count > 1 || data >= 0xc0) {
631 auto rgb = img.
color(0);
632 auto minIsBlack = (qRed(rgb) + qGreen(rgb) + qBlue(rgb)) / 3 < 127;
637 if (header.BytesPerLine == 0) {
645 for (
int y = 0; y < header.height(); ++y) {
649 for (
int i = 0; i < header.BytesPerLine; ++i) {
650 buf[i] = minIsBlack ? p[i] : ~p[i];
653 if (!writeLine(s, buf)) {
664 header.BytesPerLine = header.width() / 8;
665 if (header.BytesPerLine == 0) {
669 for (
int i = 0; i < 16; ++i) {
670 header.ColorMap.setColor(i, img.
color(i));
677 for (
int i = 0; i < 4; ++i) {
678 buf[i].
resize(header.BytesPerLine);
681 for (
int y = 0; y < header.height(); ++y) {
684 for (
int i = 0; i < 4; ++i) {
688 for (
int x = 0; x < header.width(); ++x) {
689 for (
int i = 0; i < 4; ++i) {
690 if (*(p + x) & (1 << i)) {
691 buf[i][x / 8] = (int)(buf[i][x / 8]) | 1 << (7 - x % 8);
696 for (
int i = 0; i < 4; ++i) {
697 if (!writeLine(s, buf[i])) {
717 if (header.BytesPerLine == 0) {
725 for (
int y = 0; y < header.height(); ++y) {
728 for (
int i = 0; i < header.BytesPerLine; ++i) {
732 if (!writeLine(s, buf)) {
742 for (
int i = 0; i < 256; ++i) {
744 s << RGB::from(qRgb(i, i, i));
746 s << RGB::from(img.
color(i));
756 header.NPlanes = hasAlpha ? 4 : 3;
757 header.BytesPerLine = header.width();
758 if (header.BytesPerLine == 0) {
776 for (
int y = 0; y < header.height(); ++y) {
777 auto p =
reinterpret_cast<const QRgb *
>(img.
constScanLine(y));
779 for (
int x = 0; x < header.width(); ++x) {
781 r_buf[x] = qRed(rgb);
782 g_buf[x] = qGreen(rgb);
783 b_buf[x] = qBlue(rgb);
784 a_buf[x] = qAlpha(rgb);
787 if (!writeLine(s, r_buf)) {
790 if (!writeLine(s, g_buf)) {
793 if (!writeLine(s, b_buf)) {
796 if (hasAlpha && !writeLine(s, a_buf)) {
804class PCXHandlerPrivate
807 PCXHandlerPrivate() {}
808 ~PCXHandlerPrivate() {}
813PCXHandler::PCXHandler()
815 , d(new PCXHandlerPrivate)
819bool PCXHandler::canRead()
const
821 if (canRead(device())) {
828bool PCXHandler::read(
QImage *outImage)
837 auto&& header = d->m_header;
844 if (!header.isSupported()) {
850 if (header.Bpp == 1 && header.NPlanes == 1) {
851 ok = readImage1(img, s, header);
852 }
else if (header.Bpp == 1 && (header.NPlanes == 4 || header.NPlanes == 3)) {
853 ok = readImage4(img, s, header);
854 }
else if (header.Bpp == 2 && header.NPlanes == 1) {
855 ok = readImage2(img, s, header);
856 }
else if (header.Bpp == 4 && header.NPlanes == 1) {
857 ok = readImage4v2(img, s, header);
858 }
else if (header.Bpp == 8 && header.NPlanes == 1) {
859 ok = readImage8(img, s, header);
860 }
else if (header.Bpp == 8 && (header.NPlanes == 3 || header.NPlanes == 4)) {
861 ok = readImage24(img, s, header);
864 if (img.
isNull() || !ok) {
874bool PCXHandler::write(
const QImage &image)
881 const int w = img.
width();
882 const int h = img.
height();
884 if (w > 65536 || h > 65536) {
890 header.Manufacturer = 10;
900 header.PaletteInfo = 1;
903 if (img.
depth() == 1) {
904 ok = writeImage1(img, s, header);
906 ok = writeImage4(img, s, header);
908 ok = writeImage8(img, s, header);
909 }
else if (img.
depth() >= 16) {
910 ok = writeImage24(img, s, header);
916bool PCXHandler::supportsOption(ImageOption option)
const
927QVariant PCXHandler::option(ImageOption option)
const
932 auto&& header = d->m_header;
933 if (header.isSupported()) {
935 }
else if (
auto dev = device()) {
936 if (peekHeader(dev, header) && header.isSupported()) {
943 auto&& header = d->m_header;
944 if (header.isSupported()) {
946 }
else if (
auto dev = device()) {
947 if (peekHeader(dev, header) && header.isSupported()) {
956bool PCXHandler::canRead(
QIODevice *device)
959 qWarning(
"PCXHandler::canRead() called with no device");
964 if (!peekHeader(device, header)) {
967 return header.isSupported();
972 if (format ==
"pcx") {
983 if (device->
isReadable() && PCXHandler::canRead(device)) {
1000#include "moc_pcx_p.cpp"
KCALENDARCORE_EXPORT QDataStream & operator>>(QDataStream &in, const KCalendarCore::Alarm::Ptr &)
QFlags< Capability > Capabilities
QDebug operator<<(QDebug dbg, const PerceptualColor::MultiSpinBoxSection &value)
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
const uchar * constScanLine(int i) const const
void convertTo(Format format, Qt::ImageConversionFlags flags)
int dotsPerMeterX() const const
int dotsPerMeterY() const const
bool hasAlphaChannel() 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)