~cosme/ubuntu/precise/freeimage/freeimage-3.15.1

« back to all changes in this revision

Viewing changes to Source/FreeImage/PluginTIFF.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Cosme Domínguez Díaz
  • Date: 2010-07-20 13:42:15 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100720134215-xt1454zaedv3b604
Tags: 3.13.1-0ubuntu1
* New upstream release. Closes: (LP: #607800)
 - Updated debian/freeimage-get-orig-source script.
 - Removing no longer necessary debian/patches/* and
   the patch system in debian/rules.
 - Updated debian/rules to work with the new Makefiles.
 - Drop from -O3 to -O2 and use lzma compression saves
   ~10 MB of free space. 
* lintian stuff
 - fixed debhelper-but-no-misc-depends
 - fixed ldconfig-symlink-missing-for-shlib

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
#endif
36
36
 
37
37
#include "../LibTIFF/tiffiop.h"
38
 
 
39
38
#include "FreeImage.h"
40
39
#include "Utilities.h"
41
 
 
42
40
#include "../Metadata/FreeImageTag.h"
43
41
 
44
42
// ----------------------------------------------------------
60
58
BOOL tiff_read_exif_tags(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib);
61
59
 
62
60
// ----------------------------------------------------------
 
61
//   LogLuv conversion functions interface (see TIFFLogLuv.cpp)
 
62
// ----------------------------------------------------------
 
63
 
 
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);
 
66
 
 
67
// ----------------------------------------------------------
63
68
 
64
69
/** Supported loading methods */
65
70
typedef enum {
67
72
        LoadAsCMYK                      = 1, 
68
73
        LoadAs8BitTrns          = 2, 
69
74
        LoadAsGenericStrip      = 3, 
70
 
        LoadAsTiled                     = 4
 
75
        LoadAsTiled                     = 4,
 
76
        LoadAsRGBF                      = 5
71
77
} TIFFLoadMethod;
72
78
 
73
79
// ----------------------------------------------------------
323
329
        if (resUnit == RESUNIT_NONE && fResX > 0.0 && fResY > 0.0) {
324
330
                resUnit = RESUNIT_INCH;
325
331
        }
326
 
 
327
 
        BITMAPINFOHEADER *pInfoHeader = FreeImage_GetInfoHeader(dib);
328
 
 
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));
335
338
        }
336
339
}
337
340
 
342
345
WriteResolution(TIFF *tiff, FIBITMAP *dib) {
343
346
        double res;
344
347
 
345
 
        BITMAPINFOHEADER *pInfoHeader = FreeImage_GetInfoHeader(dib);
346
 
 
347
348
        TIFFSetField(tiff, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
348
349
 
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);
351
352
 
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);
354
355
}
355
356
 
557
558
                                        case 64:
558
559
                                                fit = FIT_DOUBLE;
559
560
                                                break;
 
561
                                        case 96:
 
562
                                                fit = FIT_RGBF;
 
563
                                                break;
560
564
                                }
561
565
                                break;
562
566
                        case SAMPLEFORMAT_COMPLEXIEEEFP:
640
644
        uint16 compression;
641
645
        uint16 bitsperpixel = bitspersample * samplesperpixel;
642
646
 
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;
968
974
                (type == FIT_DOUBLE)  ||
969
975
                (type == FIT_COMPLEX) || 
970
976
                (type == FIT_RGB16)   || 
971
 
                (type == FIT_RGBA16)
 
977
                (type == FIT_RGBA16)  || 
 
978
                (type == FIT_RGBF)
972
979
        );
973
980
}
974
981
 
1100
1107
                case PHOTOMETRIC_CIELAB:
1101
1108
                case PHOTOMETRIC_ICCLAB:
1102
1109
                case PHOTOMETRIC_ITULAB:
 
1110
                        loadMethod = LoadAsRBGA;
 
1111
                        break;
1103
1112
                case PHOTOMETRIC_LOGLUV:
1104
 
                        loadMethod = LoadAsRBGA;
 
1113
                        loadMethod = LoadAsRGBF;
1105
1114
                        break;
1106
1115
                case PHOTOMETRIC_SEPARATED:
