terom@18: #include "tile.h" terom@18: #include "error.h" terom@18: #include "shared/log.h" // only FATAL terom@18: terom@18: #include terom@56: #include terom@56: terom@56: int pt_tile_mem_write (struct pt_tile_mem *buf, void *data, size_t len) terom@56: { terom@56: size_t buf_len = buf->len; terom@56: terom@56: // grow? terom@56: while (buf->off + len > buf_len) terom@56: buf_len *= 2; terom@56: terom@56: if (buf_len != buf->len) { terom@56: char *tmp; terom@56: terom@56: if ((tmp = realloc(buf->base, buf_len)) == NULL) terom@56: RETURN_ERROR(PT_ERR_MEM); terom@56: terom@56: buf->base = tmp; terom@56: buf->len = buf_len; terom@56: } terom@56: terom@56: // copy terom@56: memcpy(buf->base + buf->off, data, len); terom@56: terom@56: buf->off += len; terom@56: terom@56: return 0; terom@56: } terom@56: terom@18: terom@19: int pt_tile_new (struct pt_tile **tile_ptr) terom@18: { terom@19: struct pt_tile *tile; terom@19: terom@19: if ((tile = calloc(1, sizeof(*tile))) == NULL) terom@19: return -PT_ERR_MEM; terom@19: terom@19: *tile_ptr = tile; terom@19: terom@19: return 0; terom@19: } terom@19: terom@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) terom@19: { terom@18: // init terom@19: tile->cache = cache; terom@18: tile->info = *info; terom@18: tile->out_type = out_type; terom@18: } terom@18: terom@19: int pt_tile_init_file (struct pt_tile *tile, struct pt_cache *cache, const struct pt_tile_info *info, FILE *out) terom@18: { terom@19: pt_tile_init(tile, cache, info, PT_TILE_OUT_FILE); terom@18: terom@18: tile->out.file = out; terom@18: terom@18: return 0; terom@18: } terom@18: terom@19: int pt_tile_init_mem (struct pt_tile *tile, struct pt_cache *cache, const struct pt_tile_info *info) terom@18: { terom@19: pt_tile_init(tile, cache, info, PT_TILE_OUT_MEM); terom@18: terom@18: // init buffer terom@18: if ((tile->out.mem.base = malloc(PT_TILE_BUF_SIZE)) == NULL) terom@18: RETURN_ERROR(PT_ERR_MEM); terom@18: terom@18: tile->out.mem.len = PT_TILE_BUF_SIZE; terom@18: tile->out.mem.off = 0; terom@18: terom@18: return 0; terom@18: } terom@18: terom@18: terom@19: int pt_tile_render (struct pt_tile *tile) terom@18: { terom@86: // validate dimensions terom@86: if (!tile->info.width || !tile->info.height) terom@86: RETURN_ERROR(PT_ERR_TILE_DIM); terom@86: terom@56: return pt_cache_tile(tile->cache, tile); terom@18: } terom@18: terom@18: void pt_tile_abort (struct pt_tile *tile) terom@18: { terom@18: // cleanup terom@18: switch (tile->out_type) { terom@18: case PT_TILE_OUT_FILE: terom@18: // no-op terom@18: break; terom@18: terom@18: case PT_TILE_OUT_MEM: terom@18: // drop buffer terom@18: free(tile->out.mem.base); terom@18: terom@18: break; terom@18: } terom@18: } terom@18: terom@19: void pt_tile_destroy (struct pt_tile *tile) terom@19: { terom@19: pt_tile_abort(tile); terom@19: terom@19: free(tile); terom@19: } terom@21: