render_local.c
author Tero Marttila <terom@fixme.fi>
Sat, 30 Aug 2008 19:13:15 +0300
changeset 49 10c7dce1a043
parent 24 8307d28329ae
permissions -rw-r--r--
autogenerate the memcache_test help output, and pipeline memcache requests
#include <stdlib.h>
#include <time.h>
#include <assert.h>

#include "common.h"
#include "render_struct.h"
#include "render_local.h"
#include "render_png.h"
#include "render_raw.h"
#include "render_mandelbrot.h"

int render_local (struct render *render, double *duration) {
    struct render_local ctx;
    
    if (render_local_init(&ctx, render))
        return -1;
        
    int err = render_local_run(&ctx, duration);

    render_local_deinit(&ctx);

    return err;
}

int render_local_init (struct render_local *ctx, struct render *render) {
    // zero
    memset(ctx, 0, sizeof(*ctx));

    ctx->render_info = render;

    // alloc the memory buffer
    if (!(ctx->rowbuf = malloc(render->img_w)))
        ERROR("malloc");
 
    // what mode?
    switch (render->mode) {
        case RENDER_PNG :
            // the render_png stuff
            memset(&ctx->png_ctx, 0, sizeof(ctx->png_ctx));

            if (render_png_init(&ctx->png_ctx, render))
                ERROR("render_png_init");
            
            ctx->must_deinit = RENDER_PNG;

            //  set render_* to use the render_png
            if (render_local_mem(render, &ctx->rowbuf, (int(*)(void *arg, unsigned char *)) &render_png_row, &ctx->png_ctx))
                ERROR("render_local_mem");

            break;

        case RENDER_RAW :
            // the render_raw stuff
            memset(&ctx->raw_ctx, 0, sizeof(ctx->raw_ctx));

            if (render_raw_init(&ctx->raw_ctx, render))
                ERROR("render_raw_init");
            
            ctx->must_deinit = RENDER_RAW;

            //  set render_* to use the render_raw
            if (render_local_mem(render, &ctx->rowbuf, (int(*)(void *arg, unsigned char *)) &render_raw_row, &ctx->raw_ctx))
                ERROR("render_local_mem");

            break;

        default :
            assert(0);
    }
    
    // success
    return 0;

error:
    render_local_deinit(ctx);

    return -1;
}

int render_local_run (struct render_local *ctx, double *duration) {
    clock_t t1, t2;
    
    if (duration)
        *duration = -1;

    // then we can actually render
    t1 = clock();

    if (render_mandelbrot(ctx->render_info))
        goto error;

    t2 = clock();

    // flush the PNG
    if (render_png_done(&ctx->png_ctx))
        goto error;
    
    // calculate the time taken
    if (duration)
        *duration = ((double)(t2 - t1))/CLOCKS_PER_SEC;

    // success
    return 0;

error:
    // caller must deinit
    //
    return -1;
}

void render_local_deinit (struct render_local *ctx) {
    free(ctx->rowbuf);
    
    if (ctx->must_deinit == RENDER_PNG)
        render_png_deinit(&ctx->png_ctx);

    else if (ctx->must_deinit == RENDER_RAW)
        render_raw_deinit(&ctx->raw_ctx);
}