示例#1
0
 PreviewPropertiesList PreviewManager::getPreviewProperties() const
 {
     PreviewPropertiesList list;
     // go through the loader table and store all successfully created loaders in the list
     for (PreviewId id = 0; id < Loader::getNumLoaders(); ++id) {
         Loader::AutoPtr loader = Loader::create(id, image_);
         if (loader.get() && loader->readDimensions()) {
             list.push_back(loader->getProperties());
         }
     }
     std::sort(list.begin(), list.end(), cmpPreviewProperties);
     return list;
 }
示例#2
0
    void Rw2Image::readMetadata()
    {
#ifdef DEBUG
        std::cerr << "Reading RW2 file " << io_->path() << "\n";
#endif
        if (io_->open() != 0) {
            throw Error(9, io_->path(), strError());
        }
        IoCloser closer(*io_);
        // Ensure that this is the correct image type
        if (!isRw2Type(*io_, false)) {
            if (io_->error() || io_->eof()) throw Error(14);
            throw Error(3, "RW2");
        }
        clearMetadata();
        std::ofstream devnull;
        printStructure(devnull, kpsRecursive, 0);
        ByteOrder bo = Rw2Parser::decode(exifData_,
                                         iptcData_,
                                         xmpData_,
                                         io_->mmap(),
                                         io_->size());
        setByteOrder(bo);

        // A lot more metadata is hidden in the embedded preview image
        // Todo: This should go into the Rw2Parser, but for that it needs the Image
        PreviewManager loader(*this);
        PreviewPropertiesList list = loader.getPreviewProperties();
        // Todo: What if there are more preview images?
        if (list.size() > 1) {
#ifndef SUPPRESS_WARNINGS
            EXV_WARNING << "RW2 image contains more than one preview. None used.\n";
#endif
        }
        if (list.size() != 1) return;
        ExifData exifData;
        PreviewImage preview = loader.getPreviewImage(*list.begin());
        Image::AutoPtr image = ImageFactory::open(preview.pData(), preview.size());
        if (image.get() == 0) {
#ifndef SUPPRESS_WARNINGS
            EXV_WARNING << "Failed to open RW2 preview image.\n";
#endif
            return;
        }
        image->readMetadata();
        ExifData& prevData = image->exifData();
        if (!prevData.empty()) {
            // Filter duplicate tags
            for (ExifData::const_iterator pos = exifData_.begin(); pos != exifData_.end(); ++pos) {
                if (pos->ifdId() == panaRawId) continue;
                ExifData::iterator dup = prevData.findKey(ExifKey(pos->key()));
                if (dup != prevData.end()) {
#ifdef DEBUG
                    std::cerr << "Filtering duplicate tag " << pos->key()
                              << " (values '" << pos->value()
                              << "' and '" << dup->value() << "')\n";
#endif
                    prevData.erase(dup);
                }
            }
        }
        // Remove tags not applicable for raw images
        static const char* filteredTags[] = {
            "Exif.Photo.ComponentsConfiguration",
            "Exif.Photo.CompressedBitsPerPixel",
            "Exif.Panasonic.ColorEffect",
            "Exif.Panasonic.Contrast",
            "Exif.Panasonic.NoiseReduction",
            "Exif.Panasonic.ColorMode",
            "Exif.Panasonic.OpticalZoomMode",
            "Exif.Panasonic.Contrast",
            "Exif.Panasonic.Saturation",
            "Exif.Panasonic.Sharpness",
            "Exif.Panasonic.FilmMode",
            "Exif.Panasonic.SceneMode",
            "Exif.Panasonic.WBRedLevel",
            "Exif.Panasonic.WBGreenLevel",
            "Exif.Panasonic.WBBlueLevel",
            "Exif.Photo.ColorSpace",
            "Exif.Photo.PixelXDimension",
            "Exif.Photo.PixelYDimension",
            "Exif.Photo.SceneType",
            "Exif.Photo.CustomRendered",
            "Exif.Photo.DigitalZoomRatio",
            "Exif.Photo.SceneCaptureType",
            "Exif.Photo.GainControl",
            "Exif.Photo.Contrast",
            "Exif.Photo.Saturation",
            "Exif.Photo.Sharpness",
            "Exif.Image.PrintImageMatching",
            "Exif.Image.YCbCrPositioning"
        };
        for (unsigned int i = 0; i < EXV_COUNTOF(filteredTags); ++i) {
            ExifData::iterator pos = prevData.findKey(ExifKey(filteredTags[i]));
            if (pos != prevData.end()) {
#ifdef DEBUG
                std::cerr << "Exif tag " << pos->key() << " removed\n";
#endif
                prevData.erase(pos);
            }
        }

        // Add the remaining tags
        for (ExifData::const_iterator pos = prevData.begin(); pos != prevData.end(); ++pos) {
            exifData_.add(*pos);
        }

    } // Rw2Image::readMetadata
示例#3
0
QImage Exiv2Lib::getPreview()
{
    PreviewManager        loader(*mImageFile);
    PreviewPropertiesList list = loader.getPreviewProperties();

    if (list.empty())
    {
        qDebug() << "Image contains no thumbnail";
        return QImage();
    }

    PreviewProperties selected;
    // Take the last image in the list.
    // For Canon raw pictures, the 2nd preview has no white balance applied.
    // see http://lclevy.free.fr/cr2/
    //     section 2.6 IFD #2
    selected = list.back();

    // FIXME: crash hapened here when reading the QImage.
    // not quite sure what caused it

    // load the thumbnail
    PreviewImage         thumbnail = loader.getPreviewImage(selected);

    const unsigned char* tmp  = thumbnail.pData();
    size_t               size = thumbnail.size();

    QImage               thumb;

    thumb.loadFromData(tmp, size);

    // Read the EXIF orientation flag and rotate the image accordingly.
    ExifData&                data = mImageFile->exifData();
    ExifData::const_iterator pos;
    pos = data.findKey(ExifKey("Exif.Image.Orientation"));

    // TODO: should flip/rotate after resize
    if (pos != data.end())
    {
        qDebug() << "rotation" << pos->toLong();
        QTransform rotate;

        switch (pos->toLong())
        {
            case 1:     // no rotation needed
                break;

            case 2:     // flip over y
                thumb = thumb.mirrored(true, false);
                break;

            case 3:     // rotate 180 (or flip x flip y)
                thumb = thumb.mirrored(true, true);
                break;

            case 4:     // flip over x
                thumb = thumb.mirrored(false, true);
                break;

            case 5:     // rotate 90 CW & flip over y
                rotate.rotate(90);
                rotate.rotate(180, Qt::YAxis);
                thumb = thumb.transformed(rotate);
                break;

            case 6:     // rotate 90 CW
                rotate.rotate(90);
                thumb = thumb.transformed(rotate);
                break;

            case 7:     // rotate 90 CCW flip over y
                rotate.rotate(-90);
                rotate.rotate(180, Qt::YAxis);
                thumb = thumb.transformed(rotate);
                break;

            case 8:     // rotate 90 CCW
                rotate.rotate(-90);
                thumb = thumb.transformed(rotate);
                break;
        }
    }
    return thumb;
}