changes: 1) fixes problems in the original EyeTracking benchmark 2) fix a bug in...
authoryeom <yeom>
Sat, 3 Nov 2012 06:17:21 +0000 (06:17 +0000)
committeryeom <yeom>
Sat, 3 Nov 2012 06:17:21 +0000 (06:17 +0000)
Inference engine generated annotations again for the EyeTracking, but it has location type errors.

28 files changed:
Robust/src/Analysis/SSJava/DefinitelyWrittenCheck.java
Robust/src/Analysis/SSJava/FlowDownCheck.java
Robust/src/Analysis/SSJava/FlowGraph.java
Robust/src/Analysis/SSJava/FlowNode.java
Robust/src/Analysis/SSJava/LocationInference.java
Robust/src/Analysis/SSJava/SSJavaAnalysis.java
Robust/src/Benchmarks/SSJava/EyeTracking/ClassifierTree.java
Robust/src/Benchmarks/SSJava/EyeTracking/EyeDetector.java
Robust/src/Benchmarks/SSJava/EyeTracking/EyePosition.java
Robust/src/Benchmarks/SSJava/EyeTracking/FaceAndEyePosition.java
Robust/src/Benchmarks/SSJava/EyeTracking/LEA.java
Robust/src/Benchmarks/SSJava/EyeTracking/LEAImplementation.java
Robust/src/Benchmarks/SSJava/EyeTracking/Point.java
Robust/src/Benchmarks/SSJava/EyeTrackingInfer/Classifier.java
Robust/src/Benchmarks/SSJava/EyeTrackingInfer/ClassifierTree.java
Robust/src/Benchmarks/SSJava/EyeTrackingInfer/DeviationScanner.java
Robust/src/Benchmarks/SSJava/EyeTrackingInfer/DummyCaptureDevice.java
Robust/src/Benchmarks/SSJava/EyeTrackingInfer/EyeDetector.java
Robust/src/Benchmarks/SSJava/EyeTrackingInfer/EyePosition.java
Robust/src/Benchmarks/SSJava/EyeTrackingInfer/FaceAndEyePosition.java
Robust/src/Benchmarks/SSJava/EyeTrackingInfer/ICaptureDevice.java
Robust/src/Benchmarks/SSJava/EyeTrackingInfer/Image.java
Robust/src/Benchmarks/SSJava/EyeTrackingInfer/IntegralImageData.java
Robust/src/Benchmarks/SSJava/EyeTrackingInfer/LEA.java
Robust/src/Benchmarks/SSJava/EyeTrackingInfer/LEAImplementation.java
Robust/src/Benchmarks/SSJava/EyeTrackingInfer/Point.java
Robust/src/Benchmarks/SSJava/EyeTrackingInfer/Rectangle2D.java
Robust/src/Benchmarks/SSJava/EyeTrackingInfer/ScanArea.java

