Last active
August 18, 2022 00:23
-
-
Save GabrielFreeze/e8ddaf3097f68611e822f0edc227d07a to your computer and use it in GitHub Desktop.
Supply this program with an executable and it will display the bytecode as a png. Coloured pixels are used only for padding. GCC flags: -lm -lpng. [Linux]
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 <png.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdint.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <math.h> | |
typedef struct { | |
uint8_t red; | |
uint8_t green; | |
uint8_t blue; | |
} pixel_t; | |
typedef struct { | |
size_t width; | |
size_t height; | |
pixel_t *pixels; | |
} bitmap_t; | |
static pixel_t* pixel_at (bitmap_t* bitmap, int x, int y) { | |
return bitmap->pixels + bitmap->width * y + x; | |
} | |
static int save_png_to_file (bitmap_t* bitmap, const char* path) { | |
FILE * fp; | |
png_structp png_ptr = NULL; | |
png_infop info_ptr = NULL; | |
size_t x, y; | |
png_byte ** row_pointers = NULL; | |
/* "status" contains the return value of this function. At first | |
it is set to a value which means 'failure'. When the routine | |
has finished its work, it is set to a value which means | |
'success'. */ | |
int status = -1; | |
/* The following number is set by trial and error only. I cannot | |
see where it it is documented in the libpng manual. | |
*/ | |
int pixel_size = 3; | |
int depth = 8; | |
fp = fopen (path, "wb"); | |
if (! fp) { | |
goto fopen_failed; | |
} | |
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); | |
if (png_ptr == NULL) { | |
goto png_create_write_struct_failed; | |
} | |
info_ptr = png_create_info_struct (png_ptr); | |
if (info_ptr == NULL) { | |
goto png_create_info_struct_failed; | |
} | |
/* Set up error handling. */ | |
if (setjmp (png_jmpbuf (png_ptr))) { | |
goto png_failure; | |
} | |
/* Set image attributes. */ | |
png_set_IHDR (png_ptr, | |
info_ptr, | |
bitmap->width, | |
bitmap->height, | |
depth, | |
PNG_COLOR_TYPE_RGB, | |
PNG_INTERLACE_NONE, | |
PNG_COMPRESSION_TYPE_DEFAULT, | |
PNG_FILTER_TYPE_DEFAULT); | |
/* Initialize rows of PNG. */ | |
row_pointers = png_malloc (png_ptr, bitmap->height * sizeof (png_byte *)); | |
for (y = 0; y < bitmap->height; y++) { | |
png_byte *row = | |
png_malloc (png_ptr, 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; | |
} | |
} | |
/* Write the image data to "fp". */ | |
png_init_io (png_ptr, fp); | |
png_set_rows (png_ptr, info_ptr, row_pointers); | |
png_write_png (png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); | |
/* The routine has successfully written the file, so we set | |
"status" to a value which indicates success. */ | |
status = 0; | |
for (y = 0; y < bitmap->height; y++) { | |
png_free (png_ptr, row_pointers[y]); | |
} | |
png_free (png_ptr, row_pointers); | |
png_failure: | |
png_create_info_struct_failed: | |
png_destroy_write_struct (&png_ptr, &info_ptr); | |
png_create_write_struct_failed: | |
fclose (fp); | |
fopen_failed: | |
return status; | |
} | |
int main (int argc, char** argv) { | |
int status = 0; | |
//Read binary file. | |
FILE* fp; | |
if (!(fp = fopen(*++argv,"rb"))) { | |
perror("Could not open binary file"); | |
return 1; | |
} | |
//Get size of binary file. | |
fseek(fp, 0, SEEK_END); | |
size_t sz = ftell(fp); | |
rewind(fp); | |
//Store binary file as byte array. | |
uint8_t* buffer = (uint8_t*) malloc(sz); | |
sz = fread(buffer, 1, sz, fp); | |
fclose(fp); | |
// Create an image | |
uint32_t side = ceil(sqrt(sz)); | |
bitmap_t png = {side,side}; | |
if (!(png.pixels = calloc(png.width * png.height, sizeof(pixel_t)))) { | |
return 1; | |
} | |
//Colour the image | |
uint16_t x=0,y=-1; | |
pixel_t* pixel; | |
for (uint32_t i=0; i<side*side; i++) { | |
if ((x=i%side) == 0) y++; | |
pixel = pixel_at(&png, x,y); | |
if (i < sz) { | |
pixel->green = pixel->blue = pixel->red = *buffer++; | |
} else { | |
switch (rand()%3) { | |
case 0: pixel->red = 255; break; | |
case 1: pixel->green = 255; break; | |
case 2: pixel->blue = 255; break; | |
} | |
} | |
} | |
//Write the image to a file 'output.png'. | |
char cwd[1024]; | |
if (save_png_to_file(&png, strcat(getcwd(cwd,1024),"/output.png"))) { | |
fprintf(stderr, "Error writing file.\n"); | |
status = -1; | |
} | |
free(png.pixels); | |
return status; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment