From 676b4ffa0acfec2187cad2931fff9156b6802535 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Sun, 15 May 2016 15:16:36 -0500 Subject: [PATCH] Does this actually freaking work? Probably. --- include/cammy/photo.h | 4 +- src/photo.c | 146 ++++++++++++++++++++++-------------------- 2 files changed, 78 insertions(+), 72 deletions(-) diff --git a/include/cammy/photo.h b/include/cammy/photo.h index 89e2aea..d97d98c 100644 --- a/include/cammy/photo.h +++ b/include/cammy/photo.h @@ -40,8 +40,8 @@ void cammy_photo_import(cammy_photo *dest, uint8_t *src, int stride); void cammy_photo_dither(uint8_t *dest, uint8_t *src, - int width, - int height, + size_t width, + size_t height, int stride); #endif /* _CAMMY_PHOTO_H */ diff --git a/src/photo.c b/src/photo.c index 3128e22..7ce5e45 100644 --- a/src/photo.c +++ b/src/photo.c @@ -69,29 +69,79 @@ static uint32_t bayer_matrix[256] = { 0x0203ffff, 0x0203ffff, 0x0203ffff, 0x0203ffff, 0x0203ffff, }; -void cammy_photo_export(cammy_photo *src, uint8_t *dest, int stride) { - static uint8_t values[4] = { - 0, 86, 171, 255 - }; +static uint8_t tile_2bpp_palette[4] = { + 0, 86, 171, 255 +}; +static uint8_t rgb_to_grayscale(uint8_t r, uint8_t g, uint8_t b) { + return (uint8_t)((0.2126 * (float)r) + + (0.7152 * (float)g) + + (0.0722 * (float)b)); +} + +static uint8_t rgb_to_tile_2bpp(uint8_t r, uint8_t g, uint8_t b, size_t x, size_t y) { + uint8_t gray = rgb_to_grayscale(r, g, b); + + uint32_t slot = bayer_matrix[gray]; + uint8_t from = (slot & 0x03000000) >> 24; + uint8_t to = (slot & 0x00030000) >> 16; + + return (slot & (0x8000 >> ((y & 3) << 2) >> (x & 3)))? + to ^ 3: from ^ 3; +} + +static inline uint8_t tile_read(cammy_photo *photo, size_t x, size_t y) { + cammy_tile *tile = &photo->tiles[y>>3][x>>3]; + + int tile_x = x & 7, + tile_y = y & 7; + + return + ((tile->data[ tile_y<<1] & (0x80 >> tile_x)) >> (tile_x ^ 7) + | ((tile->data[(tile_y<<1)|1] & (0x80 >> tile_x)) >> (tile_x ^ 7) << 1)) + ^ 3; +} + +static inline void tile_write(cammy_photo *photo, + size_t x, size_t y, + uint8_t r, uint8_t g, uint8_t b) { + cammy_tile *tile = &photo->tiles[y>>3][x>>3]; + + int tile_x = x & 7, + tile_y = y & 7; + + uint8_t value = rgb_to_tile_2bpp(r, g, b, x, y); + + tile->data[ tile_y<<1] |= (value & 0x01) << (tile_x ^ 7); + tile->data[(tile_y<<1)|1] |= ((value & 0x02) >> 1) << (tile_x ^ 7); +} + +static inline void buf_read(uint8_t *buf, + size_t x, size_t y, size_t width, + uint8_t *r, uint8_t *g, uint8_t *b, + int stride) { + *r = buf[stride*width*y + stride*x], + *g = buf[stride*width*y + stride*x + 1], + *b = buf[stride*width*y + stride*x + 2]; +} + +static inline void buf_write(uint8_t *buf, + size_t x, size_t y, size_t width, + uint8_t r, uint8_t g, uint8_t b, + int stride) { + buf[stride*width*y + stride*x] = r; + buf[stride*width*y + stride*x + 1] = g; + buf[stride*width*y + stride*x + 2] = b; +} + +void cammy_photo_export(cammy_photo *src, uint8_t *dest, int stride) { size_t x, y; for (y=0; ytiles[y>>3][x>>3]; + uint8_t rgb = tile_2bpp_palette[tile_read(src, x, y)]; - int tile_x = x & 7, - tile_y = y & 7; - - uint8_t value = - (tile->data[ tile_y<<1] & (0x80 >> tile_x)) >> (tile_x ^ 7) - | ((tile->data[(tile_y<<1)|1] & (0x80 >> tile_x)) >> (tile_x ^ 7) << 1); - - value ^= 3; - - dest[stride*CAMMY_PHOTO_WIDTH*y+stride*x] = values[value]; - dest[stride*CAMMY_PHOTO_WIDTH*y+stride*x+1] = values[value]; - dest[stride*CAMMY_PHOTO_WIDTH*y+stride*x+2] = values[value]; + buf_write(dest, x, y, CAMMY_PHOTO_WIDTH, rgb, rgb, rgb, stride); } } } @@ -104,75 +154,31 @@ void cammy_photo_import(cammy_photo *dest, uint8_t *src, int stride) { for (y=0; ytiles[y>>3][x>>3]; + uint8_t r, g, b; - int tile_x = x & 7, - tile_y = y & 7; + buf_read(src, x, y, CAMMY_PHOTO_WIDTH, &r, &g, &b, stride); - uint8_t r = src[stride*CAMMY_PHOTO_WIDTH*y+stride*x], - g = src[stride*CAMMY_PHOTO_WIDTH*y+stride*x+1], - b = src[stride*CAMMY_PHOTO_WIDTH*y+stride*x+2]; - - uint8_t gray = (uint8_t) - ((0.2126 * (float)r) - + (0.7152 * (float)g) - + (0.0722 * (float)b)); - - uint32_t slot = bayer_matrix[gray]; - uint32_t from = (slot & 0x03000000) >> 24; - uint32_t to = (slot & 0x00030000) >> 16; - uint8_t value; - - if (slot & (0x8000 >> ((y & 3) << 2) >> (x & 3))) { - value = to ^ 0x03; - } else { - value = from ^ 0x03; - } - - tile->data[ tile_y<<1] |= (value & 0x01) << (tile_x ^ 7); - tile->data[(tile_y<<1)|1] |= ((value & 0x02) >> 1) << (tile_x ^ 7); + tile_write(dest, x, y, r, g, b); } } } void cammy_photo_dither(uint8_t *dest, uint8_t *src, - int width, - int height, + size_t width, + size_t height, int stride) { - static uint8_t values[4] = { - 0, 86, 171, 255 - }; - size_t x, y; for (y=0; y> 24; - uint32_t to = (slot & 0x00030000) >> 16; - uint8_t value; + gray = tile_2bpp_palette[rgb_to_tile_2bpp(r, g, b, x, y)]; - if (slot & (0x8000 >> ((y & 3) << 2) >> (x & 3))) { - value = to ^ 0x03; - } else { - value = from ^ 0x03; - } - - value ^= 3; - - dest[stride*width*y+stride*x] = values[value]; - dest[stride*width*y+stride*x+1] = values[value]; - dest[stride*width*y+stride*x+2] = values[value]; + buf_write(dest, x, y, width, gray, gray, gray, stride); } } }