~ubuntu-branches/ubuntu/saucy/digikam/saucy

« back to all changes in this revision

Viewing changes to libs/dimg/loaders/tiffloader.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Scott Kitterman
  • Date: 2010-12-21 23:19:11 UTC
  • mfrom: (1.2.33 upstream) (3.1.7 experimental)
  • Revision ID: james.westby@ubuntu.com-20101221231911-z9jip7s5aht1jqn9
Tags: 2:1.7.0-1ubuntu1
* Merge from Debian Experimental. Remaining Ubuntu changes:
  - Export .pot name and copy to plugins in debian/rules
  - Version build-depends on kipi-plugins-dev to ensure build is against the
    same version on all archs
* Drop debian/patches/kubuntu_01_linker.diff, incoporated upstream
* Remove patches directory and unused patches

Show diffs side-by-side

added added

removed removed

Lines of Context:
103
103
}
104
104
 
105
105
TIFFLoader::TIFFLoader(DImg* image)
106
 
          : DImgLoader(image)
 
106
    : DImgLoader(image)
107
107
{
108
108
    m_hasAlpha   = false;
109
109
    m_sixteenBit = false;
110
110
}
111
111
 
112
 
bool TIFFLoader::load(const QString& filePath, DImgLoaderObserver *observer)
 
