Qt 4.8
Functions | Variables
qbmphandler.cpp File Reference
#include "private/qbmphandler_p.h"
#include <qimage.h>
#include <qvariant.h>
#include <qvector.h>

Go to the source code of this file.

Functions

static int calc_shift (uint mask)
 
static QDataStreamoperator<< (QDataStream &s, const BMP_FILEHDR &bf)
 
static QDataStreamoperator<< (QDataStream &s, const BMP_INFOHDR &bi)
 
static QDataStreamoperator>> (QDataStream &s, BMP_FILEHDR &bf)
 
static QDataStreamoperator>> (QDataStream &s, BMP_INFOHDR &bi)
 
bool qt_read_dib (QDataStream &s, QImage &image)
 
bool qt_write_dib (QDataStream &s, QImage image)
 
static bool read_dib_body (QDataStream &s, const BMP_INFOHDR &bi, int offset, int startpos, QImage &image)
 
static bool read_dib_fileheader (QDataStream &s, BMP_FILEHDR &bf)
 
static bool read_dib_infoheader (QDataStream &s, BMP_INFOHDR &bi)
 
static void swapPixel01 (QImage *image)
 

Variables

const int BMP_BITFIELDS = 3
 
const int BMP_FILEHDR_SIZE = 14
 
const int BMP_OLD = 12
 
const int BMP_OS2 = 64
 
const int BMP_RGB = 0
 
const int BMP_RLE4 = 2
 
const int BMP_RLE8 = 1
 
const int BMP_WIN = 40
 
const int BMP_WIN4 = 108
 
const int BMP_WIN5 = 124
 

Function Documentation

◆ calc_shift()

static int calc_shift ( uint  mask)
static

Definition at line 146 of file qbmphandler.cpp.

Referenced by read_dib_body().

147 {
148  int result = 0;
149  while (mask && !(mask & 1)) {
150  result++;
151  mask >>= 1;
152  }
153  return result;
154 }

◆ operator<<() [1/2]

static QDataStream& operator<< ( QDataStream s,
const BMP_FILEHDR bf 
)
static

Definition at line 91 of file qbmphandler.cpp.

92 { // write file header
93  s.writeRawData(bf.bfType, 2);
94  s << bf.bfSize << bf.bfReserved1 << bf.bfReserved2 << bf.bfOffBits;
95  return s;
96 }
qint32 bfOffBits
Definition: qbmphandler_p.h:67
char bfType[2]
Definition: qbmphandler_p.h:63
qint32 bfSize
Definition: qbmphandler_p.h:64
qint16 bfReserved1
Definition: qbmphandler_p.h:65
qint16 bfReserved2
Definition: qbmphandler_p.h:66
int writeRawData(const char *, int len)
Writes len bytes from s to the stream.

◆ operator<<() [2/2]

static QDataStream& operator<< ( QDataStream s,
const BMP_INFOHDR bi 
)
static

Definition at line 133 of file qbmphandler.cpp.

134 {
135  s << bi.biSize;
136  s << bi.biWidth << bi.biHeight;
137  s << bi.biPlanes;
138  s << bi.biBitCount;
139  s << bi.biCompression;
140  s << bi.biSizeImage;
141  s << bi.biXPelsPerMeter << bi.biYPelsPerMeter;
142  s << bi.biClrUsed << bi.biClrImportant;
143  return s;
144 }
qint32 biSize
Definition: qbmphandler_p.h:71
qint32 biSizeImage
Definition: qbmphandler_p.h:77
qint32 biClrUsed
Definition: qbmphandler_p.h:80
qint32 biWidth
Definition: qbmphandler_p.h:72
qint32 biYPelsPerMeter
Definition: qbmphandler_p.h:79
qint16 biBitCount
Definition: qbmphandler_p.h:75
qint32 biCompression
Definition: qbmphandler_p.h:76
qint32 biClrImportant
Definition: qbmphandler_p.h:81
qint32 biXPelsPerMeter
Definition: qbmphandler_p.h:78
qint16 biPlanes
Definition: qbmphandler_p.h:74
qint32 biHeight
Definition: qbmphandler_p.h:73

◆ operator>>() [1/2]

static QDataStream& operator>> ( QDataStream s,
BMP_FILEHDR bf 
)
static

Definition at line 84 of file qbmphandler.cpp.

85 { // read file header
86  s.readRawData(bf.bfType, 2);
87  s >> bf.bfSize >> bf.bfReserved1 >> bf.bfReserved2 >> bf.bfOffBits;
88  return s;
89 }
qint32 bfOffBits
Definition: qbmphandler_p.h:67
char bfType[2]
Definition: qbmphandler_p.h:63
qint32 bfSize
Definition: qbmphandler_p.h:64
int readRawData(char *, int len)
Reads at most len bytes from the stream into s and returns the number of bytes read.
qint16 bfReserved1
Definition: qbmphandler_p.h:65
qint16 bfReserved2
Definition: qbmphandler_p.h:66

