From 03e719c00e24e29594704475fdf01297e38eb4ad Mon Sep 17 00:00:00 2001 From: plerros <48536508+plerros@users.noreply.github.com> Date: Wed, 20 Oct 2021 16:50:22 +0300 Subject: [PATCH 1/3] getopt --- src/main.c | 188 +++++++++++++++++++++++++++++++++++++++--- src/picture/picture.c | 10 +++ src/picture/picture.h | 2 + 3 files changed, 189 insertions(+), 11 deletions(-) diff --git a/src/main.c b/src/main.c index 7ef660d..fba42e6 100644 --- a/src/main.c +++ b/src/main.c @@ -4,30 +4,191 @@ */ #include +#include +#include +#include #include +#include +#include +#include #include "picture.h" #include "pixmap.h" +void help() +{ + printf( + "Usage: pixmap565 [options] -i infile%s -o outfile\n" + " or: pixmap565 [options] -w width -i infile -o outfile%s\n" + "Convert between %s image and RGB565 pixmap.\n\n" + " -w [width] set the width (height is derived from filesize /width)\n" + "\nOptions:\n" + " --help display this help and exit\n", + picture_extension(), + picture_extension(), + picture_type() + ); +} + +static void strnewcpy(char **new, const char *old) +{ + assert(old != NULL); + free(*new); + *new = malloc(sizeof(char) * (strlen(old) + 1)); + if (new == NULL) + abort(); + + strcpy(*new, old); +} + +static bool willoverflow(unsigned long x, unsigned digit) +{ + assert(digit < 10); + if (x > ULONG_MAX / 10) + return true; + if (x == ULONG_MAX / 10 && digit > ULONG_MAX % 10) + return true; + return false; +} + +static int strto_ul(const char *str, unsigned long *number) // string to unsigned long +{ + assert(str != NULL); + assert(number != NULL); + int err = 0; + unsigned long tmp = 0; + for (size_t i = 0; isgraph(str[i]); i++) { + if (!isdigit(str[i])) { + err = 1; + goto out; + } + unsigned digit = str[i] - '0'; + if (willoverflow(tmp, digit)) { + err = 1; + goto out; + } + tmp = 10 * tmp + digit; + } + *number = tmp; +out: + if (err) + fprintf(stderr, "Input out of range: [0, %lu]\n", ULONG_MAX); + return err; +} + int main(int argc, char *argv[]) { int rc = 0; - // (test code) - char in[] = "about.bmp"; - char out[] = "out.bin"; + + char *inname = NULL; + char *outname = NULL; + unsigned long width = 0; struct picture *pic = NULL; struct pixmap *pix = NULL; + FILE *infile = NULL; + FILE *outfile = NULL; - FILE *infile = fopen(in, "r"); - assert(infile != NULL); + { + static int help_flag = 0; + bool infile_is_set = false; + bool outfile_is_set = false; + bool width_is_set = false; + int c; + while (1) { + static struct option long_options[] = { + {"help", no_argument, &help_flag, true}, + {"infile", required_argument, NULL, 'i'}, + {"outfile", required_argument, NULL, 'o'}, + {"width", required_argument, NULL, 'w'}, + {NULL, 0, NULL, 0} + }; + int option_index = 0; + c = getopt_long(argc, argv, "i:o:w:", long_options, &option_index); + + // Detect end of the options + if (c == -1) + break; + if (help_flag){ + help(); + goto out; + } + + switch (c) { + case 0: + break; + + case 'i': + if (infile_is_set) { + help(); + goto out; + } + strnewcpy(&inname, optarg); + infile_is_set = true; + break; + + case 'o': + if (outfile_is_set) { + help(); + goto out; + } + strnewcpy(&outname, optarg); + outfile_is_set = true; + break; - FILE *outfile = fopen(out, "w+"); - assert(outfile != NULL); + case 'w': + if (width_is_set) { + help(); + goto out; + } + rc = strto_ul(optarg, &width); + width_is_set = true; + break; - if (is_pic(in)) + case '?': + help(); + goto out; + + default: + abort(); + } + } + if (!infile_is_set || !outfile_is_set) { + help(); + goto out; + } + if (!(is_pic(inname) ^ is_pic(outname))) { + help(); + goto out; + } + if (is_pic(outname) && !width_is_set) { + help(); + goto out; + } + } + + infile = fopen(inname, "r"); + if (infile == NULL) { + printf("Cannot open file '%s'\n", inname); + rc = 1; + goto out; + } + if (access(outname, F_OK) == 0) { + printf("File '%s' already exists.\n", outname); + rc = 1; + goto out; + } + outfile = fopen(outname, "w+"); + if (outfile == NULL) { + printf("Cannot open file '%s'\n", outname); + rc = 1; + goto out; + } + + picture_new(&pic); + + if (is_pic(inname)) { - picture_new(&pic); rc = picture_read(pic, infile); if (rc) goto out; @@ -51,7 +212,12 @@ int main(int argc, char *argv[]) picture_free(pic); pixmap_free(pix); - fclose(infile); - fclose(outfile); + if (infile != NULL) + fclose(infile); + if (outfile != NULL) + fclose(outfile); + + free(inname); + free(outname); return rc; } diff --git a/src/picture/picture.c b/src/picture/picture.c index 6e443ea..f6a73eb 100644 --- a/src/picture/picture.c +++ b/src/picture/picture.c @@ -144,6 +144,16 @@ struct pixmap *picture_get_pixmap(struct picture *ptr) return ret; } +char *picture_type() +{ + return ("BMP565"); +} + +char *picture_extension() +{ + return (".bmp\0"); +} + bool is_pic(char *filename) { bool ret = false; diff --git a/src/picture/picture.h b/src/picture/picture.h index a018bf3..48f82ab 100644 --- a/src/picture/picture.h +++ b/src/picture/picture.h @@ -18,6 +18,8 @@ void picture_free(struct picture *ptr); void picture_set_pixmap(struct picture *ptr, struct pixmap *matrix); struct pixmap *picture_get_pixmap(struct picture *ptr); +char *picture_type(); +char *picture_extension(); bool is_pic(char *filename); int picture_read(struct picture *ptr, FILE *fp); From 8ff50d0e2d317ea8e61cd7ff424f61409854ef6f Mon Sep 17 00:00:00 2001 From: plerros <48536508+plerros@users.noreply.github.com> Date: Wed, 20 Oct 2021 17:08:39 +0300 Subject: [PATCH 2/3] update README -Updated README -Changed main to allow for .bmp to .bmp conversion -Fixed a bug in picture_set_pixmap --- README.md | 6 +++++- src/main.c | 19 ++++++++++++------- src/picture/picture.c | 2 +- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 4e31396..255f58d 100644 --- a/README.md +++ b/README.md @@ -12,4 +12,8 @@ git clone https://github.com/plerros/pixmap565.git ``` make ``` -(to be filled in later) +## Run: +``` +./pixmap565 -i infile.bmp -o outfile +./pixmap565 -w width -i infile -o outfile.bmp +``` diff --git a/src/main.c b/src/main.c index fba42e6..ead4645 100644 --- a/src/main.c +++ b/src/main.c @@ -21,7 +21,7 @@ void help() "Usage: pixmap565 [options] -i infile%s -o outfile\n" " or: pixmap565 [options] -w width -i infile -o outfile%s\n" "Convert between %s image and RGB565 pixmap.\n\n" - " -w [width] set the width (height is derived from filesize /width)\n" + " -w [width] set the width (height is derived from filesize/width)\n" "\nOptions:\n" " --help display this help and exit\n", picture_extension(), @@ -109,6 +109,7 @@ int main(int argc, char *argv[]) // Detect end of the options if (c == -1) break; + if (help_flag){ help(); goto out; @@ -157,11 +158,11 @@ int main(int argc, char *argv[]) help(); goto out; } - if (!(is_pic(inname) ^ is_pic(outname))) { + if (!(is_pic(inname) || is_pic(outname))) { help(); goto out; } - if (is_pic(outname) && !width_is_set) { + if (!is_pic(inname) && is_pic(outname) && !width_is_set) { help(); goto out; } @@ -193,19 +194,23 @@ int main(int argc, char *argv[]) if (rc) goto out; pix = picture_get_pixmap(pic); - rc = pixmap_write(pix, outfile); - if (rc) - goto out; } else { - pixmap_new(&pix, 78); + pixmap_new(&pix, width); rc = pixmap_read(pix, infile); if (rc) goto out; + } + + if (is_pic(outname)) { picture_set_pixmap(pic, pix); pix = NULL; rc = picture_write(pic, outfile); if (rc) goto out; + } else { + rc = pixmap_write(pix, outfile); + if (rc) + goto out; } out: diff --git a/src/picture/picture.c b/src/picture/picture.c index f6a73eb..9fbf527 100644 --- a/src/picture/picture.c +++ b/src/picture/picture.c @@ -125,7 +125,7 @@ void picture_set_pixmap(struct picture *ptr, struct pixmap *matrix) ptr->image_size = dword_abs(ptr->width) * dword_abs(ptr->height) * BYTES_PER_PIXEL; ptr->image_size += (ptr->image_size % 4); - ptr->file_bytes += ptr->image_size; + ptr->file_bytes = ptr->image_size; } struct pixmap *picture_get_pixmap(struct picture *ptr) From ff619115af86a2455ee399f8927b94a1dbbdd26b Mon Sep 17 00:00:00 2001 From: plerros <48536508+plerros@users.noreply.github.com> Date: Wed, 20 Oct 2021 17:15:06 +0300 Subject: [PATCH 3/3] example scritps --- README.md | 5 +++++ mkstft28-icon.sh | 3 +++ mkstft28.sh | 3 +++ 3 files changed, 11 insertions(+) create mode 100644 mkstft28-icon.sh create mode 100644 mkstft28.sh diff --git a/README.md b/README.md index 255f58d..a18ad3a 100644 --- a/README.md +++ b/README.md @@ -17,3 +17,8 @@ make ./pixmap565 -i infile.bmp -o outfile ./pixmap565 -w width -i infile -o outfile.bmp ``` +## Scripts: +``` +./mkstft28.sh infile outfile +./mkstft28-icon.sh infile outfile +``` diff --git a/mkstft28-icon.sh b/mkstft28-icon.sh new file mode 100644 index 0000000..c2c61e4 --- /dev/null +++ b/mkstft28-icon.sh @@ -0,0 +1,3 @@ +#!/bin/bash +# MKS TFT28 icon resolution: 78x104 +./pixmap -w 78 -i $1 -o $2 diff --git a/mkstft28.sh b/mkstft28.sh new file mode 100644 index 0000000..aa82a57 --- /dev/null +++ b/mkstft28.sh @@ -0,0 +1,3 @@ +#!/bin/bash +# MKS TFT28 resolution: 320x240 +./pixmap -w 320 -i $1 -o $2