Created
June 18, 2015 17:51
-
-
Save maxux/52291aec6b19ad376aee to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <unistd.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <fcntl.h> | |
#include <sys/ioctl.h> | |
#include <linux/fb.h> | |
#include <sys/mman.h> | |
#include <png.h> | |
typedef struct png_t { | |
png_struct *root; | |
png_info *info; | |
int width; | |
int height; | |
png_byte depth; | |
png_byte **rows; | |
} png_t; | |
void diep(char *str) { | |
perror(str); | |
exit(EXIT_FAILURE); | |
} | |
void dies(char *str) { | |
fprintf(stderr, "%s\n", str); | |
exit(EXIT_FAILURE); | |
} | |
png_t *decode(char *filename) { | |
unsigned char header[8]; | |
png_t *png; | |
FILE *fp; | |
int i; | |
// initializing object | |
if(!(png = (png_t *) malloc(sizeof(png_t)))) | |
diep("[-] malloc"); | |
// preparing file | |
if(!(fp = fopen(filename, "r"))) | |
diep("[-] fopen"); | |
if(fread(header, 1, 8, fp) != 8) | |
diep("[-] fread"); | |
if(png_sig_cmp(header, 0, 8)) | |
dies("[-] not a png file"); | |
// initializing libpng | |
if(!(png->root = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))) | |
dies("[-] png_create_read_struct failed"); | |
if(!(png->info = png_create_info_struct(png->root))) | |
dies("[-] png_create_info_struct failed"); | |
if(setjmp(png_jmpbuf(png->root))) | |
dies("[-] libpng failed to initialize"); | |
png_init_io(png->root, fp); | |
png_set_sig_bytes(png->root, 8); | |
// initializing file info | |
png_read_info(png->root, png->info); | |
png->width = png_get_image_width(png->root, png->info); | |
png->height = png_get_image_height(png->root, png->info); | |
png->depth = png_get_bit_depth(png->root, png->info); | |
// colors = png_get_color_type(png, info); | |
printf("[+] png file: %dx%d, depth: %d\n", png->width, png->height, png->depth); | |
// number_of_passes = png_set_interlace_handling(png_ptr); | |
png_read_update_info(png->root, png->info); | |
if(setjmp(png_jmpbuf(png->root))) | |
dies("[-] cannot read png file"); | |
png->rows = (png_byte **) malloc(sizeof(png_byte *) * png->height); | |
for(i = 0; i < png->height; i++) | |
png->rows[i] = (png_byte *) malloc(png_get_rowbytes(png->root, png->info)); | |
png_read_image(png->root, png->rows); | |
fclose(fp); | |
return png; | |
} | |
int main(void) { | |
int fbfd = 0, i, j; | |
struct fb_var_screeninfo vinfo; | |
struct fb_fix_screeninfo finfo; | |
long int screensize = 0; | |
char *fbp = 0; | |
png_byte *row, *pixel; | |
png_t *png; | |
// | |
// initialize framebuffer | |
// | |
if((fbfd = open("/dev/fb0", O_RDWR)) < -1) | |
diep("[-] /dev/fb0"); | |
if(ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) | |
diep("[-] ioctl: get fixed screen info"); | |
if(ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) | |
diep("[-] ioctl: get variable screen info"); | |
printf("[+] screen initialized: %dx%d, %d bpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel); | |
screensize = finfo.smem_len; | |
printf("[+] screen buffer: %ld ko\n", screensize / 1024); | |
fbp = (char *) mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); | |
if((int) fbp == -1) | |
diep("[-] mmap"); | |
// | |
// initialize file | |
// | |
png = decode("/tmp/process.png"); | |
// | |
// rendering | |
// | |
int location = 0; | |
// int depth = vinfo.bits_per_pixel; | |
// int divider = depth / 8; | |
for(i = 0; i < png->height; i++) { | |
row = png->rows[i]; | |
for(j = 0; j < png->width; j++) { | |
pixel = row + (j * 3); | |
fbp[location + 2] = pixel[0]; | |
fbp[location + 1] = pixel[1]; | |
fbp[location + 0] = pixel[2]; | |
location += 3; | |
} | |
} | |
munmap(fbp, screensize); | |
close(fbfd); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment