python/pypngtile.pyx
changeset 91 0bf7878bdf5c
parent 87 ecd87b41e884
child 104 b5ae988c78b8
equal deleted inserted replaced
90:1c317e0628a7 91:0bf7878bdf5c
    46     
    46     
    47     struct pt_tile_info :
    47     struct pt_tile_info :
    48         size_t width, height
    48         size_t width, height
    49         size_t x, y
    49         size_t x, y
    50         int zoom
    50         int zoom
       
    51 
       
    52     ctypedef pt_image_info* const_image_info_ptr "const struct pt_image_info *"
    51     
    53     
    52     ## functions
    54     ## functions
    53     int pt_image_open (pt_image **image_ptr, pt_ctx *ctx, char *png_path, int cache_mode)
    55     int pt_image_open (pt_image **image_ptr, pt_ctx *ctx, char *png_path, int cache_mode) nogil
    54     int pt_image_info_ "pt_image_info" (pt_image *image, pt_image_info **info_ptr)
    56     int pt_image_info_ "pt_image_info" (pt_image *image, pt_image_info **info_ptr) nogil
    55     int pt_image_status (pt_image *image)
    57     int pt_image_status (pt_image *image) nogil
    56     int pt_image_load (pt_image *image)
    58     int pt_image_load (pt_image *image) nogil
    57     int pt_image_update (pt_image *image, pt_image_params *params)
    59     int pt_image_update (pt_image *image, pt_image_params *params) nogil
    58     int pt_image_tile_file (pt_image *image, pt_tile_info *info, stdio.FILE *out)
    60     int pt_image_tile_file (pt_image *image, pt_tile_info *info, stdio.FILE *out) nogil
    59     int pt_image_tile_mem (pt_image *image, pt_tile_info *info, char **buf_ptr, size_t *len_ptr)
    61     int pt_image_tile_mem (pt_image *image, pt_tile_info *info, char **buf_ptr, size_t *len_ptr) nogil
    60     void pt_image_destroy (pt_image *image)
    62     void pt_image_destroy (pt_image *image) nogil
    61     
    63     
    62     # error code -> name
    64     # error code -> name
    63     char* pt_strerror (int err)
    65     char* pt_strerror (int err)
    64 
    66 
    65 ## constants
    67 ## constants
    72 CACHE_NONE      = PT_CACHE_NONE
    74 CACHE_NONE      = PT_CACHE_NONE
    73 CACHE_STALE     = PT_CACHE_STALE
    75 CACHE_STALE     = PT_CACHE_STALE
    74 CACHE_INCOMPAT  = PT_CACHE_INCOMPAT
    76 CACHE_INCOMPAT  = PT_CACHE_INCOMPAT
    75 
    77 
    76 class Error (BaseException) :
    78 class Error (BaseException) :
    77     pass
    79     """
    78 
    80         Base class for errors raised by pypngtile.
    79 # raise Error if the given return value is <0
    81     """
    80 cdef int trap_err (char *op, int ret) except -1 :
    82 
    81     if ret < 0 :
    83     def __init__ (self, func, err) :
    82         raise Error("%s: %s: %s" % (op, pt_strerror(ret), strerror(errno)))
    84         super(Error, self).__init__("%s: %s: %s" % (func, pt_strerror(err), strerror(errno)))
    83 
       
    84     else :
       
    85         return ret
       
    86 
    85 
    87 cdef class Image :
    86 cdef class Image :
    88     """
    87     """
    89         An image file on disk (.png) and an associated .cache file.
    88         An image file on disk (.png) and an associated .cache file.
    90         
    89         
    99     cdef pt_image *image
    98     cdef pt_image *image
   100 
    99 
   101     
   100     
   102     # open the pt_image
   101     # open the pt_image
   103     def __cinit__ (self, char *path, int mode = 0) :
   102     def __cinit__ (self, char *path, int mode = 0) :
   104         trap_err("pt_image_open", 
   103         cdef int err
   105             pt_image_open(&self.image, NULL, path, mode)
   104         
   106         )
   105         # open
       
   106         with nogil :
       
   107             # XXX: I hope use of path doesn't break...
       
   108             err = pt_image_open(&self.image, NULL, path, mode)
       
   109 
       
   110         if err :
       
   111             raise Error("pt_image_open", err)
   107 
   112 
   108 
   113 
   109     def info (self) :
   114     def info (self) :
   110         """
   115         """
   111             Return a dictionary containing various information about the image.
   116             Return a dictionary containing various information about the image.
   121             cache_mtime         - last modification timestamp for cache file
   126             cache_mtime         - last modification timestamp for cache file
   122             cache_bytes         - size of cache file in bytes
   127             cache_bytes         - size of cache file in bytes
   123             cache_blocks        - size of cache file in disk blocks - 512 bytes / block
   128             cache_blocks        - size of cache file in disk blocks - 512 bytes / block
   124         """
   129         """
   125 
   130 
   126         cdef pt_image_info *info
   131         cdef const_image_info_ptr infop
   127         
   132         cdef int err
   128         trap_err("pt_image_info",
   133 
   129             pt_image_info_(self.image, &info)
   134         with nogil :
   130         )
   135             err = pt_image_info_(self.image, &infop)
   131 
   136 
       
   137         if err :
       
   138             raise Error("pt_image_info", err)
       
   139         
   132         # return as a struct
   140         # return as a struct
   133         return info[0]
   141         return infop[0]
   134 
   142 
   135 
   143 
   136     def status (self) :
   144     def status (self) :
   137         """
   145         """
   138             Return a code describing the status of the underlying cache file.
   146             Return a code describing the status of the underlying cache file.
   141             CACHE_NONE          - the cache file does not exist
   149             CACHE_NONE          - the cache file does not exist
   142             CACHE_STALE         - the cache file exists, but is older than the source image
   150             CACHE_STALE         - the cache file exists, but is older than the source image
   143             CACHE_INCOMPAT      - the cache file exists, but is incompatible with this version of the library
   151             CACHE_INCOMPAT      - the cache file exists, but is incompatible with this version of the library
   144         """
   152         """
   145 
   153 
   146         return trap_err("pt_image_status", 
   154         cdef int ret
   147             pt_image_status(self.image)
   155 
   148         )
   156         with nogil :
   149     
   157             ret = pt_image_status(self.image)
       
   158 
       
   159         if ret :
       
   160             raise Error("pt_image_status", ret)
       
   161         
       
   162         return ret
   150 
   163 
   151     def open (self) :
   164     def open (self) :
   152         """
   165         """
   153             Open the underlying cache file for reading, if available.
   166             Open the underlying cache file for reading, if available.
   154         """
   167         """
   155 
   168 
   156         return trap_err("pt_image_load",
   169         cdef int err
   157             pt_image_load(self.image)
   170 
   158         )
   171         with nogil :
       
   172             err = pt_image_load(self.image)
       
   173 
       
   174         if err :
       
   175             raise Error("pt_image_load", err)
   159 
   176 
   160 
   177 
   161     def update (self, background_color = None) :
   178     def update (self, background_color = None) :
   162         """
   179         """
   163             Update the underlying cache file from the source image.
   180             Update the underlying cache file from the source image.
   167             Requires that the Image was opened using OPEN_UPDATE.
   184             Requires that the Image was opened using OPEN_UPDATE.
   168         """
   185         """
   169 
   186 
   170         cdef pt_image_params params
   187         cdef pt_image_params params
   171         cdef char *bgcolor
   188         cdef char *bgcolor
       
   189         cdef int err
       
   190 
   172         memset(&params, 0, sizeof(params))
   191         memset(&params, 0, sizeof(params))
   173 
   192 
   174         # params
   193         # params
   175         if background_color :
   194         if background_color :
   176             # cast
   195             # cast
   181 
   200 
   182             # decode 
   201             # decode 
   183             memcpy(params.background_color, bgcolor, len(bgcolor))
   202             memcpy(params.background_color, bgcolor, len(bgcolor))
   184     
   203     
   185         # run update
   204         # run update
   186         trap_err("pt_image_update", 
   205         with nogil :
   187             pt_image_update(self.image, &params)
   206             err = pt_image_update(self.image, &params)
   188         )
   207 
       
   208         if err :
       
   209             raise Error("pt_image_update", err)
   189 
   210 
   190 
   211 
   191     def tile_file (self, size_t width, size_t height, size_t x, size_t y, int zoom, object out) :
   212     def tile_file (self, size_t width, size_t height, size_t x, size_t y, int zoom, object out) :
   192         """
   213         """
   193             Render a region of the source image as a PNG tile to the given output file.
   214             Render a region of the source image as a PNG tile to the given output file.
   202             Note that the given file object MUST be a *real* stdio FILE*, not a fake Python object.
   223             Note that the given file object MUST be a *real* stdio FILE*, not a fake Python object.
   203         """
   224         """
   204 
   225 
   205         cdef stdio.FILE *outf
   226         cdef stdio.FILE *outf
   206         cdef pt_tile_info ti
   227         cdef pt_tile_info ti
       
   228         cdef int err
   207 
   229 
   208         memset(&ti, 0, sizeof(ti))
   230         memset(&ti, 0, sizeof(ti))
   209         
   231         
   210         # convert to FILE
   232         # convert to FILE
   211         if not PyFile_Check(out) :
   233         if not PyFile_Check(out) :
   222         ti.x = x
   244         ti.x = x
   223         ti.y = y
   245         ti.y = y
   224         ti.zoom = zoom
   246         ti.zoom = zoom
   225         
   247         
   226         # render
   248         # render
   227         trap_err("pt_image_tile_file", 
   249         with nogil :
   228             pt_image_tile_file(self.image, &ti, outf)
   250             err = pt_image_tile_file(self.image, &ti, outf)
   229         )
   251 
       
   252         if err :
       
   253             raise Error("pt_image_tile_file", err)
   230 
   254 
   231 
   255 
   232     def tile_mem (self, size_t width, size_t height, size_t x, size_t y, int zoom) :
   256     def tile_mem (self, size_t width, size_t height, size_t x, size_t y, int zoom) :
   233         """
   257         """
   234             Render a region of the source image as a PNG tile, and return the PNG data a a string.
   258             Render a region of the source image as a PNG tile, and return the PNG data a a string.
   241         """
   265         """
   242 
   266 
   243         cdef pt_tile_info ti
   267         cdef pt_tile_info ti
   244         cdef char *buf
   268         cdef char *buf
   245         cdef size_t len
   269         cdef size_t len
       
   270         cdef int err
   246         
   271         
   247         memset(&ti, 0, sizeof(ti))
   272         memset(&ti, 0, sizeof(ti))
   248         
   273         
   249         # pack params
   274         # pack params
   250         ti.width = width
   275         ti.width = width
   252         ti.x = x
   277         ti.x = x
   253         ti.y = y
   278         ti.y = y
   254         ti.zoom = zoom
   279         ti.zoom = zoom
   255         
   280         
   256         # render and return via buf/len
   281         # render and return via buf/len
   257         trap_err("pt_image_tile_mem", 
   282         with nogil :
   258             pt_image_tile_mem(self.image, &ti, &buf, &len)
   283             err = pt_image_tile_mem(self.image, &ti, &buf, &len)
   259         )
   284 
       
   285         if err :
       
   286             raise Error("pt_image_tile_mem", err)
   260         
   287         
   261         # copy buffer as str...
   288         # copy buffer as str...
   262         data = python_string.PyString_FromStringAndSize(buf, len)
   289         data = python_string.PyString_FromStringAndSize(buf, len)
   263 
   290 
   264         # drop buffer...
   291         # drop buffer...