Flipper/Applications/Official/source-OLDER/grnch/wii_ec_anal/gfx/images.c

138 lines
3.8 KiB
C

#include <gui/gui.h> // GUI (screen/keyboard) API
#include "images.h"
//----------------------------------------------------------------------------- ----------------------------------------
static Canvas* _canvas;
static uint8_t _tlx;
static uint8_t _tly;
static uint8_t _x;
static uint8_t _y;
static const image_t* _img;
static bool _blk;
static Color _set;
static Color _clr;
//+============================================================================
static void _showByteSet(const uint8_t b) {
for(uint8_t m = 0x80; m; m >>= 1) {
if(b & m) // plot only SET bits
canvas_draw_dot(_canvas, (_tlx + _x), (_tly + _y));
if(((++_x) == _img->w) && !(_x = 0) && ((++_y) == _img->h)) break;
}
}
//+============================================================================
static void _showByteClr(const uint8_t b) {
for(uint8_t m = 0x80; m; m >>= 1) {
if(!(b & m)) // plot only CLR bits
canvas_draw_dot(_canvas, (_tlx + _x), (_tly + _y));
if(((++_x) == _img->w) && !(_x = 0) && ((++_y) == _img->h)) break;
}
}
//+============================================================================
static void _showByteAll(const uint8_t b) {
for(uint8_t m = 0x80; m; m >>= 1) {
if((!!(b & m)) ^ _blk) { // Change colour only when required
canvas_set_color(_canvas, ((b & m) ? _set : _clr));
_blk = !_blk;
}
canvas_draw_dot(_canvas, (_tlx + _x), (_tly + _y));
if(((++_x) == _img->w) && !(_x = 0) && ((++_y) == _img->h)) break;
}
}
//+============================================================================
// available modes are SHOW_SET_BLK - plot image pixels that are SET in BLACK
// SHOW_XOR - same as SET_BLACK
// SHOW_SET_WHT - plot image pixels that are SET in WHITE
// SHOW_CLR_BLK - plot image pixels that are CLEAR in BLACK
// SHOW_CLR_WHT - plot image pixels that are CLEAR in WHITE
// SHOW_ALL - plot all images pixels as they are
// SHOW_ALL_INV - plot all images pixels inverted
//
void show(
Canvas* const canvas,
const uint8_t tlx,
const uint8_t tly,
const image_t* img,
const showMode_t mode) {
void (*fnShow)(const uint8_t) = NULL;
const uint8_t* bp = img->data;
// code size optimisation
switch(mode & SHOW_INV_) {
case SHOW_NRM_:
_set = ColorBlack;
_clr = ColorWhite;
break;
case SHOW_INV_:
_set = ColorWhite;
_clr = ColorBlack;
break;
case SHOW_BLK_:
canvas_set_color(canvas, ColorBlack);
break;
case SHOW_WHT_:
canvas_set_color(canvas, ColorWhite);
break;
}
switch(mode & SHOW_INV_) {
case SHOW_NRM_:
case SHOW_INV_:
fnShow = _showByteAll;
canvas_set_color(canvas, ColorWhite);
_blk = 0;
break;
case SHOW_BLK_:
case SHOW_WHT_:
switch(mode & SHOW_ALL_) {
case SHOW_SET_:
fnShow = _showByteSet;
break;
case SHOW_CLR_:
fnShow = _showByteClr;
break;
}
break;
}
furi_check(fnShow);
// I want nested functions!
_canvas = canvas;
_img = img;
_tlx = tlx;
_tly = tly;
_x = 0;
_y = 0;
// Compressed
if(img->c) {
for(unsigned int i = 0; i < img->len; i++, bp++) {
// Compressed data? {tag, length, value}
if(*bp == img->tag) {
for(uint16_t c = 0; c < bp[1]; c++) fnShow(bp[2]);
bp += 3 - 1;
i += 3 - 1;
// Uncompressed byte
} else {
fnShow(*bp);
}
}
// Not compressed
} else {
for(unsigned int i = 0; i < img->len; i++, bp++) fnShow(*bp);
}
}