4#include "private/qbmphandler_p.h"
6#ifndef QT_NO_IMAGEFORMAT_BMP
17 if (
image->depth() == 1 &&
image->colorCount() == 2) {
20 for (
i=0;
i<nbytes/4;
i++) {
25 for (
i=0;
i<(nbytes&3);
i++) {
48 s.readRawData(bf.bfType, 2);
49 s >> bf.bfSize >> bf.bfReserved1 >> bf.bfReserved2 >> bf.bfOffBits;
55 s.writeRawData(bf.bfType, 2);
56 s << bf.bfSize << bf.bfReserved1 << bf.bfReserved2 << bf.bfOffBits;
78 s >> bi.biWidth >> bi.biHeight >> bi.biPlanes >> bi.biBitCount;
79 s >> bi.biCompression >> bi.biSizeImage;
80 s >> bi.biXPelsPerMeter >> bi.biYPelsPerMeter;
81 s >> bi.biClrUsed >> bi.biClrImportant;
83 s >> bi.biRedMask >> bi.biGreenMask >> bi.biBlueMask >> bi.biAlphaMask;
85 for (
int i = 0;
i < 9; ++
i)
86 s >> bi.biEndpoints[
i];
87 s >> bi.biGammaRed >> bi.biGammaGreen >> bi.biGammaBlue;
89 s >> bi.biIntent >> bi.biProfileData >> bi.biProfileSize >> bi.biReserved;
94 s >>
w >>
h >> bi.biPlanes >> bi.biBitCount;
99 bi.biXPelsPerMeter = bi.biYPelsPerMeter = 0;
100 bi.biClrUsed = bi.biClrImportant = 0;
108 s << bi.biWidth << bi.biHeight;
111 s << bi.biCompression;
113 s << bi.biXPelsPerMeter << bi.biYPelsPerMeter;
114 s << bi.biClrUsed << bi.biClrImportant;
117 s << bi.biRedMask << bi.biGreenMask << bi.biBlueMask << bi.biAlphaMask;
120 for (
int i = 0;
i < 9;
i++)
121 s << bi.biEndpoints[
i];
124 s << bi.biGammaGreen;
130 s << bi.biProfileData;
131 s << bi.biProfileSize;
151 while (low_mask &&
result) {
169 }
while (filled < 8);
178 if (
s.status() != QDataStream::Ok)
182 if (
qstrncmp(bf.bfType,
"BM",2) != 0)
191 if (
s.status() != QDataStream::Ok)
194 int nbits = bi.biBitCount;
195 int comp = bi.biCompression;
196 if (!(nbits == 1 || nbits == 4 || nbits == 8 || nbits == 16 || nbits == 24 || nbits == 32) ||
202 if (bi.biHeight == INT_MIN)
204 if (bi.biWidth <= 0 || !bi.biHeight ||
quint64(bi.biWidth) *
qAbs(bi.biHeight) > 16384 * 16384)
216 qDebug(
"offset...........%lld", datapos);
217 qDebug(
"startpos.........%lld", startpos);
218 qDebug(
"biSize...........%d", bi.biSize);
219 qDebug(
"biWidth..........%d", bi.biWidth);
220 qDebug(
"biHeight.........%d", bi.biHeight);
221 qDebug(
"biPlanes.........%d", bi.biPlanes);
222 qDebug(
"biBitCount.......%d", bi.biBitCount);
223 qDebug(
"biCompression....%d", bi.biCompression);
224 qDebug(
"biSizeImage......%d", bi.biSizeImage);
225 qDebug(
"biXPelsPerMeter..%d", bi.biXPelsPerMeter);
226 qDebug(
"biYPelsPerMeter..%d", bi.biYPelsPerMeter);
227 qDebug(
"biClrUsed........%d", bi.biClrUsed);
228 qDebug(
"biClrImportant...%d", bi.biClrImportant);
230 int w = bi.biWidth,
h = bi.biHeight, nbits = bi.biBitCount;
231 int t = bi.biSize, comp = bi.biCompression;
237 uint green_shift = 0;
239 uint alpha_shift = 0;
241 uint green_scale = 0;
243 uint alpha_scale = 0;
246 if (!
d->isSequential())
247 d->seek(startpos + bi.biSize);
250 red_mask = bi.biRedMask;
251 green_mask = bi.biGreenMask;
252 blue_mask = bi.biBlueMask;
253 alpha_mask = bi.biAlphaMask;
254 }
else if (bitfields && (nbits == 16 || nbits == 32)) {
255 if (
d->read((
char *)&red_mask,
sizeof(red_mask)) !=
sizeof(red_mask))
257 if (
d->read((
char *)&green_mask,
sizeof(green_mask)) !=
sizeof(green_mask))
259 if (
d->read((
char *)&blue_mask,
sizeof(blue_mask)) !=
sizeof(blue_mask))
261 if (comp ==
BMP_ALPHABITFIELDS &&
d->read((
char *)&alpha_mask,
sizeof(alpha_mask)) !=
sizeof(alpha_mask))
265 bool transp = bitfields || (comp ==
BMP_RGB && nbits == 32 && alpha_mask == 0xff000000);
266 transp = transp && alpha_mask;
293 ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits;
294 if (ncols < 1 || ncols > 256)
304 image.setColorCount(ncols);
307 for (
int i=0;
i<ncols;
i++) {
308 if (
d->read((
char *)
rgb, rgb_len) != rgb_len)
314 }
else if (bitfields && (nbits == 16 || nbits == 32)) {
316 if (((red_mask >> red_shift) + 1) == 0)
318 red_scale =
calc_scale(red_mask >> red_shift);
320 if (((green_mask >> green_shift) + 1) == 0)
322 green_scale =
calc_scale(green_mask >> green_shift);
324 if (((blue_mask >> blue_shift) + 1) == 0)
326 blue_scale =
calc_scale(blue_mask >> blue_shift);
328 if (((alpha_mask >> alpha_shift) + 1) == 0)
330 alpha_scale =
calc_scale(alpha_mask >> alpha_shift);
331 }
else if (comp ==
BMP_RGB && (nbits == 24 || nbits == 32)) {
332 blue_mask = 0x000000ff;
333 green_mask = 0x0000ff00;
334 red_mask = 0x00ff0000;
338 blue_scale = green_scale = red_scale = 0;
341 if (((alpha_mask >> alpha_shift) + 1) == 0)
343 alpha_scale =
calc_scale(alpha_mask >> alpha_shift);
345 }
else if (comp ==
BMP_RGB && nbits == 16) {
352 blue_scale = green_scale = red_scale = 3;
355 image.setDotsPerMeterX(bi.biXPelsPerMeter);
356 image.setDotsPerMeterY(bi.biYPelsPerMeter);
359 qDebug(
"Rmask: %08x Rshift: %08x Rscale:%08x", red_mask, red_shift, red_scale);
360 qDebug(
"Gmask: %08x Gshift: %08x Gscale:%08x", green_mask, green_shift, green_scale);
361 qDebug(
"Bmask: %08x Bshift: %08x Bscale:%08x", blue_mask, blue_shift, blue_scale);
362 qDebug(
"Amask: %08x Ashift: %08x Ascale:%08x", alpha_mask, alpha_shift, alpha_scale);
365 if (datapos >= 0 && datapos >
d->pos()) {
366 if (!
d->isSequential())
370 int bpl =
image.bytesPerLine();
375 if (
d->read((
char*)(
data +
h*bpl), bpl) != bpl)
382 else if (nbits == 4) {
383 int buflen = ((
w+7)/8)*4;
391 if (!
d->getChar((
char *)&
b))
394 if (!
d->getChar((
char *)&
b) ||
b == 1) {
405 d->getChar((
char *)&tmp);
407 d->getChar((
char *)&tmp);
426 d->getChar((
char *)&
b);
432 d->getChar((
char *)&tmp);
435 if ((((
c & 3) + 1) & 2) == 2)
445 d->getChar((
char *)&
b);
456 memset(
data, 0,
h*bpl);
458 if (
d->read((
char*)
buf,buflen) != buflen)
462 for (
int i=0;
i<
w/2;
i++) {
473 else if (nbits == 8) {
480 if (!
d->getChar((
char *)&
b))
483 if (!
d->getChar((
char *)&
b) ||
b == 1) {
494 d->getChar((
char *)&tmp);
496 d->getChar((
char *)&tmp);
513 if (
d->read((
char *)
p,
b) !=
b)
534 if (
d->read((
char *)
data +
h*bpl, bpl) != bpl)
540 else if (nbits == 16 || nbits == 24 || nbits == 32) {
544 int bpl24 = ((
w*nbits+31)/32)*4;
551 if (
d->read((
char *)buf24,bpl24) != bpl24)
561 apply_scale((
c & green_mask) >> green_shift, green_scale),
563 transp ?
apply_scale((
c & alpha_mask) >> alpha_shift, alpha_scale) : 0xff);
570 if (bi.biHeight < 0) {
574 for (
int y = 0;
y <
h/2; ++
y) {
588 if (!
d->isWritable())
593 bi.biWidth =
image.width();
594 bi.biHeight =
image.height();
596 bi.biBitCount = nbits;
598 bi.biSizeImage = bpl_bmp*
image.height();
599 bi.biXPelsPerMeter =
image.dotsPerMeterX() ?
image.dotsPerMeterX()
601 bi.biYPelsPerMeter =
image.dotsPerMeterY() ?
image.dotsPerMeterY() : 2834;
602 bi.biClrUsed =
image.colorCount();
603 bi.biClrImportant =
image.colorCount();
605 if (
s.status() != QDataStream::Ok)
608 if (
image.depth() != 32) {
611 const QList<QRgb>
c =
image.colorTable();
612 for (
int i = 0;
i <
image.colorCount();
i++) {
618 if (
d->write((
char *)color_table, 4*
image.colorCount()) == -1) {
619 delete [] color_table;
622 delete [] color_table;
627 if (nbits == 1 || nbits == 8) {
628 for (
y=
image.height()-1;
y>=0;
y--) {
629 if (
d->write((
const char*)
image.constScanLine(
y), bpl) == -1)
639 memset(
buf, 0, bpl_bmp);
640 for (
y=
image.height()-1;
y>=0;
y--) {
646 *
b++ = (*
p << 4) | (*(
p+1) & 0x0f);
649 if (
image.width() & 1)
662 if (bpl_bmp !=
d->write((
char*)
buf, bpl_bmp)) {
678 return m_format ==
BmpFormat ?
"bmp" :
"dib";
681bool QBmpHandler::readHeader()
709 if (state != Error) {
720 qWarning(
"QBmpHandler::canRead() called with 0 pointer");
737 qWarning(
"QBmpHandler::read: cannot read into null pointer");
741 if (state == Ready && !readHeader()) {
753 qint64 datapos = startpos;
765 datapos += infoHeader.
biSize;
776 const bool readSuccess = m_format ==
BmpFormat ?
789 switch (
img.format()) {
804 if (
img.hasAlphaChannel())
816 if (
image.depth() == 8 &&
image.colorCount() <= 16) {
817 bpl_bmp = (((bpl+1)/2+3)/4)*4;
819 }
else if (
image.depth() == 32) {
820 bpl_bmp = ((
image.width()*24+31)/32)*4;
824 nbits =
image.depth();
843 memcpy(bf.bfType,
"BM", 2);
849 bf.bfSize = bf.bfOffBits + bpl_bmp*
image.height();
850 if (
qsizetype(bf.bfSize) != bf.bfOffBits + bpl_bmp*
image.height())
869 if (state == Ready && !
const_cast<QBmpHandler*
>(
this)->readHeader())
872 }
else if (
option == ImageFormat) {
875 if (state == Ready && !
const_cast<QBmpHandler*
>(
this)->readHeader())
IOBluetoothDevice * device
bool supportsOption(ImageOption option) const override
Returns true if the QImageIOHandler supports the option option; otherwise returns false.
QVariant option(ImageOption option) const override
Returns the value assigned to option as a QVariant.
QBmpHandler(InternalFormat fmt=BmpFormat)
bool canRead() const override
Returns true if an image can be read from the device (i.e., the image format is supported,...
bool write(const QImage &image) override
Writes the image image to the assigned device.
void setOption(ImageOption option, const QVariant &value) override
Sets the option option with the value value.
bool read(QImage *image) override
Read an image from the device, and stores it in image.
\inmodule QtCore\reentrant
\inmodule QtCore \reentrant
qint64 peek(char *data, qint64 maxlen)
ImageOption
This enum describes the different options supported by QImageIOHandler.
static bool allocateImage(QSize size, QImage::Format format, QImage *image)
QByteArray format() const
Returns the format that is currently assigned to QImageIOHandler.
QIODevice * device() const
Returns the device currently assigned to the QImageIOHandler.
void setFormat(const QByteArray &format)
Sets the format of the QImageIOHandler to format.
Format
The following image formats are available in Qt.
Combined button and popup list for selecting options.
static uint calc_shift(uint mask)
static uint calc_scale(uint low_mask)
static bool read_dib_infoheader(QDataStream &s, BMP_INFOHDR &bi)
static QDataStream & operator>>(QDataStream &s, BMP_FILEHDR &bf)
static QDataStream & operator<<(QDataStream &s, const BMP_FILEHDR &bf)
bool qt_write_dib(QDataStream &s, const QImage &image, int bpl, int bpl_bmp, int nbits)
const int BMP_ALPHABITFIELDS
static uint apply_scale(uint value, uint scale)
const int BMP_FILEHDR_SIZE
static QT_BEGIN_NAMESPACE void swapPixel01(QImage *image)
static bool read_dib_fileheader(QDataStream &s, BMP_FILEHDR &bf)
static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 datapos, qint64 startpos, QImage &image)
int qstrncmp(const char *str1, const char *str2, size_t len)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
constexpr T qAbs(const T &t)
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint x
[0]
GLint GLenum GLsizei GLsizei GLsizei depth
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLenum GLsizei const GLchar * buf
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLint GLsizei GLsizei GLenum format
GLfloat GLfloat GLfloat GLfloat h
GLenum GLenum GLenum GLenum GLenum scale
QT_BEGIN_NAMESPACE typedef unsigned int QRgb
constexpr QRgb qRgb(int r, int g, int b)
constexpr int qRed(QRgb rgb)
constexpr int qGreen(QRgb rgb)
constexpr int qGray(int r, int g, int b)
constexpr QRgb qRgba(int r, int g, int b, int a)
constexpr int qBlue(QRgb rgb)
unsigned long long quint64
QVideoFrameFormat::PixelFormat fmt
manager head(request, this, [this](QRestReply &reply) { if(reply.isSuccess()) })
[6]