--- a/mandelbrot.c Fri Jun 06 16:05:26 2008 +0300
+++ b/mandelbrot.c Fri Jun 06 18:35:46 2008 +0300
@@ -1,9 +1,7 @@
#include <stdlib.h>
#include <time.h>
-#include <png.h>
-
-#include "render.h"
+#include "render_internal.h"
#include "mandelbrot.h"
#include "common.h"
@@ -11,97 +9,17 @@
#define absdelta(a, b) (a>b ? a-b : b-a)
-void user_write_data(png_structp png_ptr, png_bytep data, png_size_t length) {
- struct render_ctx *ctx = (struct render_ctx *) png_get_io_ptr(png_ptr);
-
- if (ctx->io_write_fn)
- switch (ctx->io_write_fn(data, length, ctx->io_cb_arg)) {
- case RENDER_CB_ERR :
- ctx->io_error = 1;
- break;
-
- case RENDER_CB_OK :
- // great!
- break;
- }
-}
-
-void user_flush_data(png_structp png_ptr) {
- struct render_ctx *ctx = (struct render_ctx *) png_get_io_ptr(png_ptr);
-
- if (ctx->io_flush_fn)
- switch (ctx->io_flush_fn(ctx->io_cb_arg)) {
- case RENDER_CB_ERR :
- ctx->io_error = 1;
- break;
-
- case RENDER_CB_OK :
- // great!
- break;
- }
-}
-
-int mandelbrot_render (render_t *ctx) {
- // libpng handles
- png_structp png_ptr = NULL;
- png_infop info_ptr = NULL;
-
+int render_mandelbrot (struct render *ctx) {
// render algorithm vars
u_int32_t img_x, img_y;
double x0, y0, x, y, _x, _y, w_scale, h_scale;
u_int8_t iter;
u_int8_t *row;
- // clear out any potential error in ctx
- ctx->io_error = 0;
-
// calcluate the scale factors
w_scale = ctx->img_w/absdelta(ctx->x1, ctx->x2);
h_scale = ctx->img_h/absdelta(ctx->y1, ctx->y2);
- // malloc the memory used to render each row
- row = (u_int8_t *) malloc(ctx->img_w);
-
- if (!row)
- goto error;
-
- // PNG or not?
- if (ctx->mode == RENDER_PNG) {
- // libpng initialization
- png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-
- if (!png_ptr)
- goto error;
-
- info_ptr = png_create_info_struct(png_ptr);
-
- if (!info_ptr)
- goto error;
-
- // libpng error handling
- if (setjmp(png_jmpbuf(png_ptr))) {
- goto error;
- }
-
- if (ctx->io_stream) {
- // use normal libpng I/O
- png_init_io(png_ptr, ctx->io_stream);
- } else {
- // setup our custom I/O callbacks
- png_set_write_fn(png_ptr, ctx, &user_write_data, &user_flush_data);
- }
-
- // some PNG metadata
- png_set_IHDR(png_ptr, info_ptr, ctx->img_w, ctx->img_h, 8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
-
- // write out the PNG header
- png_write_info(png_ptr, info_ptr);
-
- // possible error return
- if (ctx->io_error)
- goto error;
- }
-
// start rendering!
for (img_y=0; img_y < ctx->img_h; img_y++) {
// render the current row
@@ -122,56 +40,24 @@
iter--;
}
- row[img_x] = iter;
+ (*ctx->local_rowbuf_addr)[img_x] = iter;
}
-
- if (ctx->mode == RENDER_PNG) {
- // write the raw pixels to libpng
- png_write_row(png_ptr, row);
-
- // check for user errors return
- if (ctx->io_error)
- goto error;
- } else {
- // pass on the pixels to the io callback
- if (ctx->io_write_fn(row, ctx->img_w, ctx->io_cb_arg) == RENDER_CB_ERR) {
- ctx->io_error = 1;
- goto error;
- }
- }
+
+ // row cb
+ if (ctx->local_row_fn(ctx->cb_arg, (*ctx->local_rowbuf_addr)))
+ ERROR("local_row_fn");
}
- if (ctx->mode == RENDER_PNG) {
- // finished writing
- png_write_end(png_ptr, info_ptr);
- }
-
- // clean up
- png_destroy_write_struct(&png_ptr, &info_ptr);
- free(row); row = NULL;
-
- // check for user errors return
- if (ctx->io_error)
- goto error;
-
// return succesfully
- return MANDELBROT_OK;
+ return 0;
error:
- if (png_ptr || info_ptr)
- png_destroy_write_struct(&png_ptr, &info_ptr);
-
- if (row)
- free(row);
-
- row = NULL;
-
- return MANDELBROT_ERR;
+ return -1;
}
-int mandelbrot_render_timed (render_t *ctx, double *duration) {
+int render_mandelbrot_timed (struct render *ctx, double *duration) {
clock_t t1 = clock();
- int ret = mandelbrot_render(ctx);
+ int ret = render_mandelbrot(ctx);
clock_t t2 = clock();
*duration = ((double)(t2 - t1))/CLOCKS_PER_SEC;