◆ operator>>() [2/2]

static QDataStream& operator>> ( QDataStream s,
BMP_INFOHDR bi 
)
static

Definition at line 111 of file qbmphandler.cpp.

112 {
113  s >> bi.biSize;
114  if (bi.biSize == BMP_WIN || bi.biSize == BMP_OS2 || bi.biSize == BMP_WIN4 || bi.biSize == BMP_WIN5) {
115  s >> bi.biWidth >> bi.biHeight >> bi.biPlanes >> bi.biBitCount;
116  s >> bi.biCompression >> bi.biSizeImage;
117  s >> bi.biXPelsPerMeter >> bi.biYPelsPerMeter;
118  s >> bi.biClrUsed >> bi.biClrImportant;
119  }
120  else { // probably old Windows format
121  qint16 w, h;
122  s >> w >> h >> bi.biPlanes >> bi.biBitCount;
123  bi.biWidth = w;
124  bi.biHeight = h;
125  bi.biCompression = BMP_RGB; // no compression
126  bi.biSizeImage = 0;
127  bi.biXPelsPerMeter = bi.biYPelsPerMeter = 0;
128  bi.biClrUsed = bi.biClrImportant = 0;
129  }
130  return s;
131 }
const int BMP_WIN
qint32 biSize
Definition: qbmphandler_p.h:71
qint32 biSizeImage
Definition: qbmphandler_p.h:77
qint32 biClrUsed
Definition: qbmphandler_p.h:80
qint32 biWidth
Definition: qbmphandler_p.h:72
const int BMP_RGB
qint32 biYPelsPerMeter
Definition: qbmphandler_p.h:79
short qint16
Definition: qglobal.h:935
qint16 biBitCount
Definition: qbmphandler_p.h:75
const int BMP_OS2
qint32 biCompression
Definition: qbmphandler_p.h:76
const int BMP_WIN4
const int BMP_WIN5
qint32 biClrImportant
Definition: qbmphandler_p.h:81
qint32 biXPelsPerMeter
Definition: qbmphandler_p.h:78
qint16 biPlanes
Definition: qbmphandler_p.h:74
qint32 biHeight
Definition: qbmphandler_p.h:73

◆ qt_read_dib()

bool qt_read_dib ( QDataStream s,
QImage image 
)

Definition at line 685 of file qbmphandler.cpp.

Referenced by QWindowsMimeImage::convertToMime().

686 {
687  BMP_INFOHDR bi;
688  if (!read_dib_infoheader(s, bi))
689  return false;
690  return read_dib_body(s, bi, -1, -BMP_FILEHDR_SIZE, image);
691 }
static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int startpos, QImage &image)
const int BMP_FILEHDR_SIZE
Definition: qbmphandler.cpp:82
static bool read_dib_infoheader(QDataStream &s, BMP_INFOHDR &bi)

◆ qt_write_dib()

bool qt_write_dib ( QDataStream s,
QImage  image 
)

Definition at line 565 of file qbmphandler.cpp.

Referenced by QWindowsMimeImage::convertFromMime(), and QBmpHandler::write().

