mandelbrot.c
changeset 11 082bfaf38cf0
parent 3 675be0a45157
--- 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;