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. |
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, ¶ms) |
206 err = pt_image_update(self.image, ¶ms) |
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. |
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... |