terom@2: #include "lib/pngtile.h" terom@2: #include "shared/log.h" terom@2: terom@2: #include terom@2: #include terom@2: #include terom@2: terom@2: /** terom@2: * Command-line options terom@2: */ terom@2: static const struct option options[] = { terom@6: { "help", false, NULL, 'h' }, terom@6: { "quiet", false, NULL, 'q' }, terom@6: { "verbose", false, NULL, 'v' }, terom@6: { "debug", false, NULL, 'D' }, terom@6: { "force-update", false, NULL, 'U' }, terom@9: { "width", true, NULL, 'W' }, terom@9: { "height", true, NULL, 'H' }, terom@9: { "x", true, NULL, 'x' }, terom@9: { "y", true, NULL, 'y' }, terom@6: { 0, 0, 0, 0 } terom@2: }; terom@2: terom@2: /** terom@2: * Print usage/help info on stderr terom@2: */ terom@2: void help (const char *argv0) terom@2: { terom@2: fprintf(stderr, "Usage: %s [options] [...]\n", argv0); terom@2: fprintf(stderr, terom@2: "XXX: Process some image files.\n" terom@2: "\n" terom@2: "\t-h, --help show this help and exit\n" terom@2: "\t-q, --quiet supress informational output\n" terom@2: "\t-v, --verbose display more informational output\n" terom@2: "\t-D, --debug equivalent to -v\n" terom@6: "\t-U, --force-update unconditionally update image caches\n" terom@9: "\t-W, --width set tile width\n" terom@9: "\t-H, --height set tile height\n" terom@9: "\t-x, --x set tile x offset\n" terom@9: "\t-y, --y set tile z offset\n" terom@2: ); terom@2: } terom@2: terom@2: int main (int argc, char **argv) terom@2: { terom@2: int opt; terom@6: bool force_update = false; terom@9: struct pt_tile_info ti = {0, 0, 0, 0}; terom@2: terom@2: // parse arguments terom@9: while ((opt = getopt_long(argc, argv, "hqvDUW:H:x:y:", options, NULL)) != -1) { terom@2: switch (opt) { terom@2: case 'h': terom@2: // display help terom@2: help(argv[0]); terom@2: terom@2: return EXIT_SUCCESS; terom@2: terom@2: case 'q': terom@2: // supress excess log output terom@2: set_log_level(LOG_WARN); terom@2: terom@2: break; terom@2: terom@2: case 'v': terom@2: case 'D': terom@2: // display additional output terom@2: set_log_level(LOG_DEBUG); terom@2: terom@2: break; terom@6: terom@6: case 'U': terom@6: // force update of image caches terom@6: force_update = true; terom@6: terom@6: break; terom@2: terom@9: case 'W': terom@9: ti.width = strtol(optarg, NULL, 0); break; terom@9: terom@9: case 'H': terom@9: ti.height = strtol(optarg, NULL, 0); break; terom@9: terom@9: case 'x': terom@9: ti.x = strtol(optarg, NULL, 0); break; terom@9: terom@9: case 'y': terom@9: ti.y = strtol(optarg, NULL, 0); break; terom@9: terom@2: case '?': terom@2: // useage error terom@2: help(argv[0]); terom@2: terom@2: return EXIT_FAILURE; terom@2: terom@2: default: terom@2: // getopt??? terom@2: FATAL("getopt_long returned unknown code %d", opt); terom@2: } terom@2: } terom@2: terom@2: // end-of-arguments? terom@2: if (!argv[optind]) terom@2: EXIT_WARN(EXIT_FAILURE, "No images given"); terom@2: terom@2: terom@2: terom@2: struct pt_ctx *ctx = NULL; terom@5: struct pt_image *image = NULL; terom@8: enum pt_cache_status status; terom@2: terom@2: log_debug("Processing %d images...", argc - optind); terom@2: terom@2: for (int i = optind; i < argc; i++) { terom@2: const char *img_path = argv[i]; terom@2: terom@5: log_debug("Loading image from: %s...", img_path); terom@2: terom@2: // open terom@6: if (pt_image_open(&image, ctx, img_path, PT_IMG_WRITE)) { terom@2: log_errno("pt_image_open: %s", img_path); terom@2: continue; terom@5: } terom@2: terom@5: log_info("Opened image at: %s", img_path); terom@5: terom@5: // check if stale terom@8: if ((status = pt_image_status(image)) < 0) { terom@8: log_errno("pt_image_status: %s", img_path); terom@5: goto error; terom@5: } terom@5: terom@5: // update if stale terom@8: if (status != PT_CACHE_FRESH || force_update) { terom@8: if (status == PT_CACHE_NONE) terom@8: log_debug("Image cache is missing"); terom@8: terom@8: else if (status == PT_CACHE_STALE) terom@8: log_debug("Image cache is stale"); terom@8: terom@8: else if (status == PT_CACHE_FRESH) terom@8: log_debug("Image cache is fresh"); terom@8: terom@8: log_debug("Updating image cache..."); terom@2: terom@5: if (pt_image_update(image)) { terom@5: log_warn_errno("pt_image_update: %s", img_path); terom@5: } terom@5: terom@6: log_info("Updated image cache"); terom@2: } terom@5: terom@7: // show info terom@7: const struct pt_image_info *img_info; terom@7: terom@7: if (pt_image_info(image, &img_info)) terom@7: log_warn_errno("pt_image_info: %s", img_path); terom@7: terom@7: else terom@7: log_info("\tImage dimensions: %zux%zu", img_info->width, img_info->height); terom@7: terom@9: // render tile? terom@9: if (ti.width && ti.height) { terom@9: log_debug("Render tile %zux%zu@(%zu,%zu) -> stdout", ti.width, ti.height, ti.x, ti.y); terom@9: terom@9: if (pt_image_tile(image, &ti, stdout)) terom@9: log_errno("pt_image_tile: %s", img_path); terom@9: } terom@5: terom@5: error: terom@5: // cleanup terom@5: pt_image_destroy(image); terom@2: } terom@2: terom@2: // XXX: done terom@2: return 0; terom@2: } terom@2: