1
2%{
3#include "wisebase.h"
4
5typedef enum dpenvelope_type {
6  DPENV_RECT = 0,
7  DPENV_DIAG
8} dpenv_type;
9
10
11
12#define DPEnvelopeLISTLENGTH 32
13%}
14
15
16struct DPUnit
17int type !def="DPENV_RECT"
18int starti
19int startj
20int height // for diagonal units
21int length // for diagonal units
22
23struct DPEnvelope
24DPUnit ** dpu !list
25DPUnit * bbox
26int starti
27int startj
28int endi
29int endj
30
31%{
32#include "dpenvelope.h"
33
34%func
35Helper function that checks whether things overlap or not
36%%
37boolean overlap_DPUnit(DPUnit * a,DPUnit * b)
38{
39  int diag_a;
40  int diag_b;
41
42  if( a->type == DPENV_DIAG && b->type == DPENV_DIAG ) {
43    diag_a = a->starti - a->startj;
44    diag_b = b->starti - b->startj;
45
46    if( diag_a - a->height > diag_b + b->height || diag_a + a->height < diag_b + b->height ) {
47      return FALSE;
48    }
49
50    diag_a = a->starti + a->startj;
51    diag_b = b->starti + b->startj;
52
53    if( diag_a + a->length < diag_b || diag_a > diag_b + b->length ) {
54      return FALSE;
55    }
56
57    return TRUE;
58
59  }
60
61  if( a->type == DPENV_RECT && b->type == DPENV_RECT ) {
62    fatal("Not implemented rectangle overlap!");
63  }
64
65
66  fatal("Not implemented rectangle - diag overlap!");
67
68}
69
70%func
71Helper function that also opens the filename
72%%
73DPEnvelope * read_DPEnvelope_file(char * filename)
74{
75  FILE * ifp;
76  DPEnvelope * dpenv;
77
78  ifp = openfile(filename,"r");
79  if( ifp == NULL ) {
80    error("Could not open file with %s",filename);
81    return NULL;
82  }
83
84  dpenv = read_DPEnvelope(ifp);
85
86  fclose(ifp);
87
88  return dpenv;
89}
90
91
92%func
93Reads a DPEnvelope from a file
94%%
95DPEnvelope * read_DPEnvelope(FILE * ifp)
96{
97  char buffer[MAXLINE];
98  char ** base;
99  char ** str;
100  DPEnvelope * out;
101  DPUnit * unit;
102
103  out = DPEnvelope_alloc_std();
104
105
106
107  while( fgets(buffer,MAXLINE,ifp) != NULL ) {
108
109    base = str = breakstring(buffer,spacestr);
110    unit = DPUnit_alloc();
111    add_DPEnvelope(out,unit);
112
113    if( strcmp(*str,"rect") == 0 ) {
114      unit->type = DPENV_RECT;
115    } else if ( strcmp(*str,"diag") == 0 ) {
116      unit->type = DPENV_DIAG;
117    } else {
118      error("Cannot parse DPEnv file");
119      continue;
120    }
121
122    str++;
123    if( *str == NULL ) {
124      error("Cannot parse DPEnv file");
125      continue;
126    }
127    unit->starti = atoi(*str);
128    str++;
129    if( *str == NULL ) {
130      error("Cannot parse DPEnv file");
131      continue;
132    }
133    unit->startj = atoi(*str);
134
135    str++;
136    if( *str == NULL ) {
137      error("Cannot parse DPEnv file");
138      continue;
139    }
140    unit->height = atoi(*str);
141
142    str++;
143    if( *str == NULL ) {
144      error("Cannot parse DPEnv file");
145      continue;
146    }
147    unit->length = atoi(*str);
148  }
149
150  return out;
151}
152
153
154%func
155shows structure. useful for debugging
156%%
157void show_DPEnvelope(DPEnvelope * dpe,FILE * ofp)
158{
159  int i;
160
161  for(i=0;i<dpe->len;i++) {
162    fprintf(ofp,"Unit %d [%s] Start %d-%d Height: %d Length: %d\n",i,dpe->dpu[i]->type == DPENV_RECT ? "rect" : "diag",dpe->dpu[i]->starti,dpe->dpu[i]->startj,dpe->dpu[i]->height,dpe->dpu[i]->length);
163  }
164
165}
166
167%func
168Tests whether this i,j position is allowed in the
169DPEnvelope
170%%
171boolean is_in_DPEnvelope(DPEnvelope * dpe,int i,int j)
172{
173  int k;
174
175  for(k=0;k<dpe->len;k++) {
176    auto DPUnit * u;
177    u = dpe->dpu[k];
178
179    switch (u->type) {
180
181    case DPENV_RECT :
182      if( i >= u->starti && j >= u->startj && i <= (u->starti+u->height) && j <= (u->startj+u->length) )
183	return TRUE;
184      else
185	break;
186    case DPENV_DIAG :
187      if( abs( (i-j) - (u->starti-u->startj)) <= u->height &&
188	i+j >= u->starti+u->startj && i+j+u->length >= u->starti+u->startj)
189	return TRUE;
190      break;
191
192    default :
193      warn("Bad DPUnit type put in. Yuk. Bad error... %d",u->type);
194      return FALSE;
195    }
196  }
197
198
199  return FALSE;
200}
201
202%func
203Should run this before using the DPEnvelope
204%%
205boolean prepare_DPEnvelope(DPEnvelope * dpe)
206{
207  int i;
208
209  dpe->starti = 1000000;
210  dpe->startj = 1000000;
211  dpe->endi   = 1;
212  dpe->endj   = 1;
213
214  sort_DPEnvelope_by_startj(dpe);
215
216  for(i=0;i<dpe->len;i++) {
217    if( dpe->dpu[i]->type == DPENV_RECT ) {
218      if( dpe->starti > dpe->dpu[i]->starti-1 ) {
219	dpe->starti = dpe->dpu[i]->starti-1;
220      }
221      if( dpe->startj > dpe->dpu[i]->startj-1 ) {
222	dpe->startj = dpe->dpu[i]->startj-1;
223      }
224      if( dpe->endi < dpe->dpu[i]->starti+ dpe->dpu[i]->height ) {
225	dpe->endi = dpe->dpu[i]->starti+ dpe->dpu[i]->height;
226      }
227      if( dpe->endj < dpe->dpu[i]->startj + dpe->dpu[i]->length ) {
228	dpe->endj = dpe->dpu[i]->startj + dpe->dpu[i]->length;
229      }
230    } else { /* DIAG */
231      if( dpe->starti > dpe->dpu[i]->starti-dpe->dpu[i]->height ) {
232	dpe->starti = dpe->dpu[i]->starti-dpe->dpu[i]->height;
233      }
234      if( dpe->startj > dpe->dpu[i]->startj-dpe->dpu[i]->height ) {
235	dpe->startj = dpe->dpu[i]->startj-dpe->dpu[i]->height;
236      }
237      if( dpe->endi < dpe->dpu[i]->starti+ dpe->dpu[i]->length+dpe->dpu[i]->height ) {
238	dpe->endi = dpe->dpu[i]->starti+ dpe->dpu[i]->length + dpe->dpu[i]->height;
239      }
240      if( dpe->endj < dpe->dpu[i]->startj + dpe->dpu[i]->length + dpe->dpu[i]->height ) {
241	dpe->endj = dpe->dpu[i]->startj + dpe->dpu[i]->length + dpe->dpu[i]->height;
242      }
243    }
244  }
245
246  return TRUE;
247}
248
249%func
250Sorts by startj
251%%
252void sort_DPEnvelope_by_startj(DPEnvelope * dpe)
253{
254  sort_DPEnvelope(dpe,compare_DPUnit_startj);
255}
256
257%func
258internal for sort by startj
259%type internal
260%%
261int compare_DPUnit_startj(DPUnit * one,DPUnit * two)
262{
263  return one->startj  - two->startj;
264}
265
266
267
268
269
270
271
272