111static bool read_pbm_body(QIODevice *device,
char type,
int w,
int h,
int mcc, QImage *outImage)
117 QImage::Format format;
122 format = QImage::Format_Mono;
127 format = QImage::Format_Grayscale8;
132 format = QImage::Format_RGB32;
139 if (!QImageIOHandler::allocateImage(QSize(w, h), format, outImage))
142 pbm_bpl = (qsizetype(w) * nbits + 7) / 8;
146 pbm_bpl = mcc < 256 ? 3*w : 6*w;
147 uchar *buf24 =
new uchar[pbm_bpl], *b;
150 for (y=0; y<h; y++) {
151 if (device->read((
char *)buf24, pbm_bpl) != pbm_bpl) {
155 p = (QRgb *)outImage->scanLine(y);
161 *p++ = qRgb(b[0],b[1],b[2]);
163 *p++ = scale_pbm_color(mcc, b[0], b[1], b[2]);
166 quint16 rv = b[0] << 8 | b[1];
167 quint16 gv = b[2] << 8 | b[3];
168 quint16 bv = b[4] << 8 | b[5];
170 *p++ = QRgba64::fromRgba64(rv, gv, bv, 0xffff).toArgb32();
172 *p++ = scale_pbm_color(mcc, rv, gv, bv);
178 }
else if (nbits == 8 && mcc > 255) {
180 uchar *buf16 =
new uchar[pbm_bpl];
181 for (y=0; y<h; y++) {
182 if (device->read((
char *)buf16, pbm_bpl) != pbm_bpl) {
186 uchar *p = outImage->scanLine(y);
190 *p++ = (b[0] << 8 | b[1]) * 255 / mcc;
196 for (y=0; y<h; y++) {
197 uchar *p = outImage->scanLine(y);
198 if (device->read((
char *)p, pbm_bpl) != pbm_bpl)
200 if (nbits == 8 && mcc < 255) {
201 for (qsizetype i = 0; i < pbm_bpl; i++)
202 p[i] = (p[i] * 255) / mcc;
210 for (y = 0; y < h && ok; y++) {
211 p = outImage->scanLine(y);
218 for (
int i=0; i<8; i++) {
222 b = (b << 1) | (0 & 1);
227 }
else if (nbits == 8) {
245 *((QRgb*)p) = qRgb(r, g, b);
253 *((QRgb*)p) = scale_pbm_color(mcc, r, g, b);
263 if (format == QImage::Format_Mono) {
264 outImage->setColorCount(2);
265 outImage->setColor(0, qRgb(255,255,255));
266 outImage->setColor(1, qRgb(0,0,0));
272static bool write_pbm_image(QIODevice *out,
const QImage &sourceImage, QByteArrayView sourceFormat)
275 QImage image = sourceImage;
276 const QByteArrayView format = sourceFormat.left(3);
278 bool gray = format ==
"pgm";
280 if (format ==
"pbm") {
281 image = image.convertToFormat(QImage::Format_Mono);
283 image = image.convertToFormat(QImage::Format_Grayscale8);
285 switch (image.format()) {
286 case QImage::Format_Mono:
287 case QImage::Format_MonoLSB:
288 image = image.convertToFormat(QImage::Format_Indexed8);
290 case QImage::Format_Indexed8:
291 case QImage::Format_RGB32:
292 case QImage::Format_ARGB32:
295 if (image.hasAlphaChannel())
296 image = image.convertToFormat(QImage::Format_ARGB32);
298 image = image.convertToFormat(QImage::Format_RGB32);
303 if (image.depth() == 1 && image.colorCount() == 2) {
304 if (qGray(image.color(0)) < qGray(image.color(1))) {
307 for (
int y=0; y<image.height(); y++) {
308 uchar *p = image.scanLine(y);
309 uchar *end = p + image.bytesPerLine();
316 uint w = image.width();
317 uint h = image.height();
320 str += QByteArray::number(w);
322 str += QByteArray::number(h);
325 switch (image.depth()) {
328 if (out->write(str, str.size()) != str.size())
331 for (uint y=0; y<h; y++) {
332 uchar* line = image.scanLine(y);
333 if (w != (uint)out->write((
char*)line, w))
340 str.insert(1, gray ?
'5' :
'6');
342 if (out->write(str, str.size()) != str.size())
344 qsizetype bpl = qsizetype(w) * (gray ? 1 : 3);
345 uchar *buf =
new uchar[bpl];
346 if (image.format() == QImage::Format_Indexed8) {
347 const QList<QRgb> color = image.colorTable();
348 for (uint y=0; y<h; y++) {
349 const uchar *b = image.constScanLine(y);
351 uchar *end = buf+bpl;
354 uchar g = (uchar)qGray(color[*b++]);
359 QRgb rgb = color[*b++];
365 if (bpl != (qsizetype)out->write((
char*)buf, bpl))
369 for (uint y=0; y<h; y++) {
370 const uchar *b = image.constScanLine(y);
372 uchar *end = buf + bpl;
384 if (bpl != (qsizetype)out->write((
char*)buf, bpl))
395 if (out->write(str, str.size()) != str.size())
397 qsizetype bpl = qsizetype(w) * 3;
398 uchar *buf =
new uchar[bpl];
399 for (uint y=0; y<h; y++) {
400 const QRgb *b =
reinterpret_cast<
const QRgb *>(image.constScanLine(y));
402 uchar *end = buf+bpl;
409 if (bpl != (qsizetype)out->write((
char*)buf, bpl))
431 if (!read_pbm_header(device(), type, width, height, mcc))
479bool QPpmHandler::read(QImage *image)
484 if (state == Ready && !readHeader()) {
489 if (!read_pbm_body(device(), type, width, height, mcc, image)) {
510QVariant QPpmHandler::option(ImageOption option)
const
512 if (option == SubType) {
514 }
else if (option == Size) {
517 if (state == Ready && !
const_cast<QPpmHandler*>(
this)->readHeader())
519 return QSize(width, height);
520 }
else if (option == ImageFormat) {
523 if (state == Ready && !
const_cast<QPpmHandler*>(
this)->readHeader())
525 QImage::Format format = QImage::Format_Invalid;
529 format = QImage::Format_Mono;
533 format = QImage::Format_Grayscale8;
537 format = QImage::Format_RGB32;