#!/usr/bin/env python
"""
.. module:: pngfloat
   :synopsis: Support for writing PNG image files.

.. moduleauthor:: <NAME> <<EMAIL>>

"""
import argparse
import os
import sys
import math
import numpy as np
import imageio
from enum import Enum
from pathlib import Path

from filemanager import FileManager

class Format(Enum):
    """ PNG file formats. """
    grayscale = 'grayscale'
    rgba = 'rgba'

    def __str__(self):
        return self.value

class PngWriter:
    """
    Creates PNG files.
    """
    BytesPerSinglePrecisionFloat = 4

    def __init__(self, arguments):
        """
        Performs initialization.
        """
        self.arguments = arguments
        self.source_file = self.arguments.file

    def write_grayscale(self)->None:
        """
        Writes the single precision float source file as a 16-bit grayscale PNG.
        """

        filename = Path(self.source_file)
        png_filename = filename.with_suffix('.png')

        raw_bytes = FileManager().read_binary( self.source_file)
        elements = len(raw_bytes) / PngWriter.BytesPerSinglePrecisionFloat
        dimensions = int(math.sqrt(elements))

        image_array = FileManager().unpack_floats(raw_bytes)
        image_array = np.reshape(image_array, [dimensions, dimensions])

        # convert to 16 bit unsigned integers
        image_array = (65535 * ((image_array - image_array.min()) / image_array.ptp())).astype(np.uint16)

        # invert
        image_array = 65535 - image_array

        image_array = np.flipud(image_array)

        imageio.imwrite(png_filename, image_array)

    def write_rgba(self)->None:
        """
        Writes the RGBA source file as an RGBA PNG.
        """

        filename = Path(self.source_file)
        png_filename = filename.with_suffix('.png')

        file_manager = FileManager()
        raw_bytes = file_manager.read_binary(self.source_file)
        rgba_array = file_manager.unpack_rgba(raw_bytes)

        rgba_array = np.flipud(rgba_array)

        imageio.imwrite(png_filename,  rgba_array)

def main():
    """
    Main entry point.
    """
    os.chdir(os.path.dirname(__file__))

    # command line options
    options_parser = argparse.ArgumentParser()
    options_parser.add_argument('--file', '-f',
                                help='Source file', required=True)

    # Format
    options_parser.add_argument('--format', '-t',
                                help='File format', type=Format, required=True)

    arguments = options_parser.parse_args()

    writer = PngWriter(arguments)
    if arguments.format == Format.rgba:
        writer.write_rgba()
    else:
        writer.write_grayscale()

if __name__ == '__main__':
    main()



#!/usr/bin/env python
"""
.. module:: pngfloat
   :synopsis: Support for writing PNG image files.

.. moduleauthor:: <NAME> <<EMAIL>>

"""
import argparse
import os
import sys
import math
import numpy as np
import imageio
from enum import Enum
from pathlib import Path

from filemanager import FileManager

class Format(Enum):
    """ PNG file formats. """
    grayscale = 'grayscale'
    rgba = 'rgba'

    def __str__(self):
        return self.value

class PngWriter:
    """
    Creates PNG files.
    """
    BytesPerSinglePrecisionFloat = 4

    def __init__(self, arguments):
        """
        Performs initialization.
        """
        self.arguments = arguments
        self.source_file = self.arguments.file

    def write_grayscale(self)->None:
        """
        Writes the single precision float source file as a 16-bit grayscale PNG.
        """

        filename = Path(self.source_file)
        png_filename = filename.with_suffix('.png')

        raw_bytes = FileManager().read_binary( self.source_file)
        elements = len(raw_bytes) / PngWriter.BytesPerSinglePrecisionFloat
        dimensions = int(math.sqrt(elements))

        image_array = FileManager().unpack_floats(raw_bytes)
        image_array = np.reshape(image_array, [dimensions, dimensions])

        # convert to 16 bit unsigned integers
        image_array = (65535 * ((image_array - image_array.min()) / image_array.ptp())).astype(np.uint16)

        # invert
        image_array = 65535 - image_array

        image_array = np.flipud(image_array)

        imageio.imwrite(png_filename, image_array)

    def write_rgba(self)->None:
        """
        Writes the RGBA source file as an RGBA PNG.
        """

        filename = Path(self.source_file)
        png_filename = filename.with_suffix('.png')

        file_manager = FileManager()
        raw_bytes = file_manager.read_binary(self.source_file)
        rgba_array = file_manager.unpack_rgba(raw_bytes)

        rgba_array = np.flipud(rgba_array)

        imageio.imwrite(png_filename,  rgba_array)

def main():
    """
    Main entry point.
    """
    os.chdir(os.path.dirname(__file__))

    # command line options
    options_parser = argparse.ArgumentParser()
    options_parser.add_argument('--file', '-f',
                                help='Source file', required=True)

    # Format
    options_parser.add_argument('--format', '-t',
                                help='File format', type=Format, required=True)

    arguments = options_parser.parse_args()

    writer = PngWriter(arguments)
    if arguments.format == Format.rgba:
        writer.write_rgba()
    else:
        writer.write_grayscale()

if __name__ == '__main__':
    main()



#!/usr/bin/env python .. module:: pngfloat    :synopsis: Support for writing PNG image files.  .. moduleauthor:: <NAME> <<EMAIL>> PNG file formats. Creates PNG files. Performs initialization. Writes the single precision float source file as a 16-bit grayscale PNG. # convert to 16 bit unsigned integers # invert Writes the RGBA source file as an RGBA PNG. Main entry point. # command line options # Format