diff options
author | Khaled Emara <ekhaled1836@gmail.com> | 2019-07-16 08:02:37 +0200 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2019-07-17 22:27:30 +0000 |
commit | a09d38f94e27dcc5fe52adf99404c821028e3e9d (patch) | |
tree | aba47b8b6850ac8c6082a046339aa758b864afa0 /texturator.c | |
parent | d4bcd183456008a083f37ee7c8baca0c9001b6ca (diff) | |
download | kmscube-a09d38f94e27dcc5fe52adf99404c821028e3e9d.tar.gz |
texturator: capture the screen to a png image
Signed-off-by: Khaled Emara <ekhaled1836@gmail.com>
Reviewed-by: Eric Engestrom <eric@engestrom.ch>
Diffstat (limited to 'texturator.c')
-rw-r--r-- | texturator.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/texturator.c b/texturator.c index 631b82b..3fcacb3 100644 --- a/texturator.c +++ b/texturator.c @@ -32,6 +32,10 @@ #include <GLES3/gl3.h> #include <GLES3/gl3ext.h> +#ifdef HAVE_LIBPNG +#include <png.h> +#endif + #include "common.h" #include "drm-common.h" @@ -91,6 +95,7 @@ static int error_frames; static int zoom = 1; static bool full; static bool stop; +static bool png; static GLenum target; static struct size { unsigned x, y, z; @@ -658,6 +663,41 @@ static bool check_quads(void) return err; } +#ifdef HAVE_LIBPNG +static void write_png_file(char *filename, int width, int height, uint8_t *buffer) +{ + FILE *fp = fopen(filename, "wb"); + png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + png_infop info = png_create_info_struct(png); + + png_init_io(png, fp); + + png_set_IHDR( + png, + info, + width, height, + 8, + PNG_COLOR_TYPE_RGBA, + PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, + PNG_FILTER_TYPE_BASE + ); + png_write_info(png, info); + + png_bytepp rows = (png_bytepp)png_malloc(png, height * sizeof(png_bytep)); + for (int i = 0; i < height; i++) + rows[i] = (png_bytep)(buffer + (height - i - 1) * width * 4); + + png_write_image(png, rows); + + png_write_end(png, NULL); + + fclose(fp); + png_destroy_write_struct(&png, &info); + free(rows); +} +#endif + static bool needs_check = true; static void draw_and_check_quads(unsigned frame) @@ -704,6 +744,17 @@ static void draw_and_check_quads(unsigned frame) if (err) error_frames++; needs_check = false; + +#ifdef HAVE_LIBPNG + if (png) { + uint8_t rgba[gbm->width*gbm->height*4]; + glReadPixels(0, 0, gbm->width, gbm->height, GL_RGBA, GL_UNSIGNED_BYTE, rgba); + static char buf[64]; + sprintf(buf, "kmscube-texturator-%dx%dx%d:%s.png", + size.x, size.y, size.z, fmt->name); + write_png_file(buf, gbm->width, gbm->height, rgba); + } +#endif } /* if we've hit max # of error frames, stop growing: */ @@ -752,6 +803,9 @@ static const struct option longopts[] = { {"full", no_argument, 0, 'f'}, {"stop", no_argument, 0, 's'}, {"zoom", no_argument, 0, 'z'}, +#ifdef HAVE_LIBPNG + {"png", no_argument, 0, 'p'}, +#endif {0, 0, 0, 0} }; @@ -765,6 +819,9 @@ static void usage(const char *name) " -f, --full check all pixels (do not stop after first faulty pixel)\n" " -s, --stop exit after testing all sizes\n" " -z, --zoom increase zoom (can be specified multiple times)\n" +#ifdef HAVE_LIBPNG + " -p, --png capture the screen to a png image\n" +#endif "\n" "where:\n" " <target> is one of 2D/2DArray/3D\n" @@ -815,6 +872,11 @@ int main(int argc, char *argv[]) case 'z': zoom++; break; +#ifdef HAVE_LIBPNG + case 'p': + png = true; + break; +#endif default: usage(argv[0]); } |