1 /**********
2 *
3 * Copyright (c) 2003, Division of Imaging Science and Biomedical Engineering,
4 * University of Manchester, UK. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without modification,
7 * are permitted provided that the following conditions are met:
8 *
9 * . Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * . Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
15 *
16 * . Neither the name of the University of Manchester nor the names of its
17 * contributors may be used to endorse or promote products derived from this
18 * software without specific prior written permission.
19 *
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 **********
34 *
35 * Program : TINA
36 * File : $Source: /home/tina/cvs/tina-libs/tina/image/imgGen_alloc.c,v $
37 * Date : $Date: 2004/08/05 14:32:44 $
38 * Version : $Revision: 1.8 $
39 * CVS Id : $Id: imgGen_alloc.c,v 1.8 2004/08/05 14:32:44 neil Exp $
40 *
41 * Author : Legacy TINA
42 */
43
44 /**
45 * @file
46 * @brief Allocation and copying of Imrect - Tina's generic image structure.
47 *
48 * Imrect is:
49 * Ts_id ts_id The TINA structure identifier.
50 * Vartype vtype The variable type of the image data.
51 * int width, height The width and height of the image.
52 * Imregion *region The region coveredby the image.
53 * void *data Array of pointers to the image rows.
54 * List *props Properties list: covers all the extras for an edge rect.
55 */
56
57
58 #include "imgGen_alloc.h"
59
60 #if HAVE_CONFIG_H
61 #include <config.h>
62 #endif
63
64
65 #include <stdio.h>
66 #include <memory.h>
67 #include <tina/sys/sysDef.h>
68 #include <tina/sys/sysPro.h>
69 #include <tina/image/img_GenDef.h>
70 #include <tina/image/imgGen_region.h>
71
72
73 /**
74 * @brief Allocates an imrect structure.
75 * @param height The image height (i.e. no of rows).
76 * @param width The image width (i.e. length of rows).
77 * @param region Pointer to the roi: the region covered.
78 * @param vtype The variable type of the image data.
79 * @return image Pointer to the allocated imrect
80 *
81 * Image allocation. Allocate memory for Imrect data structure and for
82 * region of interest (roi) i.e. Imrect (image rectangle) and imregion. Set
83 * roi co-ordinates (top-left bottom-right). Allocate memory for image data.
84 * Note that if the argument roi is NULL, a roi will be allocated from 0 to height
85 * and 0 to width; if not, the argument roi will be copied i.e. a new roi is
86 * always allocated.
87 */
88 Imrect *im_alloc(int height, int width, Imregion * region, Vartype vtype)
89 {
90 Imrect *image;
91 /*
92 Imregion *roi_alloc();
93 Imregion *roi_copy();
94
95 void **narray_alloc();
96 */
97
98 int lx, ly, ux, uy;
99
100 if (region == NULL) /* alloc whole image */
101 region = roi_alloc(0, 0, width, height);
102 else /* use copy of given region */
103 region = roi_copy(region);
104
105 if (region == NULL)
106 return (NULL);
107
108 lx = region->lx;
109 ly = region->ly;
110 ux = region->ux;
111 uy = region->uy;
112
113 image = ts_ralloc(Imrect);
114
115 image->height = height;
116 image->width = width;
117 image->vtype = vtype;
118 image->region = region;
119 image->props = NULL;
120 if (vtype == complex_v)
121 {
122 image->data = (void *) ts_narray_alloc(ly, lx, uy, ux, Complex);
123 } else
124 {
125 image->data = (void *) narray_alloc(ly, lx, uy, ux, var_size(vtype));
126 }
127
128 return image;
129 }
130
131
132 /**
133 * @brief Wrap an imrect data structure around the contiguous block of memory.
134 * @param mem_ptr Pointer to a contiguous memory block to be wrapped in an imrect.
135 * @param height The height of the image i.e. no. of rows.
136 * @param width The width of the image i.e. length of rows.
137 * @param region The region covered.
138 * @param vtype The variable type of the image data.
139 * @return image Pointer to the allocated imrect.
140 *
141 * Wrap an imrect data structure around the contiguous block of memory
142 * specified by the region and vtype arguments. Note that if the argument region
143 * is NULL, a region will be allocated from 0 to height and 0 to width; if not, the
144 * argument region will be copied i.e. a new region is always allocated.
145 */
146 Imrect *im_wrap_contig(void *mem_ptr, int height, int width,
147 Imregion * region, Vartype vtype)
148 {
149 Imrect *image;
150 Imregion *roi_alloc();
151 Imregion *roi_copy();
152 int i;
153 int lx, ly, ux, uy;
154 int roi_width;
155 unsigned int vsize;
156 void *nvector_alloc();
157 void **data;
158
159 if (region == NULL) /* alloc whole image */
160 region = roi_alloc(0, 0, width, height);
161 else /* use copy of given region */
162 region = roi_copy(region);
163
164 if (region == NULL)
165 return (NULL);
166
167 lx = region->lx;
168 ly = region->ly;
169 ux = region->ux;
170 uy = region->uy;
171 roi_width = ux - lx;
172
173 image = ts_ralloc(Imrect);
174
175 image->height = height;
176 image->width = width;
177 image->vtype = vtype;
178 image->region = region;
179 image->props = NULL;
180
181 data = (void **) nvector_alloc(ly, uy, sizeof(void *));
182 image->data = (void *) data;
183
184 vsize = var_size(vtype);
185
186 for (i = ly; i < uy; ++i)
187 data[i] =
188 (void *) ((int) mem_ptr + (roi_width * (i - ly) - lx) * vsize);
189
190 return image;
191 }
192
193
194 /**
195 * @brief Copy specified roi of image1 to image2 through a double.
196 * @param image1 Pointer to the image acting as a data source.
197 * @param image2 Pointer to the image acting as a data destination.
198 * @param roi The region of image1 to be copied into image 2.
199 * @return void
200 *
201 * Copy specified roi of image1 to image2 through a double. Storage must
202 * already be allocated for image2.
203 */
204 static void write_thro_double(Imrect * image1, Imrect * image2,
205 Imregion * roi)
206 {
207 int lx, ly, ux, uy;
208 int i, j;
209 double gl;
210
211
212 lx = roi->lx;
213 ly = roi->ly;
214 ux = roi->ux;
215 uy = roi->uy;
216
217 for (i = ly; i < uy; ++i)
218 for (j = lx; j < ux; ++j)
219 {
220 IM_PIX_GET(image1, i, j, gl);
221 IM_PIX_SET(image2, i, j, gl);
222 }
223 }
224
225
226 /**
227 * @brief Copy specified roi of image1 to image2 through type int (ok for ptr).
228 * @param image1 Pointer to the image acting as a data source.
229 * @param image2 Pointer to the image acting as a data destination.
230 * @param roi The region of image1 to be copied into image 2.
231 * @return void
232 *
233 * Copy specified roi of image1 to image2 through type int (ok for ptr).
234 * Storage must already be allocated for image2.
235 */
236 static void write_thro_int(Imrect * image1, Imrect * image2,
237 Imregion * roi)
238 {
239 int lx, ly, ux, uy;
240 int i, j;
241 double gl;
242
243 lx = roi->lx;
244 ly = roi->ly;
245 ux = roi->ux;
246 uy = roi->uy;
247
248 for (i = ly; i < uy; ++i)
249 for (j = lx; j < ux; ++j)
250 {
251 IM_PIX_GET(image1, i, j, gl);
252 IM_PIX_SET(image2, i, j, (int) gl);
253 }
254 }
255
256
257 /**
258 * @brief Copy specified roi of image1 to image2 through type complex.
259 * @param image1 Pointer to the image acting as a data source.
260 * @param image2 Pointer to the image acting as a data destination.
261 * @param roi The region of image1 to be copied into image 2.
262 * @return void
263 *
264 * Copy specified roi of image1 to image2 through type complex.
265 * Storage must already be allocated for image2.
266 */
267 static void write_thro_complex(Imrect * image1, Imrect * image2,
268 Imregion * roi)
269 {
270 int lx, ly, ux, uy;
271 int i, j;
272 Complex gl = {Complex_id};
273
274 lx = roi->lx;
275 ly = roi->ly;
276 ux = roi->ux;
277 uy = roi->uy;
278
279 for (i = ly; i < uy; ++i)
280 for (j = lx; j < ux; ++j)
281 {
282 IM_PIX_GETZ(image1, i, j, gl);
283 IM_PIX_SETZ(image2, i, j, gl);
284 }
285 }
286
287
288 /**
289 * @brief Overwrite region of image2 by region of image1.
290 * @param image2 Pointer to the image acting as a data destination.
291 * @param image1 Pointer to the image acting as a data source.
292 * @return void
293 *
294 * Overwrite region of image2 by region of image1. The region used is the
295 * intersection of the roi's of image1 and image2. Storage must already be
296 * allocated for image2.
297 */
298 void im_copy_inplace(Imrect * image2, Imrect * image1)
299 {
300 Imregion *roi;
301 Imregion *roi_inter();
302 Vartype vtype;
303
304 if (image1 == NULL || image2 == NULL)
305 return;
306
307 roi = roi_inter(image1->region, image2->region);
308 if (!roi)
309 {
310 errorf(warning, "im_copy_inplace() regions do not overlap\n");
311 return;
312 }
313 vtype = (Vartype) MAX((int) image1->vtype, (int) image2->vtype);
314
315 if (image1->vtype != image2->vtype
316 || (int) image1->vtype > (int) complex_v)
317 {
318 switch (vtype)
319 {
320 case char_v:
321 case uchar_v:
322 case short_v:
323 case ushort_v:
324 case int_v:
325 case uint_v:
326 case ptr_v:
327 write_thro_int(image1, image2, roi);
328 break;
329 case float_v:
330 case double_v:
331 write_thro_double(image1, image2, roi);
332 break;
333 case complex_v:
334 write_thro_complex(image1, image2, roi);
335 break;
336 case vram0_v:
337 case vram1_v:
338 case vram2_v:
339 case vram3_v:
340 write_thro_int(image1, image2, roi);
341 break;
342 default:
343 error("Cannot copy this image type", fatal);
344 break;
345 }
346 } else
347 {
348 /* same type */
349 int lx, ly, ux, uy;
350 int nchars;
351 unsigned int vsize;
352 int i;
353 char **array1 = (char **) image1->data;
354 char **array2 = (char **) image2->data;
355
356 vsize = var_size(image1->vtype);
357
358 lx = roi->lx;
359 ly = roi->ly;
360 ux = roi->ux;
361 uy = roi->uy;
362 lx *= vsize;
363 ux *= vsize;
364 nchars = ux - lx;
365
366 for (i = ly; i < uy; ++i)
367 (void) memcpy(array2[i] + lx, array1[i] + lx, nchars);
368 }
369
370 rfree((void *) (char *) roi);
371 }
372
373
374 /**
375 * @brief Make new copy of specified roi of image.
376 * @param image Image acting as a data source.
377 * @param region The region of the image to be copied.
378 * @return subimage Pointer to the new image.
379 *
380 * Make new copy of specified roi of image. Allocate storage for new copy.
381 * Copy specified roi of image into it. Return pointer to it.
382 */
383 Imrect *im_subim(Imrect * image, Imregion * region)
384 {
385 Imregion *subregion;
386 Imregion *roi_inter();
387 Imrect *subimage;
388
389 if (image == NULL)
390 return (NULL);
391
392 subregion = roi_inter(region, image->region);
393 if (subregion == NULL)
394 return (NULL);
395
396 subimage =
397 im_alloc(image->height, image->width, subregion, image->vtype);
398 rfree((void *) (char *) subregion);
399 im_copy_inplace(subimage, image);
400 return (subimage);
401 }
402
403
404 /**
405 * @brief Make new copy of image of given type.
406 * @param image Pointer to the image to be copied.
407 * @param vtype The variable type of the image data.
408 * @return copy Pointer to the copy of the input image.
409 *
410 * Make new copy of image of given type. Allocate storage for new copy. Copy
411 * whole image into it. Return pointer to it.
412 */
413 Imrect *im_cast(Imrect * image, Vartype vtype)
414 {
415 Imrect *copy;
416
417 if (image == NULL)
418 return (NULL);
419
420 copy = im_alloc(image->height, image->width, image->region, vtype);
421 im_copy_inplace(copy, image);
422
423 return (copy);
424 }
425
426
427 /**
428 * @brief Make new copy of an image.
429 * @param image Pointer to the image to be copied.
430 * @return copy Pointer to the copy of the input image.
431 *
432 * Make new copy of image. Allocate storage for new copy. Copy whole image
433 * into it. Return pointer to it.
434 */
435 Imrect *im_copy(Imrect * image)
436 {
437 Imrect *copy;
438
439 if (image == NULL)
440 return (NULL);
441
442 copy =
443 im_alloc(image->height, image->width, image->region, image->vtype);
444 im_copy_inplace(copy, image);
445
446 return (copy);
447 }
448
449
450 /**
451 * @brief Free an imrect structure.
452 * @param image Pointer to the imrect structure to be freed.
453 * @return void
454 *
455 * Free an imrect structure. All elements are freed: the data array, the region, and
456 * the proplist.
457 */
458 void im_free(Imrect * image)
459 {
460 int lx, ly, ux, uy;
461 unsigned int vsize;
462
463 if (image == NULL)
464 return;
465
466 proplist_freelist(image->props);
467
468 lx = image->region->lx;
469 ly = image->region->ly;
470 ux = image->region->ux;
471 uy = image->region->uy;
472
473 vsize = var_size(image->vtype);
474 narray_free((char **) image->data, ly, lx, uy, ux, vsize);
475 rfree((void *) image->region);
476 rfree((void *) image);
477 }
478
479
480 /**
481 * @brief Shift the data and roi of an image.
482 * @param im Pointer to the image to be shifted.
483 * @param dy Shift applied to the rows.
484 * @param dx Shift applied to the columns.
485 * @return void.
486 *
487 * Shifts data and roi of an image by dy rows and dx cols, cheaply, in place
488 */
489 void im_shift(Imrect * im, int dy, int dx)
490 {
491 Imregion *roi;
492 int y, ly, uy;
493 unsigned int vsize;
494 void *row;
495
496 if (im == NULL)
497 return;
498
499 roi = im->region;
500 ly = roi->ly;
501 uy = roi->uy;
502 vsize = var_size(im->vtype);
503
504 for (y = ly; y < uy; y++)
505 {
506 IM_ROW_GET(im, y, row);
507 /*
508 row = (void *) ((int) row - vsize * dx);
509 */
510 row = nvector_shift(row, roi->lx, roi->lx + dx, vsize);
511 IM_ROW_SET(im, y, row);
512 }
513 /*
514 im->data = (void **) im->data - dy;
515 */
516 im->data = nvector_shift((void **) im->data, roi->ly, roi->ly + dy,
517 var_size(ptr_v));
518
519 roi->lx += dx;
520 roi->ux += dx;
521 roi->ly += dy;
522 roi->uy += dy;
523 }
524
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.