bugs: Suggest possible naming and labeling approaches for code targeted at client...
[libale.git] / src / image.c
blob408f325ad5061431a08ca6da40361302cd518834
1 /*
2 * Copyright 2008, 2009 David Hilvert <dhilvert@gmail.com>
4 * This file is part of libale.
6 * libale is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU Affero General Public License as published by the Free
8 * Software Foundation, either version 3 of the License, or (at your option)
9 * any later version.
11 * libale is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
14 * more details.
16 * You should have received a copy of the GNU Affero General Public License
17 * along with libale. If not, see <http://www.gnu.org/licenses/>.
20 #include "libale.h"
23 * Infrastructure.
26 typedef union {
27 libale_voidp mem;
28 libale_filep file;
29 } image_buffer;
32 * API types.
35 TYPE_STRUCTURE(ale_image, \
36 size_t height; \
37 size_t width; \
38 int type; \
39 int format; \
40 ale_context ac; \
41 int buffer_type; \
42 int buffer_static; \
43 image_buffer buffer;)
45 static void release_memory(ale_image ai) {
47 DQ(ale_image, ai, qai)
49 if (qai->buffer_type == ALE_BUFFER_CL)
50 ale_context_mrelease(qai->ac, LIBALE_INDEX_TO_MEMENTRY(qai->buffer.mem));
51 else if (qai->buffer_type == ALE_BUFFER_HOST && !qai->buffer_static)
52 free(P(qai->buffer.mem));
53 else if (qai->buffer_type == ALE_BUFFER_FILE && !qai->buffer_static)
54 fclose(P(qai->buffer.file));
56 qai->buffer_type = ALE_BUFFER_HOST;
57 P(qai->buffer.mem) = NULL;
60 TYPE_COMMON_FUNCTIONS(ale_image, \
61 release_memory(this);)
64 * API Implementation.
67 ale_image ale_new_image(ale_context ac, int format, int type) {
68 if (!ale_context_valid(ac))
69 return N(ale_image);
71 if (type != ALE_TYPE_FLOAT_32 && type != ALE_TYPE_FLOAT_64)
72 return N(ale_image);
74 ale_image ai = ale_image_alloc(ac);
76 if (!ale_image_valid(ai))
77 return N(ale_image);
79 DQ(ale_image, ai, qai)
81 qai->type = type;
82 qai->format = format;
83 qai->width = 0;
84 qai->height = 0;
85 qai->ac = ac;
86 qai->buffer_type = ALE_BUFFER_HOST;
87 P(qai->buffer.mem) = NULL;
89 return ai;
92 int ale_resize_image(ale_image ai, int x_offset, int y_offset, size_t width, size_t height) {
93 #warning function unfinished.
96 int ale_image_set_cl(ale_image ai, size_t width, size_t height, cl_mem buffer) {
97 if (!ale_image_valid(ai))
98 return ALE_UNSPECIFIED_FAILURE;
100 if (buffer == ((cl_mem) 0))
101 return ALE_UNSPECIFIED_FAILURE;
103 release_memory(ai);
105 DQ(ale_image, ai, qai)
107 qai->buffer_type = ALE_BUFFER_CL;
108 qai->buffer.mem.t.index = LIBALE_MEMENTRY_TO_INDEX(ale_context_mref(qai->ac, buffer));
109 qai->width = width;
110 qai->height = height;
112 if (qai->buffer.mem.t.index == 0)
113 return ALE_UNSPECIFIED_FAILURE;
115 return ALE_SUCCESS;
118 int ale_image_set_host_dynamic(ale_image ai, size_t width, size_t height, void *buffer) {
119 #warning unimplemented function
120 return ALE_UNSPECIFIED_FAILURE;
123 int ale_image_set_host_static(ale_image ai, size_t width, size_t height, void *buffer, void (*release_callback)(void *), void *callback_data) {
124 #warning unimplemented function
125 return ALE_UNSPECIFIED_FAILURE;
128 PARAMETER_R(ale_image, buffer_type, int)
130 cl_mem ale_image_retain_cl(ale_image ai) {
131 if (!ale_image_valid(ai) || Q(ale_image, ai)->buffer_type != ALE_BUFFER_CL)
132 return ((cl_mem) 0);
134 DQ(ale_image, ai, qai)
136 return ale_context_mretain(qai->ac, LIBALE_INDEX_TO_MEMENTRY(qai->buffer.mem));
139 void *ale_image_retain_host(ale_image ai) {
140 #warning function unimplemented
141 return NULL;
144 FILE *ale_image_retain_file(ale_image ai) {
145 #warning function unimplemented
146 return NULL;
149 int ale_image_release_host(ale_image ai, void *hi) {
150 #warning function unimplemented
151 return 0;
154 int ale_image_release_file(ale_image ai, FILE *fi) {
155 #warning function unimplemented
156 return 0;
159 ale_image ale_image_nn_fill(ale_image ai, double defined_radius) {
160 #warning raw imported code should be revised for libale
162 #if 0
164 * Original ALE header copyright notice gives '2002 David Hilvert' for the
165 * following, but git-blame (correctly) gives 2005.
168 * Get nearest-neighbor defined values.
170 * XXX: While this implementation is correct, it is inefficient
171 * for large radii. A better implementation would search
172 * perimeters of squares of ever-increasing radius, tracking
173 * the best-so-far data until the square perimeter exceeded the
174 * best-so-far radius.
177 for (int k = 0; k < 3; k++)
178 if (isnan(value[k]))
179 for (int radius = 1; radius <= nn_defined_radius; radius++) {
180 double nearest_radius_squared = (radius + 1) * (radius + 1);
181 for (int ii = -radius; ii <= radius; ii++)
182 for (int jj = -radius; jj <= radius; jj++) {
183 if (!im->in_bounds(point(i + ii, j + jj)))
184 continue;
185 if (ii * ii + jj * jj < nearest_radius_squared
186 && finite(im->get_pixel(i + ii, j + jj)[k])) {
187 value[k] = im->get_pixel(i + ii, j + jj)[k];
188 nearest_radius_squared = ii * ii + jj * jj;
191 if (nearest_radius_squared < (radius + 1) * (radius + 1))
192 break;
196 * Unlinearize
199 pixel unlinearized(exp->unlinearize((value - minval_pixel)
200 / (maxval - minval)));
202 unlinearized = unlinearized.clamp();
203 #endif
206 ale_image ale_image_get_weights(ale_image ai) {
207 #warning function unimplemented
208 return N(ale_image);
211 PARAMETER_R(ale_image, height, size_t)
212 PARAMETER_R(ale_image, width, size_t)
213 PARAMETER_R(ale_image, type, int)
214 PARAMETER_R(ale_image, format, int)