1107
1116
                        if(planar_config == PLANARCONFIG_CONTIG) {
1160
1169
                uint16 planar_config;
1161
1170
 
1162
1171
                FIBITMAP *dib = NULL;
1163
 
                BYTE *bits = NULL;              // pointer to dib data
1164
1172
                uint32 iccSize = 0;             // ICC profile length
1165
1173
                void *iccBuf = NULL;    // ICC profile data             
1166
1174
 
1168
1176
                        fi_TIFFIO *fio = (fi_TIFFIO*)data;
1169
1177
                        tif = fio->tif;
1170
1178
 
1171
 
                        if (page != -1)
1172
 
                                if (!tif || !TIFFSetDirectory(tif, (tdir_t)page))
 
1179
                        if (page != -1) {
 
1180
                                if (!tif || !TIFFSetDirectory(tif, (tdir_t)page)) {
1173
1181
                                        throw "Error encountered while opening TIFF file";                      
 
1182
                                }
 
1183
                        }
 
1184
 
 
1185
                        // first, get the photometric, the compression and basic metadata
 
1186
                        // ---------------------------------------------------------------------------------
1174
1187
 
1175
1188
                        TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
1176
1189
                        TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression);
 
1190
 
 
1191
                        // check for HDR formats
 
1192
                        // ---------------------------------------------------------------------------------
 
1193
 
 
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";
 
1198
                                }
 
1199
                                // set decoder to output in IEEE 32-bit float XYZ values
 
1200
                                TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_FLOAT);
 
1201
                        }
 
1202
 
 
1203
                        // ---------------------------------------------------------------------------------
 
1204
 
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
                        // ---------------------------------------------------------------------------------
1187
1215
 
1188
 
                        if (compression == COMPRESSION_OJPEG)
1189
 
                                throw "6.0 JPEG encoding is not supported";
1190
 
 
1191
1216
                        if((photometric == PHOTOMETRIC_SEPARATED) && (bitspersample == 16))
1192
1217
                                throw "Unable to handle 16-bit CMYK TIFF";
1193
1218
 
1211
1236
                        // ---------------------------------------------------------------------------------
1212
1237
 
1213
1238
                        if(loadMethod == LoadAsRBGA) {
 
1239
                                // ---------------------------------------------------------------------------------
 
1240
                                // RGB[A] loading using the TIFFReadRGBAImage() API
 
1241
                                // ---------------------------------------------------------------------------------
 
1242
 
1214
1243
                                BOOL has_alpha = FALSE;   
1215
1244
 
1216
1245
                                // Read the whole image into one big RGBA buffer and then 
1218
1247
                                // TIFFReadRGBAImage() API that we trust.
1219
1248
 
1220
1249
                                uint32 *raster = (uint32*)_TIFFmalloc(width * height * sizeof(uint32));
1221
 
 
1222
 
                                if (raster == NULL)
1223
 
                                        throw "No space for raster buffer";
 
1250
                                if (raster == NULL) {
 
1251
                                        throw FI_MSG_ERROR_MEMORY;
 
1252
                                }
1224
1253
 
1225
1254
                                // read the image in one chunk into an RGBA array
1226
1255
 
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;
1230
1259
                                }
1231
1260
 
1232
1261
                                // TIFFReadRGBAImage always deliveres 3 or 4 samples per pixel images
1252
1281
 
1253
1282
                                        _TIFFfree(raster);
1254
1283
 
1255
 
                                        throw "DIB allocation failed";
 
1284
                                        throw FI_MSG_ERROR_DIB_MEMORY;
1256
1285
                                }
1257
1286
                                
1258
1287
                                // fill in the resolution (english or universal)
1269
1298
                                if (samplesperpixel == 4) {
1270
1299
                                        // 32-bit RGBA
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]);
1286
1315
                                } else {
1287
1316
                                        // 24-bit RGB
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);
1304
1333
 
1305
1334
                        } else if(loadMethod == LoadAs8BitTrns) {
 
1335
                                // ---------------------------------------------------------------------------------
 
1336
                                // 8-bit + 8-bit alpha layer loading
 
1337
                                // ---------------------------------------------------------------------------------
 
1338
 
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;
1310
1343
                                }
1311
1344
 
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
1335
1368
 
1336
 
                                bits = FreeImage_GetBits(dib) + height * dst_pitch;
 
