diff options
author | Ian C <ianc@noddybox.co.uk> | 2016-11-25 15:57:41 +0000 |
---|---|---|
committer | Ian C <ianc@noddybox.co.uk> | 2016-11-25 15:57:41 +0000 |
commit | 119fd651b00b94350ae97ae4fdceeffa6d4f71e2 (patch) | |
tree | 3e44eb3446f53ff4a8516db1d687e090ebaf0cc1 /png8.c | |
parent | 4697fa1ea0911f51ac1032eec2b88940ff206aa4 (diff) |
Skeleton in place.
Diffstat (limited to 'png8.c')
-rwxr-xr-x | png8.c | 263 |
1 files changed, 263 insertions, 0 deletions
@@ -0,0 +1,263 @@ +/* + + png8 - Simple PNG sprite strip converter for assembly targets + + Copyright (C) 2016 Ian Cowburn <ianc@noddybox.co.uk> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + ------------------------------------------------------------------------- + + Main + +*/ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#include <time.h> +#include <setjmp.h> + +#include <png.h> + +/* ---------------------------------------- MACROS +*/ +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +#define IS_BLACK(ul) (((ul) && 0x00FFFFFFul) == 0) +#define IS_TRANS(ul) (((ul) && 0xFF000000ul) == 0) + + +/* ---------------------------------------- VERSION INFO +*/ + +static const char *png8_usage = +"Version 1.0 development\n" +"\n" +"This program is distributed in the hope that it will be useful,\n" +"but WITHOUT ANY WARRANTY; without even the implied warranty of\n" +"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" +"GNU General Public License (Version 3) for more details.\n" +"\n" +"usage: png8 <options> <file> -- convert a file\n" +"usage: png8 -h -- get help on <options>\n"; + + +/* ---------------------------------------- TYPES +*/ +typedef enum +{ + OUTPUT_Undefined, + OUTPUT_Mono, + OUTPUT_4Col +} output_type_t; + +typedef unsigned long ulong; + + +/* ---------------------------------------- HELP & USAGE +*/ +static void Usage(void) +{ + fprintf(stderr,"%s\n", png8_usage); + exit(EXIT_FAILURE); +} + + +static void Help(void) +{ + static const char *help = +"Usage:\n" +" png8 <switches> <PNG file>\n" +"\nGeneral switches:\n" +"-h - This help text.\n" +"\nOne of these switches must be provided:\n" +"-1 - Produce a monochrome sprite data set (e.g. Spectrum).\n" +"-4 - Produce a 4-colour sprite data set (e.g. Commodore 64).\n" +"\nOptional switches:\n" +"-s - Treat black the same as a transparent pixel.\n" +"-p <text> - Use <text> in place of 'byte' for output.\n" +"-i - For monochrome data, produce pre-shifted values.\n" +""; + + fprintf(stderr,"%s\n", help); + exit(EXIT_SUCCESS); +} + + +/* ---------------------------------------- UTIL +*/ +static void Exit(const char *fmt, ...) +{ + va_list va; + + va_start(va, fmt); + vfprintf(stderr, fmt, va); + va_end(va); + + exit(EXIT_FAILURE); +} + + +static void *Malloc(size_t size) +{ + void *p = malloc(size); + + if (!p) + { + Exit("memory allocation failed\n"); + } + + return p; +} + + +static ulong RGBA(png_byte r, png_byte g, png_byte b, png_byte a) +{ + return ((ulong)r << 16ul) | + ((ulong)g << 8ul) | + ((ulong)b) | + ((ulong)a << 24ul); +} + + +/* ---------------------------------------- MAIN +*/ +int main(int argc, char *argv[]) +{ + png_structp png; + png_infop png_info; + int num_passes; + png_bytep *data; + int width, height; + png_byte colour_type, colour_depth; + const char *opcode = "byte"; + output_type_t output = OUTPUT_Undefined; + int pre_shift = FALSE; + int f; + FILE *fp; + char header[8]; + + f = 1; + + while(argv[f] && argv[f][0] == '-') + { + switch(argv[f][1]) + { + case 'h': + Help(); + break; + + case '1': + output = OUTPUT_Mono; + break; + + case '4': + output = OUTPUT_4Col; + break; + + default: + Usage(); + break; + } + + f++; + } + + if (output == OUTPUT_Undefined || !argv[f]) + { + Usage(); + } + + if (!(fp = fopen(argv[f], "rb"))) + { + Exit("Failed to open %s\n", argv[f]); + } + + fread(header, 1, sizeof header, fp); + + if (png_sig_cmp(header, 0, sizeof header)) + { + Exit("%s not recognised as a PNG file\n", argv[f]); + } + + if (!(png = png_create_read_struct + (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))) + { + Exit("png_create_read_struct failed\n"); + } + + if (!(png_info = png_create_info_struct(png))) + { + Exit("png_create_info_struct failed\n"); + } + + if (setjmp(png_jmpbuf(png))) + { + Exit("png_init_io failed\n"); + } + + png_init_io(png, fp); + png_set_sig_bytes(png, sizeof header); + png_read_info(png, png_info); + + width = png_get_image_width(png, png_info); + height = png_get_image_height(png, png_info); + colour_type = png_get_color_type(png, png_info); + colour_depth = png_get_bit_depth(png, png_info); + num_passes = png_set_interlace_handling(png); + + if (colour_type != PNG_COLOR_TYPE_RGBA) + { + Exit("PNG must be an RGB image with an alpha channel.\n"); + } + + png_read_update_info(png, png_info); + + data = Malloc((sizeof *data) * height); + + for(f = 0; f < height; f++) + { + data[f] = Malloc(png_get_rowbytes(png, png_info)); + } + + if (setjmp(png_jmpbuf(png))) + { + Exit("png_read_image failed\n"); + } + + png_read_image(png, data); + + fclose(fp); + + for(f = 0; f < height; f++) + { + free(data[f]); + } + + free(data); + + return EXIT_SUCCESS; +} + + +/* +vim: ai sw=4 ts=8 expandtab +*/ |