Does this actually freaking work? Probably.
This commit is contained in:
parent
d18c319c89
commit
676b4ffa0a
2 changed files with 78 additions and 72 deletions
|
@ -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 */
|
||||
|
|
146
src/photo.c
146
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; y<CAMMY_PHOTO_HEIGHT; y++) {
|
||||
for (x=0; x<CAMMY_PHOTO_WIDTH; x++) {
|
||||
cammy_tile *tile = &src->tiles[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; y<CAMMY_PHOTO_HEIGHT; y++) {
|
||||
for (x=0; x<CAMMY_PHOTO_WIDTH; x++) {
|
||||
cammy_tile *tile = &dest->tiles[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<height; y++) {
|
||||
for (x=0; x<width; x++) {
|
||||
uint8_t r = src[stride*width*y+stride*x],
|
||||
g = src[stride*width*y+stride*x+1],
|
||||
b = src[stride*width*y+stride*x+2];
|
||||
uint8_t r, g, b, gray;
|
||||
|
||||
uint8_t gray = (uint8_t)
|
||||
((0.2126 * (float)r)
|
||||
+ (0.7152 * (float)g)
|
||||
+ (0.0722 * (float)b));
|
||||
buf_read(src, x, y, width, &r, &g, &b, stride);
|
||||
|
||||
uint32_t slot = bayer_matrix[gray];
|
||||
uint32_t from = (slot & 0x03000000) >> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue