improve pypngtile
authorTero Marttila <terom@fixme.fi>
Mon, 25 Jan 2010 04:06:44 +0200
changeset 78 a3aaf5c23454
parent 77 29c57814204a
child 79 016c20a15283
improve pypngtile
python/pypngtile.pyx
--- a/python/pypngtile.pyx	Mon Jan 25 04:00:37 2010 +0200
+++ b/python/pypngtile.pyx	Mon Jan 25 04:06:44 2010 +0200
@@ -4,6 +4,9 @@
 cdef extern from "string.h" :
     char* strerror (int err)
 
+    void* memset (void *, int, size_t)
+    void* memcpy (void *, void *, size_t)
+
 cimport stdio
 cimport stdlib
 cimport python_string
@@ -22,19 +25,20 @@
         pass
 
     enum pt_open_mode :
+        PT_OPEN_READ    # 0
         PT_OPEN_UPDATE
 
     enum pt_cache_status :
-        PT_CACHE_ERROR
+        PT_CACHE_ERROR  # -1
         PT_CACHE_FRESH
         PT_CACHE_NONE
         PT_CACHE_STALE
         PT_CACHE_INCOMPAT
 
     struct pt_image_info :
-        size_t img_width, img_height
-        int img_mtime, cache_mtime, cache_version
-        size_t img_bytes, cache_bytes
+        size_t img_width, img_height, img_bpp
+        int image_mtime, cache_mtime, cache_version
+        size_t image_bytes, cache_bytes
         size_t cache_blocks
 
     struct pt_image_params :
@@ -55,12 +59,16 @@
 
     char* pt_strerror (int err)
 
-OPEN_UPDATE = PT_OPEN_UPDATE
-CACHE_ERROR = PT_CACHE_ERROR
-CACHE_FRESH = PT_CACHE_FRESH
-CACHE_NONE = PT_CACHE_NONE
-CACHE_STALE = PT_CACHE_STALE
-CACHE_INCOMPAT = PT_CACHE_INCOMPAT
+## constants
+# Image()
+OPEN_READ       = PT_OPEN_READ
+OPEN_UPDATE     = PT_OPEN_UPDATE
+
+# Image.status -> ...
+CACHE_FRESH     = PT_CACHE_FRESH
+CACHE_NONE      = PT_CACHE_NONE
+CACHE_STALE     = PT_CACHE_STALE
+CACHE_INCOMPAT  = PT_CACHE_INCOMPAT
 
 class Error (BaseException) :
     pass
@@ -73,33 +81,99 @@
         return ret
 
 cdef class Image :
+    """
+        An image file on disk (.png) and an associated .cache file.
+        
+        Open the .png file at the given path using the given mode.
+
+        path        - filesystem path to .png file
+        mode        - mode to operate cache in
+            OPEN_READ       - read-only access to cache
+            OPEN_UPDATE     - allow .update()
+    """
+
     cdef pt_image *image
 
-    def __cinit__ (self, char *png_path, int cache_mode = 0) :
+    
+    # open the pt_image
+    def __cinit__ (self, char *path, int mode = 0) :
         trap_err("pt_image_open", 
-            pt_image_open(&self.image, NULL, png_path, cache_mode)
+            pt_image_open(&self.image, NULL, path, mode)
         )
-    
+
+
     def info (self) :
-        cdef pt_image_info *image_info
+        """
+            Return a dictionary containing various information about the image.
+
+            img_width           - pixel dimensions of the source image
+            img_height            only available if the cache was opened
+            img_bpp             - bits per pixel for the source image
+
+            image_mtime         - last modification timestamp for source image
+            image_bytes         - size of source image file in bytes
+
+            cache_version       - version of cache file available
+            cache_mtime         - last modification timestamp for cache file
+            cache_bytes         - size of cache file in bytes
+            cache_blocks        - size of cache file in disk blocks - 512 bytes / block
+        """
+
+        cdef pt_image_info *info
         
         trap_err("pt_image_info",
-            pt_image_info_func(self.image, &image_info)
+            pt_image_info_func(self.image, &info)
         )
 
-        return (image_info.img_width, image_info.img_height)
-    
+        # return as a struct
+        return info[0]
+
+
     def status (self) :
+        """
+            Return a code describing the status of the underlying cache file.
+
+            CACHE_FRESH         - the cache file exists and is up-to-date
+            CACHE_NONE          - the cache file does not exist
+            CACHE_STALE         - the cache file exists, but is older than the source image
+            CACHE_INCOMPAT      - the cache file exists, but is incompatible with this version of the library
+        """
+
         return trap_err("pt_image_status", 
             pt_image_status(self.image)
         )
+
+
+    def update (self, background_color = None) :
+        """
+            Update the underlying cache file from the source image.
+
+            background_color    - skip consecutive pixels that match this byte pattern in output
+
+            Requires that the Image was opened using OPEN_UPDATE.
+        """
+
+        cdef pt_image_params params
+        cdef char *bgcolor
+        memset(&params, 0, sizeof(params))
+
+        # params
+        if background_color :
+            # cast
+            bgcolor = <char *>background_color
+
+            if 0 >= len(bgcolor) > 4 :
+                raise ValueError("background_color must be a str of between 1 and 4 bytes")
+
+            # decode 
+            memcpy(params.background_color, bgcolor, len(bgcolor))
     
-    # XXX: support params
-    def update (self) :
+        # run update
         trap_err("pt_image_update", 
-            pt_image_update(self.image, NULL)
+            pt_image_update(self.image, &params)
         )
 
+
     def tile_file (self, size_t width, size_t height, size_t x, size_t y, int zoom, object out) :
         cdef stdio.FILE *outf
         cdef pt_tile_info ti
@@ -122,6 +196,7 @@
             pt_image_tile_file(self.image, &ti, outf)
         )
 
+
     def tile_mem (self, size_t width, size_t height, size_t x, size_t y, int zoom) :
         cdef pt_tile_info ti
         cdef char *buf
@@ -146,6 +221,7 @@
 
         return data
 
+    # release the pt_image
     def __dealloc__ (self) :
         if self.image :
             pt_image_destroy(self.image)