index 052ec48..c1f4824 100644 (file)
@@ -67,6 +67,8 @@ public class DefinitelyWrittenCheck {
   // written to but not overwritten by the higher value
   private Hashtable<FlatMethod, SharedLocMap> mapFlatMethodToDeleteSet;
 
+  private Hashtable<FlatMethod, SharedLocMap> mapFlatMethodToMustClearMap;
+
   // maps a flat method to the S SET that is a set of heap path to shared
   // locations that are overwritten by the higher value
   private Hashtable<FlatMethod, SharedLocMap> mapFlatMethodToSharedLocMap;
@@ -113,6 +115,7 @@ public class DefinitelyWrittenCheck {
 
   private Hashtable<FlatNode, SharedLocMap> mapFlatNodeToSharedLocMapping;
   private Hashtable<FlatNode, SharedLocMap> mapFlatNodeToDeleteSet;
+  private Hashtable<FlatNode, SharedLocMap> mapFlatNodeToMustClearMap;
 
   private LoopFinder ssjavaLoop;
   private Set<FlatNode> loopIncElements;
@@ -122,6 +125,7 @@ public class DefinitelyWrittenCheck {
   private Set<NTuple<Descriptor>> calleeUnionBoundMayWriteSet;
   private SharedLocMap calleeUnionBoundDeleteSet;
   private SharedLocMap calleeIntersectBoundSharedSet;
+  private SharedLocMap calleeIntersectBoundMustClearSet;
 
   Set<TempDescriptor> liveInTempSetToEventLoop;
 
@@ -167,6 +171,9 @@ public class DefinitelyWrittenCheck {
     this.mapFlatNodeToDeleteSet = new Hashtable<FlatNode, SharedLocMap>();
     this.liveness = new Liveness();
     this.liveInTempSetToEventLoop = new HashSet<TempDescriptor>();
+    this.mapFlatNodeToMustClearMap = new Hashtable<FlatNode, SharedLocMap>();
+    this.calleeIntersectBoundMustClearSet = new SharedLocMap();
+    this.mapFlatMethodToMustClearMap = new Hashtable<FlatMethod, SharedLocMap>();
   }
 
   public void definitelyWrittenCheck() {
@@ -211,14 +218,18 @@ public class DefinitelyWrittenCheck {
 
       SharedLocMap sharedLocMap = new SharedLocMap();
       SharedLocMap deleteSet = new SharedLocMap();
+      SharedLocMap mustClearMap = new SharedLocMap();
 
-      sharedLoc_analyzeMethod(fm, sharedLocMap, deleteSet);
+      sharedLoc_analyzeMethod(fm, sharedLocMap, deleteSet, mustClearMap);
       SharedLocMap prevSharedLocMap = mapFlatMethodToSharedLocMap.get(fm);
       SharedLocMap prevDeleteSet = mapFlatMethodToDeleteSet.get(fm);
+      SharedLocMap prevMustClearMap = mapFlatMethodToMustClearMap.get(fm);
 
-      if (!(deleteSet.equals(prevDeleteSet) && sharedLocMap.equals(prevSharedLocMap))) {
+      if (!(deleteSet.equals(prevDeleteSet) && sharedLocMap.equals(prevSharedLocMap) && mustClearMap
+          .equals(prevMustClearMap))) {
         mapFlatMethodToSharedLocMap.put(fm, sharedLocMap);
         mapFlatMethodToDeleteSet.put(fm, deleteSet);
+        mapFlatMethodToMustClearMap.put(fm, mustClearMap);
 
         // results for callee changed, so enqueue dependents caller for
         // further
@@ -247,23 +258,24 @@ public class DefinitelyWrittenCheck {
     }
     SharedLocMap sharedLocMap = new SharedLocMap();
     SharedLocMap deleteSet = new SharedLocMap();
+    SharedLocMap mustClearMap = new SharedLocMap();
     sharedLoc_analyzeBody(state.getMethodFlat(methodContainingSSJavaLoop),
-        ssjava.getSSJavaLoopEntrance(), sharedLocMap, deleteSet, true);
+        ssjava.getSSJavaLoopEntrance(), sharedLocMap, deleteSet, mustClearMap, true);
 
   }
 
   private void sharedLoc_analyzeMethod(FlatMethod fm, SharedLocMap sharedLocMap,
-      SharedLocMap deleteSet) {
+      SharedLocMap deleteSet, SharedLocMap mustClearMap) {
     if (state.SSJAVADEBUG) {
       System.out.println("SSJAVA: Definite clearance for shared locations Analyzing: " + fm);
     }
 
-    sharedLoc_analyzeBody(fm, fm, sharedLocMap, deleteSet, false);
+    sharedLoc_analyzeBody(fm, fm, sharedLocMap, deleteSet, mustClearMap, false);
 
   }
 
   private void sharedLoc_analyzeBody(FlatMethod fm, FlatNode startNode, SharedLocMap sharedLocMap,
-      SharedLocMap deleteSet, boolean isEventLoopBody) {
+      SharedLocMap deleteSet, SharedLocMap mustClearMap, boolean isEventLoopBody) {
 
     // intraprocedural analysis
     Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
@@ -275,6 +287,7 @@ public class DefinitelyWrittenCheck {
 
       SharedLocMap currSharedSet = new SharedLocMap();
       SharedLocMap currDeleteSet = new SharedLocMap();
+      SharedLocMap currMustClearMap = new SharedLocMap();
 
       for (int i = 0; i < fn.numPrev(); i++) {
         FlatNode prevFn = fn.getPrev(i);
@@ -287,17 +300,26 @@ public class DefinitelyWrittenCheck {
         if (inDeleteLoc != null) {
           mergeDeleteSet(currDeleteSet, inDeleteLoc);
         }
+
+        SharedLocMap inMustClearMap = mapFlatNodeToMustClearMap.get(prevFn);
+        if (inMustClearMap != null) {
+          mergeSharedLocMap(currMustClearMap, inMustClearMap);
+        }
+
       }
 
-      sharedLoc_nodeActions(fm, fn, currSharedSet, currDeleteSet, sharedLocMap, deleteSet,
-          isEventLoopBody);
+      sharedLoc_nodeActions(fm, fn, currSharedSet, currDeleteSet, currMustClearMap, sharedLocMap,
+          deleteSet, mustClearMap, isEventLoopBody);
 
       SharedLocMap prevSharedSet = mapFlatNodeToSharedLocMapping.get(fn);
       SharedLocMap prevDeleteSet = mapFlatNodeToDeleteSet.get(fn);
+      SharedLocMap prevMustClearMap = mapFlatNodeToMustClearMap.get(fn);
 
-      if (!(currSharedSet.equals(prevSharedSet) && currDeleteSet.equals(prevDeleteSet))) {
+      if (!(currSharedSet.equals(prevSharedSet) && currDeleteSet.equals(prevDeleteSet) && currMustClearMap
+          .equals(prevMustClearMap))) {
         mapFlatNodeToSharedLocMapping.put(fn, currSharedSet);
         mapFlatNodeToDeleteSet.put(fn, currDeleteSet);
+        mapFlatNodeToMustClearMap.put(fn, currMustClearMap);
         for (int i = 0; i < fn.numNext(); i++) {
           FlatNode nn = fn.getNext(i);
           if ((!isEventLoopBody) || loopIncElements.contains(nn)) {
@@ -312,8 +334,8 @@ public class DefinitelyWrittenCheck {
   }
 
   private void sharedLoc_nodeActions(FlatMethod fm, FlatNode fn, SharedLocMap curr,
-      SharedLocMap currDeleteSet, SharedLocMap sharedLocMap, SharedLocMap deleteSet,
-      boolean isEventLoopBody) {
+      SharedLocMap currDeleteSet, SharedLocMap currMustClearMap, SharedLocMap sharedLocMap,
+      SharedLocMap deleteSet, SharedLocMap mustClearMap, boolean isEventLoopBody) {
 
     MethodDescriptor md = fm.getMethod();
 
@@ -324,6 +346,10 @@ public class DefinitelyWrittenCheck {
     TempDescriptor rhs;
     FieldDescriptor fld;
 
+    NTuple<Location> fieldLocTuple = null;
+    Location fieldLoc = null;
+    boolean isHigherWriteCase = false;
+
     switch (fn.kind()) {
 
     case FKind.FlatOpNode: {
@@ -374,7 +400,6 @@ public class DefinitelyWrittenCheck {
     case FKind.FlatSetFieldNode:
     case FKind.FlatSetElementNode: {
 
-      Location fieldLoc;
       if (fn.kind() == FKind.FlatSetFieldNode) {
         FlatSetFieldNode fsfn = (FlatSetFieldNode) fn;
         lhs = fsfn.getDst();
@@ -391,7 +416,7 @@ public class DefinitelyWrittenCheck {
         break;
       }
 
-      NTuple<Location> fieldLocTuple = new NTuple<Location>();
+      fieldLocTuple = new NTuple<Location>();
       if (fld.isStatic()) {
         if (fld.isFinal()) {
           // in this case, fld has TOP location
@@ -433,6 +458,9 @@ public class DefinitelyWrittenCheck {
         if (!ssjava.isSameHeightWrite(fn)) {
           computeGENSetForHigherWrite(curr, genSet, fieldLocTuple, fldHeapPath);
           updateDeleteSetForHigherWrite(currDeleteSet, fieldLocTuple, fldHeapPath);
+
+          isHigherWriteCase = true;
+
         } else {
           computeGENSetForSameHeightWrite(curr, genSet, fieldLocTuple, fldHeapPath);
           updateDeleteSetForSameHeightWrite(currDeleteSet, fieldLocTuple, fldHeapPath);
@@ -452,6 +480,12 @@ public class DefinitelyWrittenCheck {
       generateKILLSetForFlatCall(curr, killSet);
       generateGENSetForFlatCall(curr, genSet);
 
+      Set<NTuple<Location>> locTupleSet = calleeIntersectBoundMustClearSet.keySet();
+      for (Iterator iterator = locTupleSet.iterator(); iterator.hasNext();) {
+        NTuple<Location> locTupleKey = (NTuple<Location>) iterator.next();
+        currMustClearMap.addWrite(locTupleKey, calleeIntersectBoundMustClearSet.get(locTupleKey));
+      }
+
     }
       break;
 
@@ -459,13 +493,38 @@ public class DefinitelyWrittenCheck {
       // merge the current delete/shared loc mapping
       mergeSharedLocMap(sharedLocMap, curr);
       mergeDeleteSet(deleteSet, currDeleteSet);
-
+      mergeSharedLocMap(mustClearMap, currMustClearMap);
     }
       break;
 
     }
 
     computeNewMapping(curr, killSet, genSet);
+    if (isHigherWriteCase) {
+      // check all locations with the same shared location are cleared out at this point
+      Set<NTuple<Descriptor>> writtenSet = curr.get(fieldLocTuple);
+      Set<Descriptor> requirementSet = ssjava.getSharedDescSet(fieldLoc);
+
+      if (checkAllSharedLocationsAreOverwritten(requirementSet, writtenSet)) {
+        currMustClearMap.addWrite(fieldLocTuple, writtenSet);
+      }
+    }
+  }
+
+  private boolean checkAllSharedLocationsAreOverwritten(Set<Descriptor> sharedDescSet,
+      Set<NTuple<Descriptor>> writtenSet) {
+
+    if (sharedDescSet == null || writtenSet == null) {
+      return false;
+    }
+    Set<Descriptor> writtenDescSet = new HashSet<Descriptor>();
+    for (Iterator iterator = writtenSet.iterator(); iterator.hasNext();) {
+      NTuple<Descriptor> tuple = (NTuple<Descriptor>) iterator.next();
+      writtenDescSet.add(tuple.get(tuple.size() - 1));
+    }
+
+    return writtenDescSet.containsAll(sharedDescSet);
+    // return sharedDescSet.containsAll(writtenDescSet);
 
   }
 
@@ -527,7 +586,6 @@ public class DefinitelyWrittenCheck {
     if (currWriteSet != null) {
       genSet.addWrite(locTuple, currWriteSet);
     }
-
     genSet.addWrite(locTuple, hp);
   }
 
@@ -604,7 +662,6 @@ public class DefinitelyWrittenCheck {
 
   private void computeSharedCoverSet_analyzeMethod(FlatMethod fm, boolean onlyVisitSSJavaLoop) {
 
-    // System.out.println("computeSharedCoverSet_analyzeMethod=" + fm);
     MethodDescriptor md = fm.getMethod();
 
     Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
@@ -1296,7 +1353,10 @@ public class DefinitelyWrittenCheck {
                 Set<NTuple<Descriptor>> writtenSet =
                     mapFlatNodeToSharedLocMapping.get(fn).get(varLocTuple);
 
-                if (isCovered(varLocTuple, writtenSet)) {
+                Set<NTuple<Descriptor>> mustClearSet =
+                    mapFlatNodeToMustClearMap.get(fn).get(varLocTuple);
+
+                if (isCovered(varLocTuple, writtenSet, mustClearSet)) {
                   computeKILLSetForSharedWrite(curr, writtenSet, readWriteKillSet);
                   computeGENSetForSharedAllCoverWrite(curr, writtenSet, readWriteGenSet);
                 } else {
@@ -1398,7 +1458,6 @@ public class DefinitelyWrittenCheck {
 
             Set<NTuple<Descriptor>> writtenSet =
                 mapFlatNodeToSharedLocMapping.get(fn).get(fieldLocTuple);
-
             if (isCovered(fieldLocTuple, writtenSet)) {
               computeKILLSetForSharedWrite(curr, writtenSet, readWriteKillSet);
               computeGENSetForSharedAllCoverWrite(curr, writtenSet, readWriteGenSet);
@@ -1418,10 +1477,10 @@ public class DefinitelyWrittenCheck {
 
       case FKind.FlatCall: {
         FlatCall fc = (FlatCall) fn;
-
         SharedLocMap sharedLocMap = mapFlatNodeToSharedLocMapping.get(fc);
-        generateKILLSetForFlatCall(fc, curr, sharedLocMap, readWriteKillSet);
-        generateGENSetForFlatCall(fc, sharedLocMap, readWriteGenSet);
+        SharedLocMap mustClearMap = mapFlatNodeToMustClearMap.get(fc);
+        generateKILLSetForFlatCall(fc, curr, sharedLocMap, mustClearMap, readWriteKillSet);
+        generateGENSetForFlatCall(fc, sharedLocMap, mustClearMap, readWriteGenSet);
 
       }
         break;
@@ -1479,22 +1538,37 @@ public class DefinitelyWrittenCheck {
 
   }
 
-  private boolean isCovered(NTuple<Location> locTuple, Set<NTuple<Descriptor>> inSet) {
+  private boolean isCovered(NTuple<Location> locTuple, Set<NTuple<Descriptor>> curWrittenSet) {
 
-    if (inSet == null) {
+    Set<NTuple<Descriptor>> coverSet =
+        mapMethodToSharedLocCoverSet.get(methodContainingSSJavaLoop).get(locTuple);
+
+    if (curWrittenSet == null) {
       return false;
     }
 
+    return curWrittenSet.containsAll(coverSet);
+  }
+
+  private boolean isCovered(NTuple<Location> locTuple, Set<NTuple<Descriptor>> curWrittenSet,
+      Set<NTuple<Descriptor>> mustClearSet) {
+
     Set<NTuple<Descriptor>> coverSet =
         mapMethodToSharedLocCoverSet.get(methodContainingSSJavaLoop).get(locTuple);
 
-    return inSet.containsAll(coverSet);
+    if (mustClearSet != null && mustClearSet.containsAll(coverSet)) {
+      return true;
+    }
+
+    if (curWrittenSet == null) {
+      return false;
+    }
+
+    return curWrittenSet.containsAll(coverSet);
   }
 
   private void checkManyRead(FlatCall fc, Hashtable<NTuple<Descriptor>, Set<WriteAge>> curr) {
-
     Set<NTuple<Descriptor>> boundReadSet = mapFlatNodeToBoundReadSet.get(fc);
-
     for (Iterator iterator = boundReadSet.iterator(); iterator.hasNext();) {
       NTuple<Descriptor> readHeapPath = (NTuple<Descriptor>) iterator.next();
       Set<WriteAge> writeAgeSet = curr.get(readHeapPath);
@@ -1540,7 +1614,7 @@ public class DefinitelyWrittenCheck {
   }
 
   private void generateGENSetForFlatCall(FlatCall fc, SharedLocMap sharedLocMap,
-      Hashtable<NTuple<Descriptor>, Set<WriteAge>> GENSet) {
+      SharedLocMap mustClearMap, Hashtable<NTuple<Descriptor>, Set<WriteAge>> GENSet) {
 
     Set<NTuple<Descriptor>> boundMayWriteSet = mapFlatNodeToBoundMayWriteSet.get(fc);
 
@@ -1556,10 +1630,9 @@ public class DefinitelyWrittenCheck {
 
         Set<NTuple<Descriptor>> sharedWriteHeapPathSet = sharedLocMap.get(locTuple);
 
-        if (isCovered(locTuple, sharedLocMap.get(locTuple))) {
+        if (isCovered(locTuple, sharedLocMap.get(locTuple), mustClearMap.get(locTuple))) {
           // if it is covered, add all of heap paths belong to the same shared
           // loc with write age 0
-
           for (Iterator iterator2 = sharedWriteHeapPathSet.iterator(); iterator2.hasNext();) {
             NTuple<Descriptor> sharedHeapPath = (NTuple<Descriptor>) iterator2.next();
             addWriteAgeToSet(sharedHeapPath, GENSet, new WriteAge(0));
@@ -1591,7 +1664,7 @@ public class DefinitelyWrittenCheck {
 
   private void generateKILLSetForFlatCall(FlatCall fc,
       Hashtable<NTuple<Descriptor>, Set<WriteAge>> curr, SharedLocMap sharedLocMap,
-      Hashtable<NTuple<Descriptor>, Set<WriteAge>> KILLSet) {
+      SharedLocMap mustClearMap, Hashtable<NTuple<Descriptor>, Set<WriteAge>> KILLSet) {
 
     Set<NTuple<Descriptor>> boundMustWriteSet = mapFlatNodeToBoundMustWriteSet.get(fc);
 
@@ -1601,7 +1674,8 @@ public class DefinitelyWrittenCheck {
       if (isSharedLocation(heapPath)) {
         NTuple<Location> locTuple = getLocationTuple(heapPath);
 
-        if (isCovered(locTuple, sharedLocMap.get(locTuple)) && curr.containsKey(heapPath)) {
+        if (isCovered(locTuple, sharedLocMap.get(locTuple), mustClearMap.get(locTuple))
+            && curr.containsKey(heapPath)) {
           // if it is shared loc and corresponding shared loc has been covered
           KILLSet.put(heapPath, curr.get(heapPath));
         }
@@ -1909,6 +1983,7 @@ public class DefinitelyWrittenCheck {
           NTuple<Location> calleeLocationPath = deriveLocationTuple(mdCallee, calleeParam);
           SharedLocMap calleeDeleteSet = mapFlatMethodToDeleteSet.get(calleeFlatMethod);
           SharedLocMap calleeSharedLocMap = mapFlatMethodToSharedLocMap.get(calleeFlatMethod);
+          SharedLocMap calleeMustClearMap = mapFlatMethodToMustClearMap.get(calleeFlatMethod);
 
           if (calleeDeleteSet != null) {
             createNewMappingOfDeleteSet(callerArgLocationPath, callerArgHeapPath,
@@ -1920,6 +1995,11 @@ public class DefinitelyWrittenCheck {
                 calleeLocationPath, calleeSharedLocMap);
           }
 
+          if (calleeMustClearMap != null) {
+            createNewMappingOfMustClearMap(callerArgLocationPath, callerArgHeapPath,
+                calleeLocationPath, calleeMustClearMap);
+          }
+
         }
 
       }
@@ -1927,6 +2007,28 @@ public class DefinitelyWrittenCheck {
 
   }
 
+  private void createNewMappingOfMustClearMap(NTuple<Location> callerArgLocationPath,
+      NTuple<Descriptor> callerArgHeapPath, NTuple<Location> calleeLocationPath,
+      SharedLocMap calleeMustClearMap) {
+
+    SharedLocMap calleeParamSharedSet =
+        calleeMustClearMap.getHeapPathStartedWith(calleeLocationPath);
+
+    Set<NTuple<Location>> keySet = calleeParamSharedSet.keySet();
+    for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
+      NTuple<Location> calleeLocTupleKey = (NTuple<Location>) iterator.next();
+      Set<NTuple<Descriptor>> heapPathSet = calleeParamSharedSet.get(calleeLocTupleKey);
+      Set<NTuple<Descriptor>> boundHeapPathSet = new HashSet<NTuple<Descriptor>>();
+      for (Iterator iterator2 = heapPathSet.iterator(); iterator2.hasNext();) {
+        NTuple<Descriptor> calleeHeapPath = (NTuple<Descriptor>) iterator2.next();
+        boundHeapPathSet.add(bindHeapPath(callerArgHeapPath, calleeHeapPath));
+      }
+      calleeIntersectBoundMustClearSet.intersect(
+          bindLocationPath(callerArgLocationPath, calleeLocTupleKey), boundHeapPathSet);
+    }
+
+  }
+
   private void createNewMappingOfDeleteSet(NTuple<Location> callerArgLocationPath,
       NTuple<Descriptor> callerArgHeapPath, NTuple<Location> calleeLocationPath,
       SharedLocMap calleeDeleteSet) {
index 3d24596..d9bc290 100644 (file)
@@ -1155,7 +1155,12 @@ public class FlowDownCheck {
     // System.out.println("base location=" + callerBaseLoc + " constraint=" +
     // constraint);
 
-    for (int i = 0; i < calleeParamList.size(); i++) {
+    System.out.println("calleeParamList=" + calleeParamList);
+    int offset = 0;
+    if (!md.isStatic()) {
+      offset = 1;
+    }
+    for (int i = offset; i < calleeParamList.size(); i++) {
       CompositeLocation calleeParamLoc = calleeParamList.get(i);
       if (calleeParamLoc.get(0).equals(calleeThisLoc) && calleeParamLoc.getSize() > 1) {
 
@@ -1182,6 +1187,8 @@ public class FlowDownCheck {
           continue;
         }
 
+        System.out.println("---idx=" + i + "  callerArgLoc=" + callerArgLoc + "   paramLocation="
+            + paramLocation);
         // if (!CompositeLattice.isGreaterThan(callerArgLoc, paramLocation, errorMsg)) {
         if (CompositeLattice.compare(callerArgLoc, paramLocation, true, errorMsg) == ComparisonResult.LESS) {
           throw new Error("Caller argument '" + min.getArg(i).printNode(0) + " : " + callerArgLoc
@@ -1736,9 +1743,12 @@ public class FlowDownCheck {
         Set<FlatNode> flatNodeSet = ssjava.getBuildFlat().getFlatNodeSet(an);
         for (Iterator iterator = flatNodeSet.iterator(); iterator.hasNext();) {
           FlatNode fn = (FlatNode) iterator.next();
+          System.out.println("SAMEHEIGHT!");
           ssjava.addSameHeightWriteFlatNode(fn);
         }
 
+      } else {
+        System.out.println("NOT SAME HEIGHT!");
       }
 
     } else {
@@ -1985,6 +1995,9 @@ public class FlowDownCheck {
 
         addLocationType(fd.getType(), loc);
 
+        if (ssjava.isSharedLocation(loc)) {
+          ssjava.addSharedDesc(loc, fd);
+        }
       }
     }
 
index c2a8f8e..b9a39f7 100644 (file)
@@ -458,7 +458,7 @@ public class FlowGraph {
         FlowReturnNode rnode = (FlowReturnNode) originalSrcNode;
         Set<NTuple<Descriptor>> rtupleSetFromRNode = rnode.getReturnTupleSet();
         Set<NTuple<Descriptor>> rtupleSet = getReturnTupleSet(rtupleSetFromRNode);
-        System.out.println("#rnode=" + rnode + "  rtupleSet=" + rtupleSet);
+        // System.out.println("#rnode=" + rnode + "  rtupleSet=" + rtupleSet);
         for (Iterator iterator2 = rtupleSet.iterator(); iterator2.hasNext();) {
           NTuple<Descriptor> rtuple = (NTuple<Descriptor>) iterator2.next();
           if (rtuple.startsWith(prefix)) {
index 31a9ded..0c83d75 100644 (file)
@@ -28,6 +28,8 @@ public class FlowNode {
 
   private boolean isSkeleton;
 
+  private boolean isFormHolder = false;
+
   public boolean isIntermediate() {
     return isIntermediate;
   }
@@ -36,6 +38,14 @@ public class FlowNode {
     this.isIntermediate = isIntermediate;
   }
 
+  public void setFormHolder(boolean in) {
+    isFormHolder = in;
+  }
+
+  public boolean isFromHolder() {
+    return isFormHolder;
+  }
+
   public Set<FlowNode> getFieldNodeSet() {
     return fieldNodeSet;
   }
index e2adb19..5502eb8 100644 (file)
@@ -370,6 +370,26 @@ public class LocationInference {
     System.out.println("\nSSJAVA: Add addtional ordering constriants:");
     MethodDescriptor methodEventLoopDesc = ssjava.getMethodContainingSSJavaLoop();
     addAddtionalOrderingConstraints(methodEventLoopDesc);
+    // calculateReturnHolderLocation();
+  }
+
+  private void calculateReturnHolderLocation() {
+    LinkedList<MethodDescriptor> methodDescList =
+        (LinkedList<MethodDescriptor>) toanalyze_methodDescList.clone();
+
+    while (!methodDescList.isEmpty()) {
+      MethodDescriptor md = methodDescList.removeLast();
+
+      FlowGraph fg = getFlowGraph(md);
+      Set<FlowNode> nodeSet = fg.getNodeSet();
+      for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) {
+        FlowNode flowNode = (FlowNode) iterator.next();
+        if (flowNode.isFromHolder()) {
+          calculateCompositeLocationFromFlowGraph(md, flowNode);
+        }
+      }
+
+    }
   }
 
   private void updateCompositeLocationAssignments() {
@@ -1536,6 +1556,132 @@ public class LocationInference {
 
   }
 
+  private CompositeLocation calculateCompositeLocationFromFlowGraph(MethodDescriptor md,
+      FlowNode node) {
+
+    System.out.println("#############################################################");
+    System.out.println("calculateCompositeLocationFromFlowGraph=" + node);
+
+    FlowGraph flowGraph = getFlowGraph(md);
+    // NTuple<Location> paramLocTuple = translateToLocTuple(md, paramNode.getDescTuple());
+    // GlobalFlowNode paramGlobalNode = subGlobalFlowGraph.getFlowNode(paramLocTuple);
+
+    List<NTuple<Location>> prefixList = calculatePrefixListFlowGraph(flowGraph, node);
+
+    // Set<GlobalFlowNode> reachableNodeSet =
+    // subGlobalFlowGraph.getReachableNodeSetByPrefix(paramGlobalNode.getLocTuple().get(0));
+    //
+    Set<FlowNode> reachableNodeSet =
+        flowGraph.getReachableSetFrom(node.getDescTuple().subList(0, 1));
+
+    // Set<GlobalFlowNode> reachNodeSet = globalFlowGraph.getReachableNodeSetFrom(node);
+
+    // System.out.println("node=" + node + "    prefixList=" + prefixList);
+
+    for (int i = 0; i < prefixList.size(); i++) {
+      NTuple<Location> curPrefix = prefixList.get(i);
+      Set<NTuple<Location>> reachableCommonPrefixSet = new HashSet<NTuple<Location>>();
+
+      for (Iterator iterator2 = reachableNodeSet.iterator(); iterator2.hasNext();) {
+        FlowNode reachNode = (FlowNode) iterator2.next();
+        NTuple<Location> reachLocTuple = translateToLocTuple(md, reachNode.getCurrentDescTuple());
+        if (reachLocTuple.startsWith(curPrefix)) {
+          reachableCommonPrefixSet.add(reachLocTuple);
+        }
+      }
+      // System.out.println("reachableCommonPrefixSet=" + reachableCommonPrefixSet);
+
+      if (!reachableCommonPrefixSet.isEmpty()) {
+
+        MethodDescriptor curPrefixFirstElementMethodDesc =
+            (MethodDescriptor) curPrefix.get(0).getDescriptor();
+
+        // MethodDescriptor nodePrefixLocFirstElementMethodDesc =
+        // (MethodDescriptor) prefixLoc.getDescriptor();
+
+        // System.out.println("curPrefixFirstElementMethodDesc=" +
+        // curPrefixFirstElementMethodDesc);
+        // System.out.println("nodePrefixLocFirstElementMethodDesc="
+        // + nodePrefixLocFirstElementMethodDesc);
+
+        // TODO
+        // if (!node.getLocTuple().startsWith(curPrefix.get(0))) {
+
+        Location curPrefixLocalLoc = curPrefix.get(0);
+
+        Location targetLocalLoc = new Location(md, node.getDescTuple().get(0));
+        // Location targetLocalLoc = paramGlobalNode.getLocTuple().get(0);
+
+        CompositeLocation newCompLoc = generateCompositeLocation(curPrefix);
+        System.out.println("NEED2ASSIGN COMP LOC TO " + node + " with prefix=" + curPrefix);
+        System.out.println("-targetLocalLoc=" + targetLocalLoc + "   - newCompLoc=" + newCompLoc);
+
+        // // makes sure that a newly generated location appears in the hierarchy graph
+        // for (int compIdx = 0; compIdx < newCompLoc.getSize(); compIdx++) {
+        // Location curLoc = newCompLoc.get(compIdx);
+        // getHierarchyGraph(curLoc.getDescriptor()).getHNode(curLoc.getLocDescriptor());
+        // }
+        // subGlobalFlowGraph.addMapLocationToInferCompositeLocation(targetLocalLoc, newCompLoc);
+        node.setCompositeLocation(newCompLoc);
+
+        return newCompLoc;
+
+      }
+
+    }
+    return null;
+  }
+
+  private List<NTuple<Location>> calculatePrefixListFlowGraph(FlowGraph graph, FlowNode node) {
+
+    System.out.println("\n##### calculatePrefixList node=" + node);
+
+    MethodDescriptor md = graph.getMethodDescriptor();
+    Set<FlowNode> incomingNodeSetPrefix =
+        graph.getIncomingNodeSetByPrefix(node.getDescTuple().get(0));
+    // System.out.println("---incomingNodeSetPrefix=" + incomingNodeSetPrefix);
+
+    Set<FlowNode> reachableNodeSetPrefix =
+        graph.getReachableSetFrom(node.getDescTuple().subList(0, 1));
+    // System.out.println("---reachableNodeSetPrefix=" + reachableNodeSetPrefix);
+
+    List<NTuple<Location>> prefixList = new ArrayList<NTuple<Location>>();
+
+    for (Iterator iterator = incomingNodeSetPrefix.iterator(); iterator.hasNext();) {
+      FlowNode inNode = (FlowNode) iterator.next();
+      NTuple<Location> inNodeTuple = translateToLocTuple(md, inNode.getCurrentDescTuple());
+
+      // if (inNodeTuple.get(0).getLocDescriptor() instanceof InterDescriptor
+      // || inNodeTuple.get(0).getLocDescriptor().equals(GLOBALDESC)) {
+      // continue;
+      // }
+
+      for (int i = 1; i < inNodeTuple.size(); i++) {
+        NTuple<Location> prefix = inNodeTuple.subList(0, i);
+        if (!prefixList.contains(prefix)) {
+          prefixList.add(prefix);
+        }
+      }
+    }
+
+    Collections.sort(prefixList, new Comparator<NTuple<Location>>() {
+      public int compare(NTuple<Location> arg0, NTuple<Location> arg1) {
+        int s0 = arg0.size();
+        int s1 = arg1.size();
+        if (s0 > s1) {
+          return -1;
+        } else if (s0 == s1) {
+          return 0;
+        } else {
+          return 1;
+        }
+      }
+    });
+
+    return prefixList;
+
+  }
+
   private boolean containsClassDesc(ClassDescriptor cd, NTuple<Location> prefixLocTuple) {
     for (int i = 0; i < prefixLocTuple.size(); i++) {
       Location loc = prefixLocTuple.get(i);
@@ -1604,7 +1750,6 @@ public class LocationInference {
     NTuple<Location> locTuple = new NTuple<Location>();
 
     Descriptor enclosingDesc = md;
-    System.out.println("md=" + md + "  descTuple=" + descTuple);
     for (int i = 0; i < descTuple.size(); i++) {
       Descriptor desc = descTuple.get(i);
 
@@ -4966,12 +5111,14 @@ public class LocationInference {
 
       if (mdCallee.getReturnType() != null && !mdCallee.getReturnType().isVoid()) {
         FlowReturnNode setNode = getFlowGraph(mdCaller).createReturnNode(min);
-        System.out.println("ADD TUPLESET=" + tupleSet + " to returnnode=" + setNode);
 
         if (needToGenerateInterLoc(tupleSet)) {
           System.out.println("20");
           FlowGraph fg = getFlowGraph(mdCaller);
-          NTuple<Descriptor> interTuple = fg.createIntermediateNode().getDescTuple();
+          FlowNode interNode = fg.createIntermediateNode();
+          interNode.setFormHolder(true);
+
+          NTuple<Descriptor> interTuple = interNode.getDescTuple();
 
           for (Iterator iterator = tupleSet.iterator(); iterator.hasNext();) {
             NTuple<Descriptor> tuple = (NTuple<Descriptor>) iterator.next();
@@ -4990,10 +5137,14 @@ public class LocationInference {
           }
 
           setNode.addTuple(interTuple);
+          System.out.println("ADD TUPLESET=" + interTuple + " to returnnode=" + setNode);
+
         } else {
           setNode.addTupleSet(tupleSet);
-        }
+          System.out.println("ADD TUPLESET=" + tupleSet + " to returnnode=" + setNode);
 
+        }
+        // setNode.addTupleSet(tupleSet);
         nodeSet.addTuple(setNode.getDescTuple());
 
       }
index a39fd01..da84de6 100644 (file)
@@ -96,7 +96,7 @@ public class SSJavaAnalysis {
 
   // keep the field ownership from the linear type checking
   Hashtable<MethodDescriptor, Set<FieldDescriptor>> mapMethodToOwnedFieldSet;
-  
+
   Set<FlatNode> sameHeightWriteFlatNodeSet;
 
   CallGraph callgraph;
@@ -110,6 +110,8 @@ public class SSJavaAnalysis {
 
   private LinkedList<MethodDescriptor> sortedDescriptors;
 
+  private Map<Location, Set<Descriptor>> mapSharedLocToDescSet;
+
   public SSJavaAnalysis(State state, TypeUtil tu, BuildFlat bf, CallGraph callgraph) {
     this.state = state;
     this.tu = tu;
@@ -129,6 +131,7 @@ public class SSJavaAnalysis {
     this.mapDescriptorToSetDependents = new Hashtable<Descriptor, Set<MethodDescriptor>>();
     this.sortedDescriptors = new LinkedList<MethodDescriptor>();
     this.md2pcLoc = new HashMap<MethodDescriptor, CompositeLocation>();
+    this.mapSharedLocToDescSet = new HashMap<Location, Set<Descriptor>>();
   }
 
   public void doCheck() {
@@ -166,6 +169,17 @@ public class SSJavaAnalysis {
     return (LinkedList<MethodDescriptor>) sortedDescriptors.clone();
   }
 
+  public void addSharedDesc(Location loc, Descriptor fd) {
+    if (!mapSharedLocToDescSet.containsKey(loc)) {
+      mapSharedLocToDescSet.put(loc, new HashSet<Descriptor>());
+    }
+    mapSharedLocToDescSet.get(loc).add(fd);
+  }
+
+  public Set<Descriptor> getSharedDescSet(Location loc) {
+    return mapSharedLocToDescSet.get(loc);
+  }
+
   private void inference() {
     LocationInference inferEngine = new LocationInference(this, state);
     inferEngine.inference();
index fa69d23..3c7c94e 100644 (file)
@@ -14,7 +14,10 @@ import SSJava.PCLOC;
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
- * 
+ *   private Point readEyes(@LOC("IN") Image image, @LOC("IN") Rectangle2D rect) {
+ @LOC("OUT") EyeDetector ed = new EyeDetector(image, rect);
+ return ed.detectEye();
+ }
  * You should have received a copy of the GNU Lesser General Public License
  * along with LEA. If not, see <http://www.gnu.org/licenses/>.
  */
@@ -23,15 +26,33 @@ import SSJava.PCLOC;
  * 
  * @author Florian
  */
-@LATTICE("CS<C,C*")
+@LATTICE("C<CS,CS<CUR,CUR<PREV,PREV<SIZE,PREV*,C*,CUR*")
 @METHODDEFAULT("OUT<THIS,THIS<IN,THISLOC=THIS,RETURNLOC=OUT")
 public class ClassifierTree {
 
   @LOC("CS")
   private Classifier classifiers[];
 
-  public ClassifierTree(int size) {
+  @LOC("CUR")
+  double x;
+  @LOC("CUR")
+  double y;
+  @LOC("CUR")
+  double width;
+  @LOC("CUR")
+  double height;
+
+  @LOC("SIZE")
+  int size;
+
+  @LATTICE("THIS<IN,THISLOC=THIS")
+  public ClassifierTree(@LOC("IN") int size) {
+    this.size = size;
     classifiers = new Classifier[size];
+    x = -1;
+    y = -1;
+    width = -1;
+    height = -1;
   }
 
   public void addClassifier(@LOC("IN") int idx, @LOC("IN") Classifier c) {
@@ -39,120 +60,141 @@ public class ClassifierTree {
   }
 
   /**
-   * Locates a face by searching radial starting at the last known position. If
-   * lastCoordinates are null we simply start in the center of the image.
+   * Locates a face by searching radial starting at the last known position. If lastCoordinates are
+   * null we simply start in the center of the image.
    * <p>
-   * TODO: This method could quite possible be tweaked so that face recognition
-   * would be much faster
+   * TODO: This method could quite possible be tweaked so that face recognition would be much faster
    * 
    * @param image
    *          the image to process
    * @param lastCoordinates
    *          the last known coordinates or null if unknown
-   * @return an rectangle representing the actual face position on success or
-   *         null if no face could be detected
+   * @return an rectangle representing the actual face position on success or null if no face could
+   *         be detected
    */
   @LATTICE("OUT<CXY,CXY<THIS,THIS<V,V<IMG,IMG<C,C<IN,C*,V*,FACTOR*,CXY*,THISLOC=THIS,RETURNLOC=OUT,GLOBALLOC=IN")
-  @PCLOC("C")
-  public Rectangle2D locateFaceRadial(@LOC("IN") Image smallImage,
-      @LOC("THIS,ClassifierTree.C") Rectangle2D lastCoordinates) {
+  public void locateFaceRadial(@LOC("IN") Image smallImage) {
+
+    @LOC("THIS,ClassifierTree.CUR") double px = x;
+    @LOC("THIS,ClassifierTree.CUR") double py = y;
+    @LOC("THIS,ClassifierTree.CUR") double pwidth = width;
+    @LOC("THIS,ClassifierTree.CUR") double pheight = height;
+
+    x = -1;
+    y = -1;
+    width = -1;
+    height = -1;
 
     @LOC("IMG") IntegralImageData imageData = new IntegralImageData(smallImage);
     @LOC("IN") float originalImageFactor = 1;
-
-    if (lastCoordinates == null) {
+    if (px == -1) {
+      // if(true){
       // if we don't have a last coordinate we just begin in the center
-      @LOC("THIS,ClassifierTree.C") int smallImageMaxDimension =
+      @LOC("THIS,ClassifierTree.PREV") int smallImageMaxDimension =
           Math.min(smallImage.getWidth(), smallImage.getHeight());
-      lastCoordinates =
-          new Rectangle2D((smallImage.getWidth() - smallImageMaxDimension) / 2.0,
-              (smallImage.getHeight() - smallImageMaxDimension) / 2.0, smallImageMaxDimension,
-              smallImageMaxDimension);
-      // System.out.println("lastCoordinates=" + lastCoordinates);
+
+      px = (smallImage.getWidth() - smallImageMaxDimension) / 2.0;
+      py = (smallImage.getHeight() - smallImageMaxDimension) / 2.0;
+      pwidth = smallImageMaxDimension;
+      pheight = smallImageMaxDimension;
     } else {
       // first we have to scale the last coodinates back relative to the resized
       // image
-      lastCoordinates =
-          new Rectangle2D((lastCoordinates.getX() * (1 / originalImageFactor)),
-              (lastCoordinates.getY() * (1 / originalImageFactor)),
-              (lastCoordinates.getWidth() * (1 / originalImageFactor)),
-              (lastCoordinates.getHeight() * (1 / originalImageFactor)));
+      px = px * (1 / originalImageFactor);
+      py = py * (1 / originalImageFactor);
+      pwidth = pwidth * (1 / originalImageFactor);
+      pheight = pheight * (1 / originalImageFactor);
     }
 
-    @LOC("THIS,ClassifierTree.C") float startFactor = (float) (lastCoordinates.getWidth() / 100.0f);
+
+    @LOC("THIS,ClassifierTree.CUR") float startFactor = (float) (pwidth / 100.0f);
 
     // first we calculate the maximum scale factor for our 200x200 image
-    @LOC("THIS,ClassifierTree.C") float maxScaleFactor =
+    @LOC("THIS,ClassifierTree.CUR") float maxScaleFactor =
         Math.min(imageData.getWidth() / 100f, imageData.getHeight() / 100f);
     // maxScaleFactor = 1.0f;
 
     // we simply won't recognize faces that are smaller than 40x40 px
-    @LOC("THIS,ClassifierTree.C") float minScaleFactor = 0.5f;
+    @LOC("THIS,ClassifierTree.CUR") float minScaleFactor = 0.5f;
 
-    @LOC("THIS,ClassifierTree.C") float maxScaleDifference =
+    @LOC("THIS,ClassifierTree.CUR") float maxScaleDifference =
         Math.max(Math.abs(maxScaleFactor - startFactor), Math.abs(minScaleFactor - startFactor));
 
     // border for faceYes-possibility must be greater that that
-    @LOC("THIS,ClassifierTree.C") float maxBorder = 0.999f;
+    @LOC("THIS,ClassifierTree.CUR") float maxBorder = 0.999f;
 
-    @LOC("THIS,ClassifierTree.C") int startPosX = (int) lastCoordinates.getX();
-    @LOC("THIS,ClassifierTree.C") int startPosY = (int) lastCoordinates.getX();
+    @LOC("THIS,ClassifierTree.CUR") int startPosX = (int) px;
+    @LOC("THIS,ClassifierTree.CUR") int startPosY = (int) py;
 
-    @LOC("THIS,ClassifierTree.C") int loopidx = 0;
-    TERMINATE: for (@LOC("THIS,ClassifierTree.C") float factorDiff = 0.0f; Math.abs(factorDiff) <= maxScaleDifference; factorDiff =
+    @LOC("THIS,ClassifierTree.CUR") int loopidx = 0;
+    TERMINATE: for (@LOC("THIS,ClassifierTree.CUR") float factorDiff = 0.0f; Math.abs(factorDiff) <= maxScaleDifference; factorDiff =
         (factorDiff + sgn(factorDiff) * 0.1f) * -1 // we alternate between
                                                    // negative and positiv
                                                    // factors
     ) {
 
       if (++loopidx > 1000) {
-        return null;
+        px = -1;
+        py = -1;
+        pwidth = -1;
+        pheight = -1;
+        return;
       }
 
-      @LOC("THIS,ClassifierTree.C") float factor = startFactor + factorDiff;
+      @LOC("THIS,ClassifierTree.CUR") float factor = startFactor + factorDiff;
       if (factor > maxScaleFactor || factor < minScaleFactor)
         continue;
 
       // now we calculate the actualDimmension
-      @LOC("THIS,ClassifierTree.C") int actualDimmension = (int) (100 * factor);
-      @LOC("THIS,ClassifierTree.C") int maxX = imageData.getWidth() - actualDimmension;
-      @LOC("THIS,ClassifierTree.C") int maxY = imageData.getHeight() - actualDimmension;
+      @LOC("THIS,ClassifierTree.CUR") int actualDimmension = (int) (100 * factor);
+      @LOC("THIS,ClassifierTree.CUR") int maxX = imageData.getWidth() - actualDimmension;
+      @LOC("THIS,ClassifierTree.CUR") int maxY = imageData.getHeight() - actualDimmension;
 
-      @LOC("THIS,ClassifierTree.C") int maxDiffX = Math.max(Math.abs(startPosX - maxX), startPosX);
-      @LOC("THIS,ClassifierTree.C") int maxDiffY = Math.max(Math.abs(startPosY - maxY), startPosY);
+      @LOC("THIS,ClassifierTree.CUR") int maxDiffX =
+          Math.max(Math.abs(startPosX - maxX), startPosX);
+      @LOC("THIS,ClassifierTree.CUR") int maxDiffY =
+          Math.max(Math.abs(startPosY - maxY), startPosY);
 
-      @LOC("CXY") int xidx = 0;
-      TERMINATE: for (@LOC("CXY") float xDiff = 0.1f; Math.abs(xDiff) <= maxDiffX; xDiff =
+      @LOC("THIS,ClassifierTree.CUR") int xidx = 0;
+      TERMINATE: for (@LOC("THIS,ClassifierTree.CUR") float xDiff = 0.1f; Math.abs(xDiff) <= maxDiffX; xDiff =
           (xDiff + sgn(xDiff) * 0.5f) * -1) {
 
         if (++xidx > 1000) {
-          return null;
+          px = -1;
+          py = -1;
+          pwidth = -1;
+          pheight = -1;
+          return;
         }
 
-        @LOC("CXY") int xPos = Math.round((float) (startPosX + xDiff));
+        @LOC("THIS,ClassifierTree.CUR") int xPos = Math.round((float) (startPosX + xDiff));
 
         if (xPos < 0 || xPos > maxX)
           continue;
 
-        @LOC("CXY") int yidx = 0;
+        @LOC("THIS,ClassifierTree.CUR") int yidx = 0;
         // yLines:
-        TERMINATE: for (@LOC("CXY") float yDiff = 0.1f; Math.abs(yDiff) <= maxDiffY; yDiff =
+        TERMINATE: for (@LOC("THIS,ClassifierTree.CUR") float yDiff = 0.1f; Math.abs(yDiff) <= maxDiffY; yDiff =
             (yDiff + sgn(yDiff) * 0.5f) * -1) {
 
           if (++yidx > 1000) {
-            return null;
+            px = -1;
+            py = -1;
+            pwidth = -1;
+            pheight = -1;
+            return;
           }
 
-          @LOC("CXY") int yPos = Math.round(startPosY + yDiff);
+          @LOC("THIS,ClassifierTree.CUR") int yPos = Math.round(startPosY + yDiff);
           if (yPos < 0 || yPos > maxY)
             continue;
 
           // by now we should have a valid coordinate to process which we should
           // do now
-          @LOC("CXY") boolean backToYLines = false;
-          for (@LOC("CXY") int idx = 0; idx < classifiers.length; ++idx) {
-            @LOC("CXY") float borderline =
-                0.8f + (idx / (classifiers.length - 1)) * (maxBorder - 0.8f);
+          @LOC("THIS,ClassifierTree.C") boolean backToYLines = false;
+          for (@LOC("THIS,ClassifierTree.CUR") int idx = 0; idx < size; ++idx) {
+            @LOC("THIS,ClassifierTree.CUR") float borderline =
+                0.8f + (idx / (size - 1)) * (maxBorder - 0.8f);
             if (!classifiers[idx].classifyFace(imageData, factor, xPos, yPos, borderline)) {
               backToYLines = true;
               break;
@@ -167,11 +209,12 @@ public class ClassifierTree {
           if (backToYLines) {
             continue;
           }
-          @LOC("OUT") Rectangle2D faceRect =
-              new Rectangle2D(xPos * originalImageFactor, yPos * originalImageFactor,
-                  actualDimmension * originalImageFactor, actualDimmension * originalImageFactor);
 
-          return faceRect;
+          x = xPos * originalImageFactor;
+          y = yPos * originalImageFactor;
+          width = actualDimmension * originalImageFactor;
+          height = actualDimmension * originalImageFactor;
+          return;
 
         }
 
@@ -180,7 +223,7 @@ public class ClassifierTree {
     }
 
     // System.out.println("Time: "+(System.currentTimeMillis()-timeStart)+"ms");
-    return null;
+    // return null;
 
   }
 
@@ -190,4 +233,36 @@ public class ClassifierTree {
     return (value < 0 ? -1 : (value > 0 ? +1 : 1));
   }
 
+  @LATTICE("OUT<P,P<ED,ED<V,V<THIS,THIS<IN,V*,THISLOC=THIS,RETURNLOC=OUT,GLOBALLOC=IN")
+  public FaceAndEyePosition getEyePosition(@LOC("IN") Image image) {
+    if (image == null) {
+      return null;
+    }
+
+    @LOC("IN") float originalImageFactor = 1;
+
+    locateFaceRadial(image);
+
+    if (width > image.getWidth() || height > image.getHeight()) {
+      return null;
+    }
+
+    @LOC("OUT") EyePosition eyePosition = null;
+
+    if (x != -1) {
+      @LOC("ED") EyeDetector ed = new EyeDetector(image, x, y, width, height);
+      @LOC("P") Point point = ed.detectEye();
+      if (point != null) {
+        eyePosition = new EyePosition(point.getX(), point.getY());
+      }
+    }
+
+    System.out.println("eyePosition=" + eyePosition);
+
+    @LOC("OUT") FaceAndEyePosition fep = new FaceAndEyePosition(x, y, width, height, eyePosition);
+
+    return fep;
+  }
+
+
 }
index 88620a4..ffe8cb6 100644 (file)
@@ -35,12 +35,16 @@ class EyeDetector {
   @LOC("IMG")
   double percent;
 
-  public EyeDetector(Image image, Rectangle2D faceRect) {
+  // public EyeDetector(Image image, Rectangle2D faceRect) {
+  public EyeDetector(Image image, double fx, double fy, double fwidth, double fheight) {
 
-    percent = 0.15 * faceRect.getWidth();
+    percent = 0.15 * fwidth;
     Rectangle2D adjustedFaceRect =
-        new Rectangle2D(faceRect.getX() + percent, faceRect.getY() + percent, faceRect.getWidth()
-            - percent, faceRect.getHeight() - 2 * percent);
+        new Rectangle2D(fx + percent, fy + percent, fwidth - percent, fheight - 2 * percent);
+    // percent = 0.15 * faceRect.getWidth();
+    // Rectangle2D adjustedFaceRect =
+    // new Rectangle2D(faceRect.getX() + percent, faceRect.getY() + percent, faceRect.getWidth()
+    // - percent, faceRect.getHeight() - 2 * percent);
 
     width = (int) adjustedFaceRect.getWidth() / 2;
     height = (int) adjustedFaceRect.getHeight() / 2;
index 5b4ffd5..8422220 100644 (file)
@@ -29,17 +29,27 @@ public class EyePosition {
   private int x;
   @LOC("POS")
   private int y;
-  @LOC("POS")
-  private Rectangle2D faceRect;
+  @LOC("POS") private double facex;
+  @LOC("POS") private double facey;
+  @LOC("POS") private double facewidth;
+  @LOC("POS") private double faceheight;
 
-  public EyePosition(Point p, Rectangle2D faceRect) {
-    this(p.x, p.y, faceRect);
-  }
+  // private Rectangle2D faceRect;
+
+  // public EyePosition(Point p, Rectangle2D faceRect) {
+  // this(p.x, p.y, faceRect);
+  // }
+  //
+  // public EyePosition(int x, int y, Rectangle2D faceRect) {
+  // this.x = x;
+  // this.y = y;
+  // this.faceRect = faceRect;
+  // }
 
-  public EyePosition(int x, int y, Rectangle2D faceRect) {
+  public EyePosition(int x, int y) {
     this.x = x;
     this.y = y;
-    this.faceRect = faceRect;
   }
 
   public int getX() {
index 29e0f6e..f184e5a 100644 (file)
@@ -31,8 +31,8 @@ public class FaceAndEyePosition {
   @LOC("POS")
   private EyePosition eyePosition;
 
-  public FaceAndEyePosition(Rectangle2D facePosition, EyePosition eyePosition) {
-    this.facePosition = facePosition;
+  public FaceAndEyePosition(double x, double y, double w, double h, EyePosition eyePosition) {
+    this.facePosition = new Rectangle2D(x, y, w, h);
     this.eyePosition = eyePosition;
   }
 
index c20bc93..3197ac3 100644 (file)
@@ -57,7 +57,7 @@ public class LEA {
   @LOC("IMPL")
   private LEAImplementation implementation;
   @LOC("LAST")
-  private FaceAndEyePosition lastPositions = new FaceAndEyePosition(null, null);
+  private FaceAndEyePosition lastPositions = new FaceAndEyePosition(-1,-1,-1,-1, null);
   @LOC("DEV")
   private DeviationScanner deviationScanner = new DeviationScanner();
 
index cf564ff..bf5c497 100644 (file)
@@ -29,9 +29,6 @@ public class LEAImplementation {
   @LOC("CT")
   private ClassifierTree classifierTree;
 
-  @LOC("R")
-  private Rectangle2D lastRectangle;
-
   public LEAImplementation() {
     this.loadFaceData();
   }
@@ -39,34 +36,7 @@ public class LEAImplementation {
   @LATTICE("OUT<V,V<THIS,THIS<IN,V*,THISLOC=THIS,RETURNLOC=OUT")
   @PCLOC("THIS")
   public FaceAndEyePosition getEyePosition(@LOC("IN") Image image) {
-    if (image == null)
-      return null;
-    @LOC("THIS,LEAImplementation.R") Rectangle2D faceRect =
-        classifierTree.locateFaceRadial(image, lastRectangle);
-    if (faceRect.getWidth() > image.getWidth() || faceRect.getHeight() > image.getHeight()) {
-      return null;
-    }
-    @LOC("V") EyePosition eyePosition = null;
-    if (faceRect != null) {
-      lastRectangle = faceRect;
-      faceRect = null;
-      @LOC("V") Point point = readEyes(image, lastRectangle);
-      if (point != null) {
-        eyePosition = new EyePosition(point, lastRectangle);
-      }
-    } else {
-      lastRectangle = null;
-    }
-    System.out.println("eyePosition=" + eyePosition);
-
-    return new FaceAndEyePosition(lastRectangle, eyePosition);
-  }
-
-  @LATTICE("OUT<P,P<IN,OUT<THIS,THISLOC=THIS,RETURNLOC=OUT")
-  @PCLOC("P")
-  private Point readEyes(@LOC("IN") Image image, @LOC("IN") Rectangle2D rect) {
-    @LOC("OUT") EyeDetector ed = new EyeDetector(image, rect);
-    return ed.detectEye();
+    return classifierTree.getEyePosition(image);
   }
 
   public boolean needsCalibration() {
@@ -74,8 +44,8 @@ public class LEAImplementation {
   }
 
   /**
-   * This method loads the faceData from a file called facedata.dat which should
-   * be within the jar-file
+   * This method loads the faceData from a file called facedata.dat which should be within the
+   * jar-file
    */
   private void loadFaceData() {
 
index edc3f61..2d0d07b 100644 (file)
@@ -16,5 +16,13 @@ public class Point {
   public String toString(){
     return "("+x+","+y+")";
   }
+  
+  public int getX(){
+    return x;
+  }
+  
+  public int getY(){
+    return y;    
+  }
 
 }
index 9fa81d4..b890c40 100644 (file)
@@ -81,19 +81,11 @@ public class Classifier {
     for (int i = 0; i < scanAreas.length; ++i) {
       values[i] = 0l;
 
-      values[i] +=
-          image.getIntegralAt(translationX + scanAreas[i].getToX(scaleFactor), translationY
-              + scanAreas[i].getToY(scaleFactor));
-      values[i] +=
-          image.getIntegralAt(translationX + scanAreas[i].getFromX(scaleFactor), translationY
-              + scanAreas[i].getFromY(scaleFactor));
-
-      values[i] -=
-          image.getIntegralAt(translationX + scanAreas[i].getToX(scaleFactor), translationY
-              + scanAreas[i].getFromY(scaleFactor));
-      values[i] -=
-          image.getIntegralAt(translationX + scanAreas[i].getFromX(scaleFactor), translationY
-              + scanAreas[i].getToY(scaleFactor));
+      values[i] += image.getIntegralAt(translationX + scanAreas[i].getToX(scaleFactor), translationY + scanAreas[i].getToY(scaleFactor));
+      values[i] += image.getIntegralAt(translationX + scanAreas[i].getFromX(scaleFactor), translationY + scanAreas[i].getFromY(scaleFactor));
+
+      values[i] -= image.getIntegralAt(translationX + scanAreas[i].getToX(scaleFactor), translationY + scanAreas[i].getFromY(scaleFactor));
+      values[i] -= image.getIntegralAt(translationX + scanAreas[i].getFromX(scaleFactor), translationY + scanAreas[i].getToY(scaleFactor));
 
       values[i] = (long) (values[i] / ((float) scanAreas[i].getSize(scaleFactor)));
       avg = ((avgItems * avg) + values[i]) / (++avgItems);
index 01c2fe1..dc150e1 100644 (file)
@@ -14,7 +14,10 @@ import SSJava.PCLOC;
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
- * 
+ *   private Point readEyes( Image image,  Rectangle2D rect) {
+  EyeDetector ed = new EyeDetector(image, rect);
+ return ed.detectEye();
+ }
  * You should have received a copy of the GNU Lesser General Public License
  * along with LEA. If not, see <http://www.gnu.org/licenses/>.
  */
@@ -24,18 +27,38 @@ import SSJava.PCLOC;
  * @author Florian
  */
 
-public class ClassifierTree {
 
-  private Classifier classifiers[];
+public class ClassifierTree {
 
-  public ClassifierTree(int size) {
+  
+  private Classifier[] classifiers;
+  
+  double x;
+  
+  double y;
+  
+  double width;
+  
+  double height;
+
+  
+  int size;
+
+  
+  public ClassifierTree( int size) {
+    this.size = size;
     classifiers = new Classifier[size];
+    x = -1;
+    y = -1;
+    width = -1;
+    height = -1;
   }
 
-  public void addClassifier(int idx, Classifier c) {
+  public void addClassifier( int idx,  Classifier c) {
     classifiers[idx] = c;
   }
 
+  
   /**
    * Locates a face by searching radial starting at the last known position. If lastCoordinates are
    * null we simply start in the center of the image.
@@ -49,101 +72,123 @@ public class ClassifierTree {
    * @return an rectangle representing the actual face position on success or null if no face could
    *         be detected
    */
-
-  public Rectangle2D locateFaceRadial(Image smallImage, Rectangle2D lastCoordinates) {
-
-    IntegralImageData imageData = new IntegralImageData(smallImage);
-    float originalImageFactor = 1;
-
-    if (lastCoordinates == null) {
+  
+  public void locateFaceRadial( Image smallImage) {
+
+     double px = x;
+     double py = y;
+     double pwidth = width;
+     double pheight = height;
+
+    x = -1;
+    y = -1;
+    width = -1;
+    height = -1;
+
+     IntegralImageData imageData = new IntegralImageData(smallImage);
+     float originalImageFactor = 1;
+    if (px == -1) {
+      // if(true){
       // if we don't have a last coordinate we just begin in the center
-      int smallImageMaxDimension = Math.min(smallImage.getWidth(), smallImage.getHeight());
-      lastCoordinates =
-          new Rectangle2D((smallImage.getWidth() - smallImageMaxDimension) / 2.0,
-              (smallImage.getHeight() - smallImageMaxDimension) / 2.0, smallImageMaxDimension,
-              smallImageMaxDimension);
-      // System.out.println("lastCoordinates=" + lastCoordinates);
+       int smallImageMaxDimension = Math.min(smallImage.getWidth(), smallImage.getHeight());
+
+      px = (smallImage.getWidth() - smallImageMaxDimension) / 2.0;
+      py = (smallImage.getHeight() - smallImageMaxDimension) / 2.0;
+      pwidth = smallImageMaxDimension;
+      pheight = smallImageMaxDimension;
     } else {
       // first we have to scale the last coodinates back relative to the resized
       // image
-      lastCoordinates =
-          new Rectangle2D((lastCoordinates.getX() * (1 / originalImageFactor)),
-              (lastCoordinates.getY() * (1 / originalImageFactor)),
-              (lastCoordinates.getWidth() * (1 / originalImageFactor)),
-              (lastCoordinates.getHeight() * (1 / originalImageFactor)));
+      px = px * (1 / originalImageFactor);
+      py = py * (1 / originalImageFactor);
+      pwidth = pwidth * (1 / originalImageFactor);
+      pheight = pheight * (1 / originalImageFactor);
     }
 
-    float startFactor = (float) (lastCoordinates.getWidth() / 100.0f);
+
+     float startFactor = (float) (pwidth / 100.0f);
 
     // first we calculate the maximum scale factor for our 200x200 image
-    float maxScaleFactor = Math.min(imageData.getWidth() / 100f, imageData.getHeight() / 100f);
+     float maxScaleFactor = Math.min(imageData.getWidth() / 100f, imageData.getHeight() / 100f);
     // maxScaleFactor = 1.0f;
 
     // we simply won't recognize faces that are smaller than 40x40 px
-    float minScaleFactor = 0.5f;
+     float minScaleFactor = 0.5f;
 
-    float maxScaleDifference = Math.max(Math.abs(maxScaleFactor - startFactor), Math.abs(minScaleFactor - startFactor));
+     float maxScaleDifference = Math.max(Math.abs(maxScaleFactor - startFactor), Math.abs(minScaleFactor - startFactor));
 
     // border for faceYes-possibility must be greater that that
-    float maxBorder = 0.999f;
+     float maxBorder = 0.999f;
 
-    int startPosX = (int) lastCoordinates.getX();
-    int startPosY = (int) lastCoordinates.getX();
+     int startPosX = (int) px;
+     int startPosY = (int) py;
 
-    int loopidx = 0;
-    TERMINATE: for (float factorDiff = 0.0f; Math.abs(factorDiff) <= maxScaleDifference; factorDiff =
+     int loopidx = 0;
+    TERMINATE: for ( float factorDiff = 0.0f; Math.abs(factorDiff) <= maxScaleDifference; factorDiff =
         (factorDiff + sgn(factorDiff) * 0.1f) * -1 // we alternate between
                                                    // negative and positiv
                                                    // factors
     ) {
 
       if (++loopidx > 1000) {
-        return null;
+        px = -1;
+        py = -1;
+        pwidth = -1;
+        pheight = -1;
+        return;
       }
 
-      float factor = startFactor + factorDiff;
+       float factor = startFactor + factorDiff;
       if (factor > maxScaleFactor || factor < minScaleFactor)
         continue;
 
       // now we calculate the actualDimmension
-      int actualDimmension = (int) (100 * factor);
-      int maxX = imageData.getWidth() - actualDimmension;
-      int maxY = imageData.getHeight() - actualDimmension;
+       int actualDimmension = (int) (100 * factor);
+       int maxX = imageData.getWidth() - actualDimmension;
+       int maxY = imageData.getHeight() - actualDimmension;
 
-      int maxDiffX = Math.max(Math.abs(startPosX - maxX), startPosX);
-      int maxDiffY = Math.max(Math.abs(startPosY - maxY), startPosY);
+       int maxDiffX = Math.max(Math.abs(startPosX - maxX), startPosX);
+       int maxDiffY = Math.max(Math.abs(startPosY - maxY), startPosY);
 
-      int xidx = 0;
-      TERMINATE: for (float xDiff = 0.1f; Math.abs(xDiff) <= maxDiffX; xDiff =
+       int xidx = 0;
+      TERMINATE: for ( float xDiff = 0.1f; Math.abs(xDiff) <= maxDiffX; xDiff =
           (xDiff + sgn(xDiff) * 0.5f) * -1) {
 
         if (++xidx > 1000) {
-          return null;
+          px = -1;
+          py = -1;
+          pwidth = -1;
+          pheight = -1;
+          return;
         }
 
-        int xPos = Math.round((float) (startPosX + xDiff));
+         int xPos = Math.round((float) (startPosX + xDiff));
 
         if (xPos < 0 || xPos > maxX)
           continue;
 
-        int yidx = 0;
+         int yidx = 0;
         // yLines:
-        TERMINATE: for (float yDiff = 0.1f; Math.abs(yDiff) <= maxDiffY; yDiff =
+        TERMINATE: for ( float yDiff = 0.1f; Math.abs(yDiff) <= maxDiffY; yDiff =
             (yDiff + sgn(yDiff) * 0.5f) * -1) {
 
           if (++yidx > 1000) {
-            return null;
+            px = -1;
+            py = -1;
+            pwidth = -1;
+            pheight = -1;
+            return;
           }
 
-          int yPos = Math.round(startPosY + yDiff);
+           int yPos = Math.round(startPosY + yDiff);
           if (yPos < 0 || yPos > maxY)
             continue;
 
           // by now we should have a valid coordinate to process which we should
           // do now
-          boolean backToYLines = false;
-          for (int idx = 0; idx < classifiers.length; ++idx) {
-            float borderline = 0.8f + (idx / (classifiers.length - 1)) * (maxBorder - 0.8f);
+           boolean backToYLines = false;
+          for ( int idx = 0; idx < size; ++idx) {
+             float borderline = 0.8f + (idx / (size - 1)) * (maxBorder - 0.8f);
             if (!classifiers[idx].classifyFace(imageData, factor, xPos, yPos, borderline)) {
               backToYLines = true;
               break;
@@ -159,9 +204,11 @@ public class ClassifierTree {
             continue;
           }
 
-          Rectangle2D faceRect = new Rectangle2D(xPos * originalImageFactor, yPos * originalImageFactor, actualDimmension * originalImageFactor, actualDimmension * originalImageFactor);
-
-          return faceRect;
+          x = xPos * originalImageFactor;
+          y = yPos * originalImageFactor;
+          width = actualDimmension * originalImageFactor;
+          height = actualDimmension * originalImageFactor;
+          return;
 
         }
 
@@ -169,13 +216,46 @@ public class ClassifierTree {
 
     }
 
-    // System.out.println("Time: "+(System.currentTimeMillis()-timeStart)+"ms");
-    return null;
 
   }
 
-  private static int sgn(float value) {
+  
+  
+  private static int sgn( float value) {
     return (value < 0 ? -1 : (value > 0 ? +1 : 1));
   }
 
+  
+  public FaceAndEyePosition getEyePosition( Image image) {
+    if (image == null) {
+      return null;
+    }
+
+     float originalImageFactor = 1;
+
+    locateFaceRadial(image);
+
+    if (width > image.getWidth() || height > image.getHeight()) {
+      return null;
+    }
+
+     EyePosition eyePosition = null;
+
+    if (x != -1) {
+       EyeDetector ed = new EyeDetector(image, x, y, width, height);
+       Point point = ed.detectEye();
+      if (point != null) {
+        eyePosition = new EyePosition(point.getX(), point.getY());
+      }
+    }
+
+    System.out.println("eyePosition=" + eyePosition);
+
+     FaceAndEyePosition fep = new FaceAndEyePosition(x, y, width, height, eyePosition);
+
+
+    return fep;
+  }
+
+
 }
index 6da3f7e..4cc353e 100644 (file)
  * @author Florian Frankenberger\r
  */\r
 \r
+\r
 public class DeviationScanner {\r
 \r
+  \r
   private EyePosition eyePositions[];\r
 \r
   // LEFT_UP(+1, -1), UP(0, -1), RIGHT_UP(-1, -1), LEFT(+1, 0), NONE(0, 0),\r
@@ -45,7 +47,8 @@ public class DeviationScanner {
     eyePositions = new EyePosition[3];\r
   }\r
 \r
-  public void addEyePosition(EyePosition eyePosition) {\r
+  \r
+  public void addEyePosition( EyePosition eyePosition) {\r
 \r
     // for ( int i = 1; i < 3; i++) {\r
     // eyePositions[i - 1] = eyePositions[i];\r
@@ -57,23 +60,24 @@ public class DeviationScanner {
 \r
   }\r
 \r
-  //\r
-\r
-  public int scanForDeviation(Rectangle2D faceRect) {\r
+  // \r
+  \r
+  \r
+  public int scanForDeviation( Rectangle2D faceRect) {\r
 \r
-    int deviation = NONE;\r
+     int deviation = NONE;\r
 \r
-    for (int i = 0; i < 3; i++) {\r
+    for ( int i = 0; i < 3; i++) {\r
       if (eyePositions[i] == null) {\r
         return deviation;\r
       }\r
     }\r
 \r
-    double deviationX = 0;\r
-    double deviationY = 0;\r
+     double deviationX = 0;\r
+     double deviationY = 0;\r
 \r
-    int lastIdx = -1;\r
-    for (int i = 0; i < 3; ++i) {\r
+     int lastIdx = -1;\r
+    for ( int i = 0; i < 3; ++i) {\r
       if (lastIdx != -1) {\r
         deviationX += (eyePositions[i].getX() - eyePositions[lastIdx].getX());\r
         deviationY += (eyePositions[i].getY() - eyePositions[lastIdx].getY());\r
@@ -81,14 +85,14 @@ public class DeviationScanner {
       lastIdx = i;\r
     }\r
 \r
-    final double deviationPercentX = 0.04;\r
-    final double deviationPercentY = 0.04;\r
+     final double deviationPercentX = 0.04;\r
+     final double deviationPercentY = 0.04;\r
 \r
     deviationX /= faceRect.getWidth();\r
     deviationY /= faceRect.getWidth();\r
 \r
-    int deviationAbsoluteX = 0;\r
-    int deviationAbsoluteY = 0;\r
+     int deviationAbsoluteX = 0;\r
+     int deviationAbsoluteY = 0;\r
     if (deviationX > deviationPercentX)\r
       deviationAbsoluteX = 1;\r
     if (deviationX < -deviationPercentX)\r
@@ -110,7 +114,8 @@ public class DeviationScanner {
     return deviation;\r
   }\r
 \r
-  public int getDirectionFor(int directionX, int directionY) {\r
+  \r
+  public int getDirectionFor( int directionX,  int directionY) {\r
 \r
     if (directionX == +1 && directionY == -1) {\r
       return LEFT_UP;\r
@@ -140,7 +145,7 @@ public class DeviationScanner {
     eyePositions = new EyePosition[3];\r
   }\r
 \r
-  public String toStringDeviation(int dev) {\r
+  public String toStringDeviation( int dev) {\r
     if (dev == LEFT_UP) {\r
       return "LEFT_UP";\r
     } else if (dev == UP) {\r
index e035b65..699a620 100644 (file)
@@ -15,44 +15,38 @@ import de.darkblue.lea.ifaces.ICaptureDevice;
  */\r
 public class DummyCaptureDevice implements ICaptureDevice {\r
 \r
-  /**\r
+       /**\r
         * \r
         */\r
-  public DummyCaptureDevice() {\r
-    // TODO Auto-generated constructor stub\r
-  }\r
-\r
-  /*\r
-   * (non-Javadoc)\r
-   * \r
-   * @see de.darkblue.lea.ifaces.ICaptureDevice#close()\r
-   */\r
-  @Override\r
-  public void close() {\r
-  }\r
-\r
-  /*\r
-   * (non-Javadoc)\r
-   * \r
-   * @see de.darkblue.lea.ifaces.ICaptureDevice#getFrameRate()\r
-   */\r
-  @Override\r
-  public int getFrameRate() {\r
-    return 15;\r
-  }\r
-\r
-  /*\r
-   * (non-Javadoc)\r
-   * \r
-   * @see de.darkblue.lea.ifaces.ICaptureDevice#getImage()\r
-   */\r
-  @Override\r
-  public BufferedImage getImage() {\r
-    BufferedImage image = new BufferedImage(640, 480, BufferedImage.TYPE_INT_RGB);\r
-    Graphics2D g2d = (Graphics2D) image.getGraphics();\r
-    g2d.setColor(new Color(255, 255, 255));\r
-    g2d.fillRect(0, 0, 639, 479);\r
-    return image;\r
-  }\r
+       public DummyCaptureDevice() {\r
+               // TODO Auto-generated constructor stub\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see de.darkblue.lea.ifaces.ICaptureDevice#close()\r
+        */\r
+       @Override\r
+       public void close() {\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see de.darkblue.lea.ifaces.ICaptureDevice#getFrameRate()\r
+        */\r
+       @Override\r
+       public int getFrameRate() {\r
+               return 15;\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see de.darkblue.lea.ifaces.ICaptureDevice#getImage()\r
+        */\r
+       @Override\r
+       public BufferedImage getImage() {\r
+               BufferedImage image = new BufferedImage(640, 480, BufferedImage.TYPE_INT_RGB);\r
+               Graphics2D g2d = (Graphics2D)image.getGraphics();\r
+               g2d.setColor(new Color(255, 255, 255));\r
+               g2d.fillRect(0, 0, 639, 479);\r
+               return image;\r
+       }\r
 \r
 }\r
index d162bc0..6e21f39 100644 (file)
  * @author Florian Frankenberger
  */
 
+
 class EyeDetector {
 
+  
   private int width;
-
+  
   private int height;
-
+  
   private int[] pixelBuffer;
-
+  
   double percent;
 
-  public EyeDetector(Image image, Rectangle2D faceRect) {
+  // public EyeDetector(Image image, Rectangle2D faceRect) {
+  public EyeDetector(Image image, double fx, double fy, double fwidth, double fheight) {
 
-    percent = 0.15 * faceRect.getWidth();
-    Rectangle2D adjustedFaceRect =
-        new Rectangle2D(faceRect.getX() + percent, faceRect.getY() + percent, faceRect.getWidth()
-            - percent, faceRect.getHeight() - 2 * percent);
+    percent = 0.15 * fwidth;
+    Rectangle2D adjustedFaceRect = new Rectangle2D(fx + percent, fy + percent, fwidth - percent, fheight - 2 * percent);
+    // percent = 0.15 * faceRect.getWidth();
+    // Rectangle2D adjustedFaceRect =
+    // new Rectangle2D(faceRect.getX() + percent, faceRect.getY() + percent, faceRect.getWidth()
+    // - percent, faceRect.getHeight() - 2 * percent);
 
     width = (int) adjustedFaceRect.getWidth() / 2;
     height = (int) adjustedFaceRect.getHeight() / 2;
@@ -55,15 +60,16 @@ class EyeDetector {
 
   }
 
+  
   public Point detectEye() {
-    Point eyePosition = null;
-    float brightness = 255f;
-    for (int y = 0; y < height; ++y) {
-      for (int x = 0; x < width; ++x) {
-        int position = y * width + x;
-        int[] color = new int[] { (pixelBuffer[position] & 0xFF0000) >> 16, (pixelBuffer[position] & 0x00FF00) >> 8, pixelBuffer[position] & 0x0000FF };
+     Point eyePosition = null;
+     float brightness = 255f;
+    for ( int y = 0; y < height; ++y) {
+      for ( int x = 0; x < width; ++x) {
+         int position = y * width + x;
+         int[] color =  new int[] { (pixelBuffer[position] & 0xFF0000) >> 16,(pixelBuffer[position] & 0x00FF00) >> 8, pixelBuffer[position] & 0x0000FF };
         // System.out.println("("+x+","+y+")="+color[0]+" "+color[1]+" "+color[2]);
-        float acBrightness = getBrightness(color);
+         final float acBrightness = getBrightness(color);
 
         if (acBrightness < brightness) {
           eyePosition = new Point(x + (int) percent, y + (int) percent);
@@ -75,9 +81,10 @@ class EyeDetector {
     return eyePosition;
   }
 
-  private static float getBrightness(int[] color) {
-    int min = Math.min(Math.min(color[0], color[1]), color[2]);
-    int max = Math.max(Math.max(color[0], color[1]), color[2]);
+  
+  private static float getBrightness( int[] color) {
+     int min = Math.min(Math.min(color[0], color[1]), color[2]);
+     int max = Math.max(Math.max(color[0], color[1]), color[2]);
 
     return 0.5f * (max + min);
   }
index be45cee..a599a3c 100644 (file)
  * @author Florian Frankenberger
  */
 
-public class EyePosition {
 
+public class EyePosition {
+  
   private int x;
-
+  
   private int y;
+   private double facex;
+   private double facey;
+   private double facewidth;
+   private double faceheight;
 
-  private Rectangle2D faceRect;
+  // private Rectangle2D faceRect;
 
-  public EyePosition(Point p, Rectangle2D faceRect) {
-    this(p.x, p.y, faceRect);
-  }
+  // public EyePosition(Point p, Rectangle2D faceRect) {
+  // this(p.x, p.y, faceRect);
+  // }
+  //
+  // public EyePosition(int x, int y, Rectangle2D faceRect) {
+  // this.x = x;
+  // this.y = y;
+  // this.faceRect = faceRect;
+  // }
 
-  public EyePosition(int x, int y, Rectangle2D faceRect) {
+  public EyePosition(int x, int y) {
     this.x = x;
     this.y = y;
-    this.faceRect = faceRect;
   }
 
   public int getX() {
index e1d9450..3dce544 100644 (file)
  * @author Florian Frankenberger
  */
 
+
 public class FaceAndEyePosition {
 
+  
   private Rectangle2D facePosition;
-
+  
   private EyePosition eyePosition;
 
-  public FaceAndEyePosition(Rectangle2D facePosition, EyePosition eyePosition) {
-    this.facePosition = facePosition;
+  public FaceAndEyePosition(double x, double y, double w, double h, EyePosition eyePosition) {
+    this.facePosition = new Rectangle2D(x, y, w, h);
     this.eyePosition = eyePosition;
   }
 
index 2caa04a..f050a97 100644 (file)
  * along with LEA. If not, see <http://www.gnu.org/licenses/>.\r
  */\r
 \r
+\r
 import java.awt.image.BufferedImage;\r
 \r
 /**\r
- * Describes a capture device. For now it is only tested with images in <code>640x480</code> at\r
- * <code>RGB</code> or <code>YUV</code> color space.\r
+ * Describes a capture device. For now it is only tested\r
+ * with images in <code>640x480</code> at <code>RGB</code> or <code>YUV</code> color space.\r
  * \r
  * @author Florian Frankenberger\r
  */\r
 public interface ICaptureDevice {\r
 \r
-  /**\r
-   * Returns the frame rate of the image source per second\r
-   * \r
-   * @return the frame rate (e.g. 15 = 15 frames per second)\r
-   */\r
-  public int getFrameRate();\r
-\r
-  /**\r
-   * Will be called a maximum of getFrameRate()-times in a second and returns the actual image of\r
-   * the capture device\r
-   * \r
-   * @return the actual image of the capture device\r
-   */\r
-  public BufferedImage getImage();\r
-\r
-  /**\r
-   * LEA calls this when it cleans up. You should put your own cleanup code in here.\r
-   */\r
-  public void close();\r
+       /**\r
+        * Returns the frame rate of the image source per second\r
+        * \r
+        * @return the frame rate (e.g. 15 = 15 frames per second)\r
+        */\r
+       public int getFrameRate();\r
 \r
+       /**\r
+        * Will be called a maximum of getFrameRate()-times in a second and returns\r
+        * the actual image of the capture device\r
+        *  \r
+        * @return the actual image of the capture device \r
+        */\r
+       public BufferedImage getImage();\r
+       \r
+       /**\r
+        * LEA calls this when it cleans up. You should put your own cleanup code in here.\r
+        */\r
+       public void close();\r
+       \r
+       \r
 }\r
index 5245320..d91a7e4 100644 (file)
@@ -1,10 +1,12 @@
 
+
 public class Image {
 
+  
   int width;
-
+  
   int height;
-
+  
   int pixel[][];
 
   public Image(int width, int height) {
index 80d7782..d517a37 100644 (file)
  * @author Florian Frankenberger
  */
 
+
 public class IntegralImageData {
 
+  
   private long[][] integral;
-
+  
   private int width;
-
+  
   private int hegith;
 
   // private Dimension dimension;
@@ -49,7 +51,7 @@ public class IntegralImageData {
 
   }
 
-  public long getIntegralAt(int x, int y) {
+  public long getIntegralAt( int x,  int y) {
     return this.integral[x][y];
   }
 
@@ -61,8 +63,4 @@ public class IntegralImageData {
     return hegith;
   }
 
-  public String toString() {
-    super.toString();
-  }
-
 }
index b3fda52..40479eb 100644 (file)
 /**
  * This is the main class of LEA.
  * <p>
- * It uses a face detection algorithm to find an a face within the provided image(s). Then it
- * searches for the eye in a region where it most likely located and traces its position relative to
- * the face and to the last known position. The movements are estimated by comparing more than one
- * movement. If a movement is distinctly pointing to a direction it is recognized and all listeners
- * get notified.
+ * It uses a face detection algorithm to find an a face within the provided
+ * image(s). Then it searches for the eye in a region where it most likely
+ * located and traces its position relative to the face and to the last known
+ * position. The movements are estimated by comparing more than one movement. If
+ * a movement is distinctly pointing to a direction it is recognized and all
+ * listeners get notified.
  * <p>
  * The notification is designed as observer pattern. You simply call
- * <code>addEyeMovementListener(IEyeMovementListener)</code> to add an implementation of
- * <code>IEyeMovementListener</code> to LEA. When a face is recognized/lost or whenever an eye
- * movement is detected LEA will call the appropriate methods of the listener
+ * <code>addEyeMovementListener(IEyeMovementListener)</code> to add an
+ * implementation of <code>IEyeMovementListener</code> to LEA. When a face is
+ * recognized/lost or whenever an eye movement is detected LEA will call the
+ * appropriate methods of the listener
  * <p>
- * LEA also needs an image source implementing the <code>ICaptureDevice</code>. One image source
- * proxy to the <code>Java Media Framework</code> is included ( <code>JMFCaptureDevice</code>).
+ * LEA also needs an image source implementing the <code>ICaptureDevice</code>.
+ * One image source proxy to the <code>Java Media Framework</code> is included (
+ * <code>JMFCaptureDevice</code>).
  * <p>
  * Example (for using LEA with <code>Java Media Framework</code>):
  * <p>
  * LEA lea = new LEA(new JMFCaptureDevice(), true);
  * </code>
  * <p>
- * This will start LEA with the first available JMF datasource with an extra status window showing
- * if face/eye has been detected successfully. Please note that face detection needs about 2 seconds
- * to find a face. After detection the following face detection is much faster.
+ * This will start LEA with the first available JMF datasource with an extra
+ * status window showing if face/eye has been detected successfully. Please note
+ * that face detection needs about 2 seconds to find a face. After detection the
+ * following face detection is much faster.
  * 
  * @author Florian Frankenberger
  */
 
+
 public class LEA {
 
+  
   private LEAImplementation implementation;
-
-  private FaceAndEyePosition lastPositions = new FaceAndEyePosition(null, null);
-
+  
+  private FaceAndEyePosition lastPositions = new FaceAndEyePosition(-1,-1,-1,-1, null);
+  
   private DeviationScanner deviationScanner = new DeviationScanner();
 
   public LEA() {
@@ -62,17 +68,18 @@ public class LEA {
   }
 
   /**
-   * Clears the internal movement buffer. If you just capture some of the eye movements you should
-   * call this every time you start recording the movements. Otherwise you may get notified for
-   * movements that took place BEFORE you started recording.
+   * Clears the internal movement buffer. If you just capture some of the eye
+   * movements you should call this every time you start recording the
+   * movements. Otherwise you may get notified for movements that took place
+   * BEFORE you started recording.
    */
   public void clear() {
     // this.imageProcessor.clearDeviationScanner();
   }
 
   /**
-   * @METHOD To test LEA with the first capture device from the <code>Java Media Framework</code>
-   *         just start from here.
+   * @METHOD To test LEA with the first capture device from the
+   *         <code>Java Media Framework</code> just start from here.
    * 
    * @param args
    * @throws Exception
@@ -82,12 +89,13 @@ public class LEA {
     lea.doRun();
   }
 
+  
   public void doRun() {
 
-    int i = 0;
+     int i = 0;
 
     SSJAVA: while (true) {
-      Image image = ImageReader.getImage();
+       Image image =  ImageReader.getImage();
       if (image == null) {
         break;
       }
@@ -97,12 +105,13 @@ public class LEA {
     System.out.println("Done.");
 
   }
+  
 
-  private void processImage(Image image) {
-    FaceAndEyePosition positions = implementation.getEyePosition(image);
+  private void processImage( Image image) {
+     FaceAndEyePosition positions = implementation.getEyePosition(image);
     // if (positions.getEyePosition() != null) {
     deviationScanner.addEyePosition(positions.getEyePosition());
-    int deviation = deviationScanner.scanForDeviation(positions.getFacePosition());// positions.getEyePosition().getDeviation(lastPositions.getEyePosition());
+     int deviation = deviationScanner.scanForDeviation(positions.getFacePosition());// positions.getEyePosition().getDeviation(lastPositions.getEyePosition());
     if (deviation != DeviationScanner.NONE) {
       System.out.println("deviation=" + deviationScanner.toStringDeviation(deviation));
       // notifyEyeMovementListenerEyeMoved(deviation);
index b9dc7d3..3c2449c 100644 (file)
  * @author Florian Frankenberger
  */
 
+
 public class LEAImplementation {
 
+  
   private ClassifierTree classifierTree;
 
-  private Rectangle2D lastRectangle;
 
   public LEAImplementation() {
     this.loadFaceData();
   }
 
-  public FaceAndEyePosition getEyePosition(Image image) {
-    if (image == null)
-      return null;
-    Rectangle2D faceRect = classifierTree.locateFaceRadial(image, lastRectangle);
-    if (faceRect.getWidth() > image.getWidth() || faceRect.getHeight() > image.getHeight()) {
-      return null;
-    }
-    EyePosition eyePosition = null;
-    if (faceRect != null) {
-      lastRectangle = faceRect;
-      faceRect = null;
-      Point point = readEyes(image, lastRectangle);
-      if (point != null) {
-        eyePosition = new EyePosition(point, lastRectangle);
-      }
-    } else {
-      lastRectangle = null;
-    }
-    System.out.println("eyePosition=" + eyePosition);
-
-    return new FaceAndEyePosition(lastRectangle, eyePosition);
-  }
-
-  private Point readEyes(Image image, Rectangle2D rect) {
-    EyeDetector ed = new EyeDetector(image, rect);
-    return ed.detectEye();
+  
+  
+  public FaceAndEyePosition getEyePosition( Image image) {
+    return classifierTree.getEyePosition(image);
   }
 
   public boolean needsCalibration() {
index a3b6c37..044f37e 100644 (file)
@@ -1,7 +1,9 @@
+
+
 public class Point {
 
-  public int x;
-  public int y;
+   public int x;
+   public int y;
 
   public Point(int x, int y) {
     this.x = x;
@@ -10,9 +12,17 @@ public class Point {
 
   public Point() {
   }
-
-  public String toString() {
-    return "(" + x + "," + y + ")";
+  
+  public String toString(){
+    return "("+x+","+y+")";
+  }
+  
+  public int getX(){
+    return x;
+  }
+  
+  public int getY(){
+    return y;    
   }
 
 }
index ae53816..e765e70 100644 (file)
@@ -1,9 +1,11 @@
+
+
 public class Rectangle2D {
 
-  double x;
-  double y;
-  double width;
-  double height;
+   double x;
+   double y;
+   double width;
+   double height;
 
   public Rectangle2D(double x, double y, double w, double h) {
     this.x = x;
index 62e9b4a..abb581b 100644 (file)
  * @author Florian
  */
 
+
 public class ScanArea {
 
+  
   private Point fromPoint;
-
+  
   private Point toPoint;
-
+  
   private float size;
 
   /**
-   * Imagine you want to classify an image with 100px x 100px what would be the scanarea in this
-   * kind of image. That size gets automatically scalled to fit bigger images
+   * Imagine you want to classify an image with 100px x 100px what would be the
+   * scanarea in this kind of image. That size gets automatically scalled to fit
+   * bigger images
    * 
    * @param fromPoint
    * @param toPoint
@@ -54,23 +57,23 @@ public class ScanArea {
     this(new Point(fromX, fromY), new Point(fromX + width, fromY + height));
   }
 
-  public int getFromX(float scaleFactor) {
+  public int getFromX( float scaleFactor) {
     return (int) (this.fromPoint.x * scaleFactor);
   }
 
-  public int getFromY(float scaleFactor) {
+  public int getFromY( float scaleFactor) {
     return (int) (this.fromPoint.y * scaleFactor);
   }
 
-  public int getToX(float scaleFactor) {
+  public int getToX( float scaleFactor) {
     return (int) (this.toPoint.x * scaleFactor);
   }
 
-  public int getToY(float scaleFactor) {
+  public int getToY( float scaleFactor) {
     return (int) (this.toPoint.y * scaleFactor);
   }
 
-  public int getSize(float scaleFactor) {
+  public int getSize( float scaleFactor) {
     return (int) (this.size * Math.pow(scaleFactor, 2));
   }
 
@@ -107,7 +110,7 @@ public class ScanArea {
   // }
 
   public String toString() {
-    String str = "";
+     String str = "";
     str += "fromPoint=(" + fromPoint.x + "," + fromPoint.y + ")";
     str += "toPoint=(" + toPoint.x + "," + toPoint.y + ")";
     str += "size=" + size;