1369
                                BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
1337
1370
 
1338
1371
                                // read the tiff lines and save them in the DIB
1339
1372
 
1340
1373
                                if(planar_config == PLANARCONFIG_CONTIG) {
1341
1374
 
1342
1375
                                        BYTE *buf = (BYTE*)malloc(TIFFStripSize(tif) * sizeof(BYTE));
 
1376
                                        if(buf == NULL) throw FI_MSG_ERROR_MEMORY;
 
1377
 
1343
1378
 
1344
1379
                                        for (uint32 y = 0; y < height; y += rowsperstrip) {
1345
1380
                                                int32 nrow = (y + rowsperstrip > height ? height - y : rowsperstrip);
1346
1381
 
1347
1382
                                                if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), buf, nrow * src_line) == -1) {
1348
1383
                                                        free(buf);
1349
 
                                                        throw "Parsing error";
 
1384
                                                        throw FI_MSG_ERROR_PARSING;
1350
1385
                                                }
1351
1386
                                                for (int l = 0; l < nrow; l++) {
1352
 
                                                        bits -= dst_pitch;
1353
 
 
1354
1387
                                                        BYTE *p = bits;
1355
1388
                                                        BYTE *b = buf + l * src_line;
1356
1389
 
1363
1396
                                                                p++;
1364
1397
                                                                b += samplesperpixel;
1365
1398
                                                        }
 
1399
                                                        bits -= dst_pitch;
1366
1400
                                                }
1367
1401
                                        }
1368
1402
 
1379
1413
 
1380
1414
                                                if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), grey, nrow * src_line) == -1) {
1381
1415
                                                        free(buf);
1382
 
                                                        throw "Parsing error";
 
1416
                                                        throw FI_MSG_ERROR_PARSING;
1383
1417
                                                } 
1384
1418
                                                if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 1), alpha, nrow * src_line) == -1) {
1385
1419
                                                        free(buf);
1386
 
                                                        throw "Parsing error";
 
1420
                                                        throw FI_MSG_ERROR_PARSING;
1387
1421
                                                } 
1388
1422
 
1389
1423
                                                for (int l = 0; l < nrow; l++) {
1390
 
                                                        bits -= dst_pitch;
1391
 
 
1392
1424
                                                        BYTE *p = bits;
1393
1425
                                                        BYTE *g = grey + l * src_line;
1394
1426
                                                        BYTE *a = alpha + l * src_line;
1403
1435
                                                                g++;
1404
1436
                                                                a++;
1405
1437
                                                        }
 
1438
                                                        bits -= dst_pitch;
1406
1439
                                                }
1407
1440
                                        }
1408
1441
 
1409
1442
                                        free(buf);
1410
1443
 
1411
1444
                                }
1412
 
 
1413
1445
                                
1414
1446
                                FreeImage_SetTransparencyTable(dib, &trns[0], 256);
1415
1447
                                FreeImage_SetTransparent(dib, TRUE);
1416
1448
 
1417
1449
                        } else if(loadMethod == LoadAsCMYK) {
 
1450
                                // ---------------------------------------------------------------------------------
 
1451
                                // CMYK loading
 
1452
                                // ---------------------------------------------------------------------------------
 
1453
 
1418
1454
                                BOOL has_alpha = FALSE;    
1419
1455
 
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;
1435
1471
                                }
1436
1472
 
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
1448
1484
 
1449
 
                                bits = FreeImage_GetBits(dib) + height * dst_pitch;
 
1485
                                BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
1450
1486
 
1451
1487
                                // read the tiff lines and save them in the DIB
1452
1488
 
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;
1455
1492
 
1456
1493
                                        for (uint32 y = 0; y < height; y += rowsperstrip) {
1457
1494
                                                int32 nrow = (y + rowsperstrip > height ? height - y : rowsperstrip);
1458
1495
 
1459
1496
                                                if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), buf, nrow * src_line) == -1) {
1460
1497
                                                        free(buf);
1461
 
                                                        throw "Parsing error";
 
1498
                                                        throw FI_MSG_ERROR_PARSING;
1462
1499
                                                } 
