Exemplo n.º 1
0
int main (int argc, char **argv)
{
    if(argc != 2)
    {
        kDebug() << "loadfromba - test to load metadata from image as byte array";
        kDebug() << "Usage: <image>";
        return -1;
    }

    QString filePath(argv[1]);
    QString baFile("ba.dat");

    QImage image(filePath);
    image.save(baFile, "PNG");

    QFile file(baFile);
    if ( !file.open(QIODevice::ReadOnly) )
        return false;

    QByteArray data;
    data.resize(file.size());
    QDataStream stream( &file );
    stream.readRawData(data.data(), data.size());
    file.close();

    KExiv2 meta;
    meta.loadFromData(data);

    return 0;
}
Exemplo n.º 2
0
bool setFaceTags(KExiv2& meta,const char* xmpTagName,const QMap<QString,QRectF>& faces,
                     bool setProgramName)
{

        Q_UNUSED(setProgramName);
        meta.setXmpTagString(xmpTagName,QString(),KExiv2::XmpTagType(1),false);

        QString qxmpTagName(QString::fromLatin1(xmpTagName));
        QString nameTagKey     = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Name");
        QString typeTagKey     = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Type");
        QString areaTagKey     = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area");
        QString areaxTagKey    = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area/stArea:x");
        QString areayTagKey    = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area/stArea:y");
        QString areawTagKey    = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area/stArea:w");
        QString areahTagKey    = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area/stArea:h");
        QString areanormTagKey = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area/stArea:unit");

        QMap<QString,QRectF>::const_iterator it = faces.constBegin();
        int i =1;
        while(it != faces.constEnd())
        {
            qreal x,y,w,h;
            it.value().getRect(&x,&y,&w,&h);
            /** Set tag name **/
            meta.setXmpTagString(nameTagKey.arg(i).toLatin1().constData(),it.key(),
                                 KExiv2::XmpTagType(0),false);
            /** Set tag type as Face **/
            meta.setXmpTagString(typeTagKey.arg(i).toLatin1().constData(),QString::fromLatin1("Face"),
                                 KExiv2::XmpTagType(0),false);
            /** Set tag Area, with xmp type struct **/
            meta.setXmpTagString(areaTagKey.arg(i).toLatin1().constData(),QString(),
                                 KExiv2::XmpTagType(2),false);
            /** Set stArea:x inside Area structure **/
            meta.setXmpTagString(areaxTagKey.arg(i).toLatin1().constData(),QString::number(x),
                                 KExiv2::XmpTagType(0),false);
            /** Set stArea:y inside Area structure **/
            meta.setXmpTagString(areayTagKey.arg(i).toLatin1().constData(),QString::number(y),
                                 KExiv2::XmpTagType(0),false);
            /** Set stArea:w inside Area structure **/
            meta.setXmpTagString(areawTagKey.arg(i).toLatin1().constData(),QString::number(w),
                                 KExiv2::XmpTagType(0),false);
            /** Set stArea:h inside Area structure **/
            meta.setXmpTagString(areahTagKey.arg(i).toLatin1().constData(),QString::number(h),
                                 KExiv2::XmpTagType(0),false);
            /** Set stArea:unit inside Area structure  as normalized **/
            meta.setXmpTagString(areanormTagKey.arg(i).toLatin1().constData(),QString::fromLatin1("normalized"),
                                 KExiv2::XmpTagType(0),false);

            ++it;
            ++i;
        }

    return true;

}
Exemplo n.º 3
0
void removeFaceTags(KExiv2& meta,const char* xmpTagName)
{
        QString qxmpTagName(QString::fromLatin1(xmpTagName));
        QString regionTagKey   = qxmpTagName + QString::fromLatin1("[%1]");
        QString nameTagKey     = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Name");
        QString typeTagKey     = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Type");
        QString areaTagKey     = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area");
        QString areaxTagKey    = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area/stArea:x");
        QString areayTagKey    = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area/stArea:y");
        QString areawTagKey    = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area/stArea:w");
        QString areahTagKey    = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area/stArea:h");
        QString areanormTagKey = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area/stArea:unit");

        meta.removeXmpTag(xmpTagName,false);
        bool dirty = true;
        int i      =1;

        while(dirty)
        {
            dirty = false;
            dirty |=meta.removeXmpTag(regionTagKey.arg(i).toLatin1().constData(),false);
            dirty |=meta.removeXmpTag(nameTagKey.arg(i).toLatin1().constData(),false);
            dirty |=meta.removeXmpTag(typeTagKey.arg(i).toLatin1().constData(),false);
            dirty |=meta.removeXmpTag(areaTagKey.arg(i).toLatin1().constData(),false);
            dirty |=meta.removeXmpTag(areaxTagKey.arg(i).toLatin1().constData(),false);
            dirty |=meta.removeXmpTag(areayTagKey.arg(i).toLatin1().constData(),false);
            dirty |=meta.removeXmpTag(areawTagKey.arg(i).toLatin1().constData(),false);
            dirty |=meta.removeXmpTag(areahTagKey.arg(i).toLatin1().constData(),false);
            dirty |=meta.removeXmpTag(areanormTagKey.arg(i).toLatin1().constData(),false);
            i++;
        }
}
Exemplo n.º 4
0
int main (int argc, char **argv)
{
    if(argc != 2)
    {
        kDebug() << "erasetag - erase tag from from image";
        kDebug() << "Usage: <image>";
        return -1;
    }

    QString filePath(argv[1]);

    KExiv2 meta;
    meta.load(filePath);
    meta.setWriteRawFiles(true);
    bool b = meta.removeExifTag("Exif.OlympusIp.BlackLevel", false);
    kDebug() << "Exif.OlympusIp.BlackLevel found = " << b;

    QByteArray ba = meta.getExifTagData("Exif.OlympusIp.BlackLevel");
    kDebug() << "Exif.OlympusIp.BlackLevel removed = " << ba.isEmpty();

    if (b)
    {
        meta.applyChanges();
    }

    return 0;
}
Exemplo n.º 5
0
void SaveImgThread::run()
{
    // Perform saving ---------------------------------------------------------------

    QImage prev     = d->img.scaled(1280, 1024, Qt::KeepAspectRatio, Qt::SmoothTransformation);
    QImage thumb    = d->img.scaled(160, 120,   Qt::KeepAspectRatio, Qt::SmoothTransformation);
    QByteArray prof = KPWriteImage::getICCProfilFromFile(RawDecodingSettings::SRGB);

    KExiv2 meta;
    meta.setImageProgramId(QString("Kipi-plugins"), QString(kipiplugins_version));
    meta.setImageDimensions(d->img.size());
    if (d->format != QString("JPEG"))
        meta.setImagePreview(prev);
    meta.setExifThumbnail(thumb);
    meta.setExifTagString("Exif.Image.DocumentName", QString("Scanned Image")); // not i18n
    meta.setExifTagString("Exif.Image.Make",  d->make);
    meta.setXmpTagString("Xmp.tiff.Make",     d->make);
    meta.setExifTagString("Exif.Image.Model", d->model);
    meta.setXmpTagString("Xmp.tiff.Model",    d->model);
    meta.setImageDateTime(QDateTime::currentDateTime());
    meta.setImageOrientation(KExiv2::ORIENTATION_NORMAL);
    meta.setImageColorWorkSpace(KExiv2::WORKSPACE_SRGB);

    KPWriteImage wImageIface;
    if (d->frmt != KSaneIface::KSaneWidget::FormatRGB_16_C)
    {
        QByteArray data((const char*)d->img.bits(), d->img.numBytes());
        wImageIface.setImageData(data, d->img.width(), d->img.height(), false, true, prof, meta);
    }
    else
    {
        // 16 bits color depth image.
        wImageIface.setImageData(d->ksaneData, d->width, d->height, true, false, prof, meta);
    }

    bool ret = false;

    QString path;
    if(d->newUrl.isLocalFile())
        path = d->newUrl.toLocalFile();
    else
        path = d->newUrl.path();

    if (d->format == QString("JPEG"))
    {
        ret = wImageIface.write2JPEG(path);
    }
    else if (d->format == QString("PNG"))
    {
        ret = wImageIface.write2PNG(path);
    }
    else if (d->format == QString("TIFF"))
    {
        ret = wImageIface.write2TIFF(path);
    }
    else
    {
        ret = d->img.save(path, d->format.toAscii().data());
    }

    emit signalComplete(d->newUrl, ret);
}
Exemplo n.º 6
0
int DNGWriter::convert()
{
    d->cancel = false;

    try
    {
        if (inputFile().isEmpty())
        {
            kDebug( 51000 ) << "DNGWriter: No input file to convert. Aborted..." << endl;
            return -1;
        }

        QFileInfo inputInfo(inputFile());
        QString   dngFilePath = outputFile();

        if (dngFilePath.isEmpty())
        {
            dngFilePath = QString(inputInfo.baseName() + QString(".dng"));
        }

        QFileInfo          outputInfo(dngFilePath);
        QByteArray         rawData;
        DcrawInfoContainer identify;

        // -----------------------------------------------------------------------------------------

        kDebug( 51000 ) << "DNGWriter: Loading RAW data from " << inputInfo.fileName() << endl;

        KDcraw rawProcessor;
        if (!rawProcessor.extractRAWData(inputFile(), rawData, identify))
        {
            kDebug( 51000 ) << "DNGWriter: Loading RAW data failed. Aborted..." << endl;
            return -1;
        }

        if (d->cancel) return -2;

        int width      = identify.imageSize.width();
        int height     = identify.imageSize.height();
        int pixelRange = 16;

        kDebug( 51000 ) << "DNGWriter: Raw data loaded:" << endl;
        kDebug( 51000 ) << "--- Data Size:     " << rawData.size() << " bytes" << endl;
        kDebug( 51000 ) << "--- Date:          " << identify.dateTime.toString(Qt::ISODate) << endl;
        kDebug( 51000 ) << "--- Make:          " << identify.make << endl;
        kDebug( 51000 ) << "--- Model:         " << identify.model << endl;
        kDebug( 51000 ) << "--- Size:          " << width << "x" << height << endl;
        kDebug( 51000 ) << "--- Orientation:   " << identify.orientation << endl;
        kDebug( 51000 ) << "--- Top margin:    " << identify.topMargin << endl;
        kDebug( 51000 ) << "--- Left margin:   " << identify.leftMargin << endl;
        kDebug( 51000 ) << "--- Filter:        " << identify.filterPattern << endl;
        kDebug( 51000 ) << "--- Colors:        " << identify.rawColors << endl;
        kDebug( 51000 ) << "--- Black:         " << identify.blackPoint << endl;
        kDebug( 51000 ) << "--- White:         " << identify.whitePoint << endl;
        kDebug( 51000 ) << "--- CAM->XYZ:" << endl;

        QString matrixVal;
        for(int i=0; i<12; i+=3)
        {
            kDebug( 51000 ) << "                   "
                     << QString().sprintf("%03.4f  %03.4f  %03.4f", identify.cameraXYZMatrix[0][ i ],
                                                                    identify.cameraXYZMatrix[0][i+1],
                                                                    identify.cameraXYZMatrix[0][i+2])
                     << endl;
        }

        // Check if CFA layout is supported by DNG SDK.
        int bayerMosaic;

        if (identify.filterPattern == QString("GRBGGRBGGRBGGRBG"))
        {
            bayerMosaic = 0;
        }
        else if (identify.filterPattern == QString("RGGBRGGBRGGBRGGB"))
        {
            bayerMosaic = 1;
        }
        else if (identify.filterPattern == QString("BGGRBGGRBGGRBGGR"))
        {
            bayerMosaic = 2;
        }
        else if (identify.filterPattern == QString("GBRGGBRGGBRGGBRG"))
        {
            bayerMosaic = 3;
        }
        else
        {
            kDebug( 51000 ) << "DNGWriter: Bayer mosaic not supported. Aborted..." << endl;
            return -1;
        }

        // Check if number of Raw Color components is supported.
        if (identify.rawColors != 3)
        {
            kDebug( 51000 ) << "DNGWriter: Number of Raw color components not supported. Aborted..." << endl;
            return -1;
        }

/*      // NOTE: code to hack RAW data extraction

        QString   rawdataFilePath(inputInfo.baseName() + QString(".dat"));
        QFileInfo rawdataInfo(rawdataFilePath);

        QFile rawdataFile(rawdataFilePath);
        if (!rawdataFile.open(QIODevice::WriteOnly))
        {
            kDebug( 51000 ) << "DNGWriter: Cannot open file to write RAW data. Aborted..." << endl;
            return -1;
        }
        QDataStream rawdataStream(&rawdataFile);
        rawdataStream.writeRawData(rawData.data(), rawData.size());
        rawdataFile.close();
*/
        // -----------------------------------------------------------------------------------------

        kDebug( 51000 ) << "DNGWriter: Formating RAW data to memory" << endl;

        std::vector<unsigned short> raw_data;
        raw_data.resize(rawData.size());
        const unsigned short* dp = (const unsigned short*)rawData.data();
        for (uint i = 0; i < raw_data.size()/2; i++)
        {
            raw_data[i] = *dp;
            *dp++;
        }

        if (d->cancel) return -2;

        // -----------------------------------------------------------------------------------------

        kDebug( 51000 ) << "DNGWriter: DNG memory allocation and initialization" << endl;

        dng_memory_allocator memalloc(gDefaultDNGMemoryAllocator);
        dng_memory_stream stream(memalloc);
        stream.Put(&raw_data.front(), raw_data.size()*sizeof(unsigned short));

        dng_rect rect(height, width);
        DNGWriterHost host(d, &memalloc);

        // Unprocessed raw data.
        host.SetKeepStage1(true);

        // Linearized, tone curve processed data.
        host.SetKeepStage2(true);

        AutoPtr<dng_image> image(new dng_simple_image(rect, 1, ttShort, 1<<pixelRange, memalloc));

        if (d->cancel) return -2;

        // -----------------------------------------------------------------------------------------

        kDebug( 51000 ) << "DNGWriter: DNG IFD structure creation" << endl;

        dng_ifd ifd;

        ifd.fUsesNewSubFileType        = true;
        ifd.fNewSubFileType            = 0;
        ifd.fImageWidth                = width;
        ifd.fImageLength               = height;
        ifd.fBitsPerSample[0]          = pixelRange;
        ifd.fBitsPerSample[1]          = 0;
        ifd.fBitsPerSample[2]          = 0;
        ifd.fBitsPerSample[3]          = 0;
        ifd.fCompression               = ccUncompressed;
        ifd.fPredictor                 = 1;
        ifd.fCFALayout                 = 1;                 // Rectangular (or square) layout.
        ifd.fPhotometricInterpretation = piCFA;
        ifd.fFillOrder                 = 1;
        ifd.fOrientation               = identify.orientation;
        ifd.fSamplesPerPixel           = 1;
        ifd.fPlanarConfiguration       = 1;
        ifd.fXResolution               = 0.0;
        ifd.fYResolution               = 0.0;
        ifd.fResolutionUnit            = 0;

        ifd.fUsesStrips                = true;
        ifd.fUsesTiles                 = false;

        ifd.fTileWidth                 = width;
        ifd.fTileLength                = height;
        ifd.fTileOffsetsType           = 4;
        ifd.fTileOffsetsCount          = 0;

        ifd.fSubIFDsCount              = 0;
        ifd.fSubIFDsOffset             = 0;
        ifd.fExtraSamplesCount         = 0;
        ifd.fSampleFormat[0]           = 1;
        ifd.fSampleFormat[1]           = 1;
        ifd.fSampleFormat[2]           = 1;
        ifd.fSampleFormat[3]           = 1;

        ifd.fLinearizationTableType    = 0;
        ifd.fLinearizationTableCount   = 0;
        ifd.fLinearizationTableOffset  = 0;

        ifd.fBlackLevelRepeatRows      = 1;
        ifd.fBlackLevelRepeatCols      = 1;
        ifd.fBlackLevel[0][0][0]       = identify.blackPoint;
        ifd.fBlackLevelDeltaHType      = 0;
        ifd.fBlackLevelDeltaHCount     = 0;
        ifd.fBlackLevelDeltaHOffset    = 0;
        ifd.fBlackLevelDeltaVType      = 0;
        ifd.fBlackLevelDeltaVCount     = 0;
        ifd.fBlackLevelDeltaVOffset    = 0;
        ifd.fWhiteLevel[0]             = identify.whitePoint;
        ifd.fWhiteLevel[1]             = identify.whitePoint;
        ifd.fWhiteLevel[2]             = identify.whitePoint;
        ifd.fWhiteLevel[3]             = identify.whitePoint;

        ifd.fDefaultScaleH             = dng_urational(1, 1);
        ifd.fDefaultScaleV             = dng_urational(1, 1);
        ifd.fBestQualityScale          = dng_urational(1, 1);

        ifd.fCFARepeatPatternRows      = 0;
        ifd.fCFARepeatPatternCols      = 0;

        ifd.fBayerGreenSplit           = 0;
        ifd.fChromaBlurRadius          = dng_urational(0, 0);
        ifd.fAntiAliasStrength         = dng_urational(100, 100);

        ifd.fActiveArea                = rect;
        ifd.fDefaultCropOriginH        = dng_urational(0, 1);
        ifd.fDefaultCropOriginV        = dng_urational(0, 1);
        ifd.fDefaultCropSizeH          = dng_urational(width, 1);
        ifd.fDefaultCropSizeV          = dng_urational(height, 1);

        ifd.fMaskedAreaCount           = 0;
        ifd.fLosslessJPEGBug16         = false;
        ifd.fSampleBitShift            = 0;

        ifd.ReadImage(host, stream, *image.Get());

        if (d->cancel) return -2;

        // -----------------------------------------------------------------------------------------

        kDebug( 51000 ) << "DNGWriter: DNG Negative structure creation" << endl;

        AutoPtr<dng_negative> negative(host.Make_dng_negative());

        negative->SetDefaultScale(ifd.fDefaultScaleH, ifd.fDefaultScaleV);
        negative->SetDefaultCropOrigin(ifd.fDefaultCropOriginH, ifd.fDefaultCropOriginV);
        negative->SetDefaultCropSize(ifd.fDefaultCropSizeH, ifd.fDefaultCropSizeV);
        negative->SetActiveArea(ifd.fActiveArea);

        negative->SetModelName(identify.model.toAscii());
        negative->SetLocalName(QString("%1 %2").arg(identify.make).arg(identify.model).toAscii());
        negative->SetOriginalRawFileName(inputInfo.fileName().toAscii());

        negative->SetColorChannels(3);
        negative->SetColorKeys(colorKeyRed, colorKeyGreen, colorKeyBlue);
        negative->SetBayerMosaic(bayerMosaic);

        negative->SetWhiteLevel(identify.whitePoint, 0);
        negative->SetWhiteLevel(identify.whitePoint, 1);
        negative->SetWhiteLevel(identify.whitePoint, 2);
        negative->SetBlackLevel(identify.blackPoint, 0);
        negative->SetBlackLevel(identify.blackPoint, 1);
        negative->SetBlackLevel(identify.blackPoint, 2);

        negative->SetBaselineExposure(0.0);
        negative->SetBaselineNoise(1.0);
        negative->SetBaselineSharpness(1.0);

        dng_orientation orientation;
        switch (identify.orientation)
        {
            case DcrawInfoContainer::ORIENTATION_180:
                orientation = dng_orientation::Rotate180();
                break;

            case DcrawInfoContainer::ORIENTATION_90CCW:
                orientation = dng_orientation::Rotate90CCW();
                break;

            case DcrawInfoContainer::ORIENTATION_90CW:
                orientation = dng_orientation::Rotate90CW();
                break;

            default:   // ORIENTATION_NONE
                orientation = dng_orientation::Normal();
                break;
        }
        negative->SetBaseOrientation(orientation);

        negative->SetAntiAliasStrength(dng_urational(100, 100));
        negative->SetLinearResponseLimit(1.0);
        negative->SetShadowScale( dng_urational(1, 1) );

        negative->SetAnalogBalance(dng_vector_3(1.0, 1.0, 1.0));

        // -------------------------------------------------------------------------------

        // Set Camera->XYZ Color matrix as profile.
        dng_matrix_3by3 matrix(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0);
        dng_matrix_3by3 camXYZ;

        AutoPtr<dng_camera_profile> prof(new dng_camera_profile);
        prof->SetName(QString("%1 %2").arg(identify.make).arg(identify.model).toAscii());

        camXYZ[0][0] = identify.cameraXYZMatrix[0][0];
        camXYZ[0][1] = identify.cameraXYZMatrix[0][1];
        camXYZ[0][2] = identify.cameraXYZMatrix[0][2];
        camXYZ[1][0] = identify.cameraXYZMatrix[0][3];
        camXYZ[1][1] = identify.cameraXYZMatrix[1][0];
        camXYZ[1][2] = identify.cameraXYZMatrix[1][1];
        camXYZ[2][0] = identify.cameraXYZMatrix[1][2];
        camXYZ[2][1] = identify.cameraXYZMatrix[1][3];
        camXYZ[2][2] = identify.cameraXYZMatrix[2][0];

        if (camXYZ.MaxEntry() == 0.0)
            kDebug( 51000 ) << "DNGWriter: Warning, camera XYZ Matrix is null" << endl;
        else 
            matrix = camXYZ;

        prof->SetColorMatrix1((dng_matrix) matrix);
        prof->SetCalibrationIlluminant1(lsD65);
        negative->AddProfile(prof);

        // -------------------------------------------------------------------------------

        // Clear "Camera WhiteXY"
        negative->SetCameraWhiteXY(dng_xy_coord());

        // This settings break color on preview and thumbnail
        //negative->SetCameraNeutral(dng_vector_3(1.0, 1.0, 1.0));

        if (d->cancel) return -2;

        // -----------------------------------------------------------------------------------------

        kDebug( 51000 ) << "DNGWriter: Updating metadata to DNG Negative" << endl;

        dng_exif *exif = negative->GetExif();
        exif->fModel.Set_ASCII(identify.model.toAscii());
        exif->fMake.Set_ASCII(identify.make.toAscii());

        // Time from original shot
        dng_date_time dt;
        dt.fYear   = identify.dateTime.date().year();
        dt.fMonth  = identify.dateTime.date().month();
        dt.fDay    = identify.dateTime.date().day();
        dt.fHour   = identify.dateTime.time().hour();
        dt.fMinute = identify.dateTime.time().minute();
        dt.fSecond = identify.dateTime.time().second();

        dng_date_time_info dti;
        dti.SetDateTime(dt);
        exif->fDateTimeOriginal  = dti;
        exif->fDateTimeDigitized = dti;
        negative->UpdateDateTime(dti);

        long int num, den;
        long     val;
        QString  str;
        KExiv2   meta;
        if (meta.load(inputFile()))
        {
            // String Tags

            str = meta.getExifTagString("Exif.Image.Software");
            if (!str.isEmpty()) exif->fSoftware.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.Image.ImageDescription");
            if (!str.isEmpty()) exif->fImageDescription.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.Image.Artist");
            if (!str.isEmpty()) exif->fArtist.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.Image.Copyright");
            if (!str.isEmpty()) exif->fCopyright.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.Photo.UserComment");
            if (!str.isEmpty()) exif->fUserComment.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.Image.CameraSerialNumber");
            if (!str.isEmpty()) exif->fCameraSerialNumber.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.GPSInfo.GPSLatitudeRef");
            if (!str.isEmpty()) exif->fGPSLatitudeRef.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.GPSInfo.GPSLongitudeRef");
            if (!str.isEmpty()) exif->fGPSLongitudeRef.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.GPSInfo.GPSSatellites");
            if (!str.isEmpty()) exif->fGPSSatellites.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.GPSInfo.GPSStatus");
            if (!str.isEmpty()) exif->fGPSStatus.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.GPSInfo.GPSMeasureMode");
            if (!str.isEmpty()) exif->fGPSMeasureMode.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.GPSInfo.GPSSpeedRef");
            if (!str.isEmpty()) exif->fGPSSpeedRef.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.GPSInfo.GPSTrackRef");
            if (!str.isEmpty()) exif->fGPSTrackRef.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.GPSInfo.GPSSpeedRef");
            if (!str.isEmpty()) exif->fGPSSpeedRef.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.GPSInfo.GPSImgDirectionRef");
            if (!str.isEmpty()) exif->fGPSSpeedRef.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.GPSInfo.GPSMapDatum");
            if (!str.isEmpty()) exif->fGPSMapDatum.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.GPSInfo.GPSDestLatitudeRef");
            if (!str.isEmpty()) exif->fGPSDestLatitudeRef.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.GPSInfo.GPSDestLongitudeRef");
            if (!str.isEmpty()) exif->fGPSDestLongitudeRef.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.GPSInfo.GPSDestBearingRef");
            if (!str.isEmpty()) exif->fGPSDestBearingRef.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.GPSInfo.GPSDestDistanceRef");
            if (!str.isEmpty()) exif->fGPSDestDistanceRef.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.GPSInfo.GPSProcessingMethod");
            if (!str.isEmpty()) exif->fGPSProcessingMethod.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.GPSInfo.GPSAreaInformation");
            if (!str.isEmpty()) exif->fGPSAreaInformation.Set_ASCII(str.toAscii());

            str = meta.getExifTagString("Exif.GPSInfo.GPSDateStamp");
            if (!str.isEmpty()) exif->fGPSDateStamp.Set_ASCII(str.toAscii());

            // Rational Tags

            if (meta.getExifTagRational("Exif.Photo.ExposureTime", num, den))          exif->fExposureTime          = dng_urational(num, den);
            if (meta.getExifTagRational("Exif.Photo.FNumber", num, den))               exif->fFNumber               = dng_urational(num, den);
            if (meta.getExifTagRational("Exif.Photo.ShutterSpeedValue", num, den))     exif->fShutterSpeedValue     = dng_srational(num, den);
            if (meta.getExifTagRational("Exif.Photo.ApertureValue", num, den))         exif->fApertureValue         = dng_urational(num, den);
            if (meta.getExifTagRational("Exif.Photo.BrightnessValue", num, den))       exif->fBrightnessValue       = dng_srational(num, den);
            if (meta.getExifTagRational("Exif.Photo.ExposureBiasValue", num, den))     exif->fExposureBiasValue     = dng_srational(num, den);
            if (meta.getExifTagRational("Exif.Photo.MaxApertureValue", num, den))      exif->fMaxApertureValue      = dng_urational(num, den);
            if (meta.getExifTagRational("Exif.Photo.FocalLength", num, den))           exif->fFocalLength           = dng_urational(num, den);
            if (meta.getExifTagRational("Exif.Photo.DigitalZoomRatio", num, den))      exif->fDigitalZoomRatio      = dng_urational(num, den);
            if (meta.getExifTagRational("Exif.Photo.SubjectDistance", num, den))       exif->fSubjectDistance       = dng_urational(num, den);
            if (meta.getExifTagRational("Exif.Image.BatteryLevel", num, den))          exif->fBatteryLevelR         = dng_urational(num, den);
            if (meta.getExifTagRational("Exif.Photo.FocalPlaneXResolution", num, den)) exif->fFocalPlaneXResolution = dng_urational(num, den);
            if (meta.getExifTagRational("Exif.Photo.FocalPlaneYResolution", num, den)) exif->fFocalPlaneYResolution = dng_urational(num, den);
            if (meta.getExifTagRational("Exif.GPSInfo.GPSAltitude", num, den))         exif->fGPSAltitude           = dng_urational(num, den);
            if (meta.getExifTagRational("Exif.GPSInfo.GPSDOP", num, den))              exif->fGPSDOP                = dng_urational(num, den);
            if (meta.getExifTagRational("Exif.GPSInfo.GPSSpeed", num, den))            exif->fGPSSpeed              = dng_urational(num, den);
            if (meta.getExifTagRational("Exif.GPSInfo.GPSTrack", num, den))            exif->fGPSTrack              = dng_urational(num, den);
            if (meta.getExifTagRational("Exif.GPSInfo.GPSImgDirection", num, den))     exif->fGPSImgDirection       = dng_urational(num, den);
            if (meta.getExifTagRational("Exif.GPSInfo.GPSDestBearing", num, den))      exif->fGPSDestBearing        = dng_urational(num, den);
            if (meta.getExifTagRational("Exif.GPSInfo.GPSDestDistance", num, den))     exif->fGPSDestDistance       = dng_urational(num, den);
            if (meta.getExifTagRational("Exif.GPSInfo.GPSLatitude", num, den))         exif->fGPSLatitude[0]        = dng_urational(num, den);
            if (meta.getExifTagRational("Exif.GPSInfo.GPSLongitude", num, den))        exif->fGPSLongitude[0]       = dng_urational(num, den);
            if (meta.getExifTagRational("Exif.GPSInfo.GPSTimeStamp", num, den))        exif->fGPSTimeStamp[0]       = dng_urational(num, den);
            if (meta.getExifTagRational("Exif.GPSInfo.GPSDestLatitude", num, den))     exif->fGPSDestLatitude[0]    = dng_urational(num, den);
            if (meta.getExifTagRational("Exif.GPSInfo.GPSDestLongitude", num, den))    exif->fGPSDestLongitude[0]   = dng_urational(num, den);

            // Integer Tags

            if (meta.getExifTagLong("Exif.Photo.ExposureProgram", val))          exif->fExposureProgram          = (uint32)val;
            if (meta.getExifTagLong("Exif.Photo.MeteringMode", val))             exif->fMeteringMode             = (uint32)val;
            if (meta.getExifTagLong("Exif.Photo.LightSource", val))              exif->fLightSource              = (uint32)val;
            if (meta.getExifTagLong("Exif.Photo.Flash", val))                    exif->fFlash                    = (uint32)val;
            if (meta.getExifTagLong("Exif.Photo.SensingMethod", val))            exif->fSensingMethod            = (uint32)val;
            if (meta.getExifTagLong("Exif.Photo.FileSource", val))               exif->fFileSource               = (uint32)val;
            if (meta.getExifTagLong("Exif.Photo.SceneType", val))                exif->fSceneType                = (uint32)val;
            if (meta.getExifTagLong("Exif.Photo.CustomRendered", val))           exif->fCustomRendered           = (uint32)val;
            if (meta.getExifTagLong("Exif.Photo.ExposureMode", val))             exif->fExposureMode             = (uint32)val;
            if (meta.getExifTagLong("Exif.Photo.WhiteBalance", val))             exif->fWhiteBalance             = (uint32)val;
            if (meta.getExifTagLong("Exif.Photo.SceneCaptureType", val))         exif->fSceneCaptureType         = (uint32)val;
            if (meta.getExifTagLong("Exif.Photo.GainControl", val))              exif->fGainControl              = (uint32)val;
            if (meta.getExifTagLong("Exif.Photo.Contrast", val))                 exif->fContrast                 = (uint32)val;
            if (meta.getExifTagLong("Exif.Photo.Saturation", val))               exif->fSaturation               = (uint32)val;
            if (meta.getExifTagLong("Exif.Photo.Sharpness", val))                exif->fSharpness                = (uint32)val;
            if (meta.getExifTagLong("Exif.Photo.SubjectDistanceRange", val))     exif->fSubjectDistanceRange     = (uint32)val;
            if (meta.getExifTagLong("Exif.Photo.FocalLengthIn35mmFilm", val))    exif->fFocalLengthIn35mmFilm    = (uint32)val;
            if (meta.getExifTagLong("Exif.Photo.ComponentsConfiguration", val))  exif->fComponentsConfiguration  = (uint32)val;
            if (meta.getExifTagLong("Exif.Photo.PixelXDimension", val))          exif->fPixelXDimension          = (uint32)val;
            if (meta.getExifTagLong("Exif.Photo.PixelYDimension", val))          exif->fPixelYDimension          = (uint32)val;
            if (meta.getExifTagLong("Exif.Photo.FocalPlaneResolutionUnit", val)) exif->fFocalPlaneResolutionUnit = (uint32)val;
            if (meta.getExifTagLong("Exif.GPSInfo.GPSVersionID", val))           exif->fGPSVersionID             = (uint32)val;
            if (meta.getExifTagLong("Exif.GPSInfo.GPSAltitudeRef", val))         exif->fGPSAltitudeRef           = (uint32)val;
            if (meta.getExifTagLong("Exif.GPSInfo.GPSDifferential", val))        exif->fGPSDifferential          = (uint32)val;
        }

        // Markernote backup.

        QByteArray mkrnts = meta.getExifTagData("Exif.Photo.MakerNote");
        if (!mkrnts.isEmpty())
        {
            kDebug( 51000 ) << "DNGWriter: Backup Makernote (" << mkrnts.size() << " bytes)" << endl;

            dng_memory_allocator memalloc(gDefaultDNGMemoryAllocator);
            dng_memory_stream stream(memalloc);
            stream.Put(mkrnts.data(), mkrnts.size());
            AutoPtr<dng_memory_block> block(host.Allocate(mkrnts.size()));
            stream.SetReadPosition(0);
            stream.Get(block->Buffer(), mkrnts.size());
            negative->SetMakerNote(block);
            negative->SetMakerNoteSafety(true);
        }

        if (d->backupOriginalRawFile)
        {
            kDebug( 51000 ) << "DNGWriter: Backup Original RAW file (" << inputInfo.size() << " bytes)" << endl;

            // Compress Raw file data to Zip archive.

            QTemporaryFile zipFile;
            if (!zipFile.open())
            {
                kDebug( 51000 ) << "DNGWriter: Cannot open temporary file to write Zip Raw file. Aborted..." << endl;
                return -1;
            }
            KZip zipArchive(zipFile.fileName());
            zipArchive.open(QIODevice::WriteOnly);
            zipArchive.setCompression(KZip::DeflateCompression);
            zipArchive.addLocalFile(inputFile(), inputFile());
            zipArchive.close();

            // Load Zip Archive in a byte array

            QFileInfo zipFileInfo(zipFile.fileName());
            QByteArray zipRawFileData;
            zipRawFileData.resize(zipFileInfo.size());
            QDataStream dataStream(&zipFile);
            dataStream.readRawData(zipRawFileData.data(), zipRawFileData.size());
            kDebug( 51000 ) << "DNGWriter: Zipped RAW file size " << zipRawFileData.size() << " bytes" << endl;

            // Pass byte array to DNG sdk and compute MD5 fingerprint.

            dng_memory_allocator memalloc(gDefaultDNGMemoryAllocator);
            dng_memory_stream stream(memalloc);
            stream.Put(zipRawFileData.data(), zipRawFileData.size());
            AutoPtr<dng_memory_block> block(host.Allocate(zipRawFileData.size()));
            stream.SetReadPosition(0);
            stream.Get(block->Buffer(), zipRawFileData.size());

            dng_md5_printer md5;
            md5.Process(block->Buffer(), block->LogicalSize());
            negative->SetOriginalRawFileData(block);
            negative->SetOriginalRawFileDigest(md5.Result());
            negative->ValidateOriginalRawFileDigest();

            zipFile.remove();
        }

        if (d->cancel) return -2;

        // -----------------------------------------------------------------------------------------

        kDebug( 51000 ) << "DNGWriter: Build DNG Negative" << endl;

        // Assign Raw image data.
        negative->SetStage1Image(image);

        // Compute linearized and range mapped image
        negative->BuildStage2Image(host);

        // Compute demosaiced image (used by preview and thumbnail)
        negative->BuildStage3Image(host);

        negative->SynchronizeMetadata();
        negative->RebuildIPTC();

        if (d->cancel) return -2;

        // -----------------------------------------------------------------------------------------

        dng_preview_list previewList;

// NOTE: something is wrong with Qt < 4.4.0 to import TIFF data as stream in QImage.
#if QT_VERSION >= 0x40400

        if (d->previewMode != DNGWriter::NONE)
        {
            kDebug( 51000 ) << "DNGWriter: DNG preview image creation" << endl;

            // Construct a preview image as TIFF format.
            AutoPtr<dng_image> tiffImage;
            dng_render tiff_render(host, *negative);
            tiff_render.SetFinalSpace(dng_space_sRGB::Get());
            tiff_render.SetFinalPixelType(ttByte);
            tiff_render.SetMaximumSize(d->previewMode == MEDIUM ? 1280 : width);
            tiffImage.Reset(tiff_render.Render());

            dng_image_writer tiff_writer;
            AutoPtr<dng_memory_stream> dms(new dng_memory_stream(gDefaultDNGMemoryAllocator));

            tiff_writer.WriteTIFF(host, *dms, *tiffImage.Get(), piRGB,
                                  ccUncompressed, negative.Get(), &tiff_render.FinalSpace());

            // Write TIFF preview image data to a temp JPEG file
            std::vector<char> tiff_mem_buffer(dms->Length());
            dms->SetReadPosition(0);
            dms->Get(&tiff_mem_buffer.front(), tiff_mem_buffer.size());
            dms.Reset();

            QImage pre_image;
            if (!pre_image.loadFromData((uchar*)&tiff_mem_buffer.front(), tiff_mem_buffer.size(), "TIFF"))
            {
                kDebug( 51000 ) << "DNGWriter: Cannot load TIFF preview data in memory. Aborted..." << endl;
                return -1;
            }

            QTemporaryFile previewFile;
            if (!previewFile.open())
            {
                kDebug( 51000 ) << "DNGWriter: Cannot open temporary file to write JPEG preview. Aborted..." << endl;
                return -1;
            }

            if (!pre_image.save(previewFile.fileName(), "JPEG", 90))
            {
                kDebug( 51000 ) << "DNGWriter: Cannot save file to write JPEG preview. Aborted..." << endl;
                return -1;
            }

            // Load JPEG preview file data in DNG preview container.
            AutoPtr<dng_jpeg_preview> jpeg_preview;
            jpeg_preview.Reset(new dng_jpeg_preview);
            jpeg_preview->fPhotometricInterpretation = piYCbCr;
            jpeg_preview->fPreviewSize.v             = pre_image.height();
            jpeg_preview->fPreviewSize.h             = pre_image.width();
            jpeg_preview->fCompressedData.Reset(host.Allocate(previewFile.size()));

            QDataStream previewStream( &previewFile );
            previewStream.readRawData(jpeg_preview->fCompressedData->Buffer_char(), previewFile.size());

            AutoPtr<dng_preview> pp( dynamic_cast<dng_preview*>(jpeg_preview.Release()) );
            previewList.Append(pp);

            previewFile.remove();
        }

#endif /* QT_VERSION >= 0x40400 */

        if (d->cancel) return -2;

        // -----------------------------------------------------------------------------------------

        kDebug( 51000 ) << "DNGWriter: DNG thumbnail creation" << endl;

        dng_image_preview thumbnail;
        dng_render thumbnail_render(host, *negative);
        thumbnail_render.SetFinalSpace(dng_space_sRGB::Get());
        thumbnail_render.SetFinalPixelType(ttByte);
        thumbnail_render.SetMaximumSize(256);
        thumbnail.fImage.Reset(thumbnail_render.Render());

        if (d->cancel) return -2;

        // -----------------------------------------------------------------------------------------

        kDebug( 51000 ) << "DNGWriter: Creating DNG file " << outputInfo.fileName() << endl;

        dng_image_writer writer;
        dng_file_stream filestream(QFile::encodeName(dngFilePath), true);

        writer.WriteDNG(host, filestream, *negative.Get(), thumbnail, 
                        d->jpegLossLessCompression ? ccJPEG : ccUncompressed,
                        &previewList);
    }

    catch (const dng_exception &exception)
    {
        int ret = exception.ErrorCode();
        kDebug( 51000 ) << "DNGWriter: DNG SDK exception code (" << ret << ")" << endl;
        return ret;
    }

    catch (...)
    {
        kDebug( 51000 ) << "DNGWriter: DNG SDK exception code unknow" << endl;
        return dng_error_unknown;
    }

    kDebug( 51000 ) << "DNGWriter: DNG conversion complete..." << endl;

    return dng_error_none;
}
Exemplo n.º 7
0
int main (int argc, char **argv)
{
    if (argc != 3)
    {
        qDebug() << "Adding a face rectangle to image";
        qDebug() << "Usage: <add/remove> <image>";
        return -1;
    }

    QString filePath(QString::fromLatin1(argv[2]));

    KExiv2Iface::KExiv2::initializeExiv2();
    KExiv2 meta;
    meta.load(filePath);
    meta.setWriteRawFiles(true);

    /** Add a random rectangle with facetag Bob **/
    QString name = QString::fromLatin1("Bob Marley");
    float x =0.5;
    float y =0.5;
    float w = 60;
    float h = 60;

    QRectF rect(x,y,w,h);

    QMap<QString, QRectF> faces;

    faces[name] = rect;

    QString name2 = QString::fromLatin1("Hello Kitty!");
    QRectF rect2(0.4,0.4,30,30);

    faces[name2] = rect2;

    bool g = meta.supportXmp();

    qDebug() << "Image support XMP" << g;

    const QString bag = QString::fromLatin1("Xmp.mwg-rs.Regions/mwg-rs:RegionList");

    QString op(QString::fromLatin1(argv[1]));

    if (op == QString::fromLatin1("add"))
        setFaceTags(meta,bag.toLatin1().constData(),faces,false);
    else
        removeFaceTags(meta,bag.toLatin1().constData());

        meta.applyChanges();

    QString recoverName = QString::fromLatin1("Xmp.mwg-rs.Regions/mwg-rs:RegionList[1]/mwg-rs:Name");

    KExiv2 meta2;
    meta2.load(filePath);
    meta2.setWriteRawFiles(true);

    QString nameR = meta2.getXmpTagString(recoverName.toLatin1().constData(),false);

    qDebug() << "Saved name is:" << nameR;

    KExiv2Iface::KExiv2::cleanupExiv2();
    return 0;
}