1 module vips.option; 2 3 import std.variant : Variant; 4 5 import vips.bindings; 6 import vips.image; 7 import vips.operation; 8 import vips.conv : toGObject; 9 import gobject.Value; 10 import gobject.ObjectG; 11 12 private struct ParamConfig 13 { 14 string key; 15 bool isOutput; 16 Value value; 17 Variant output; 18 19 this(string key) 20 { 21 this.key = key; 22 } 23 } 24 25 extern(C) 26 { 27 bool g_type_is_a(GType src, GType target); 28 } 29 30 struct VOption 31 { 32 public: 33 ~this() 34 { 35 foreach (config; options) 36 { 37 config.value.unset(); 38 } 39 } 40 41 ref VOption set(string key, VImage value) 42 { 43 auto config = ParamConfig(key); 44 config.value = new Value().init(VImage.getType()); 45 g_value_set_object(config.value.getValueStruct, value.img.toGObject); 46 options[key] = config; 47 return this; 48 } 49 50 ref VOption set(string key, VImage* value) 51 { 52 import gobject.Type : Type; 53 54 auto config = ParamConfig(key); 55 config.value = new Value().init(VImage.getType()); 56 config.isOutput = true; 57 config.output = value; 58 options[key] = config; 59 return this; 60 } 61 62 ref VOption set(string key, VImage[] value) 63 { 64 auto config = ParamConfig(key); 65 config.value = new Value(); 66 config.value.init(vips_array_image_get_type()); 67 vips_value_set_array_image(config.value.getValueStruct(), cast(int)(value.length)); 68 auto array = vips_value_get_array_image(config.value.getValueStruct, null); 69 foreach (i, image; value) 70 { 71 array[i] = image.img; 72 } 73 options[key] = config; 74 return this; 75 } 76 77 ref VOption set(T)(string key, T value) 78 { 79 auto config = ParamConfig(key); 80 config.value = new Value(value); 81 options[key] = config; 82 return this; 83 } 84 85 ref VOption set(string key, VipsBlob* blob) 86 { 87 auto config = ParamConfig(key); 88 config.value = new Value(new ObjectG(cast(GObject*) blob)); 89 options[key] = config; 90 return this; 91 } 92 93 ref VOption set(T : U*, U)(string key, T value) 94 { 95 import std.traits : isScalarType; 96 97 auto config = ParamConfig(key); 98 config.isOutput = true; 99 static if (isScalarType!U) 100 { 101 config.value = new Value(U.init); 102 } 103 else static if (is(U == double[])) 104 { 105 config.value = new Value().init(vips_array_double_get_type()); 106 //TODO need to add corresponding reader method for this 107 } 108 else static if (is(U == VipsBlob*)) 109 { 110 config.value = new Value().init(vips_blob_get_type()); 111 //TODO need to add corresponding reader handler for this 112 } 113 else 114 { 115 static assert(false, "Unknown output value: " ~ U.stringof); 116 } 117 config.output = value; 118 options[key] = config; 119 return this; 120 } 121 122 ref VOption set(string key, double[] vals) 123 { 124 auto config = ParamConfig(key); 125 config.value = new Value(); 126 config.value.init(vips_array_double_get_type()); 127 vips_value_set_array_double(config.value.getValueStruct(), vals.ptr, 128 cast(int) vals.length,); 129 return this; 130 } 131 132 ref VOption set(string key, int[] vals) 133 { 134 auto config = ParamConfig(key); 135 config.value = new Value().init(vips_array_int_get_type()); 136 vips_value_set_array_int(config.value.getValueStruct(), vals.ptr, cast(int) vals.length,); 137 return this; 138 } 139 140 void setInputs(ref VOperation operation) 141 { 142 foreach (option; options) 143 { 144 if (!option.isOutput) 145 { 146 operation.setProperty(option.key, option.value); 147 } 148 } 149 } 150 151 void readOutputs(ref VOperation operation) 152 { 153 import gobject.Type : Type; 154 import vips.bindings : g_value_get_object; 155 foreach (option; options) 156 { 157 if (option.isOutput) 158 { 159 operation.getProperty(option.key, option.value); 160 immutable type = option.value.getValueStruct().gType; 161 if (type == vips_image_get_type()) 162 { 163 auto obj = cast(VipsImage*) 164 g_value_get_object(option.value.getValueStruct); 165 *(option.output.get!(VImage*)) = VImage(obj); 166 } 167 else if (type == GType.INT) 168 { 169 *(option.output.get!(int*)) = option.value.getInt(); 170 } 171 else if (type == GType.BOOLEAN) 172 { 173 *(option.output.get!(bool*)) = option.value.getBoolean(); 174 } 175 else if (type == GType.DOUBLE) 176 { 177 *(option.output.get!(double*)) = option.value.getDouble(); 178 } 179 else 180 { 181 // still need to handle double arrays 182 // and blobs 183 } 184 } 185 } 186 } 187 188 private: 189 ParamConfig[string] options; 190 }