1463
1500
                                                if(isCMYKA) {
1464
1501
                                                        // CMYKA picture
1465
1502
                                                        for (int l = 0; l < nrow; l++) {
1466
 
                                                                bits -= dst_pitch;
1467
 
 
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;
1487
1522
                                                                        p += spp;
1488
1523
                                                                }
 
1524
                                                                bits -= dst_pitch;
1489
1525
                                                        }                                                               
1490
1526
                                                }
1491
1527
                                                else  {
1492
1528
                                                        // CMYK picture: just copy
1493
 
                                                        for (int l = 0; l < nrow; l++) {
1494
 
                                                                bits -= dst_pitch;
 
1529
                                                        for (int l = 0; l < nrow; l++) {                                                                
1495
1530
                                                                BYTE *b = buf + l * src_line;
1496
1531
                                                                memcpy(bits, b, src_line);
 
1532
                                                                bits -= dst_pitch;
1497
1533
                                                        }
1498
1534
                                                }                                               
1499
1535
                                        }
1505
1541
                                        BYTE *channel;
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;
1508
1545
 
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) {
1516
1553
                                                                free(buf);
1517
 
                                                                throw "Parsing error";
 
1554
                                                                throw FI_MSG_ERROR_PARSING;
1518
1555
                                                        } 
1519
1556
                                                        channel += stripsize;
1520
1557
                                                }
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++) {
1524
 
                                                                bits -= dst_pitch;                                                              
1525
1561
                                                                channel = buf;
1526
1562
                                                                for(sample = 0; sample < spp; sample++) {
1527
1563
                                                                        BYTE *src_bits = channel + l * src_line;
1532
1568
                                                                        }
1533
1569
                                                                        channel += stripsize;
1534
1570
                                                                }
 
1571
                                                                bits -= dst_pitch;
1535
1572
                                                        }
1536
1573
                                                }
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++) {
1540
 
                                                                bits -= dst_pitch;                                                              
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;
1555
1591
                                                                }
 
1592
                                                                bits -= dst_pitch;
1556
1593
                                                        }
1557
1594
                                                }
1558
1595
                                                else  {                                                 
1559
1596
                                                        // CMYK picture: convert to RGB
1560
 
                                                        for (int l = 0; l < nrow; l++) {
1561
 
                                                                bits -= dst_pitch;                                                              
 
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;
1571
1607
                                                                        dst_bits[FI_RGBA_BLUE]  = (k*(255-y_channel[x]))/255;
1572
1608
                                                                        dst_bits += spp;
1573
1609
                                                                }
 
1610
                                                                bits -= dst_pitch;
1574
1611
                                                        }
1575
1612
                                                }                                               
1576
1613
                                        }
1581
1618
                                FreeImage_SetTransparent(dib, has_alpha);
1582
1619
 
1583
1620
                        } else if(loadMethod == LoadAsGenericStrip) {
 
1621
                                // ---------------------------------------------------------------------------------
 
1622
                                // Generic loading
 
1623
                                // ---------------------------------------------------------------------------------
 
1624
 
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;
1588
1629
                                }
1589
1630
 
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
1605
1646
 
1606
 
                                bits = FreeImage_GetBits(dib) + height * dst_pitch;
 
1647
                                BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
1607
1648
 
1608
1649
                                // read the tiff lines and save them in the DIB
1609
1650
 
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;
1613
1655
 
1614
1656
                                        for (uint32 y = 0; y < height; y += rowsperstrip) {
1615
1657
                                                int32 nrow = (y + rowsperstrip > height ? height - y : rowsperstrip);
1619
1661
                                                        bThrowMessage = TRUE;                                                   
1620
1662
                                                        /*
1621
1663
                                                        free(buf);
1622
 
                                                        throw "Parsing error";
 
1664
                                                        throw FI_MSG_ERROR_PARSING;
1623
1665
                                                        */
1624
1666
                                                } 
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++) {
1628
 
                                                        bits -= dst_pitch;
 
1669
                                                for (int l = 0; l < nrow; l++) {                                                        
1629
1670
                                                        memcpy(bits, buf + l * src_line, src_line);
 
1671
                                                        bits -= dst_pitch;
1630
1672
                                                }
1631
1673
                                        }
1632
1674
 
1642
1684
                                        BYTE *channel;
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;
1645
1688
                                        
