use stdc malloc instead of mymalloc()
[imager.git] / context.c
CommitLineData
74315ca9 1#include "imageri.h"
31a13473 2#include <stdio.h>
74315ca9
TC
3
4/*
5=item im_context_new()
6
7Create a new Imager context object.
8
9=cut
10*/
11
12im_context_t
13im_context_new(void) {
cf8c77ae 14 im_context_t ctx = malloc(sizeof(im_context_struct));
74315ca9
TC
15 int i;
16
cf8c77ae
TC
17 if (!ctx)
18 return NULL;
19
74315ca9
TC
20 ctx->error_sp = IM_ERROR_COUNT-1;
21 for (i = 0; i < IM_ERROR_COUNT; ++i) {
22 ctx->error_alloc[i] = 0;
23 ctx->error_stack[i].msg = NULL;
24 ctx->error_stack[i].code = 0;
25 }
26#ifdef IMAGER_LOG
27 ctx->log_level = 0;
28 ctx->lg_file = NULL;
29#endif
44d86483
TC
30 ctx->max_width = 0;
31 ctx->max_height = 0;
cf8c77ae 32 ctx->max_bytes = DEF_BYTES_LIMIT;
74315ca9 33
31a13473
TC
34 ctx->refcount = 1;
35
36#ifdef IMAGER_TRACE_CONTEXT
37 fprintf(stderr, "im_context: created %p\n", ctx);
38#endif
39
74315ca9
TC
40 return ctx;
41}
42
43/*
31a13473 44=item im_context_refinc(ctx, where)
abffffed
TC
45X<im_context_refinc API>
46=section Context objects
47=synopsis im_context_refinc(aIMCTX, "a description");
31a13473
TC
48
49Add a new reference to the context.
50
51=cut
52*/
53
54void
55im_context_refinc(im_context_t ctx, const char *where) {
56 ++ctx->refcount;
57
58#ifdef IMAGER_TRACE_CONTEXT
59 fprintf(stderr, "im_context:%s: refinc %p (count now %lu)\n", where,
60 ctx, (unsigned long)ctx->refcount);
61#endif
62}
63
64/*
abffffed
TC
65=item im_context_refdec(ctx, where)
66X<im_context_refdec API>
67=section Context objects
68=synopsis im_context_refdec(aIMCTX, "a description");
74315ca9 69
abffffed
TC
70Remove a reference to the context, releasing it if all references have
71been removed.
74315ca9
TC
72
73=cut
74*/
75
76void
31a13473 77im_context_refdec(im_context_t ctx, const char *where) {
74315ca9
TC
78 int i;
79
31a13473
TC
80 im_assert(ctx->refcount > 0);
81
82 --ctx->refcount;
83
84#ifdef IMAGER_TRACE_CONTEXT
85 fprintf(stderr, "im_context:%s: delete %p (count now %lu)\n", where,
86 ctx, (unsigned long)ctx->refcount);
87#endif
88
89 if (ctx->refcount != 0)
90 return;
91
74315ca9
TC
92 for (i = 0; i < IM_ERROR_COUNT; ++i) {
93 if (ctx->error_stack[i].msg)
94 myfree(ctx->error_stack[i].msg);
95 }
96#ifdef IMAGER_LOG
97 if (ctx->lg_file)
98 fclose(ctx->lg_file);
99#endif
cf8c77ae
TC
100
101 free(ctx);
74315ca9
TC
102}
103
104/*
105=item im_context_clone(ctx)
106
107Clone an Imager context object, returning the result.
108
109=cut
110*/
111
112im_context_t
31a13473 113im_context_clone(im_context_t ctx, const char *where) {
cf8c77ae 114 im_context_t nctx = malloc(sizeof(im_context_struct));
74315ca9
TC
115 int i;
116
cf8c77ae
TC
117 if (!nctx)
118 return NULL;
119
74315ca9
TC
120 nctx->error_sp = ctx->error_sp;
121 for (i = 0; i < IM_ERROR_COUNT; ++i) {
122 if (ctx->error_stack[i].msg) {
123 size_t sz = ctx->error_alloc[i];
124 nctx->error_alloc[i] = sz;
125 nctx->error_stack[i].msg = mymalloc(sz);
126 memcpy(nctx->error_stack[i].msg, ctx->error_stack[i].msg, sz);
127 }
128 else {
129 nctx->error_alloc[i] = 0;
130 nctx->error_stack[i].msg = NULL;
131 }
132 nctx->error_stack[i].code = ctx->error_stack[i].code;
133 }
134#ifdef IMAGER_LOG
135 nctx->log_level = ctx->log_level;
136 if (ctx->lg_file) {
137 /* disable buffering, this isn't perfect */
138 setvbuf(ctx->lg_file, NULL, _IONBF, 0);
139
140 /* clone that and disable buffering some more */
141 nctx->lg_file = fdopen(fileno(ctx->lg_file), "a");
142 if (nctx->lg_file)
143 setvbuf(nctx->lg_file, NULL, _IONBF, 0);
144 }
145 else {
44d86483 146 nctx->lg_file = NULL;
74315ca9
TC
147 }
148#endif
44d86483
TC
149 nctx->max_width = ctx->max_width;
150 nctx->max_height = ctx->max_height;
151 nctx->max_bytes = ctx->max_bytes;
31a13473 152 nctx->refcount = 1;
74315ca9 153
31a13473
TC
154#ifdef IMAGER_TRACE_CONTEXT
155 fprintf(stderr, "im_context:%s: cloned %p to %p\n", where, ctx, nctx);
156#endif
157
158 return nctx;
74315ca9 159}