--force-update and store palette
authorTero Marttila <terom@fixme.fi>
Mon, 28 Dec 2009 22:31:33 +0200
changeset 6 766df7c9b90d
parent 5 4b440fa03183
child 7 997906f5fd2d
--force-update and store palette
src/lib/cache.c
src/lib/cache.h
src/lib/image.c
src/lib/image.h
src/lib/pngtile.h
src/util/main.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 <stdlib.h>
 #include <unistd.h>
@@ -8,6 +9,7 @@
 #include <fcntl.h>
 #include <sys/mman.h>
 #include <errno.h>
+#include <assert.h>
 
 
 
@@ -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
--- 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];
 };
 
 /**
--- 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 <stdlib.h>
-#include <limits.h> // for _POSIX_PATH_MAX
+#include <errno.h>
 
 #include <png.h>
 
@@ -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);
--- 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
--- 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 <stddef.h>
 
 /**
  * "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
--- 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