Author Topic: PCL: FileFormatInstance.WriteImage(Image) writes integers instead of floats  (Read 1348 times)

Offline georg.viehoever

  • PTeam Member
  • PixInsight Jedi Master
  • ******
  • Posts: 2131
    • View Profile
The following piece of code  writes an integer image instead of a float image (as the code and the documentation would suggest):
Code: [Select]
const ImageVariant* pImage_p; //is float Image, i.e. references image of type pcl::Image
...
const FileFormat fileFormat(File::ExtractExtension(m_sSourceFileName), false, true);
FileFormatInstance fileWriter(fileFormat);
if (!fileWriter.Create(m_sSourceFileName)) {
                    throw Error("Cannot create source file");
                };
if(!fileWriter.WriteImage(static_cast<const Image &>(**pImage_p))){
                    throw Error("Cannot write the image");
                }

Output at console:
Writing FITS image: 16-bit integers, 3 channel(s), 1024x1024 pixels: done

How do I persuade the System to write the native data format (float in this case)?

Georg
« Last Edit: 2015 January 18 10:35:27 by georg.viehoever »
Georg (6 inch Newton, unmodified Canon EOS40D+80D, unguided EQ5 mount)

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 6931
    • View Profile
    • http://pixinsight.com/
See the ImageOptions class, and especially the pcl/ImageOptions.h header in your PCL distribution. You have to pass a modified ImageOptions structure to control the sample format of an output file (among other things). The default format is 16-bit unsigned integer. The basic scheme is as follows:

Code: [Select]
   FileFormat outputFormat;
   Image image;
   String outputFilePath;
   IsoString outputHints;
   ...
   FileFormatInstance outputFile( outputFormat );

   if ( !outputFile.Create( outputFilePath, outputHints ) )
      throw CatchedException();

   ImageOptions options;
   options.bitsPerSample = 32;
   options.ieeefpSampleFormat = true;
   outputFile.SetOptions( options );

   if ( !outputFile.WriteImage( image ) )
      throw CatchedException();

   outputFile.Close();
Juan Conejero
PixInsight Development Team
http://pixinsight.com/

Offline georg.viehoever

  • PTeam Member
  • PixInsight Jedi Master
  • ******
  • Posts: 2131
    • View Profile
Hi Juan,

thanks for pointing me into the right direction. After setting options as follows everything works as it should:

Code: [Select]
const ImageVariant &rImage =*pImage_p;
...
ImageOptions options;
options.bitsPerSample=rImage.BitsPerSample();
options.ieeefpSampleFormat=rImage.IsFloatSample();
options.complexSample=rImage.IsComplexSample();
options.signedIntegers=false;
fileWriter.SetOptions(options);
...

Let me say however that I find this behaviour non-intuitive:

1. What I would expect is that FileInstance.WriteImage() evaluates the available image type information (just as it evaluates width, height, number of channels,...) to write in the format that best preserves the data -unless the user gives specific options. If necessary, a type conversion should be done. What happens now that WriteImage() interprets any Image as uint16, and just writes out the binary data that it finds in the Image (without type conversion).

The current design nicely abstract the specifics of the different writers, but via ImageOptions I get them again into my code, even if I just want to write out my existing data the best way supported by the FileFormat.

2. The documentation says:
Code: [Select]
/*!
 * Writes a 32-bit floating point image to this file. Returns true if the
 * image was successfully written.
 */
bool WriteImage( const FImage& image );
So I would expect to get a result of
Code: [Select]
false if I try to write a float Image as 16bit int, because the Image was not successfully written. Or it should actually do what the documentation says: Write a 32 bit floating point image to a file (which it does not, because it interprets float data as 16 bit integer data).

3. As the very minimum, I would hope to see a warning message.

Consider this as an improvement request in this area.

Georg
Georg (6 inch Newton, unmodified Canon EOS40D+80D, unguided EQ5 mount)