ux-dx 0.2.1

3D Graphics Primitives for Angular Rust
Documentation
use super::{Context, PixelBuffer, PixelFormat};
use bytes::Bytes;
use std::fmt;

// @short_description: Functions for loading images
//
//  allows loading image data into memory as Bitmaps without
// loading them immediately into GPU textures.
#[derive(Debug, Clone)]
pub struct Bitmap {
    format: PixelFormat,
    width: u32,
    height: u32,
    rowstride: u32,

    // uint8_t *data;
    mapped: bool,
    bound: bool,

    // If this is non-None then 'data' is ignored and instead it is
    // fetched from this shared bitmap.
    shared_bmp: Option<Box<Bitmap>>,

    // If this is non-None then 'data' is treated as an offset into the
    // buffer and map will divert to mapping the buffer */
    buffer: Option<Bytes>,
}

impl Bitmap {
    /// Creates a bitmap using some existing data. The data is not copied
    /// so the application must keep the buffer alive for the lifetime of
    /// the `Bitmap`. This can be used for example with
    /// `Framebuffer::read_pixels_into_bitmap` to read data directly
    /// into an application buffer with the specified rowstride.
    /// ## `context`
    /// A `Context`
    /// ## `width`
    /// The width of the bitmap.
    /// ## `height`
    /// The height of the bitmap.
    /// ## `format`
    /// The format of the pixel data.
    /// ## `rowstride`
    /// The rowstride of the bitmap (the number of bytes from
    ///  the start of one row of the bitmap to the next).
    /// ## `data`
    /// A pointer to the data. The bitmap will take ownership of this data.
    ///
    /// # Returns
    ///
    /// A new `Bitmap`.
    pub fn new_for_data(
        width: u32,
        height: u32,
        format: PixelFormat,
        rowstride: u32,
        data: &[u8],
    ) -> Bitmap {
        // Rowstride from width if not given
        let rowstride = match rowstride {
            0 => width * format.bytes_per_pixel(),
            _ => rowstride,
        };

        // TODO: fix with data

        Self {
            format,
            width,
            height,
            rowstride,
            mapped: false,
            bound: false,
            shared_bmp: None,
            buffer: None,
        }
    }

    // bitmap_new_from_buffer:
    // @buffer: A #Buffer containing image data
    // @format: The #PixelFormat defining the format of the image data
    //          in the given @buffer.
    // @width: The width of the image data in the given @buffer.
    // @height: The height of the image data in the given @buffer.
    // @rowstride: The rowstride in bytes of the image data in the given @buffer.
    // @offset: The offset into the given @buffer to the first pixel that
    //          should be considered part of the #Bitmap.
    //
    // Wraps some image data that has been uploaded into a #Buffer as
    // a #Bitmap. The data is not copied in this process.
    //
    // Return value: (transfer full): a #Bitmap encapsulating the given @buffer.
    //
    // Since: 1.8
    // Stability: unstable
    pub fn from_buffer(
        buffer: Bytes,
        format: PixelFormat,
        width: u32,
        height: u32,
        rowstride: u32,
        offset: i32,
    ) -> Bitmap {
        // Bitmap *bmp;

        // _RETURN_VAL_IF_FAIL (is_buffer (buffer), NULL);

        // bmp = bitmap_new_for_data (buffer->context,
        //                                 width, height,
        //                                 format,
        //                                 rowstride,
        //                                 NULL /* data */);

        // bmp->buffer = object_ref (buffer);
        // bmp->data = GINT_TO_POINTER (offset);

        // return bmp;
        unimplemented!()
    }

    // bitmap_new_from_file:
    // @filename: the file to load.
    // @error: a #Error or %NULL.
    //
    // Loads an image file from disk. This fn can be safely called from
    // within a thread.
    //
    // Return value: (transfer full): a #Bitmap to the new loaded
    //               image data, or %NULL if loading the image failed.
    pub fn from_file(filename: &str) -> Bitmap {
        // _GET_CONTEXT (ctx, NULL);

        // _RETURN_VAL_IF_FAIL (filename != NULL, NULL);
        // _RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, NULL);

        // return _bitmap_from_file (ctx, filename, error);
        unimplemented!()
    }

