diff options
author | Tauwasser <Tauwasser@tauwasser.eu> | 2018-06-03 22:16:21 +0200 |
---|---|---|
committer | Tauwasser <Tauwasser@tauwasser.eu> | 2018-06-03 22:16:21 +0200 |
commit | 40c8b5f0a304155ac50ea526b890770214bf1343 (patch) | |
tree | 241fa9c549b89d7863db3e172b91a6c22149bfc8 | |
parent | b50c850650727689a60689db2fa63f2cd92ddd09 (diff) |
tools/gfx: add option to trim trailing tiles of solid color
This helps when the last tile is completely white and the shape of the
png has additional tiles. In that case, the last tile is cut as well.
Signed-off-by: Tauwasser <Tauwasser@tauwasser.eu>
-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) { |