GridInfoObjectType *CreateGridInfoObject( char *fileName ) { int numberGrids; int maxPossibleGrids; int gridFileID; int iret; int gridCounter; GridInfoObjectType *gio; GridType *gt; /* * Character Strings passed to GEMPAK fortran subroutines. When passing * the length of the string to GEMPAK, subtract out one for the NULL. * */ char lastTime[GEMPAKSTRING]; char time1[GEMPAKSTRING]; char time2[GEMPAKSTRING]; char gridField[GEMPAKSTRING]; int levels[2]; int jvcoordinate; /* may not be right declaration - check common */ int verbose; verbose = GetVerboseLevel(); if ( verbose > VERBOSE_0 ) printf ("CreateGridInfoObject\n" ); memset( lastTime, 0, sizeof( lastTime ) ); memset( time1, 0, sizeof( time1 ) ); memset( time2, 0, sizeof( time2 ) ); memset( gridField, 0, sizeof( gridField) ); gdinfo( fileName, lastTime, &numberGrids, &maxPossibleGrids, &gridFileID, &iret, strlen( fileName ), sizeof( lastTime ) - 1); if( iret ) return( NULL ); /* * Allocate all the memory... */ gio = (GridInfoObjectType *) malloc( sizeof(GridInfoObjectType) ); gio->gridList = (GridType *) malloc( numberGrids * sizeof( GridType) ); /* * ....and then check for errors. */ if( ! gio || ! gio->gridList ) { printf("*** CreateGridInfoObject: malloc failure.\n"); return( NULL ); } /* * Intialize the object. */ gt = gio->gridList; memset( gt, 0, numberGrids * sizeof( GridType) ); gio->fileName = strdup( fileName ); gio->lastTime = strdup( lastTime ); gio->numberOfGrids = numberGrids; gio->maxPossibleGrids = maxPossibleGrids; gio->destroyFunc = GridInfoObjectDestroy; gio->printfFunc = GridInfoObjectPrintf; gio->textFunc = GridInfoObjectToText; gio->numLevels = 0; gio->levels = NULL; gio->numTimes = 0; gio->times = NULL; gio->numVerticalCoordinates = 0; gio->verticalCoordinates = NULL; gio->numGridFields = 0; gio->gridFields = NULL; gio->numForecastIntervals = 0; gio->forecastIntervals = NULL; if ( verbose > VERBOSE_1 ) { printf(" file is %s\n", fileName ); printf(" numberGrids %d,", numberGrids ); printf(" maxPossibleGrids %d,", maxPossibleGrids ); printf(" iret %d\n", iret ); } iret = 0; for( gridCounter = 1; gridCounter <= numberGrids; gridCounter++, gt++ ){ getnxtgrd( &gridFileID, &gridCounter, gt->time1, gt->time2, gt->levels, gt->verticalCoordinate, gt->gridField, &iret, sizeof(gt->time1) - 1, sizeof(gt->time2) - 1, sizeof(gt->verticalCoordinate) - 1, sizeof(gt->gridField) - 1 ); if( iret ) { printf(" CreateGridInfoObject: getnxtgrd ret %d\n", iret ); break; } StringClean( gt->time1 ); StringClean( gt->time2 ); StringClean( gt->gridField ); StringClean( gt->verticalCoordinate ); if ( verbose > VERBOSE_3 ) { printf(" Grid # %d:\n", gridCounter ); printf(" time1 %s,", gt->time1 ); printf(" time2 %s,", gt->time2 ); printf(" lev1 %d,", gt->levels[0] ); printf(" lev2 %d,", gt->levels[1] ); printf(" jv %s,", gt->verticalCoordinate ); printf(" gridField %s\n", gt->gridField ); } AddString( gio->numberOfGrids, &gio->numForecastIntervals, &gio->forecastIntervals, ParseOffForecast(gt->time1) ); AddString( gio->numberOfGrids, &gio->numTimes, &gio->times, gt->time1 ); AddString( gio->numberOfGrids, &gio->numGridFields, &gio->gridFields, gt->gridField ); AddString( gio->numberOfGrids, &gio->numVerticalCoordinates, &gio->verticalCoordinates, gt->verticalCoordinate ); AddInteger( gio->numberOfGrids, &gio->numLevels, &gio->levels, gt->levels[0] ); } /* for(;;) */ /* * Cleanup and go home if there was an error. */ if( iret ) { (*gio->destroyFunc)( gio ); gio = NULL; } /* * Close the gridfile for next time... */ gd_clos( &gridFileID, &iret ); return( gio ); }
bool ptImageHelper::WriteExif(const QString &AFileName, const std::vector<uint8_t> &AExifBuffer, Exiv2::IptcData &AIptcData, Exiv2::XmpData &AXmpData) { try { #if EXIV2_TEST_VERSION(0,17,91) /* Exiv2 0.18-pre1 */ Exiv2::ExifData hInExifData; Exiv2::ExifParser::decode(hInExifData, AExifBuffer.data() + CExifHeader.size(), AExifBuffer.size() - CExifHeader.size()); // Reset orientation Exiv2::ExifData::iterator pos = hInExifData.begin(); if ((pos = hInExifData.findKey(Exiv2::ExifKey("Exif.Image.Orientation"))) != hInExifData.end()) { pos->setValue("1"); // Normal orientation } // Adapted from UFRaw, necessary for Tiff files QStringList ExifKeys; ExifKeys << "Exif.Image.ImageWidth" << "Exif.Image.ImageLength" << "Exif.Image.BitsPerSample" << "Exif.Image.Compression" << "Exif.Image.PhotometricInterpretation" << "Exif.Image.FillOrder" << "Exif.Image.SamplesPerPixel" << "Exif.Image.StripOffsets" << "Exif.Image.RowsPerStrip" << "Exif.Image.StripByteCounts" << "Exif.Image.XResolution" << "Exif.Image.YResolution" << "Exif.Image.PlanarConfiguration" << "Exif.Image.ResolutionUnit"; for (short i = 0; i < ExifKeys.count(); i++) { if ((pos = hInExifData.findKey(Exiv2::ExifKey(ExifKeys.at(i).toLocal8Bit().data()))) != hInExifData.end()) hInExifData.erase(pos); } if (Settings->GetInt("EraseExifThumbnail")) { Exiv2::ExifThumb Thumb(hInExifData); Thumb.erase(); } QStringList JpegExtensions; JpegExtensions << "jpg" << "JPG" << "Jpg" << "jpeg" << "Jpeg" << "JPEG"; bool deleteDNGdata = false; for (short i = 0; i < JpegExtensions.count(); i++) { if (!AFileName.endsWith(JpegExtensions.at(i))) deleteDNGdata = true; } Exiv2::Image::AutoPtr Exiv2Image = Exiv2::ImageFactory::open(AFileName.toLocal8Bit().data()); Exiv2Image->readMetadata(); Exiv2::ExifData outExifData = Exiv2Image->exifData(); for (auto hPos = hInExifData.begin(); hPos != hInExifData.end(); hPos++) { if (!deleteDNGdata || (*hPos).key() != "Exif.Image.DNGPrivateData") { outExifData.add(*hPos); } } // IPTC data QStringList Tags = Settings->GetStringList("TagsList"); QStringList DigikamTags = Settings->GetStringList("DigikamTagsList"); Exiv2::StringValue StringValue; for (int i = 0; i < Tags.size(); i++) { StringValue.read(Tags.at(i).toStdString()); AIptcData.add(Exiv2::IptcKey("Iptc.Application2.Keywords"), &StringValue); } // XMP data for (int i = 0; i < Tags.size(); i++) { AXmpData["Xmp.dc.subject"] = Tags.at(i).toStdString(); } for (int i = 0; i < DigikamTags.size(); i++) { AXmpData["Xmp.digiKam.TagsList"] = DigikamTags.at(i).toStdString(); } // Image rating outExifData["Exif.Image.Rating"] = Settings->GetInt("ImageRating"); AXmpData["Xmp.xmp.Rating"] = Settings->GetInt("ImageRating"); // Program name outExifData["Exif.Image.ProcessingSoftware"] = ProgramName; outExifData["Exif.Image.Software"] = ProgramName; AIptcData["Iptc.Application2.Program"] = ProgramName; AIptcData["Iptc.Application2.ProgramVersion"] = "idle"; AXmpData["Xmp.xmp.CreatorTool"] = ProgramName; AXmpData["Xmp.tiff.Software"] = ProgramName; // Title QString TitleWorking = Settings->GetString("ImageTitle"); StringClean(TitleWorking); if (TitleWorking != "") { outExifData["Exif.Photo.UserComment"] = TitleWorking.toStdString(); AIptcData["Iptc.Application2.Caption"] = TitleWorking.toStdString(); AXmpData["Xmp.dc.description"] = TitleWorking.toStdString(); AXmpData["Xmp.exif.UserComment"] = TitleWorking.toStdString(); AXmpData["Xmp.tiff.ImageDescription"] = TitleWorking.toStdString(); } // Copyright QString CopyrightWorking = Settings->GetString("Copyright"); StringClean(CopyrightWorking); if (CopyrightWorking != "") { outExifData["Exif.Image.Copyright"] = CopyrightWorking.toStdString(); AIptcData["Iptc.Application2.Copyright"] = CopyrightWorking.toStdString(); AXmpData["Xmp.tiff.Copyright"] = CopyrightWorking.toStdString(); } Exiv2Image->setExifData(outExifData); Exiv2Image->setIptcData(AIptcData); Exiv2Image->setXmpData(AXmpData); Exiv2Image->writeMetadata(); return true; #endif } catch (Exiv2::AnyError& Error) { if (Settings->GetInt("JobMode") == 0) { ptMessageBox::warning(0 ,"Exiv2 Error","No exif data written!\nCaught Exiv2 exception '" + QString(Error.what()) + "'\n"); } else { std::cout << "Caught Exiv2 exception '" << Error << "'\n"; } } return false; }