mmap header, implement pt_image_info (post-update)
authorTero Marttila <terom@fixme.fi>
Mon, 28 Dec 2009 22:50:00 +0200
changeset 7 997906f5fd2d
parent 6 766df7c9b90d
child 8 400ddf1e7aa9
mmap header, implement pt_image_info (post-update)
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 22:31:33 2009 +0200
+++ b/src/lib/cache.c	Mon Dec 28 22:50:00 2009 +0200
@@ -81,10 +81,11 @@
  */
 static void pt_cache_abort (struct pt_cache *cache)
 {
-    if (cache->mmap != NULL) {
-        munmap(cache->mmap, cache->size);
+    if (cache->header != NULL) {
+        munmap(cache->header, PT_CACHE_HEADER_SIZE + cache->size);
 
-        cache->mmap = NULL;
+        cache->header = NULL;
+        cache->data = NULL;
     }
 
     if (cache->fd >= 0) {
@@ -144,7 +145,7 @@
 
 
 /**
- * Mmap the opened cache file from offset PT_CACHE_PAGE, using the calculated size stored in cache->size
+ * Mmap the opened cache file using PT_CACHE_HEADER_SIZE plus the calculated size stored in cache->size
  */
 static int pt_cache_open_mmap (struct pt_cache *cache, void **addr_ptr)
 {
@@ -158,7 +159,7 @@
         prot |= PROT_WRITE;
 
     // perform mmap() from second page on
-    if ((addr = mmap(NULL, cache->size, prot, MAP_SHARED, cache->fd, PT_CACHE_PAGE)) == MAP_FAILED)
+    if ((addr = mmap(NULL, PT_CACHE_HEADER_SIZE + cache->size, prot, MAP_SHARED, cache->fd, 0)) == MAP_FAILED)
         return -1;
 
     // ok
@@ -201,6 +202,8 @@
  */
 static int pt_cache_open_create (struct pt_cache *cache, struct pt_cache_header *header)
 {
+    void *base;
+
     // no access
     if (!(cache->mode & PT_IMG_WRITE)) {
         errno = EPERM;
@@ -215,14 +218,18 @@
     cache->size = sizeof(*header) + header->height * header->row_bytes;
 
     // grow file
-    if (ftruncate(cache->fd, PT_CACHE_PAGE + cache->size) < 0)
+    if (ftruncate(cache->fd, PT_CACHE_HEADER_SIZE + cache->size) < 0)
         goto error;
 
-    // open mmap
-    if (pt_cache_open_mmap(cache, (void **) &cache->mmap))
+    // mmap header and data
+    if (pt_cache_open_mmap(cache, &base))
         goto error;
 
+    cache->header = base;
+    cache->data = base + PT_CACHE_HEADER_SIZE;
+
     // write header
+    // XXX: should just mmap...
     if (pt_cache_write_header(cache, header))
         goto error;
 
@@ -288,6 +295,7 @@
             // XXX: PLTE chunk not read?
             return -1;
         
+        // should only be 256 of them at most
         assert(num_palette <= PNG_MAX_PALETTE_LENGTH);
     
         // copy
@@ -297,16 +305,19 @@
         log_debug("num_palette=%u", num_palette);
     }
 
+
     // create .tmp and write out header
     if (pt_cache_open_create(cache, &header))
         return -1;
 
+
     // write out raw image data a row at a time
     for (size_t row = 0; row < header.height; row++) {
         // read row data, non-interlaced
-        png_read_row(png, cache->mmap + row * header.row_bytes, NULL);
+        png_read_row(png, cache->data + row * header.row_bytes, NULL);
     }
 
+
     // move from .tmp to .cache
     if (pt_cache_create_done(cache))
         return -1;
--- a/src/lib/cache.h	Mon Dec 28 22:31:33 2009 +0200
+++ b/src/lib/cache.h	Mon Dec 28 22:50:00 2009 +0200
@@ -26,17 +26,20 @@
     /** Opened file */
     int fd;
 
-    /** Memory-mapped file data, from the second page on */
-    uint8_t *mmap;
+    /** The mmap'd header */
+    struct pt_cache_header *header;
 
-    /** Size of the mmap'd segment in bytes */
+    /** Memory-mapped file data, starting at PT_CACHE_HEADER_SIZE */
+    uint8_t *data;
+
+    /** Size of the data segment in bytes, starting at PT_CACHE_HEADER_SIZE */
     size_t size;
 };
 
 /**
- * Size of a cache file page in bytes
+ * Size used to store the cache header
  */
-#define PT_CACHE_PAGE 4096
+#define PT_CACHE_HEADER_SIZE 4096
 
 /**
  * On-disk header
--- a/src/lib/image.c	Mon Dec 28 22:31:33 2009 +0200
+++ b/src/lib/image.c	Mon Dec 28 22:50:00 2009 +0200
@@ -95,6 +95,20 @@
 }
 
 /**
+ * Update the image_info field from the given png object.
+ *
+ * Must be called under libpng-error-trap!
+ */
+static int pt_image_update_info (struct pt_image *image, png_structp png, png_infop info)
+{
+    // query png_get_*
+    image->info.width = png_get_image_width(png, info); 
+    image->info.height = png_get_image_height(png, info); 
+
+    return 0;
+}
+
+/**
  * Open the PNG image, and write out to the cache
  */
 static int pt_image_update_cache (struct pt_image *image)
@@ -119,6 +133,10 @@
     // read meta-info
     png_read_info(png, info);
 
+    // update our meta-info
+    if (pt_image_update_info(image, png, info))
+        goto error;
+
     // pass to cache object
     if (pt_cache_update_png(image->cache, png, info))
         goto error;
@@ -177,6 +195,14 @@
     return -1;
 }
 
+int pt_image_info (struct pt_image *image, const struct pt_image_info **info_ptr)
+{
+    // XXX: ensure that this was read?
+    *info_ptr = &image->info;
+
+    return 0;
+}
+
 int pt_image_stale (struct pt_image *image)
 {
     return pt_cache_stale(image->cache, image->path);
--- a/src/lib/image.h	Mon Dec 28 22:31:33 2009 +0200
+++ b/src/lib/image.h	Mon Dec 28 22:50:00 2009 +0200
@@ -17,6 +17,9 @@
     
     /** Cache object */
     struct pt_cache *cache;
+
+    /** Image info */
+    struct pt_image_info info;
 };
 
 
--- a/src/lib/pngtile.h	Mon Dec 28 22:31:33 2009 +0200
+++ b/src/lib/pngtile.h	Mon Dec 28 22:50:00 2009 +0200
@@ -30,7 +30,7 @@
 /** Metadata info for image */
 struct pt_image_info {
     /** Dimensions of image */
-    size_t width, height;   
+    size_t width, height;
 };
 
 
@@ -49,7 +49,7 @@
 /**
  * Get the image's metadata
  */
-int pt_image_info (struct pt_image *image, struct pt_image_info **info_ptr);
+int pt_image_info (struct pt_image *image, const struct pt_image_info **info_ptr);
 
 /**
  * Check the given image's cache is stale - in other words, the image needs to be updated.
--- a/src/util/main.c	Mon Dec 28 22:31:33 2009 +0200
+++ b/src/util/main.c	Mon Dec 28 22:50:00 2009 +0200
@@ -124,6 +124,15 @@
             log_info("Updated image cache");
         }
 
+        // show info
+        const struct pt_image_info *img_info;
+        
+        if (pt_image_info(image, &img_info))
+            log_warn_errno("pt_image_info: %s", img_path);
+
+        else
+            log_info("\tImage dimensions: %zux%zu", img_info->width, img_info->height);
+
         // done
 
 error: