about summary refs log tree commit diff
path: root/include/buchstabensuppe.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/buchstabensuppe.h')
-rw-r--r--include/buchstabensuppe.h250
1 files changed, 246 insertions, 4 deletions
diff --git a/include/buchstabensuppe.h b/include/buchstabensuppe.h
index 461d96f..d1f8a62 100644
--- a/include/buchstabensuppe.h
+++ b/include/buchstabensuppe.h
@@ -4,12 +4,10 @@
 #ifndef BUCHSTABENSUPPE_H
 #define BUCHSTABENSUPPE_H
 
-#include <buchstabensuppe/bitmap.h>
-
 #include <stdbool.h>
 #include <stddef.h>
-
-// buffers
+#include <stdint.h>
+#include <sys/socket.h>  /* sockaddr */
 
 /*!
  * @name UTF-32 Buffer API
@@ -34,6 +32,250 @@ bs_utf32_buffer_t bs_decode_utf8(const char *, size_t);
 //! @}
 
 /*!
+ * @name Grayscale Bitmap API
+ * @{
+ */
+
+/*!
+ * @brief 8-bit bitmap
+ *
+ * bs_bitmap_t wraps a `unsigned char` buffer
+ * representing a bitmap of a certain width
+ * and height. The pixels are written into
+ * the buffer row by row. This means the
+ * index of a pixel is computed like this:
+ * `y * width + x`.
+ */
+typedef struct bs_bitmap {
+  unsigned char *bs_bitmap;         //!< Dynamically allocated bitmap buffer
+
+  int            bs_bitmap_height;  //!< Height of the bitmap
+  int            bs_bitmap_width;   //!< Width of the bitmap
+  // TODO make unsigned
+} bs_bitmap_t;
+
+/*!
+ * @brief Create a new bitmap
+ *
+ * Creates a new bitmap with the given width and height.
+ * The allocated bitmap is then initialized to hold the
+ * value `initial` for every pixel.
+ *
+ * The caller is responsible for freeing the returned bitmap.
+ */
+bs_bitmap_t bs_bitmap_new(int width, int height, unsigned char inital);
+
+/*!
+ * @brief Free a bitmap's buffer
+ *
+ * Frees the buffer allocated for the given bitmap and
+ * updates its dimensions to zero width and height, so
+ * future operations won't crash. Note that this does
+ * _not_ free the bitmap structure itself as it is not
+ * intended to be dynamically allocated.
+ */
+void bs_bitmap_free(bs_bitmap_t *bitmap);
+
+/*!
+ * @brief Increase the size of a bitmap
+ *
+ * Resizes the bitmap to a new size, but will only increase
+ * its size. The newly allocated space is then intialized
+ * with the given value.
+ */
+bool bs_bitmap_extend(bs_bitmap_t *bitmap, int new_width,
+  int new_height, unsigned char initial_value);
+
+/*!
+ * @brief Set a pixel value
+ *
+ * Sets the pixel at the specified location to the given value
+ * or does nothing if the location is out of bounds.
+ */
+void bs_bitmap_set(bs_bitmap_t bitmap, int x, int y, unsigned char value);
+
+/*!
+ * @brief Get a pixel value
+ *
+ * Gets the value at the specified location. If the location
+ * is out of bounds it returns `def` and sets `errno` to `EINVAL`.
+ */
+unsigned char bs_bitmap_get(bs_bitmap_t bitmap, int x, int y, unsigned char def);
+
+/*!
+ * @brief Copy a bitmap into another one
+ *
+ * Copies the source bitmap into the destination one with the
+ * given offset. Any overflow is cut off, offsets may be
+ * negative as well.
+ */
+void bs_bitmap_copy(bs_bitmap_t destination, int offset_x,
+  int offset_y, bs_bitmap_t source);
+
+/*!
+ * @brief Print a representation of a bitmap to stdout
+ *
+ * Uses the unicode block character to render a representation
+ * of the bitmap. If `binary_image` is false, the image is
+ * considered as a grayscale image and all values greater than
+ * 0x80 are rendered as “white” pixels, all below as “black”
+ * pixels. Else 1 is “white”, 0 is “black”.
+ */
+void bs_bitmap_print(bs_bitmap_t bitmap, bool binary_image);
+
+/*!
+ * @brief Map a bitmap
+ *
+ * Calls the provided function on every pixel of the bitmap
+ * and sets it to the returned value.
+ */
+void bs_bitmap_map(bs_bitmap_t bitmap, unsigned char (*fun)(unsigned char));
+
+/*!
+ * @brief Invert a binary pixel
+ *
+ * To be used with bs_bitmap_map().
+ */
+unsigned char bs_pixel_invert_binary(unsigned char);
+
+/*!
+ * @brief Invert a grayscale pixel
+ *
+ * To be used with bs_bitmap_map().
+ */
+unsigned char bs_pixel_invert_grayscale(unsigned char);
+
+/*!
+ * @brief Convert a grayscale pixel to binary
+ *
+ * To be used with bs_bitmap_map().
+ */
+unsigned char bs_pixel_to_binary(unsigned char);
+
+/*!
+ * @brief convert a binary pixel to grayscale
+ *
+ * To be used with bs_bitmap_map().
+ */
+unsigned char bs_pixel_to_grayscale(unsigned char);
+
+//! @}
+
+/*!
+ * @name Bitmap Views
+ * @{
+ */
+
+/*!
+ * @brief Bitmap subset
+ *
+ * A view represents a cropped bitmap in
+ * a cheap manner similar to a string slice.
+ */
+typedef struct bs_bm_view {
+  bs_bitmap_t  bs_view_bitmap;
+  int bs_view_offset_x;
+  int bs_view_offset_y;
+  int bs_view_width;
+  int bs_view_height;
+} bs_view_t;
+
+/*
+ * @brief Compact a binary bitmap
+ *
+ * This converts a binary bitmap into a more compact
+ * representation which every byte stores 8 pixels
+ * instead of just 1. The highest bit represents the
+ * pixel that comes first in the bitmap.
+ *
+ * The resulting format is precisely what the
+ * [Flidpot UDP protocol](https://wiki.openlab-augsburg.de/Flipdots#per-udp-schnittstelle)
+ * requires.
+ *
+ * `view` describes the bitmap to be used and the area
+ * of it. `size` will hold the length of the returned array.
+ *
+ * If the `view` contains areas which are not covered by its
+ * bitmap, these pixels are treated as if they had the value
+ * `def`.
+ *
+ * On error `NULL` is returned and `size` is 0. The allocated
+ * memory must be freed by the caller.
+ */
+uint8_t *bs_view_bitarray(bs_view_t view, size_t *size, unsigned char def);
+
+/*!
+ * @brief Axis description
+ *
+ * Describes which direction to perform a movement in for
+ * bs_scroll_next_view() and bs_page_next_view().
+ */
+enum bs_dimension {
+  BS_DIMENSION_X,    //!< X Axis
+  BS_DIMENSION_Y,    //!< Y Axis
+};
+
+/*!
+ * @brief Calculates next view for a one dimensional scroll through a bitmap.
+ *
+ * Advance a bitmap view by `step` in a given dimension. Will return `true`
+ * as soon as the bitmap is out of view and wrap around, i. e. sets the offset
+ * to `-len`. This is intended to provide the view for the next frame to be
+ * rendered to a (flipdot) display.
+ *
+ * The given view is expected to be fully intialized and `bs_view_width` and
+ * `bs_view_height` to be equal to the dimensions of the target screen. Also
+ * the first view position must be set by the caller.
+ *
+ * @param view bitmap view to alter
+ * @param step step to advance by
+ * @param dim  dimension to advance in
+ *
+ * @return true if the bitmap has come out of view,
+ *         i. e. the scrolling motion is finished
+ */
+bool bs_scroll_next_view(bs_view_t *view, int step, enum bs_dimension dim);
+
+/*!
+ * @brief Calculates next view for one dimensional paging through a bitmap.
+ *
+ * This is similar to bs_scroll_next_view(), but the scroll step is the target
+ * display's width or height and the picture is never scrolled out of view.
+ *
+ * If the edge of the bitmap is in view, true is returned and the offset is
+ * set so the first page is in view.
+ *
+ * @param view bitmap view to alter
+ * @param step step to advance by
+ * @param dim  dimension to advance in
+ *
+ * @return true if another page would mean the bitmap would come out of view
+ *         i. e. all pages have been viewed
+ */
+bool bs_page_next_view(bs_view_t *view, int direction, enum bs_dimension dim);
+
+/*!
+ * @brief Render a bitmap view onto a flipdot display
+ *
+ * This function renders a view to a flipdot display compatible bitarray
+ * using bs_view_bitmap() and sends it to a display listening at the given
+ * address using a given socket.
+ *
+ * The viewed bitmap must be a binary bitmap for this to work properly.
+ * Zero is black, all values greater than zero are white.
+ *
+ * @param sockfd          file descriptor of a `SOCK_DGRAM` socket
+ * @param addr            address of the target flipdot display
+ * @param addrlen         length of the address structure
+ * @param view            bitmap view to render
+ * @param overflow_color  value area outside of the picture should get (either 0 or 1)
+ */
+int bs_flipdot_render(int sockfd, struct sockaddr *addr, socklen_t addrlen,
+  bs_view_t view, unsigned char overflow_color);
+
+//! @}
+
+/*!
  * @name Font Rendering
  * @{
  */