aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt27
-rw-r--r--src/image.c141
-rw-r--r--src/image.h13
-rw-r--r--src/main.c133
4 files changed, 314 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..63e18a6
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,27 @@
+
+find_package(libpng REQUIRED)
+
+list(APPEND
+ SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/image.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/image.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/main.c
+)
+
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
+
+set(CFLAGS
+ -Wall -Wextra -pedantic
+ -Wconversion -Wshadow -Wstrict-aliasing
+ -Winit-self -Wcast-align -Wpointer-arith
+ -Wmissing-declarations -Wmissing-include-dirs
+ -Wno-unused-parameter -Wuninitialized
+)
+
+add_executable(splash ${SOURCES})
+target_compile_options(splash PUBLIC ${CFLAGS})
+
+target_include_directories(splash PUBLIC ${LIBPNG_INCLUDE_DIRS})
+
+target_link_libraries(splash LINK_PUBLIC ${LIBPNG_LIBRARIES})
+target_link_libraries(splash LINK_PUBLIC m)
diff --git a/src/image.c b/src/image.c
new file mode 100644
index 0000000..618a854
--- /dev/null
+++ b/src/image.c
@@ -0,0 +1,141 @@
+#include <stdlib.h>
+#include <png.h>
+
+#include "image.h"
+
+size_t bin_to_rgba(uint8_t** bufp, size_t size)
+{
+ size_t out_size = (size / 3) * 4;
+ uint8_t* buf = malloc(out_size);
+
+ for (size_t i = 0, j = 0; i < size; i+=3, j+=4)
+ {
+ (buf+j)[0] = (*bufp+i)[2];
+ (buf+j)[1] = (*bufp+i)[1];
+ (buf+j)[2] = (*bufp+i)[0];
+ (buf+j)[3] = 0xFF;
+ }
+ free(*bufp);
+ *bufp = buf;
+ return out_size;
+}
+
+
+size_t rgba_to_bin(uint8_t** bufp, size_t size)
+{
+ size_t out_size = (size / 4) * 3;
+ uint8_t* buf = malloc(out_size);
+
+ for (size_t i = 0, j = 0; i < size; i+=4, j+=3)
+ {
+ (buf+j)[0] = (*bufp+i)[2];
+ (buf+j)[1] = (*bufp+i)[1];
+ (buf+j)[2] = (*bufp+i)[0];
+ }
+ free(*bufp);
+ *bufp = buf;
+ return out_size;
+}
+
+size_t png_to_rgba(uint8_t** bufp, size_t size)
+{
+ size_t out_size = 0;
+
+ uint32_t* buf = (uint32_t*)*bufp;
+ FILE* fp = fmemopen(buf, size, "rb");;
+ png_bytep* row_pointers = NULL;
+
+ png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ png_infop info = png_create_info_struct(png);
+
+ png_init_io(png, fp);
+ png_read_info(png, info);
+
+ if(png_get_bit_depth(png, info) == 16) png_set_strip_16(png);
+
+ uint32_t w = png_get_image_width(png, info);
+ uint32_t h = png_get_image_height(png, info);
+
+ printf("%i, %i\n", w, h);
+
+ png_byte color_type = png_get_color_type(png, info);
+
+ if(color_type == PNG_COLOR_TYPE_PALETTE)
+ png_set_palette_to_rgb(png);
+
+ if(png_get_valid(png, info, PNG_INFO_tRNS))
+ png_set_tRNS_to_alpha(png);
+
+ row_pointers = malloc(sizeof(png_bytep) * h);
+ out_size = sizeof(uint32_t) * (w * h);
+ uint32_t* out = malloc(out_size);
+ for(uint32_t y = 0; y < h; y++)
+ {
+ row_pointers[y] = (png_byte*)(out+(w*y));
+ }
+
+ png_read_image(png, row_pointers);
+
+ png_destroy_read_struct(&png, &info, NULL);
+
+ if (fp) fclose(fp);
+ if (row_pointers) free(row_pointers);
+
+ free(*bufp);
+ *bufp = (uint8_t*)out;
+
+ return out_size;
+}
+
+#define DEFAULT_WIDTH 240
+
+size_t rgba_to_png(uint8_t** bufp, size_t size)
+{
+ uint32_t* buf = (uint32_t*)*bufp;
+
+ size_t out_size = size;
+ uint32_t* out = malloc(out_size);
+ memset(out, 0, out_size);
+ //FILE *fp = fopen("out.png", "wb");
+ FILE* fp = fmemopen(out, size, "wb");
+ png_bytep* row_pointers = NULL;
+
+ uint32_t w = 240;
+ uint32_t h = (uint32_t)((size/4)/w);
+
+ printf("%i, %i\n", w, h);
+
+ printf("%li\n", size);
+
+ /* initialize stuff */
+ png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ png_infop info_ptr = png_create_info_struct(png);
+
+ png_init_io(png, fp);
+
+ png_set_IHDR(png, info_ptr, w, h,
+ 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+
+ png_write_info(png, info_ptr);
+
+ row_pointers = malloc(sizeof(png_bytep) * h);
+ for(uint32_t y = 0; y < h; y++)
+ {
+ row_pointers[y] = (png_byte*)(buf+(w*y));
+ }
+
+ png_write_image(png, row_pointers);
+
+ png_write_end(png, NULL);
+
+ free(row_pointers);
+ fclose(fp);
+
+ while (!out[out_size/4]) --out_size;
+
+ free(buf);
+ *bufp = out;
+
+ return out_size;
+} \ No newline at end of file
diff --git a/src/image.h b/src/image.h
new file mode 100644
index 0000000..5c14fdf
--- /dev/null
+++ b/src/image.h
@@ -0,0 +1,13 @@
+#ifndef IMAGE_H
+#define IMAGE_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+size_t bin_to_rgba(uint8_t**, size_t);
+size_t rgba_to_bin(uint8_t**, size_t);
+
+size_t png_to_rgba(uint8_t**, size_t);
+size_t rgba_to_png(uint8_t**, size_t);
+
+#endif \ No newline at end of file
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..b4fea17
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,133 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "image.h"
+
+#define ARRAY_LEN(arr) sizeof(arr) / sizeof(arr[0])
+
+#define FORMAT_ERROR "%s is not in a supported format\n"
+
+typedef size_t (*splash_func)(uint8_t**, size_t);
+typedef struct {
+ char* extension;
+ splash_func func;
+} splash_types;
+
+const splash_types in_conversions[] = {
+ { .extension = "bin", .func = bin_to_rgba },
+ { .extension = "png", .func = png_to_rgba },
+};
+
+const splash_types out_conversions[] = {
+ { .extension = "bin", .func = rgba_to_bin },
+ { .extension = "png", .func = rgba_to_png },
+};
+
+int main(int argc, char** argv)
+{
+ FILE* in_fd = NULL;
+ FILE* out_fd = NULL;
+
+ int retval = EXIT_SUCCESS;
+ if (argc < 3)
+ {
+ fprintf(stderr, "%s [input] [output]\n", argv[0]);
+ retval = EXIT_FAILURE;
+ goto exit;
+ }
+
+ char* in_path = argv[1];
+ size_t in_path_len = strlen(in_path);
+ splash_func in_func = NULL;
+
+ char* out_path = argv[2];
+ size_t out_path_len = strlen(out_path);
+ splash_func out_func = NULL;
+
+ for (size_t i = 0; i <= ARRAY_LEN(in_conversions); ++i)
+ {
+ if (i == ARRAY_LEN(in_conversions))
+ {
+ fprintf(stderr, FORMAT_ERROR, in_path);
+ retval = EXIT_FAILURE;
+ goto exit;
+ }
+
+ char* extension = in_conversions[i].extension;
+ if (!strcmp(in_path+(in_path_len-strlen(extension)), extension))
+ {
+ in_func = in_conversions[i].func;
+ break;
+ }
+ }
+
+ for (size_t i = 0; i <= ARRAY_LEN(out_conversions); ++i)
+ {
+ if (i == ARRAY_LEN(out_conversions))
+ {
+ fprintf(stderr, FORMAT_ERROR, out_path);
+ retval = EXIT_FAILURE;
+ goto exit;
+ }
+
+ char* extension = out_conversions[i].extension;
+ if (!strcmp(out_path+(out_path_len-strlen(extension)), extension))
+ {
+ out_func = out_conversions[i].func;
+ break;
+ }
+ }
+
+
+ in_fd = fopen(in_path, "rb");
+ if (!in_fd)
+ {
+ fprintf(stderr, "cannot open %s\n", in_path);
+ retval = EXIT_FAILURE;
+ goto exit;
+ }
+
+ fseek(in_fd, 0L, SEEK_END);
+ size_t in_size = (size_t)ftell(in_fd);
+ rewind(in_fd);
+
+ if (!in_size)
+ {
+ fprintf(stderr, "%s is empty\n", in_path);
+ retval = EXIT_FAILURE;
+ goto exit;
+ }
+
+ out_fd = fopen(out_path, "wb");
+ if (!out_fd)
+ {
+ fprintf(stderr, "cannot open %s\n", out_path);
+ retval = EXIT_FAILURE;
+ goto exit;
+ }
+
+ uint8_t* buf = malloc(in_size+1);
+ fread(buf, 1, in_size, in_fd);
+ buf[in_size] = '\0';
+
+ if (in_func)
+ {
+ in_size = in_func(&buf, in_size);
+ }
+
+ if (out_func)
+ {
+ in_size = out_func(&buf, in_size);
+ }
+
+ fwrite(buf, 1, in_size, out_fd);
+
+ exit:
+
+ if (in_fd) fclose(in_fd);
+ if (out_fd) fclose(out_fd);
+
+ return retval;
+} \ No newline at end of file