summaryrefslogtreecommitdiff
path: root/src/graphics-processor.vala
blob: dc468453bc41bb76dfa9a778ed142a96f35d5910 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
static string? input_file = null;
static string? output_file = null;
static string? pipeline = null;
static bool auto_enhance = false;
static string? format = null;
static int jobs = -1;

const GLib.OptionEntry[] options = {
    { "input", 'i', 0, GLib.OptionArg.FILENAME, ref input_file, "FILE to process", "FILE" },
    { "output", 'o', 0, GLib.OptionArg.FILENAME, ref output_file, "destination FILE", "FILE" },
    { "pipeline", 'p', 0, GLib.OptionArg.FILENAME, ref pipeline, "graphics PIPELINE to run", "PIPELINE" },
    { "auto-enance", 'a', 0, GLib.OptionArg.NONE, ref auto_enhance, "run auto-enhance on input file", null },
    { "format", 'f', 0, GLib.OptionArg.STRING, ref format, "Save output file in specific format [png, jpeg (default)]", null},
    { "jobs", 'j', 0, GLib.OptionArg.INT, ref jobs, "Number of parallel jobs to run on an image", null },
    { null, 0, 0, GLib.OptionArg.NONE, null, null, null }
};

Gee.HashMap<string, KeyValueMap>? marshall_all_transformations(string filename) {
    try {
        var keyfile = new KeyFile();
        if (filename.has_prefix("string:")) {
            var data = "[adjustments]\n" + filename.substring(7).replace("&", "\n");
            keyfile.load_from_data(data, data.length, KeyFileFlags.NONE);
        } else {
            keyfile.load_from_file(filename, KeyFileFlags.NONE);
        }

        var map = new Gee.HashMap<string, KeyValueMap>();

        var objects = keyfile.get_groups();
        foreach (var object in objects) {
            var keys = keyfile.get_keys(object);
            if (keys == null || keys.length == 0) {
                continue;
            }

            var key_map = new KeyValueMap(object);
            foreach (var key in keys) {
                key_map.set_string(key, keyfile.get_string(object, key));
            }
            map.set(object, key_map);
        }

        return map;
    } catch (Error err) {
        error("%s", err.message);
    }
}

int main(string[] args) {
    var ctx = new OptionContext("- Apply shotwell transformations on commandline");
    ctx.set_help_enabled(true);
    ctx.set_ignore_unknown_options(true);
    ctx.add_main_entries(options, null);

    try {
        ctx.parse(ref args);
    } catch (Error error) {
        print(ctx.get_help(true, null));

        return 1;
    }

    if (input_file == null || output_file == null) {
        print("You need to provide and input and output file\n");
        print(ctx.get_help(true, null));

        return 1;
    }

    if (auto_enhance == false && pipeline == null) {
        print("No operation provided. Nothing to do.\n");

        return 0;
    }

    Gdk.Pixbuf? src = null;
    try {
        src = new Gdk.Pixbuf.from_file(input_file);
    } catch (Error err) {
        error ("%s", err.message);
    }

    var output = src.copy();
    PixelTransformationBundle? adjustments = null;

    if (pipeline != null) {
        var transformations = marshall_all_transformations(pipeline);

        adjustments = new PixelTransformationBundle();
        var map = transformations.get("adjustments");
        if (map == null) {
            adjustments.set_to_identity();
        } else {
            adjustments.load(map);
        }
    }

    if (auto_enhance) {
        adjustments = AutoEnhance.create_auto_enhance_adjustments(src);
    }

    var transformer = adjustments.generate_transformer();
    var timer = new Timer();
    transformer.transform_to_other_pixbuf(src, output, null, jobs);
    var elapsed = timer.elapsed();

    print("Transformation took %f\n", elapsed);

    // Trz to guess output format. If it's not PNG, assume JPEG.
    if (format == null) {
        var content_type = ContentType.guess(output_file, null, null);
        if (content_type == "image/png") {
            format = "png";
        }

        format = "jpeg";
    }

    try {
        output.save(output_file, format, null);
    } catch (Error err) {
        error("%s", err.message);
    }

    return 0;
}