112
bool TIFFLoader::load(const QString& filePath, DImgLoaderObserver* observer)
113
113
{
114
114
    readMetadata(filePath, DImg::TIFF);
115
115
 
124
124
    // Open the file
125
125
 
126
126
    TIFF* tif = TIFFOpen(QFile::encodeName(filePath), "r");
 
127
 
127
128
    if (!tif)
128
129
    {
129
130
        kDebug() << "Cannot open image file.";
158
159
        || rows_per_strip == 0 || rows_per_strip == (unsigned int)-1)
159
160
    {
160
161
        kWarning()  << "TIFF loader: Cannot handle non-stripped images. Loading file "
161
 
                         << filePath;
 
162
                    << filePath;
162
163
        TIFFClose(tif);
163
164
        loadingFailed();
164
165
        return false;
170
171
        rows_per_strip > h)
171
172
    {
172
173
        kWarning() << "TIFF loader: Encountered invalid value 0 in image."
173
 
                        << " bits_per_sample " << bits_per_sample
174
 
                        << " samples_per_pixel " << samples_per_pixel
175
 
                        << " rows_per_strip " << rows_per_strip
176
 
                        << " Loading file " << filePath;
 
174
                   << " bits_per_sample " << bits_per_sample
 
175
                   << " samples_per_pixel " << samples_per_pixel
 
176
                   << " rows_per_strip " << rows_per_strip
 
177
                   << " Loading file " << filePath;
177
178
        TIFFClose(tif);
178
179
        loadingFailed();
179
180
        return false;
185
186
    // http://www.awaresystems.be/imaging/tiff/tifftags/photometricinterpretation.html
186
187
 
187
188
    TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &photometric);
 
189
 
188
190
    if (photometric != PHOTOMETRIC_RGB &&
189
191
        photometric != PHOTOMETRIC_MINISBLACK &&
190
192
        photometric != PHOTOMETRIC_PALETTE &&
191
193
        (m_loadFlags & LoadImageData))
192
194
    {
193
195
        kWarning() << "Can not handle image without RGB color-space: "
194
 
                        << photometric;
 
196
                   << photometric;
195
197
        TIFFClose(tif);
196
198
        loadingFailed();
197
199
        return false;
198
200
    }
199
201
 
200
202
    int colorModel = DImg::COLORMODELUNKNOWN;
 
203
 
201
204
    switch (photometric)
202
205
    {
203
206
        case PHOTOMETRIC_MINISWHITE:
231
234
    }
232
235
 
233
236
    if (samples_per_pixel == 4)
 
237
    {
234
238
        m_hasAlpha = true;
 
239
    }
235
240
    else
 
241
    {
236
242
        m_hasAlpha = false;
 
243
    }
237
244
 
238
245
    if (bits_per_sample == 16)
 
246
    {
239
247
        m_sixteenBit = true;
 
248
    }
240
249
    else
 
250
    {
241
251
        m_sixteenBit = false;
 
252
    }
242
253
 
243
254
    // -------------------------------------------------------------------
244
255
    // Read image ICC profile
245
256
 
246
257
    if (m_loadFlags & LoadICCData)
247
258
    {
248
 
        uchar  *profile_data=0;
 
259
        uchar*  profile_data=0;
249
260
        uint32  profile_size;
250
261
 
251
262
        if (TIFFGetField (tif, TIFFTAG_ICCPROFILE, &profile_size, &profile_data))
270
281
    if (m_loadFlags & LoadImageData)
271
282
    {
272
283
        if (observer)
 
284
        {
273
285
            observer->progressInfo(m_image, 0.1F);
 
286
        }
274
287
 
275
288
        strip_size    = TIFFStripSize(tif);
276
289
        num_of_strips = TIFFNumberOfStrips(tif);
278
291
        if (bits_per_sample == 16)          // 16 bits image.
279
292
        {
280
293
            data  = new_failureTolerant(w*h*8);
281
 
            uchar *strip = new_failureTolerant(strip_size);
 
294
            uchar* strip = new_failureTolerant(strip_size);
 
295
 
282
296
            if (!data || !strip)
283
297
            {
284
298
                kDebug() << "Failed to allocate memory for TIFF image" << filePath;
288
302
                loadingFailed();
289
303
                return false;
290
304
            }
 
305
 
291
306
            long offset    = 0;
292
307
            long bytesRead = 0;
293
308
 
298
313
                if (observer && st == checkpoint)
299
314
                {
300
315
                    checkpoint += granularity(observer, num_of_strips, 0.8F);
 
316
 
301
317
                    if (!observer->continueQuery(m_image))
302
318
                    {
303
319
                        delete [] data;
306
322
                        loadingFailed();
307
323
                        return false;
308
324
                    }
 
325
 
309
326
                    observer->progressInfo(m_image, 0.1 + (0.8 * ( ((float)st)/((float)num_of_strips) )));
310
327
                }
311
328
 
326
343
                    offset = 0;
327
344
                }
328
345
 
329
 
                ushort *stripPtr = (ushort*)(strip);
330
 
                ushort *dataPtr  = (ushort*)(data + offset);
331
 
                ushort *p;
 
346
                ushort* stripPtr = (ushort*)(strip);
 
347
                ushort* dataPtr  = (ushort*)(data + offset);
 
348
                ushort* p;
332
349
 
333
350
                // tiff data is read as BGR or ABGR or Greyscale
334
351
 
354
371
                            p[2] = *stripPtr++;
355
372
                            p[3] = 0xFFFF;         // set alpha to 100%
356
373
                        }
 
374
 
357
375
                        dataPtr += 4;
358
376
                    }
359
377
 
424
442
                                    p[0] = *stripPtr++;
425
443
                                    break;
426
444
                            }
427
 
                         }
 
445
                        }
428
446
 
429
447
                        dataPtr += 4;
430
448
                    }
452
470
                            p[0] = *stripPtr++;
453
471
                            p[3] = *stripPtr++;
454
472
                        }
 
473
 
455
474
                        dataPtr += 4;
456
475
                    }
457
476
 
499
518
                                    p[3] = *stripPtr++;
500
519
                                    break;
501
520
                            }
502
 
                         }
 
521
                        }
503
522
 
504
523
                        dataPtr += 4;
505
524
                    }
513
532
        else       // Non 16 bits images ==> get it on BGRA 8 bits.
