#include #include #include #include "pixmap.h" #include "pixmap_impl.h" struct packed_pixmap { struct pixmap pixmap; unsigned int width; unsigned int height; uint8_t * pixels; }; static unsigned int line_size(unsigned int width) { return width/8 + ((width % 8)==0 ? 0 : 1); } static void packed_pixmap_clear(struct pixmap * p) { struct packed_pixmap * this = (struct packed_pixmap *)p; memset(this->pixels, 0, this->height*line_size(this->width)*sizeof(uint8_t)); } /* Draw a point on the pixmap. */ static void packed_pixmap_set_pixel(struct pixmap * p, unsigned int x, unsigned int y, int v) { struct packed_pixmap * this = (struct packed_pixmap *)p; if (x < this->width && y < this->height) { uint8_t mask = 1; mask <<= x % 8; if (v) this->pixels[line_size(this->width)*y + x/8] |= mask; else this->pixels[line_size(this->width)*y + x/8] &= ~mask; } } static int packed_pixmap_get_pixel(const struct pixmap * p, unsigned int x, unsigned int y) { struct packed_pixmap * this = (struct packed_pixmap *)p; if (x < this->width && y < this->height) { uint8_t mask = 1; mask <<= x % 8; return (this->pixels[line_size(this->width)*y + x/8] & mask); } return 0; } static unsigned int packed_pixmap_get_width(const struct pixmap * p) { struct packed_pixmap * this = (struct packed_pixmap *)p; return this->width; } static unsigned int packed_pixmap_get_height(const struct pixmap * p) { struct packed_pixmap * this = (struct packed_pixmap *)p; return this->height; } static size_t packed_pixmap_get_memory_size(const struct pixmap * p) { struct packed_pixmap * this = (struct packed_pixmap *)p; return this->height * line_size(this->width) * sizeof(uint8_t); } static void packed_pixmap_destroy(struct pixmap * this) { free(this); } struct pixmap * packed_pixmap_new(unsigned int width, unsigned int height, uint8_t * buf) { static const struct pixmap_vtable vtable = { .clear = packed_pixmap_clear, .set_pixel = packed_pixmap_set_pixel, .get_pixel = packed_pixmap_get_pixel, .get_width = packed_pixmap_get_width, .get_height = packed_pixmap_get_height, .get_memory_size = packed_pixmap_get_memory_size, .destroy = packed_pixmap_destroy, }; struct packed_pixmap * this = malloc(sizeof(struct packed_pixmap) + height*line_size(width)*sizeof(uint8_t)); if (this) { this->pixmap.vtable = & vtable; this->width = width; this->height = height; this->pixels = buf; memset(this->pixels, 0, height*line_size(width)*sizeof(uint8_t)); } return &(this->pixmap); }