00001
00002
00003 #include <stdlib.h>
00004 #include <assert.h>
00005 #include <string.h>
00006 #include <math.h>
00007
00012 #define AMI_EVENT_LIST_LOAD_XML 1
00013
00014 #include "ami_event_set.h"
00015
00016 #define EVENT_BUFF_SIZE 1000
00017 #define FRAMES_BUFF_SIZE 50000
00018
00019
00027 float amiEventsIntersection(amiEvent * E1, amiEvent * E2)
00028 {
00029 int minX, minY, maxX, maxY;
00030
00031 assert(E1);
00032 assert(E2);
00033
00034 minX = max(E1->pMin.x, E2->pMin.x);
00035 maxX = min(E1->pMax.x, E2->pMax.x);
00036 minY = max(E1->pMin.y, E2->pMin.y);
00037 maxY = min(E1->pMax.y, E2->pMax.y);
00038
00039
00040 if (minX > maxX || minY > maxY) return 0.0;
00041
00042 return fabs((maxX-minX)*(maxY-minY));
00043 }
00044
00045
00051 float amiEventArea(amiEvent * E)
00052 {
00053 assert(E);
00054 return fabs((E->pMax.x-E->pMin.x)*(E->pMax.y-E->pMin.y));
00055 }
00056
00057
00068 unsigned char amiEventsOcclusion(amiEvent * E, amiEventsSubSet * ES, float Threshold)
00069 {
00070 unsigned long i;
00071 assert(E);
00072 assert(ES);
00073 for (i = 0; i < ES->n; i++) {
00074 if (E->ObjectID == ES->Event[i]->ObjectID) continue;
00075 if (2*amiEventsIntersection(E, ES->Event[i])/(amiEventArea(E)+amiEventArea(ES->Event[i])) > Threshold)
00076 return 1;
00077 }
00078 return 0;
00079 }
00080
00081
00082
00083
00084
00089 amiEventList * amiEventListNew(void)
00090 {
00091 amiEventList * E = (amiEventList *)malloc(sizeof(amiEventList));
00092 assert(E);
00093 E->Event = NULL;
00094 E->nEvents = 0;
00095 E->Frames = NULL;
00096 E->nFrames = 0;
00097 E->Types = NULL;
00098 E->nTypes = 0;
00099 E->defaultType = EVENT_TYPE_HEAD;
00100 return E;
00101 }
00102
00103
00108 int amiEventListFree(amiEventList * E)
00109 {
00110 if (!E) return 1;
00111 free(E->Event); E->Event = NULL;
00112 E->nEvents = 0;
00113 free(E->Frames); E->Frames = NULL;
00114 E->nFrames = 0;
00115 free(E->Types); E->Types = NULL;
00116 E->nTypes = 0;
00117 free(E); E = NULL;
00118 return 1;
00119 }
00120
00121
00128 int amiEventListInit(amiEventList * E, unsigned long Size)
00129 {
00130 assert(E);
00131 if (E->Event) E->Event = (amiEvent *)realloc(E->Event, Size*sizeof(amiEvent));
00132 else E->Event = (amiEvent *)calloc(Size, sizeof(amiEvent));
00133 E->nEvents = Size;
00134 if (E->Frames) free(E->Frames);
00135 E->Frames = NULL;
00136 E->nFrames = 0;
00137 free(E->Types); E->Types = NULL;
00138 E->nTypes = 0;
00139 return 1;
00140 }
00141
00142
00154 int _amiEventListLoadTXT(amiEventList * E, const char * Filename)
00155 {
00156 char buff[1024];
00157 int frame, id;
00158 float p1, p2, p3, p4, occ;
00159 long last;
00160 long size;
00161 long FramesBuff[FRAMES_BUFF_SIZE];
00162 long nFB;
00163 amiEvent *itr;
00164 FILE *fin;
00165
00166 assert(E);
00167
00168 if ((fin = fopen(Filename, "rt")) == NULL) return -1;
00169
00170 size = 0;
00171 while(fgets(buff, 1024, fin)) size++;
00172 fseek(fin, 0L, SEEK_SET);
00173
00174 amiEventListInit(E, size);
00175
00176 last = -1;
00177 nFB = 0;
00178 itr = E->Event;
00179 while(fgets(buff, 1024, fin)) {
00180 if (sscanf(buff, "%d %d %f %f %f %f %f\n", &frame, &id, &occ, &p1, &p2, &p3, &p4)) {
00181 (*itr).Time = frame;
00182 (*itr).ObjectID = id;
00183 (*itr).Type = E->defaultType;
00184 amiPoint2iSet((*itr).pMin, (int)p1, (int)p2);
00185 amiPoint2iSet((*itr).pMax, (int)p3, (int)p4);
00186 if (last != frame) {
00187
00188 for (size = 0 ; size < nFB; size++) if (frame == FramesBuff[size]) break;
00189
00190 if (size >= nFB) {
00191 FramesBuff[nFB++] = frame;
00192 last = frame;
00193 }
00194 }
00195 }
00196 itr++;
00197 }
00198
00199 E->nFrames = nFB;
00200 E->Frames = (long *)malloc(E->nFrames*sizeof(long));
00201 memcpy(E->Frames, FramesBuff, E->nFrames*sizeof(long));
00202
00203 _amiEventListSortFrames(E);
00204
00205 E->nTypes = 1;
00206 E->Types = (int *)malloc(E->nTypes*sizeof(int));
00207 E->Types[0] = E->defaultType;
00208
00209 fclose(fin);
00210
00211 return 1;
00212 }
00213
00214
00219 int _amiEventListSortFrames(amiEventList * E)
00220 {
00221 char change;
00222 long size, last;
00223
00224 assert(E);
00225
00226
00227 change = 1;
00228 while (change) {
00229 change = 0;
00230 for (size = 0; size < E->nFrames-1; size++) {
00231 if (E->Frames[size] > E->Frames[size+1]) {
00232 last = E->Frames[size];
00233 E->Frames[size] = E->Frames[size+1];
00234 E->Frames[size+1] = last;
00235 change++;
00236 }
00237 }
00238 change = change;
00239 }
00240
00241 return 1;
00242 }
00243
00244
00251 int amiEventListMerge(amiEventList * EDst, amiEventList * ESrc)
00252 {
00253 long FramesBuff[FRAMES_BUFF_SIZE];
00254 long nFB, i, idst;
00255 amiEvent *dst;
00256 long *dstFr;
00257 int *dstType;
00258
00259 assert(EDst);
00260 assert(ESrc);
00261
00262
00263 dst = (amiEvent *)malloc((EDst->nEvents+ESrc->nEvents)*sizeof(amiEvent));
00264 assert(dst);
00265 memcpy(dst, EDst->Event, EDst->nEvents*sizeof(amiEvent));
00266 memcpy(dst+EDst->nEvents, ESrc->Event, ESrc->nEvents*sizeof(amiEvent));
00267 EDst->nEvents += ESrc->nEvents;
00268 free(EDst->Event);
00269 EDst->Event = dst;
00270
00271
00272 nFB = 0;
00273 for (i = 0; i < ESrc->nFrames; i++) {
00274
00275 for (idst = 0 ; idst < EDst->nFrames; idst++) if (ESrc->Frames[i] == EDst->Frames[idst]) break;
00276
00277 if (idst >= EDst->nFrames) {
00278
00279
00280 for (idst = 0 ; idst < nFB; idst++) if (ESrc->Frames[i] == FramesBuff[idst]) break;
00281
00282 if (idst >= nFB) FramesBuff[nFB++] = ESrc->Frames[i];
00283 }
00284 }
00285
00286 dstFr = (long *)malloc((EDst->nFrames+nFB)*sizeof(long));
00287 memcpy(dstFr, EDst->Frames, EDst->nFrames*sizeof(long));
00288 memcpy(dstFr+EDst->nFrames, FramesBuff, nFB*sizeof(long));
00289
00290 free(EDst->Frames);
00291 EDst->Frames = dstFr;
00292 EDst->nFrames += nFB;
00293
00294 _amiEventListSortFrames(EDst);
00295
00296
00297 nFB = 0;
00298 for (i = 0; i < ESrc->nTypes; i++) {
00299 for (idst = 0 ; idst < EDst->nTypes; idst++) if (ESrc->Types[i] == EDst->Types[idst]) break;
00300 if (idst >= EDst->nTypes) {
00301 for (idst = 0 ; idst < nFB; idst++) if (ESrc->Types[i] == FramesBuff[idst]) break;
00302 if (idst >= nFB) FramesBuff[nFB++] = ESrc->Types[i];
00303 }
00304 }
00305
00306 dstType = (int *)malloc((EDst->nTypes+nFB)*sizeof(int));
00307 memcpy(dstType, EDst->Types, EDst->nTypes*sizeof(long));
00308 memcpy(dstType+EDst->nTypes, FramesBuff, nFB*sizeof(long));
00309 free(EDst->Types);
00310 EDst->Types = dstType;
00311 EDst->nTypes += nFB;
00312
00313 return 1;
00314 }
00315
00324 int amiEventListLoad(amiEventList * E, const char * Filename)
00325 {
00326 int i;
00327 amiEventList * EventsTmp = amiEventListNew();
00328
00329 EventsTmp->defaultType = E->defaultType;
00330
00331 for (i = strlen(Filename)-1; i >= 0; i--) if (Filename[i] == '.') break;
00332
00333 #ifdef AMI_EVENT_LIST_LOAD_XML
00334 if (strncmp(&(Filename[i+1]), "xml", 3) == 0) _amiEventListLoadXML(EventsTmp, Filename);
00335 else _amiEventListLoadTXT(EventsTmp, Filename);
00336 #else
00337 if (strncmp(&(Filename[i+1]), "xml", 3) == 0) return -1;
00338 else _amiEventListLoadTXT(EventsTmp, Filename);
00339 #endif
00340
00341 amiEventListMerge(E, EventsTmp);
00342 amiEventListFree(EventsTmp);
00343
00344 return 1;
00345 }
00346
00347
00353 int amiEventListEmpty(amiEventList * E)
00354 {
00355 return (E->nEvents == 0);
00356 }
00357
00358
00359
00360 #ifdef AMI_EVENT_LIST_LOAD_XML
00361
00362 #include <libxml\tree.h>
00363
00370 int _amiEventSetXML(amiEvent * Event, xmlNodePtr Node)
00371 {
00372 xmlAttrPtr Param;
00373 float x1, x2, y1, y2;
00374
00375 assert(Event);
00376 assert(Node);
00377
00378 while (Node) {
00379 if (xmlStrcmp(Node->name, BAD_CAST "Time") == 0)
00380 Event->Time = atol(Node->children->content);
00381 else if (xmlStrcmp(Node->name, BAD_CAST "ID") == 0)
00382 Event->Type = (unsigned char)atoi(Node->children->content);
00383 else if (xmlStrcmp(Node->name, BAD_CAST "Parameters") == 0) {
00384 Param = Node->properties;
00385 while (Param) {
00386 if (xmlStrcmp(Param->name,"MinX")==0) x1 = atof(Param->children->content);
00387 else if (xmlStrcmp(Param->name,"MinY")==0) y1 = atof(Param->children->content);
00388 else if (xmlStrcmp(Param->name,"MaxX")==0) x2 = atof(Param->children->content);
00389 else if (xmlStrcmp(Param->name,"MaxY")==0) y2 = atof(Param->children->content);
00390 else if (xmlStrcmp(Param->name,"Object")==0)
00391 Event->ObjectID = (unsigned int)atoi(Param->children->content);
00392 Param = Param->next;
00393 }
00394 amiPoint2iSet(Event->pMin, (int)x1, (int)y1);
00395 amiPoint2iSet(Event->pMax, (int)x2, (int)y2);
00396
00397 }
00398 Node = Node->next;
00399 }
00400 return 1;
00401 }
00402
00403
00413 int _amiEventListLoadXML(amiEventList * E, const char * Filename)
00414 {
00415 amiEvent * actE;
00416 xmlNodePtr nodeE, backUp;
00417 long i;
00418 long FramesBuff[FRAMES_BUFF_SIZE];
00419 long nFB;
00420 int TypesBuff[EVENT_BUFF_SIZE];
00421 long nTB;
00422 long size, last;
00423 xmlDocPtr docXML;
00424
00425 assert(E);
00426
00427 xmlInitParser();
00428 docXML = xmlParseFile(Filename);
00429 if (!docXML) return -1;
00430 nodeE = docXML->children->children;
00431 while (nodeE && (xmlStrcmp(nodeE->name, BAD_CAST "File") != 0)) nodeE = nodeE->next;
00432 nodeE = nodeE->children;
00433 backUp = nodeE;
00434
00435 size = 0;
00436 while (nodeE) {
00437 if (xmlStrcmp(nodeE->name, BAD_CAST "Event") == 0) size++;
00438 nodeE = nodeE->next;
00439 }
00440
00441 amiEventListInit(E, size);
00442
00443 nodeE = backUp;
00444 actE = E->Event;
00445 last = -1;
00446 nFB = 0;
00447 nTB = 0;
00448 while(nodeE) {
00449 if (xmlStrcmp(nodeE->name, BAD_CAST "Event") == 0) {
00450 _amiEventSetXML(actE, nodeE->children);
00451 if (last != actE->Time) {
00452
00453 for (size = 0 ; size < nFB; size++) if (actE->Time == FramesBuff[size]) break;
00454
00455 if (size >= nFB) {
00456 FramesBuff[nFB++] = actE->Time;
00457 last = actE->Time;
00458 }
00459 }
00460 for (size = 0; size < nTB; size++) if (actE->Type == TypesBuff[size]) break;
00461 if (size >= E->nTypes) TypesBuff[nTB++] = actE->Type;
00462
00463 actE++;
00464 }
00465 nodeE = nodeE->next;
00466 }
00467
00468 E->nFrames = nFB;
00469 E->Frames = (long *)malloc(E->nFrames*sizeof(long));
00470 memcpy(E->Frames, FramesBuff, E->nFrames*sizeof(long));
00471
00472 _amiEventListSortFrames(E);
00473
00474 E->nTypes = nTB;
00475 E->Types = (int *)malloc(E->nTypes*sizeof(int));
00476 memcpy(E->Types, TypesBuff, E->nTypes*sizeof(int));
00477
00478
00479 xmlFreeDoc(docXML); docXML = NULL;
00480
00481 return 1;
00482 }
00483
00484
00485
00486 #endif
00487
00488
00489
00490
00491
00496 amiEventsSubSet * amiEventsSubSetNew(void)
00497 {
00498 amiEventsSubSet * ES = (amiEventsSubSet *)malloc(sizeof(amiEventsSubSet));
00499 assert(ES);
00500 ES->n = 0;
00501 ES->Event = NULL;
00502 return ES;
00503 }
00504
00505
00510 int amiEventsSubSetFree(amiEventsSubSet * ES)
00511 {
00512 assert(ES);
00513 free(ES->Event); ES->Event = NULL;
00514 ES->n = 0;
00515 free(ES);
00516 ES = NULL;
00517 return 1;
00518 }
00519
00520
00528 int amiEventsSubSetInit(amiEventsSubSet * ES, amiEventList * E, long Frame, int *Types, int nTypes)
00529 {
00530 amiEvent * itr;
00531 amiEvent * buff[EVENT_BUFF_SIZE];
00532 long nbuff, i, k;
00533
00534 itr = E->Event;
00535 nbuff = 0;
00536 for (i = 0; i < E->nEvents; i++) {
00537 if (itr->Time == Frame) {
00538 k = -1;
00539 if (Types) for (k = 0; k < nTypes; k++) if (Types[k] == itr->Type) break;
00540
00541 if (k < nTypes) buff[nbuff++] = itr;
00542 }
00543 itr++;
00544 }
00545
00546 ES->n = nbuff;
00547 if (ES->Event || nbuff)
00548 ES->Event = (amiEvent **)realloc(ES->Event, nbuff*sizeof(amiEvent *));
00549 if (nbuff > 0)
00550 memcpy(ES->Event, buff, nbuff*sizeof(amiEvent *));
00551
00552 return 1;
00553 }
00554
00555
00556
00557
00558
00559
00560