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_get.c,v $
37 * Date : $Date: 2004/08/05 14:32:44 $
38 * Version : $Revision: 1.7 $
39 * CVS Id : $Id: imgGen_get.c,v 1.7 2004/08/05 14:32:44 neil Exp $
40 */
41 /**
42 * @file
43 * @brief Pixel level read access to Imrect data.
44 *
45 * This includes sub-pixel access via bi-linear interpolation and access access to lines of data by row, column and diagonals.
46 *
47 */
48
49
50 #include "imgGen_get.h"
51
52 #if HAVE_CONFIG_H
53 #include <config.h>
54 #endif
55
56 #include <stdio.h>
57 #include <tina/sys/sysPro.h>
58 #include <tina/sys/sysDef.h>
59 #include <tina/math/mathPro.h>
60 #include <tina/math/mathDef.h>
61 #include <tina/image/img_GenDef.h>
62
63
64 /**
65 * @brief Reads a value from the specified coordinates of an image, casting it to an integer.
66 * @param image The image to read data from.
67 * @param i The x coordinate of the desired pixel.
68 * @param j The y coordinate of the desired pixel.
69 * @return pixval The value of the pixel at the specified coordinates, cast to an integer.
70 *
71 * Returns zero for an image of pointers, or if the coordinates lie outside the image. If not, the pixel
72 * value is cast to an integer and returned.
73 */
74 int im_get_pix(Imrect * image, int i, int j)
75 {
76 Imregion *region;
77 double pixval;
78
79 if (image == NULL || image->vtype == ptr_v)
80 return (0);
81
82 region = image->region;
83 if (i < region->ly || i >= region->uy || j < region->lx
84 || j >= region->ux)
85 return (0);
86
87 IM_PIX_GET(image, i, j, pixval);
88
89 return ((int) pixval);
90 }
91
92
93 /**
94 * @brief Returns the pointer to the specified coordinates of an image of pointers.
95 * @param image The image to read data from.
96 * @param i The x coordinate of the desired pixel.
97 * @param j The y coordinate of the desired pixel.
98 * @return IM_PTR Pointer to the desired pixel
99 *
100 * Only useful for images of pointers.
101 */
102 void *im_get_ptr(Imrect * image, int i, int j)
103 {
104 Imregion *region;
105
106 if (image == NULL || image->vtype != ptr_v)
107 return (NULL);
108
109 region = image->region;
110 if (i < region->ly || i >= region->uy || j < region->lx
111 || j >= region->ux)
112 return (NULL);
113
114 return (IM_PTR(image, i, j));
115 }
116
117
118 /**
119 * @brief Reads a value, as a double, from the specified coordinates of an image.
120 * @param image The image to read data from.
121 * @param i The x coordinate of the desired pixel.
122 * @param j The y coordinate of the desired pixel.
123 * @return pixval The value of the pixel at the specified coordinates, cast to a double.
124 *
125 * Returns zero for an image of pointers, or if the coordinates lie outside the image. If not, the pixel
126 * value is cast to an double and returned.
127 */
128 double im_get_pixf(Imrect * image, int i, int j)
129 {
130 Imregion *region;
131 double pixval;
132
133 if (image == NULL || image->vtype == ptr_v)
134 return (0);
135
136 region = image->region;
137 if (i < region->ly || i >= region->uy || j < region->lx
138 || j >= region->ux)
139 return (0);
140
141 IM_PIX_GET(image, i, j, pixval);
142
143 return (pixval);
144 }
145
146
147 /**
148 * @brief Reads a value from the specified coordinates of a complex image.
149 * @param image The image to read data from.
150 * @param i The x coordinate of the desired pixel.
151 * @param j The y coordinate of the desired pixel.
152 * @return pixval The value of the pixel at the specified coordinates, as a complex number.
153 *
154 * Returns complex zero for an image of pointers, or if the coordinates lie outside the image. If not, the pixel
155 * value as a complex number is returned.
156 */
157 Complex im_get_pixz(Imrect * image, int i, int j)
158 {
159 Imregion *region;
160 Complex pixval = {Complex_id};
161
162 if (image == NULL || image->vtype == ptr_v)
163 return (cmplx_zero());
164
165 region = image->region;
166 if (i < region->ly || i >= region->uy || j < region->lx
167 || j >= region->ux)
168 return (cmplx_zero());
169
170 if (image->vtype == complex_v)
171 pixval = IM_COMPLEX(image, i, j);
172 else
173 {
174 pixval.y = 0.0;
175 IM_PIX_GET(image, i, j, pixval.x);
176 }
177 return (pixval);
178 }
179
180
181 /**
182 * @brief Uses bi-linear interpolation to read a value from an image at the desired coordinates, casting it to an integer.
183 * @param image The image to read data from.
184 * @param r The image coordinate, to sub-pixel accuracy, in the y direction.
185 * @param c The image coordinate, to sub-pixel accuracy, in the x direction.
186 * @return pixval The value at the desired image coordinates, cast to an integer.
187 *
188 * Equivalent function to im_get_pix, but supports sub-pixel accuracy through bi-linear interpolation.
189 * The pixel value at the desired coordinates is cast to an integer.
190 */
191 int im_sub_pix(Imrect * image, double r, double c)
192 {
193 Imregion *region;
194 int i, j;
195 double x1, x2, y1, y2;
196 double gl, pix11, pix12, pix21, pix22;
197 double pixval;
198
199 if (image == NULL || image->vtype == ptr_v)
200 return (0);
201
202 r -= 0.5;
203 c -= 0.5;
204
205 region = image->region;
206 if (r < region->ly || r + 1 >= region->uy || c < region->lx
207 || c + 1 >= region->ux)
208 return (0);
209
210 i = (int) r;
211 y1 = r - i;
212 y2 = 1.0 - y1;
213 j = (int) c;
214 x1 = c - j;
215 x2 = 1.0 - x1;
216
217 IM_PIX_GET(image, i, j, pix11);
218 IM_PIX_GET(image, i, j + 1, pix12);
219 IM_PIX_GET(image, i + 1, j, pix21);
220 IM_PIX_GET(image, i + 1, j + 1, pix22);
221
222 gl = (pix11 * x2 + pix12 * x1) * y2 + (pix21 * x2 + pix22 * x1) * y1;
223
224 pixval = (gl > 0) ? gl + 0.5 : gl - 0.5;
225 return ((int) pixval);
226 }
227
228
229 /**
230 * @brief Uses bi-linear interpolation to read a value from an image at the desired coordinates, casting it to a double.
231 * @param image The image to read data from.
232 * @param r The image coordinate, to sub-pixel accuracy, in the y direction.
233 * @param c The image coordinate, to sub-pixel accuracy, in the x direction.
234 * @return pixval The value at the desired image coordinates, cast to an double.
235 *
236 * Equivalent function to im_get_pixf, but supports sub-pixel accuracy through bi-linear interpolation.
237 * The pixel value at the desired coordinates is cast to an double.
238 */
239 double im_sub_pixf(Imrect * image, double r, double c)
240 {
241 Imregion *region;
242 int i, j;
243 double x1, x2, y1, y2;
244 double pix11, pix12, pix21, pix22;
245 double pixval;
246
247 if (image == NULL || image->vtype == ptr_v)
248 return (0);
249
250 r -= 0.5;
251 c -= 0.5;
252
253 region = image->region;
254 if (r < region->ly || r + 1 >= region->uy || c < region->lx
255 || c + 1 >= region->ux)
256 return (0);
257
258 i = (int) r;
259 y1 = r - i;
260 y2 = 1.0 - y1;
261 j = (int) c;
262 x1 = c - j;
263 x2 = 1.0 - x1;
264
265 IM_PIX_GET(image, i, j, pix11);
266 IM_PIX_GET(image, i, j + 1, pix12);
267 IM_PIX_GET(image, i + 1, j, pix21);
268 IM_PIX_GET(image, i + 1, j + 1, pix22);
269
270 pixval = (pix11 * x2 + pix12 * x1) * y2 + (pix21 * x2 + pix22 * x1) * y1;
271
272 return (pixval);
273 }
274
275
276 /**
277 * @brief Uses 2d quadratic interpolation to read a value from an image at the desired coordinates, casting it to a double.
278 * @param image The image to read data from.
279 * @param r The image coordinate, to sub-pixel accuracy, in the y direction.
280 * @param c The image coordinate, to sub-pixel accuracy, in the x direction.
281 * @return pixval The value at the desired image coordinates, cast to an double.
282 *
283 * Equivalent function to im_get_pixf and im_sub_pixf, but supports sub-pixel accuracy through 2d quadratic interpolation.
284 * The pixel value at the desired coordinates is cast to an double. NAT 10/10/90
285 */
286 double im_sub_pixqf(Imrect * image, double y, double x)
287 {
288 Imregion *region = image->region;
289 double pixval[3][3];
290 float a, b, c, d, e, f;
291 double inter;
292 int i, j, n, m;
293 float xs, ys;
294
295 i = tina_int(x - 1);
296 j = tina_int(y - 1);
297
298 xs = (float) (x - i - 1.5);
299 ys = (float) (y - j - 1.5);
300
301 if (j < region->ly || j > region->uy - 3
302 || i < region->lx || i > region->ux - 3)
303 return (0);
304 for (n = 0; n < 3; n++)
305 {
306 for (m = 0; m < 3; m++)
307 {
308 IM_PIX_GET(image, j + n, i + m, pixval[n][m]);
309 }
310 }
311
312 a = (float) pixval[1][1];
313 b = (float) ((pixval[0][2] - pixval[0][0]
314 + pixval[1][2] - pixval[1][0]
315 + pixval[2][2] - pixval[2][0]) / 6.0);
316 c = (float) ((pixval[2][0] - pixval[0][0]
317 + pixval[2][1] - pixval[0][1]
318 + pixval[2][2] - pixval[0][2]) / 6.0);
319 d = (float) ((pixval[0][0] - 2.0 * pixval[0][1] + pixval[0][2]
320 + 3.0 * pixval[1][0] - 6.0 * pixval[1][1] +
321 3.0 * pixval[1][2] + pixval[2][0] - 2.0 * pixval[2][1] +
322 pixval[2][2]) / 10.0);
323 e =
324 (float) ((pixval[0][0] - pixval[2][0] + pixval[2][2] - pixval[0][2])
325 / 4.0);
326 f =
327 (float) (
328 (pixval[0][0] + 3.0 * pixval[0][1] + pixval[0][2] -
329 2.0 * pixval[1][0] - 6.0 * pixval[1][1] -
330 2.0 * pixval[1][2] + pixval[2][0] + 3.0 * pixval[2][1] +
331 pixval[2][2]) / 10.0);
332
333 xs *= (float) 2.0;
334 ys *= (float) 2.0;
335 inter =
336 a + 0.5 * (b * xs + c * ys + d * xs * xs + e * xs * ys +
337 f * ys * ys);
338
339 return (inter);
340 }
341
342
343 /**
344 * @brief Uses bi-linear interpolation to read a value from a complex image at the desired coordinates.
345 * @param image The complex image to read data from.
346 * @param r The image coordinate, to sub-pixel accuracy, in the y direction.
347 * @param c The image coordinate, to sub-pixel accuracy, in the x direction.
348 * @return pixval The value at the desired image coordinates, as a complex number.
349 *
350 * Equivalent function to im_get_pixz, but supports sub-pixel accuracy through bi-linear interpolation.
351 * The pixel value at the desired coordinates is returned as a complex number.
352 */
353 Complex im_sub_pixz(Imrect * im, double y, double x)
354 {
355 int i, j;
356 double x1, x2, y1, y2;
357 Complex z00 = {Complex_id};
358 Complex z10 = {Complex_id};
359 Complex z01 = {Complex_id};
360 Complex z11 = {Complex_id};
361 double re00, re01, re10, re11, re0;
362 double im00, im01, im10, im11, im0;
363
364 y -= 0.5;
365 i = (int) y;
366 y1 = y - i;
367 y2 = 1.0 - y1;
368 x -= 0.5;
369 j = (int) x;
370 x1 = x - j;
371 x2 = 1.0 - x1;
372
373 z00 = im_get_pixz(im, i, j);
374 z01 = im_get_pixz(im, i, j + 1);
375 z10 = im_get_pixz(im, i + 1, j);
376 z11 = im_get_pixz(im, i + 1, j + 1);
377
378 re00 = cmplx_re(z00);
379 re10 = cmplx_re(z10);
380 re01 = cmplx_re(z01);
381 re11 = cmplx_re(z11);
382 re0 = y2 * (x2 * re00 + x1 * re01) + y1 * (x2 * re10 + x1 * re11);
383
384 im00 = cmplx_im(z00);
385 im10 = cmplx_im(z10);
386 im01 = cmplx_im(z01);
387 im11 = cmplx_im(z11);
388 im0 = y2 * (x2 * im00 + x1 * im01) + y1 * (x2 * im10 + x1 * im11);
389
390 return (cmplx(re0, im0));
391 }
392
393
394 /**
395 * @brief Copies the values of a portion of a specified row of an image into a vector, casting them to integers.
396 * @param line An integer vector, which must already be allocated, to hold the image row data.
397 * @param image The image to read data from.
398 * @param i The coordinate of the row to read data from.
399 * @param from The column at which to start reading data.
400 * @param to The column at which to stop reading data.
401 * @return void
402 *
403 * Copies the values of a portion of a specified row of an image into an integer vector, which must be
404 * allocated before the function is called, casting the pixel values to integers. No check is made on line:
405 * this will crash if line is not allocated, too short etc. Any part of the vector outside the image will
406 * be filled with zeros.
407 */
408 void im_get_row(int *line, Imrect * image, int i, int from, int to)
409 {
410 int j;
411 Imregion *region;
412 double pixval;
413
414 for (j = from; j < to; ++j)
415 line[j] = 0;
416
417 if (image == NULL || image->vtype == ptr_v)
418 return;
419
420 region = image->region;
421 if (i < region->ly || i >= region->uy)
422 return;
423
424 if (from >= region->ux || to < region->lx)
425 return;
426
427 if (to > region->ux)
428 to = region->ux;
429
430 if (from < region->lx)
431 from = region->lx;
432
433 for (j = from; j < to; ++j)
434 {
435 IM_PIX_GET(image, i, j, pixval);
436 line[j] = (int) pixval;
437 }
438 }
439
440
441 /**
442 * @brief Copies the values of a portion of a specified column of an image into a vector, casting them to integers.
443 * @param line An integer vector, which must already be allocated, to hold the image column data.
444 * @param image The image to read data from.
445 * @param i The coordinate of the column to read data from.
446 * @param from The row at which to start reading data.
447 * @param to The row at which to stop reading data.
448 * @return void
449 *
450 * Copies the values of a portion of a specified column of an image into an integer vector, which must be
451 * allocated before the function is called, casting the pixel values to integers. No check is made on line:
452 * this will crash if line is not allocated, too short etc. Any part of the vector outside the image will
453 * be filled with zeros.
454 */
455 void im_get_col(int *line, Imrect * image, int i, int from, int to)
456 {
457 int j;
458 Imregion *region;
459 double pixval;
460
461 for (j = from; j < to; ++j)
462 line[j] = 0;
463
464 if (image == NULL || image->vtype == ptr_v)
465 return;
466
467 region = image->region;
468 if (i < region->lx || i >= region->ux)
469 return;
470
471 if (from >= region->uy || to < region->ly)
472 return;
473
474 if (to > region->uy)
475 to = region->uy;
476
477 if (from < region->ly)
478 from = region->ly;
479
480 for (j = from; j < to; ++j)
481 {
482 IM_PIX_GET(image, j, i, pixval);
483 line[j] = (int) pixval;
484 }
485 }
486
487
488 /**
489 * @brief Copies the values of a portion of a specified row of an image into a vector, casting them to floats.
490 * @param line A float vector, which must already be allocated, to hold the image row data.
491 * @param image The image to read data from.
492 * @param i The coordinate of the row to read data from.
493 * @param from The column at which to start reading data.
494 * @param to The column at which to stop reading data.
495 * @return void
496 *
497 * Copies the values of a portion of a specified row of an image into an float vector, which must be
498 * allocated before the function is called, casting the pixel values to floats. No check is made on line:
499 * this will crash if line is not allocated, too short etc. Any part of the vector outside the image will
500 * be filled with zeros.
501 */
502 void im_get_rowf(float *line, Imrect * image, int i, int from, int to)
503 {
504 int j;
505 Imregion *region;
506 double pixval;
507
508 for (j = from; j < to; ++j)
509 line[j] = (float) 0.0;
510
511 if (image == NULL || image->vtype == ptr_v)
512 return;
513
514 region = image->region;
515 if (i < region->ly || i >= region->uy)
516 return;
517
518 if (from >= region->ux || to < region->lx)
519 return;
520
521 if (to > region->ux)
522 to = region->ux;
523
524 if (from < region->lx)
525 from = region->lx;
526
527 for (j = from; j < to; ++j)
528 {
529 IM_PIX_GET(image, i, j, pixval);
530 line[j] = (float) pixval;
531 }
532 }
533
534
535 /**
536 * @brief Copies the values of a portion of a specified column of an image into a vector, casting them to floats.
537 * @param line A float vector, which must already be allocated, to hold the image column data.
538 * @param image The image to read data from.
539 * @param i The coordinate of the column to read data from.
540 * @param from The row at which to start reading data.
541 * @param to The row at which to stop reading data.
542 * @return void
543 *
544 * Copies the values of a portion of a specified column of an image into an float vector, which must be
545 * allocated before the function is called, casting the pixel values to floats. No check is made on line:
546 * this will crash if line is not allocated, too short etc. Any part of the vector outside the image will
547 * be filled with zeros.
548 */
549 void im_get_colf(float *line, Imrect * image, int i, int from, int to)
550 {
551 int j;
552 Imregion *region;
553 double pixval;
554
555 for (j = from; j < to; ++j)
556 line[j] = (float) 0.0;
557
558 if (image == NULL || image->vtype == ptr_v)
559 return;
560
561 region = image->region;
562 if (i < region->lx || i >= region->ux)
563 return;
564
565 if (from >= region->uy || to < region->ly)
566 return;
567
568 if (to > region->uy)
569 to = region->uy;
570
571 if (from < region->ly)
572 from = region->ly;
573
574 for (j = from; j < to; ++j)
575 {
576 IM_PIX_GET(image, j, i, pixval);
577 line[j] = (float) pixval;
578 }
579 }
580
581
582 /**
583 * @brief Copies the values of a portion of a specified row of a complex image into a complex vector.
584 * @param line A complex vector, which must already be allocated, to hold the image row data.
585 * @param image The image to read data from.
586 * @param i The coordinate of the row to read data from.
587 * @param from The column at which to start reading data.
588 * @param to The column at which to stop reading data.
589 * @return void
590 *
591 * Copies the values of a portion of a specified row of a complex image into an complex vector, which must be
592 * allocated before the function is called. No check is made on line:
593 * this will crash if line is not allocated, too short etc. Any part of the vector outside the image will
594 * be filled with zeros.
595 */
596 void im_get_rowz(Complex * line, Imrect * image, int i, int from, int to)
597 {
598 int j;
599 Imregion *region;
600
601 for (j = from; j < to; ++j)
602 line[j] = cmplx_zero();
603
604 if (image == NULL || image->vtype == ptr_v)
605 return;
606
607 region = image->region;
608 if (i < region->ly || i >= region->uy)
609 return;
610
611 if (from >= region->ux || to < region->lx)
612 return;
613
614 if (to > region->ux)
615 to = region->ux;
616
617 if (from < region->lx)
618 from = region->lx;
619
620 if (image->vtype == complex_v)
621 {
622 for (j = from; j < to; ++j)
623 line[j] = IM_COMPLEX(image, i, j);
624 } else
625 {
626 for (j = from; j < to; ++j)
627 IM_PIX_GET(image, i, j, line[j].x);
628 }
629 }
630
631
632 /**
633 * @brief Copies the values of a portion of a specified column of a complex image into a complex vector.
634 * @param line A complex vector, which must already be allocated, to hold the image column data.
635 * @param image The image to read data from.
636 * @param i The coordinate of the column to read data from.
637 * @param from The row at which to start reading data.
638 * @param to The row at which to stop reading data.
639 * @return void
640 *
641 * Copies the values of a portion of a specified column of a complex image into an complex vector, which must be
642 * allocated before the function is called. No check is made on line:
643 * this will crash if line is not allocated, too short etc. Any part of the vector outside the image will
644 * be filled with zeros.
645 */
646 void im_get_colz(Complex * line, Imrect * image, int i, int from, int to)
647 {
648 int j;
649 Imregion *region;
650
651 for (j = from; j < to; ++j)
652 line[j] = cmplx_zero();
653
654 if (image == NULL || image->vtype == ptr_v)
655 return;
656
657 region = image->region;
658 if (i < region->lx || i >= region->ux)
659 return;
660
661 if (from >= region->uy || to < region->ly)
662 return;
663
664 if (to > region->uy)
665 to = region->uy;
666
667 if (from < region->ly)
668 from = region->ly;
669
670 if (image->vtype == complex_v)
671 {
672 for (j = from; j < to; ++j)
673 line[j] = IM_COMPLEX(image, j, i);
674 } else
675 {
676 for (j = from; j < to; ++j)
677 IM_PIX_GET(image, j, i, line[j].x);
678 }
679 }
680
681
682 /**
683 * @brief Copies the values along a positive diagonal line in an image into a vector, casting them to integers.
684 * @param line Integer vector into which the image data is copied.
685 * @param image The image to read data from.
686 * @param x x-coordinate of the starting point of the diagonal.
687 * @param y y-coordinate of the starting point of the diagonal.
688 * @param len length of the diagonal from which to copy data.
689 * @return void
690 *
691 * Copies the values from a positive diagonal line on an image, starting from a point specified by x,y and of
692 * length len, into the integer vector line, casting them to integers where neccessary. The direction of the line is
693 * such that both coordinates increase i.e. down and right in the image plane. No check is made on line:
694 * this will crash if line is not allocated, too short etc. Any part of the vector outside the image will
695 * be filled with zeros, and the whole vector will be filled with zeros if the image is of type complex or
696 * pointer.
697 */
698 void im_get_pos_diag(int *line, Imrect * image, int x, int y, int len)
699 {
700 int j;
701 int minoff;
702 Imregion *region;
703
704 for (j = 0; j < len; ++j)
705 line[j] = 0;
706
707 if (image == NULL)
708 return;
709
710 region = image->region;
711 if (x >= region->ux || (x + len) < region->lx)
712 return;
713
714 if (y >= region->uy || (y + len) < region->ly)
715 return;
716
717 minoff = MIN(x - region->lx, y - region->ly);
718 if (minoff < 0)
719 {
720 x -= minoff;
721 y -= minoff;
722 len += minoff;
723 }
724 minoff = MIN(region->ux - x - len, region->uy - y - len);
725 if (minoff < 0)
726 len += minoff;
727
728 switch (image->vtype)
729 {
730 case char_v:
731 {
732 char **array = (char **) image->data;
733
734 for (j = 0; j < len; j++)
735 line[j] = array[y + j][x + j];
736 }
737 break;
738 case uchar_v:
739 {
740 unsigned char **array = (unsigned char **) image->data;
741
742 for (j = 0; j < len; j++)
743 line[j] = array[y + j][x + j];
744 }
745 break;
746 case short_v:
747 {
748 short **array = (short **) image->data;
749
750 for (j = 0; j < len; j++)
751 line[j] = array[y + j][x + j];
752 }
753 break;
754 case ushort_v:
755 {
756 unsigned short **array = (unsigned short **) image->data;
757
758 for (j = 0; j < len; j++)
759 line[j] = array[y + j][x + j];
760 }
761 break;
762 case int_v:
763 {
764 int **array = (int **) image->data;
765
766 for (j = 0; j < len; j++)
767 line[j] = array[y + j][x + j];
768 }
769 break;
770 case uint_v:
771 {
772 unsigned int **array = (unsigned int **) image->data;
773
774 for (j = 0; j < len; j++)
775 line[j] = array[y + j][x + j];
776 }
777 break;
778 case float_v:
779 {
780 float **array = (float **) image->data;
781
782 for (j = 0; j < len; j++)
783 {
784 float gl = array[y + j][x + j];
785
786 line[j] = (int) ((gl > 0) ? gl + 0.5 : gl - 0.5);
787 }
788 }
789 break;
790 case double_v:
791 {
792 double **array = (double **) image->data;
793
794 for (j = 0; j < len; j++)
795 {
796 double gl = array[y + j][x + j];
797
798 line[j] = (int) ((gl > 0) ? gl + 0.5 : gl - 0.5);
799 }
800 }
801 break;
802 default:
803 error("im_get_pos_diag: unsupported type", non_fatal);
804 break;
805 }
806 }
807
808
809 /**
810 * @brief Copies the values along a negative diagonal line in an image into a vector, casting them to integers.
811 * @param line Integer vector into which the image data is copied.
812 * @param image The image to read data from.
813 * @param x x-coordinate of the starting point of the diagonal.
814 * @param y y-coordinate of the starting point of the diagonal.
815 * @param len length of the diagonal from which to copy data.
816 * @return void
817 *
818 * Copies the values from a negative diagonal line on an image, starting from a point specified by x,y and of
819 * length len, into the integer vector line, casting them to integers where neccessary. The direction of the line is
820 * such that the y coordinate increases whilst the x decreases i.e. down and left in the image plane. No check is made on line:
821 * this will crash if line is not allocated, too short etc. Any part of the vector outside the image will
822 * be filled with zeros, and the whole vector will be filled with zeros if the image is of type complex or
823 * pointer.
824 */
825 void im_get_neg_diag(int *line, Imrect * image, int x, int y, int len)
826 {
827 int j;
828 int minoff;
829 Imregion *region;
830
831 for (j = 0; j < len; ++j)
832 line[j] = 0;
833
834 if (image == NULL)
835 return;
836
837 region = image->region;
838 if (x < region->lx || (x - len) >= region->ux)
839 return;
840
841 if (y >= region->uy || (y + len) < region->ly)
842 return;
843
844 minoff = MIN(region->ux - x, y - region->ly);
845 if (minoff < 0)
846 {
847 x += minoff;
848 y -= minoff;
849 len += minoff;
850 }
851 minoff = MIN(x - len - region->lx, region->uy - y - len);
852 if (minoff < 0)
853 len += minoff;
854
855
856 switch (image->vtype)
857 {
858 case char_v:
859 {
860 char **array = (char **) image->data;
861
862 for (j = 0; j < len; j++)
863 line[j] = array[y + j][x - j];
864 }
865 break;
866 case uchar_v:
867 {
868 unsigned char **array = (unsigned char **) image->data;
869
870 for (j = 0; j < len; j++)
871 line[j] = array[y + j][x - j];
872 }
873 break;
874 case short_v:
875 {
876 short **array = (short **) image->data;
877
878 for (j = 0; j < len; j++)
879 line[j] = array[y + j][x - j];
880 }
881 break;
882 case ushort_v:
883 {
884 unsigned short **array = (unsigned short **) image->data;
885
886 for (j = 0; j < len; j++)
887 line[j] = array[y + j][x - j];
888 }
889 break;
890 case int_v:
891 {
892 int **array = (int **) image->data;
893
894 for (j = 0; j < len; j++)
895 line[j] = array[y + j][x - j];
896 }
897 break;
898 case uint_v:
899 {
900 unsigned int **array = (unsigned int **) image->data;
901
902 for (j = 0; j < len; j++)
903 line[j] = array[y + j][x - j];
904 }
905 break;
906 case float_v:
907 {
908 float **array = (float **) image->data;
909
910 for (j = 0; j < len; j++)
911 {
912 float gl = array[y + j][x - j];
913
914 line[j] = (int) ((gl > 0) ? gl + 0.5 : gl - 0.5);
915 }
916 }
917 break;
918 case double_v:
919 {
920 double **array = (double **) image->data;
921
922 for (j = 0; j < len; j++)
923 {
924 double gl = array[y + j][x - j];
925
926 line[j] = (int) ((gl > 0) ? gl + 0.5 : gl - 0.5);
927 }
928 }
929 break;
930 default:
931 error("im_get_neg_diag: unsupported type", non_fatal);
932 break;
933 }
934 }
935
936
937 /**
938 * @brief Copies the values along a positive diagonal line in an image into a vector, casting them to floats.
939 * @param line Vector into which the image data is copied.
940 * @param image The image to read data from.
941 * @param x x-coordinate of the starting point of the diagonal.
942 * @param y y-coordinate of the starting point of the diagonal.
943 * @param len length of the diagonal from which to copy data.
944 * @return void
945 *
946 * Copies the values from a positive diagonal line on an image, starting from a point specified by x,y and of
947 * length len, into the integer vector line, casting them to floats. The direction of the line is
948 * such that both coordinates increase i.e. down and right in the image plane. No check is made on line:
949 * this will crash if line is not allocated, too short etc. Any part of the vector outside the image will
950 * be filled with zeros, and the whole vector will be filled with zeros if the image is of type complex or
951 * pointer.
952 */
953 void im_get_pos_diagf(float *line, Imrect * image, int x, int y, int len)
954 {
955 int j;
956 int minoff;
957 Imregion *region;
958
959 for (j = 0; j < len; ++j)
960 line[j] = (float) 0.0;
961
962 if (image == NULL)
963 return;
964
965 region = image->region;
966 if (x >= region->ux || (x + len) < region->lx)
967 return;
968
969 if (y >= region->uy || (y + len) < region->ly)
970 return;
971
972 minoff = MIN(x - region->lx, y - region->ly);
973 if (minoff < 0)
974 {
975 x -= minoff;
976 y -= minoff;
977 len += minoff;
978 }
979 minoff = MIN(region->ux - x - len, region->uy - y - len);
980 if (minoff < 0)
981 len += minoff;
982
983 switch (image->vtype)
984 {
985 case char_v:
986 {
987 char **array = (char **) image->data;
988
989 for (j = 0; j < len; j++)
990 line[j] = array[y + j][x + j];
991 }
992 break;
993 case uchar_v:
994 {
995 unsigned char **array = (unsigned char **) image->data;
996
997 for (j = 0; j < len; j++)
998 line[j] = array[y + j][x + j];
999 }
1000 break;
1001 case short_v:
1002 {
1003 short **array = (short **) image->data;
1004
1005 for (j = 0; j < len; j++)
1006 line[j] = array[y + j][x + j];
1007 }
1008 break;
1009 case ushort_v:
1010 {
1011 unsigned short **array = (unsigned short **) image->data;
1012
1013 for (j = 0; j < len; j++)
1014 line[j] = array[y + j][x + j];
1015 }
1016 break;
1017 case int_v:
1018 {
1019 int **array = (int **) image->data;
1020
1021 for (j = 0; j < len; j++)
1022 line[j] = (float) array[y + j][x + j];
1023 }
1024 break;
1025 case uint_v:
1026 {
1027 unsigned int **array = (unsigned int **) image->data;
1028
1029 for (j = 0; j < len; j++)
1030 line[j] = (float) array[y + j][x + j];
1031 }
1032 break;
1033 case float_v:
1034 {
1035 float **array = (float **) image->data;
1036
1037 for (j = 0; j < len; j++)
1038 {
1039 float gl = array[y + j][x + j];
1040
1041 line[j] = (float) ((gl > 0) ? gl + 0.5 : gl - 0.5);
1042 }
1043 }
1044 break;
1045 case double_v:
1046 {
1047 double **array = (double **) image->data;
1048
1049 for (j = 0; j < len; j++)
1050 {
1051 double gl = array[y + j][x + j];
1052
1053 line[j] = (float) ((gl > 0) ? gl + 0.5 : gl - 0.5);
1054 }
1055 }
1056 break;
1057 default:
1058 error("im_get_pos_diagf: unsupported type", non_fatal);
1059 break;
1060 }
1061 }
1062
1063
1064
1065 /**
1066 * @brief Copies the values along a negative diagonal line in an image into a vector, casting them to floats.
1067 * @param line Vector into which the image data is copied.
1068 * @param image The image to read data from.
1069 * @param x x-coordinate of the starting point of the diagonal.
1070 * @param y y-coordinate of the starting point of the diagonal.
1071 * @param len length of the diagonal from which to copy data.
1072 * @return void
1073 *
1074 * Copies the values from a negative diagonal line on an image, starting from a point specified by x,y and of
1075 * length len, into the vector line, casting them to floats. The direction of the line is such that the y
1076 * coordinate increases whilst the x decreases i.e. down and left in the image plane. No check is made on line:
1077 * this will crash if line is not allocated, too short etc. Any part of the vector outside the image will
1078 * be filled with zeros, and the whole vector will be filled with zeros if the image is of type complex or
1079 * pointer.
1080 */
1081 void im_get_neg_diagf(float *line, Imrect * image, int x, int y, int len)
1082 {
1083 int j;
1084 int minoff;
1085 Imregion *region;
1086
1087 for (j = 0; j < len; ++j)
1088 line[j] = (float) 0.0;
1089
1090 if (image == NULL)
1091 return;
1092
1093 region = image->region;
1094 if (x < region->lx || (x - len) >= region->ux)
1095 return;
1096
1097 if (y >= region->uy || (y + len) < region->ly)
1098 return;
1099
1100 minoff = MIN(region->ux - x, y - region->ly);
1101 if (minoff < 0)
1102 {
1103 x += minoff;
1104 y -= minoff;
1105 len += minoff;
1106 }
1107 minoff = MIN(x - len - region->lx, region->uy - y - len);
1108 if (minoff < 0)
1109 len += minoff;
1110
1111 switch (image->vtype)
1112 {
1113 case char_v:
1114 {
1115 char **array = (char **) image->data;
1116
1117 for (j = 0; j < len; j++)
1118 line[j] = array[y + j][x - j];
1119 }
1120 break;
1121 case uchar_v:
1122 {
1123 unsigned char **array = (unsigned char **) image->data;
1124
1125 for (j = 0; j < len; j++)
1126 line[j] = array[y + j][x - j];
1127 }
1128 break;
1129 case short_v:
1130 {
1131 short **array = (short **) image->data;
1132
1133 for (j = 0; j < len; j++)
1134 line[j] = array[y + j][x - j];
1135 }
1136 break;
1137 case ushort_v:
1138 {
1139 unsigned short **array = (unsigned short **) image->data;
1140
1141 for (j = 0; j < len; j++)
1142 line[j] = array[y + j][x - j];
1143 }
1144 break;
1145 case int_v:
1146 {
1147 int **array = (int **) image->data;
1148
1149 for (j = 0; j < len; j++)
1150 line[j] = (float) array[y + j][x - j];
1151 }
1152 break;
1153 case uint_v:
1154 {
1155 unsigned int **array = (unsigned int **) image->data;
1156
1157 for (j = 0; j < len; j++)
1158 line[j] = (float) array[y + j][x - j];
1159 }
1160 break;
1161 case float_v:
1162 {
1163 float **array = (float **) image->data;
1164
1165 for (j = 0; j < len; j++)
1166 {
1167 float gl = array[y + j][x - j];
1168
1169 line[j] = (float) ((gl > 0) ? gl + 0.5 : gl - 0.5);
1170 }
1171 }
1172 break;
1173 case double_v:
1174 {
1175 double **array = (double **) image->data;
1176
1177 for (j = 0; j < len; j++)
1178 {
1179 double gl = array[y + j][x - j];
1180
1181 line[j] = (float) ((gl > 0) ? gl + 0.5 : gl - 0.5);
1182 }
1183 }
1184 break;
1185 default:
1186 error("im_get_pos_diagf: unsupported type", non_fatal);
1187 break;
1188 }
1189 }
1190
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.