src/pngtile/main.c
changeset 96 b7f6473c4adf
parent 85 bbc12563752a
child 98 f195b8195b5a
equal deleted inserted replaced
95:af7d0de9a35c 96:b7f6473c4adf
     1 #include "shared/log.h"
     1 #include "shared/log.h"
     2 
     2 
     3 #include "pngtile.h"
     3 #include "pngtile.h"
     4 
     4 
     5 #include <getopt.h>
     5 #include <getopt.h>
       
     6 #include <string.h>
     6 #include <stdio.h>
     7 #include <stdio.h>
     7 #include <stdbool.h>
     8 #include <stdbool.h>
     8 
     9 
     9 /**
    10 /**
    10  * Command-line options
    11  * Command-line options
    20     { "width",          true,   NULL,   'W' },
    21     { "width",          true,   NULL,   'W' },
    21     { "height",         true,   NULL,   'H' },
    22     { "height",         true,   NULL,   'H' },
    22     { "x",              true,   NULL,   'x' },
    23     { "x",              true,   NULL,   'x' },
    23     { "y",              true,   NULL,   'y' },
    24     { "y",              true,   NULL,   'y' },
    24     { "zoom",           true,   NULL,   'z' },
    25     { "zoom",           true,   NULL,   'z' },
       
    26     { "out",            true,   NULL,   'o' },
    25     { "threads",        true,   NULL,   'j' },
    27     { "threads",        true,   NULL,   'j' },
    26     { 0,                0,      0,      0   }
    28     { 0,                0,      0,      0   }
    27 };
    29 };
    28 
    30 
    29 /**
    31 /**
    46         "\t-W, --width          set tile width\n"
    48         "\t-W, --width          set tile width\n"
    47         "\t-H, --height         set tile height\n"
    49         "\t-H, --height         set tile height\n"
    48         "\t-x, --x              set tile x offset\n"
    50         "\t-x, --x              set tile x offset\n"
    49         "\t-y, --y              set tile y offset\n"
    51         "\t-y, --y              set tile y offset\n"
    50         "\t-z, --zoom           set zoom factor (<0)\n"
    52         "\t-z, --zoom           set zoom factor (<0)\n"
       
    53         "\t-o, --out            set tile output file\n"
    51         "\t-j, --threads        number of threads\n"
    54         "\t-j, --threads        number of threads\n"
    52     );
    55     );
    53 }
    56 }
    54 
    57 
    55 int main (int argc, char **argv)
    58 int main (int argc, char **argv)
    56 {
    59 {
    57     int opt;
    60     int opt;
    58     bool force_update = false, no_update = false;
    61     bool force_update = false, no_update = false;
    59     struct pt_tile_info ti = {0, 0, 0, 0, 0};
    62     struct pt_tile_info ti = {
       
    63         .width  = 800,
       
    64         .height = 600,
       
    65         .x      = 0,
       
    66         .y      = 0,
       
    67         .zoom   = 0
       
    68     };
    60     struct pt_image_params update_params = { };
    69     struct pt_image_params update_params = { };
    61     int threads = 2;
    70     const char *out_path = NULL;
       
    71     int threads = 0;
    62     int tmp, err;
    72     int tmp, err;
    63     
    73     
    64     // parse arguments
    74     // parse arguments
    65     while ((opt = getopt_long(argc, argv, "hqvDUNB:W:H:x:y:z:j:", options, NULL)) != -1) {
    75     while ((opt = getopt_long(argc, argv, "hqvDUNB:W:H:x:y:z:o:j:", options, NULL)) != -1) {
    66         switch (opt) {
    76         switch (opt) {
    67             case 'h':
    77             case 'h':
    68                 // display help
    78                 // display help
    69                 help(argv[0]);
    79                 help(argv[0]);
    70                 
    80                 
   125                 ti.y = strtol(optarg, NULL, 0); break;
   135                 ti.y = strtol(optarg, NULL, 0); break;
   126 
   136 
   127             case 'z':
   137             case 'z':
   128                 ti.zoom = strtol(optarg, NULL, 0); break;
   138                 ti.zoom = strtol(optarg, NULL, 0); break;
   129 
   139 
       
   140             case 'o':
       
   141                 // output file
       
   142                 out_path = optarg;
       
   143 
       
   144                 break;
       
   145 
   130             case 'j':
   146             case 'j':
   131                 if ((tmp = strtol(optarg, NULL, 0)) < 1)
   147                 if ((tmp = strtol(optarg, NULL, 0)) < 1)
   132                     FATAL("Invalid value for -j/--threads: %s", optarg);
   148                     FATAL("Invalid value for -j/--threads: %s", optarg);
   133 
   149 
   134                 threads = tmp; break;
   150                 threads = tmp; break;
   152 
   168 
   153 
   169 
   154     struct pt_ctx *ctx = NULL;
   170     struct pt_ctx *ctx = NULL;
   155     struct pt_image *image = NULL;
   171     struct pt_image *image = NULL;
   156     enum pt_cache_status status;
   172     enum pt_cache_status status;
   157 
   173     
   158     // build ctx
   174     if (threads) {
   159     log_debug("Construct pt_ctx with %d threads", threads);
   175         // build ctx
   160 
   176         log_debug("Construct pt_ctx with %d threads", threads);
   161     if ((err = pt_ctx_new(&ctx, threads)))
   177 
   162         EXIT_ERROR(EXIT_FAILURE, "pt_ctx_new: threads=%d", threads);
   178         if ((err = pt_ctx_new(&ctx, threads)))
   163 
   179             EXIT_ERROR(EXIT_FAILURE, "pt_ctx_new: threads=%d", threads);
       
   180     }
   164     
   181     
   165     // process each image in turn
   182     // process each image in turn
   166     log_debug("Processing %d images...", argc - optind);
   183     log_debug("Processing %d images...", argc - optind);
   167 
   184 
   168     for (int i = optind; i < argc; i++) {
   185     for (int i = optind; i < argc; i++) {
   214                 log_warn("\tSupressing cache update");
   231                 log_warn("\tSupressing cache update");
   215             }
   232             }
   216 
   233 
   217         } else {    
   234         } else {    
   218             log_debug("\tImage cache is fresh");
   235             log_debug("\tImage cache is fresh");
       
   236 
       
   237             // ensure it's loaded
       
   238             log_debug("\tLoad image cache...");
       
   239 
       
   240             if ((err = pt_image_load(image)))
       
   241                 log_errno("pt_image_load: %s", pt_strerror(err));
       
   242 
   219         }
   243         }
   220 
   244 
   221         // show info
   245         // show info
   222         const struct pt_image_info *info;
   246         const struct pt_image_info *info;
   223         
   247         
   231                     (long) info->cache_mtime, info->cache_bytes, info->cache_blocks, info->cache_blocks * 512, info->cache_version
   255                     (long) info->cache_mtime, info->cache_bytes, info->cache_blocks, info->cache_blocks * 512, info->cache_version
   232             );
   256             );
   233         }
   257         }
   234 
   258 
   235         // render tile?
   259         // render tile?
   236         if (ti.width && ti.height) {
   260         if (out_path) {
       
   261             FILE *out_file;
   237             char tmp_name[] = "pt-tile-XXXXXX";
   262             char tmp_name[] = "pt-tile-XXXXXX";
   238             int fd;
   263 
   239             FILE *out;
   264             if (strcmp(out_path, "-") == 0) {
   240             
   265                 // use stdout
   241             // temporary file for output
   266                 out_file = stdout;
   242             if ((fd = mkstemp(tmp_name)) < 0) {
   267             
   243                 log_errno("mkstemp");
   268             } else if (false /* tmp */) {
       
   269                 int fd;
   244                 
   270                 
   245                 continue;
   271                 // temporary file for output
       
   272                 if ((fd = mkstemp(tmp_name)) < 0) {
       
   273                     log_errno("mkstemp");
       
   274                     
       
   275                     continue;
       
   276                 }
       
   277 
       
   278                 out_path = tmp_name;
       
   279 
       
   280                 // open out
       
   281                 if ((out_file = fdopen(fd, "w")) == NULL) {
       
   282                     log_errno("fdopen");
       
   283 
       
   284                     continue;
       
   285                 }
       
   286 
       
   287             } else {
       
   288                 // use file
       
   289                 if ((out_file = fopen(out_path, "wb")) == NULL) {
       
   290                     log_errno("fopen: %s", out_path);
       
   291                     goto error;
       
   292                 }
       
   293 
   246             }
   294             }
   247 
   295 
   248             // open out
   296             
   249             if ((out = fdopen(fd, "w")) == NULL) {
   297             if (ctx) {
   250                 log_errno("fdopen");
   298                 // render
   251 
   299                 log_info("\tAsync render tile %zux%zu@(%zu,%zu) -> %s", ti.width, ti.height, ti.x, ti.y, out_path);
   252                 continue;
   300 
       
   301                 if ((err = pt_image_tile_async(image, &ti, out_file)))
       
   302                     log_errno("pt_image_tile_async: %s: %s", img_path, pt_strerror(err));
       
   303 
       
   304             } else {
       
   305                 // render
       
   306                 log_info("\tRender tile %zux%zu@(%zu,%zu) -> %s", ti.width, ti.height, ti.x, ti.y, out_path);
       
   307 
       
   308                 if ((err = pt_image_tile_file(image, &ti, out_file)))
       
   309                     log_errno("pt_image_tile_file: %s: %s", img_path, pt_strerror(err));
       
   310 
   253             }
   311             }
   254             
       
   255             // ensure it's loaded
       
   256             log_debug("\tLoad image cache...");
       
   257 
       
   258             if ((err = pt_image_load(image)))
       
   259                 log_errno("pt_image_load: %s", pt_strerror(err));
       
   260 
       
   261             // render
       
   262             log_info("\tAsync render tile %zux%zu@(%zu,%zu) -> %s", ti.width, ti.height, ti.x, ti.y, tmp_name);
       
   263 
       
   264 
       
   265             if ((err = pt_image_tile_async(image, &ti, out)))
       
   266                 log_errno("pt_image_tile: %s: %s", img_path, pt_strerror(err));
       
   267         }
   312         }
   268 
   313 
   269 error:
   314 error:
   270         // cleanup
   315         // cleanup
   271         // XXX: leak because of async: pt_image_destroy(image);
   316         // XXX: leak because of async
   272         ;
   317         if (!ctx)
       
   318             pt_image_destroy(image);
   273     }
   319     }
   274 
   320     
   275     log_info("Waiting for images to finish...");
   321     if (ctx) {
   276 
   322         log_info("Waiting for images to finish...");
   277     // wait for tile operations to finish...
   323 
   278     pt_ctx_shutdown(ctx);
   324         // wait for tile operations to finish...
       
   325         pt_ctx_shutdown(ctx);
       
   326     }
   279 
   327 
   280     log_info("Done");
   328     log_info("Done");
   281 
   329 
   282     return 0;
   330     return 0;
   283 }
   331 }