I managed to get past the error where the system claims it doesn't know what a HorizontalSizer is.... the routine runs for a second or so, and then dies a horrible death, ending in a major fault of the entire system and PixInsight goes into the Apple Error Reporting System to report a SegFault.
A snippet of the Apple report shows that just before being killed by the OS, the application was attempting a memmove operation. Something is seriously wrong down in the belly of the beast.
9 libsystem_platform.dylib 0x00007fff948d4080 _platform_memmove$VARIANT$Unknown + 224
I get past the initial complaint about the HorizontalSizer by making sure that I have an image loaded and showing, then I bring up a benign script like CopyCoordinates and cancel out of that leader script. Then on running LinearPatternGenerator, I manage to show a window on screen for several seconds before the entire system dies. No content is ever visible in that new window before it dies.
--- so this kind of behavior indicates that some state is not getting initially established where it should have been... I have also seen state errors when I cancel out of BatchPreprocessing. The entire script must be terminated completely if you cancel a run.
----------
I see from Rick Stevensons ColorMask - another script that manages to run successfully -- that he uses PixelMath to indirectly create a mask image, rather than attempting to modify images directly. Perhaps that gets around all the locking protocol and cache control better than attempting to interact with the lower level PI class system?
----------
The problem appears to be in the protocol for view.beginProcess(...) and view.endProcess(). I commented out all the pattern generating code in between so that nothing happens between beginProcess() and endProcess(), and the system still dies a horrible death.
If I comment out the beginProcess() and endProcess() the system halts the script with an error about the image being read-only, but the PI system remains alive and well.
--------
Looking at another example script, FSDither.js, I see them creating a temporary image to hold direct modifications, then assign a copy of that temp to a freshly created window. I tried doing that and it works. Here is the modified script for LinearPatternGenerator.js. Only the makePattern function was modified. Modifications in italics.
this.makePattern = function() {
//var window = new ImageWindow( parseFloat(this.img_w), parseFloat(this.img_h), 3, 32, true, true );
//var view = window.mainView;
// var img = view.image;
var x, y, p, PV_Long;
var width = this.img_w;
var height = this.img_h;
var img = new Image(parseFloat(width), parseFloat(height), 3);
//window.show();
//window.zoomFactor = Zoom;
// Spliting comma separated values
var PValues_r_array = this.inputPattern_r.split(",");
var PValues_g_array = this.inputPattern_g.split(",");
var PValues_b_array = this.inputPattern_b.split(",");
//
if( DEBUG ) {
console.writeln( "<b>Working Parameters:</b>" );
console.writeln( "R: " + PValues_r_array );
console.writeln( "G: " + PValues_g_array );
console.writeln( "B: " + PValues_b_array );
console.writeln( "Width: " + this.img_w + "px" );
console.writeln( "Height: " + this.img_h + "px" );
console.writeln( "\n" );
};
// Determination of the most populated array
PV_Long = Math.max(PValues_r_array.length, PValues_g_array.length, PValues_b_array.length);
/* -- we can do better than this...
if(PValues_r_array.length == PValues_g_array.length && PValues_r_array.length == PValues_b_array.length && PValues_g_array.length == PValues_b_array.length) {
PV_Long = PValues_r_array.length;
} else {
if(PValues_r_array.length >= PValues_g_array.length && PValues_r_array.length >= PValues_b_array.length) {
PV_Long = PValues_r_array.length;
};
if(PValues_g_array.length >= PValues_r_array.length && PValues_g_array.length >= PValues_b_array.length) {
PV_Long = PValues_g_array.length;
};
if(PValues_b_array.length >= PValues_r_array.length && PValues_b_array.length >= PValues_g_array.length) {
PV_Long = PValues_b_array.length;
};
};
*/
if( DEBUG ) {
console.writeln( "R Elements:" + PValues_r_array.length );
console.writeln( "G Elements:" + PValues_g_array.length );
console.writeln( "B Elements:" + PValues_b_array.length );
console.writeln( "Max: " + PV_Long + " elements" );
console.writeln( "\n" );
};
//
// view.beginProcess( UndoFlag_NoSwapFile ); // do not generate any swap file
// Pattern Making
switch( this.direction ) {
case "Vertical":
// y values
for( y = 0; y < height; y++) {
// X Values
for ( x = 0; x < width; x++ ) {
for( p = 0; p < PV_Long; p++) {
img.setSample( parseFloat( PValues_r_array[p] ), x, y, 0); // R
img.setSample( parseFloat( PValues_g_array[p] ), x, y, 1); // G
img.setSample( parseFloat( PValues_b_array[p] ), x, y, 2); // B
if( p + 1 != PV_Long && x + 1 < width) {
x++;
} else {
break;
};
};
};
};
break;
case "Horizontal":
// x values
for( x = 0; x < width; x++) {
// y Values
for ( y = 0; y < height; y++ ) {
for( p = 0; p < PV_Long; p++) {
img.setSample( parseFloat( PValues_r_array[p] ), x, y, 0); // R
img.setSample( parseFloat( PValues_g_array[p] ), x, y, 1); // G
img.setSample( parseFloat( PValues_b_array[p] ), x, y, 2); // B
if( p + 1 != PV_Long && y + 1 < height) {
y++;
} else {
break;
};
};
};
};
break;
}; // switch
// --
var window = new ImageWindow( parseFloat(this.img_w), parseFloat(this.img_h), 3, 32, true, true );
var view = window.mainView;
view.beginProcess();
view.image.apply( img );
view.endProcess();
img.free();
window.bringToFront();
}; // makeParttern()