    // bitmap_new_with_size:
    // @context: A #Context
    // @width: width of the bitmap in pixels
    // @height: height of the bitmap in pixels
    // @format: the format of the pixels the array will store
    //
    // Creates a new #Bitmap with the given width, height and format.
    // The initial contents of the bitmap are undefined.
    //
    // The data for the bitmap will be stored in a newly created
    // #PixelBuffer. You can get a pointer to the pixel buffer using
    // bitmap_get_buffer(). The #Buffer API can then be
    // used to fill the bitmap with data.
    //
    //  will try its best to provide a hardware array you can
    // map, write into and effectively do a zero copy upload when creating
    // a texture from it with texture_new_from_bitmap(). For various
    // reasons, such arrays are likely to have a stride larger than width
    // * bytes_per_pixel. The user must take the stride into account when
    // writing into it. The stride can be retrieved with
    // bitmap_get_rowstride().
    //
    // Return value: (transfer full): a #PixelBuffer representing the
    //               newly created array or %NULL on failure
    //
    // Since: 1.10
    // Stability: Unstable
    pub fn with_size(context: &Context, width: u32, height: u32, format: PixelFormat) -> Bitmap {
        // PixelBuffer *pixel_buffer;
        // Bitmap *bitmap;

        // creating a buffer to store "any" format does not make sense
        // _RETURN_VAL_IF_FAIL (format != PIXEL_FORMAT_ANY, NULL);

        // for now we fallback to pixel_buffer_new, later, we could ask
        // libdrm a tiled buffer for instance

        let rowstride = width * format.bytes_per_pixel();

        // pixel_buffer =
        //     pixel_buffer_new (context,
        //                         height * rowstride,
        //                         NULL); /* data */
        // _RETURN_VAL_IF_FAIL (pixel_buffer != NULL, NULL);

        // bitmap = bitmap_new_from_buffer (BUFFER (pixel_buffer),
        //                                         format,
        //                                         width, height,
        //                                         rowstride,
        //                                         0 /* offset */);

        // object_unref (pixel_buffer);

        // return bitmap;
        unimplemented!()
    }

    ///
    /// # Returns
    ///
    /// the `PixelBuffer` that this
    ///  buffer uses for storage. Note that if the bitmap was created with
    ///  `Bitmap::new_from_file` then it will not actually be using a
    ///  pixel buffer and this fn will return `None`.
    pub fn buffer(&self) -> Option<PixelBuffer> {
        // while (bitmap->shared_bmp)
        //     bitmap = bitmap->shared_bmp;

        // return PIXEL_BUFFER (bitmap->buffer);
        unimplemented!()
    }

    ///
    /// # Returns
    ///
    /// the `PixelFormat` that the data for the bitmap is in.
    pub fn format(&self) -> PixelFormat {
        self.format
    }

    ///
    /// # Returns
    ///
    /// the height of the bitmap
    pub fn height(&self) -> u32 {
        self.height
    }

    ///
    /// # Returns
    ///
    /// the rowstride of the bitmap. This is the number of
    ///  bytes between the address of start of one row to the address of the
    ///  next row in the image.
    pub fn rowstride(&self) -> u32 {
        self.rowstride
    }

    ///
    /// # Returns
    ///
    /// the width of the bitmap
    pub fn width(&self) -> u32 {
        self.width
    }

    /// Parses an image file enough to extract the width and height
    /// of the bitmap.
    /// ## `filename`
    /// the file to check
    /// ## `width`
    /// return location for the bitmap width, or `None`
    /// ## `height`
    /// return location for the bitmap height, or `None`
    ///
    /// # Returns
    ///
    /// `true` if the image was successfully parsed
    pub fn size_from_file(filename: &str) -> (bool, u32, u32) {
        use std::fs::File;
        match File::open(filename) {
            Ok(file) => match png::Decoder::new(file).read_info() {
                Ok(reader) => {
                    let info = reader.info();
                    (true, info.width, info.height)
                }
                Err(err) => {
                    println!("{}", err);
                    (false, 0, 0)
                }
            },
            Err(err) => {
                println!("{}", err);
                (false, 0, 0)
            }
        }
    }
}

impl fmt::Display for Bitmap {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Bitmap")
    }
}