Bug #780

save thumbnail

Added by Florian Kleber almost 6 years ago. Updated about 1 year ago.

Status:ClosedStart date:18 Jul 2011
Priority:NormalDue date:
Assignee:Robin Mills% Done:

100%

Category:withdrawnEstimated time:1.00 hour
Target version:0.26

Description

Hello,

we've tried to use exiv2 for reading and writing thumbs (windows7, msvc compiler). although the reading of thumbnails works fine, we've problems if the thumbnails doesn't exist and we try to create a new one. writeMetaData throws an exception in tiffimage.cpp, line 1853 (io.transfer(*tempio). the complete code for the writing of the thumbs is listed below. it seems that the temporary file is locked. the exception is thrown in basicio.cpp, line 635 (called by transfer). The Error Code of "DeleteFile" is 32. it doesn't matter if the file is a tif file or another kind of image type.
we've tried the last official release as well as the trunk version. thank you for any help.

kind regards,

florian

    Exiv2::ExifData exifData = exifImg->exifData();

    if (exifData.empty()) {
        DkUtils::printDebug(DK_MODULE, "exif data is empty\n");
        exifData = Exiv2::ExifData();
    }

    // ok, let's try to save the thumbnail...
    try {

        Exiv2::ExifThumb eThumb(exifData);

        if (isTiff()) {
            eThumb.erase();

            Exiv2::ExifData::const_iterator pos = exifData.findKey(Exiv2::ExifKey("Exif.Image.NewSubfileType"));
            if (pos == exifData.end() || pos->count() != 1 || pos->toLong() != 0) {
                 throw DkException("Exif.Image.NewSubfileType missing or not set as main image", __LINE__, __FILE__);
             }
             std::string subImage1("SubImage1");
             for (Exiv2::ExifData::iterator md = exifData.begin(); md != exifData.end();)
             {
                 if (md->groupName() == subImage1)
                     md = exifData.erase(md);
                 else
                     ++md;
             }
        }

        QByteArray data;
        QBuffer buffer(&data);
        buffer.open(QIODevice::WriteOnly);
        thumb.save(&buffer, "JPEG");

        if (isTiff()) {
            Exiv2::DataBuf buf((Exiv2::byte *)data.data(), data.size());
            Exiv2::ULongValue val;
            val.read("0");
            val.setDataArea(buf.pData_, buf.size_);
            exifData["Exif.SubImage1.JPEGInterchangeFormat"] = val;
            exifData["Exif.SubImage1.JPEGInterchangeFormatLength"] = uint32_t(buf.size_);
            exifData["Exif.SubImage1.Compression"] = uint16_t(6); // JPEG (old-style)
            exifData["Exif.SubImage1.NewSubfileType"] = uint32_t(1); // Thumbnail image
            DkUtils::printDebug(DK_MODULE, "As you told me to, I am writing the tiff thumbs...\n");

        } else {
            eThumb.setJpegThumbnail((Exiv2::byte *)data.data(), data.size());
            DkUtils::printDebug(DK_MODULE, "As you told me to, I am writing the thumbs...\n");
        }

        exifImg->setExifData(exifData);
        exifImg->writeMetadata();

thumb.cpp Magnifier - Reproducer based on the code in the bug report (2.33 KB) Andreas Huggel, 27 Jul 2011 19:35

History

#1 Updated by Andreas Huggel almost 6 years ago

Florian, I tried to reproduce the issue on OSX but it works fine here. Can you try the attached program (a standalone version of your sample code) on your system?

Andreas

#2 Updated by Florian Kleber almost 6 years ago

Andreas, we've tried your sample code. it works fine, until the file is locked (Write) somewhere else,
e.g.

QFile* fu = new QFile(QString("H:\\img0001.tif"));
fu->open(QIODevice::ReadWrite);

in this case, the output of your sample code is:
As you told me to, I am writing the TIFF thumbs...
Caught Exiv2 exception 'H:\img0001.tif: Call to `::remove' failed: Permission denied (errno = 13)'

which results in an empty file: img0001.tif and a (correct) backup file img0001.tif676
we've missinterpreted the error the last time, when we've wrote the ticket. however we suggest to check if the file is locked in advance, in order to avoid destroyed files... would it be possible? thank you for your help.

florian

#3 Updated by Andreas Huggel almost 6 years ago

There is already a test to make sure the file can be opened for writing (at the beginning of transfer()).
However that is not sufficient to ensure the file can be removed. On Windows this is apparently not the case if someone still has the file open for writing ("locked"). On Unix, the file can't be removed (but may be written to) if the process doesn't have write permissions for the directory that contains the file.

Do you know how I can check if a file can be removed on Windows?

Andreas

#4 Updated by Robin Mills almost 6 years ago

Andreas

I think if you call LockFile (or LockFileEx) and obtain an exclusive lock on the file, you know you have ownership.
http://msdn.microsoft.com/en-us/library/aa365203(v=VS.85).aspx

DeleteFile will delete the file.
http://msdn.microsoft.com/en-us/library/aa363915(v=vs.85).aspx

If the file has the 'r' attribute set to read-protect the file, I think you'll have to unset that. GetFileAttributes(), SetFileAttributes()

Robin

#5 Updated by Florian Kleber over 5 years ago

Andreas, i am not sure if it is possible on windows. you could try to write to the file and throw an exception if it is locked. this will allow to leave the file unchanged to avoid a damaged file.

florian

#6 Updated by Robin Mills over 1 year ago

  • Target version set to 53

#7 Updated by Robin Mills about 1 year ago

  • Status changed from New to Assigned
  • Assignee set to Robin Mills

This issue has been in the database for 4 years and nobody else has requested progress with this matter. So, unless you engage to persuade me to keep this matter alive, it will be closed on April 30 as “no longer needed/wanted.

There have been similar issues on Windows tracked down to the virus checker. http://dev.exiv2.org/boards/3/topics/1816

#8 Updated by Robin Mills about 1 year ago

  • Category changed from basicio to withdrawn
  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100
  • Estimated time set to 1.00

#9 Updated by Robin Mills about 1 year ago

  • Target version changed from 53 to 0.26

Also available in: Atom PDF

Redmine Appliance - Powered by TurnKey Linux