566 {
567  int nbits;
568  int bpl_bmp;
569  int bpl = image.bytesPerLine();
570 
571  QIODevice* d = s.device();
572  if (!d->isWritable())
573  return false;
574 
575  if (image.depth() == 8 && image.colorCount() <= 16) {
576  bpl_bmp = (((bpl+1)/2+3)/4)*4;
577  nbits = 4;
578  } else if (image.depth() == 32) {
579  bpl_bmp = ((image.width()*24+31)/32)*4;
580  nbits = 24;
581 #ifdef Q_WS_QWS
582  } else if (image.depth() == 1 || image.depth() == 8) {
583  // Qt for Embedded Linux doesn't word align.
584  bpl_bmp = ((image.width()*image.depth()+31)/32)*4;
585  nbits = image.depth();
586 #endif
587  } else {
588  bpl_bmp = bpl;
589  nbits = image.depth();
590  }
591 
592  BMP_INFOHDR bi;
593  bi.biSize = BMP_WIN; // build info header
594  bi.biWidth = image.width();
595  bi.biHeight = image.height();
596  bi.biPlanes = 1;
597  bi.biBitCount = nbits;
598  bi.biCompression = BMP_RGB;
599  bi.biSizeImage = bpl_bmp*image.height();
600  bi.biXPelsPerMeter = image.dotsPerMeterX() ? image.dotsPerMeterX()
601  : 2834; // 72 dpi default
602  bi.biYPelsPerMeter = image.dotsPerMeterY() ? image.dotsPerMeterY() : 2834;
603  bi.biClrUsed = image.colorCount();
604  bi.biClrImportant = image.colorCount();
605  s << bi; // write info header
606  if (s.status() != QDataStream::Ok)
607  return false;
608 
609  if (image.depth() != 32) { // write color table
610  uchar *color_table = new uchar[4*image.colorCount()];
611  uchar *rgb = color_table;
612  QVector<QRgb> c = image.colorTable();
613  for (int i=0; i<image.colorCount(); i++) {
614  *rgb++ = qBlue (c[i]);
615  *rgb++ = qGreen(c[i]);
616  *rgb++ = qRed (c[i]);
617  *rgb++ = 0;
618  }
619  if (d->write((char *)color_table, 4*image.colorCount()) == -1) {
620  delete [] color_table;
621  return false;
622  }
623  delete [] color_table;
624  }
625 
626  if (image.format() == QImage::Format_MonoLSB)
627  image = image.convertToFormat(QImage::Format_Mono);
628 
629  int y;
630 
631  if (nbits == 1 || nbits == 8) { // direct output
632 #ifdef Q_WS_QWS
633  // Qt for Embedded Linux doesn't word align.
634  int pad = bpl_bmp - bpl;
635  char padding[4];
636 #endif
637  for (y=image.height()-1; y>=0; y--) {
638  if (d->write((char*)image.scanLine(y), bpl) == -1)
639  return false;
640 #ifdef Q_WS_QWS
641  if (d->write(padding, pad) == -1)
642  return false;
643 #endif
644  }
645  return true;
646  }
647 
648  uchar *buf = new uchar[bpl_bmp];
649  uchar *b, *end;
650  register uchar *p;
651 
652  memset(buf, 0, bpl_bmp);
653  for (y=image.height()-1; y>=0; y--) { // write the image bits
654  if (nbits == 4) { // convert 8 -> 4 bits
655  p = image.scanLine(y);
656  b = buf;
657  end = b + image.width()/2;
658  while (b < end) {
659  *b++ = (*p << 4) | (*(p+1) & 0x0f);
660  p += 2;
661  }
662  if (image.width() & 1)
663  *b = *p << 4;
664  } else { // 32 bits
665  QRgb *p = (QRgb *)image.scanLine(y);
666  QRgb *end = p + image.width();
667  b = buf;
668  while (p < end) {
669  *b++ = qBlue(*p);
670  *b++ = qGreen(*p);
671  *b++ = qRed(*p);
672  p++;
673  }
674  }
675  if (bpl_bmp != d->write((char*)buf, bpl_bmp)) {
676  delete[] buf;
677  return false;
678  }
679  }
680  delete[] buf;
681  return true;
682 }
double d
Definition: qnumeric_p.h:62
Status status() const
Returns the status of the data stream.
const int BMP_WIN
unsigned int QRgb
Definition: qrgb.h:53
unsigned char c[8]
Definition: qnumeric_p.h:62
bool isWritable() const
Returns true if data can be written to the device; otherwise returns false.
Definition: qiodevice.cpp:558
qint32 biSize
Definition: qbmphandler_p.h:71
int bytesPerLine() const
Returns the number of bytes per image scanline.
Definition: qimage.cpp:1812
int dotsPerMeterY() const
Returns the number of pixels that fit vertically in a physical meter.
Definition: qimage.cpp:5628
int qRed(QRgb rgb)
Returns the red component of the ARGB quadruplet rgb.
Definition: qrgb.h:57
Format format() const
Returns the format of the image.
Definition: qimage.cpp:2305
qint32 biSizeImage
Definition: qbmphandler_p.h:77
qint32 biClrUsed
Definition: qbmphandler_p.h:80
qint32 biWidth
Definition: qbmphandler_p.h:72
const int BMP_RGB
unsigned char uchar
Definition: qglobal.h:994
qint32 biYPelsPerMeter
Definition: qbmphandler_p.h:79
int depth() const
Returns the depth of the image.
Definition: qimage.cpp:1620
qint16 biBitCount
Definition: qbmphandler_p.h:75
#define rgb(r, g, b)
Definition: qcolor_p.cpp:130
int width() const
Returns the width of the image.
Definition: qimage.cpp:1557
QImage convertToFormat(Format f, Qt::ImageConversionFlags flags=Qt::AutoColor) const Q_REQUIRED_RESULT
Returns a copy of the image in the given format.
Definition: qimage.cpp:3966
QIODevice * device() const
Returns the I/O device currently set, or 0 if no device is currently set.
Definition: qdatastream.h:206
int colorCount() const
Returns the size of the color table for the image.
Definition: qimage.cpp:1656
qint32 biCompression
Definition: qbmphandler_p.h:76
int height() const
Returns the height of the image.
Definition: qimage.cpp:1572
qint32 biClrImportant
Definition: qbmphandler_p.h:81
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
Definition: qiodevice.cpp:1342
int qGreen(QRgb rgb)
Returns the green component of the ARGB quadruplet rgb.
Definition: qrgb.h:60
int qBlue(QRgb rgb)
Returns the blue component of the ARGB quadruplet rgb.
Definition: qrgb.h:63
static const KeyPair *const end
The QIODevice class is the base interface class of all I/O devices in Qt.
Definition: qiodevice.h:66
qint32 biXPelsPerMeter
Definition: qbmphandler_p.h:78
int dotsPerMeterX() const
Returns the number of pixels that fit horizontally in a physical meter.
Definition: qimage.cpp:5615
QVector< QRgb > colorTable() const
Returns a list of the colors contained in the image&#39;s color table, or an empty list if the image does...
Definition: qimage.cpp:1770
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
Definition: qimage.cpp:1886
qint16 biPlanes
Definition: qbmphandler_p.h:74
qint32 biHeight
Definition: qbmphandler_p.h:73