1646
1689
                                        int bytespersample = bitspersample / 8;
1647
1690
                                        int bytesperpixel = bytespersample * samplesperpixel;
1657
1700
                                                                bThrowMessage = TRUE;                                                           
1658
1701
                                                                /*
1659
1702
                                                                free(buf);
1660
 
                                                                throw "Parsing error";
 
1703
                                                                throw FI_MSG_ERROR_PARSING;
1661
1704
                                                                */
1662
1705
                                                        } 
1663
1706
                                                        channel += stripsize;
1664
1707
                                                }
1665
1708
 
1666
1709
                                                // reconstruct the picture                                              
1667
 
                                                for (int l = 0; l < nrow; l++) {
1668
 
                                                        bits -= dst_pitch;                                                              
 
1710
                                                for (int l = 0; l < nrow; l++) {                                                        
1669
1711
                                                        channel = buf;
1670
1712
                                                        for(sample = 0; sample < samplesperpixel; sample++) {
1671
1713
                                                                BYTE *src_bits = channel + l * src_line;
1677
1719
                                                                }
1678
1720
                                                                channel += stripsize;
1679
1721
                                                        }
 
1722
                                                        bits -= dst_pitch;
1680
1723
                                                }
1681
1724
                                        }
1682
1725
 
1688
1731
                                }
1689
1732
 
1690
1733
                        } else if(loadMethod == LoadAsTiled) {
 
1734
                                // ---------------------------------------------------------------------------------
 
1735
                                // Tiled image loading
 
1736
                                // ---------------------------------------------------------------------------------
 
1737
 
1691
1738
                                uint32 tileWidth, tileHeight;
1692
1739
                                uint32 src_line = 0;
1693
1740
 
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;
1698
1745
                                }
1699
1746
 
1700
1747
                                // fill in the resolution (english or universal)
1715
1762
 
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;
1719
1766
 
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
1728
1775
 
1729
 
                                bits = FreeImage_GetScanLine(dib, height - 1);
 
1776
                                BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
1730
1777
 
1731
1778
                                // read the tiff lines and save them in the DIB
1732
1779
 
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";
1745
1792
                                                        }
1746
1793
                                                        // convert to strip
1747
1794
                                                        if(x + tileWidth > width) {
1769
1816
 
1770
1817
                                free(tileBuffer);
1771
1818
 
 
1819
                        } else if(loadMethod == LoadAsRGBF) {
 
1820
                                // ---------------------------------------------------------------------------------
 
1821
                                // RGBF loading
 
1822
                                // ---------------------------------------------------------------------------------
 
1823
 
 
1824
                                double  stonits;        // input conversion to nits
 
1825
                                if (!TIFFGetField(tif, TIFFTAG_STONITS, &stonits)) {
 
1826
                                        stonits = 1;
 
1827
                                }
 
1828
                                
 
1829
                                // create a new DIB
 
1830
                                dib = CreateImageType(image_type, width, height, bitspersample, samplesperpixel);
 
1831
                                if (dib == NULL) {
 
1832
                                        throw FI_MSG_ERROR_MEMORY;
 
1833
                                }
 
1834
 
 
1835
                                // fill in the resolution (english or universal)
 
1836
 
 
1837
                                ReadResolution(tif, dib);
 
1838
 
 
1839
                                // calculate the line + pitch (separate for scr & dest)
 
1840
 
 
1841
                                tsize_t src_line = TIFFScanlineSize(tif);
 
1842
                                int dst_pitch = FreeImage_GetPitch(dib);
 
1843
 
 
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
 
1846
 
 
1847
                                BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
 
1848
 
 
1849
                                // read the tiff lines and save them in the DIB
 
1850
 
 
1851
                                if(planar_config == PLANARCONFIG_CONTIG) {
 
1852
                                        BYTE *buf = (BYTE*)malloc(TIFFStripSize(tif) * sizeof(BYTE));
 
1853
                                        if(buf == NULL) throw FI_MSG_ERROR_MEMORY;
 
1854
 
 
1855
                                        for (uint32 y = 0; y < height; y += rowsperstrip) {
 
1856
                                                int32 nrow = (y + rowsperstrip > height ? height - y : rowsperstrip);
 
1857
 
 
1858
                                                if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), buf, nrow * src_line) == -1) {
 
1859
                                                        free(buf);
 
1860
                                                        throw FI_MSG_ERROR_PARSING;
 
1861
                                                } 
 
