Setup buildsystem for c apps

Added fbcp to repo
Added setup-apps.sh
Disable non runtable apps
This commit is contained in:
Andreas Völker
2018-12-30 12:41:38 +01:00
parent 9283caed3b
commit 2f16ff59b8
8 changed files with 186 additions and 18 deletions

11
apps/c-src/CMakeLists.txt Normal file
View File

@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 2.8)
SET(COMPILE_DEFINITIONS -Werror -Wall)
set(CMAKE_C_FLAGS "-O3")
add_executable(fbcp fbcp.c)
target_link_libraries(fbcp m)
add_executable(flicker flicker.c)

136
apps/c-src/fbcp.c Normal file
View File

@ -0,0 +1,136 @@
#include <stdint.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <termios.h>
#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
volatile sig_atomic_t flag = 0;
void Error(const char * format, ...) {
fprintf(stderr, "Error: ");
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
fprintf(stderr, "\n");
}
// fast and only approximate
void DownsampleFrameBufferBGRA2RGB(uint8_t *in, int xin, int yin, uint8_t* out, int xout, int yout){
int sx = xin/xout;
int sy = yin/yout;
int size = sx*sy;
for(int y = 0; y != yout; y++){
for(int x = 0; x != xout; x++){
int xmin = x*xin/xout;
int ymin = y*yin/yout;
int xmax = xmin+sx;
int ymax = ymin+sy;
int r = 0, g = 0, b = 0;
int idx = xmin+ymin*xin;
uint8_t *mem = in+4*idx;
for (int yp = ymin; yp != ymax; yp++ ){
for (int xp =xmin; xp != xmax; xp++ ){
b += *mem++;
g += *mem++;
r += *mem++;
mem++;
}
mem += 4*(xin-sx);
}
*out++ = r/size;
*out++ = g/size;
*out++ = b/size;
}
}
}
void SignalHandler(int sig){
flag = 1;
}
int main(int argc, char **argv) {
//DISPMANX_RESOURCE_HANDLE_T screen_resource;
uint32_t image_prt;
//VC_RECT_T rect1;
int ret;
int fbfd = 0;
char *framebuffer_gbra = 0;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
int serial;
int x = atoi(argv[2]);
int y = atoi(argv[3]);
uint8_t * out_rgb = malloc(x*y*3+1);
signal(SIGINT, SignalHandler);
if (argc < 4){
fprintf(stderr, "Wrong number of parameters, should be:\n\n");
fprintf(stderr, " fbcp <framebuffer> <sizex> <sizey>\n\n");
fprintf(stderr, "i.e. fbcp /dev/fb0\n");
goto exit;
}
fbfd = open(argv[1], O_RDWR);
if (fbfd == -1) {
Error("Unable to open display %s", argv[2]);
goto clean1_1;
}
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
Error("Unable to get display information");
goto clean2;
}
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
Error("Unable to get display information");
goto clean2;
}
fprintf(stderr, "Display is %d x %d %dbps\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
if (vinfo.bits_per_pixel != 32){
Error("Display has %i bits per pixel. This program only works for 32.", vinfo.bits_per_pixel);
}
framebuffer_gbra = (char*) mmap(0, finfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
if (framebuffer_gbra <= 0) {
Error("Unable to create framebuffer memory mapping");
goto clean3;
}
FILE *logfile = fopen("out.log", "w");
int frame = 0;
while(!flag) {
// vc_dispmanx_resource_read_data(screen_resource, &rect1, framebuffer_gbra, vinfo.xres * vinfo.bits_per_pixel / 8);
fflush(logfile);
uint8_t* out = out_rgb;
*out++ = 1; // Begin of frame marker
DownsampleFrameBufferBGRA2RGB(framebuffer_gbra, vinfo.xres, vinfo.yres, out, x, y);
write(1, out_rgb+1, x*y*3);
frame++;
}
clean4:
munmap(framebuffer_gbra, finfo.smem_len);
clean3:
clean2:
close(fbfd);
clean1_1:
clean1:
exit:
return 0;
}

79
apps/c-src/flicker.c Normal file
View File

@ -0,0 +1,79 @@
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
// Here I use a lcg RNG with a specificaly crafted period to enumerate all pixels
// and color them by cycling a colormap in a randomish order
// Same approch as in DOOM (1993)
// see: Knuth - The Art of Computer Programming, Volume 2: Seminumerical Algorithms
uint32_t hash32(uint32_t d) {
// DJB Hash
uint32_t h = 0x811c9dc5;
h = (h * 16777619) ^ ((d >> 0) & 0xff);
h = (h * 16777619) ^ ((d >> 8) & 0xff);
h = (h * 16777619) ^ ((d >> 16) & 0xff);
h = (h * 16777619) ^ ((d >> 24) & 0xff);
return h;
}
// must be the next prime after NUM_TOTAL_LEDS
#define IDLE_PRIME 3203
// must be a primitive element of the prime residue field |N/IDLE_PRIM
#define IDLE_PRIM_ELEM 777
int IDLE_rand(int *seed){
return *seed = (*seed * IDLE_PRIM_ELEM ) % IDLE_PRIME;
}
int IDLE_last_pixel = 34;
int IDLE_color_offset = 2;
uint32_t IDLE_colors[5] ={
0xd31719,
0x0f6851,
0xd4772e,
0xd84b23,
0x3d89a7
};
int Nx, Ny;
uint8_t *buf;
void SetPixel(int x, int y, uint8_t r, uint8_t g, uint8_t b){
buf[3*(x+Nx*y)+0] = r;
buf[3*(x+Nx*y)+1] = g;
buf[3*(x+Nx*y)+2] = b;
}
void IDLE_set_pixel(){
int i = IDLE_rand(&IDLE_last_pixel)-1;
int x = i%Nx;
int y = i/Nx;
if (i == IDLE_color_offset){
IDLE_color_offset++;
if (IDLE_color_offset > 100)
IDLE_color_offset=2;
}
if (i >= Nx*Ny) return;
int color_count = sizeof(IDLE_colors)/sizeof(IDLE_colors[0]);
int color = IDLE_colors[hash32(i+IDLE_color_offset)%color_count];
SetPixel(x, y, (color>>16)&0xff, (color>>8)&0xff, (color>>0)&0xff);
}
int main(int argc, char **argv) {
Nx = atoi(argv[1]);
Ny = atoi(argv[2]);
buf = malloc(Nx*Ny*3);
int sleepms = atoi(argv[3]);
if (sleepms == 0) sleepms = 30;
while(1) {
IDLE_set_pixel();
write(1, buf, Nx*Ny*3);
usleep(1000*sleepms);
}
}