summaryrefslogtreecommitdiffstats
path: root/libdimension
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2010-04-07 14:26:15 -0400
committerTavian Barnes <tavianator@gmail.com>2010-04-07 14:34:52 -0400
commit2b087cb45ae91f90492a935625570d7d42ee3ecb (patch)
treea464213b08d04c8c91c8879a84e534f895c84378 /libdimension
parent7d6663eeb68bf9d0a3dff86128827c0c1d85df69 (diff)
downloaddimension-2b087cb45ae91f90492a935625570d7d42ee3ecb.tar.xz
New dmnsn_malloc() function, and friends.
I'm tired of checking for malloc failures everywhere, considering it never happens. So just bail out whenever it does. A lot of stuff is guaranteed to succeed if it returns now.
Diffstat (limited to 'libdimension')
-rw-r--r--libdimension/Makefile.am2
-rw-r--r--libdimension/ambient.c20
-rw-r--r--libdimension/bvst.c13
-rw-r--r--libdimension/camera.c9
-rw-r--r--libdimension/canvas.c27
-rw-r--r--libdimension/csg.c248
-rw-r--r--libdimension/cube.c13
-rw-r--r--libdimension/diffuse.c19
-rw-r--r--libdimension/dimension.h1
-rw-r--r--libdimension/dimension/array.h32
-rw-r--r--libdimension/dimension/malloc.h31
-rw-r--r--libdimension/dimension/raytrace.h2
-rw-r--r--libdimension/error.c5
-rw-r--r--libdimension/finish_combination.c65
-rw-r--r--libdimension/gl.c23
-rw-r--r--libdimension/interior.c11
-rw-r--r--libdimension/light.c13
-rw-r--r--libdimension/malloc.c50
-rw-r--r--libdimension/object.c22
-rw-r--r--libdimension/perspective.c21
-rw-r--r--libdimension/phong.c21
-rw-r--r--libdimension/png.c118
-rw-r--r--libdimension/point_light.c22
-rw-r--r--libdimension/progress.c67
-rw-r--r--libdimension/raytrace.c125
-rw-r--r--libdimension/reflective.c24
-rw-r--r--libdimension/scene.c37
-rw-r--r--libdimension/solid_pigment.c20
-rw-r--r--libdimension/sphere.c11
-rw-r--r--libdimension/texture.c35
30 files changed, 411 insertions, 696 deletions
diff --git a/libdimension/Makefile.am b/libdimension/Makefile.am
index 2dda68c..9774202 100644
--- a/libdimension/Makefile.am
+++ b/libdimension/Makefile.am
@@ -34,6 +34,7 @@ nobase_include_HEADERS = dimension.h \
dimension/interior.h \
dimension/light.h \
dimension/lights.h \
+ dimension/malloc.h \
dimension/object.h \
dimension/objects.h \
dimension/pigments.h \
@@ -62,6 +63,7 @@ libdimension_la_SOURCES = $(nobase_include_HEADERS) \
inlines.c \
interior.c \
light.c \
+ malloc.c \
object.c \
perspective.c \
phong.c \
diff --git a/libdimension/ambient.c b/libdimension/ambient.c
index 66fabe0..aa1153a 100644
--- a/libdimension/ambient.c
+++ b/libdimension/ambient.c
@@ -21,7 +21,6 @@
#include "dimension.h"
#include <errno.h>
#include <math.h>
-#include <stdlib.h> /* For malloc */
/*
* Ambient finish
@@ -41,18 +40,13 @@ dmnsn_finish *
dmnsn_new_ambient_finish(dmnsn_color ambient)
{
dmnsn_finish *finish = dmnsn_new_finish();
- if (finish) {
- dmnsn_color *param = malloc(sizeof(dmnsn_color));
- if (!param) {
- dmnsn_delete_finish(finish);
- errno = ENOMEM;
- return NULL;
- }
- *param = ambient;
- finish->ptr = param;
- finish->ambient_fn = &dmnsn_ambient_finish_fn;
- finish->free_fn = &free;
- }
+ dmnsn_color *param = dmnsn_malloc(sizeof(dmnsn_color));
+ *param = ambient;
+
+ finish->ptr = param;
+ finish->ambient_fn = &dmnsn_ambient_finish_fn;
+ finish->free_fn = &free;
+
return finish;
}
diff --git a/libdimension/bvst.c b/libdimension/bvst.c
index 6e23d6d..958273d 100644
--- a/libdimension/bvst.c
+++ b/libdimension/bvst.c
@@ -25,22 +25,15 @@
dmnsn_bvst *
dmnsn_new_bvst()
{
- dmnsn_bvst *tree = malloc(sizeof(dmnsn_bvst));
- if (tree) {
- tree->root = NULL;
- } else {
- dmnsn_error(DMNSN_SEVERITY_HIGH, "BVST allocation failed.");
- }
+ dmnsn_bvst *tree = dmnsn_malloc(sizeof(dmnsn_bvst));
+ tree->root = NULL;
return tree;
}
static dmnsn_bvst_node *
dmnsn_new_bvst_node()
{
- dmnsn_bvst_node *node = malloc(sizeof(dmnsn_bvst_node));
- if (!node) {
- dmnsn_error(DMNSN_SEVERITY_HIGH, "BVST node allocation failed.");
- }
+ dmnsn_bvst_node *node = dmnsn_malloc(sizeof(dmnsn_bvst_node));
return node;
}
diff --git a/libdimension/camera.c b/libdimension/camera.c
index eeb399c..9d30731 100644
--- a/libdimension/camera.c
+++ b/libdimension/camera.c
@@ -20,18 +20,13 @@
#include "dimension.h"
#include <errno.h>
-#include <stdlib.h> /* For malloc */
/* Allocate a new dummy camera */
dmnsn_camera *
dmnsn_new_camera()
{
- dmnsn_camera *camera = malloc(sizeof(dmnsn_camera));
- if (camera) {
- camera->free_fn = NULL;
- } else {
- errno = ENOMEM;
- }
+ dmnsn_camera *camera = dmnsn_malloc(sizeof(dmnsn_camera));
+ camera->free_fn = NULL;
return camera;
}
diff --git a/libdimension/canvas.c b/libdimension/canvas.c
index d18d0b7..d6c3c23 100644
--- a/libdimension/canvas.c
+++ b/libdimension/canvas.c
@@ -21,33 +21,24 @@
#include "dimension.h"
#include <pthread.h>
#include <errno.h>
-#include <stdlib.h> /* For malloc(), free() */
+#include <stdlib.h> /* For free() */
/* Allocate a new canvas, of width x and height y */
dmnsn_canvas *
dmnsn_new_canvas(unsigned int x, unsigned int y)
{
/* Allocate the dmnsn_canvas struct */
- dmnsn_canvas *canvas = malloc(sizeof(dmnsn_canvas));
+ dmnsn_canvas *canvas = dmnsn_malloc(sizeof(dmnsn_canvas));
- if (canvas) {
- /* Set the width and height */
- canvas->x = x;
- canvas->y = y;
+ /* Set the width and height */
+ canvas->x = x;
+ canvas->y = y;
- /* Allocate room for the optimizers */
- canvas->optimizers = dmnsn_new_array(sizeof(dmnsn_canvas_optimizer));
+ /* Allocate room for the optimizers */
+ canvas->optimizers = dmnsn_new_array(sizeof(dmnsn_canvas_optimizer));
- /* Allocate the pixels */
- canvas->pixels = malloc(sizeof(dmnsn_color)*x*y);
- if (!canvas->pixels) {
- dmnsn_delete_canvas(canvas);
- errno = ENOMEM;
- return NULL;
- }
- } else {
- errno = ENOMEM;
- }
+ /* Allocate the pixels */
+ canvas->pixels = dmnsn_malloc(sizeof(dmnsn_color)*x*y);
return canvas;
}
diff --git a/libdimension/csg.c b/libdimension/csg.c
index 78df625..6342432 100644
--- a/libdimension/csg.c
+++ b/libdimension/csg.c
@@ -98,48 +98,28 @@ dmnsn_csg_union_inside_fn(const dmnsn_object *csg, dmnsn_vector point)
dmnsn_object *
dmnsn_new_csg_union(dmnsn_object *A, dmnsn_object *B)
{
- if (A && B) {
- A->trans_inv = dmnsn_matrix_inverse(A->trans);
- B->trans_inv = dmnsn_matrix_inverse(B->trans);
-
- dmnsn_object *csg = dmnsn_new_object();
- if (csg) {
- dmnsn_object **params = malloc(2*sizeof(dmnsn_object *));
- if (!params) {
- dmnsn_delete_object(csg);
- dmnsn_delete_object(B);
- dmnsn_delete_object(A);
- errno = ENOMEM;
- return NULL;
- }
-
- params[0] = A;
- params[1] = B;
-
- csg->ptr = params;
- csg->intersection_fn = &dmnsn_csg_union_intersection_fn;
- csg->inside_fn = &dmnsn_csg_union_inside_fn;
- csg->free_fn = &dmnsn_csg_free_fn;
-
- dmnsn_bounding_box Abox
- = dmnsn_matrix_bounding_box_mul(A->trans, A->bounding_box);
- dmnsn_bounding_box Bbox
- = dmnsn_matrix_bounding_box_mul(B->trans, B->bounding_box);
- csg->bounding_box.min = dmnsn_vector_min(Abox.min, Bbox.min);
- csg->bounding_box.max = dmnsn_vector_max(Abox.max, Bbox.max);
-
- return csg;
- } else {
- dmnsn_delete_object(B);
- dmnsn_delete_object(A);
- }
- } else if (A) {
- dmnsn_delete_object(B);
- } else if (B) {
- dmnsn_delete_object(A);
- }
+ A->trans_inv = dmnsn_matrix_inverse(A->trans);
+ B->trans_inv = dmnsn_matrix_inverse(B->trans);
+
+ dmnsn_object *csg = dmnsn_new_object();
+
+ dmnsn_object **params = dmnsn_malloc(2*sizeof(dmnsn_object *));
+ params[0] = A;
+ params[1] = B;
+
+ csg->ptr = params;
+ csg->intersection_fn = &dmnsn_csg_union_intersection_fn;
+ csg->inside_fn = &dmnsn_csg_union_inside_fn;
+ csg->free_fn = &dmnsn_csg_free_fn;
+
+ dmnsn_bounding_box Abox
+ = dmnsn_matrix_bounding_box_mul(A->trans, A->bounding_box);
+ dmnsn_bounding_box Bbox
+ = dmnsn_matrix_bounding_box_mul(B->trans, B->bounding_box);
+ csg->bounding_box.min = dmnsn_vector_min(Abox.min, Bbox.min);
+ csg->bounding_box.max = dmnsn_vector_max(Abox.max, Bbox.max);
- return NULL;
+ return csg;
}
/* Intersections */
@@ -237,48 +217,28 @@ dmnsn_csg_intersection_inside_fn(const dmnsn_object *csg, dmnsn_vector point)
dmnsn_object *
dmnsn_new_csg_intersection(dmnsn_object *A, dmnsn_object *B)
{
- if (A && B) {
- A->trans_inv = dmnsn_matrix_inverse(A->trans);
- B->trans_inv = dmnsn_matrix_inverse(B->trans);
-
- dmnsn_object *csg = dmnsn_new_object();
- if (csg) {
- dmnsn_object **params = malloc(2*sizeof(dmnsn_object *));
- if (!params) {
- dmnsn_delete_object(csg);
- dmnsn_delete_object(B);
- dmnsn_delete_object(A);
- errno = ENOMEM;
- return NULL;
- }
-
- params[0] = A;
- params[1] = B;
-
- csg->ptr = params;
- csg->intersection_fn = &dmnsn_csg_intersection_intersection_fn;
- csg->inside_fn = &dmnsn_csg_intersection_inside_fn;
- csg->free_fn = &dmnsn_csg_free_fn;
-
- dmnsn_bounding_box Abox
- = dmnsn_matrix_bounding_box_mul(A->trans, A->bounding_box);
- dmnsn_bounding_box Bbox
- = dmnsn_matrix_bounding_box_mul(B->trans, B->bounding_box);
- csg->bounding_box.min = dmnsn_vector_min(Abox.min, Bbox.min);
- csg->bounding_box.max = dmnsn_vector_max(Abox.max, Bbox.max);
-
- return csg;
- } else {
- dmnsn_delete_object(B);
- dmnsn_delete_object(A);
- }
- } else if (A) {
- dmnsn_delete_object(B);
- } else if (B) {
- dmnsn_delete_object(A);
- }
+ A->trans_inv = dmnsn_matrix_inverse(A->trans);
+ B->trans_inv = dmnsn_matrix_inverse(B->trans);
+
+ dmnsn_object *csg = dmnsn_new_object();
+
+ dmnsn_object **params = dmnsn_malloc(2*sizeof(dmnsn_object *));
+ params[0] = A;
+ params[1] = B;
+
+ csg->ptr = params;
+ csg->intersection_fn = &dmnsn_csg_intersection_intersection_fn;
+ csg->inside_fn = &dmnsn_csg_intersection_inside_fn;
+ csg->free_fn = &dmnsn_csg_free_fn;
+
+ dmnsn_bounding_box Abox
+ = dmnsn_matrix_bounding_box_mul(A->trans, A->bounding_box);
+ dmnsn_bounding_box Bbox
+ = dmnsn_matrix_bounding_box_mul(B->trans, B->bounding_box);
+ csg->bounding_box.min = dmnsn_vector_min(Abox.min, Bbox.min);
+ csg->bounding_box.max = dmnsn_vector_max(Abox.max, Bbox.max);
- return NULL;
+ return csg;
}
/* Differences */
@@ -376,48 +336,28 @@ dmnsn_csg_difference_inside_fn(const dmnsn_object *csg, dmnsn_vector point)
dmnsn_object *
dmnsn_new_csg_difference(dmnsn_object *A, dmnsn_object *B)
{
- if (A && B) {
- A->trans_inv = dmnsn_matrix_inverse(A->trans);
- B->trans_inv = dmnsn_matrix_inverse(B->trans);
-
- dmnsn_object *csg = dmnsn_new_object();
- if (csg) {
- dmnsn_object **params = malloc(2*sizeof(dmnsn_object *));
- if (!params) {
- dmnsn_delete_object(csg);
- dmnsn_delete_object(B);
- dmnsn_delete_object(A);
- errno = ENOMEM;
- return NULL;
- }
-
- params[0] = A;
- params[1] = B;
-
- csg->ptr = params;
- csg->intersection_fn = &dmnsn_csg_difference_intersection_fn;
- csg->inside_fn = &dmnsn_csg_difference_inside_fn;
- csg->free_fn = &dmnsn_csg_free_fn;
-
- dmnsn_bounding_box Abox
- = dmnsn_matrix_bounding_box_mul(A->trans, A->bounding_box);
- dmnsn_bounding_box Bbox
- = dmnsn_matrix_bounding_box_mul(B->trans, B->bounding_box);
- csg->bounding_box.min = dmnsn_vector_min(Abox.min, Bbox.min);
- csg->bounding_box.max = dmnsn_vector_max(Abox.max, Bbox.max);
-
- return csg;
- } else {
- dmnsn_delete_object(B);
- dmnsn_delete_object(A);
- }
- } else if (A) {
- dmnsn_delete_object(B);
- } else if (B) {
- dmnsn_delete_object(A);
- }
+ A->trans_inv = dmnsn_matrix_inverse(A->trans);
+ B->trans_inv = dmnsn_matrix_inverse(B->trans);
+
+ dmnsn_object *csg = dmnsn_new_object();
+
+ dmnsn_object **params = dmnsn_malloc(2*sizeof(dmnsn_object *));
+ params[0] = A;
+ params[1] = B;
+
+ csg->ptr = params;
+ csg->intersection_fn = &dmnsn_csg_difference_intersection_fn;
+ csg->inside_fn = &dmnsn_csg_difference_inside_fn;
+ csg->free_fn = &dmnsn_csg_free_fn;
+
+ dmnsn_bounding_box Abox
+ = dmnsn_matrix_bounding_box_mul(A->trans, A->bounding_box);
+ dmnsn_bounding_box Bbox
+ = dmnsn_matrix_bounding_box_mul(B->trans, B->bounding_box);
+ csg->bounding_box.min = dmnsn_vector_min(Abox.min, Bbox.min);
+ csg->bounding_box.max = dmnsn_vector_max(Abox.max, Bbox.max);
- return NULL;
+ return csg;
}
/* Merges */
@@ -515,46 +455,26 @@ dmnsn_csg_merge_inside_fn(const dmnsn_object *csg, dmnsn_vector point)
dmnsn_object *
dmnsn_new_csg_merge(dmnsn_object *A, dmnsn_object *B)
{
- if (A && B) {
- A->trans_inv = dmnsn_matrix_inverse(A->trans);
- B->trans_inv = dmnsn_matrix_inverse(B->trans);
-
- dmnsn_object *csg = dmnsn_new_object();
- if (csg) {
- dmnsn_object **params = malloc(2*sizeof(dmnsn_object *));
- if (!params) {
- dmnsn_delete_object(csg);
- dmnsn_delete_object(B);
- dmnsn_delete_object(A);
- errno = ENOMEM;
- return NULL;
- }
-
- params[0] = A;
- params[1] = B;
-
- csg->ptr = params;
- csg->intersection_fn = &dmnsn_csg_merge_intersection_fn;
- csg->inside_fn = &dmnsn_csg_merge_inside_fn;
- csg->free_fn = &dmnsn_csg_free_fn;
-
- dmnsn_bounding_box Abox
- = dmnsn_matrix_bounding_box_mul(A->trans, A->bounding_box);
- dmnsn_bounding_box Bbox
- = dmnsn_matrix_bounding_box_mul(B->trans, B->bounding_box);
- csg->bounding_box.min = dmnsn_vector_min(Abox.min, Bbox.min);
- csg->bounding_box.max = dmnsn_vector_max(Abox.max, Bbox.max);
-
- return csg;
- } else {
- dmnsn_delete_object(B);
- dmnsn_delete_object(A);
- }
- } else if (A) {
- dmnsn_delete_object(B);
- } else if (B) {
- dmnsn_delete_object(A);
- }
+ A->trans_inv = dmnsn_matrix_inverse(A->trans);
+ B->trans_inv = dmnsn_matrix_inverse(B->trans);
+
+ dmnsn_object *csg = dmnsn_new_object();
+
+ dmnsn_object **params = dmnsn_malloc(2*sizeof(dmnsn_object *));
+ params[0] = A;
+ params[1] = B;
+
+ csg->ptr = params;
+ csg->intersection_fn = &dmnsn_csg_merge_intersection_fn;
+ csg->inside_fn = &dmnsn_csg_merge_inside_fn;
+ csg->free_fn = &dmnsn_csg_free_fn;
+
+ dmnsn_bounding_box Abox
+ = dmnsn_matrix_bounding_box_mul(A->trans, A->bounding_box);
+ dmnsn_bounding_box Bbox
+ = dmnsn_matrix_bounding_box_mul(B->trans, B->bounding_box);
+ csg->bounding_box.min = dmnsn_vector_min(Abox.min, Bbox.min);
+ csg->bounding_box.max = dmnsn_vector_max(Abox.max, Bbox.max);
- return NULL;
+ return csg;
}
diff --git a/libdimension/cube.c b/libdimension/cube.c
index a6f656d..033d2fb 100644
--- a/libdimension/cube.c
+++ b/libdimension/cube.c
@@ -19,8 +19,7 @@
*************************************************************************/
#include "dimension.h"
-#include <stdlib.h> /* For malloc */
-#include <math.h> /* For sqrt */
+#include <math.h> /* For sqrt */
/*
* Cube
@@ -37,12 +36,10 @@ dmnsn_object *
dmnsn_new_cube()
{
dmnsn_object *cube = dmnsn_new_object();
- if (cube) {
- cube->intersection_fn = &dmnsn_cube_intersection_fn;
- cube->inside_fn = &dmnsn_cube_inside_fn;
- cube->bounding_box.min = dmnsn_new_vector(-1.0, -1.0, -1.0);
- cube->bounding_box.max = dmnsn_new_vector(1.0, 1.0, 1.0);
- }
+ cube->intersection_fn = &dmnsn_cube_intersection_fn;
+ cube->inside_fn = &dmnsn_cube_inside_fn;
+ cube->bounding_box.min = dmnsn_new_vector(-1.0, -1.0, -1.0);
+ cube->bounding_box.max = dmnsn_new_vector(1.0, 1.0, 1.0);
return cube;
}
diff --git a/libdimension/diffuse.c b/libdimension/diffuse.c
index d6ecf37..dc41944 100644
--- a/libdimension/diffuse.c
+++ b/libdimension/diffuse.c
@@ -20,7 +20,6 @@
#include "dimension.h"
#include <errno.h>
-#include <stdlib.h> /* For malloc */
#include <math.h>
/*
@@ -45,19 +44,13 @@ dmnsn_finish *
dmnsn_new_diffuse_finish(double diffuse)
{
dmnsn_finish *finish = dmnsn_new_finish();
- if (finish) {
- double *param = malloc(sizeof(double));
- if (!param) {
- dmnsn_delete_finish(finish);
- errno = ENOMEM;
- return NULL;
- }
- *param = diffuse;
+ double *param = dmnsn_malloc(sizeof(double));
+ *param = diffuse;
+
+ finish->ptr = param;
+ finish->diffuse_fn = &dmnsn_diffuse_finish_fn;
+ finish->free_fn = &free;
- finish->ptr = param;
- finish->diffuse_fn = &dmnsn_diffuse_finish_fn;
- finish->free_fn = &free;
- }
return finish;
}
diff --git a/libdimension/dimension.h b/libdimension/dimension.h
index e693841..5aca9b3 100644
--- a/libdimension/dimension.h
+++ b/libdimension/dimension.h
@@ -61,6 +61,7 @@ typedef void dmnsn_free_fn(void *ptr);
/* Include all the libdimension headers */
#include <dimension/error.h>
+#include <dimension/malloc.h>
#include <dimension/array.h>
#include <dimension/progress.h>
#include <dimension/geometry.h>
diff --git a/libdimension/dimension/array.h b/libdimension/dimension/array.h
index c1e28cd..a301de5 100644
--- a/libdimension/dimension/array.h
+++ b/libdimension/dimension/array.h
@@ -28,7 +28,7 @@
#define DIMENSION_ARRAY_H
#include <pthread.h> /* For pthread_rwlock_t */
-#include <stdlib.h> /* For size_t, malloc */
+#include <stdlib.h> /* For size_t */
#include <string.h> /* For memcpy */
typedef struct {
@@ -46,26 +46,17 @@ dmnsn_delete_array(dmnsn_array *array)
}
}
-/* Array allocation never returns NULL - if dmnsn_new_array returns, it
- succeeded */
+/* Array allocation */
DMNSN_INLINE dmnsn_array *
dmnsn_new_array(size_t obj_size)
{
- dmnsn_array *array = (dmnsn_array *)malloc(sizeof(dmnsn_array));
- if (array) {
- array->obj_size = obj_size;
- array->length = 0;
- array->capacity = 4; /* Start with capacity of 4 */
-
- /* Allocate the memory */
- array->ptr = malloc(array->capacity*array->obj_size);
- if (!array->ptr) {
- dmnsn_delete_array(array);
- dmnsn_error(DMNSN_SEVERITY_HIGH, "Array allocation failed.");
- }
- } else {
- dmnsn_error(DMNSN_SEVERITY_HIGH, "Array allocation failed.");
- }
+ dmnsn_array *array = (dmnsn_array *)dmnsn_malloc(sizeof(dmnsn_array));
+ array->obj_size = obj_size;
+ array->length = 0;
+ array->capacity = 4; /* Start with capacity of 4 */
+
+ /* Allocate the memory */
+ array->ptr = dmnsn_malloc(array->capacity*array->obj_size);
return array;
}
@@ -84,10 +75,7 @@ dmnsn_array_resize(dmnsn_array *array, size_t length)
if (length > array->capacity) {
/* Resize if we don't have enough capacity */
array->capacity = length*2; /* We are greedy */
- array->ptr = realloc(array->ptr, array->obj_size*array->capacity);
- if (!array->ptr) {
- dmnsn_error(DMNSN_SEVERITY_HIGH, "Resizing array failed.");
- }
+ array->ptr = dmnsn_realloc(array->ptr, array->obj_size*array->capacity);
}
array->length = length;
diff --git a/libdimension/dimension/malloc.h b/libdimension/dimension/malloc.h
new file mode 100644
index 0000000..8ca4f9d
--- /dev/null
+++ b/libdimension/dimension/malloc.h
@@ -0,0 +1,31 @@
+/*************************************************************************
+ * Copyright (C) 2010 Tavian Barnes <tavianator@gmail.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+/*
+ * Seriously, how often does malloc fail? And how often can you do something
+ * better than bail out when it does? dmnsn_malloc() is like malloc in every
+ * way except it calls dmnsn_error() on failure.
+ */
+
+#include <stdlib.h> /* For size_t */
+
+void *dmnsn_malloc(size_t size);
+void *dmnsn_realloc(void *ptr, size_t size);
+char *dmnsn_strdup(const char *s);
diff --git a/libdimension/dimension/raytrace.h b/libdimension/dimension/raytrace.h
index 1c7d875..914f944 100644
--- a/libdimension/dimension/raytrace.h
+++ b/libdimension/dimension/raytrace.h
@@ -26,7 +26,7 @@
#define DIMENSION_RAYTRACE_H
/* Render a scene by raytracing */
-int dmnsn_raytrace_scene(dmnsn_scene *scene);
+void dmnsn_raytrace_scene(dmnsn_scene *scene);
dmnsn_progress *dmnsn_raytrace_scene_async(dmnsn_scene *scene);
#endif /* DIMENSION_RAYTRACE_H */
diff --git a/libdimension/error.c b/libdimension/error.c
index 118dd54..222f5eb 100644
--- a/libdimension/error.c
+++ b/libdimension/error.c
@@ -153,8 +153,9 @@ dmnsn_default_fatal_error_fn()
if (pid == tid) {
exit(EXIT_FAILURE);
} else {
- int *ret = malloc(sizeof(int));
- *ret = 1;
+ int *ret = malloc(sizeof(int)); /* Don't use dmnsn_malloc */
+ if (ret)
+ *ret = 1;
pthread_exit(ret);
}
#else
diff --git a/libdimension/finish_combination.c b/libdimension/finish_combination.c
index 472dc23..c281285 100644
--- a/libdimension/finish_combination.c
+++ b/libdimension/finish_combination.c
@@ -20,7 +20,6 @@
#include "dimension.h"
#include <errno.h>
-#include <stdlib.h> /* For malloc */
#include <math.h>
/*
@@ -119,47 +118,27 @@ dmnsn_finish_combination_free_fn(void *ptr)
dmnsn_finish *
dmnsn_new_finish_combination(dmnsn_finish *f1, dmnsn_finish *f2)
{
- if (f1 && f2) {
- dmnsn_finish *finish = dmnsn_new_finish();
- if (finish) {
- dmnsn_finish **params = malloc(2*sizeof(dmnsn_finish *));
- if (!params) {
- dmnsn_delete_finish(finish);
- dmnsn_delete_finish(f2);
- dmnsn_delete_finish(f1);
- errno = ENOMEM;
- return NULL;
- }
-
- params[0] = f1;
- params[1] = f2;
-
- finish->ptr = params;
-
- if (f1->diffuse_fn || f2->diffuse_fn)
- finish->diffuse_fn = &dmnsn_finish_combination_diffuse_fn;
-
- if (f1->specular_fn || f2->specular_fn)
- finish->specular_fn = &dmnsn_finish_combination_specular_fn;
-
- if (f1->ambient_fn || f2->ambient_fn)
- finish->ambient_fn = &dmnsn_finish_combination_ambient_fn;
-
- if (f1->reflection_fn || f2->reflection_fn)
- finish->reflection_fn = &dmnsn_finish_combination_reflection_fn;
-
- finish->free_fn = &dmnsn_finish_combination_free_fn;
-
- return finish;
- } else {
- dmnsn_delete_finish(f2);
- dmnsn_delete_finish(f1);
- }
- } else if (f1) {
- dmnsn_delete_finish(f1);
- } else if (f2) {
- dmnsn_delete_finish(f2);
- }
+ dmnsn_finish *finish = dmnsn_new_finish();
+
+ dmnsn_finish **params = dmnsn_malloc(2*sizeof(dmnsn_finish *));
+ params[0] = f1;
+ params[1] = f2;
+
+ finish->ptr = params;
+
+ if (f1->diffuse_fn || f2->diffuse_fn)
+ finish->diffuse_fn = &dmnsn_finish_combination_diffuse_fn;
+
+ if (f1->specular_fn || f2->specular_fn)
+ finish->specular_fn = &dmnsn_finish_combination_specular_fn;
+
+ if (f1->ambient_fn || f2->ambient_fn)
+ finish->ambient_fn = &dmnsn_finish_combination_ambient_fn;
+
+ if (f1->reflection_fn || f2->reflection_fn)
+ finish->reflection_fn = &dmnsn_finish_combination_reflection_fn;
+
+ finish->free_fn = &dmnsn_finish_combination_free_fn;
- return NULL;
+ return finish;
}
diff --git a/libdimension/gl.c b/libdimension/gl.c
index 0136ac3..86f41e4 100644
--- a/libdimension/gl.c
+++ b/libdimension/gl.c
@@ -48,11 +48,7 @@ dmnsn_gl_optimize_canvas(dmnsn_canvas *canvas)
optimizer.free_fn = &free;
/* Allocate a buffer to hold RGB values */
- optimizer.ptr = malloc(4*canvas->x*canvas->y*sizeof(GLushort));
- if (!optimizer.ptr) {
- errno = ENOTSUP;
- return -1;
- }
+ optimizer.ptr = dmnsn_malloc(4*canvas->x*canvas->y*sizeof(GLushort));
/* Set a new optimizer */
dmnsn_optimize_canvas(canvas, optimizer);
@@ -83,11 +79,7 @@ dmnsn_gl_write_canvas(const dmnsn_canvas *canvas)
}
/* We couldn't, so transform the canvas to RGB now */
- pixels = malloc(4*width*height*sizeof(GLushort));
- if (!pixels) {
- errno = ENOMEM;
- return -1;
- }
+ pixels = dmnsn_malloc(4*width*height*sizeof(GLushort));
for (y = 0; y < height; ++y) {
for (x = 0; x < width; ++x) {
@@ -146,16 +138,7 @@ dmnsn_gl_read_canvas(unsigned int x0, unsigned int y0,
unsigned int x, y;
canvas = dmnsn_new_canvas(width, height);
- if (!canvas) {
- return NULL;
- }
-
- pixels = malloc(4*width*height*sizeof(GLushort));
- if (!pixels) {
- dmnsn_delete_canvas(canvas);
- errno = ENOMEM;
- return NULL;
- }
+ pixels = dmnsn_malloc(4*width*height*sizeof(GLushort));
glReadPixels(x0, y0, width, height, GL_RGBA, GL_UNSIGNED_SHORT, pixels);
diff --git a/libdimension/interior.c b/libdimension/interior.c
index 546a420..452d879 100644
--- a/libdimension/interior.c
+++ b/libdimension/interior.c
@@ -20,19 +20,14 @@
#include "dimension.h"
#include <errno.h>
-#include <stdlib.h> /* For malloc */
/* Allocate an interior */
dmnsn_interior *
dmnsn_new_interior()
{
- dmnsn_interior *interior = malloc(sizeof(dmnsn_interior));
- if (interior) {
- interior->ior = 1.0;
- interior->free_fn = NULL;
- } else {
- errno = ENOMEM;
- }
+ dmnsn_interior *interior = dmnsn_malloc(sizeof(dmnsn_interior));
+ interior->ior = 1.0;
+ interior->free_fn = NULL;
return interior;
}
diff --git a/libdimension/light.c b/libdimension/light.c
index cc2c961..8be90e0 100644
--- a/libdimension/light.c
+++ b/libdimension/light.c
@@ -20,20 +20,15 @@
#include "dimension.h"
#include <errno.h>
-#include <stdlib.h> /* For malloc */
/* Allocate a new dummy light */
dmnsn_light *
dmnsn_new_light()
{
- dmnsn_light *light = malloc(sizeof(dmnsn_light));
- if (light) {
- light->light_fn = NULL;
- light->free_fn = NULL;
- light->ptr = NULL;
- } else {
- errno = ENOMEM;
- }
+ dmnsn_light *light = dmnsn_malloc(sizeof(dmnsn_light));
+ light->light_fn = NULL;
+ light->free_fn = NULL;
+ light->ptr = NULL;
return light;
}
diff --git a/libdimension/malloc.c b/libdimension/malloc.c
new file mode 100644
index 0000000..f1f234e
--- /dev/null
+++ b/libdimension/malloc.c
@@ -0,0 +1,50 @@
+/*************************************************************************
+ * Copyright (C) 2010 Tavian Barnes <tavianator@gmail.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+#include "dimension.h"
+#include <string.h>
+
+void *
+dmnsn_malloc(size_t size)
+{
+ void *ptr = malloc(size);
+ if (!ptr) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Memory allocation failed.");
+ }
+ return ptr;
+}
+
+void *
+dmnsn_realloc(void *ptr, size_t size)
+{
+ ptr = realloc(ptr, size);
+ if (!ptr) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Memory allocation failed.");
+ }
+ return ptr;
+}
+
+char *
+dmnsn_strdup(const char *s)
+{
+ char *copy = dmnsn_malloc(strlen(s) + 1);
+ strcpy(copy, s);
+ return copy;
+}
diff --git a/libdimension/object.c b/libdimension/object.c
index 9f17971..51db42f 100644
--- a/libdimension/object.c
+++ b/libdimension/object.c
@@ -20,16 +20,12 @@
#include "dimension.h"
#include <errno.h>
-#include <stdlib.h> /* For malloc */
-/* Allocate an intersection - cannot fail */
+/* Allocate an intersection */
dmnsn_intersection *
dmnsn_new_intersection()
{
- dmnsn_intersection *intersection = malloc(sizeof(dmnsn_intersection));
- if (!intersection) {
- dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't allocate an intersection.");
- }
+ dmnsn_intersection *intersection = dmnsn_malloc(sizeof(dmnsn_intersection));
return intersection;
}
@@ -44,15 +40,11 @@ dmnsn_delete_intersection(dmnsn_intersection *intersection)
dmnsn_object *
dmnsn_new_object()
{
- dmnsn_object *object = malloc(sizeof(dmnsn_object));
- if (object) {
- object->texture = NULL;
- object->interior = NULL;
- object->trans = dmnsn_identity_matrix();
- object->free_fn = NULL;
- } else {
- errno = ENOMEM;
- }
+ dmnsn_object *object = dmnsn_malloc(sizeof(dmnsn_object));
+ object->texture = NULL;
+ object->interior = NULL;
+ object->trans = dmnsn_identity_matrix();
+ object->free_fn = NULL;
return object;
}
diff --git a/libdimension/perspective.c b/libdimension/perspective.c
index df679ae..678c87b 100644
--- a/libdimension/perspective.c
+++ b/libdimension/perspective.c
@@ -35,22 +35,15 @@ static dmnsn_line dmnsn_perspective_camera_ray_fn(const dmnsn_camera *camera,
dmnsn_camera *
dmnsn_new_perspective_camera()
{
- dmnsn_matrix *ptr;
dmnsn_camera *camera = dmnsn_new_camera();
- if (camera) {
- /* Allocate room for the transformation matrix */
- ptr = malloc(sizeof(dmnsn_matrix));
- if (!ptr) {
- dmnsn_delete_camera(camera);
- errno = ENOMEM;
- return NULL;
- }
- *ptr = dmnsn_identity_matrix();
- camera->ray_fn = &dmnsn_perspective_camera_ray_fn;
- camera->free_fn = &free;
- camera->ptr = ptr;
- }
+ dmnsn_matrix *ptr = dmnsn_malloc(sizeof(dmnsn_matrix));
+ *ptr = dmnsn_identity_matrix();
+
+ camera->ray_fn = &dmnsn_perspective_camera_ray_fn;
+ camera->free_fn = &free;
+ camera->ptr = ptr;
+
return camera;
}
diff --git a/libdimension/phong.c b/libdimension/phong.c
index 8188488..ae7b2ce 100644
--- a/libdimension/phong.c
+++ b/libdimension/phong.c
@@ -20,7 +20,6 @@
#include "dimension.h"
#include <errno.h>
-#include <stdlib.h> /* For malloc */
#include <math.h>
/*
@@ -55,20 +54,14 @@ dmnsn_finish *
dmnsn_new_phong_finish(double specular, double exp)
{
dmnsn_finish *finish = dmnsn_new_finish();
- if (finish) {
- double *params = malloc(2*sizeof(double));
- if (!params) {
- dmnsn_delete_finish(finish);
- errno = ENOMEM;
- return NULL;
- }
- params[0] = specular;
- params[1] = exp;
+ double *params = dmnsn_malloc(2*sizeof(double));
+ params[0] = specular;
+ params[1] = exp;
+
+ finish->ptr = params;
+ finish->specular_fn = &dmnsn_phong_specular_fn;
+ finish->free_fn = &free;
- finish->ptr = params;
- finish->specular_fn = &dmnsn_phong_specular_fn;
- finish->free_fn = &free;
- }
return finish;
}
diff --git a/libdimension/png.c b/libdimension/png.c
index 4f622dc..76bace9 100644
--- a/libdimension/png.c
+++ b/libdimension/png.c
@@ -50,11 +50,7 @@ dmnsn_png_optimize_canvas(dmnsn_canvas *canvas)
optimizer.optimizer_fn = &dmnsn_png_optimizer_fn;
optimizer.free_fn = &free;
- optimizer.ptr = malloc(4*canvas->x*canvas->y*sizeof(uint16_t));
- if (!optimizer.ptr) {
- errno = ENOMEM;
- return -1;
- }
+ optimizer.ptr = dmnsn_malloc(4*canvas->x*canvas->y*sizeof(uint16_t));
dmnsn_optimize_canvas(canvas, optimizer);
return 0;
@@ -140,28 +136,20 @@ dmnsn_progress *
dmnsn_png_write_canvas_async(const dmnsn_canvas *canvas, FILE *file)
{
dmnsn_progress *progress = dmnsn_new_progress();
- dmnsn_png_write_payload *payload;
- if (progress) {
- payload = malloc(sizeof(dmnsn_png_write_payload));
- if (!payload) {
- dmnsn_delete_progress(progress);
- errno = ENOMEM;
- return NULL;
- }
+ dmnsn_png_write_payload *payload
+ = dmnsn_malloc(sizeof(dmnsn_png_write_payload));
+ payload->progress = progress;
+ payload->canvas = canvas;
+ payload->file = file;
- payload->progress = progress;
- payload->canvas = canvas;
- payload->file = file;
-
- /* Create the worker thread */
- if (pthread_create(&progress->thread, NULL, &dmnsn_png_write_canvas_thread,
- payload) != 0)
- {
- free(payload);
- dmnsn_delete_progress(progress);
- return NULL;
- }
+ /* Create the worker thread */
+ if (pthread_create(&progress->thread, NULL, &dmnsn_png_write_canvas_thread,
+ payload) != 0)
+ {
+ free(payload);
+ dmnsn_delete_progress(progress);
+ return NULL;
}
return progress;
@@ -182,28 +170,18 @@ dmnsn_progress *
dmnsn_png_read_canvas_async(dmnsn_canvas **canvas, FILE *file)
{
dmnsn_progress *progress = dmnsn_new_progress();
- dmnsn_png_read_payload *payload;
+ dmnsn_png_read_payload *payload
+ = dmnsn_malloc(sizeof(dmnsn_png_write_payload));
- if (progress) {
- payload = malloc(sizeof(dmnsn_png_write_payload));
- if (!payload) {
- dmnsn_delete_progress(progress);
- errno = ENOMEM;
- return NULL;
- }
+ payload->progress = progress;
+ payload->canvas = canvas;
+ payload->file = file;
- payload->progress = progress;
- payload->canvas = canvas;
- payload->file = file;
-
- /* Create the worker thread */
- if (pthread_create(&progress->thread, NULL, &dmnsn_png_read_canvas_thread,
- payload) != 0)
- {
- free(payload);
- dmnsn_delete_progress(progress);
- return NULL;
- }
+ /* Create the worker thread */
+ if (pthread_create(&progress->thread, NULL, &dmnsn_png_read_canvas_thread,
+ payload) != 0)
+ {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't start worker thread.");
}
return progress;
@@ -221,11 +199,9 @@ static void *
dmnsn_png_write_canvas_thread(void *ptr)
{
dmnsn_png_write_payload *payload = ptr;
- int *retval = malloc(sizeof(int));
- if (retval) {
- *retval = dmnsn_png_write_canvas_impl(payload->progress,
- payload->canvas, payload->file);
- }
+ int *retval = dmnsn_malloc(sizeof(int));
+ *retval = dmnsn_png_write_canvas_impl(payload->progress,
+ payload->canvas, payload->file);
dmnsn_done_progress(payload->progress);
free(payload);
return retval;
@@ -235,12 +211,12 @@ static void *
dmnsn_png_read_canvas_thread(void *ptr)
{
dmnsn_png_read_payload *payload = ptr;
- int *retval = malloc(sizeof(int));
- if (retval) {
- *payload->canvas = dmnsn_png_read_canvas_impl(payload->progress,
- payload->file);
- *retval = *payload->canvas ? 0 : -1; /* Fail if it returned NULL */
- }
+ *payload->canvas = dmnsn_png_read_canvas_impl(payload->progress,
+ payload->file);
+
+ int *retval = dmnsn_malloc(sizeof(int));
+ *retval = *payload->canvas ? 0 : -1; /* Fail if it returned NULL */
+
dmnsn_done_progress(payload->progress);
free(payload);
return retval;
@@ -331,12 +307,7 @@ dmnsn_png_write_canvas_impl(dmnsn_progress *progress,
}
/* Allocate the temporary row of RGBA values */
- row = malloc(4*sizeof(uint16_t)*width);
- if (!row) {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- errno = ENOMEM;
- return -1;
- }
+ row = dmnsn_malloc(4*sizeof(uint16_t)*width);
/* Write the pixels */
for (y = 0; y < height; ++y) {
@@ -524,22 +495,10 @@ dmnsn_png_read_canvas_impl(dmnsn_progress *progress, FILE *file)
rowbytes = png_get_rowbytes(png_ptr, info_ptr);
/* Allocate the temporary image buffer */
- image = malloc(rowbytes*height);
- if (!image) {
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- errno = ENOMEM;
- return NULL;
- }
+ image = dmnsn_malloc(rowbytes*height);
/* Allocate and set an array of pointers to rows in image */
-
- row_pointers = malloc(sizeof(png_bytep)*height);
- if (!row_pointers) {
- free(image);
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- errno = ENOMEM;
- return NULL;
- }
+ row_pointers = dmnsn_malloc(sizeof(png_bytep)*height);
for (y = 0; y < height; ++y) {
row_pointers[y] = image + y*rowbytes;
@@ -551,13 +510,6 @@ dmnsn_png_read_canvas_impl(dmnsn_progress *progress, FILE *file)
/* Allocate the canvas */
canvas = dmnsn_new_canvas(width, height);
- if (!canvas) {
- free(row_pointers);
- free(image);
- png_read_end(png_ptr, NULL);
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- return NULL;
- }
/* Now we convert the image to our canvas format. This depends on the image
bit depth (which has been scaled up to at least 8 or 16), and the presence
diff --git a/libdimension/point_light.c b/libdimension/point_light.c
index 1ca3c96..02ab2ea 100644
--- a/libdimension/point_light.c
+++ b/libdimension/point_light.c
@@ -35,20 +35,14 @@ dmnsn_light *
dmnsn_new_point_light(dmnsn_vector x0, dmnsn_color color)
{
dmnsn_light *light = dmnsn_new_light();
- if (light) {
- /* Allocate room for the transformation matrix */
- dmnsn_color *ptr = malloc(sizeof(dmnsn_color));
- if (!ptr) {
- dmnsn_delete_light(light);
- errno = ENOMEM;
- return NULL;
- }
- *ptr = color;
- light->x0 = x0;
- light->light_fn = &dmnsn_point_light_fn;
- light->free_fn = &free;
- light->ptr = ptr;
- }
+ dmnsn_color *ptr = dmnsn_malloc(sizeof(dmnsn_color));
+ *ptr = color;
+
+ light->x0 = x0;
+ light->light_fn = &dmnsn_point_light_fn;
+ light->free_fn = &free;
+ light->ptr = ptr;
+
return light;
}
diff --git a/libdimension/progress.c b/libdimension/progress.c
index 998af8e..bc8830b 100644
--- a/libdimension/progress.c
+++ b/libdimension/progress.c
@@ -21,7 +21,6 @@
#include "dimension.h"
#include <pthread.h>
#include <errno.h>
-#include <stdlib.h> /* For malloc */
/* For thread synchronization */
static void dmnsn_progress_rdlock(const dmnsn_progress *progress);
@@ -32,70 +31,44 @@ static void dmnsn_progress_unlock(const dmnsn_progress *progress);
dmnsn_progress *
dmnsn_new_progress()
{
- dmnsn_progress_element element = { .progress = 0, .total = 1 };
- dmnsn_progress *progress = malloc(sizeof(dmnsn_progress));
- if (progress) {
- progress->elements = dmnsn_new_array(sizeof(dmnsn_progress_element));
- dmnsn_array_push(progress->elements, &element);
+ dmnsn_progress *progress = dmnsn_malloc(sizeof(dmnsn_progress));
+ progress->elements = dmnsn_new_array(sizeof(dmnsn_progress_element));
- /* Initialize the rwlock, condition variable, and mutex */
+ dmnsn_progress_element element = { .progress = 0, .total = 1 };
+ dmnsn_array_push(progress->elements, &element);
- progress->rwlock = NULL;
- progress->mutex = NULL;
- progress->cond = NULL;
+ /* Initialize the rwlock, condition variable, and mutex */
- progress->rwlock = malloc(sizeof(pthread_rwlock_t));
- if (!progress->rwlock) {
- dmnsn_delete_progress(progress);
- errno = ENOMEM;
- return NULL;
- }
- if (pthread_rwlock_init(progress->rwlock, NULL) != 0) {
- dmnsn_delete_progress(progress);
- return NULL;
- }
+ progress->rwlock = dmnsn_malloc(sizeof(pthread_rwlock_t));
+ if (pthread_rwlock_init(progress->rwlock, NULL) != 0) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't initialize read-write lock.");
+ }
- progress->cond = malloc(sizeof(pthread_cond_t));
- if (!progress->cond) {
- dmnsn_delete_progress(progress);
- errno = ENOMEM;
- return NULL;
- }
- if (pthread_cond_init(progress->cond, NULL) != 0) {
- dmnsn_delete_progress(progress);
- return NULL;
- }
+ progress->cond = dmnsn_malloc(sizeof(pthread_cond_t));
+ if (pthread_cond_init(progress->cond, NULL) != 0) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't initialize condition variable.");
+ }
- progress->mutex = malloc(sizeof(pthread_mutex_t));
- if (!progress->mutex) {
- dmnsn_delete_progress(progress);
- errno = ENOMEM;
- return NULL;
- }
- if (pthread_mutex_init(progress->mutex, NULL) != 0) {
- dmnsn_delete_progress(progress);
- return NULL;
- }
- } else {
- errno = ENOMEM;
+ progress->mutex = dmnsn_malloc(sizeof(pthread_mutex_t));
+ if (pthread_mutex_init(progress->mutex, NULL) != 0) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't initialize mutex.");
}
return progress;
}
-/* Delete a dmnsn_progress*, which has not yet been associated with a thread;
- mostly for failed returns from *_async() functions. */
+/* Delete a dmnsn_progress*, which has not yet been associated with a thread */
void
dmnsn_delete_progress(dmnsn_progress *progress)
{
if (progress) {
- if (progress->rwlock && pthread_rwlock_destroy(progress->rwlock) != 0) {
+ if (pthread_rwlock_destroy(progress->rwlock) != 0) {
dmnsn_error(DMNSN_SEVERITY_LOW, "Leaking rwlock.");
}
- if (progress->mutex && pthread_mutex_destroy(progress->mutex) != 0) {
+ if (pthread_mutex_destroy(progress->mutex) != 0) {
dmnsn_error(DMNSN_SEVERITY_LOW, "Leaking mutex.");
}
- if (progress->cond && pthread_cond_destroy(progress->cond) != 0) {
+ if (pthread_cond_destroy(progress->cond) != 0) {
dmnsn_error(DMNSN_SEVERITY_LOW, "Leaking condition variable.");
}
diff --git a/libdimension/raytrace.c b/libdimension/raytrace.c
index 840f6f2..812b6a6 100644
--- a/libdimension/raytrace.c
+++ b/libdimension/raytrace.c
@@ -40,68 +40,55 @@ typedef struct {
static void *dmnsn_raytrace_scene_thread(void *ptr);
/* Raytrace a scene */
-int
+void
dmnsn_raytrace_scene(dmnsn_scene *scene)
{
dmnsn_progress *progress = dmnsn_raytrace_scene_async(scene);
- return dmnsn_finish_progress(progress);
+ dmnsn_finish_progress(progress);
}
/* Raytrace a scene in the background */
dmnsn_progress *
dmnsn_raytrace_scene_async(dmnsn_scene *scene)
{
- unsigned int i;
- dmnsn_object *object;
- dmnsn_raytrace_payload *payload;
dmnsn_progress *progress = dmnsn_new_progress();
- if (progress) {
- payload = malloc(sizeof(dmnsn_raytrace_payload));
- if (!payload) {
- dmnsn_delete_progress(progress);
- errno = ENOMEM;
- return NULL;
- }
-
- payload->progress = progress;
- payload->scene = scene;
- payload->bvst = dmnsn_new_bvst();
+ dmnsn_raytrace_payload *payload
+ = dmnsn_malloc(sizeof(dmnsn_raytrace_payload));
+ payload->progress = progress;
+ payload->scene = scene;
+ payload->bvst = dmnsn_new_bvst();
- for (i = 0; i < dmnsn_array_size(payload->scene->objects); ++i) {
- dmnsn_array_get(payload->scene->objects, i, &object);
- dmnsn_bvst_insert(payload->bvst, object);
- }
+ unsigned int i;
+ for (i = 0; i < dmnsn_array_size(payload->scene->objects); ++i) {
+ dmnsn_object *object;
+ dmnsn_array_get(payload->scene->objects, i, &object);
+ dmnsn_bvst_insert(payload->bvst, object);
+ }
- if (pthread_create(&progress->thread, NULL, &dmnsn_raytrace_scene_thread,
- payload) != 0)
- {
- dmnsn_delete_bvst(payload->bvst);
- free(payload);
- dmnsn_delete_progress(progress);
- return NULL;
- }
+ if (pthread_create(&progress->thread, NULL, &dmnsn_raytrace_scene_thread,
+ payload) != 0)
+ {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't start worker thread.");
}
return progress;
}
/* Start the multi-threaded implementation */
-static int dmnsn_raytrace_scene_multithread(dmnsn_raytrace_payload *payload);
+static void dmnsn_raytrace_scene_multithread(dmnsn_raytrace_payload *payload);
/* Thread callback */
static void *
dmnsn_raytrace_scene_thread(void *ptr)
{
dmnsn_raytrace_payload *payload = ptr;
- int *retval = malloc(sizeof(int));
- if (retval) {
- *retval = dmnsn_raytrace_scene_multithread(payload);
- } else {
- errno = ENOMEM;
- }
+ dmnsn_raytrace_scene_multithread(payload);
dmnsn_done_progress(payload->progress);
free(payload);
+
+ int *retval = dmnsn_malloc(sizeof(int));
+ *retval = 0;
return retval;
}
@@ -109,12 +96,9 @@ dmnsn_raytrace_scene_thread(void *ptr)
static void *dmnsn_raytrace_scene_multithread_thread(void *ptr);
/* Set up the multi-threaded engine */
-static int
+static void
dmnsn_raytrace_scene_multithread(dmnsn_raytrace_payload *payload)
{
- int i, j;
- void *ptr;
- int retval = 0;
dmnsn_raytrace_payload *payloads;
pthread_t *threads;
@@ -123,24 +107,15 @@ dmnsn_raytrace_scene_multithread(dmnsn_raytrace_payload *payload)
if (nthreads < 1)
nthreads = 1;
- payloads = malloc(nthreads*sizeof(dmnsn_raytrace_payload));
- if (!payloads) {
- errno = ENOMEM;
- return -1;
- }
-
- threads = malloc(nthreads*sizeof(pthread_t));
- if (!threads) {
- free(payloads);
- errno = ENOMEM;
- return -1;
- }
+ payloads = dmnsn_malloc(nthreads*sizeof(dmnsn_raytrace_payload));
+ threads = dmnsn_malloc(nthreads*sizeof(pthread_t));
/* Set up the progress object */
dmnsn_new_progress_element(payload->progress,
payload->scene->canvas->y);
/* Create the payloads */
+ unsigned int i;
for (i = 0; i < nthreads; ++i) {
payloads[i] = *payload;
payloads[i].index = i;
@@ -156,62 +131,38 @@ dmnsn_raytrace_scene_multithread(dmnsn_raytrace_payload *payload)
&dmnsn_raytrace_scene_multithread_thread,
&payloads[i]) != 0)
{
- for (j = 0; j < i; ++j) {
- if (pthread_join(threads[j], &ptr)) {
- dmnsn_error(DMNSN_SEVERITY_MEDIUM,
- "Couldn't join worker thread in failed raytrace engine"
- " initialization.");
- } else {
- /* Only free on a successful join - otherwise we might free a pointer
- out from under a running thread */
- dmnsn_delete_bvst(payloads[j].bvst);
- free(ptr);
- }
- }
-
- free(payloads);
- return -1;
+ dmnsn_error(DMNSN_SEVERITY_HIGH,
+ "Couldn't start worker thread in raytrace engine.");
}
}
for (i = 0; i < nthreads; ++i) {
- if (pthread_join(threads[i], &ptr)) {
+ if (pthread_join(threads[i], NULL)) {
dmnsn_error(DMNSN_SEVERITY_MEDIUM,
"Couldn't join worker thread in raytrace engine.");
} else {
- if (retval == 0) {
- retval = *(int *)ptr;
- }
dmnsn_delete_bvst(payloads[i].bvst);
- free(ptr);
}
}
free(threads);
free(payloads);
- return retval;
}
/* Actual raytracing implementation */
-static int dmnsn_raytrace_scene_impl(dmnsn_progress *progress,
- dmnsn_scene *scene,
- dmnsn_bvst *bvst,
- unsigned int index, unsigned int threads);
+static void dmnsn_raytrace_scene_impl(dmnsn_progress *progress,
+ dmnsn_scene *scene,
+ dmnsn_bvst *bvst,
+ unsigned int index, unsigned int threads);
/* Multi-threading thread callback */
static void *
dmnsn_raytrace_scene_multithread_thread(void *ptr)
{
dmnsn_raytrace_payload *payload = ptr;
- int *retval = malloc(sizeof(int));
- if (retval) {
- *retval = dmnsn_raytrace_scene_impl(payload->progress, payload->scene,
- payload->bvst,
- payload->index, payload->threads);
- } else {
- errno = ENOMEM;
- }
- return retval;
+ dmnsn_raytrace_scene_impl(payload->progress, payload->scene,
+ payload->bvst, payload->index, payload->threads);
+ return NULL;
}
/*
@@ -242,7 +193,7 @@ static dmnsn_color dmnsn_raytrace_shoot(dmnsn_raytrace_state *state,
dmnsn_line ray);
/* Actually raytrace a scene */
-static int
+static void
dmnsn_raytrace_scene_impl(dmnsn_progress *progress, dmnsn_scene *scene,
dmnsn_bvst *bvst,
unsigned int index, unsigned int threads)
@@ -283,8 +234,6 @@ dmnsn_raytrace_scene_impl(dmnsn_progress *progress, dmnsn_scene *scene,
dmnsn_increment_progress(progress);
}
-
- return 0;
}
#define ITEXTURE(state) (state->intersection->texture)
diff --git a/libdimension/reflective.c b/libdimension/reflective.c
index 2e90b8f..24b6efb 100644
--- a/libdimension/reflective.c
+++ b/libdimension/reflective.c
@@ -20,7 +20,6 @@
#include "dimension.h"
#include <errno.h>
-#include <stdlib.h> /* For malloc */
#include <math.h>
/*
@@ -50,21 +49,16 @@ dmnsn_finish *
dmnsn_new_reflective_finish(dmnsn_color min, dmnsn_color max, double falloff)
{
dmnsn_finish *finish = dmnsn_new_finish();
- if (finish) {
- dmnsn_reflection_params *params = malloc(sizeof(dmnsn_reflection_params));
- if (!params) {
- dmnsn_delete_finish(finish);
- errno = ENOMEM;
- return NULL;
- }
- params->min = min;
- params->max = max;
- params->falloff = falloff;
+ dmnsn_reflection_params *params
+ = dmnsn_malloc(sizeof(dmnsn_reflection_params));
+ params->min = min;
+ params->max = max;
+ params->falloff = falloff;
+
+ finish->ptr = params;
+ finish->reflection_fn = &dmnsn_reflective_finish_fn;
+ finish->free_fn = &free;
- finish->ptr = params;
- finish->reflection_fn = &dmnsn_reflective_finish_fn;
- finish->free_fn = &free;
- }
return finish;
}
diff --git a/libdimension/scene.c b/libdimension/scene.c
index 4595afd..dbda90b 100644
--- a/libdimension/scene.c
+++ b/libdimension/scene.c
@@ -20,37 +20,28 @@
#include "dimension.h"
#include <errno.h>
-#include <stdlib.h> /* For malloc */
#include <unistd.h> /* For sysconf */
/* Allocate an empty scene */
dmnsn_scene *
dmnsn_new_scene()
{
- dmnsn_scene *scene = malloc(sizeof(dmnsn_scene));
- if (scene) {
- scene->default_texture = dmnsn_new_texture();
- if (!scene->default_texture) {
- dmnsn_delete_scene(scene);
- errno = ENOMEM;
- return NULL;
- }
+ dmnsn_scene *scene = dmnsn_malloc(sizeof(dmnsn_scene));
- scene->camera = NULL;
- scene->canvas = NULL;
- scene->objects = dmnsn_new_array(sizeof(dmnsn_object *));
- scene->lights = dmnsn_new_array(sizeof(dmnsn_light *));
- scene->quality = DMNSN_RENDER_FULL;
- scene->reclimit = 5;
+ scene->default_texture = dmnsn_new_texture();
+ scene->camera = NULL;
+ scene->canvas = NULL;
+ scene->objects = dmnsn_new_array(sizeof(dmnsn_object *));
+ scene->lights = dmnsn_new_array(sizeof(dmnsn_light *));
+ scene->quality = DMNSN_RENDER_FULL;
+ scene->reclimit = 5;
+
+ /* Find the number of processors/cores running (TODO: do this portably) */
+ int nprocs = sysconf(_SC_NPROCESSORS_ONLN);
+ if (nprocs < 1)
+ nprocs = 1;
+ scene->nthreads = nprocs;
- /* Find the number of processors/cores running (TODO: do this portably) */
- int nprocs = sysconf(_SC_NPROCESSORS_ONLN);
- if (nprocs < 1)
- nprocs = 1;
- scene->nthreads = nprocs;
- } else {
- errno = ENOMEM;
- }
return scene;
}
diff --git a/libdimension/solid_pigment.c b/libdimension/solid_pigment.c
index a69e25a..e414fc2 100644
--- a/libdimension/solid_pigment.c
+++ b/libdimension/solid_pigment.c
@@ -20,7 +20,6 @@
#include "dimension.h"
#include <errno.h>
-#include <stdlib.h> /* For malloc */
/* Solid color pigment callback */
static dmnsn_color dmnsn_solid_pigment_fn(const dmnsn_pigment *pigment,
@@ -30,21 +29,14 @@ static dmnsn_color dmnsn_solid_pigment_fn(const dmnsn_pigment *pigment,
dmnsn_pigment *
dmnsn_new_solid_pigment(dmnsn_color color)
{
- dmnsn_color *solid;
dmnsn_pigment *pigment = dmnsn_new_pigment();
- if (pigment) {
- solid = malloc(sizeof(dmnsn_color));
- if (!solid) {
- dmnsn_delete_pigment(pigment);
- errno = ENOMEM;
- return NULL;
- }
- *solid = color;
- pigment->pigment_fn = &dmnsn_solid_pigment_fn;
- pigment->free_fn = &free;
- pigment->ptr = solid;
- }
+ dmnsn_color *solid = dmnsn_malloc(sizeof(dmnsn_color));
+ *solid = color;
+
+ pigment->pigment_fn = &dmnsn_solid_pigment_fn;
+ pigment->free_fn = &free;
+ pigment->ptr = solid;
return pigment;
}
diff --git a/libdimension/sphere.c b/libdimension/sphere.c
index 7c2894b..77fd1d4 100644
--- a/libdimension/sphere.c
+++ b/libdimension/sphere.c
@@ -19,7 +19,6 @@
*************************************************************************/
#include "dimension.h"
-#include <stdlib.h> /* For malloc */
#include <math.h> /* For sqrt */
/*
@@ -39,12 +38,10 @@ dmnsn_object *
dmnsn_new_sphere()
{
dmnsn_object *sphere = dmnsn_new_object();
- if (sphere) {
- sphere->intersection_fn = &dmnsn_sphere_intersection_fn;
- sphere->inside_fn = &dmnsn_sphere_inside_fn;
- sphere->bounding_box.min = dmnsn_new_vector(-1.0, -1.0, -1.0);
- sphere->bounding_box.max = dmnsn_new_vector(1.0, 1.0, 1.0);
- }
+ sphere->intersection_fn = &dmnsn_sphere_intersection_fn;
+ sphere->inside_fn = &dmnsn_sphere_inside_fn;
+ sphere->bounding_box.min = dmnsn_new_vector(-1.0, -1.0, -1.0);
+ sphere->bounding_box.max = dmnsn_new_vector(1.0, 1.0, 1.0);
return sphere;
}
diff --git a/libdimension/texture.c b/libdimension/texture.c
index 28f5033..7feb0e0 100644
--- a/libdimension/texture.c
+++ b/libdimension/texture.c
@@ -20,18 +20,13 @@
#include "dimension.h"
#include <errno.h>
-#include <stdlib.h> /* For malloc */
/* Allocate a dummy pigment */
dmnsn_pigment *
dmnsn_new_pigment()
{
- dmnsn_pigment *pigment = malloc(sizeof(dmnsn_pigment));
- if (pigment) {
- pigment->free_fn = NULL;
- } else {
- errno = ENOMEM;
- }
+ dmnsn_pigment *pigment = dmnsn_malloc(sizeof(dmnsn_pigment));
+ pigment->free_fn = NULL;
return pigment;
}
@@ -51,16 +46,12 @@ dmnsn_delete_pigment(dmnsn_pigment *pigment)
dmnsn_finish *
dmnsn_new_finish()
{
- dmnsn_finish *finish = malloc(sizeof(dmnsn_finish));
- if (finish) {
- finish->diffuse_fn = NULL;
- finish->specular_fn = NULL;
- finish->ambient_fn = NULL;
- finish->reflection_fn = NULL;
- finish->free_fn = NULL;
- } else {
- errno = ENOMEM;
- }
+ dmnsn_finish *finish = dmnsn_malloc(sizeof(dmnsn_finish));
+ finish->diffuse_fn = NULL;
+ finish->specular_fn = NULL;
+ finish->ambient_fn = NULL;
+ finish->reflection_fn = NULL;
+ finish->free_fn = NULL;
return finish;
}
@@ -80,13 +71,9 @@ dmnsn_delete_finish(dmnsn_finish *finish)
dmnsn_texture *
dmnsn_new_texture()
{
- dmnsn_texture *texture = malloc(sizeof(dmnsn_texture));
- if (texture) {
- texture->pigment = NULL;
- texture->finish = NULL;
- } else {
- errno = ENOMEM;
- }
+ dmnsn_texture *texture = dmnsn_malloc(sizeof(dmnsn_texture));
+ texture->pigment = NULL;
+ texture->finish = NULL;
return texture;
}