514
533
        {
515
534
            data  = new_failureTolerant(w*h*4);
516
 
            uchar *strip = new_failureTolerant(w*rows_per_strip*4);
 
535
            uchar* strip = new_failureTolerant(w*rows_per_strip*4);
 
536
 
517
537
            if (!data || !strip)
518
538
            {
519
539
                kDebug() << "Failed to allocate memory for TIFF image" << filePath;
523
543
                loadingFailed();
524
544
                return false;
525
545
            }
 
546
 
526
547
            long offset     = 0;
527
548
            long pixelsRead = 0;
528
549
 
538
559
            if (!TIFFRGBAImageOK(tif, emsg) || !TIFFRGBAImageBegin(&img, tif, 0, emsg))
539
560
            {
540
561
                kDebug() << "Failed to set up RGBA reading of image, filename "
541
 
                        << TIFFFileName(tif) <<  " error message from Libtiff: " << emsg;
 
562
                         << TIFFFileName(tif) <<  " error message from Libtiff: " << emsg;
542
563
                delete [] data;
543
564
                delete [] strip;
544
565
                TIFFClose(tif);
554
575
                if (observer && row >= checkpoint)
555
576
                {
556
577
                    checkpoint += granularity(observer, h, 0.8F);
 
578
 
557
579
                    if (!observer->continueQuery(m_image))
558
580
                    {
559
581
                        delete [] data;
562
584
                        loadingFailed();
563
585
                        return false;
564
586
                    }
 
587
 
565
588
                    observer->progressInfo(m_image, 0.1 + (0.8 * ( ((float)row)/((float)h) )));
566
589
                }
567
590
 
568
591
                img.row_offset  = row;
569
592
                img.col_offset  = 0;
570
593
 
571
 
                if( row + rows_per_strip > img.height )
 
594
                if ( row + rows_per_strip > img.height )
 
595
                {
572
596
                    rows_to_read = img.height - row;
 
597
                }
573
598
                else
 
599
                {
574
600
                    rows_to_read = rows_per_strip;
 
601
                }
575
602
 
576
603
                // Read data
577
604
 
587
614
 
588
615
                pixelsRead = rows_to_read * img.width;
589
616
 
590
 
                uchar *stripPtr = (uchar*)(strip);
591
 
                uchar *dataPtr  = (uchar*)(data + offset);
592
 
                uchar *p;
 
617
                uchar* stripPtr = (uchar*)(strip);
 
618
                uchar* dataPtr  = (uchar*)(data + offset);
 
619
                uchar* p;
593
620
 
594
621
                // Reverse red and blue
595
622
 
629
656
    TIFFClose(tif);
630
657
 
631
658
    if (observer)
 
659
    {
632
660
        observer->progressInfo(m_image, 1.0);
 
661
    }
633
662
 
634
663
    imageWidth()  = w;
635
664
    imageHeight() = h;
641
670
    return true;
642
671
}
643
672
 
644
 
bool TIFFLoader::save(const QString& filePath, DImgLoaderObserver *observer)
 
673
bool TIFFLoader::save(const QString& filePath, DImgLoaderObserver* observer)
645
674
{
646
675
    uint32 w     = imageWidth();
647
676
    uint32 h     = imageHeight();
648
 
    uchar  *data = imageData();
 
677
    uchar*  data = imageData();
649
678
 
650
679
    // -------------------------------------------------------------------
651
680
    // TIFF error handling. If an errors/warnings occurs during reading,
657
686
    // -------------------------------------------------------------------
658
687
    // Open the file
659
688
 
660
 
    TIFF *tif = TIFFOpen(QFile::encodeName(filePath), "w");
 
689
    TIFF* tif = TIFFOpen(QFile::encodeName(filePath), "w");
 
690
 
661
691
    if (!tif)
662
692
    {
663
693
        kDebug() << "Cannot open target image file.";
691
721
        TIFFSetField(tif, TIFFTAG_PREDICTOR,   2);
692
722
    }
693
723
    else
 
724
    {
694
725
        TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
 
726
    }
695
727
 
696
728
    uint16 sampleinfo[1];
 
729
 
697
730
    if (imageHasAlpha())
698
731
    {
699
732
        sampleinfo[0] = EXTRASAMPLE_ASSOCALPHA;
716
749
    // Standard IPTC tag (available with libtiff 3.6.1)
717
750
 
718
751
    QByteArray ba = metaData.getIptc(true);
 
752
 
719
753
    if (!ba.isEmpty())
720
754
    {
721
755
#if defined(TIFFTAG_PHOTOSHOP)
722
 
        TIFFSetField (tif, TIFFTAG_PHOTOSHOP, (uint32)ba.size(), (uchar *)ba.data());
 
756
        TIFFSetField (tif, TIFFTAG_PHOTOSHOP, (uint32)ba.size(), (uchar*)ba.data());
723
757
#endif
724
758
    }
725
759
 
758
792
    if (!profile_rawdata.isEmpty())
759
793
    {
760
794
#if defined(TIFFTAG_ICCPROFILE)
761
 
        TIFFSetField(tif, TIFFTAG_ICCPROFILE, (uint32)profile_rawdata.size(), (uchar *)profile_rawdata.data());
 
795
        TIFFSetField(tif, TIFFTAG_ICCPROFILE, (uint32)profile_rawdata.size(), (uchar*)profile_rawdata.data());
762
796
#endif
763
797
    }
764
798
 
766
800
    // Write full image data in tiff directory IFD0
767
801
 
768
802
    if (observer)
 
803
    {
769
804
        observer->progressInfo(m_image, 0.1F);
 
805
    }
770
806
 
771
 
    uchar  *pixel;
 
807
    uchar*  pixel;
772
808
    double  alpha_factor;
773
809
    uint32  x, y;
774
810
    uint8   r8, g8, b8, a8=0;
775
811
    uint16  r16, g16, b16, a16=0;
776
812
    int     i=0;
777
813
 
778
 
    uint8 *buf = (uint8 *)_TIFFmalloc(TIFFScanlineSize(tif));
 
814
    uint8* buf = (uint8*)_TIFFmalloc(TIFFScanlineSize(tif));
 
815
 
779
816
    if (!buf)
780
817
    {
781
818
        kDebug() << "Cannot allocate memory buffer for main image.";
791
828
        if (observer && y == checkpoint)
792
829
        {
793
830
            checkpoint += granularity(observer, h, 0.8F);
 
831
 
794
832
            if (!observer->continueQuery(m_image))
795
833
            {
796
834
                _TIFFfree(buf);
797
835
                TIFFClose(tif);
798
836
                return false;
799
837
            }
 
838
 
800
839
            observer->progressInfo(m_image, 0.1 + (0.8 * ( ((float)y)/((float)h) )));
801
840
        }
802
841
 
862
901
                buf[i++] = b8;
863
902
 
864
903
                if (imageHasAlpha())
 
904
                {
865
905
                    buf[i++] = a8;
 
906
                }
866
907
            }
867
908
        }
868
909
 
894
935
    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE,   8);
895
936
    TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP,    TIFFDefaultStripSize(tif, 0));
