Author Topic: LinearPatternGenerator errors  (Read 3145 times)

Offline dmcclain

  • PixInsight Addict
  • ***
  • Posts: 117
LinearPatternGenerator errors
« on: 2016 January 23 10:34:22 »
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()

« Last Edit: 2016 January 23 11:47:14 by dmcclain »

Offline dmcclain

  • PixInsight Addict
  • ***
  • Posts: 117
Re: LinearPatternGenerator errors
« Reply #1 on: 2016 January 23 14:00:07 »
After closer inspection of what the code was attempting to do, I suggest the following generalization:

   this.makePattern = function() {

      var width  = parseInt(this.img_w);
      var height = parseInt(this.img_h);
      var img = new Image(width, height, 3);

      // Spliting comma separated values
      var PValues_r_array = this.inputPattern_r.split(",").map(parseFloat);
      var PValues_g_array = this.inputPattern_g.split(",").map(parseFloat);
      var PValues_b_array = this.inputPattern_b.split(",").map(parseFloat);
      var PVr = Math.max(1, PValues_r_array.length);
      var PVg = Math.max(1, PValues_g_array.length);
      var PVb = Math.max(1, PValues_b_array.length);
 
      switch( this.direction ) {
         case "Vertical":
            for(var x = 0; x < width; x++)
            {
               var pr = Math.mod(x, PVr);
               var pg = Math.mod(x, PVg);
               var pb = Math.mod(x, PVb);
               var r = PValues_r_array[pr];
               var g = PValues_g_array[pg];
               var b = PValues_b_array[pb];
               for(var y = 0; y < height; y++) {
                  img.setSample(r, x, y, 0);
                  img.setSample(g, x, y, 1);
                  img.setSample(b, x, y, 2);
               }
            }
         break;
         case "Horizontal":
            for(var y = 0; y < height; y++)
            {
               var pr = Math.mod(y, PVr);
               var pg = Math.mod(y, PVg);
               var pb = Math.mod(y, PVb);
               var r = PValues_r_array[pr];
               var g = PValues_g_array[pg];
               var b = PValues_b_array[pb];
               for (var x = 0; x < width; x++ ) {
                  img.setSample(r, x, y, 0);
                  img.setSample(g, x, y, 1);
                  img.setSample(b, x, y, 2);
               };
            };
         break;
      }; // switch
      // --
      var window = new ImageWindow(width, height, 3, 32, true, true );
      var view   = window.mainView;
      view.beginProcess();
      view.image.apply( img );
      view.endProcess();
      img.free();
      window.bringToFront();

   }; // makeParttern()


Offline dmcclain

  • PixInsight Addict
  • ***
  • Posts: 117
Re: LinearPatternGenerator errors
« Reply #2 on: 2016 January 23 14:57:16 »
Cleaning up the syntax and logic a bit more:

   this.makePattern = function() {

      var width  = parseInt(this.img_w);
      var height = parseInt(this.img_h);
      var img = new Image(width, height, 3);

      // Spliting comma separated values
      var Patterns = [this.inputPattern_r, this.inputPattern_g, this.inputPattern_b];
      var PValues = Patterns.map(function (pat) {
                                    return pat.split(",").map(parseFloat);});
      var PModBase = PValues.map(function (arr) {
                                    return Math.max(1, arr.length); });

      var rgbfn = function(ix) {
         return [0,1,2].map(function (jx) {
                        return PValues[jx][Math.mod(ix, PModBase[jx])]});
                        };

      var setpixel = function(rgb, x, y) {
         [0,1,2].map(function (ix) {
            img.setSample(rgb[ix], x, y, ix);});
      }
     
      switch( this.direction ) {
         case "Vertical":
            for(var x = 0; x < width; x++)
            {
               var rgb = rgbfn(x);
               for(var y = 0; y < height; y++) {
                  setpixel(rgb, x, y);
               }
            }
         break;
         case "Horizontal":
            for(var y = 0; y < height; y++)
            {
               var rgb = rgbfn(y);
               for (var x = 0; x < width; x++ ) {
                  setpixel(rgb, x, y);
               };
            };
         break;
      }; // switch
      // --
      var window = new ImageWindow(width, height, 3, 32, true, true );
      var view   = window.mainView;
      view.beginProcess();
      view.image.apply( img );
      view.endProcess();
      img.free();
      window.bringToFront();

   }; // makeParttern()