diff options
Diffstat (limited to 'tools/gfx.c')
-rwxr-xr-x | tools/gfx.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/tools/gfx.c b/tools/gfx.c index 8c4066a..1ce0590 100755 --- a/tools/gfx.c +++ b/tools/gfx.c @@ -8,7 +8,9 @@ #include "common.h" static void usage(void) { - fprintf(stderr, "Usage: gfx [--trim-whitespace] [--remove-whitespace] [--interleave] [--remove-duplicates [--keep-whitespace]] [--remove-xflip] [--remove-yflip] [--png filename] [-d depth] [-h] [-o outfile] infile\n"); + fprintf(stderr, "Usage: gfx [[--trim-whitespace] | [--trim-trailing]] [--remove-whitespace] [--interleave] " + "[--remove-duplicates [--keep-whitespace]] [--remove-xflip] [--remove-yflip] [--png filename] " + "[-d depth] [-h] [-o outfile] infile\n"); } static void error(char *message) { @@ -18,6 +20,7 @@ static void error(char *message) { struct Options { int trim_whitespace; + int trim_trailing; int remove_whitespace; int help; char *outfile; @@ -38,6 +41,7 @@ void get_args(int argc, char *argv[]) { struct option long_options[] = { {"remove-whitespace", no_argument, &Options.remove_whitespace, 1}, {"trim-whitespace", no_argument, &Options.trim_whitespace, 1}, + {"trim-trailing", no_argument, &Options.trim_trailing, 1}, {"interleave", no_argument, &Options.interleave, 1}, {"remove-duplicates", no_argument, &Options.remove_duplicates, 1}, {"keep-whitespace", no_argument, &Options.keep_whitespace, 1}, @@ -88,6 +92,27 @@ bool is_whitespace(uint8_t *tile, int tile_size) { return true; } +/** + * is_solid_color + * Check if a tile is solid color, i.e. each + * bitplane is filled with the same value. + * Different bitplanes can have different values. + * + * Returns true if solid color, else false. + */ +bool is_solid_color(uint8_t *tile, int depth, int tile_size) { + + const uint8_t ONES = 0xff; + const uint8_t ZEROS = 0x00; + + for (int i = 0; i < depth; i++) { + if (tile[i] != ONES && tile[i] != ZEROS) { + return false; + } + } + return !memcmp(&tile[0], &tile[depth], tile_size - depth); +} + void trim_whitespace(struct Graphic *graphic) { int tile_size = Options.depth * 8; for (int i = graphic->size - tile_size; i > 0; i -= tile_size) { @@ -99,6 +124,21 @@ void trim_whitespace(struct Graphic *graphic) { } } +void trim_trailing(struct Graphic *graphic) { + int tile_size = Options.depth * 8; + int last_tile = graphic->size - tile_size; + if (!is_solid_color(&graphic->data[last_tile], Options.depth, tile_size)) { + return; + } + for (int i = graphic->size - 2 * tile_size; i > 0; i -= tile_size) { + if (!memcmp(&graphic->data[i], &graphic->data[last_tile], tile_size)) { + graphic->size = i; + } else { + break; + } + } +} + void remove_whitespace(struct Graphic *graphic) { int tile_size = Options.depth * 8; if (Options.interleave) tile_size *= 2; @@ -263,6 +303,8 @@ int main(int argc, char *argv[]) { graphic.data = read_u8(infile, &graphic.size); if (Options.trim_whitespace) { trim_whitespace(&graphic); + } else if (Options.trim_trailing) { + trim_trailing(&graphic); } if (Options.interleave) { if (!Options.png_file) { |