Skip to content

Instantly share code, notes, and snippets.

@maxux
Created June 18, 2015 17:51
Show Gist options
  • Save maxux/52291aec6b19ad376aee to your computer and use it in GitHub Desktop.
Save maxux/52291aec6b19ad376aee to your computer and use it in GitHub Desktop.
#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