|
Packit Service |
48484a |
/*
|
|
Packit Service |
48484a |
Test for library image modificator object.
|
|
Packit Service |
48484a |
*/
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
#include <glib.h>
|
|
Packit Service |
48484a |
#include <locale.h>
|
|
Packit Service |
48484a |
#include <getopt.h>
|
|
Packit Service |
48484a |
#include <stdio.h>
|
|
Packit Service |
48484a |
#include <stdlib.h>
|
|
Packit Service |
48484a |
#include <string.h>
|
|
Packit Service |
48484a |
#include <time.h>
|
|
Packit Service |
48484a |
#include <ctype.h>
|
|
Packit Service |
48484a |
#include "lensfun.h"
|
|
Packit Service |
48484a |
#include "image.h"
|
|
Packit Service |
48484a |
#include "auxfun.h"
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
/* Define this to apply stage 1 & 3 corrections in one step,
|
|
Packit Service |
48484a |
see main comment to the lfModifier class */
|
|
Packit Service |
48484a |
#define COMBINE_13
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
#if defined(_MSC_VER)
|
|
Packit Service |
48484a |
#define strcasecmp _stricmp
|
|
Packit Service |
48484a |
#define snprintf _snprintf
|
|
Packit Service |
48484a |
#define strtof (float)strtod
|
|
Packit Service |
48484a |
#endif
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
static struct
|
|
Packit Service |
48484a |
{
|
|
Packit Service |
48484a |
const char *Program;
|
|
Packit Service |
48484a |
const char *Input;
|
|
Packit Service |
48484a |
const char *Output;
|
|
Packit Service |
48484a |
int ModifyFlags;
|
|
Packit Service |
48484a |
bool Inverse;
|
|
Packit Service |
48484a |
const char *Lens;
|
|
Packit Service |
48484a |
const char *Camera;
|
|
Packit Service |
48484a |
float Scale;
|
|
Packit Service |
48484a |
float Crop;
|
|
Packit Service |
48484a |
float Focal;
|
|
Packit Service |
48484a |
float Aperture;
|
|
Packit Service |
48484a |
float Distance;
|
|
Packit Service |
48484a |
Image::InterpolationMethod Interpolation;
|
|
Packit Service |
48484a |
lfLensType TargetGeom;
|
|
Packit Service |
48484a |
bool Verbose;
|
|
Packit Service |
48484a |
} opts =
|
|
Packit Service |
48484a |
{
|
|
Packit Service |
48484a |
NULL,
|
|
Packit Service |
48484a |
NULL,
|
|
Packit Service |
48484a |
"output.png",
|
|
Packit Service |
48484a |
0,
|
|
Packit Service |
48484a |
false,
|
|
Packit Service |
48484a |
NULL,
|
|
Packit Service |
48484a |
NULL,
|
|
Packit Service |
48484a |
1.0f,
|
|
Packit Service |
48484a |
0,
|
|
Packit Service |
48484a |
0,
|
|
Packit Service |
48484a |
0,
|
|
Packit Service |
48484a |
1.0f,
|
|
Packit Service |
48484a |
Image::I_LANCZOS,
|
|
Packit Service |
48484a |
LF_RECTILINEAR,
|
|
Packit Service |
48484a |
false
|
|
Packit Service |
48484a |
};
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
static void DisplayVersion ()
|
|
Packit Service |
48484a |
{
|
|
Packit Service |
48484a |
g_print ("Lenstool reference implementation for Lensfun version %d.%d.%d\n",
|
|
Packit Service |
48484a |
LF_VERSION_MAJOR, LF_VERSION_MINOR, LF_VERSION_MICRO);
|
|
Packit Service |
48484a |
g_print ("Copyright (C) 2007 Andrew Zabolotny\n\n");
|
|
Packit Service |
48484a |
g_print ("For distribution rules and conditions of use see the file\n");
|
|
Packit Service |
48484a |
g_print ("COPYING which is part of the distribution.\n");
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
static void DisplayUsage ()
|
|
Packit Service |
48484a |
{
|
|
Packit Service |
48484a |
DisplayVersion ();
|
|
Packit Service |
48484a |
g_print ("\nCommand-line options:\n\n");
|
|
Packit Service |
48484a |
g_print (" -d --distortion Apply lens distortion\n");
|
|
Packit Service |
48484a |
g_print (" -g# --geometry=# Convert image geometry to given (one of:\n");
|
|
Packit Service |
48484a |
g_print (" rectilinear,fisheye,panoramic,equirectangular,\n");
|
|
Packit Service |
48484a |
g_print (" orthographic, stereographic, equisolid, thoby)\n");
|
|
Packit Service |
48484a |
g_print (" -t --tca Apply lens chromatic aberrations\n");
|
|
Packit Service |
48484a |
g_print (" -v --vignetting Apply lens vignetting\n");
|
|
Packit Service |
48484a |
g_print (" -a --all Apply all possible corrections (tca, vign, dist)\n");
|
|
Packit Service |
48484a |
g_print (" -i --inverse Inverse correction of the image (e.g. simulate\n");
|
|
Packit Service |
48484a |
g_print (" lens distortions instead of correcting them)\n");
|
|
Packit Service |
48484a |
g_print ("\n");
|
|
Packit Service |
48484a |
g_print (" -C# --camera=# Camera name\n");
|
|
Packit Service |
48484a |
g_print (" -c# --crop=# Set camera crop factor in case the camera is not given\n");
|
|
Packit Service |
48484a |
g_print ("\n");
|
|
Packit Service |
48484a |
g_print (" -L# --lens=# Lens name to search for in the database\n");
|
|
Packit Service |
48484a |
g_print (" -F# --focal=# Set focal length at which image has been taken\n");
|
|
Packit Service |
48484a |
g_print (" -A# --aperture=# Set aperture at which image has been taken\n");
|
|
Packit Service |
48484a |
g_print (" -D# --distance=# Set subject distance at which image has been taken\n");
|
|
Packit Service |
48484a |
g_print ("\n");
|
|
Packit Service |
48484a |
g_print (" -s# --scale=# Apply additional scale on the image\n");
|
|
Packit Service |
48484a |
g_print (" -I# --interpol=# Choose interpolation algorithm (n[earest], b[ilinear], l[anczos])\n");
|
|
Packit Service |
48484a |
g_print ("\n");
|
|
Packit Service |
48484a |
g_print (" -o# --output=# Set file name for output image\n");
|
|
Packit Service |
48484a |
g_print (" --verbose Verbose output\n");
|
|
Packit Service |
48484a |
g_print (" --version Display program version and exit\n");
|
|
Packit Service |
48484a |
g_print (" -h --help Display this help text\n");
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
static bool ParseParameters(int argc, char **argv)
|
|
Packit Service |
48484a |
{
|
|
Packit Service |
48484a |
static struct option long_options[] = {
|
|
Packit Service |
48484a |
{"output", required_argument, NULL, 'o'},
|
|
Packit Service |
48484a |
{"distortion", no_argument, NULL, 'd'},
|
|
Packit Service |
48484a |
{"geometry", optional_argument, NULL, 'g'},
|
|
Packit Service |
48484a |
{"tca", no_argument, NULL, 't'},
|
|
Packit Service |
48484a |
{"vignetting", no_argument, NULL, 'v'},
|
|
Packit Service |
48484a |
{"all", no_argument, NULL, 'a'},
|
|
Packit Service |
48484a |
{"inverse", no_argument, NULL, 'i'},
|
|
Packit Service |
48484a |
{"scale", required_argument, NULL, 'S'},
|
|
Packit Service |
48484a |
{"lens", required_argument, NULL, 'L'},
|
|
Packit Service |
48484a |
{"camera", required_argument, NULL, 'C'},
|
|
Packit Service |
48484a |
{"crop", required_argument, NULL, 'c'},
|
|
Packit Service |
48484a |
{"focal", required_argument, NULL, 'F'},
|
|
Packit Service |
48484a |
{"aperture", required_argument, NULL, 'A'},
|
|
Packit Service |
48484a |
{"distance", required_argument, NULL, 'D'},
|
|
Packit Service |
48484a |
{"interpol", required_argument, NULL, 'I'},
|
|
Packit Service |
48484a |
{"help", no_argument, NULL, 'h'},
|
|
Packit Service |
48484a |
{"version", no_argument, NULL, 4},
|
|
Packit Service |
48484a |
{"verbose", no_argument, NULL, 5},
|
|
Packit Service |
48484a |
{0, 0, 0, 0}
|
|
Packit Service |
48484a |
};
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
opts.Program = argv [0];
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
int c;
|
|
Packit Service |
48484a |
while ((c = getopt_long (argc, argv, "o:dg::tvaiS:L:C:c:F:A:D:I:h", long_options, NULL)) != EOF) {
|
|
Packit Service |
48484a |
switch (c) {
|
|
Packit Service |
48484a |
case 'o':
|
|
Packit Service |
48484a |
opts.Output = optarg;
|
|
Packit Service |
48484a |
break;
|
|
Packit Service |
48484a |
case 'd':
|
|
Packit Service |
48484a |
opts.ModifyFlags |= LF_MODIFY_DISTORTION;
|
|
Packit Service |
48484a |
break;
|
|
Packit Service |
48484a |
case 'g':
|
|
Packit Service |
48484a |
opts.ModifyFlags |= LF_MODIFY_GEOMETRY;
|
|
Packit Service |
48484a |
if (optarg) {
|
|
Packit Service |
48484a |
if (!strcasecmp (optarg, "rectilinear"))
|
|
Packit Service |
48484a |
opts.TargetGeom = LF_RECTILINEAR;
|
|
Packit Service |
48484a |
else if (!strcasecmp (optarg, "fisheye"))
|
|
Packit Service |
48484a |
opts.TargetGeom = LF_FISHEYE;
|
|
Packit Service |
48484a |
else if (!strcasecmp (optarg, "panoramic"))
|
|
Packit Service |
48484a |
opts.TargetGeom = LF_PANORAMIC;
|
|
Packit Service |
48484a |
else if (!strcasecmp (optarg, "equirectangular"))
|
|
Packit Service |
48484a |
opts.TargetGeom = LF_EQUIRECTANGULAR;
|
|
Packit Service |
48484a |
else if (!strcasecmp (optarg, "orthographic"))
|
|
Packit Service |
48484a |
opts.TargetGeom = LF_FISHEYE_ORTHOGRAPHIC;
|
|
Packit Service |
48484a |
else if (!strcasecmp (optarg, "stereographic"))
|
|
Packit Service |
48484a |
opts.TargetGeom = LF_FISHEYE_STEREOGRAPHIC;
|
|
Packit Service |
48484a |
else if (!strcasecmp (optarg, "equisolid"))
|
|
Packit Service |
48484a |
opts.TargetGeom = LF_FISHEYE_EQUISOLID;
|
|
Packit Service |
48484a |
else if (!strcasecmp (optarg, "thoby"))
|
|
Packit Service |
48484a |
opts.TargetGeom = LF_FISHEYE_THOBY;
|
|
Packit Service |
48484a |
else {
|
|
Packit Service |
48484a |
DisplayUsage();
|
|
Packit Service |
48484a |
g_print ("\nTarget lens geometry must be one of 'rectilinear', 'fisheye', 'panoramic', 'equirectangular'\n'orthographic', 'stereographic', 'equisolid', 'thoby'\n");
|
|
Packit Service |
48484a |
return false;
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
break;
|
|
Packit Service |
48484a |
case 't':
|
|
Packit Service |
48484a |
opts.ModifyFlags |= LF_MODIFY_TCA;
|
|
Packit Service |
48484a |
break;
|
|
Packit Service |
48484a |
case 'v':
|
|
Packit Service |
48484a |
opts.ModifyFlags |= LF_MODIFY_VIGNETTING;
|
|
Packit Service |
48484a |
break;
|
|
Packit Service |
48484a |
case 'a':
|
|
Packit Service |
48484a |
opts.ModifyFlags |= LF_MODIFY_VIGNETTING;
|
|
Packit Service |
48484a |
opts.ModifyFlags |= LF_MODIFY_TCA;
|
|
Packit Service |
48484a |
opts.ModifyFlags |= LF_MODIFY_DISTORTION;
|
|
Packit Service |
48484a |
break;
|
|
Packit Service |
48484a |
case 'i':
|
|
Packit Service |
48484a |
opts.Inverse = true;
|
|
Packit Service |
48484a |
break;
|
|
Packit Service |
48484a |
case 'S':
|
|
Packit Service |
48484a |
opts.ModifyFlags |= LF_MODIFY_SCALE;
|
|
Packit Service |
48484a |
opts.Scale = _atof (optarg);
|
|
Packit Service |
48484a |
break;
|
|
Packit Service |
48484a |
case'L':
|
|
Packit Service |
48484a |
opts.Lens = optarg;
|
|
Packit Service |
48484a |
break;
|
|
Packit Service |
48484a |
case'C':
|
|
Packit Service |
48484a |
opts.Camera = optarg;
|
|
Packit Service |
48484a |
break;
|
|
Packit Service |
48484a |
case 'c':
|
|
Packit Service |
48484a |
opts.Crop = _atof (optarg);
|
|
Packit Service |
48484a |
break;
|
|
Packit Service |
48484a |
case 'F':
|
|
Packit Service |
48484a |
opts.Focal = _atof (optarg);
|
|
Packit Service |
48484a |
break;
|
|
Packit Service |
48484a |
case 'A':
|
|
Packit Service |
48484a |
opts.Aperture = _atof (optarg);
|
|
Packit Service |
48484a |
break;
|
|
Packit Service |
48484a |
case 'D':
|
|
Packit Service |
48484a |
opts.Distance = _atof (optarg);
|
|
Packit Service |
48484a |
break;
|
|
Packit Service |
48484a |
case 'I':
|
|
Packit Service |
48484a |
if (smartstreq (optarg, "nearest"))
|
|
Packit Service |
48484a |
opts.Interpolation = Image::I_NEAREST;
|
|
Packit Service |
48484a |
else if (smartstreq (optarg, "bilinear"))
|
|
Packit Service |
48484a |
opts.Interpolation = Image::I_BILINEAR;
|
|
Packit Service |
48484a |
else if (smartstreq (optarg, "lanczos"))
|
|
Packit Service |
48484a |
opts.Interpolation = Image::I_LANCZOS;
|
|
Packit Service |
48484a |
else {
|
|
Packit Service |
48484a |
DisplayUsage();
|
|
Packit Service |
48484a |
g_print ("\nUnknown interpolation method `%s'\n", optarg);
|
|
Packit Service |
48484a |
return false;
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
break;
|
|
Packit Service |
48484a |
case 'h':
|
|
Packit Service |
48484a |
DisplayUsage ();
|
|
Packit Service |
48484a |
return false;
|
|
Packit Service |
48484a |
case 4:
|
|
Packit Service |
48484a |
DisplayVersion ();
|
|
Packit Service |
48484a |
return false;
|
|
Packit Service |
48484a |
case 5:
|
|
Packit Service |
48484a |
opts.Verbose = true;
|
|
Packit Service |
48484a |
break;
|
|
Packit Service |
48484a |
default:
|
|
Packit Service |
48484a |
return false;
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
if (optind <= argc)
|
|
Packit Service |
48484a |
opts.Input = argv [optind];
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
if (!opts.Lens && !opts.Camera) {
|
|
Packit Service |
48484a |
DisplayUsage();
|
|
Packit Service |
48484a |
g_print ("\nAt least a lens or camera name is required to perform a database lookup!\n");
|
|
Packit Service |
48484a |
return false;
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
if (!opts.Lens && opts.Input) {
|
|
Packit Service |
48484a |
DisplayUsage();
|
|
Packit Service |
48484a |
g_print ("\nNo lens information (-L) supplied to process specified input image!\n");
|
|
Packit Service |
48484a |
return false;
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
return true;
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
static Image *ApplyModifier (int modflags, bool reverse, Image *img,
|
|
Packit Service |
48484a |
const lfModifier *mod)
|
|
Packit Service |
48484a |
{
|
|
Packit Service |
48484a |
// Create a new image where we will copy the modified image
|
|
Packit Service |
48484a |
Image *newimg = new Image ();
|
|
Packit Service |
48484a |
// Output image always equals input image size, although
|
|
Packit Service |
48484a |
// this is not a requirement of the library, it's just a
|
|
Packit Service |
48484a |
// limitation of the testbed.
|
|
Packit Service |
48484a |
newimg->Resize (img->width, img->height);
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
#ifdef COMBINE_13
|
|
Packit Service |
48484a |
int lwidth = img->width * 2 * 3;
|
|
Packit Service |
48484a |
#else
|
|
Packit Service |
48484a |
int lwidth = img->width * 2;
|
|
Packit Service |
48484a |
if (modflags & LF_MODIFY_TCA)
|
|
Packit Service |
48484a |
lwidth *= 3;
|
|
Packit Service |
48484a |
#endif
|
|
Packit Service |
48484a |
float *pos = new float [lwidth];
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
int step_start = reverse ? 2 : 0;
|
|
Packit Service |
48484a |
int step_delta = reverse ? -1 : +1;
|
|
Packit Service |
48484a |
int step_finish = reverse ? -1 : 3;
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
for (int step = step_start; step != step_finish; step += step_delta)
|
|
Packit Service |
48484a |
{
|
|
Packit Service |
48484a |
RGBpixel *dst = newimg->image;
|
|
Packit Service |
48484a |
char *imgdata = (char *)img->image;
|
|
Packit Service |
48484a |
bool ok = true;
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
img->InitInterpolation (opts.Interpolation);
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
for (unsigned y = 0; ok && y < img->height; y++)
|
|
Packit Service |
48484a |
switch (step)
|
|
Packit Service |
48484a |
{
|
|
Packit Service |
48484a |
#ifdef COMBINE_13
|
|
Packit Service |
48484a |
case 0:
|
|
Packit Service |
48484a |
ok = false;
|
|
Packit Service |
48484a |
break;
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
case 2:
|
|
Packit Service |
48484a |
/* TCA and geometry correction */
|
|
Packit Service |
48484a |
ok = mod->ApplySubpixelGeometryDistortion (0.0, y, img->width, 1, pos);
|
|
Packit Service |
48484a |
#else
|
|
Packit Service |
48484a |
case 0:
|
|
Packit Service |
48484a |
/* TCA correction */
|
|
Packit Service |
48484a |
ok = mod->ApplySubpixelDistortion (0.0, y, img->width, 1, pos);
|
|
Packit Service |
48484a |
#endif
|
|
Packit Service |
48484a |
if (ok)
|
|
Packit Service |
48484a |
{
|
|
Packit Service |
48484a |
float *src = pos;
|
|
Packit Service |
48484a |
for (unsigned x = 0; x < img->width; x++)
|
|
Packit Service |
48484a |
{
|
|
Packit Service |
48484a |
dst->red = img->GetR (src [0], src [1]);
|
|
Packit Service |
48484a |
dst->green = img->GetG (src [2], src [3]);
|
|
Packit Service |
48484a |
dst->blue = img->GetB (src [4], src [5]);
|
|
Packit Service |
48484a |
src += 2 * 3;
|
|
Packit Service |
48484a |
dst++;
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
break;
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
case 1:
|
|
Packit Service |
48484a |
/* Colour correction: vignetting */
|
|
Packit Service |
48484a |
ok = mod->ApplyColorModification (imgdata, 0.0, y, img->width, 1,
|
|
Packit Service |
48484a |
LF_CR_4 (RED, GREEN, BLUE, UNKNOWN), 0);
|
|
Packit Service |
48484a |
imgdata += img->width * 4;
|
|
Packit Service |
48484a |
break;
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
#ifndef COMBINE_13
|
|
Packit Service |
48484a |
case 2:
|
|
Packit Service |
48484a |
/* Distortion and geometry correction, scaling */
|
|
Packit Service |
48484a |
ok = mod->ApplyGeometryDistortion (0.0, y, newimg->width, 1, pos);
|
|
Packit Service |
48484a |
if (ok)
|
|
Packit Service |
48484a |
{
|
|
Packit Service |
48484a |
float *src = pos;
|
|
Packit Service |
48484a |
for (unsigned x = 0; x < img->width; x++)
|
|
Packit Service |
48484a |
{
|
|
Packit Service |
48484a |
img->Get (*dst, src [0], src [1]);
|
|
Packit Service |
48484a |
src += 2;
|
|
Packit Service |
48484a |
dst++;
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
break;
|
|
Packit Service |
48484a |
#endif
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
// After TCA and distortion steps switch img and newimg.
|
|
Packit Service |
48484a |
// This is crucial since newimg is now the input image
|
|
Packit Service |
48484a |
// to the next stage.
|
|
Packit Service |
48484a |
if (ok && (step == 0 || step == 2))
|
|
Packit Service |
48484a |
{
|
|
Packit Service |
48484a |
Image *tmp = newimg;
|
|
Packit Service |
48484a |
newimg = img;
|
|
Packit Service |
48484a |
img = tmp;
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
delete [] pos;
|
|
Packit Service |
48484a |
delete newimg;
|
|
Packit Service |
48484a |
return img;
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
int main (int argc, char **argv)
|
|
Packit Service |
48484a |
{
|
|
Packit Service |
48484a |
setlocale (LC_ALL, "");
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
if (!ParseParameters(argc, argv))
|
|
Packit Service |
48484a |
return -1;
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
// load database
|
|
Packit Service |
48484a |
lfDatabase *ldb = new lfDatabase ();
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
if (ldb->Load () != LF_NO_ERROR) {
|
|
Packit Service |
48484a |
ldb->Destroy();
|
|
Packit Service |
48484a |
g_print ("\rERROR: Database could not be loaded\n");
|
|
Packit Service |
48484a |
return -1;
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
// try to find camera in the database
|
|
Packit Service |
48484a |
const lfCamera *cam = NULL;
|
|
Packit Service |
48484a |
if (opts.Camera) {
|
|
Packit Service |
48484a |
const lfCamera ** cameras = ldb->FindCamerasExt(NULL, opts.Camera);
|
|
Packit Service |
48484a |
if (cameras)
|
|
Packit Service |
48484a |
cam = cameras[0];
|
|
Packit Service |
48484a |
else
|
|
Packit Service |
48484a |
g_print ("Cannot find a camera matching `%s' in database\n", opts.Camera);
|
|
Packit Service |
48484a |
lf_free (cameras);
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
// try to find a matching lens in the database
|
|
Packit Service |
48484a |
const lfLens *lens = NULL;
|
|
Packit Service |
48484a |
if (opts.Lens) {
|
|
Packit Service |
48484a |
const lfLens **lenses = ldb->FindLenses (cam, NULL, opts.Lens);
|
|
Packit Service |
48484a |
if (lenses)
|
|
Packit Service |
48484a |
lens = lenses [0];
|
|
Packit Service |
48484a |
else
|
|
Packit Service |
48484a |
g_print ("Cannot find a lens matching `%s' in database\n", opts.Lens);
|
|
Packit Service |
48484a |
lf_free (lenses);
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
// print camera and lens information if in verbose mode or if no input file is specified
|
|
Packit Service |
48484a |
if (opts.Verbose || !opts.Input) {
|
|
Packit Service |
48484a |
if (cam && lens) {
|
|
Packit Service |
48484a |
g_print("Matching lens and camera combination found in the database:\n");
|
|
Packit Service |
48484a |
PrintCamera(cam, ldb);
|
|
Packit Service |
48484a |
PrintLens(lens, ldb);
|
|
Packit Service |
48484a |
} else if (!cam && lens) {
|
|
Packit Service |
48484a |
g_print("Matching lens found in the database:\n");
|
|
Packit Service |
48484a |
PrintLens(lens, ldb);
|
|
Packit Service |
48484a |
} else if (!lens && cam) {
|
|
Packit Service |
48484a |
g_print("Matching camera found in the database:\n");
|
|
Packit Service |
48484a |
PrintCamera(cam, ldb);
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
} else {
|
|
Packit Service |
48484a |
if (cam && lens) {
|
|
Packit Service |
48484a |
g_print("= Selecting %s / %s\n", cam->Model, lens->Model);
|
|
Packit Service |
48484a |
} else if (!cam && lens) {
|
|
Packit Service |
48484a |
g_print("= Selecting %s\n", lens->Model);
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
// nothing to process, so lets quit here
|
|
Packit Service |
48484a |
if (!opts.Input) {
|
|
Packit Service |
48484a |
ldb->Destroy();
|
|
Packit Service |
48484a |
return 0;
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
// assume standard values if parameters are not specified
|
|
Packit Service |
48484a |
if (cam)
|
|
Packit Service |
48484a |
opts.Crop = cam->CropFactor;
|
|
Packit Service |
48484a |
else if (!opts.Crop)
|
|
Packit Service |
48484a |
opts.Crop = lens->CropFactor;
|
|
Packit Service |
48484a |
if (!opts.Focal)
|
|
Packit Service |
48484a |
opts.Focal = lens->MinFocal;
|
|
Packit Service |
48484a |
if (!opts.Aperture)
|
|
Packit Service |
48484a |
opts.Aperture = lens->MinAperture;
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
if (opts.Verbose) {
|
|
Packit Service |
48484a |
g_print("\nProcessing parameters:\n"
|
|
Packit Service |
48484a |
" |- Image crop factor: %g\n"
|
|
Packit Service |
48484a |
" |- Focal length: %gmm\n"
|
|
Packit Service |
48484a |
" |- Aperture: f/%g\n"
|
|
Packit Service |
48484a |
" |- Distance: %gm\n\n",
|
|
Packit Service |
48484a |
opts.Crop, opts.Focal, opts.Aperture, opts.Distance);
|
|
Packit Service |
48484a |
} else {
|
|
Packit Service |
48484a |
g_print("= Processing parameters: Crop %g, Focal %gmm, Aperture f/%g, Distance: %gm\n",
|
|
Packit Service |
48484a |
opts.Crop, opts.Focal, opts.Aperture, opts.Distance);
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
Image *img = new Image ();
|
|
Packit Service |
48484a |
g_print ("~ Loading `%s' ... ", opts.Input);
|
|
Packit Service |
48484a |
if (!img->Open (opts.Input)) {
|
|
Packit Service |
48484a |
g_print ("\rERROR: failed to open file `%s'\n", opts.Input);
|
|
Packit Service |
48484a |
delete img;
|
|
Packit Service |
48484a |
ldb->Destroy();
|
|
Packit Service |
48484a |
return -1;
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
if (!img->LoadPNG ()) {
|
|
Packit Service |
48484a |
g_print ("\rERROR: failed to parse PNG data from file `%s'\n", opts.Input);
|
|
Packit Service |
48484a |
delete img;
|
|
Packit Service |
48484a |
ldb->Destroy();
|
|
Packit Service |
48484a |
return -1;
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
g_print ("done.\n~ Image size [%ux%u].\n", img->width, img->height);
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
lfModifier *mod = lfModifier::Create (lens, opts.Crop, img->width, img->height);
|
|
Packit Service |
48484a |
if (!mod) {
|
|
Packit Service |
48484a |
g_print ("\rWarning: failed to create modifier\n");
|
|
Packit Service |
48484a |
delete img;
|
|
Packit Service |
48484a |
ldb->Destroy();
|
|
Packit Service |
48484a |
return -1;
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
int modflags = mod->Initialize (
|
|
Packit Service |
48484a |
lens, LF_PF_U8, opts.Focal,
|
|
Packit Service |
48484a |
opts.Aperture, opts.Distance, opts.Scale, opts.TargetGeom,
|
|
Packit Service |
48484a |
opts.ModifyFlags, opts.Inverse);
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
g_print("~ Selected modifications: ");
|
|
Packit Service |
48484a |
if (modflags & LF_MODIFY_TCA)
|
|
Packit Service |
48484a |
g_print ("[tca]");
|
|
Packit Service |
48484a |
if (modflags & LF_MODIFY_VIGNETTING)
|
|
Packit Service |
48484a |
g_print ("[vign]");
|
|
Packit Service |
48484a |
if (modflags & LF_MODIFY_DISTORTION)
|
|
Packit Service |
48484a |
g_print ("[dist]");
|
|
Packit Service |
48484a |
if (modflags & LF_MODIFY_GEOMETRY)
|
|
Packit Service |
48484a |
g_print ("[geom]");
|
|
Packit Service |
48484a |
if (opts.Scale != 1.0)
|
|
Packit Service |
48484a |
g_print ("[scale]");
|
|
Packit Service |
48484a |
if (modflags==0)
|
|
Packit Service |
48484a |
g_print ("[NOTHING]");
|
|
Packit Service |
48484a |
g_print ("\n");
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
g_print("~ Run processing chain... ");
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
clock_t st;
|
|
Packit Service |
48484a |
clock_t xt = clock ();
|
|
Packit Service |
48484a |
while (xt == (st = clock ()))
|
|
Packit Service |
48484a |
;
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
img = ApplyModifier (modflags, opts.Inverse, img, mod);
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
clock_t et = clock ();
|
|
Packit Service |
48484a |
g_print ("done (%.3g secs)\n", double (et - st) / CLOCKS_PER_SEC);
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
mod->Destroy ();
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
g_print ("~ Save output as `%s'...", opts.Output);
|
|
Packit Service |
48484a |
bool ok = img->SavePNG (opts.Output);
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
delete img;
|
|
Packit Service |
48484a |
ldb->Destroy ();
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
if (ok) {
|
|
Packit Service |
48484a |
g_print (" done\n");
|
|
Packit Service |
48484a |
return 0;
|
|
Packit Service |
48484a |
} else {
|
|
Packit Service |
48484a |
g_print (" FAILED\n");
|
|
Packit Service |
48484a |
return -1;
|
|
Packit Service |
48484a |
}
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
}
|