896
937
 
897
 
    uchar *pixelThumb;
898
 
    uchar *dataThumb = thumb.bits();
899
 
    uint8 *bufThumb  = (uint8 *) _TIFFmalloc(TIFFScanlineSize(tif));
 
938
    uchar* pixelThumb;
 
939
    uchar* dataThumb = thumb.bits();
 
940
    uint8* bufThumb  = (uint8*) _TIFFmalloc(TIFFScanlineSize(tif));
900
941
 
901
942
    if (!bufThumb)
902
943
    {
934
975
    // -------------------------------------------------------------------
935
976
 
936
977
    if (observer)
 
978
    {
937
979
        observer->progressInfo(m_image, 1.0);
 
980
    }
938
981
 
939
982
    imageSetAttribute("savedformat", "TIFF");
940
983
 
964
1007
                                     const DMetadata& metaData, const char* exifTagName)
965
1008
{
966
1009
    QByteArray tag = metaData.getExifTagData(exifTagName);
 
1010
 
967
1011
    if (!tag.isEmpty())
968
1012
    {
969
1013
        QByteArray str(tag.data(), tag.size());
975
1019
                                    const DMetadata& metaData, const char* exifTagName)
976
1020
{
977
1021
    QByteArray tag = metaData.getExifTagData(exifTagName);
 
1022
 
978
1023
    if (!tag.isEmpty())
979
1024
    {
980
 
        TIFFSetField (tif, tiffTag, (uint32)tag.size(), (char *)tag.data());
 
1025
        TIFFSetField (tif, tiffTag, (uint32)tag.size(), (char*)tag.data());
981
1026
    }
982
1027
}
983
1028