Author Topic: [PJSR] [1.8RC3]: Image.assign() behaviour changed  (Read 4568 times)

Offline georg.viehoever

  • PTeam Member
  • PixInsight Jedi Master
  • ******
  • Posts: 2132
[PJSR] [1.8RC3]: Image.assign() behaviour changed
« on: 2013 February 02 05:50:40 »
Hi,

I am working on a fix for http://pixinsight.com/forum/index.php?topic=5176.0. As part of this fix, I have the following problem. image.assign() no longer seems to create a copy of the image. The following code and output shown below suggest that in 1.8RC3 both image and img are change by applying HT to a view. This used to be different  in 1.7.4. Is this a bug or intentional? What would be the correct code that avoids changing image?
Georg
PS: Code available on https://bitbucket.org/georgviehoever/pixinsight/src/4103e9d8c078367c00c7a569c306edbec3bb32b7/src/scripts?at=default

Code: [Select]
      console.writeln(HT.H)
      console.writeln("img.mean()=",img.mean());     
      var wtmp = new ImageWindow( 1, 1, img.numberOfChannels,
         img.bitsPerSample, img.sampleType == SampleType_Real, img.isColor, "tmpSTFWindow" );
      var v = wtmp.mainView;

      v.beginProcess( UndoFlag_NoSwapFile );
      v.image.assign( img );
      v.endProcess();

      HT.executeOn( v, false ); // no swap file
      var image=v.image;
      console.writeln("image.mean()=",image.mean());
      console.writeln("img.mean()=",img.mean());
output with 1.8RC3:
Code: [Select]
0,0.023166023194789886,1,0,1,0,0.023166023194789886,1,0,1,0,0.023166023194789886,1,0,1,0,0.5,1,0,1,0,0.5,1,0,1
img.mean()=0.02786551974227715

HistogramTransformation: Processing view: tmpSTFWindow3
Processing channel #0:
Histogram transformation: done
Processing channel #1:
Histogram transformation: done
Processing channel #2:
Histogram transformation: done
0.285 s
image.mean()=0.3053046362266739
img.mean()=0.3053046362266739

Output with 1.7.4:
Code: [Select]
0,0.023166023194789886,1,0,1,0,0.023166023194789886,1,0,1,0,0.023166023194789886,1,0,1,0,0.5,1,0,1,0,0.5,1,0,1
img.mean()=0.02786551974227715

HistogramTransformation: Processing view: tmpSTFWindow
Processing channel #0: Histogram transformation: 100%
Processing channel #1: Histogram transformation: 100%
Processing channel #2: Histogram transformation: 100%
0.228 s
image.mean()=0.3053046362266739
img.mean()=0.02786551974227715
Georg (6 inch Newton, unmodified Canon EOS40D+80D, unguided EQ5 mount)

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
Re: [PJSR] [1.8RC3]: Image.assign() behaviour changed
« Reply #1 on: 2013 February 06 12:49:46 »
Hi Georg,

This is actually a bug in the JavaScript engine of PI 1.8.0 RC3.

As you know, GenericImage<> in PCL 2.0 is a reference-counted template class with implicit data sharing. In the following code:

GenericImage<P> image1;
// ...
GenericImage<P> image2( image1 );


image2 does not allocate new image data, but just a reference to the image allocated in image1. As soon as a mutable operation is invoked for image2, as for example:

image2.Rescale();

image2 makes a deep copy of its image data, i.e. a uniquely referenced duplicate of the image, before performing the action. In addition, the implicit data sharing mechanism of GenericImage<> is thread-safe (two or more concurrent threads can trigger a deep copy without problems) and non-blocking (thread safety has a marginal performance impact). These features are great for C++ because they allow for more efficient and elegant code: images can be passed by value as function arguments, and can be returned by value from functions, which makes the whole GenericImage<>/ImageVariant branches much more feature-rich and expressive.

However, for JavaScript code this implicit data sharing mechanism is counter-productive. This is because JavaScript already implements its own object referencing system transparently. For example:

var foo = new Image( 100, 100 );
var bar = foo;


In this code, bar is a reference to foo. In other words, bar does not create a new image as a duplicate of the foo image. This is a feature of the JavaScript language. For example, this makes possible the following declaration of a function returning an image:

function CreateWhiteImage( width, height, numChannels )
{
   var image = new Image( width, height, numChannels );
   image.fill( 1.0 );
   return image;
}


So the problem here is that PCL's implicit data sharing is duplicating JavaScript's automatic variable referencing, leading to the confusion and undesirable side-effects that you have seen in your tests. The problem is already fixed in PI 1.8.0 RC4, where Image.assign( image ) creates a uniquely referenced duplicate of the currently selected pixel samples in the image argument, as expected.

While I release RC4 (some days), a workaround can be:

var image1 = new Image( ... );
// ...
var image2 = new Image( image1.width, image1.height, image1.numberOfChannels, image1.colorSpace );
image2.apply( image1 );


that is, make sure that you allocate the pixel data before copying pixel samples.
Juan Conejero
PixInsight Development Team
http://pixinsight.com/