Skip to content

Commit

Permalink
WIP context objects
Browse files Browse the repository at this point in the history
  • Loading branch information
tonycoz committed Nov 24, 2012
1 parent 3f35d28 commit 74315ca
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 39 deletions.
2 changes: 1 addition & 1 deletion Makefile.PL
Expand Up @@ -159,7 +159,7 @@ my $OSDEF = "-DOS_$^O";
if ($^O eq 'hpux') { $OSLIBS .= ' -ldld'; }
if (defined $Config{'d_dlsymun'}) { $OSDEF .= ' -DDLSYMUN'; }

my @objs = qw(Imager.o draw.o polygon.o image.o io.o iolayer.o
my @objs = qw(Imager.o context.o draw.o polygon.o image.o io.o iolayer.o
log.o gaussian.o conv.o pnm.o raw.o feat.o font.o combine.o
filters.o dynaload.o stackmach.o datatypes.o
regmach.o trans2.o quant.o error.o convert.o
Expand Down
96 changes: 96 additions & 0 deletions context.c
@@ -0,0 +1,96 @@
#include "imageri.h"

/*
=item im_context_new()
Create a new Imager context object.
=cut
*/

im_context_t
im_context_new(void) {
im_context_t ctx = mymalloc(sizeof(im_context_struct));
int i;

ctx->error_sp = IM_ERROR_COUNT-1;
for (i = 0; i < IM_ERROR_COUNT; ++i) {
ctx->error_alloc[i] = 0;
ctx->error_stack[i].msg = NULL;
ctx->error_stack[i].code = 0;
}
#ifdef IMAGER_LOG
ctx->log_level = 0;
ctx->lg_file = NULL;
#endif

return ctx;
}

/*
=item im_context_delete(ctx)
Release memory used by an Imager context object.
=cut
*/

void
im_context_delete(im_context_t ctx) {
int i;

for (i = 0; i < IM_ERROR_COUNT; ++i) {
if (ctx->error_stack[i].msg)
myfree(ctx->error_stack[i].msg);
}
#ifdef IMAGER_LOG
if (ctx->lg_file)
fclose(ctx->lg_file);
#endif
}

/*
=item im_context_clone(ctx)
Clone an Imager context object, returning the result.
=cut
*/

im_context_t
im_context_clone(im_context_t ctx) {
im_context_t nctx = mymalloc(sizeof(im_context_struct));
int i;

nctx->error_sp = ctx->error_sp;
for (i = 0; i < IM_ERROR_COUNT; ++i) {
if (ctx->error_stack[i].msg) {
size_t sz = ctx->error_alloc[i];
nctx->error_alloc[i] = sz;
nctx->error_stack[i].msg = mymalloc(sz);
memcpy(nctx->error_stack[i].msg, ctx->error_stack[i].msg, sz);
}
else {
nctx->error_alloc[i] = 0;
nctx->error_stack[i].msg = NULL;
}
nctx->error_stack[i].code = ctx->error_stack[i].code;
}
#ifdef IMAGER_LOG
nctx->log_level = ctx->log_level;
if (ctx->lg_file) {
/* disable buffering, this isn't perfect */
setvbuf(ctx->lg_file, NULL, _IONBF, 0);

/* clone that and disable buffering some more */
nctx->lg_file = fdopen(fileno(ctx->lg_file), "a");
if (nctx->lg_file)
setvbuf(nctx->lg_file, NULL, _IONBF, 0);
}
else {
ctx->lg_file = NULL;
}
#endif

return ctx;
}
95 changes: 58 additions & 37 deletions error.c
Expand Up @@ -61,25 +61,15 @@ C). The Perl level won't use all of this.
=cut
*/

#include "imager.h"
#include "imageri.h"
#include <stdio.h>
#include <stdlib.h>

/* we never actually use the last item - it's the NULL terminator */
#define ERRSTK 20
static i_errmsg error_stack[ERRSTK];
static int error_sp = ERRSTK - 1;
/* we track the amount of space used each string, so we don't reallocate
space unless we need to.
This also means that a memory tracking library may see the memory
allocated for this as a leak. */
static int error_space[ERRSTK];

#if 0
static i_error_cb error_cb;
static i_failed_cb failed_cb;
static int failures_fatal;
static char *argv0;

/*
=item i_set_argv0(char const *program)
Expand Down Expand Up @@ -157,6 +147,8 @@ i_failed_cb i_set_failed_cb(i_failed_cb cb) {
return old;
}

#endif

/*
=item i_errors()
Expand All @@ -165,8 +157,12 @@ terminated by a NULL pointer. The highest level message is first.
=cut
*/
i_errmsg *i_errors() {
return error_stack + error_sp;
i_errmsg *im_errors(im_context_t ctx) {
return ctx->error_stack + ctx->error_sp;
}

i_errmsg *i_errors(void) {
return im_errors(im_get_context());
}

/*
Expand All @@ -192,19 +188,26 @@ Called by any Imager function before doing any other processing.
=cut
*/
void i_clear_error() {

void
im_clear_error(im_context_t ctx) {
#ifdef IMAGER_DEBUG_MALLOC
int i;

for (i = 0; i < ERRSTK; ++i) {
if (error_space[i]) {
myfree(error_stack[i].msg);
error_stack[i].msg = NULL;
error_space[i] = 0;
for (i = 0; i < IM_ERROR_COUNT; ++i) {
if (ctx->error_space[i]) {
myfree(ctx->error_stack[i].msg);
ctx->error_stack[i].msg = NULL;
ctx->error_space[i] = 0;
}
}
#endif
error_sp = ERRSTK-1;
ctx->error_sp = IM_ERROR_COUNT-1;
}

void
i_clear_error(void) {
im_clear_error(im_get_context());
}

/*
Expand All @@ -221,29 +224,32 @@ error handling is calling function that does.).
=cut
*/
void i_push_error(int code, char const *msg) {
void
im_push_error(im_context_t ctx, int code, char const *msg) {
size_t size = strlen(msg)+1;

if (error_sp <= 0)
if (ctx->error_sp <= 0)
/* bad, bad programmer */
return;

--error_sp;
if (error_space[error_sp] < size) {
if (error_stack[error_sp].msg)
myfree(error_stack[error_sp].msg);
--ctx->error_sp;
if (ctx->error_alloc[ctx->error_sp] < size) {
if (ctx->error_stack[ctx->error_sp].msg)
myfree(ctx->error_stack[ctx->error_sp].msg);
/* memory allocated on the following line is only ever released when
we need a bigger string */
/* size is size (len+1) of an existing string, overflow would mean
the system is broken anyway */
error_stack[error_sp].msg = mymalloc(size); /* checked 17jul05 tonyc */
error_space[error_sp] = size;
ctx->error_stack[ctx->error_sp].msg = mymalloc(size); /* checked 17jul05 tonyc */
ctx->error_alloc[ctx->error_sp] = size;
}
strcpy(error_stack[error_sp].msg, msg);
error_stack[error_sp].code = code;
strcpy(ctx->error_stack[ctx->error_sp].msg, msg);
ctx->error_stack[ctx->error_sp].code = code;
}

if (error_cb)
error_cb(code, msg);
void
i_push_error(int code, char const *msg) {
im_push_error(im_get_context(), code, msg);
}

/*
Expand All @@ -258,7 +264,8 @@ Does not support perl specific format codes.
=cut
*/
void i_push_errorvf(int code, char const *fmt, va_list ap) {
void
im_push_errorvf(im_context_t ctx, int code, char const *fmt, va_list ap) {
char buf[1024];
#if defined(IMAGER_VSNPRINTF)
vsnprintf(buf, sizeof(buf), fmt, ap);
Expand All @@ -271,7 +278,12 @@ void i_push_errorvf(int code, char const *fmt, va_list ap) {
*/
vsprintf(buf, fmt, ap);
#endif
i_push_error(code, buf);
im_push_error(ctx, code, buf);
}

void
i_push_errorvf(int code, char const *fmt, va_list ap) {
im_push_errorvf(im_get_context(), code, fmt, ap);
}

/*
Expand All @@ -285,13 +297,22 @@ Does not support perl specific format codes.
=cut
*/
void i_push_errorf(int code, char const *fmt, ...) {
void
i_push_errorf(int code, char const *fmt, ...) {
va_list ap;
va_start(ap, fmt);
i_push_errorvf(code, fmt, ap);
va_end(ap);
}

void
im_push_errorf(im_context_t ctx, int code, char const *fmt, ...) {
va_list ap;
va_start(ap, fmt);
im_push_errorvf(ctx, code, fmt, ap);
va_end(ap);
}

#ifdef IMAGER_I_FAILED
#error "This isn't used and is untested"

Expand Down Expand Up @@ -369,7 +390,7 @@ void
im_assert_fail(char const *file, int line, char const *message) {
fprintf(stderr, "Assertion failed line %d file %s: %s\n",
line, file, message);
exit(EXIT_FAILURE);
abort();
}

/*
Expand Down
4 changes: 4 additions & 0 deletions imager.h
Expand Up @@ -452,6 +452,10 @@ extern int
i_gsampf_bg(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samples,
int out_channels, i_fcolor const *bg);

extern im_context_t (*im_get_context)(void);

#define aIMCTX (im_get_context())

#include "imio.h"

#endif
11 changes: 11 additions & 0 deletions imageri.h
Expand Up @@ -111,4 +111,15 @@ i_img_dim i_abs(i_img_dim x);

#define color_to_grey(col) ((col)->rgb.r * 0.222 + (col)->rgb.g * 0.707 + (col)->rgb.b * 0.071)

#define IM_ERROR_COUNT 20
typedef struct im_context_tag {
int error_sp;
size_t error_alloc[IM_ERROR_COUNT];
i_errmsg error_stack[IM_ERROR_COUNT];
#ifdef IMAGER_LOG
int log_level;
FILE *lg_file;
#endif
} im_context_struct;

#endif
2 changes: 2 additions & 0 deletions imdatatypes.h
Expand Up @@ -6,6 +6,8 @@

#define MAXCHANNELS 4

typedef struct im_context_tag *im_context_t;

/* used for palette indices in some internal code (which might be
exposed at some point
*/
Expand Down
1 change: 0 additions & 1 deletion imext.h
Expand Up @@ -262,5 +262,4 @@ extern im_ext_funcs *imager_function_ext_table;
#define mm_log(x)
#endif


#endif
8 changes: 8 additions & 0 deletions immacros.h
Expand Up @@ -75,4 +75,12 @@ returns -1 and pushes an error.
#define i_psampf(im, l, r, y, samps, chans, count) \
(((im)->i_f_psampf)((im), (l), (r), (y), (samps), (chans), (count)))

#ifdef IMAGER_NO_CONTEXT
#define dIMCTX im_context_t my_im_ctx = im_get_context()
#define dIMCTXa(a) im_context_t my_im_ctx = im_get_context()
#define aIMCTX my_im_ctx
#else
#define aIMCTX im_get_context()
#endif

#endif

0 comments on commit 74315ca

Please sign in to comment.