Skip to content

Instantly share code, notes, and snippets.

@T0w3ntum
Forked from JakubVanek/ Framebuffer to PNG
Created February 20, 2018 20:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save T0w3ntum/147aed88a62ba814c554660501943518 to your computer and use it in GitHub Desktop.
Save T0w3ntum/147aed88a62ba814c554660501943518 to your computer and use it in GitHub Desktop.
Convert raw BGRA framebuffer to RGB png file
This program can be used to convert raw BGRA 8888 framebuffer to standard PNG file.
#include <png.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
typedef struct {
uint8_t red;
uint8_t green;
uint8_t blue;
} pixel_t;
typedef struct {
pixel_t *pixels;
size_t width;
size_t height;
} bitmap_t;
static pixel_t * pixel_at (bitmap_t *bitmap, int x, int y) {
return bitmap->pixels + x + bitmap->width * y;
}
static int save_png_to_file (bitmap_t *bitmap, const char* path) {
FILE *p_file;
png_structp p_png = NULL;
png_infop p_info = NULL;
size_t x, y;
png_byte ** row_pointers = NULL;
int status = -1;
int pixel_size = 3;
int depth = 8;
p_file = fopen(path, "wb");
if (!p_file) {
goto fopen_failed;
}
p_png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (p_png == NULL) {
goto png_create_write_struct_failed;
}
p_info = png_create_info_struct (p_png);
if (p_info == NULL) {
goto png_create_info_struct_failed;
}
if (setjmp (png_jmpbuf (p_png))) {
goto png_failure;
}
png_set_IHDR ( p_png,
p_info,
bitmap->width,
bitmap->height,
depth,
PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
row_pointers = png_malloc (p_png, bitmap->height * sizeof (png_byte*));
for (y = 0; y < bitmap->height; ++y) {
png_byte *row = png_malloc (p_png, sizeof (uint8_t) * bitmap->width * pixel_size);
row_pointers[y] = row;
for (x = 0; x < bitmap->width; ++x) {
pixel_t *pixel = pixel_at (bitmap, x, y);
*row++ = pixel->red;
*row++ = pixel->green;
*row++ = pixel->blue;
}
}
png_init_io (p_png, p_file);
png_set_rows (p_png, p_info, row_pointers);
png_write_png (p_png, p_info, PNG_TRANSFORM_IDENTITY, NULL);
status = 0;
for (y = 0; y < bitmap->height; y++) {
png_free (p_png, row_pointers[y]);
}
png_free (p_png, row_pointers);
png_failure:
png_create_info_struct_failed:
png_destroy_write_struct(&p_png, &p_info);
png_create_write_struct_failed:
fclose(p_file);
fopen_failed:
return status;
}
int main (int argc, char **argv) {
size_t width, height, read = 0, length;
int i, status = 0;
char *input, *output;
uint8_t *buffer = NULL;
bitmap_t *bitmap = NULL;
pixel_t *pixel_out;
uint8_t *pixel_in;
FILE * fp = NULL;
if (argc != 5) {
printf("Usage: %s <width> <height> <input> <output>\n", argv[0]);
exit(1);
}
width = (size_t) atoi (argv[1]);
height = (size_t) atoi (argv[2]);
input = argv[3];
output = argv[4];
length = width * height * 4;
buffer = malloc (length);
bitmap = malloc (sizeof (pixel_t*) + sizeof (size_t) * 2);
bitmap->pixels = malloc(sizeof (pixel_t) * width * height);
bitmap->width = width;
bitmap->height = height;
fp = fopen(input, "rb");
if (!fp) {
printf ("Error opening file (%d): %s.\n", errno, strerror (errno));
status = 1;
goto free_val;
}
do {
read = fread (buffer + read, length - read, 1, fp);
} while (read > 0);
read = fclose (fp);
if (read == EOF) {
printf ("Error closing file (%d): %s.\n", errno, strerror (errno));
status = 1;
goto free_val;
}
pixel_in = buffer;
pixel_out = bitmap->pixels;
for (i = 0; i < width * height; i++) {
pixel_out->blue = *(pixel_in++);
pixel_out->green = *(pixel_in++);
pixel_out->red = *(pixel_in++);
pixel_in++; // ignore alpha
pixel_out++; // to next pixel
}
pixel_in = NULL;
pixel_out = NULL;
int retval = save_png_to_file (bitmap, output);
if (retval != 0) {
printf ("Error saving PNG.\n");
goto free_val;
}
free_val:
free(buffer);
free(bitmap->pixels);
free(bitmap);
return status;
}
@T0w3ntum
Copy link
Author

Compile

gcc data.c -O2 -lpng -o data

./data <fb width> <fb height> /dev/fb0 <out>.png (replace <...> with corresponding values)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment