# HG changeset patch # User Tero Marttila # Date 1262032293 -7200 # Node ID 766df7c9b90ddc52eda236c2023855628b94a0db # Parent 4b440fa03183fd43ed5c14b5afd06b0a4a9d5b03 --force-update and store palette diff -r 4b440fa03183 -r 766df7c9b90d src/lib/cache.c --- a/src/lib/cache.c Mon Dec 28 20:43:33 2009 +0200 +++ b/src/lib/cache.c Mon Dec 28 22:31:33 2009 +0200 @@ -1,5 +1,6 @@ #include "cache.h" #include "shared/util.h" +#include "shared/log.h" // only LOG_DEBUG #include #include @@ -8,6 +9,7 @@ #include #include #include +#include @@ -97,7 +99,7 @@ * * XXX: needs locking */ -static int pt_cache_open_read (struct pt_cache *cache, int *fd_ptr) +static int pt_cache_open_read_fd (struct pt_cache *cache, int *fd_ptr) { int fd; @@ -114,7 +116,7 @@ /** * Open the .tmp cache file as an fd for writing */ -static int pt_cache_open_tmp (struct pt_cache *cache, int *fd_ptr) +static int pt_cache_open_tmp_fd (struct pt_cache *cache, int *fd_ptr) { int fd; char tmp_path[1024]; @@ -150,8 +152,7 @@ void *addr; // determine prot - if (cache->mode & PT_IMG_READ) - prot |= PROT_READ; + prot |= PROT_READ; if (cache->mode & PT_IMG_WRITE) prot |= PROT_WRITE; @@ -207,7 +208,7 @@ } // open as .tmp - if (pt_cache_open_tmp(cache, &cache->fd)) + if (pt_cache_open_tmp_fd(cache, &cache->fd)) return -1; // calculate data size @@ -269,15 +270,37 @@ header.bit_depth = png_get_bit_depth(png, info); header.color_type = png_get_color_type(png, info); + log_debug("width=%u, height=%u, bit_depth=%u, color_type=%u", + header.width, header.height, header.bit_depth, header.color_type + ); + // fill in other info header.row_bytes = png_get_rowbytes(png, info); + log_debug("row_bytes=%u", header.row_bytes); + + // palette etc. + if (header.color_type == PNG_COLOR_TYPE_PALETTE) { + int num_palette; + png_colorp palette; + + if (png_get_PLTE(png, info, &palette, &num_palette) == 0) + // XXX: PLTE chunk not read? + return -1; + + assert(num_palette <= PNG_MAX_PALETTE_LENGTH); + + // copy + header.num_palette = num_palette; + memcpy(&header.palette, palette, num_palette * sizeof(*palette)); + + log_debug("num_palette=%u", num_palette); + } + // create .tmp and write out header if (pt_cache_open_create(cache, &header)) return -1; - // XXX: pallette etc. - // write out raw image data a row at a time for (size_t row = 0; row < header.height; row++) { // read row data, non-interlaced diff -r 4b440fa03183 -r 766df7c9b90d src/lib/cache.h --- a/src/lib/cache.h Mon Dec 28 20:43:33 2009 +0200 +++ b/src/lib/cache.h Mon Dec 28 22:31:33 2009 +0200 @@ -48,8 +48,14 @@ /** Pixel format */ uint8_t bit_depth, color_type; + /** Number of png_color entries that follow */ + uint16_t num_palette; + /** Convenience field for number of bytes per row */ uint32_t row_bytes; + + /** Palette entries, up to 256 entries used */ + png_color palette[PNG_MAX_PALETTE_LENGTH]; }; /** diff -r 4b440fa03183 -r 766df7c9b90d src/lib/image.c --- a/src/lib/image.c Mon Dec 28 20:43:33 2009 +0200 +++ b/src/lib/image.c Mon Dec 28 22:31:33 2009 +0200 @@ -3,7 +3,7 @@ #include "shared/util.h" #include -#include // for _POSIX_PATH_MAX +#include #include @@ -97,13 +97,19 @@ /** * Open the PNG image, and write out to the cache */ -static int pt_image_update_cache (struct pt_image *img) +static int pt_image_update_cache (struct pt_image *image) { png_structp png; png_infop info; + // pre-check enabled + if (!(image->cache->mode & PT_IMG_WRITE)) { + errno = EPERM; + return -1; + } + // open .png - if (pt_image_open_png(img, &png, &info)) + if (pt_image_open_png(image, &png, &info)) return -1; // setup error trap @@ -114,7 +120,7 @@ png_read_info(png, info); // pass to cache object - if (pt_cache_update_png(img->cache, png, info)) + if (pt_cache_update_png(image->cache, png, info)) goto error; // finish off, ignore trailing data @@ -144,7 +150,7 @@ int pt_image_open (struct pt_image **image_ptr, struct pt_ctx *ctx, const char *path, int cache_mode) { struct pt_image *image; - char cache_path[_POSIX_PATH_MAX]; + char cache_path[1024]; // XXX: verify that the path exists and looks like a PNG file @@ -181,7 +187,6 @@ return pt_image_update_cache(image); } - void pt_image_destroy (struct pt_image *image) { free(image->path); diff -r 4b440fa03183 -r 766df7c9b90d src/lib/image.h --- a/src/lib/image.h Mon Dec 28 20:43:33 2009 +0200 +++ b/src/lib/image.h Mon Dec 28 22:31:33 2009 +0200 @@ -19,10 +19,5 @@ struct pt_cache *cache; }; -/** - * Release the given pt_image without any clean shutdown - */ -void pt_image_destroy (struct pt_image *image); - #endif diff -r 4b440fa03183 -r 766df7c9b90d src/lib/pngtile.h --- a/src/lib/pngtile.h Mon Dec 28 20:43:33 2009 +0200 +++ b/src/lib/pngtile.h Mon Dec 28 22:31:33 2009 +0200 @@ -6,6 +6,7 @@ * * Tile-based access to large PNG images. */ +#include /** * "Global" context shared between images @@ -17,9 +18,19 @@ */ struct pt_image; +/** Bitmask for pt_image_open modes */ enum pt_image_mode { - PT_IMG_READ = 0x01, - PT_IMG_WRITE = 0x02, + /** Update cache if needed */ + PT_IMG_WRITE = 0x01, + + /** Accept stale cache */ + PT_IMG_STALE = 0x02, +}; + +/** Metadata info for image */ +struct pt_image_info { + /** Dimensions of image */ + size_t width, height; }; @@ -36,6 +47,11 @@ int pt_image_open (struct pt_image **image_ptr, struct pt_ctx *ctx, const char *png_path, int cache_mode); /** + * Get the image's metadata + */ +int pt_image_info (struct pt_image *image, struct pt_image_info **info_ptr); + +/** * Check the given image's cache is stale - in other words, the image needs to be updated. */ int pt_image_stale (struct pt_image *image); @@ -45,4 +61,9 @@ */ int pt_image_update (struct pt_image *image); +/** + * Release the given pt_image without any clean shutdown + */ +void pt_image_destroy (struct pt_image *image); + #endif diff -r 4b440fa03183 -r 766df7c9b90d src/util/main.c --- a/src/util/main.c Mon Dec 28 20:43:33 2009 +0200 +++ b/src/util/main.c Mon Dec 28 22:31:33 2009 +0200 @@ -9,11 +9,12 @@ * Command-line options */ static const struct option options[] = { - { "help", false, NULL, 'h' }, - { "quiet", false, NULL, 'q' }, - { "verbose", false, NULL, 'v' }, - { "debug", false, NULL, 'D' }, - { 0, 0, 0, 0 } + { "help", false, NULL, 'h' }, + { "quiet", false, NULL, 'q' }, + { "verbose", false, NULL, 'v' }, + { "debug", false, NULL, 'D' }, + { "force-update", false, NULL, 'U' }, + { 0, 0, 0, 0 } }; /** @@ -29,15 +30,17 @@ "\t-q, --quiet supress informational output\n" "\t-v, --verbose display more informational output\n" "\t-D, --debug equivalent to -v\n" + "\t-U, --force-update unconditionally update image caches\n" ); } int main (int argc, char **argv) { int opt; + bool force_update = false; // parse arguments - while ((opt = getopt_long(argc, argv, "hqvD", options, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "hqvDU", options, NULL)) != -1) { switch (opt) { case 'h': // display help @@ -57,6 +60,12 @@ set_log_level(LOG_DEBUG); break; + + case 'U': + // force update of image caches + force_update = true; + + break; case '?': // useage error @@ -78,7 +87,7 @@ struct pt_ctx *ctx = NULL; struct pt_image *image = NULL; - int ret; + int stale; log_debug("Processing %d images...", argc - optind); @@ -88,7 +97,7 @@ log_debug("Loading image from: %s...", img_path); // open - if (pt_image_open(&image, ctx, img_path, PT_IMG_READ | PT_IMG_WRITE)) { + if (pt_image_open(&image, ctx, img_path, PT_IMG_WRITE)) { log_errno("pt_image_open: %s", img_path); continue; } @@ -96,20 +105,23 @@ log_info("Opened image at: %s", img_path); // check if stale - if ((ret = pt_image_stale(image)) < 0) { + if ((stale = pt_image_stale(image)) < 0) { log_errno("pt_image_stale: %s", img_path); goto error; } // update if stale - if (ret) { - log_info("Image cache is stale, updating..."); + if (stale || force_update) { + if (stale) + log_debug("Image cache is stale, updating..."); + else // force_update + log_debug("Updating image cache..."); if (pt_image_update(image)) { log_warn_errno("pt_image_update: %s", img_path); } - log_debug("Image cache updated"); + log_info("Updated image cache"); } // done