◆ read_dib_body()

static bool read_dib_body ( QDataStream s,
const BMP_INFOHDR bi,
int  offset,
int  startpos,
QImage image 
)
static

Definition at line 188 of file qbmphandler.cpp.

Referenced by qt_read_dib(), and QBmpHandler::read().

189 {
190  QIODevice* d = s.device();
191  if (d->atEnd()) // end of stream/file
192  return false;
193 #if 0
194  qDebug("offset...........%d", offset);
195  qDebug("startpos.........%d", startpos);
196  qDebug("biSize...........%d", bi.biSize);
197  qDebug("biWidth..........%d", bi.biWidth);
198  qDebug("biHeight.........%d", bi.biHeight);
199  qDebug("biPlanes.........%d", bi.biPlanes);
200  qDebug("biBitCount.......%d", bi.biBitCount);
201  qDebug("biCompression....%d", bi.biCompression);
202  qDebug("biSizeImage......%d", bi.biSizeImage);
203  qDebug("biXPelsPerMeter..%d", bi.biXPelsPerMeter);
204  qDebug("biYPelsPerMeter..%d", bi.biYPelsPerMeter);
205  qDebug("biClrUsed........%d", bi.biClrUsed);
206  qDebug("biClrImportant...%d", bi.biClrImportant);
207 #endif
208  int w = bi.biWidth, h = bi.biHeight, nbits = bi.biBitCount;
209  int t = bi.biSize, comp = bi.biCompression;
210  uint red_mask = 0;
211  uint green_mask = 0;
212  uint blue_mask = 0;
213  int red_shift = 0;
214  int green_shift = 0;
215  int blue_shift = 0;
216  int red_scale = 0;
217  int green_scale = 0;
218  int blue_scale = 0;
219 
220  int ncols = 0;
221  int depth = 0;
223  switch (nbits) {
224  case 32:
225  case 24:
226  case 16:
227  depth = 32;
228  format = QImage::Format_RGB32;
229  break;
230  case 8:
231  case 4:
232  depth = 8;
233  format = QImage::Format_Indexed8;
234  break;
235  default:
236  depth = 1;
237  format = QImage::Format_Mono;
238  }
239 
240  if (bi.biHeight < 0)
241  h = -h; // support images with negative height
242 
243  if (image.size() != QSize(w, h) || image.format() != format) {
244  image = QImage(w, h, format);
245  if (image.isNull()) // could not create image
246  return false;
247  }
248 
249  if (depth != 32) {
250  ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits;
251  if (ncols > 256) // sanity check - don't run out of mem if color table is broken
252  return false;
253  image.setColorCount(ncols);
254  }
255 
258 
259  if (!d->isSequential())
260  d->seek(startpos + BMP_FILEHDR_SIZE + (bi.biSize >= BMP_WIN4? BMP_WIN : bi.biSize)); // goto start of colormap
261 
262  if (bi.biSize >= BMP_WIN4 || (comp == BMP_BITFIELDS && (nbits == 16 || nbits == 32))) {
263  if (d->read((char *)&red_mask, sizeof(red_mask)) != sizeof(red_mask))
264  return false;
265  if (d->read((char *)&green_mask, sizeof(green_mask)) != sizeof(green_mask))
266  return false;
267  if (d->read((char *)&blue_mask, sizeof(blue_mask)) != sizeof(blue_mask))
268  return false;
269 
270  // Read BMP v4+ header
271  if (bi.biSize >= BMP_WIN4) {
272  int alpha_mask = 0;
273  int CSType = 0;
274  int gamma_red = 0;
275  int gamma_green = 0;
276  int gamma_blue = 0;
277  int endpoints[9];
278 
279  if (d->read((char *)&alpha_mask, sizeof(alpha_mask)) != sizeof(alpha_mask))
280  return false;
281  if (d->read((char *)&CSType, sizeof(CSType)) != sizeof(CSType))
282  return false;
283  if (d->read((char *)&endpoints, sizeof(endpoints)) != sizeof(endpoints))
284  return false;
285  if (d->read((char *)&gamma_red, sizeof(gamma_red)) != sizeof(gamma_red))
286  return false;
287  if (d->read((char *)&gamma_green, sizeof(gamma_green)) != sizeof(gamma_green))
288  return false;
289  if (d->read((char *)&gamma_blue, sizeof(gamma_blue)) != sizeof(gamma_blue))
290  return false;
291 
292  if (bi.biSize == BMP_WIN5) {
293  qint32 intent = 0;
294  qint32 profileData = 0;
295  qint32 profileSize = 0;
296  qint32 reserved = 0;
297 
298  if (d->read((char *)&intent, sizeof(intent)) != sizeof(intent))
299  return false;
300  if (d->read((char *)&profileData, sizeof(profileData)) != sizeof(profileData))
301  return false;
302  if (d->read((char *)&profileSize, sizeof(profileSize)) != sizeof(profileSize))
303  return false;
304  if (d->read((char *)&reserved, sizeof(reserved)) != sizeof(reserved) || reserved != 0)
305  return false;
306  }
307  }
308  }
309 
310  if (ncols > 0) { // read color table
311  uchar rgb[4];
312  int rgb_len = t == BMP_OLD ? 3 : 4;
313  for (int i=0; i<ncols; i++) {
314  if (d->read((char *)rgb, rgb_len) != rgb_len)
315  return false;
316  image.setColor(i, qRgb(rgb[2],rgb[1],rgb[0]));
317  if (d->atEnd()) // truncated file
318  return false;
319  }
320  } else if (comp == BMP_BITFIELDS && (nbits == 16 || nbits == 32)) {
321  red_shift = calc_shift(red_mask);
322  red_scale = 256 / ((red_mask >> red_shift) + 1);
323  green_shift = calc_shift(green_mask);
324  green_scale = 256 / ((green_mask >> green_shift) + 1);
325  blue_shift = calc_shift(blue_mask);
326  blue_scale = 256 / ((blue_mask >> blue_shift) + 1);
327  } else if (comp == BMP_RGB && (nbits == 24 || nbits == 32)) {
328  blue_mask = 0x000000ff;
329  green_mask = 0x0000ff00;
330  red_mask = 0x00ff0000;
331  blue_shift = 0;
332  green_shift = 8;
333  red_shift = 16;
334  blue_scale = green_scale = red_scale = 1;
335  } else if (comp == BMP_RGB && nbits == 16) {
336  blue_mask = 0x001f;
337  green_mask = 0x03e0;
338  red_mask = 0x7c00;
339  blue_shift = 0;
340  green_shift = 2;
341  red_shift = 7;
342  red_scale = 1;
343  green_scale = 1;
344  blue_scale = 8;
345  }
346 
347  // offset can be bogus, be careful
348  if (offset>=0 && startpos + offset > d->pos()) {
349  if (!d->isSequential())
350  d->seek(startpos + offset); // start of image data
351  }
352 
353  int bpl = image.bytesPerLine();
354  uchar *data = image.bits();
355 
356  if (nbits == 1) { // 1 bit BMP image
357  while (--h >= 0) {
358  if (d->read((char*)(data + h*bpl), bpl) != bpl)
359  break;
360  }
361  if (ncols == 2 && qGray(image.color(0)) < qGray(image.color(1)))
362  swapPixel01(&image); // pixel 0 is white!
363  }
364 
365  else if (nbits == 4) { // 4 bit BMP image
366  int buflen = ((w+7)/8)*4;
367  uchar *buf = new uchar[buflen];
368  if (comp == BMP_RLE4) { // run length compression
369  int x=0, y=0, c, i;
370  quint8 b;
371  register uchar *p = data + (h-1)*bpl;
372  const uchar *endp = p + w;
373  while (y < h) {
374  if (!d->getChar((char *)&b))
375  break;
376  if (b == 0) { // escape code
377  if (!d->getChar((char *)&b) || b == 1) {
378  y = h; // exit loop
379  } else switch (b) {
380  case 0: // end of line
381  x = 0;
382  y++;
383  p = data + (h-y-1)*bpl;
384  break;
385  case 2: // delta (jump)
386  {
387  quint8 tmp;
388  d->getChar((char *)&tmp);
389  x += tmp;
390  d->getChar((char *)&tmp);
391  y += tmp;
392  }
393 
394  // Protection
395  if ((uint)x >= (uint)w)
396  x = w-1;
397  if ((uint)y >= (uint)h)
398  y = h-1;
399 
400  p = data + (h-y-1)*bpl + x;
401  break;
402  default: // absolute mode
403  // Protection
404  if (p + b > endp)
405  b = endp-p;
406 
407  i = (c = b)/2;
408  while (i--) {
409  d->getChar((char *)&b);
410  *p++ = b >> 4;
411  *p++ = b & 0x0f;
412  }
413  if (c & 1) {
414  unsigned char tmp;
415  d->getChar((char *)&tmp);
416  *p++ = tmp >> 4;
417  }
418  if ((((c & 3) + 1) & 2) == 2)
419  d->getChar(0); // align on word boundary
420  x += c;
421  }
422  } else { // encoded mode
423  // Protection
424  if (p + b > endp)
425  b = endp-p;
426 
427  i = (c = b)/2;
428  d->getChar((char *)&b); // 2 pixels to be repeated
429  while (i--) {
430  *p++ = b >> 4;
431  *p++ = b & 0x0f;
432  }
433  if (c & 1)
434  *p++ = b >> 4;
435  x += c;
436  }
437  }
438  } else if (comp == BMP_RGB) { // no compression
439  memset(data, 0, h*bpl);
440  while (--h >= 0) {
441  if (d->read((char*)buf,buflen) != buflen)
442  break;
443  register uchar *p = data + h*bpl;
444  uchar *b = buf;
445  for (int i=0; i<w/2; i++) { // convert nibbles to bytes
446  *p++ = *b >> 4;
447  *p++ = *b++ & 0x0f;
448  }
449  if (w & 1) // the last nibble
450  *p = *b >> 4;
451  }
452  }
453  delete [] buf;
454  }
455 
456  else if (nbits == 8) { // 8 bit BMP image
457  if (comp == BMP_RLE8) { // run length compression
458  int x=0, y=0;
459  quint8 b;
460  register uchar *p = data + (h-1)*bpl;
461  const uchar *endp = p + w;
462  while (y < h) {
463  if (!d->getChar((char *)&b))
464  break;
465  if (b == 0) { // escape code
466  if (!d->getChar((char *)&b) || b == 1) {
467  y = h; // exit loop
468  } else switch (b) {
469  case 0: // end of line
470  x = 0;
471  y++;
472  p = data + (h-y-1)*bpl;
473  break;
474  case 2: // delta (jump)
475  // Protection
476  if ((uint)x >= (uint)w)
477  x = w-1;
478  if ((uint)y >= (uint)h)
479  y = h-1;
480 
481  {
482  quint8 tmp;
483  d->getChar((char *)&tmp);
484  x += tmp;
485  d->getChar((char *)&tmp);
486  y += tmp;
487  }
488  p = data + (h-y-1)*bpl + x;
489  break;
490  default: // absolute mode
491  // Protection
492  if (p + b > endp)
493  b = endp-p;
494 
495  if (d->read((char *)p, b) != b)
496  return false;
497  if ((b & 1) == 1)
498  d->getChar(0); // align on word boundary
499  x += b;
500  p += b;
501  }
502  } else { // encoded mode
503  // Protection
504  if (p + b > endp)
505  b = endp-p;
506 
507  char tmp;
508  d->getChar(&tmp);
509  memset(p, tmp, b); // repeat pixel
510  x += b;
511  p += b;
512  }
513  }
514  } else if (comp == BMP_RGB) { // uncompressed
515  while (--h >= 0) {
516  if (d->read((char *)data + h*bpl, bpl) != bpl)
517  break;
518  }
519  }
520  }
521 
522  else if (nbits == 16 || nbits == 24 || nbits == 32) { // 16,24,32 bit BMP image
523  register QRgb *p;
524  QRgb *end;
525  uchar *buf24 = new uchar[bpl];
526  int bpl24 = ((w*nbits+31)/32)*4;
527  uchar *b;
528  int c;
529 
530  while (--h >= 0) {
531  p = (QRgb *)(data + h*bpl);
532  end = p + w;
533  if (d->read((char *)buf24,bpl24) != bpl24)
534  break;
535  b = buf24;
536  while (p < end) {
537  c = *(uchar*)b | (*(uchar*)(b+1)<<8);
538  if (nbits != 16)
539  c |= *(uchar*)(b+2)<<16;
540  *p++ = qRgb(((c & red_mask) >> red_shift) * red_scale,
541  ((c & green_mask) >> green_shift) * green_scale,
542  ((c & blue_mask) >> blue_shift) * blue_scale);
543  b += nbits/8;
544  }
545  }
546  delete[] buf24;
547  }
548 
549  if (bi.biHeight < 0) {
550  // Flip the image
551  uchar *buf = new uchar[bpl];
552  h = -bi.biHeight;
553  for (int y = 0; y < h/2; ++y) {
554  memcpy(buf, data + y*bpl, bpl);
555  memcpy(data + y*bpl, data + (h-y-1)*bpl, bpl);
556  memcpy(data + (h-y-1)*bpl, buf, bpl);
557  }
558  delete [] buf;
559  }
560 
561  return true;
562 }
double d
Definition: qnumeric_p.h:62
const int BMP_WIN
Format
The following image formats are available in Qt.
Definition: qimage.h:91
unsigned int QRgb
Definition: qrgb.h:53
void setColor(int i, QRgb c)
Sets the color at the given index in the color table, to the given to colorValue. ...
Definition: qimage.cpp:1850
unsigned char c[8]
Definition: qnumeric_p.h:62
int qint32
Definition: qglobal.h:937
const int BMP_RLE4
bool isNull() const
Returns true if it is a null image, otherwise returns false.
Definition: qimage.cpp:1542
qint32 biSize
Definition: qbmphandler_p.h:71
static void swapPixel01(QImage *image)
Definition: qbmphandler.cpp:52
virtual qint64 pos() const
For random-access devices, this function returns the position that data is written to or read from...
Definition: qiodevice.cpp:624
bool getChar(char *c)
Reads one character from the device and stores it in c.
Definition: qiodevice.cpp:1536
int bytesPerLine() const
Returns the number of bytes per image scanline.
Definition: qimage.cpp:1812
unsigned char quint8
Definition: qglobal.h:934
static int calc_shift(uint mask)
const int BMP_BITFIELDS
virtual bool atEnd() const
Returns true if the current read and write position is at the end of the device (i.e.
Definition: qiodevice.cpp:711
Format format() const
Returns the format of the image.
Definition: qimage.cpp:2305
qint32 biSizeImage
Definition: qbmphandler_p.h:77
qint32 biClrUsed
Definition: qbmphandler_p.h:80
qint32 biWidth
Definition: qbmphandler_p.h:72
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read...
Definition: qiodevice.cpp:791
Q_CORE_EXPORT void qDebug(const char *,...)
const int BMP_RGB
unsigned char uchar
Definition: qglobal.h:994
const int BMP_RLE8
void setColorCount(int)
Resizes the color table to contain colorCount entries.
Definition: qimage.cpp:2275
qint32 biYPelsPerMeter
Definition: qbmphandler_p.h:79
const int BMP_OLD
Definition: qbmphandler.cpp:99
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
int qGray(int r, int g, int b)
Definition: qrgb.h:75
void setDotsPerMeterY(int)
Sets the number of pixels that fit vertically in a physical meter, to y.
Definition: qimage.cpp:5667
qint16 biBitCount
Definition: qbmphandler_p.h:75
const int BMP_FILEHDR_SIZE
Definition: qbmphandler.cpp:82
virtual bool isSequential() const
Returns true if this device is sequential; otherwise returns false.
Definition: qiodevice.cpp:454
QSize size() const
Returns the size of the image, i.
Definition: qimage.cpp:1587
#define rgb(r, g, b)
Definition: qcolor_p.cpp:130
QRgb qRgb(int r, int g, int b)
Returns the ARGB quadruplet (255, {r}, {g}, {b}).
Definition: qrgb.h:69
uchar * bits()
Returns a pointer to the first pixel data.
Definition: qimage.cpp:1946
QIODevice * device() const
Returns the I/O device currently set, or 0 if no device is currently set.
Definition: qdatastream.h:206
void setDotsPerMeterX(int)
Sets the number of pixels that fit horizontally in a physical meter, to x.
Definition: qimage.cpp:5645
qint32 biCompression
Definition: qbmphandler_p.h:76
const int BMP_WIN4
const int BMP_WIN5
qint32 biClrImportant
Definition: qbmphandler_p.h:81
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
static const KeyPair *const end
The QIODevice class is the base interface class of all I/O devices in Qt.
Definition: qiodevice.h:66
qint32 biXPelsPerMeter
Definition: qbmphandler_p.h:78
virtual bool seek(qint64 pos)
For random-access devices, this function sets the current position to pos, returning true on success...
Definition: qiodevice.cpp:659
QRgb color(int i) const
Returns the color in the color table at index i.
Definition: qimage.cpp:1829
qint16 biPlanes
Definition: qbmphandler_p.h:74
qint32 biHeight
Definition: qbmphandler_p.h:73

◆ read_dib_fileheader()

static bool read_dib_fileheader ( QDataStream s,
BMP_FILEHDR bf 
)
static

Definition at line 156 of file qbmphandler.cpp.

Referenced by QBmpHandler::readHeader().

157 {
158  // read BMP file header
159  s >> bf;
160  if (s.status() != QDataStream::Ok)
161  return false;
162 
163  // check header
164  if (qstrncmp(bf.bfType,"BM",2) != 0)
165  return false;
166 
167  return true;
168 }
Status status() const
Returns the status of the data stream.
int qstrncmp(const char *str1, const char *str2, uint len)
Definition: qbytearray.h:101

◆ read_dib_infoheader()

static bool read_dib_infoheader ( QDataStream s,
BMP_INFOHDR bi 
)
static

Definition at line 170 of file qbmphandler.cpp.

Referenced by qt_read_dib(), and QBmpHandler::readHeader().

171 {
172  s >> bi; // read BMP info header
173  if (s.status() != QDataStream::Ok)
174  return false;
175 
176  int nbits = bi.biBitCount;
177  int comp = bi.biCompression;
178  if (!(nbits == 1 || nbits == 4 || nbits == 8 || nbits == 16 || nbits == 24 || nbits == 32) ||
179  bi.biPlanes != 1 || comp > BMP_BITFIELDS)
180  return false; // weird BMP image
181  if (!(comp == BMP_RGB || (nbits == 4 && comp == BMP_RLE4) ||
182  (nbits == 8 && comp == BMP_RLE8) || ((nbits == 16 || nbits == 32) && comp == BMP_BITFIELDS)))
183  return false; // weird compression type
184 
185  return true;
186 }
Status status() const
Returns the status of the data stream.
const int BMP_RLE4
const int BMP_BITFIELDS
const int BMP_RGB
const int BMP_RLE8
qint16 biBitCount
Definition: qbmphandler_p.h:75

◆ swapPixel01()

static void swapPixel01 ( QImage image)
static

Definition at line 52 of file qbmphandler.cpp.

Referenced by read_dib_body().

53 {
54  int i;
55  if (image->depth() == 1 && image->colorCount() == 2) {
56  register uint *p = (uint *)image->bits();
57  int nbytes = image->byteCount();
58  for (i=0; i<nbytes/4; i++) {
59  *p = ~*p;
60  p++;
61  }
62  uchar *p2 = (uchar *)p;
63  for (i=0; i<(nbytes&3); i++) {
64  *p2 = ~*p2;
65  p2++;
66  }
67  QRgb t = image->color(0); // swap color 0 and 1
68  image->setColor(0, image->color(1));
69  image->setColor(1, t);
70  }
71 }
unsigned int QRgb
Definition: qrgb.h:53
void setColor(int i, QRgb c)
Sets the color at the given index in the color table, to the given to colorValue. ...
Definition: qimage.cpp:1850
int byteCount() const
Returns the number of bytes occupied by the image data.
Definition: qimage.cpp:1800
unsigned char uchar
Definition: qglobal.h:994
unsigned int uint
Definition: qglobal.h:996
int depth() const
Returns the depth of the image.
Definition: qimage.cpp:1620
uchar * bits()
Returns a pointer to the first pixel data.
Definition: qimage.cpp:1946
int colorCount() const
Returns the size of the color table for the image.
Definition: qimage.cpp:1656
QRgb color(int i) const
Returns the color in the color table at index i.
Definition: qimage.cpp:1829

Variable Documentation

◆ BMP_BITFIELDS

const int BMP_BITFIELDS = 3

Definition at line 108 of file qbmphandler.cpp.

Referenced by read_dib_body(), and read_dib_infoheader().

◆ BMP_FILEHDR_SIZE

const int BMP_FILEHDR_SIZE = 14

Definition at line 82 of file qbmphandler.cpp.

Referenced by qt_read_dib(), read_dib_body(), and QBmpHandler::write().

◆ BMP_OLD

const int BMP_OLD = 12

Definition at line 99 of file qbmphandler.cpp.

Referenced by read_dib_body().

◆ BMP_OS2

const int BMP_OS2 = 64

Definition at line 101 of file qbmphandler.cpp.

Referenced by operator>>().

◆ BMP_RGB

const int BMP_RGB = 0

Definition at line 105 of file qbmphandler.cpp.

Referenced by operator>>(), qt_write_dib(), read_dib_body(), and read_dib_infoheader().

◆ BMP_RLE4

const int BMP_RLE4 = 2

Definition at line 107 of file qbmphandler.cpp.

Referenced by read_dib_body(), and read_dib_infoheader().

◆ BMP_RLE8

const int BMP_RLE8 = 1

Definition at line 106 of file qbmphandler.cpp.

Referenced by read_dib_body(), and read_dib_infoheader().

◆ BMP_WIN

const int BMP_WIN = 40

Definition at line 100 of file qbmphandler.cpp.

Referenced by operator>>(), qt_write_dib(), read_dib_body(), and QBmpHandler::write().

◆ BMP_WIN4

const int BMP_WIN4 = 108

Definition at line 102 of file qbmphandler.cpp.

Referenced by operator>>(), and read_dib_body().

◆ BMP_WIN5

const int BMP_WIN5 = 124

Definition at line 103 of file qbmphandler.cpp.

Referenced by operator>>(), and read_dib_body().