--- a/render_slices.c Mon Jun 09 18:58:39 2008 +0300
+++ b/render_slices.c Tue Jun 17 16:39:55 2008 +0300
@@ -13,16 +13,13 @@
free(ctx);
}
-int render_slices_deinit (struct render_slices *ctx) {
- // if it's not initialized, just ignore
- if (!ctx->rowbuf)
- return 1;
-
- free(ctx->rowbuf);
+void render_slices_deinit (struct render_slices *ctx) {
+ if (ctx->rowbuf) {
+ free(ctx->rowbuf);
+ ctx->rowbuf = NULL;
+ }
render_png_deinit(&ctx->png_info);
-
- return 0;
}
#define HALF(a, b) (( a + b) / 2)
@@ -113,41 +110,40 @@
int render_slices_segment_done (struct render_slices *ctx, int index) {
assert(index >= 0 && index < ctx->num_slices);
+ assert(ctx->render_row >= 0);
+ assert(ctx->segments_done >= 0 && ctx->segments_done < ctx->num_slices);
// our return status
- int status = 0;
+ int i, status = 0;
- // keep track of the number of full segments in this row
- ctx->segments_done++;
-
- // is this row complete?
- if (ctx->segments_done == ctx->num_slices) {
+ // is this row now complete?
+ if (++ctx->segments_done == ctx->num_slices) {
// the row is complete
ctx->segments_done = 0;
// once we fill up a row we can always call process_row
status |= SLICE_PROCESS_ROW;
- // is the other row still waiting for it to get processed?
+ // is the other row already rendered?
if (ctx->done_row < 0) {
- // no, point the done_row at this row, point the render buffers to the unused row
+ // yes, point the done_row at this row, point the render buffers to the unused row
ctx->done_row = ctx->render_row;
ctx->render_row = (ctx->render_row == 0 ? 1 : 0);
- int i ;
-
+ // can now continue rendering as well as call process_row
+ status |= SLICE_CONTINUE;
+
// update the remaining render buffers
for (i = 0; i < ctx->num_slices; i++) {
ctx->slices[i].info.render_buf = ctx->rows[ctx->render_row] + ctx->slices[i].row_offset;
}
-
- // can now continue rendering as well as call process_row
- status |= SLICE_CONTINUE;
} else {
// cannot continue rendering, need to have process_row complete first
+
+ ctx->render_row = -1;
+ }
- }
} else {
// the row is not complete, do not render the next segment, do not call process_row
@@ -160,15 +156,39 @@
int render_slices_process_row (struct render_slices *ctx) {
assert(ctx->done_row >= 0);
+ int i;
+
// pass the data to render_png, this results in calls to _render_multi_png_data
if (render_png_row(&ctx->png_info, ctx->rows[ctx->done_row]))
ERROR("render_png_row");
- // mark the row as processed
- ctx->done_row = -1;
-
- // ok, but don't call me again until I tell you to.
- return SLICE_CONTINUE;
+ // is the other row still in the process of being assembled?
+ if (ctx->render_row == -1) {
+ // no, both rows were full
+ ctx->render_row = ctx->done_row;
+ ctx->done_row = (ctx->done_row == 0 ? 1 : 0);
+
+ // update the remaining render buffers
+ for (i = 0; i < ctx->num_slices; i++) {
+ ctx->slices[i].info.render_buf = ctx->rows[ctx->render_row] + ctx->slices[i].row_offset;
+ }
+
+ // you can call me again, but also segment_done
+ return SLICE_PROCESS_ROW | SLICE_CONTINUE;
+
+ } else {
+ // yes, so that still needs to be finished
+ ctx->done_row = -1;
+
+ if (ctx->segments_done == 0) {
+ // that row is empty, then we can continue
+ return SLICE_CONTINUE;
+
+ } else {
+ // that row is partially built, so some segment is still on the way - don't resume the other slices until that's arrived!
+ return 0;
+ }
+ }
error:
// user needs to deinit/free us
@@ -178,7 +198,7 @@
int render_slices_done (struct render_slices *ctx) {
// finish off render_png
if (render_png_done(&ctx->png_info))
- ERROR("render_png_done");
+ goto error;
return 0;
@@ -186,3 +206,4 @@
render_slices_free(ctx);
return -1;
}
+