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