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