Panda3D
pnm-image-filter-sparse-core.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file pnm-image-filter-sparse-core.cxx
10  * @author drose
11  * @date 2013-01-25
12  */
13 
14 // We map X and Y to A and B, because we might change our minds about which is
15 // dominant, and we map getset functions for the channel in question to
16 // GETVALSETVAL.
17 
18 
19 static void
20 FUNCTION_NAME(IMAGETYPE &dest, const IMAGETYPE &source,
21  float width, FilterFunction *make_filter, int channel) {
22  if (!dest.is_valid() || !source.is_valid()) {
23  return;
24  }
25 
26  // First, set up a 2-d column-major matrix of StoreTypes, big enough to hold
27  // the image xelvals scaled in the A direction only. This will hold the
28  // adjusted xel data from our first pass.
29 
30  StoreType **matrix = (StoreType **)PANDA_MALLOC_ARRAY(dest.ASIZE() * sizeof(StoreType *));
31  StoreType **matrix_weight = (StoreType **)PANDA_MALLOC_ARRAY(dest.ASIZE() * sizeof(StoreType *));
32 
33  int a, b;
34 
35  for (a=0; a<dest.ASIZE(); a++) {
36  matrix[a] = (StoreType *)PANDA_MALLOC_ARRAY(source.BSIZE() * sizeof(StoreType));
37  matrix_weight[a] = (StoreType *)PANDA_MALLOC_ARRAY(source.BSIZE() * sizeof(StoreType));
38  }
39 
40  // First, scale the image in the A direction.
41  float scale;
42  StoreType *temp_source, *temp_source_weight, *temp_dest, *temp_dest_weight;
43 
44  scale = (float)dest.ASIZE() / (float)source.ASIZE();
45  temp_source = (StoreType *)PANDA_MALLOC_ARRAY(source.ASIZE() * sizeof(StoreType));
46  temp_source_weight = (StoreType *)PANDA_MALLOC_ARRAY(source.ASIZE() * sizeof(StoreType));
47  temp_dest = (StoreType *)PANDA_MALLOC_ARRAY(dest.ASIZE() * sizeof(StoreType));
48  temp_dest_weight = (StoreType *)PANDA_MALLOC_ARRAY(dest.ASIZE() * sizeof(StoreType));
49 
50  WorkType *filter;
51  float filter_width;
52 
53  make_filter(scale, width, filter, filter_width);
54 
55  for (b = 0; b < source.BSIZE(); b++) {
56  memset(temp_source_weight, 0, source.ASIZE() * sizeof(StoreType));
57  for (a = 0; a < source.ASIZE(); a++) {
58  if (source.HASVAL(a, b)) {
59  temp_source[a] = (StoreType)(source_max * source.GETVAL(a, b, channel));
60  temp_source_weight[a] = filter_max;
61  }
62  }
63 
64  filter_sparse_row(temp_dest, temp_dest_weight, dest.ASIZE(),
65  temp_source, temp_source_weight, source.ASIZE(),
66  scale,
67  filter, filter_width);
68 
69  for (a = 0; a < dest.ASIZE(); a++) {
70  matrix[a][b] = temp_dest[a];
71  matrix_weight[a][b] = temp_dest_weight[a];
72  }
73  }
74 
75  PANDA_FREE_ARRAY(temp_source);
76  PANDA_FREE_ARRAY(temp_source_weight);
77  PANDA_FREE_ARRAY(temp_dest);
78  PANDA_FREE_ARRAY(temp_dest_weight);
79  PANDA_FREE_ARRAY(filter);
80 
81  // Now, scale the image in the B direction.
82  scale = (float)dest.BSIZE() / (float)source.BSIZE();
83  temp_dest = (StoreType *)PANDA_MALLOC_ARRAY(dest.BSIZE() * sizeof(StoreType));
84  temp_dest_weight = (StoreType *)PANDA_MALLOC_ARRAY(dest.BSIZE() * sizeof(StoreType));
85 
86  make_filter(scale, width, filter, filter_width);
87 
88  for (a = 0; a < dest.ASIZE(); a++) {
89  filter_sparse_row(temp_dest, temp_dest_weight, dest.BSIZE(),
90  matrix[a], matrix_weight[a], source.BSIZE(),
91  scale,
92  filter, filter_width);
93 
94  for (b = 0; b < dest.BSIZE(); b++) {
95  if (temp_dest_weight[b] != 0) {
96  dest.SETVAL(a, b, channel, (float)temp_dest[b]/(float)source_max);
97  }
98  }
99  }
100 
101  PANDA_FREE_ARRAY(temp_dest);
102  PANDA_FREE_ARRAY(temp_dest_weight);
103  PANDA_FREE_ARRAY(filter);
104 
105  // Now, clean up our temp matrix and go home!
106 
107  for (a = 0; a < dest.ASIZE(); a++) {
108  PANDA_FREE_ARRAY(matrix[a]);
109  PANDA_FREE_ARRAY(matrix_weight[a]);
110  }
111  PANDA_FREE_ARRAY(matrix);
112  PANDA_FREE_ARRAY(matrix_weight);
113 }