69 if (*
base !=
nullptr) {
76 *
base =
const_cast<char *
>(
buf->data().constData());
116static QImageIOHandler::Transformations
exif2Qt(
int exifOrientation)
118 switch (exifOrientation) {
136 qWarning(
"Invalid EXIF orientation");
140static int qt2Exif(QImageIOHandler::Transformations transformation)
142 switch (transformation) {
160 qWarning(
"Invalid Qt image transformation");
172 , currentDirectory(0)
192 qWarning(
"QTiffHandler::canRead() called with no device");
201 if ((
h[0] == 0x49 &&
h[1] == 0x49) && (
h[2] == 0x2a ||
h[2] == 0x2b) &&
h[3] == 0)
203 if ((
h[0] == 0x4d &&
h[1] == 0x4d) &&
h[2] == 0 && (
h[3] == 0x2a ||
h[3] == 0x2b))
216 tiff = TIFFClientOpen(
"foo",
245 if (!TIFFGetField(
tiff, TIFFTAG_IMAGEWIDTH, &
width)
246 || !TIFFGetField(
tiff, TIFFTAG_IMAGELENGTH, &
height)
253 uint16_t orientationTag;
254 if (TIFFGetField(
tiff, TIFFTAG_ORIENTATION, &orientationTag))
258 uint16_t bitPerSample;
259 if (!TIFFGetField(
tiff, TIFFTAG_BITSPERSAMPLE, &bitPerSample))
261 uint16_t samplesPerPixel;
262 if (!TIFFGetField(
tiff, TIFFTAG_SAMPLESPERPIXEL, &samplesPerPixel))
264 uint16_t sampleFormat;
265 if (!TIFFGetField(
tiff, TIFFTAG_SAMPLEFORMAT, &sampleFormat))
266 sampleFormat = SAMPLEFORMAT_VOID;
271 if (
grayscale && bitPerSample == 1 && samplesPerPixel == 1)
273 else if (
photometric == PHOTOMETRIC_MINISBLACK && bitPerSample == 8 && samplesPerPixel == 1)
277 else if ((
grayscale ||
photometric == PHOTOMETRIC_PALETTE) && bitPerSample == 8 && samplesPerPixel == 1)
279 else if (samplesPerPixel < 4)
288 uint16_t *extrasamples;
293 bool premultiplied =
true;
294 bool gotField = TIFFGetField(
tiff, TIFFTAG_EXTRASAMPLES, &
count, &extrasamples);
295 if (!gotField || !
count || extrasamples[0] == EXTRASAMPLE_UNSPECIFIED)
296 premultiplied =
false;
298 if (bitPerSample == 16 &&
photometric == PHOTOMETRIC_RGB) {
300 if (gotField &&
count && extrasamples[0] == EXTRASAMPLE_UNASSALPHA)
301 premultiplied =
false;
307 if (gotField &&
count && extrasamples[0] == EXTRASAMPLE_UNASSALPHA)
308 premultiplied =
false;
360 TIFF *
const tiff = d->
tiff;
361 if (TIFFIsTiled(tiff) && TIFFTileSize64(tiff) > uint64_t(
image->sizeInBytes()))
371 colortable[0] = 0xff000000;
372 colortable[1] = 0xffffffff;
374 colortable[0] = 0xffffffff;
375 colortable[1] = 0xff000000;
377 image->setColorTable(colortable);
379 const uint16_t tableSize = 256;
382 for (
int i = 0;
i<tableSize; ++
i) {
383 const int c = (d->
photometric == PHOTOMETRIC_MINISBLACK) ?
i : (255 -
i);
388 uint16_t *redTable = 0;
389 uint16_t *greenTable = 0;
390 uint16_t *blueTable = 0;
391 if (!TIFFGetField(tiff, TIFFTAG_COLORMAP, &redTable, &greenTable, &blueTable)) {
395 if (!redTable || !greenTable || !blueTable) {
400 for (
int i = 0;
i<tableSize ;++
i) {
402 const int red = redTable[
i] >> 8;
403 const int green = greenTable[
i] >> 8;
404 const int blue = blueTable[
i] >> 8;
408 image->setColorTable(qtColorTable);
419 if (format8bit || format16bit || format64bit || format64fp || format128fp) {
420 int bytesPerPixel =
image->depth() / 8;
422 bytesPerPixel = d->
photometric == PHOTOMETRIC_RGB ? 6 : 2;
424 bytesPerPixel = d->
photometric == PHOTOMETRIC_RGB ? 12 : 4;
425 if (TIFFIsTiled(tiff)) {
427 TIFFGetField(tiff, TIFFTAG_TILEWIDTH, &tileWidth);
428 TIFFGetField(tiff, TIFFTAG_TILELENGTH, &tileLength);
429 if (!tileWidth || !tileLength || tileWidth % 16 || tileLength % 16) {
435 tmsize_t byteTileSize = TIFFTileSize(tiff);
436 if (byteTileSize >
image->sizeInBytes() || byteTileSize / tileLength < byteTileWidth) {
447 if (TIFFReadTile(tiff,
buf,
x,
y, 0, 0) < 0) {
454 quint32 widthToCopy =
qMin(byteTileWidth, byteWidth - byteOffset);
456 ::memcpy(
image->scanLine(
y +
i) + byteOffset,
buf + (
i * byteTileWidth), widthToCopy);
462 if (
image->bytesPerLine() < TIFFScanlineSize(tiff)) {
467 if (TIFFReadScanline(tiff,
image->scanLine(
y),
y, 0) < 0) {
485 const int stopOnError = 1;
499 if (!TIFFGetField(tiff, TIFFTAG_RESOLUTIONUNIT, &resUnit))
500 resUnit = RESUNIT_INCH;
502 if (TIFFGetField(tiff, TIFFTAG_XRESOLUTION, &resX)
503 && TIFFGetField(tiff, TIFFTAG_YRESOLUTION, &resY)) {
506 case RESUNIT_CENTIMETER:
511 image->setDotsPerMeterX(
qRound(resX * (100 / 2.54)));
512 image->setDotsPerMeterY(
qRound(resY * (100 / 2.54)));
523 if (TIFFGetField(tiff, TIFFTAG_ICCPROFILE, &
count, &profile)) {
535 if (colorTable.
size() != 256)
538 const bool increasing = (colorTable.
at(0) == 0xff000000);
539 for (
int i = 0;
i < 256; ++
i) {
540 if ((increasing && colorTable.
at(
i) !=
qRgb(
i,
i,
i))
541 || (!increasing && colorTable.
at(
i) !=
qRgb(255 -
i, 255 -
i, 255 -
i)))
550 switch (
image.format()) {
556 for (
int i = 0;
i < 256; ++
i)
562 for (
int i = 0;
i < 256; ++
i)
575 qint64 numRows = (4 * 1024 * 1024) / scanSize;
577 return TIFFDefaultStripSize(tiff, reqSize);
582 if (!
device()->isWritable())
585 TIFF *
const tiff = TIFFClientOpen(
"foo",
602 if (!TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH,
width)
603 || !TIFFSetField(tiff, TIFFTAG_IMAGELENGTH,
height)
604 || !TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)) {
610 bool resolutionSet =
false;
611 const int dotPerMeterX =
image.dotsPerMeterX();
612 const int dotPerMeterY =
image.dotsPerMeterY();
613 if ((dotPerMeterX % 100) == 0
614 && (dotPerMeterY % 100) == 0) {
615 resolutionSet = TIFFSetField(tiff, TIFFTAG_RESOLUTIONUNIT, RESUNIT_CENTIMETER)
616 && TIFFSetField(tiff, TIFFTAG_XRESOLUTION, dotPerMeterX/100.0)
617 && TIFFSetField(tiff, TIFFTAG_YRESOLUTION, dotPerMeterY/100.0);
619 resolutionSet = TIFFSetField(tiff, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH)
620 && TIFFSetField(tiff, TIFFTAG_XRESOLUTION,
static_cast<float>(
image.logicalDpiX()))
621 && TIFFSetField(tiff, TIFFTAG_YRESOLUTION,
static_cast<float>(
image.logicalDpiY()));
623 if (!resolutionSet) {
628 bool orientationSet =
false;
630 if (!orientationSet) {
635 if (
image.colorSpace().isValid()) {
637 if (!TIFFSetField(tiff, TIFFTAG_ICCPROFILE, iccProfile.
size(),
reinterpret_cast<const void *
>(iccProfile.
constData()))) {
645 uint16_t photometric = PHOTOMETRIC_MINISBLACK;
646 if (
image.colorTable().at(0) == 0xffffffff)
647 photometric = PHOTOMETRIC_MINISWHITE;
648 if (!TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, photometric)
649 || !TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression ==
NoCompression ? COMPRESSION_NONE : COMPRESSION_LZW)
650 || !TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 1)
657 const int chunks = int(
image.sizeInBytes() / (1024 * 1024 * 16)) + 1;
658 const int chunkHeight =
qMax(
height / chunks, 1);
665 int chunkEnd =
y + chunk.
height();
666 while (
y < chunkEnd) {
667 if (TIFFWriteScanline(tiff,
reinterpret_cast<uint32_t *
>(chunk.
scanLine(
y - chunkStart)),
y) != 1) {
682 uint16_t photometric = PHOTOMETRIC_MINISBLACK;
683 if (colorTable.
at(0) == 0xffffffff)
684 photometric = PHOTOMETRIC_MINISWHITE;
685 if (!TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, photometric)
686 || !TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression ==
NoCompression ? COMPRESSION_NONE : COMPRESSION_LZW)
687 || !TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE,
image.depth())
688 || !TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT)
694 if (!TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE)
695 || !TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression ==
NoCompression ? COMPRESSION_NONE : COMPRESSION_LZW)
696 || !TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8)
703 const int tableSize = colorTable.
size();
710 for (
int i = 0;
i<tableSize; ++
i) {
717 const bool setColorTableSuccess = TIFFSetField(tiff, TIFFTAG_COLORMAP, redTable.
data(), greenTable.
data(), blueTable.
data());
719 if (!setColorTableSuccess) {
727 if (TIFFWriteScanline(tiff,
const_cast<uchar *
>(
image.scanLine(
y)),
y) != 1) {
734 if (!TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB)
735 || !TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression ==
NoCompression ? COMPRESSION_NONE : COMPRESSION_LZW)
736 || !TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 3)
737 || !TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 16)
738 || !TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT,
741 : SAMPLEFORMAT_IEEEFP)
742 || !TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tiff, 0))) {
746 std::unique_ptr<quint16[]> rgb48line(
new quint16[
width * 3]);
750 rgb48line[
x * 3 + 0] = srcLine[
x * 4 + 0];
751 rgb48line[
x * 3 + 1] = srcLine[
x * 4 + 1];
752 rgb48line[
x * 3 + 2] = srcLine[
x * 4 + 2];
755 if (TIFFWriteScanline(tiff, (
void*)rgb48line.get(),
y) != 1) {
764 const uint16_t extrasamples = premultiplied ? EXTRASAMPLE_ASSOCALPHA : EXTRASAMPLE_UNASSALPHA;
765 if (!TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB)
766 || !TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression ==
NoCompression ? COMPRESSION_NONE : COMPRESSION_LZW)
767 || !TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 4)
768 || !TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 16)
769 || !TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT)
770 || !TIFFSetField(tiff, TIFFTAG_EXTRASAMPLES, 1, &extrasamples)
771 || !TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tiff, 0))) {
776 if (TIFFWriteScanline(tiff, (
void*)
image.scanLine(
y),
y) != 1) {
783 if (!TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB)
784 || !TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression ==
NoCompression ? COMPRESSION_NONE : COMPRESSION_LZW)
785 || !TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 3)
786 || !TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 32)
787 || !TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP)
788 || !TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tiff, 0))) {
792 std::unique_ptr<float[]>
line(
new float[
width * 3]);
794 const float *srcLine =
reinterpret_cast<const float *
>(
image.constScanLine(
y));
796 line[
x * 3 + 0] = srcLine[
x * 4 + 0];
797 line[
x * 3 + 1] = srcLine[
x * 4 + 1];
798 line[
x * 3 + 2] = srcLine[
x * 4 + 2];
801 if (TIFFWriteScanline(tiff, (
void*)
line.get(),
y) != 1) {
811 const uint16_t extrasamples = premultiplied ? EXTRASAMPLE_ASSOCALPHA : EXTRASAMPLE_UNASSALPHA;
812 if (!TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB)
813 || !TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression ==
NoCompression ? COMPRESSION_NONE : COMPRESSION_LZW)
814 || !TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 4)
815 || !TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE,
image.depth() == 64 ? 16 : 32)
816 || !TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP)
817 || !TIFFSetField(tiff, TIFFTAG_EXTRASAMPLES, 1, &extrasamples)
818 || !TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tiff, 0))) {
823 if (TIFFWriteScanline(tiff, (
void*)
image.scanLine(
y),
y) != 1) {
829 }
else if (!
image.hasAlphaChannel()) {
830 if (!TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB)
831 || !TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression ==
NoCompression ? COMPRESSION_NONE : COMPRESSION_LZW)
832 || !TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 3)
833 || !TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8)
839 const int chunks = int(
image.sizeInBytes() / (1024 * 1024 * 16)) + 1;
840 const int chunkHeight =
qMax(
height / chunks, 1);
847 int chunkEnd =
y + chunk.
height();
848 while (
y < chunkEnd) {
849 if (TIFFWriteScanline(tiff, (
void*)chunk.
scanLine(
y - chunkStart),
y) != 1) {
860 const uint16_t extrasamples = premultiplied ? EXTRASAMPLE_ASSOCALPHA : EXTRASAMPLE_UNASSALPHA;
861 if (!TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB)
862 || !TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression ==
NoCompression ? COMPRESSION_NONE : COMPRESSION_LZW)
863 || !TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 4)
864 || !TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8)
865 || !TIFFSetField(tiff, TIFFTAG_EXTRASAMPLES, 1, &extrasamples)
871 const int chunks = int(
image.sizeInBytes() / (1024 * 1024 * 16)) + 1;
872 const int chunkHeight =
qMax(
height / chunks, 1);
881 int chunkEnd =
y + chunk.
height();
882 while (
y < chunkEnd) {
883 if (TIFFWriteScanline(tiff, (
void*)chunk.
scanLine(
y - chunkStart),
y) != 1) {
918 int transformation =
value.toInt();
919 if (transformation > 0 && transformation < 8)
920 d->
transformation = QImageIOHandler::Transformations(transformation);
934 if (!ensureHaveDirectoryCount())
946 if (!ensureHaveDirectoryCount())
960 if (!ensureHaveDirectoryCount())
971void QTiffHandler::convert32BitOrder(
void *
buffer,
int width)
973 uint32_t *
target =
reinterpret_cast<uint32_t *
>(
buffer);
978 | ((
p & 0x00ff0000) >> 16)
980 | ((
p & 0x000000ff) << 16);
987 const int h =
image->height();
988 const int w =
image->width();
994 memcpy(&
mask, &fp_mask, 2);
995 for (
int y = 0;
y <
h; ++
y) {
996 quint16 *
dst =
reinterpret_cast<uint16_t *
>(scanline);
997 for (
int x =
w - 1;
x >= 0; --
x) {
1010 const int h =
image->height();
1011 const int w =
image->width();
1014 for (
int y = 0;
y <
h; ++
y) {
1015 float *
dst =
reinterpret_cast<float *
>(scanline);
1016 for (
int x =
w - 1;
x >= 0; --
x) {
1017 dst[
x * 4 + 3] = 1.0f;
1029 if (
image->depth() == 64) {
1030 const int h =
image->height();
1031 const int w =
image->width();
1034 for (
int y = 0;
y <
h; ++
y) {
1036 for (
int x =
w - 1;
x >= 0; --
x) {
1045 const int h =
image->height();
1046 const int w =
image->width();
1049 for (
int y = 0;
y <
h; ++
y) {
1050 float *
dst =
reinterpret_cast<float *
>(scanline);
1051 for (
int x =
w - 1;
x >= 0; --
x) {
1052 dst[
x * 4 + 3] = 1.0f;
1062bool QTiffHandler::ensureHaveDirectoryCount()
const
1067 TIFF *tiff = TIFFClientOpen(
"foo",
1084 }
while (TIFFReadDirectory(tiff));
IOBluetoothDevice * device
\inmodule QtCore \reentrant
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
static QColorSpace fromIccProfile(const QByteArray &iccProfile)
Creates a QColorSpace from ICC profile iccProfile.
uchar * map(qint64 offset, qint64 size, MemoryMapFlags flags=NoOptions)
Maps size bytes of the file into memory starting at offset.
bool unmap(uchar *address)
Unmaps the memory address.
qint64 size() const override
\reimp
\inmodule QtCore \reentrant
virtual bool reset()
Seeks to the start of input for random-access devices.
The QImageIOHandler class defines the common image I/O interface for all image formats in Qt.
ImageOption
This enum describes the different options supported by QImageIOHandler.
static bool allocateImage(QSize size, QImage::Format format, QImage *image)
QIODevice * device() const
Returns the device currently assigned to the QImageIOHandler.
@ TransformationRotate270
@ TransformationFlipAndRotate90
@ TransformationMirrorAndRotate90
@ TransformationRotate180
void setFormat(const QByteArray &format)
Sets the format of the QImageIOHandler to format.
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
int height() const
Returns the height of the image.
Format
The following image formats are available in Qt.
@ Format_RGBA32FPx4_Premultiplied
@ Format_RGBA64_Premultiplied
@ Format_RGBA8888_Premultiplied
@ Format_RGBA16FPx4_Premultiplied
@ Format_ARGB32_Premultiplied
qsizetype size() const noexcept
const_reference at(qsizetype i) const noexcept
constexpr int height() const noexcept
Returns the height.
constexpr int width() const noexcept
Returns the width.
qsizetype size() const
Returns the number of characters in this string.
static bool canRead(QIODevice *device)
bool readHeaders(QIODevice *device)
QImageIOHandler::Transformations transformation
bool openForRead(QIODevice *device)
bool jumpToNextImage() override
For image formats that support animation, this function jumps to the next image.
QVariant option(ImageOption option) const override
Returns the value assigned to option as a QVariant.
bool read(QImage *image) override
Read an image from the device, and stores it in image.
bool supportsOption(ImageOption option) const override
Returns true if the QImageIOHandler supports the option option; otherwise returns false.
void setOption(ImageOption option, const QVariant &value) override
Sets the option option with the value value.
bool canRead() const override
Returns true if an image can be read from the device (i.e., the image format is supported,...
bool jumpToImage(int imageNumber) override
For image formats that support animation, this function jumps to the image whose sequence number is i...
int imageCount() const override
For image formats that support animation, this function returns the number of images in the animation...
int currentImageNumber() const override
For image formats that support animation, this function returns the sequence number of the current im...
bool write(const QImage &image) override
Writes the image image to the assigned device.
\keyword 16-bit Floating Point Support\inmodule QtCore \inheaderfile QFloat16
Combined button and popup list for selecting options.
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
int qRound(qfloat16 d) noexcept
static int qt2Exif(QImageIOHandler::Transformations transformation)
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qBound(const T &min, const T &val, const T &max)
constexpr const T & qMax(const T &a, const T &b)
GLint GLint GLint GLint GLint x
[0]
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei count
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
static void grayscale(const QImage &image, QImage &dest, const QRect &rect=QRect())
static QT_BEGIN_NAMESPACE const QRgb colors[][14]
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 QRgb qRgba(int r, int g, int b, int a)
constexpr int qBlue(QRgb rgb)
toff_t qtiffSeekProc(thandle_t fd, toff_t off, int whence)
QT_BEGIN_NAMESPACE tsize_t qtiffReadProc(thandle_t fd, tdata_t buf, tsize_t size)
tsize_t qtiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size)
void qtiffUnmapProc(thandle_t fd, void *base, toff_t)
toff_t qtiffSizeProc(thandle_t fd)
static bool checkGrayscale(const QList< QRgb > &colorTable)
static QList< QRgb > effectiveColorTable(const QImage &image)
static quint32 defaultStripSize(TIFF *tiff)
static int qt2Exif(QImageIOHandler::Transformations transformation)
int qtiffCloseProc(thandle_t)
static QImageIOHandler::Transformations exif2Qt(int exifOrientation)
int qtiffMapProc(thandle_t fd, void **base, toff_t *size)
gzip write("uncompressed data")