1862
                                                // convert from XYZ to RGB
 
1863
                                                for (int l = 0; l < nrow; l++) {                                                
 
1864
                                                        tiff_ConvertLineXYZToRGB(bits, buf + l * src_line, stonits, width);
 
1865
                                                        bits -= dst_pitch;
 
1866
                                                }
 
1867
                                        }
 
1868
 
 
1869
                                        free(buf);
 
1870
                                }
 
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";
 
1874
                                }
 
1875
 
1772
1876
                        } else {
1773
 
                                throw "Unknown format";
 
1877
                                // ---------------------------------------------------------------------------------
 
1878
                                // Unknown or unsupported format
 
1879
                                // ---------------------------------------------------------------------------------
 
1880
 
 
1881
                                throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
1774
1882
                        }
1775
1883
 
1776
1884
                        // copy ICC profile data (must be done after FreeImage_Allocate)
1809
1917
                uint16 bitspersample;
1810
1918
                uint16 samplesperpixel;
1811
1919
                uint16 photometric;
1812
 
                uint16 pitch;
 
1920
                uint32 pitch;
1813
1921
                int32 x, y;
1814
1922
 
1815
1923
                FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
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
 
1979
 
 
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 
1869
1986
                } else {
1870
1987
                        // special image type (int, long, double, ...)
1871
1988
 
1920
2037
                        RGBQUAD *pal = FreeImage_GetPalette(dib);
1921
2038
 
1922
2039
                        r = (uint16 *) _TIFFmalloc(sizeof(uint16) * 3 * nColors);
 
2040
                        if(r == NULL) throw FI_MSG_ERROR_MEMORY;
1923
2041
                        g = r + nColors;
1924
2042
                        b = g + nColors;
1925
2043
 
1947
2065
                // and save them in the TIF
1948
2066
                // -------------------------------------
1949
2067
                
1950
 
                pitch = (uint16)FreeImage_GetPitch(dib);
 
2068
                pitch = FreeImage_GetPitch(dib);
1951
2069
 
1952
2070
                if(image_type == FIT_BITMAP) {
1953
2071
                        // standard bitmap type
1964
2082
                                                BYTE *trns = FreeImage_GetTransparencyTable(dib);
1965
2083
 
1966
2084
                                                BYTE *buffer = (BYTE *)malloc(2 * width * sizeof(BYTE));
 
2085
                                                if(buffer == NULL) throw FI_MSG_ERROR_MEMORY;
1967
2086
 
1968
2087
                                                for (y = height - 1; y >= 0; y--) {
1969
2088
                                                        BYTE *bits = FreeImage_GetScanLine(dib, y);
1990
2109
                                        else {
1991
2110
                                                // other cases
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);
2006
2126
                                case 32:
2007
2127
                                {
2008
2128
                                        BYTE *buffer = (BYTE *)malloc(pitch * sizeof(BYTE));
 
2129
                                        if(buffer == NULL) throw FI_MSG_ERROR_MEMORY;
2009
2130
 
2010
2131
                                        for (y = 0; y < height; y++) {
2011
2132
                                                // get a copy of the scanline
2035
2156
                                }
2036
2157
                        }
2037
2158
 
 
2159
                } else if(image_type == FIT_RGBF) {
 
2160
                        // RGBF image => store as XYZ using a LogLuv encoding
 
2161
 
 
2162
                        BYTE *buffer = (BYTE *)malloc(pitch * sizeof(BYTE));
 
2163
                        if(buffer == NULL) throw FI_MSG_ERROR_MEMORY;
 
2164
 
 
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);
 
2170
                        }
 
2171
                        free(buffer);
2038
2172
                } else {
2039
2173
                        // special bitmap type (int, long, double, etc.)
2040
2174
 
2046
2180
                                case 128:
2047
2181
                                {
2048
2182
                                        BYTE *buffer = (BYTE *)malloc(pitch * sizeof(BYTE));
 
2183
                                        if(buffer == NULL) throw FI_MSG_ERROR_MEMORY;
 
2184
 
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);