author | Tero Marttila <terom@fixme.fi> |
Sun, 24 Jan 2010 23:20:39 +0200 | |
changeset 55 | a3542e78ecd8 |
parent 21 | 47f15166e25a |
child 56 | d5e3089906da |
permissions | -rw-r--r-- |
18 | 1 |
#include "tile.h" |
2 |
#include "error.h" |
|
3 |
#include "shared/log.h" // only FATAL |
|
4 |
||
5 |
#include <stdlib.h> |
|
6 |
||
19
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
7 |
int pt_tile_new (struct pt_tile **tile_ptr) |
18 | 8 |
{ |
19
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
9 |
struct pt_tile *tile; |
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
10 |
|
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
11 |
if ((tile = calloc(1, sizeof(*tile))) == NULL) |
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
12 |
return -PT_ERR_MEM; |
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
13 |
|
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
14 |
*tile_ptr = tile; |
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
15 |
|
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
16 |
return 0; |
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
17 |
} |
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
18 |
|
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
19 |
static void pt_tile_init (struct pt_tile *tile, struct pt_cache *cache, const struct pt_tile_info *info, enum pt_tile_output out_type) |
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
20 |
{ |
18 | 21 |
// init |
19
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
22 |
tile->cache = cache; |
18 | 23 |
tile->info = *info; |
24 |
tile->out_type = out_type; |
|
25 |
} |
|
26 |
||
19
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
27 |
int pt_tile_init_file (struct pt_tile *tile, struct pt_cache *cache, const struct pt_tile_info *info, FILE *out) |
18 | 28 |
{ |
19
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
29 |
pt_tile_init(tile, cache, info, PT_TILE_OUT_FILE); |
18 | 30 |
|
31 |
tile->out.file = out; |
|
32 |
||
33 |
return 0; |
|
34 |
} |
|
35 |
||
19
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
36 |
int pt_tile_init_mem (struct pt_tile *tile, struct pt_cache *cache, const struct pt_tile_info *info) |
18 | 37 |
{ |
19
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
38 |
pt_tile_init(tile, cache, info, PT_TILE_OUT_MEM); |
18 | 39 |
|
40 |
// init buffer |
|
41 |
if ((tile->out.mem.base = malloc(PT_TILE_BUF_SIZE)) == NULL) |
|
42 |
RETURN_ERROR(PT_ERR_MEM); |
|
43 |
||
44 |
tile->out.mem.len = PT_TILE_BUF_SIZE; |
|
45 |
tile->out.mem.off = 0; |
|
46 |
||
47 |
return 0; |
|
48 |
} |
|
49 |
||
50 |
static void pt_tile_mem_write (png_structp png, png_bytep data, png_size_t length) |
|
51 |
{ |
|
52 |
struct pt_tile_mem *buf = png_get_io_ptr(png); |
|
53 |
size_t buf_len = buf->len; |
|
54 |
||
55 |
// grow? |
|
56 |
while (buf->off + length > buf_len) |
|
57 |
buf_len *= 2; |
|
58 |
||
59 |
if (buf_len != buf->len) { |
|
60 |
char *tmp; |
|
61 |
||
62 |
if ((tmp = realloc(buf->base, buf_len)) == NULL) |
|
63 |
png_error(png, "pt_tile_buf_write - realloc failed"); |
|
64 |
||
65 |
buf->base = tmp; |
|
66 |
buf->len = buf_len; |
|
67 |
} |
|
68 |
||
69 |
// copy |
|
70 |
memcpy(buf->base + buf->off, data, length); |
|
71 |
||
72 |
buf->off += length; |
|
73 |
} |
|
74 |
||
75 |
static void pt_tile_mem_flush (png_structp png_ptr) |
|
76 |
{ |
|
77 |
// no-op |
|
78 |
} |
|
79 |
||
80 |
||
19
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
81 |
int pt_tile_render (struct pt_tile *tile) |
18 | 82 |
{ |
83 |
png_structp png = NULL; |
|
84 |
png_infop info = NULL; |
|
85 |
int err = 0; |
|
86 |
||
87 |
// open PNG writer |
|
88 |
if ((png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)) == NULL) |
|
89 |
JUMP_SET_ERROR(err, PT_ERR_PNG_CREATE); |
|
90 |
||
91 |
if ((info = png_create_info_struct(png)) == NULL) |
|
92 |
JUMP_SET_ERROR(err, PT_ERR_PNG_CREATE); |
|
93 |
||
94 |
// libpng error trap |
|
95 |
if (setjmp(png_jmpbuf(png))) |
|
96 |
JUMP_SET_ERROR(err, PT_ERR_PNG); |
|
97 |
||
98 |
// setup output I/O |
|
99 |
switch (tile->out_type) { |
|
100 |
case PT_TILE_OUT_FILE: |
|
101 |
// use default FILE* operation |
|
102 |
png_init_io(png, tile->out.file); |
|
103 |
||
104 |
break; |
|
105 |
||
106 |
case PT_TILE_OUT_MEM: |
|
107 |
// use pt_tile_mem struct via pt_tile_mem_* callbacks |
|
108 |
png_set_write_fn(png, &tile->out.mem, pt_tile_mem_write, pt_tile_mem_flush); |
|
109 |
||
110 |
break; |
|
111 |
||
112 |
default: |
|
113 |
FATAL("tile->out_type: %d", tile->out_type); |
|
114 |
} |
|
115 |
||
116 |
// render tile |
|
19
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
117 |
if ((err = pt_cache_tile_png(tile->cache, png, info, &tile->info))) |
18 | 118 |
JUMP_ERROR(err); |
119 |
||
120 |
// done |
|
121 |
png_write_end(png, info); |
|
122 |
||
123 |
error: |
|
124 |
// cleanup |
|
125 |
png_destroy_write_struct(&png, &info); |
|
126 |
||
127 |
return err; |
|
128 |
} |
|
129 |
||
130 |
void pt_tile_abort (struct pt_tile *tile) |
|
131 |
{ |
|
132 |
// cleanup |
|
133 |
switch (tile->out_type) { |
|
134 |
case PT_TILE_OUT_FILE: |
|
135 |
// no-op |
|
136 |
break; |
|
137 |
||
138 |
case PT_TILE_OUT_MEM: |
|
139 |
// drop buffer |
|
140 |
free(tile->out.mem.base); |
|
141 |
||
142 |
break; |
|
143 |
} |
|
144 |
} |
|
145 |
||
19
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
146 |
void pt_tile_destroy (struct pt_tile *tile) |
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
147 |
{ |
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
148 |
pt_tile_abort(tile); |
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
149 |
|
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
150 |
free(tile); |
ebcc49de97d0
implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
151 |
} |
21 | 152 |