60
58
BOOL tiff_read_exif_tags(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib);
62
60
// ----------------------------------------------------------
61
// LogLuv conversion functions interface (see TIFFLogLuv.cpp)
62
// ----------------------------------------------------------
64
void tiff_ConvertLineXYZToRGB(BYTE *target, BYTE *source, double stonits, int width_in_pixels);
65
void tiff_ConvertLineRGBToXYZ(BYTE *target, BYTE *source, int width_in_pixels);
67
// ----------------------------------------------------------
64
69
/** Supported loading methods */
323
329
if (resUnit == RESUNIT_NONE && fResX > 0.0 && fResY > 0.0) {
324
330
resUnit = RESUNIT_INCH;
327
BITMAPINFOHEADER *pInfoHeader = FreeImage_GetInfoHeader(dib);
329
332
if (resUnit == RESUNIT_INCH) {
330
pInfoHeader->biXPelsPerMeter = (int) (fResX/0.0254000 + 0.5);
331
pInfoHeader->biYPelsPerMeter = (int) (fResY/0.0254000 + 0.5);
333
FreeImage_SetDotsPerMeterX(dib, (unsigned) (fResX/0.0254000 + 0.5));
334
FreeImage_SetDotsPerMeterY(dib, (unsigned) (fResY/0.0254000 + 0.5));
332
335
} else if(resUnit == RESUNIT_CENTIMETER) {
333
pInfoHeader->biXPelsPerMeter = (int) (fResX*100.0 + 0.5);
334
pInfoHeader->biYPelsPerMeter = (int) (fResY*100.0 + 0.5);
336
FreeImage_SetDotsPerMeterX(dib, (unsigned) (fResX*100.0 + 0.5));
337
FreeImage_SetDotsPerMeterY(dib, (unsigned) (fResY*100.0 + 0.5));
342
345
WriteResolution(TIFF *tiff, FIBITMAP *dib) {
345
BITMAPINFOHEADER *pInfoHeader = FreeImage_GetInfoHeader(dib);
347
348
TIFFSetField(tiff, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
349
res = (unsigned long) (0.5 + 0.0254 * pInfoHeader->biXPelsPerMeter); // rounded ! (99,9998 -> 100)
350
res = (unsigned long) (0.5 + 0.0254 * FreeImage_GetDotsPerMeterX(dib));
350
351
TIFFSetField(tiff, TIFFTAG_XRESOLUTION, res);
352
res = (unsigned long) (0.5 + 0.0254 * pInfoHeader->biYPelsPerMeter);
353
res = (unsigned long) (0.5 + 0.0254 * FreeImage_GetDotsPerMeterY(dib));
353
354
TIFFSetField(tiff, TIFFTAG_YRESOLUTION, res);
640
644
uint16 compression;
641
645
uint16 bitsperpixel = bitspersample * samplesperpixel;
643
if ((flags & TIFF_PACKBITS) == TIFF_PACKBITS) {
647
if(photometric == PHOTOMETRIC_LOGLUV) {
648
compression = COMPRESSION_SGILOG;
649
} else if ((flags & TIFF_PACKBITS) == TIFF_PACKBITS) {
644
650
compression = COMPRESSION_PACKBITS;
645
651
} else if ((flags & TIFF_DEFLATE) == TIFF_DEFLATE) {
646
652
compression = COMPRESSION_DEFLATE;
1168
1176
fi_TIFFIO *fio = (fi_TIFFIO*)data;
1169
1177
tif = fio->tif;
1172
if (!tif || !TIFFSetDirectory(tif, (tdir_t)page))
1180
if (!tif || !TIFFSetDirectory(tif, (tdir_t)page)) {
1173
1181
throw "Error encountered while opening TIFF file";
1185
// first, get the photometric, the compression and basic metadata
1186
// ---------------------------------------------------------------------------------
1175
1188
TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
1176
1189
TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression);
1191
// check for HDR formats
1192
// ---------------------------------------------------------------------------------
1194
if(photometric == PHOTOMETRIC_LOGLUV) {
1195
// check the compression
1196
if(compression != COMPRESSION_SGILOG && compression != COMPRESSION_SGILOG24) {
1197
throw "Only support SGILOG compressed LogLuv data";
1199
// set decoder to output in IEEE 32-bit float XYZ values
1200
TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_FLOAT);
1203
// ---------------------------------------------------------------------------------
1177
1205
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
1178
1206
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
1179
1207
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
1185
1213
// check for unsupported formats
1186
1214
// ---------------------------------------------------------------------------------
1188
if (compression == COMPRESSION_OJPEG)
1189
throw "6.0 JPEG encoding is not supported";
1191
1216
if((photometric == PHOTOMETRIC_SEPARATED) && (bitspersample == 16))
1192
1217
throw "Unable to handle 16-bit CMYK TIFF";
1211
1236
// ---------------------------------------------------------------------------------
1213
1238
if(loadMethod == LoadAsRBGA) {
1239
// ---------------------------------------------------------------------------------
1240
// RGB[A] loading using the TIFFReadRGBAImage() API
1241
// ---------------------------------------------------------------------------------
1214
1243
BOOL has_alpha = FALSE;
1216
1245
// Read the whole image into one big RGBA buffer and then
1218
1247
// TIFFReadRGBAImage() API that we trust.
1220
1249
uint32 *raster = (uint32*)_TIFFmalloc(width * height * sizeof(uint32));
1223
throw "No space for raster buffer";
1250
if (raster == NULL) {
1251
throw FI_MSG_ERROR_MEMORY;
1225
1254
// read the image in one chunk into an RGBA array
1227
if (!TIFFReadRGBAImage(tif, width, height, raster, 0)) {
1256
if (!TIFFReadRGBAImage(tif, width, height, raster, 1)) {
1228
1257
_TIFFfree(raster);
1229
throw "Unsupported TIF format";
1258
throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
1232
1261
// TIFFReadRGBAImage always deliveres 3 or 4 samples per pixel images
1269
1298
if (samplesperpixel == 4) {
1271
1300
for (uint32 y = 0; y < height; y++) {
1272
bits = FreeImage_GetScanLine(dib, y);
1301
BYTE *bits = FreeImage_GetScanLine(dib, y);
1273
1302
for (uint32 x = 0; x < width; x++) {
1274
1303
bits[FI_RGBA_BLUE] = (BYTE)TIFFGetB(row[x]);
1275
1304
bits[FI_RGBA_GREEN] = (BYTE)TIFFGetG(row[x]);
1288
1317
for (uint32 y = 0; y < height; y++) {
1289
bits = FreeImage_GetScanLine(dib, y);
1318
BYTE *bits = FreeImage_GetScanLine(dib, y);
1290
1319
for (uint32 x = 0; x < width; x++) {
1291
1320
bits[FI_RGBA_BLUE] = (BYTE)TIFFGetB(row[x]);
1292
1321
bits[FI_RGBA_GREEN] = (BYTE)TIFFGetG(row[x]);
1303
1332
FreeImage_SetTransparent(dib, has_alpha);
1305
1334
} else if(loadMethod == LoadAs8BitTrns) {
1335
// ---------------------------------------------------------------------------------
1336
// 8-bit + 8-bit alpha layer loading
1337
// ---------------------------------------------------------------------------------
1306
1339
// create a new 8-bit DIB
1307
1340
dib = CreateImageType(image_type, width, height, bitspersample, samplesperpixel);
1308
1341
if (dib == NULL) {
1309
throw "No space for DIB image";
1342
throw FI_MSG_ERROR_MEMORY;
1312
1345
// fill in the resolution (english or universal)
1333
1366
// In the tiff file the lines are save from up to down
1334
1367
// In a DIB the lines must be saved from down to up
1336
bits = FreeImage_GetBits(dib) + height * dst_pitch;
1369
BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
1338
1371
// read the tiff lines and save them in the DIB
1340
1373
if(planar_config == PLANARCONFIG_CONTIG) {
1342
1375
BYTE *buf = (BYTE*)malloc(TIFFStripSize(tif) * sizeof(BYTE));
1376
if(buf == NULL) throw FI_MSG_ERROR_MEMORY;
1344
1379
for (uint32 y = 0; y < height; y += rowsperstrip) {
1345
1380
int32 nrow = (y + rowsperstrip > height ? height - y : rowsperstrip);
1347
1382
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), buf, nrow * src_line) == -1) {
1349
throw "Parsing error";
1384
throw FI_MSG_ERROR_PARSING;
1351
1386
for (int l = 0; l < nrow; l++) {
1354
1387
BYTE *p = bits;
1355
1388
BYTE *b = buf + l * src_line;
1380
1414
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), grey, nrow * src_line) == -1) {
1382
throw "Parsing error";
1416
throw FI_MSG_ERROR_PARSING;
1384
1418
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 1), alpha, nrow * src_line) == -1) {
1386
throw "Parsing error";
1420
throw FI_MSG_ERROR_PARSING;
1389
1423
for (int l = 0; l < nrow; l++) {
1392
1424
BYTE *p = bits;
1393
1425
BYTE *g = grey + l * src_line;
1394
1426
BYTE *a = alpha + l * src_line;
1414
1446
FreeImage_SetTransparencyTable(dib, &trns[0], 256);
1415
1447
FreeImage_SetTransparent(dib, TRUE);
1417
1449
} else if(loadMethod == LoadAsCMYK) {
1450
// ---------------------------------------------------------------------------------
1452
// ---------------------------------------------------------------------------------
1418
1454
BOOL has_alpha = FALSE;
1420
1456
// At this place, samplesperpixel could be > 4, esp. when a CMYK(A) format
1431
1467
// create a new DIB
1432
1468
dib = CreateImageType(image_type, width, height, bitspersample, spp);
1433
1469
if (dib == NULL) {
1434
throw "No space for DIB image";
1470
throw FI_MSG_ERROR_MEMORY;
1437
1473
// fill in the resolution (english or universal)
1446
1482
// In the tiff file the lines are save from up to down
1447
1483
// In a DIB the lines must be saved from down to up
1449
bits = FreeImage_GetBits(dib) + height * dst_pitch;
1485
BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
1451
1487
// read the tiff lines and save them in the DIB
1453
1489
if(planar_config == PLANARCONFIG_CONTIG) {
1454
1490
BYTE *buf = (BYTE*)malloc(TIFFStripSize(tif) * sizeof(BYTE));
1491
if(buf == NULL) throw FI_MSG_ERROR_MEMORY;
1456
1493
for (uint32 y = 0; y < height; y += rowsperstrip) {
1457
1494
int32 nrow = (y + rowsperstrip > height ? height - y : rowsperstrip);
1459
1496
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), buf, nrow * src_line) == -1) {
1461
throw "Parsing error";
1498
throw FI_MSG_ERROR_PARSING;
1464
1501
// CMYKA picture
1465
1502
for (int l = 0; l < nrow; l++) {
1468
1503
// Here we know: samples-per-pixel was >= 5 on CMYKA picture
1469
1504
// This should be converted to RGBA or CMYK, depending on
1470
1505
// TIFF_CMYK is given. The resulting image always has 32bpp.
1486
1521
b += samplesperpixel;
1492
1528
// CMYK picture: just copy
1493
for (int l = 0; l < nrow; l++) {
1529
for (int l = 0; l < nrow; l++) {
1495
1530
BYTE *b = buf + l * src_line;
1496
1531
memcpy(bits, b, src_line);
1506
1542
tsize_t stripsize = TIFFStripSize(tif) * sizeof(BYTE);
1507
1543
BYTE *buf = (BYTE*)malloc(samplesperpixel * stripsize);
1544
if(buf == NULL) throw FI_MSG_ERROR_MEMORY;
1509
1546
for (uint32 y = 0; y < height; y += rowsperstrip) {
1510
1547
int32 nrow = (y + rowsperstrip > height ? height - y : rowsperstrip);
1514
1551
for(sample = 0; sample < samplesperpixel; sample++) {
1515
1552
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, sample), channel, nrow * src_line) == -1) {
1517
throw "Parsing error";
1554
throw FI_MSG_ERROR_PARSING;
1519
1556
channel += stripsize;
1521
1558
if ((flags & TIFF_CMYK) == TIFF_CMYK) {
1522
1559
// CMYK or CMYKA picture: load as 32-bit CMYK, skipping possibly present alpha channel(s)
1523
1560
for (int l = 0; l < nrow; l++) {
1526
1562
for(sample = 0; sample < spp; sample++) {
1527
1563
BYTE *src_bits = channel + l * src_line;
1533
1569
channel += stripsize;
1537
1574
else if(isCMYKA) {
1538
1575
// CMYKA picture: convert to RGBA, skipping possibly some alpha channel(s)
1539
1576
for (int l = 0; l < nrow; l++) {
1541
1577
BYTE *c_channel = buf + l * src_line;
1542
1578
BYTE *m_channel = buf + stripsize + l * src_line;
1543
1579
BYTE *y_channel = buf + 2*stripsize + l * src_line;
1553
1589
has_alpha = TRUE;
1554
1590
dst_bits += spp;
1559
1596
// CMYK picture: convert to RGB
1560
for (int l = 0; l < nrow; l++) {
1597
for (int l = 0; l < nrow; l++) {
1562
1598
BYTE *c_channel = buf + l * src_line;
1563
1599
BYTE *m_channel = buf + stripsize + l * src_line;
1564
1600
BYTE *y_channel = buf + 2*stripsize + l * src_line;
1581
1618
FreeImage_SetTransparent(dib, has_alpha);
1583
1620
} else if(loadMethod == LoadAsGenericStrip) {
1621
// ---------------------------------------------------------------------------------
1623
// ---------------------------------------------------------------------------------
1584
1625
// create a new DIB
1585
1626
dib = CreateImageType(image_type, width, height, bitspersample, samplesperpixel);
1586
1627
if (dib == NULL) {
1587
throw "No space for DIB image";
1628
throw FI_MSG_ERROR_MEMORY;
1590
1631
// fill in the resolution (english or universal)
1603
1644
// In the tiff file the lines are save from up to down
1604
1645
// In a DIB the lines must be saved from down to up
1606
bits = FreeImage_GetBits(dib) + height * dst_pitch;
1647
BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
1608
1649
// read the tiff lines and save them in the DIB
1610
1651
if(planar_config == PLANARCONFIG_CONTIG) {
1611
1652
BOOL bThrowMessage = FALSE;
1612
1653
BYTE *buf = (BYTE*)malloc(TIFFStripSize(tif) * sizeof(BYTE));
1654
if(buf == NULL) throw FI_MSG_ERROR_MEMORY;
1614
1656
for (uint32 y = 0; y < height; y += rowsperstrip) {
1615
1657
int32 nrow = (y + rowsperstrip > height ? height - y : rowsperstrip);
1619
1661
bThrowMessage = TRUE;
1622
throw "Parsing error";
1664
throw FI_MSG_ERROR_PARSING;
1625
1667
// color/greyscale picture (1-, 4-, 8-bit) or special type (int, long, double, ...)
1626
1668
// ... just copy
1627
for (int l = 0; l < nrow; l++) {
1669
for (int l = 0; l < nrow; l++) {
1629
1670
memcpy(bits, buf + l * src_line, src_line);
1643
1685
tsize_t stripsize = TIFFStripSize(tif) * sizeof(BYTE);
1644
1686
BYTE *buf = (BYTE*)malloc(samplesperpixel * stripsize);
1687
if(buf == NULL) throw FI_MSG_ERROR_MEMORY;
1646
1689
int bytespersample = bitspersample / 8;
1647
1690
int bytesperpixel = bytespersample * samplesperpixel;
1657
1700
bThrowMessage = TRUE;
1660
throw "Parsing error";
1703
throw FI_MSG_ERROR_PARSING;
1663
1706
channel += stripsize;
1666
1709
// reconstruct the picture
1667
for (int l = 0; l < nrow; l++) {
1710
for (int l = 0; l < nrow; l++) {
1670
1712
for(sample = 0; sample < samplesperpixel; sample++) {
1671
1713
BYTE *src_bits = channel + l * src_line;
1690
1733
} else if(loadMethod == LoadAsTiled) {
1734
// ---------------------------------------------------------------------------------
1735
// Tiled image loading
1736
// ---------------------------------------------------------------------------------
1691
1738
uint32 tileWidth, tileHeight;
1692
1739
uint32 src_line = 0;
1694
1741
// create a new DIB
1695
1742
dib = CreateImageType(image_type, width, height, bitspersample, samplesperpixel);
1696
1743
if (dib == NULL) {
1697
throw "No space for DIB image";
1744
throw FI_MSG_ERROR_MEMORY;
1700
1747
// fill in the resolution (english or universal)
1716
1763
// allocate tile buffer
1717
1764
BYTE *tileBuffer = (BYTE*)malloc(tileSize * sizeof(BYTE));
1718
if(tileBuffer == NULL) throw "Not enough space for tile buffer";
1765
if(tileBuffer == NULL) throw FI_MSG_ERROR_MEMORY;
1720
1767
// calculate src line and dst pitch
1721
1768
int dst_pitch = FreeImage_GetPitch(dib);
1726
1773
// In the tiff file the lines are save from up to down
1727
1774
// In a DIB the lines must be saved from down to up
1729
bits = FreeImage_GetScanLine(dib, height - 1);
1776
BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
1731
1778
// read the tiff lines and save them in the DIB
1741
1788
// read one tile
1742
1789
if (TIFFReadTile(tif, tileBuffer, x, y, 0, 0) < 0) {
1743
1790
free(tileBuffer);
1744
throw "Corrupted tiled TIFF file!";
1791
throw "Corrupted tiled TIFF file";
1746
1793
// convert to strip
1747
1794
if(x + tileWidth > width) {
1770
1817
free(tileBuffer);
1819
} else if(loadMethod == LoadAsRGBF) {
1820
// ---------------------------------------------------------------------------------
1822
// ---------------------------------------------------------------------------------
1824
double stonits; // input conversion to nits
1825
if (!TIFFGetField(tif, TIFFTAG_STONITS, &stonits)) {
1830
dib = CreateImageType(image_type, width, height, bitspersample, samplesperpixel);
1832
throw FI_MSG_ERROR_MEMORY;
1835
// fill in the resolution (english or universal)
1837
ReadResolution(tif, dib);
1839
// calculate the line + pitch (separate for scr & dest)
1841
tsize_t src_line = TIFFScanlineSize(tif);
1842
int dst_pitch = FreeImage_GetPitch(dib);
1844
// In the tiff file the lines are save from up to down
1845
// In a DIB the lines must be saved from down to up
1847
BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
1849
// read the tiff lines and save them in the DIB
1851
if(planar_config == PLANARCONFIG_CONTIG) {
1852
BYTE *buf = (BYTE*)malloc(TIFFStripSize(tif) * sizeof(BYTE));
1853
if(buf == NULL) throw FI_MSG_ERROR_MEMORY;
1855
for (uint32 y = 0; y < height; y += rowsperstrip) {
1856
int32 nrow = (y + rowsperstrip > height ? height - y : rowsperstrip);
1858
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), buf, nrow * src_line) == -1) {
1860
throw FI_MSG_ERROR_PARSING;
1862
// convert from XYZ to RGB
1863
for (int l = 0; l < nrow; l++) {
1864
tiff_ConvertLineXYZToRGB(bits, buf + l * src_line, stonits, width);
1871
else if(planar_config == PLANARCONFIG_SEPARATE) {
1872
// this cannot happend according to the LogLuv specification
1873
throw "Unable to handle PLANARCONFIG_SEPARATE LogLuv images";
1773
throw "Unknown format";
1877
// ---------------------------------------------------------------------------------
1878
// Unknown or unsupported format
1879
// ---------------------------------------------------------------------------------
1881
throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
1776
1884
// copy ICC profile data (must be done after FreeImage_Allocate)
1866
1974
// unassociated alpha data is transparency information
1867
1975
sampleinfo[0] = EXTRASAMPLE_UNASSALPHA;
1868
1976
TIFFSetField(out, TIFFTAG_EXTRASAMPLES, 1, sampleinfo);
1977
} else if(image_type == FIT_RGBF) {
1978
// 96-bit RGBF => store with a LogLuv encoding
1980
samplesperpixel = 3;
1981
bitspersample = bitsperpixel / samplesperpixel;
1982
photometric = PHOTOMETRIC_LOGLUV;
1983
// the library converts to and from floating-point XYZ CIE values
1984
TIFFSetField(out, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_FLOAT);
1985
// TIFFSetField(out, TIFFTAG_STONITS, 1.0); // assume unknown
1870
1987
// special image type (int, long, double, ...)
1964
2082
BYTE *trns = FreeImage_GetTransparencyTable(dib);
1966
2084
BYTE *buffer = (BYTE *)malloc(2 * width * sizeof(BYTE));
2085
if(buffer == NULL) throw FI_MSG_ERROR_MEMORY;
1968
2087
for (y = height - 1; y >= 0; y--) {
1969
2088
BYTE *bits = FreeImage_GetScanLine(dib, y);
1992
2111
BYTE *buffer = (BYTE *)malloc(pitch * sizeof(BYTE));
2112
if(buffer == NULL) throw FI_MSG_ERROR_MEMORY;
1993
2113
for (y = 0; y < height; y++) {
1994
2114
// get a copy of the scanline
1995
2115
memcpy(buffer, FreeImage_GetScanLine(dib, height - y - 1), pitch);
2159
} else if(image_type == FIT_RGBF) {
2160
// RGBF image => store as XYZ using a LogLuv encoding
2162
BYTE *buffer = (BYTE *)malloc(pitch * sizeof(BYTE));
2163
if(buffer == NULL) throw FI_MSG_ERROR_MEMORY;
2165
for (y = 0; y < height; y++) {
2166
// get a copy of the scanline and convert from RGB to XYZ
2167
tiff_ConvertLineRGBToXYZ(buffer, FreeImage_GetScanLine(dib, height - y - 1), width);
2168
// write the scanline to disc
2169
TIFFWriteScanline(out, buffer, y, 0);
2039
2173
// special bitmap type (int, long, double, etc.)
2048
2182
BYTE *buffer = (BYTE *)malloc(pitch * sizeof(BYTE));
2183
if(buffer == NULL) throw FI_MSG_ERROR_MEMORY;
2049
2185
for (y = 0; y < height; y++) {
2050
2186
// get a copy of the scanline
2051
2187
memcpy(buffer, FreeImage_GetScanLine(dib, height - y - 1), pitch);