diff --git a/core/dplugins/generic/tools/panorama/panoparser/ptoparser/ptofile.cpp b/core/dplugins/generic/tools/panorama/panoparser/ptoparser/ptofile.cpp index 698002d2c9..02cc77c788 100644 --- a/core/dplugins/generic/tools/panorama/panoparser/ptoparser/ptofile.cpp +++ b/core/dplugins/generic/tools/panorama/panoparser/ptoparser/ptofile.cpp @@ -1,552 +1,561 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2012-02-04 * Description : a tool to create panorama by fusion of several images. * This parser is based on pto file format described here: * http://hugin.sourceforge.net/docs/nona/nona.txt, and * on pto files produced by Hugin's tools. * * Copyright (C) 2012-2015 by Benjamin Girault * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "ptofile.h" // C++ includes #include #include // Qt includes #include // Local includes #include "digikam_debug.h" extern "C" { #include "tparser.h" #include "tparsergetters.h" } namespace Digikam { class Q_DECL_HIDDEN PTOFile::Private { public: explicit Private(const QString& huginVersion) : script(nullptr), huginVersion(huginVersion) { } pt_script* script; const QString& huginVersion; }; PTOFile::PTOFile(const QString& huginVersion) : d(new Private(huginVersion)) { } PTOFile::~PTOFile() { if (d->script != nullptr) { panoScriptFree(d->script); delete d->script; } delete d; } bool PTOFile::openFile(const QString& path) { -// mtrace(); - +/* + mtrace(); +*/ if (d->script != nullptr) { panoScriptFree(d->script); delete d->script; d->script = nullptr; } d->script = new pt_script(); if (!panoScriptParse(QFile::encodeName(path).constData(), d->script)) { return false; } - -// muntrace(); - +/* + muntrace(); +*/ return true; } PTOType* PTOFile::getPTO() { if (d->script == nullptr) { return nullptr; } PTOType* const out = new PTOType(d->huginVersion); // Project data conversion + for (int c = 0 ; c < panoScriptGetPanoPrevCommentsCount(d->script) ; ++c) { out->project.previousComments << QString::fromLocal8Bit(panoScriptGetPanoComment(d->script, c)); } out->project.size.setHeight(panoScriptGetPanoHeight(d->script)); out->project.size.setWidth(panoScriptGetPanoWidth(d->script)); out->project.crop.setLeft(panoScriptGetPanoCropLeft(d->script)); out->project.crop.setRight(panoScriptGetPanoCropRight(d->script)); out->project.crop.setTop(panoScriptGetPanoCropTop(d->script)); out->project.crop.setBottom(panoScriptGetPanoCropBottom(d->script)); out->project.projection = PTOType::Project::ProjectionType(panoScriptGetPanoProjection(d->script)); out->project.fieldOfView = panoScriptGetPanoHFOV(d->script); out->project.fileFormat.fileType = PTOType::Project::FileFormat::FileType(panoScriptGetPanoOutputFormat(d->script)); switch (out->project.fileFormat.fileType) { case PTOType::Project::FileFormat::TIFF_m: case PTOType::Project::FileFormat::TIFF_multilayer: { out->project.fileFormat.savePositions = panoScriptGetPanoOutputSaveCoordinates(d->script) != 0; out->project.fileFormat.cropped = panoScriptGetPanoOutputCropped(d->script) != 0; break; } case PTOType::Project::FileFormat::TIFF: { int method = panoScriptGetPanoOutputCompression(d->script); if (method != -1) out->project.fileFormat.compressionMethod = PTOType::Project::FileFormat::CompressionMethod(method); break; } case PTOType::Project::FileFormat::JPEG: { int quality = panoScriptGetPanoOutputQuality(d->script); if (quality >= 0) out->project.fileFormat.quality = quality; break; } default: { break; } } out->project.exposure = panoScriptGetPanoExposure(d->script); out->project.hdr = panoScriptGetPanoIsHDR(d->script) != 0; out->project.bitDepth = PTOType::Project::BitDepth(panoScriptGetPanoBitDepth(d->script)); out->project.photometricReferenceId = panoScriptGetPanoImageReference(d->script); + // NOTE: there should not be any unmatched parameters at this point, because the parsing would otherwise have failed // Stitcher + for (int c = 0 ; c < panoScriptGetOptimizePrevCommentsCount(d->script) ; ++c) { out->stitcher.previousComments << QString::fromLocal8Bit(panoScriptGetOptimizeComment(d->script, c)); } out->stitcher.gamma = panoScriptGetOptimizeGamma(d->script); out->stitcher.interpolator = PTOType::Stitcher::Interpolator(panoScriptGetOptimizeInterpolator(d->script)); out->stitcher.speedUp = PTOType::Stitcher::SpeedUp(panoScriptGetOptimizeSpeedUp(d->script)); out->stitcher.huberSigma = panoScriptGetOptimizeHuberSigma(d->script); out->stitcher.photometricHuberSigma = panoScriptGetOptimizePhotometricHuberSigma(d->script); // Images + out->images.clear(); for (int i = 0 ; i < panoScriptGetImagesCount(d->script) ; ++i) { out->images.insert(i, PTOType::Image()); PTOType::Image& image = out->images.last(); int tmpRef; for (int c = 0 ; c < panoScriptGetImagePrevCommentsCount(d->script, i) ; ++c) { image.previousComments << QString::fromLocal8Bit(panoScriptGetImageComment(d->script, i, c)); } image.size.setWidth(panoScriptGetImageWidth(d->script, i)); image.size.setHeight(panoScriptGetImageHeight(d->script, i)); image.id = i; image.lensProjection = PTOType::Image::LensProjection(panoScriptGetImageProjection(d->script, i)); tmpRef = panoScriptGetImageHFOVRef(d->script, i); if (tmpRef == -1) { image.fieldOfView.value = panoScriptGetImageHFOV(d->script, i); } else { image.fieldOfView.referenceId = tmpRef; } image.yaw = panoScriptGetImageYaw(d->script, i); image.pitch = panoScriptGetImagePitch(d->script, i); image.roll = panoScriptGetImageRoll(d->script, i); tmpRef = panoScriptGetImageCoefARef(d->script, i); if (tmpRef == -1) { image.lensBarrelCoefficientA.value = panoScriptGetImageCoefA(d->script, i); } else { image.lensBarrelCoefficientA.referenceId = tmpRef; } tmpRef = panoScriptGetImageCoefBRef(d->script, i); if (tmpRef == -1) { image.lensBarrelCoefficientB.value = panoScriptGetImageCoefB(d->script, i); } else { image.lensBarrelCoefficientB.referenceId = tmpRef; } tmpRef = panoScriptGetImageCoefCRef(d->script, i); if (tmpRef == -1) { image.lensBarrelCoefficientC.value = panoScriptGetImageCoefC(d->script, i); } else { image.lensBarrelCoefficientC.referenceId = tmpRef; } tmpRef = panoScriptGetImageCoefDRef(d->script, i); if (tmpRef == -1) { image.lensCenterOffsetX.value = panoScriptGetImageCoefD(d->script, i); } else { image.lensCenterOffsetX.referenceId = tmpRef; } tmpRef = panoScriptGetImageCoefERef(d->script, i); if (tmpRef == -1) { image.lensCenterOffsetY.value = panoScriptGetImageCoefE(d->script, i); } else { image.lensCenterOffsetY.referenceId = tmpRef; } tmpRef = panoScriptGetImageSheerXRef(d->script, i); if (tmpRef == -1) { image.lensShearX.value = panoScriptGetImageSheerX(d->script, i); } else { image.lensShearX.referenceId = tmpRef; } tmpRef = panoScriptGetImageSheerYRef(d->script, i); if (tmpRef == -1) { image.lensShearY.value = panoScriptGetImageSheerY(d->script, i); } else { image.lensShearY.referenceId = tmpRef; } tmpRef = panoScriptGetImageExposureRef(d->script, i); if (tmpRef == -1) { image.exposure.value = panoScriptGetImageExposure(d->script, i); } else { image.exposure.referenceId = tmpRef; } tmpRef = panoScriptGetImageWBRedRef(d->script, i); if (tmpRef == -1) { image.whiteBalanceRed.value = panoScriptGetImageWBRed(d->script, i); } else { image.whiteBalanceRed.referenceId = tmpRef; } tmpRef = panoScriptGetImageWBBlueRef(d->script, i); if (tmpRef == -1) { image.whiteBalanceBlue.value = panoScriptGetImageWBBlue(d->script, i); } else { image.whiteBalanceBlue.referenceId = tmpRef; } tmpRef = panoScriptGetImageVignettingModeRef(d->script, i); if (tmpRef == -1) { image.vignettingMode.value = PTOType::Image::VignettingMode(panoScriptGetImageVignettingMode(d->script, i)); } else { image.vignettingMode.referenceId = tmpRef; } tmpRef = panoScriptGetImageVignettingCoeffARef(d->script, i); if (tmpRef == -1) { image.vignettingCorrectionI.value = panoScriptGetImageVignettingCoeffA(d->script, i); } else { image.vignettingCorrectionI.referenceId = tmpRef; } tmpRef = panoScriptGetImageVignettingCoeffBRef(d->script, i); if (tmpRef == -1) { image.vignettingCorrectionJ.value = panoScriptGetImageVignettingCoeffB(d->script, i); } else { image.vignettingCorrectionJ.referenceId = tmpRef; } tmpRef = panoScriptGetImageVignettingCoeffCRef(d->script, i); if (tmpRef == -1) { image.vignettingCorrectionK.value = panoScriptGetImageVignettingCoeffC(d->script, i); } else { image.vignettingCorrectionK.referenceId = tmpRef; } tmpRef = panoScriptGetImageVignettingCoeffDRef(d->script, i); if (tmpRef == -1) { image.vignettingCorrectionL.value = panoScriptGetImageVignettingCoeffD(d->script, i); } else { image.vignettingCorrectionL.referenceId = tmpRef; } tmpRef = panoScriptGetImageVignettingCoeffXRef(d->script, i); if (tmpRef == -1) { image.vignettingOffsetX.value = panoScriptGetImageVignettingCoeffX(d->script, i); } else { image.vignettingOffsetX.referenceId = tmpRef; } tmpRef = panoScriptGetImageVignettingCoeffYRef(d->script, i); if (tmpRef == -1) { image.vignettingOffsetY.value = panoScriptGetImageVignettingCoeffY(d->script, i); } else { image.vignettingOffsetY.referenceId = tmpRef; } char* const flatfield = panoScriptGetImageVignettingFlatField(d->script, i); if (flatfield != nullptr) { image.vignettingFlatfieldImageName = QString::fromLocal8Bit(flatfield); } tmpRef = panoScriptGetImagePhotometricCoeffARef(d->script, i); if (tmpRef == -1) { image.photometricEMoRA.value = panoScriptGetImagePhotometricCoeffA(d->script, i); } else { image.photometricEMoRA.referenceId = tmpRef; } tmpRef = panoScriptGetImagePhotometricCoeffBRef(d->script, i); if (tmpRef == -1) { image.photometricEMoRB.value = panoScriptGetImagePhotometricCoeffB(d->script, i); } else { image.photometricEMoRB.referenceId = tmpRef; } tmpRef = panoScriptGetImagePhotometricCoeffCRef(d->script, i); if (tmpRef == -1) { image.photometricEMoRC.value = panoScriptGetImagePhotometricCoeffC(d->script, i); } else { image.photometricEMoRC.referenceId = tmpRef; } tmpRef = panoScriptGetImagePhotometricCoeffDRef(d->script, i); if (tmpRef == -1) { image.photometricEMoRD.value = panoScriptGetImagePhotometricCoeffD(d->script, i); } else { image.photometricEMoRD.referenceId = tmpRef; } tmpRef = panoScriptGetImagePhotometricCoeffERef(d->script, i); if (tmpRef == -1) { image.photometricEMoRE.value = panoScriptGetImagePhotometricCoeffE(d->script, i); } else { image.photometricEMoRE.referenceId = tmpRef; } image.mosaicCameraPositionX = panoScriptGetImageCameraTranslationX(d->script, i); image.mosaicCameraPositionY = panoScriptGetImageCameraTranslationY(d->script, i); image.mosaicCameraPositionZ = panoScriptGetImageCameraTranslationZ(d->script, i); image.mosaicProjectionPlaneYaw = panoScriptGetImageProjectionPlaneYaw(d->script, i); image.mosaicProjectionPlanePitch = panoScriptGetImageProjectionPlanePitch(d->script, i); image.crop.setLeft(panoScriptGetImageCropLeft(d->script, i)); image.crop.setRight(panoScriptGetImageCropRight(d->script, i)); image.crop.setTop(panoScriptGetImageCropTop(d->script, i)); image.crop.setBottom(panoScriptGetImageCropBottom(d->script, i)); tmpRef = panoScriptGetImageStackRef(d->script, i); if (tmpRef == -1) { image.stackNumber.value = panoScriptGetImageStack(d->script, i); } else { image.stackNumber.referenceId = tmpRef; } image.fileName = QString::fromLocal8Bit(panoScriptGetImageName(d->script, i)); } // Masks + for (int m = 0 ; m < panoScriptGetMaskCount(d->script) ; ++m) { int image = panoScriptGetMaskImage(d->script, m); out->images[image].masks.append(PTOType::Mask()); PTOType::Mask& mask = out->images[image].masks.last(); for (int c = 0 ; c < panoScriptGetMaskPrevCommentCount(d->script, m) ; ++c) { mask.previousComments << QString::fromLocal8Bit(panoScriptGetMaskComment(d->script, m, c)); } mask.type = PTOType::Mask::MaskType(panoScriptGetMaskType(d->script, m)); for (int pt = 0 ; pt < panoScriptGetMaskPointCount(d->script, m) ; ++pt) { int x = panoScriptGetMaskPointX(d->script, m, pt); int y = panoScriptGetMaskPointY(d->script, m, pt); mask.hull.append(QPoint(x, y)); } } // Variable optimization + for (int v = 0 ; v < panoScriptGetVarsToOptimizeCount(d->script) ; ++v) { int image = panoScriptGetVarsToOptimizeImageId(d->script, v); out->images[image].optimizationParameters.append(PTOType::Optimization()); PTOType::Optimization& o = out->images[image].optimizationParameters.last(); for (int c = 0 ; c < panoScriptGetVarsToOptimizePrevCommentCount(d->script, v) ; ++c) { o.previousComments << QString::fromLocal8Bit(panoScriptGetVarsToOptimizeComment(d->script, v, c)); } o.parameter = PTOType::Optimization::Parameter(panoScriptGetVarsToOptimizeName(d->script, v)); } // Control Points + for (int cp = 0 ; cp < panoScriptGetCtrlPointCount(d->script) ; ++cp) { out->controlPoints.append(PTOType::ControlPoint()); PTOType::ControlPoint& ctrlPoint = out->controlPoints.last(); for (int c = 0 ; c < panoScriptGetCtrlPointPrevCommentCount(d->script, cp) ; ++c) { ctrlPoint.previousComments << QString::fromLocal8Bit(panoScriptGetCtrlPointComment(d->script, cp, c)); } ctrlPoint.image1Id = panoScriptGetCtrlPointImage1(d->script, cp); ctrlPoint.image2Id = panoScriptGetCtrlPointImage2(d->script, cp); ctrlPoint.p1_x = panoScriptGetCtrlPointX1(d->script, cp); ctrlPoint.p1_y = panoScriptGetCtrlPointY1(d->script, cp); ctrlPoint.p2_x = panoScriptGetCtrlPointX2(d->script, cp); ctrlPoint.p2_y = panoScriptGetCtrlPointY2(d->script, cp); } // Ending comments + for (int c = 0 ; c < panoScriptGetEndingCommentCount(d->script) ; ++c) { out->lastComments << QString::fromLocal8Bit(panoScriptGetEndingComment(d->script, c)); } return out; } } // namespace Digikam diff --git a/core/dplugins/generic/tools/panorama/panoparser/ptoparser/tparser.c b/core/dplugins/generic/tools/panorama/panoparser/ptoparser/tparser.c index 4a27f40870..08b4650c92 100644 --- a/core/dplugins/generic/tools/panorama/panoparser/ptoparser/tparser.c +++ b/core/dplugins/generic/tools/panorama/panoparser/ptoparser/tparser.c @@ -1,264 +1,310 @@ /*============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Description : Hugin parser API * * Copyright (C) 2007 by Daniel M German * Copyright (C) 2012 by Benjamin Girault * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * ============================================================ */ #include "tparser.h" // C includes #include #include #include #include #include #include // Local includes #include "tparserprivate.h" #include "tparserdebug.h" #include "panoParser.h" int yyparse(void); #define PANO_PARSER_VERSION "0.10" extern pt_script script; -/* +/** * This function is be called before the parser is used for the first time, and if it wants to be reused. * Remember, the parser is not REENTRANT */ int panoScriptParserReset(void) { if (!panoScriptDataReset()) { return FALSE; } - /* There should not be anything allocated in script */ + /* + * There should not be anything allocated in script + */ panoScriptParserSetDefaults(&script); return TRUE; } void panoScriptParserSetDefaults(pt_script* ptr) { - /* This is where the defaults will be - * At this point. Just clear the data structure. */ + /* + * This is where the defaults will be + * At this point. Just clear the data structure. + */ memset(ptr, 0, sizeof(*ptr)); - /* but some parameters are meaningful when zero */ + /* + * but some parameters are meaningful when zero + */ script.pano.projection = -1; } int panoScriptParse(const char* const filename, pt_script* scriptOut) { - /* First, set the locale to C */ + /* + * First, set the locale to C + */ char* old_locale = setlocale(LC_NUMERIC, NULL); old_locale = strdup(old_locale); setlocale(LC_NUMERIC, "C"); - /* filename: input file */ + /* + * filename: input file + */ DEBUG_1("Starting to parse"); if (!panoScriptParserReset()) { fprintf(stderr, "This parser is not reentrant"); setlocale(LC_NUMERIC, old_locale); free(old_locale); + return FALSE; } if (!panoScriptParserInit(filename)) { - /* panoScriptParserInit should have displayed the error at this point */ + /* + * panoScriptParserInit should have displayed the error at this point + */ setlocale(LC_NUMERIC, old_locale); free(old_locale); + return FALSE; } if (yyparse() == 0) { - /* AT THIS POINT WE HAVE FINISHED PARSING */ + /* + * AT THIS POINT WE HAVE FINISHED PARSING + */ memcpy(scriptOut, &script, sizeof(pt_script)); panoScriptParserClose(); - /* We do not call panoScriptParserDispose here because its allocated values - * are still referenced in scriptOut */ + + /* + * We do not call panoScriptParserDispose here because its allocated values + * are still referenced in scriptOut + */ setlocale(LC_NUMERIC, old_locale); free(old_locale); + return TRUE; } else { DEBUG_1("Error in parsing\n"); } panoScriptFree(&script); panoScriptParserClose(); setlocale(LC_NUMERIC, old_locale); free(old_locale); + return FALSE; } void panoScriptFree(pt_script* ptr) { int i; - /* free all the data structures it uses */ -#define FREE(a) if ((a) != NULL) {free(a); a = NULL;} + /* + * free all the data structures it uses + */ + +#define FREE(a) if ((a) != NULL) { free(a); a = NULL; } - /* ptr->pano */ + /* + * ptr->pano + */ FREE(ptr->pano.outputFormat); - /* ptr->inputImageSpec */ - for (i = 0; i < ptr->iInputImagesCount; i++) + /* + * ptr->inputImageSpec + */ + for (i = 0 ; i < ptr->iInputImagesCount ; i++) { FREE(ptr->inputImageSpec[i].name); } FREE(ptr->inputImageSpec); - /* ptr->varsToOptimize */ - for (i = 0; i < ptr->iVarsToOptimizeCount; i++) + /* + * ptr->varsToOptimize + */ + for (i = 0 ; i < ptr->iVarsToOptimizeCount ; i++) { FREE(ptr->varsToOptimize[i].varName); } FREE(ptr->varsToOptimize); - /* ptr->ctrlPointsSpec */ + /* + * ptr->ctrlPointsSpec + */ FREE(ptr->ctrlPointsSpec); - /* ptr->masks */ - for (i = 0; i < ptr->iMasksCount; i++) + /* + * ptr->masks + */ + for (i = 0 ; i < ptr->iMasksCount ; i++) { FREE(ptr->masks[i]->points); } FREE(ptr->masks); - /* Comments */ - for (i = 0; i < ptr->iPano_prevCommentsCount; i++) + /* + * Comments + */ + for (i = 0 ; i < ptr->iPano_prevCommentsCount ; i++) { free(ptr->pano_prevComments[i]); } FREE(ptr->pano_prevComments); - /* If the parsing fails on the first input line, the comments would not be set yet */ + /* + * If the parsing fails on the first input line, the comments would not be set yet + */ if (ptr->iImage_prevCommentsCount != NULL) { - for (i = 0; i < ptr->iInputImagesCount; i++) + for (i = 0 ; i < ptr->iInputImagesCount ; i++) { int j; - for (j = 0; j < ptr->iImage_prevCommentsCount[i]; j++) + for (j = 0 ; j < ptr->iImage_prevCommentsCount[i] ; j++) { free(ptr->image_prevComments[i][j]); } FREE(ptr->image_prevComments[i]); } } FREE(ptr->iImage_prevCommentsCount); FREE(ptr->image_prevComments); - for (i = 0; i < ptr->iOptimize_prevCommentsCount; i++) + for (i = 0 ; i < ptr->iOptimize_prevCommentsCount ; i++) { free(ptr->optimize_prevComments[i]); } FREE(ptr->optimize_prevComments); - /* If the parsing fails on the first optimize line, the comments would not be set yet */ + /* + * If the parsing fails on the first optimize line, the comments would not be set yet + */ if (ptr->iVarsToOptimize_prevCommentsCount != NULL) { - for (i = 0; i < ptr->iVarsToOptimizeCount; i++) + for (i = 0 ; i < ptr->iVarsToOptimizeCount ; i++) { int j; - for (j = 0; j < ptr->iVarsToOptimize_prevCommentsCount[i]; j++) + for (j = 0 ; j < ptr->iVarsToOptimize_prevCommentsCount[i] ; j++) { free(ptr->varsToOptimize_prevComments[i][j]); } FREE(ptr->varsToOptimize_prevComments[i]); } } FREE(ptr->iVarsToOptimize_prevCommentsCount); FREE(ptr->varsToOptimize_prevComments); - /* If the parsing fails on the first control point line, the comments would not be set yet */ + /* + * If the parsing fails on the first control point line, the comments would not be set yet + */ if (ptr->iCtrlPoints_prevCommentsCount != NULL) { - for (i = 0; i < ptr->iCtrlPointsCount; i++) + for (i = 0 ; i < ptr->iCtrlPointsCount ; i++) { int j; - for (j = 0; j < ptr->iCtrlPoints_prevCommentsCount[i]; j++) + for (j = 0 ; j < ptr->iCtrlPoints_prevCommentsCount[i] ; j++) { free(ptr->ctrlPoints_prevComments[i][j]); } FREE(ptr->ctrlPoints_prevComments[i]); } } FREE(ptr->iCtrlPoints_prevCommentsCount); FREE(ptr->ctrlPoints_prevComments); - /* If the parsing fails on the first mask line, the comments would not be set yet */ + /* + * If the parsing fails on the first mask line, the comments would not be set yet + */ if (ptr->iMasks_prevCommentsCount != NULL) { - for (i = 0; i < ptr->iMasksCount; i++) + for (i = 0 ; i < ptr->iMasksCount ; i++) { int j; - for (j = 0; j < ptr->iMasks_prevCommentsCount[i]; j++) + for (j = 0 ; j < ptr->iMasks_prevCommentsCount[i] ; j++) { free(ptr->masks_prevComments[i][j]); } FREE(ptr->masks_prevComments[i]); } } FREE(ptr->iMasks_prevCommentsCount); FREE(ptr->masks_prevComments); - for (i = 0; i < ptr->iEndingCommentsCount; i++) + for (i = 0 ; i < ptr->iEndingCommentsCount ; i++) { free(ptr->endingComments[i]); } FREE(ptr->endingComments); #undef FREE - /* clear the data structure */ + /* + * clear the data structure + */ panoScriptParserSetDefaults(ptr); } diff --git a/core/dplugins/generic/tools/panorama/panoparser/ptoparser/tparser.h b/core/dplugins/generic/tools/panorama/panoparser/ptoparser/tparser.h index 29359a55ae..54055afb6f 100644 --- a/core/dplugins/generic/tools/panorama/panoparser/ptoparser/tparser.h +++ b/core/dplugins/generic/tools/panorama/panoparser/ptoparser/tparser.h @@ -1,240 +1,240 @@ /*============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Description : Hugin parser API * * Copyright (C) 2007 by Daniel M German * Copyright (C) 2012 by Benjamin Girault * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * ============================================================ */ #ifndef DIGIKAM_T_PARSER_H #define DIGIKAM_T_PARSER_H /** * Maximum size for an input token */ #define PARSER_MAX_LINE 1000 #define PT_TOKEN_MAX_LEN PARSER_MAX_LINE #define PANO_PARSER_MAX_PROJECTION_PARMS 10 #define PANO_PARSER_MAX_MASK_POINTS 20 /** * Data structure where the entire input file will be read */ #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #define PANO_PARSER_COEF_COUNT 7 #define PANO_PARSER_RESP_CURVE_COEF_COUNT 5 #define PANO_PARSER_VIGN_COEF_COUNT 6 #define PANO_TRANSLATION_COEF_COUNT 3 #define PANO_PROJECTION_COEF_COUNT 2 typedef struct { int x; int y; } pt_point; typedef enum { NEGATIVE = 0, POSITIVE = 1, NEGATIVESTACKAWARE = 2, POSITVESTACKAWARE = 3, NEGATIVELENS = 4 } pt_mask_type; typedef struct { int iImage; pt_mask_type type; int iPointsCount; pt_point* points; } pt_script_mask; typedef struct { char* varName; int varIndex; } pt_script_optimize_var; typedef struct { double x; double y; } pt_point_double; typedef struct { int iImage1; int iImage2; pt_point_double p1; pt_point_double p2; int type; } pt_script_ctrl_point; typedef enum { BD_UINT8 = 0, BD_UINT16 = 1, BD_FLOAT = 2 } pt_bitdepthoutput; typedef struct { int width; int height; int cropArea[PANO_PARSER_COEF_COUNT]; /* the rectangle to crop to */ int projection; int projectionParmsCount; double projectionParms[PANO_PARSER_MAX_PROJECTION_PARMS]; double fHorFOV; char* outputFormat; /* n : file format of output */ /** * Hugin parameters */ int dynamicRangeMode; /* R[01] 0 -> LDR; 1 -> HDR */ pt_bitdepthoutput bitDepthOutput; double exposureValue; /* E exposure value of final panorama */ int iImagePhotometricReference; } pt_script_pano; typedef struct { int projection; int width; int height; double fHorFOV; double yaw; double pitch; double roll; double geometryCoef[PANO_PARSER_COEF_COUNT]; /* a, b, c, d, e, g, t */ /** * Exposure related */ double imageEV; /* Exposure value of image Eev */ double whiteBalanceFactorRed; /* Er */ double whiteBalanceFactorBlue; /* Eb */ double photometricCoef[PANO_PARSER_RESP_CURVE_COEF_COUNT]; /* R[abcde] */ int vignettingCorrectionMode; /* Vm */ double vignettingCorrectionCoef[PANO_PARSER_VIGN_COEF_COUNT]; /* V[abcdxy] */ char* vignettingFlatFieldFile; double cameraPosition[PANO_TRANSLATION_COEF_COUNT]; /* TrX and TpX params */ double projectionPlaneRotation[PANO_PROJECTION_COEF_COUNT]; /* TpX params */ char* name; int cropArea[PANO_PARSER_COEF_COUNT]; /* the rectangle to crop to */ int stack; /** * these variables hold pointers to equivalent variables in other images * they are equivalent to the format = where * is variable name, and index is a base-zero pointer to another image * If they are -1 they are unused */ int fHorFOVRef; int yawRef; int pitchRef; int rollRef; int geometryCoefRef[PANO_PARSER_COEF_COUNT]; /* a, b, c, d, e, g, t */ /** * image references for de-referencing (var=index) */ int imageEVRef; /*Exposure value of image */ int whiteBalanceFactorRedRef; /* Er */ int whiteBalanceFactorBlueRef; /* Eb */ int photometricCoefRef[PANO_PARSER_RESP_CURVE_COEF_COUNT]; /* R[abcde] */ int vignettingCorrectionModeRef; /* Vm */ int vignettingCorrectionCoefRef[PANO_PARSER_VIGN_COEF_COUNT]; /* V[abcdxy] */ int stackRef; } pt_script_image; typedef struct { double fGamma; int interpolator; int fastFT; double huberEstimator; double photometricHuberSigma; } pt_script_optimize; typedef struct { int iPano_prevCommentsCount; char** pano_prevComments; pt_script_pano pano; int iInputImagesCount; int* iImage_prevCommentsCount; char*** image_prevComments; pt_script_image* inputImageSpec; int iOptimize_prevCommentsCount; char** optimize_prevComments; pt_script_optimize optimize; int iVarsToOptimizeCount; int* iVarsToOptimize_prevCommentsCount; char*** varsToOptimize_prevComments; pt_script_optimize_var* varsToOptimize; int iCtrlPointsCount; int* iCtrlPoints_prevCommentsCount; char*** ctrlPoints_prevComments; pt_script_ctrl_point* ctrlPointsSpec; int iMasksCount; int* iMasks_prevCommentsCount; char*** masks_prevComments; pt_script_mask** masks; int iEndingCommentsCount; char** endingComments; } pt_script; void panoScriptParserSetDefaults(pt_script* ptr); int panoScriptParse(const char* const filename, pt_script* scriptOut); void panoScriptFree(pt_script* ptr); -#endif // DIGIKAM_T_PARSER_H +#endif /* DIGIKAM_T_PARSER_H */ diff --git a/core/dplugins/generic/tools/panorama/panoparser/ptoparser/tparserdebug.h b/core/dplugins/generic/tools/panorama/panoparser/ptoparser/tparserdebug.h index d1953da8fc..3ae908b6e0 100644 --- a/core/dplugins/generic/tools/panorama/panoparser/ptoparser/tparserdebug.h +++ b/core/dplugins/generic/tools/panorama/panoparser/ptoparser/tparserdebug.h @@ -1,42 +1,42 @@ /*============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Description : Hugin parser debug header * * Copyright (C) 2007 by Daniel M German * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * ============================================================ */ #ifndef DIGIKAM_T_PARSER_DEBUG_H #define DIGIKAM_T_PARSER_DEBUG_H /* #define YYDEBUG 1 */ #ifdef YYDEBUG # define DEBUG_1(a) fprintf(stderr, #a "\n"); # define DEBUG_2(a,b) fprintf(stderr, #a "\n", b); # define DEBUG_3(a,b,c) fprintf(stderr, #a "\n", b, c); # define DEBUG_4(a,b,c,d) fprintf(stderr, #a "\n", b, c, d); #else # define DEBUG_1(a) # define DEBUG_2(a,b) # define DEBUG_3(a,b,c) # define DEBUG_4(a,b,c,d) #endif -#endif // DIGIKAM_T_PARSER_DEBUG_H +#endif /* DIGIKAM_T_PARSER_DEBUG_H */ diff --git a/core/dplugins/generic/tools/panorama/panoparser/ptoparser/tparsergetters.h b/core/dplugins/generic/tools/panorama/panoparser/ptoparser/tparsergetters.h index dd21d23088..e5baa931f9 100644 --- a/core/dplugins/generic/tools/panorama/panoparser/ptoparser/tparsergetters.h +++ b/core/dplugins/generic/tools/panorama/panoparser/ptoparser/tparsergetters.h @@ -1,180 +1,180 @@ /*============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Description : Hugin parser API * * Copyright (C) 2007 by Daniel M German * Copyright (C) 2012 by Benjamin Girault * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * ============================================================ */ #ifndef DIGIKAM_T_PARSER_GETTERS_H #define DIGIKAM_T_PARSER_GETTERS_H #include "tparser.h" /** * NOTE: any function name ending with "Ref" returns -1 if there are no such reference */ int panoScriptGetImagesCount(pt_script* script); int panoScriptGetImagePrevCommentsCount(pt_script* script, int i); char* panoScriptGetImageComment(pt_script* script, int i, int c); /** * 0: Rectilinear, 1: Panoramic, 2: Circular fisheye, 3: FF fisheye, 4: equirectangular */ int panoScriptGetImageProjection(pt_script* script, int i); int panoScriptGetImageWidth(pt_script* script, int i); int panoScriptGetImageHeight(pt_script* script, int i); double panoScriptGetImageHFOV(pt_script* script, int i); int panoScriptGetImageHFOVRef(pt_script* script, int i); double panoScriptGetImageYaw(pt_script* script, int i); double panoScriptGetImagePitch(pt_script* script, int i); double panoScriptGetImageRoll(pt_script* script, int i); double panoScriptGetImageCoefA(pt_script* script, int i); int panoScriptGetImageCoefARef(pt_script* script, int i); double panoScriptGetImageCoefB(pt_script* script, int i); int panoScriptGetImageCoefBRef(pt_script* script, int i); double panoScriptGetImageCoefC(pt_script* script, int i); int panoScriptGetImageCoefCRef(pt_script* script, int i); double panoScriptGetImageCoefD(pt_script* script, int i); int panoScriptGetImageCoefDRef(pt_script* script, int i); double panoScriptGetImageCoefE(pt_script* script, int i); int panoScriptGetImageCoefERef(pt_script* script, int i); double panoScriptGetImageSheerX(pt_script* script, int i); int panoScriptGetImageSheerXRef(pt_script* script, int i); double panoScriptGetImageSheerY(pt_script* script, int i); int panoScriptGetImageSheerYRef(pt_script* script, int i); double panoScriptGetImageExposure(pt_script* script, int i); int panoScriptGetImageExposureRef(pt_script* script, int i); double panoScriptGetImageWBRed(pt_script* script, int i); int panoScriptGetImageWBRedRef(pt_script* script, int i); double panoScriptGetImageWBBlue(pt_script* script, int i); int panoScriptGetImageWBBlueRef(pt_script* script, int i); double panoScriptGetImagePhotometricCoeffA(pt_script* script, int i); int panoScriptGetImagePhotometricCoeffARef(pt_script* script, int i); double panoScriptGetImagePhotometricCoeffB(pt_script* script, int i); int panoScriptGetImagePhotometricCoeffBRef(pt_script* script, int i); double panoScriptGetImagePhotometricCoeffC(pt_script* script, int i); int panoScriptGetImagePhotometricCoeffCRef(pt_script* script, int i); double panoScriptGetImagePhotometricCoeffD(pt_script* script, int i); int panoScriptGetImagePhotometricCoeffDRef(pt_script* script, int i); double panoScriptGetImagePhotometricCoeffE(pt_script* script, int i); int panoScriptGetImagePhotometricCoeffERef(pt_script* script, int i); /** * Bit0: radial, Bit1: flatfield, Bit2: proportional */ int panoScriptGetImageVignettingMode(pt_script* script, int i); int panoScriptGetImageVignettingModeRef(pt_script* script, int i); double panoScriptGetImageVignettingCoeffA(pt_script* script, int i); int panoScriptGetImageVignettingCoeffARef(pt_script* script, int i); double panoScriptGetImageVignettingCoeffB(pt_script* script, int i); int panoScriptGetImageVignettingCoeffBRef(pt_script* script, int i); double panoScriptGetImageVignettingCoeffC(pt_script* script, int i); int panoScriptGetImageVignettingCoeffCRef(pt_script* script, int i); double panoScriptGetImageVignettingCoeffD(pt_script* script, int i); int panoScriptGetImageVignettingCoeffDRef(pt_script* script, int i); double panoScriptGetImageVignettingCoeffX(pt_script* script, int i); int panoScriptGetImageVignettingCoeffXRef(pt_script* script, int i); double panoScriptGetImageVignettingCoeffY(pt_script* script, int i); int panoScriptGetImageVignettingCoeffYRef(pt_script* script, int i); char* panoScriptGetImageVignettingFlatField(pt_script* script, int i); double panoScriptGetImageCameraTranslationX(pt_script* script, int i); double panoScriptGetImageCameraTranslationY(pt_script* script, int i); double panoScriptGetImageCameraTranslationZ(pt_script* script, int i); double panoScriptGetImageProjectionPlaneYaw(pt_script* script, int i); double panoScriptGetImageProjectionPlanePitch(pt_script* script, int i); char* panoScriptGetImageName(pt_script* script, int i); int panoScriptGetImageCropLeft(pt_script* script, int i); int panoScriptGetImageCropRight(pt_script* script, int i); int panoScriptGetImageCropTop(pt_script* script, int i); int panoScriptGetImageCropBottom(pt_script* script, int i); int panoScriptGetImageStack(pt_script* script, int i); int panoScriptGetImageStackRef(pt_script* script, int i); int panoScriptGetPanoPrevCommentsCount(pt_script* script); char* panoScriptGetPanoComment(pt_script* script, int c); int panoScriptGetPanoWidth(pt_script* script); int panoScriptGetPanoHeight(pt_script* script); int panoScriptGetPanoCropLeft(pt_script* script); int panoScriptGetPanoCropRight(pt_script* script); int panoScriptGetPanoCropTop(pt_script* script); int panoScriptGetPanoCropBottom(pt_script* script); int panoScriptGetPanoProjection(pt_script* script); double panoScriptGetPanoProjectionParmsCount(pt_script* script); double panoScriptGetPanoProjectionParm(pt_script* script, int index); double panoScriptGetPanoHFOV(pt_script* script); int panoScriptGetPanoOutputFormat(pt_script* script); /* 0: PNG, 1: TIFF, 2: TIFF_m, 3: TIFF_multilayer, 4: JPEG */ int panoScriptGetPanoOutputCompression(pt_script* script); /* 0: PANO_NONE, 1: LZW, 2: DEFLATE */ int panoScriptGetPanoOutputCropped(pt_script* script); int panoScriptGetPanoOutputSaveCoordinates(pt_script* script); int panoScriptGetPanoOutputQuality(pt_script* script); int panoScriptGetPanoIsHDR(pt_script* script); int panoScriptGetPanoBitDepth(pt_script* script); /* 0: 8bit, 1: 16bits,2: float */ double panoScriptGetPanoExposure(pt_script* script); int panoScriptGetPanoImageReference(pt_script* script); int panoScriptGetOptimizePrevCommentsCount(pt_script* script); char* panoScriptGetOptimizeComment(pt_script* script, int c); double panoScriptGetOptimizeGamma(pt_script* script); /** * 0: poly3, 1: spline16, 2: spline36, 3: sinc256, 4: spline64, 5: bilinear, 6: nearest neighbor, 7: sinc1024 */ int panoScriptGetOptimizeInterpolator(pt_script* script); int panoScriptGetOptimizeSpeedUp(pt_script* script); /* 0: no speedup, 1: medium speedup, 2: maximum speedup */ double panoScriptGetOptimizeHuberSigma(pt_script* script); double panoScriptGetOptimizePhotometricHuberSigma(pt_script* script); int panoScriptGetVarsToOptimizeCount(pt_script* script); int panoScriptGetVarsToOptimizePrevCommentCount(pt_script* script, int v); char* panoScriptGetVarsToOptimizeComment(pt_script* script, int v, int c); int panoScriptGetVarsToOptimizeImageId(pt_script* script, int v); /** * 0-4: Lens A-E, 5: hfov, 6-8: yaw / pitch / roll, 9: exposure, 10-11: WB (red / blue) * 12-15: Vignetting A-D, 16-17: Vignetting X-Y, 18-22: photometric A-E, 23: unknown */ int panoScriptGetVarsToOptimizeName(pt_script* script, int v); int panoScriptGetCtrlPointCount(pt_script* script); int panoScriptGetCtrlPointPrevCommentCount(pt_script* script, int cp); char* panoScriptGetCtrlPointComment(pt_script* script, int cp, int c); int panoScriptGetCtrlPointImage1(pt_script* script, int cp); int panoScriptGetCtrlPointImage2(pt_script* script, int cp); double panoScriptGetCtrlPointX1(pt_script* script, int cp); double panoScriptGetCtrlPointX2(pt_script* script, int cp); double panoScriptGetCtrlPointY1(pt_script* script, int cp); double panoScriptGetCtrlPointY2(pt_script* script, int cp); int panoScriptGetCtrlPointType(pt_script* script, int cp); int panoScriptGetMaskCount(pt_script* script); int panoScriptGetMaskPrevCommentCount(pt_script* script, int m); char* panoScriptGetMaskComment(pt_script* script, int m, int c); int panoScriptGetMaskImage(pt_script* script, int m); int panoScriptGetMaskType(pt_script* script, int m); /* bit0: positive, bit1: stackaware, bit2(only): negativelens */ int panoScriptGetMaskPointCount(pt_script* script, int m); int panoScriptGetMaskPointX(pt_script* script, int m, int p); int panoScriptGetMaskPointY(pt_script* script, int m, int p); int panoScriptGetEndingCommentCount(pt_script* script); char* panoScriptGetEndingComment(pt_script* script, int c); -#endif // DIGIKAM_T_PARSER_GETTERS_H +#endif /* DIGIKAM_T_PARSER_GETTERS_H */ diff --git a/core/dplugins/generic/tools/panorama/panoparser/ptoparser/tparserprivate.h b/core/dplugins/generic/tools/panorama/panoparser/ptoparser/tparserprivate.h index c99f932d20..bee3f029fe 100644 --- a/core/dplugins/generic/tools/panorama/panoparser/ptoparser/tparserprivate.h +++ b/core/dplugins/generic/tools/panorama/panoparser/ptoparser/tparserprivate.h @@ -1,58 +1,58 @@ /*============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Description : Helper functions for the Hugin API * * Copyright (C) 2007 by Daniel M German * Copyright (C) 2012 by Benjamin Girault * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * ============================================================ */ #ifndef DIGIKAM_T_PARSER_PRIVATE_H #define DIGIKAM_T_PARSER_PRIVATE_H // C includes #include #include // Local includes #include "tparser.h" /* void TokenBegin(char *t); */ int panoScriptDataReset(void); int panoScriptParserInit(const char* const filename); void panoScriptParserClose(void); int panoScriptScannerGetNextChar(char* b, int maxBuffer); void panoScriptScannerTokenBegin(char* t); -#ifndef _MSC_VER // krazy:exclude=cpp +#ifndef _MSC_VER /* krazy:exclude=cpp */ void panoScriptParserError(char const* errorstring, ...) __attribute__ ((format (printf, 1, 2))); #else void panoScriptParserError(char const* errorstring, ...); #endif void yyerror(char const* st); void* panoScriptReAlloc(void** ptr, size_t size, int* count); -#endif // DIGIKAM_T_PARSER_PRIVATE_H +#endif /* DIGIKAM_T_PARSER_PRIVATE_H */ diff --git a/core/dplugins/generic/tools/panorama/panoparser/ptotype/ptotype.cpp b/core/dplugins/generic/tools/panorama/panoparser/ptotype/ptotype.cpp index 924f4e95dd..049787af16 100644 --- a/core/dplugins/generic/tools/panorama/panoparser/ptotype/ptotype.cpp +++ b/core/dplugins/generic/tools/panorama/panoparser/ptotype/ptotype.cpp @@ -1,457 +1,529 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2012-02-04 * Description : a tool to create panorama by fusion of several images. * This type is based on pto file format described here: * http://hugin.sourceforge.net/docs/nona/nona.txt, and * on pto files produced by Hugin's tools. * * Copyright (C) 2012-2015 by Benjamin Girault * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "ptotype.h" // C includes #include // Qt includes #include // Local includes #include "digikam_debug.h" namespace Digikam { bool PTOType::createFile(const QString& filepath) { QFile file(filepath); if (!file.open(QFile::WriteOnly | QFile::Truncate)) { qCDebug(DIGIKAM_GENERAL_LOG) << "Cannot open " << filepath << " to write the pto file"; return false; } QTextStream out(&file); out.setRealNumberPrecision(15); // First, the pano line + if (project.previousComments.size() > 0) + { out << project.previousComments.join(QLatin1Char('\n')) << endl; + } out << "p"; out << " f" << project.projection; if (project.size.width() > 0) + { out << " w" << project.size.width(); + } if (project.size.height() > 0) + { out << " h" << project.size.height(); + } if (project.fieldOfView > 0) + { out << " v" << project.fieldOfView; + } out << " k" << project.photometricReferenceId; out << " E" << project.exposure; out << " R" << project.hdr; switch (project.bitDepth) { case Project::UINT16: out << " T\"UINT16\""; break; + case Project::FLOAT: out << " T\"FLOAT\""; break; + default: break; } if (project.crop.height() > 1 && project.crop.width() > 1) { out << " S"; out << project.crop.left(); out << "," << project.crop.right(); out << "," << project.crop.top(); out << "," << project.crop.bottom(); } out << " n\""; switch (project.fileFormat.fileType) { case Project::FileFormat::PNG: + { out << "PNG"; break; + } case Project::FileFormat::JPEG: + { out << "JPEG"; out << " q" << project.fileFormat.quality; break; + } case Project::FileFormat::TIFF: + { out << "TIFF c:" << project.fileFormat.compressionMethod; break; + } case Project::FileFormat::TIFF_m: case Project::FileFormat::TIFF_multilayer: - + { if (project.fileFormat.fileType == Project::FileFormat::TIFF_multilayer) { out << "TIFF_multilayer"; } else { out << "TIFF_m"; } out << " c:"; switch (project.fileFormat.compressionMethod) { case Project::FileFormat::PANO_NONE: out << "PANO_NONE"; break; + case Project::FileFormat::LZW: out << "LZW"; break; + case Project::FileFormat::DEFLATE: out << "DEFLATE"; break; } if (project.fileFormat.savePositions) + { out << " p1"; + } if (project.fileFormat.cropped) + { out << " r:CROP"; + } + break; + } default: + { qCCritical(DIGIKAM_GENERAL_LOG) << "Unknown file format for pto file generation!"; file.close(); + return false; + } } out << "\""; out << project.unmatchedParameters.join(QLatin1Char(' ')) << endl; // Second, the stitcher line + if (stitcher.previousComments.size() > 0) + { out << stitcher.previousComments.join(QLatin1Char('\n')) << endl; + } out << "m"; out << " g" << stitcher.gamma; out << " i" << (int) stitcher.interpolator; if (stitcher.speedUp != Stitcher::SLOW) { out << " f" << 2 - ((int) stitcher.speedUp); } out << " m" << stitcher.huberSigma; out << " p" << stitcher.photometricHuberSigma; out << stitcher.unmatchedParameters.join(QLatin1Char(' ')) << endl; // Third, the images // Note: the order is very important here + for (int id = 0 ; id < images.size() ; ++id) { const Image &image = images[id]; if (image.previousComments.size() > 0) + { out << image.previousComments.join(QLatin1Char('\n')) << endl; + } out << "i"; out << " w" << image.size.width(); out << " h" << image.size.height(); out << " f" << (int) image.lensProjection; if (image.fieldOfView.referenceId >= 0 || image.fieldOfView.value > 0) + { out << " v" << image.fieldOfView; + } out << " Ra" << image.photometricEMoRA; out << " Rb" << image.photometricEMoRB; out << " Rc" << image.photometricEMoRC; out << " Rd" << image.photometricEMoRD; out << " Re" << image.photometricEMoRE; out << " Eev" << image.exposure; out << " Er" << image.whiteBalanceRed; out << " Eb" << image.whiteBalanceBlue; out << " r" << image.roll; out << " p" << image.pitch; out << " y" << image.yaw; out << " TrX" << image.mosaicCameraPositionX; out << " TrY" << image.mosaicCameraPositionY; out << " TrZ" << image.mosaicCameraPositionZ; if (version == V2014) { out << " Tpy" << image.mosaicProjectionPlaneYaw; out << " Tpp" << image.mosaicProjectionPlanePitch; } out << " j" << image.stackNumber; out << " a" << image.lensBarrelCoefficientA; out << " b" << image.lensBarrelCoefficientB; out << " c" << image.lensBarrelCoefficientC; out << " d" << image.lensCenterOffsetX; out << " e" << image.lensCenterOffsetY; out << " g" << image.lensShearX; out << " t" << image.lensShearY; const Image* imageVM = ℑ if (image.vignettingMode.referenceId >= 0) + { imageVM = &images[image.vignettingMode.referenceId]; + } - if (((int) imageVM->vignettingMode.value) & ((int) Image::RADIAL)) + if (((int)imageVM->vignettingMode.value) & ((int)Image::RADIAL)) { out << " Va" << image.vignettingCorrectionI; out << " Vb" << image.vignettingCorrectionJ; out << " Vc" << image.vignettingCorrectionK; out << " Vd" << image.vignettingCorrectionL; } else { out << " Vf" << image.vignettingFlatfieldImageName; } out << " Vx" << image.vignettingOffsetX; out << " Vy" << image.vignettingOffsetY; out << " Vm" << image.vignettingMode; out << image.unmatchedParameters.join(QLatin1Char(' ')); out << " n\"" << image.fileName << "\""; out << endl; } // Fourth, the variable to optimize + for (int id = 0 ; id < images.size() ; ++id) { const Image& image = images[id]; foreach (Optimization optim, image.optimizationParameters) { if (optim.previousComments.size() > 0) + { out << optim.previousComments.join(QLatin1Char('\n')) << endl; + } out << "v "; switch (optim.parameter) { case Optimization::LENSA: out << 'a'; break; + case Optimization::LENSB: out << 'b'; break; + case Optimization::LENSC: out << 'c'; break; + case Optimization::LENSD: out << 'd'; break; + case Optimization::LENSE: out << 'e'; break; + case Optimization::LENSHFOV: out << 'v'; break; + case Optimization::LENSYAW: out << 'y'; break; + case Optimization::LENSPITCH: out << 'p'; break; + case Optimization::LENSROLL: out << 'r'; break; + case Optimization::EXPOSURE: out << "Eev"; break; + case Optimization::WBR: out << "Er"; break; + case Optimization::WBB: out << "Eb"; break; + case Optimization::VA: out << "Va"; break; + case Optimization::VB: out << "Vb"; break; + case Optimization::VC: out << "Vc"; break; + case Optimization::VD: out << "Vd"; break; + case Optimization::VX: out << "Vx"; break; + case Optimization::VY: out << "Vy"; break; + case Optimization::RA: out << "Ra"; break; + case Optimization::RB: out << "Rb"; break; + case Optimization::RC: out << "Rc"; break; + case Optimization::RD: out << "Rd"; break; + case Optimization::RE: out << "Re"; break; + case Optimization::UNKNOWN: qCCritical(DIGIKAM_GENERAL_LOG) << "Unknown optimization parameter!"; file.close(); return false; } out << id << endl; } } out << "v" << endl; // Fifth, the masks + for (int id = 0 ; id < images.size() ; ++id) { const Image& image = images[id]; foreach (Mask mask, image.masks) { if (mask.previousComments.size() > 0) + { out << mask.previousComments.join(QLatin1Char('\n')) << endl; + } out << "k i" << id; out << " t" << (int) mask.type; out << " p\""; for (int pid = 0 ; pid < mask.hull.size() ; ++pid) { out << (pid == 0 ? "" : " "); out << mask.hull[pid].x() << ' ' << mask.hull[pid].y(); } out << "\"" << endl; } } // Sixth, the control points + foreach (ControlPoint cp, controlPoints) { if (cp.previousComments.size() > 0) + { out << cp.previousComments.join(QLatin1Char('\n')) << endl; + } out << "c n" << cp.image1Id; out << " N" << cp.image2Id; out << " x" << cp.p1_x; out << " y" << cp.p1_y; out << " X" << cp.p2_x; out << " Y" << cp.p2_y; out << " t" << cp.type; out << endl; } // Finally the ending comments + out << lastComments.join(QLatin1Char('\n')) << endl; file.close(); + return true; } /* QPair PTOType::standardDeviation(int image1Id, int image2Id) { double mean_x = 0, mean_y = 0; double n = 0; foreach (ControlPoint cp, controlPoints) { if ((cp.image1Id == image1Id && cp.image2Id == image2Id) || (cp.image1Id == image2Id && cp.image2Id == image1Id)) { mean_x += cp.p2_x - cp.p1_x; mean_y += cp.p2_y - cp.p1_y; n++; } } if (n == 0) { return QPair(0, 0); } mean_x /= n; mean_y /= n; double result = 0; foreach (PTOType::ControlPoint cp, controlPoints) { if ((cp.image1Id == image1Id && cp.image2Id == image2Id) || (cp.image1Id == image2Id && cp.image2Id == image1Id)) { double epsilon_x = (cp.p2_x - cp.p1_x) - mean_x; double epsilon_y = (cp.p2_y - cp.p1_y) - mean_y; result += epsilon_x * epsilon_x + epsilon_y * epsilon_y; } } return QPair(result, n); } QPair PTOType::standardDeviation(int imageId) { int n = 0; double result = 0; for (int i = 0; i < images.size(); ++i) { QPair tmp = standardDeviation(imageId, i); result += tmp.first; n += tmp.second; } return QPair(result, n); } QPair PTOType::standardDeviation() { int n = 0; double result = 0; for (int i = 0; i < images.size(); ++i) { QPair tmp = standardDeviation(i); result += tmp.first; n += tmp.second; } return QPair(result, n); } */ } // namespace Digikam diff --git a/core/dplugins/generic/tools/panorama/panoparser/ptotype/ptotype.h b/core/dplugins/generic/tools/panorama/panoparser/ptotype/ptotype.h index 03a47c7522..57ca708f3a 100644 --- a/core/dplugins/generic/tools/panorama/panoparser/ptotype/ptotype.h +++ b/core/dplugins/generic/tools/panorama/panoparser/ptotype/ptotype.h @@ -1,407 +1,407 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2012-02-04 * Description : a tool to create panorama by fusion of several images. * This type is based on pto file format described here: * http://hugin.sourceforge.net/docs/nona/nona.txt, and * on pto files produced by Hugin's tools. * * Copyright (C) 2012-2015 by Benjamin Girault * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #ifndef DIGIKAM_PTO_TYPE_H #define DIGIKAM_PTO_TYPE_H // Qt includes #include #include #include #include #include #include #include #include namespace Digikam { struct PTOType { struct Project { struct FileFormat { typedef enum { PNG, TIFF, TIFF_m, TIFF_multilayer, JPEG } FileType; typedef enum { PANO_NONE, LZW, DEFLATE } CompressionMethod; FileType fileType; - unsigned char quality; // JPEG - CompressionMethod compressionMethod; // TIFF - bool cropped; // TIFF - bool savePositions; // TIFF + unsigned char quality; ///< for JPEG + CompressionMethod compressionMethod; ///< for TIFF + bool cropped; ///< for TIFF + bool savePositions; ///< for TIFF FileFormat() : fileType(JPEG), quality(90), compressionMethod(LZW), cropped(false), savePositions(false) { } }; typedef enum { RECTILINEAR = 0, CYLINDRICAL = 1, EQUIRECTANGULAR = 2, FULLFRAMEFISHEYE = 3 } ProjectionType; typedef enum { UINT8, UINT16, FLOAT } BitDepth; QStringList previousComments; QSize size; QRect crop; ProjectionType projection; double fieldOfView; FileFormat fileFormat; double exposure; bool hdr; BitDepth bitDepth; int photometricReferenceId; QStringList unmatchedParameters; Project() : size(0, 0), crop(0, 0, 0, 0), projection(RECTILINEAR), fieldOfView(0), exposure(0), hdr(false), bitDepth(UINT8), photometricReferenceId(0) { } }; // -------------------------------------------------------------------------------------- struct Stitcher { typedef enum { POLY3 = 0, SPLINE16 = 1, SPLINE36 = 2, SINC256 = 3, SPLINE64 = 4, BILINEAR = 5, NEARESTNEIGHBOR = 6, SINC1024 = 7 } Interpolator; typedef enum { SLOW, MEDIUM = 1, FAST = 2 } SpeedUp; QStringList previousComments; double gamma; Interpolator interpolator; SpeedUp speedUp; double huberSigma; double photometricHuberSigma; QStringList unmatchedParameters; Stitcher() : gamma(1), interpolator(POLY3), speedUp(FAST), huberSigma(0), photometricHuberSigma(0) { } }; // -------------------------------------------------------------------------------------- struct Mask { typedef enum { NEGATIVE = 0, POSTIVE = 1, NEGATIVESTACK = 2, POSITIVESTACK = 3, NEGATIVELENS = 4 } MaskType; QStringList previousComments; MaskType type; QList hull; }; // -------------------------------------------------------------------------------------- struct Optimization { typedef enum { LENSA, LENSB, LENSC, LENSD, LENSE, LENSHFOV, LENSYAW, LENSPITCH, LENSROLL, EXPOSURE, WBR, WBB, VA, VB, VC, VD, VX, VY, RA, RB, RC, RD, RE, UNKNOWN } Parameter; QStringList previousComments; Parameter parameter; }; // -------------------------------------------------------------------------------------- struct Image { template struct LensParameter { LensParameter() : value(T()), referenceId(-1) { } explicit LensParameter(const T& v) : value(v), referenceId(-1) { } T value; int referenceId; friend QTextStream& operator<<(QTextStream& qts, const LensParameter& p) { if (p.referenceId == -1) { qts << p.value; } else { qts << "=" << p.referenceId; } return qts; } }; typedef enum { RECTILINEAR = 0, PANORAMIC = 1, CIRCULARFISHEYE = 2, FULLFRAMEFISHEYE = 3, EQUIRECTANGULAR = 4 } LensProjection; typedef enum { PANO_NONE = 0, RADIAL = 1, FLATFIELD = 2, PROPORTIONNALRADIAL = 5, PROPORTIONNALFLATFIELD = 6 } VignettingMode; QStringList previousComments; QSize size; int id; QList masks; QList optimizationParameters; LensProjection lensProjection; LensParameter fieldOfView; double yaw; double pitch; double roll; LensParameter lensBarrelCoefficientA; LensParameter lensBarrelCoefficientB; LensParameter lensBarrelCoefficientC; LensParameter lensCenterOffsetX; LensParameter lensCenterOffsetY; LensParameter lensShearX; LensParameter lensShearY; LensParameter exposure; LensParameter whiteBalanceRed; LensParameter whiteBalanceBlue; LensParameter vignettingMode; - LensParameter vignettingCorrectionI; // Va - LensParameter vignettingCorrectionJ; // Vb - LensParameter vignettingCorrectionK; // Vc - LensParameter vignettingCorrectionL; // Vd + LensParameter vignettingCorrectionI; ///< Va + LensParameter vignettingCorrectionJ; ///< Vb + LensParameter vignettingCorrectionK; ///< Vc + LensParameter vignettingCorrectionL; ///< Vd LensParameter vignettingOffsetX; LensParameter vignettingOffsetY; QString vignettingFlatfieldImageName; LensParameter photometricEMoRA; LensParameter photometricEMoRB; LensParameter photometricEMoRC; LensParameter photometricEMoRD; LensParameter photometricEMoRE; double mosaicCameraPositionX; double mosaicCameraPositionY; double mosaicCameraPositionZ; double mosaicProjectionPlaneYaw; double mosaicProjectionPlanePitch; QRect crop; LensParameter stackNumber; QString fileName; QStringList unmatchedParameters; Image() : size(0, 0), id(0), lensProjection(RECTILINEAR), fieldOfView(0), yaw(0), pitch(0), roll(0), lensBarrelCoefficientA(0), lensBarrelCoefficientB(0), lensBarrelCoefficientC(0), lensCenterOffsetX(0), lensCenterOffsetY(0), lensShearX(0), lensShearY(0), exposure(0), whiteBalanceRed(1), whiteBalanceBlue(1), vignettingMode(PANO_NONE), vignettingCorrectionI(0), vignettingCorrectionJ(0), vignettingCorrectionK(0), vignettingCorrectionL(0), vignettingOffsetX(0), vignettingOffsetY(0), photometricEMoRA(0), photometricEMoRB(0), photometricEMoRC(0), photometricEMoRD(0), photometricEMoRE(0), mosaicCameraPositionX(0), mosaicCameraPositionY(0), mosaicCameraPositionZ(0), mosaicProjectionPlaneYaw(0), mosaicProjectionPlanePitch(0), crop(0, 0, 0, 0), stackNumber(0) { } }; // -------------------------------------------------------------------------------------- struct ControlPoint { QStringList previousComments; int image1Id; int image2Id; double p1_x; double p1_y; double p2_x; double p2_y; - int type; // FIXME: change that for an enum if possible + int type; // FIXME: change that for an enum if possible QStringList unmatchedParameters; }; // -------------------------------------------------------------------------------------- enum { PRE_V2014, V2014 } version; PTOType() : version(PRE_V2014) { } explicit PTOType(const QString& version) - : version(version.split(QLatin1Char('.'))[0].toInt() >= 2014 ? V2014 - : PRE_V2014) + : version((version.split(QLatin1Char('.'))[0].toInt() >= 2014) ? V2014 + : PRE_V2014) { } bool createFile(const QString& filepath); /* NOTE: Work in progress QPair standardDeviation(int image1Id, int image2Id); QPair standardDeviation(int imageId); QPair standardDeviation(); */ Project project; Stitcher stitcher; QVector images; QList controlPoints; QStringList lastComments; }; } // namespace Digikam #endif // DIGIKAM_PTO_TYPE_H