saulgoode wrote:
The position of the array size argument in the list of parameters should not cause any difficulty from a PDB standpoint.
I hate to teach Gran to suck eggs, LOL, but FYI:
In gimp-2.8.14/app/plug-in/plug-in-params.c function plug_in_params_to_args()
for (i = 0; i < n_params; i++)
{
:
:
switch (gimp_pdb_compat_arg_type_from_gtype (type))
{
:
:
case GIMP_PDB_INT32ARRAY:
count = g_value_get_int (&args->values[i - 1]); <------THIS IS ASSUMED TO BE THE LENGTH
if (full_copy)
gimp_value_set_int32array (&value,
params[i].data.d_int32array,
count);
else
gimp_value_set_static_int32array (&value,
params[i].data.d_int32array,
count);
break;
Similarly for other *ARRAY parameters.
(The above function is called by various routines in gimpplugin-message.c, to process both the parameters passed to a plugin and the return values from the plugin.)
In other words, an array-type parameter is not simply passed-through to the plugin by pointer (as you were assuming), it is actively copied (along with all simple non-array parameters) into a dynamically-allocated message buffer and it is that buffer which gets sent to the plugin (as an inter-task message); and the procedure which does the copying
implicitly assumes that the parameter
immediately preceding an array is a simple numeric type with value set to the number of elements in the array - if it isn't, mayhem ensues (there is no sanity checking!). If you're lucky, the plugin call will fail benignly; if you're not so lucky you get a segfault.
[This is the problem I hit before when adapting the wavelet-denoise plugin for Dinasset. My first attempt used FLOATARRAYs without preceding length values and it just seg-faulted every time; in that case, the value preceding the first array was in fact a drawable ID which generally had value much greater than the length of the first array (just 2 elements) so the copying would try to access unallocated memory and hence the segfault; I soon came across a doc which explicitly stated that arrays
must be preceded by a length field in an INT32 parameter, corrected my source and had no further problems (but eventually decided arrays were too much trouble for that particular application anyway and ended-up using individual float values!).]
In this case (file-pdf-save-multi), the plugin call
was actually failing
benignly - the parameter before the array was the run-mode, either 0 or 1; if set to 0 (ie. INTERACTIVE), the array was ignored completely, but that didn't matter because the user then selected the images in the interactive GUI; and if set to 1 (ie. NON-INTERACTIVE), the plugin would only take the first image ID in the array and so produce a one-page output file. So no memory violation. The segfault was actually caused by another totally unrelated (but co-existent) bug which just happened to produce the same net result.
And this is, of course, why some plugins have length fields which appear to be entirely superfluous, eg.plug-in-convmatrix where the argc-matrix field should always be set to 25.
By grepping the source directories for Gimp plugins and looking thru the Procedure Browser entries, I find that there are, in fact, relatively few plugins which do actually take ARRAY parameters, and they all use a preceding INT32 length field:
INT8ARRAY:
file-gih-save
gimp-curves-explicit
gimp-curves-spline
gimp-drawable-set-pixel
gimp-image-convert-set-dither-matrix
gimp-image-set-colormap
plug-in-curve-bend
plug-in-metadata-decode-exif
INT32ARRAY:
plug-in-convmatrix
plug-in-film
plug-in-gap-move-path-ext
FLOATARRAY:
gimp-airbrush
gimp-clone
gimp-convolve
gimp-dodgeburn
gimp-eraser
gimp-heal
gimp-image-select-polygon
gimp-paintbrush
gimp-vectors-stroke-new-from-points
plug-in-convmatrix
plug-in-curve-bend
plug-in-gap-move-path-ext
STRINGARRAY:
extension-gimp-help-browser
file-gih-save
plug-in-metadata-set
(There are, of course, many Gimp internal procedures and quite a few plugins which
return arrays, and they do so
always with a preceding INT32 length field.)