<commit_before>//===- tools/lld/lld-core.cpp - Linker Core Test Driver -----------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lld/Core/InputFiles.h"
#include "lld/Core/Atom.h"
#include "lld/Core/DefinedAtom.h"
#include "lld/Core/UndefinedAtom.h"
#include "lld/Core/Pass.h"
#include "lld/Core/Resolver.h"
#include "lld/Core/YamlReader.h"
#include "lld/Core/YamlWriter.h"
#include "lld/Core/NativeReader.h"
#include "lld/Core/NativeWriter.h"
#include "lld/Core/Platform.h"

#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/system_error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"

#include <vector>

using namespace lld;

static void error(llvm::Twine message) {
  llvm::errs() << "lld-core: " << message << ".\n";
}

static bool error(llvm::error_code ec) {
  if (ec) {
    error(ec.message());
    return true;
  }
  return false;
}

namespace {

//
// Simple atom created by the stubs pass.
//
class TestingStubAtom : public DefinedAtom {
public:
        TestingStubAtom(const File& f, const Atom& shlib) :
                        _file(f), _shlib(shlib) {
          static uint32_t lastOrdinal = 0;
          _ordinal = lastOrdinal++;
        }

  virtual const File& file() const {
    return _file;
  }

  virtual llvm::StringRef name() const {
    return llvm::StringRef();
  }

  virtual uint64_t ordinal() const {
    return _ordinal;
  }

  virtual uint64_t size() const {
    return 0;
  }

  virtual Scope scope() const {
    return DefinedAtom::scopeLinkageUnit;
  }

  virtual Interposable interposable() const {
    return DefinedAtom::interposeNo;
  }

  virtual Merge merge() const {
    return DefinedAtom::mergeNo;
  }

  virtual ContentType contentType() const  {
    return DefinedAtom::typeStub;
  }

  virtual Alignment alignment() const {
    return Alignment(0,0);
  }

  virtual SectionChoice sectionChoice() const {
    return DefinedAtom::sectionBasedOnContent;
  }

  virtual llvm::StringRef customSectionName() const {
    return llvm::StringRef();
  }
  virtual DeadStripKind deadStrip() const {
    return DefinedAtom::deadStripNormal;
  }

  virtual ContentPermissions permissions() const  {
    return DefinedAtom::permR_X;
  }

  virtual bool isThumb() const {
    return false;
  }

  virtual bool isAlias() const {
    return false;
  }

  virtual llvm::ArrayRef<uint8_t> rawContent() const {
    return llvm::ArrayRef<uint8_t>();
  }

  virtual reference_iterator referencesBegin() const {
    return reference_iterator(*this, NULL);
  }

  virtual reference_iterator referencesEnd() const {
    return reference_iterator(*this, NULL);
  }

  virtual const Reference* derefIterator(const void* iter) const {
    return NULL;
  }

  virtual void incrementIterator(const void*& iter) const {

  }

private:
  const File&               _file;
  const Atom&               _shlib;
  uint32_t                  _ordinal;
};

//
// Simple atom created by the GOT pass.
//
class TestingGOTAtom : public DefinedAtom {
public:
        TestingGOTAtom(const File& f, const Atom& shlib) :
                        _file(f), _shlib(shlib) {
          static uint32_t lastOrdinal = 0;
          _ordinal = lastOrdinal++;
        }

  virtual const File& file() const {
    return _file;
  }

  virtual llvm::StringRef name() const {
    return llvm::StringRef();
  }

  virtual uint64_t ordinal() const {
    return _ordinal;
  }

  virtual uint64_t size() const {
    return 0;
  }

  virtual Scope scope() const {
    return DefinedAtom::scopeLinkageUnit;
  }

  virtual Interposable interposable() const {
    return DefinedAtom::interposeNo;
  }

  virtual Merge merge() const {
    return DefinedAtom::mergeNo;
  }

  virtual ContentType contentType() const  {
    return DefinedAtom::typeGOT;
  }

  virtual Alignment alignment() const {
    return Alignment(3,0);
  }

  virtual SectionChoice sectionChoice() const {
    return DefinedAtom::sectionBasedOnContent;
  }

  virtual llvm::StringRef customSectionName() const {
    return llvm::StringRef();
  }
  virtual DeadStripKind deadStrip() const {
    return DefinedAtom::deadStripNormal;
  }

  virtual ContentPermissions permissions() const  {
    return DefinedAtom::permRW_;
  }

  virtual bool isThumb() const {
    return false;
  }

  virtual bool isAlias() const {
    return false;
  }

  virtual llvm::ArrayRef<uint8_t> rawContent() const {
    return llvm::ArrayRef<uint8_t>();
  }

  virtual reference_iterator referencesBegin() const {
    return reference_iterator(*this, NULL);
  }

  virtual reference_iterator referencesEnd() const {
    return reference_iterator(*this, NULL);
  }

  virtual const Reference* derefIterator(const void* iter) const {
    return NULL;
  }

  virtual void incrementIterator(const void*& iter) const {

  }

private:
  const File&               _file;
  const Atom&               _shlib;
  uint32_t                  _ordinal;
};

//
// A simple platform for testing.
//
class TestingPlatform : public Platform {
public:

  virtual void initialize() { }

  // tell platform object another file has been added
  virtual void fileAdded(const File &file) { }

  // tell platform object another atom has been added
  virtual void atomAdded(const Atom &file) { }

  // give platform a chance to change each atom's scope
  virtual void adjustScope(const DefinedAtom &atom) { }

  // if specified atom needs alternate names, return AliasAtom(s)
  virtual bool getAliasAtoms(const Atom &atom,
                             std::vector<const DefinedAtom *>&) {
    return false;
  }

  // give platform a chance to resolve platform-specific undefs
  virtual bool getPlatformAtoms(llvm::StringRef undefined,
                                std::vector<const DefinedAtom *>&) {
    return false;
  }

  // resolver should remove unreferenced atoms
  virtual bool deadCodeStripping() {
    return false;
  }

  // atom must be kept so should be root of dead-strip graph
  virtual bool isDeadStripRoot(const Atom &atom) {
    return false;
  }

  // if target must have some atoms, denote here
  virtual bool getImplicitDeadStripRoots(std::vector<const DefinedAtom *>&) {
    return false;
  }

  // return entry point for output file (e.g. "main") or NULL
  virtual llvm::StringRef entryPointName() {
    return NULL;
  }

  // for iterating must-be-defined symbols ("main" or -u command line option)
  typedef llvm::StringRef const *UndefinesIterator;
  virtual UndefinesIterator initialUndefinesBegin() const {
    return NULL;
  }
  virtual UndefinesIterator initialUndefinesEnd() const {
    return NULL;
  }

  // if platform wants resolvers to search libraries for overrides
  virtual bool searchArchivesToOverrideTentativeDefinitions() {
    return false;
  }

  virtual bool searchSharedLibrariesToOverrideTentativeDefinitions() {
    return false;
  }

  // if platform allows symbol to remain undefined (e.g. -r)
  virtual bool allowUndefinedSymbol(llvm::StringRef name) {
    return true;
  }

  // for debugging dead code stripping, -why_live
  virtual bool printWhyLive(llvm::StringRef name) {
    return false;
  }

  virtual const Atom& handleMultipleDefinitions(const Atom& def1,
                                                const Atom& def2) {
    llvm::report_fatal_error("symbol '"
                            + llvm::Twine(def1.name())
                            + "' multiply defined");
  }

  // print out undefined symbol error messages in platform specific way
  virtual void errorWithUndefines(const std::vector<const Atom *> &undefs,
                                  const std::vector<const Atom *> &all) {}

  // print out undefined can-be-null mismatches
  virtual void undefineCanBeNullMismatch(const UndefinedAtom& undef1,
                                         const UndefinedAtom& undef2,
                                         bool& useUndef2) { }

  // print out shared library mismatches
  virtual void sharedLibrarylMismatch(const SharedLibraryAtom& shLib1,
                                      const SharedLibraryAtom& shLib2,
                                      bool& useShlib2) { }

  // last chance for platform to tweak atoms
  virtual void postResolveTweaks(std::vector<const Atom *> &all) {}

  struct KindMapping {
    const char*           string;
    Reference::Kind       value;
    bool                  isBranch;
    bool                  isGotLoad;
    bool                  isGotUse;
  };

  static const KindMapping _s_kindMappings[];

  virtual Reference::Kind kindFromString(llvm::StringRef kindName) {
    for (const KindMapping* p = _s_kindMappings; p->string != NULL; ++p) {
      if ( kindName.equals(p->string) )
        return p->value;
    }
    int k;
    if (kindName.getAsInteger(0, k))
      k = 0;
    return k;
  }

  virtual llvm::StringRef kindToString(Reference::Kind value) {
    for (const KindMapping* p = _s_kindMappings; p->string != NULL; ++p) {
      if ( value == p->value)
        return p->string;
    }
    return llvm::StringRef("???");
  }

  virtual bool noTextRelocs() {
    return true;
  }

  virtual bool isCallSite(Reference::Kind kind) {
    for (const KindMapping* p = _s_kindMappings; p->string != NULL; ++p) {
      if ( kind == p->value )
        return p->isBranch;
    }
    return false;
  }

  virtual bool isGOTAccess(Reference::Kind kind, bool& canBypassGOT) {
    for (const KindMapping* p = _s_kindMappings; p->string != NULL; ++p) {
      if ( kind == p->value ) {
        canBypassGOT = p->isGotLoad;
        return p->isGotUse;
      }
    }
    return false;
  }

  virtual void updateReferenceToGOT(const Reference* ref, bool targetIsNowGOT) {
    if ( targetIsNowGOT )
      (const_cast<Reference*>(ref))->setKind(kindFromString("pcrel32"));
    else
      (const_cast<Reference*>(ref))->setKind(kindFromString("lea32wasGot"));
  }

  virtual const DefinedAtom* makeStub(const Atom& shlibAtom, File& file) {
    return new TestingStubAtom(file, shlibAtom);
  }

  virtual const DefinedAtom* makeGOTEntry(const Atom& shlibAtom, File& file) {
    return new TestingGOTAtom(file, shlibAtom);
  }

};

//
// Table of fixup kinds in YAML documents used for testing
//
const TestingPlatform::KindMapping TestingPlatform::_s_kindMappings[] = {
    { "call32",         1,    true,  false, false},
    { "pcrel32",        2,    false, false, false },
    { "gotLoad32",      3,    false, true,  true },
    { "gotUse32",       4,    false, false, true },
    { "lea32wasGot",    5,    false, false, false },
    { NULL,             0,    false, false, false }
  };

//
// A simple input files wrapper for testing.
//
class TestingInputFiles : public InputFiles {
public:
  TestingInputFiles(std::vector<const File*>& f) : _files(f) { }

  // InputFiles interface
  virtual void forEachInitialAtom(InputFiles::Handler& handler) const {
    for (std::vector<const File *>::iterator fit = _files.begin();
                                       fit != _files.end(); ++fit) {
      const File* file = *fit;
      handler.doFile(*file);
      for(auto it=file->definedAtomsBegin(),end=file->definedAtomsEnd();
                                 it != end; ++it) {
        handler.doDefinedAtom(**it);
      }
      for(auto it=file->undefinedAtomsBegin(), end=file->undefinedAtomsEnd();
                                 it != end; ++it) {
        handler.doUndefinedAtom(**it);
      }
      for(auto it=file->sharedLibraryAtomsBegin(), end=file->sharedLibraryAtomsEnd();
                                 it != end; ++it) {
        handler.doSharedLibraryAtom(**it);
      }
      for(auto it=file->absoluteAtomsBegin(),end=file->absoluteAtomsEnd();
                                 it != end; ++it) {
        handler.doAbsoluteAtom(**it);
      }
    }
  }

  virtual bool searchLibraries(llvm::StringRef name, bool searchDylibs,
                               bool searchArchives, bool dataSymbolOnly,
                               InputFiles::Handler &) const {
    return false;
  }

private:
  std::vector<const File*>&        _files;
};
}

llvm::cl::opt<std::string>
gInputFilePath(llvm::cl::Positional,
              llvm::cl::desc("<input file>"),
              llvm::cl::init("-"));

llvm::cl::opt<std::string>
gOutputFilePath("o",
              llvm::cl::desc("Specify output filename"),
              llvm::cl::value_desc("filename"));

llvm::cl::opt<bool>
gDoStubsPass("stubs_pass",
          llvm::cl::desc("Run pass to create stub atoms"));

llvm::cl::opt<bool>
gDoGotPass("got_pass",
          llvm::cl::desc("Run pass to create GOT atoms"));

int main(int argc, char *argv[]) {
  // Print a stack trace if we signal out.
  llvm::sys::PrintStackTraceOnErrorSignal();
  llvm::PrettyStackTraceProgram X(argc, argv);
  llvm::llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  // parse options
  llvm::cl::ParseCommandLineOptions(argc, argv);

  // create platform for testing
  TestingPlatform testingPlatform;

  // read input YAML doc into object file(s)
  std::vector<const File *> files;
  if (error(yaml::parseObjectTextFileOrSTDIN(gInputFilePath,
                                            testingPlatform, files))) {
    return 1;
  }

  // create object to mange input files
  TestingInputFiles inputFiles(files);

  // merge all atom graphs
  Resolver resolver(testingPlatform, inputFiles);
  resolver.resolve();

  // run passes
  if ( gDoGotPass ) {
    GOTPass  addGot(resolver.resultFile(), testingPlatform);
    addGot.perform();
  }
  if ( gDoStubsPass ) {
    StubsPass  addStubs(resolver.resultFile(), testingPlatform);
    addStubs.perform();
  }

  // write new atom graph out as YAML doc
  std::string errorInfo;
  const char* outPath = gOutputFilePath.empty() ? "-" : gOutputFilePath.c_str();
  llvm::raw_fd_ostream out(outPath, errorInfo);
//  yaml::writeObjectText(resolver.resultFile(), out);

  // make unique temp .o file to put generated object file
  int fd;
  llvm::SmallString<128> tempPath;
  llvm::sys::fs::unique_file("temp%%%%%.o", fd, tempPath);
  llvm::raw_fd_ostream  binaryOut(fd, /*shouldClose=*/true);

  // write native file
  writeNativeObjectFile(resolver.resultFile(), binaryOut);
  binaryOut.close();  // manually close so that file can be read next

//  out << "native file: " << tempPath.str() << "\n";

  // read native file
  llvm::OwningPtr<lld::File> natFile;
  if ( error(parseNativeObjectFileOrSTDIN(tempPath, natFile)) )
	return 1;

  // write new atom graph out as YAML doc
  yaml::writeObjectText(*natFile, testingPlatform, out);

  // delete temp .o file
  bool existed;
  llvm::sys::fs::remove(tempPath.str(), existed);

  return 0;
}
<commit_msg>Add ArrayRef header. Patch by Marshall Clow.<commit_after>//===- tools/lld/lld-core.cpp - Linker Core Test Driver -----------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lld/Core/InputFiles.h"
#include "lld/Core/Atom.h"
#include "lld/Core/DefinedAtom.h"
#include "lld/Core/UndefinedAtom.h"
#include "lld/Core/Pass.h"
#include "lld/Core/Resolver.h"
#include "lld/Core/YamlReader.h"
#include "lld/Core/YamlWriter.h"
#include "lld/Core/NativeReader.h"
#include "lld/Core/NativeWriter.h"
#include "lld/Core/Platform.h"

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/system_error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"

#include <vector>

using namespace lld;

static void error(llvm::Twine message) {
  llvm::errs() << "lld-core: " << message << ".\n";
}

static bool error(llvm::error_code ec) {
  if (ec) {
    error(ec.message());
    return true;
  }
  return false;
}

namespace {

//
// Simple atom created by the stubs pass.
//
class TestingStubAtom : public DefinedAtom {
public:
        TestingStubAtom(const File& f, const Atom& shlib) :
                        _file(f), _shlib(shlib) {
          static uint32_t lastOrdinal = 0;
          _ordinal = lastOrdinal++;
        }

  virtual const File& file() const {
    return _file;
  }

  virtual llvm::StringRef name() const {
    return llvm::StringRef();
  }

  virtual uint64_t ordinal() const {
    return _ordinal;
  }

  virtual uint64_t size() const {
    return 0;
  }

  virtual Scope scope() const {
    return DefinedAtom::scopeLinkageUnit;
  }

  virtual Interposable interposable() const {
    return DefinedAtom::interposeNo;
  }

  virtual Merge merge() const {
    return DefinedAtom::mergeNo;
  }

  virtual ContentType contentType() const  {
    return DefinedAtom::typeStub;
  }

  virtual Alignment alignment() const {
    return Alignment(0,0);
  }

  virtual SectionChoice sectionChoice() const {
    return DefinedAtom::sectionBasedOnContent;
  }

  virtual llvm::StringRef customSectionName() const {
    return llvm::StringRef();
  }
  virtual DeadStripKind deadStrip() const {
    return DefinedAtom::deadStripNormal;
  }

  virtual ContentPermissions permissions() const  {
    return DefinedAtom::permR_X;
  }

  virtual bool isThumb() const {
    return false;
  }

  virtual bool isAlias() const {
    return false;
  }

  virtual llvm::ArrayRef<uint8_t> rawContent() const {
    return llvm::ArrayRef<uint8_t>();
  }

  virtual reference_iterator referencesBegin() const {
    return reference_iterator(*this, NULL);
  }

  virtual reference_iterator referencesEnd() const {
    return reference_iterator(*this, NULL);
  }

  virtual const Reference* derefIterator(const void* iter) const {
    return NULL;
  }

  virtual void incrementIterator(const void*& iter) const {

  }

private:
  const File&               _file;
  const Atom&               _shlib;
  uint32_t                  _ordinal;
};

//
// Simple atom created by the GOT pass.
//
class TestingGOTAtom : public DefinedAtom {
public:
        TestingGOTAtom(const File& f, const Atom& shlib) :
                        _file(f), _shlib(shlib) {
          static uint32_t lastOrdinal = 0;
          _ordinal = lastOrdinal++;
        }

  virtual const File& file() const {
    return _file;
  }

  virtual llvm::StringRef name() const {
    return llvm::StringRef();
  }

  virtual uint64_t ordinal() const {
    return _ordinal;
  }

  virtual uint64_t size() const {
    return 0;
  }

  virtual Scope scope() const {
    return DefinedAtom::scopeLinkageUnit;
  }

  virtual Interposable interposable() const {
    return DefinedAtom::interposeNo;
  }

  virtual Merge merge() const {
    return DefinedAtom::mergeNo;
  }

  virtual ContentType contentType() const  {
    return DefinedAtom::typeGOT;
  }

  virtual Alignment alignment() const {
    return Alignment(3,0);
  }

  virtual SectionChoice sectionChoice() const {
    return DefinedAtom::sectionBasedOnContent;
  }

  virtual llvm::StringRef customSectionName() const {
    return llvm::StringRef();
  }
  virtual DeadStripKind deadStrip() const {
    return DefinedAtom::deadStripNormal;
  }

  virtual ContentPermissions permissions() const  {
    return DefinedAtom::permRW_;
  }

  virtual bool isThumb() const {
    return false;
  }

  virtual bool isAlias() const {
    return false;
  }

  virtual llvm::ArrayRef<uint8_t> rawContent() const {
    return llvm::ArrayRef<uint8_t>();
  }

  virtual reference_iterator referencesBegin() const {
    return reference_iterator(*this, NULL);
  }

  virtual reference_iterator referencesEnd() const {
    return reference_iterator(*this, NULL);
  }

  virtual const Reference* derefIterator(const void* iter) const {
    return NULL;
  }

  virtual void incrementIterator(const void*& iter) const {

  }

private:
  const File&               _file;
  const Atom&               _shlib;
  uint32_t                  _ordinal;
};

//
// A simple platform for testing.
//
class TestingPlatform : public Platform {
public:

  virtual void initialize() { }

  // tell platform object another file has been added
  virtual void fileAdded(const File &file) { }

  // tell platform object another atom has been added
  virtual void atomAdded(const Atom &file) { }

  // give platform a chance to change each atom's scope
  virtual void adjustScope(const DefinedAtom &atom) { }

  // if specified atom needs alternate names, return AliasAtom(s)
  virtual bool getAliasAtoms(const Atom &atom,
                             std::vector<const DefinedAtom *>&) {
    return false;
  }

  // give platform a chance to resolve platform-specific undefs
  virtual bool getPlatformAtoms(llvm::StringRef undefined,
                                std::vector<const DefinedAtom *>&) {
    return false;
  }

  // resolver should remove unreferenced atoms
  virtual bool deadCodeStripping() {
    return false;
  }

  // atom must be kept so should be root of dead-strip graph
  virtual bool isDeadStripRoot(const Atom &atom) {
    return false;
  }

  // if target must have some atoms, denote here
  virtual bool getImplicitDeadStripRoots(std::vector<const DefinedAtom *>&) {
    return false;
  }

  // return entry point for output file (e.g. "main") or NULL
  virtual llvm::StringRef entryPointName() {
    return NULL;
  }

  // for iterating must-be-defined symbols ("main" or -u command line option)
  typedef llvm::StringRef const *UndefinesIterator;
  virtual UndefinesIterator initialUndefinesBegin() const {
    return NULL;
  }
  virtual UndefinesIterator initialUndefinesEnd() const {
    return NULL;
  }

  // if platform wants resolvers to search libraries for overrides
  virtual bool searchArchivesToOverrideTentativeDefinitions() {
    return false;
  }

  virtual bool searchSharedLibrariesToOverrideTentativeDefinitions() {
    return false;
  }

  // if platform allows symbol to remain undefined (e.g. -r)
  virtual bool allowUndefinedSymbol(llvm::StringRef name) {
    return true;
  }

  // for debugging dead code stripping, -why_live
  virtual bool printWhyLive(llvm::StringRef name) {
    return false;
  }

  virtual const Atom& handleMultipleDefinitions(const Atom& def1,
                                                const Atom& def2) {
    llvm::report_fatal_error("symbol '"
                            + llvm::Twine(def1.name())
                            + "' multiply defined");
  }

  // print out undefined symbol error messages in platform specific way
  virtual void errorWithUndefines(const std::vector<const Atom *> &undefs,
                                  const std::vector<const Atom *> &all) {}

  // print out undefined can-be-null mismatches
  virtual void undefineCanBeNullMismatch(const UndefinedAtom& undef1,
                                         const UndefinedAtom& undef2,
                                         bool& useUndef2) { }

  // print out shared library mismatches
  virtual void sharedLibrarylMismatch(const SharedLibraryAtom& shLib1,
                                      const SharedLibraryAtom& shLib2,
                                      bool& useShlib2) { }

  // last chance for platform to tweak atoms
  virtual void postResolveTweaks(std::vector<const Atom *> &all) {}

  struct KindMapping {
    const char*           string;
    Reference::Kind       value;
    bool                  isBranch;
    bool                  isGotLoad;
    bool                  isGotUse;
  };

  static const KindMapping _s_kindMappings[];

  virtual Reference::Kind kindFromString(llvm::StringRef kindName) {
    for (const KindMapping* p = _s_kindMappings; p->string != NULL; ++p) {
      if ( kindName.equals(p->string) )
        return p->value;
    }
    int k;
    if (kindName.getAsInteger(0, k))
      k = 0;
    return k;
  }

  virtual llvm::StringRef kindToString(Reference::Kind value) {
    for (const KindMapping* p = _s_kindMappings; p->string != NULL; ++p) {
      if ( value == p->value)
        return p->string;
    }
    return llvm::StringRef("???");
  }

  virtual bool noTextRelocs() {
    return true;
  }

  virtual bool isCallSite(Reference::Kind kind) {
    for (const KindMapping* p = _s_kindMappings; p->string != NULL; ++p) {
      if ( kind == p->value )
        return p->isBranch;
    }
    return false;
  }

  virtual bool isGOTAccess(Reference::Kind kind, bool& canBypassGOT) {
    for (const KindMapping* p = _s_kindMappings; p->string != NULL; ++p) {
      if ( kind == p->value ) {
        canBypassGOT = p->isGotLoad;
        return p->isGotUse;
      }
    }
    return false;
  }

  virtual void updateReferenceToGOT(const Reference* ref, bool targetIsNowGOT) {
    if ( targetIsNowGOT )
      (const_cast<Reference*>(ref))->setKind(kindFromString("pcrel32"));
    else
      (const_cast<Reference*>(ref))->setKind(kindFromString("lea32wasGot"));
  }

  virtual const DefinedAtom* makeStub(const Atom& shlibAtom, File& file) {
    return new TestingStubAtom(file, shlibAtom);
  }

  virtual const DefinedAtom* makeGOTEntry(const Atom& shlibAtom, File& file) {
    return new TestingGOTAtom(file, shlibAtom);
  }

};

//
// Table of fixup kinds in YAML documents used for testing
//
const TestingPlatform::KindMapping TestingPlatform::_s_kindMappings[] = {
    { "call32",         1,    true,  false, false},
    { "pcrel32",        2,    false, false, false },
    { "gotLoad32",      3,    false, true,  true },
    { "gotUse32",       4,    false, false, true },
    { "lea32wasGot",    5,    false, false, false },
    { NULL,             0,    false, false, false }
  };

//
// A simple input files wrapper for testing.
//
class TestingInputFiles : public InputFiles {
public:
  TestingInputFiles(std::vector<const File*>& f) : _files(f) { }

  // InputFiles interface
  virtual void forEachInitialAtom(InputFiles::Handler& handler) const {
    for (std::vector<const File *>::iterator fit = _files.begin();
                                       fit != _files.end(); ++fit) {
      const File* file = *fit;
      handler.doFile(*file);
      for(auto it=file->definedAtomsBegin(),end=file->definedAtomsEnd();
                                 it != end; ++it) {
        handler.doDefinedAtom(**it);
      }
      for(auto it=file->undefinedAtomsBegin(), end=file->undefinedAtomsEnd();
                                 it != end; ++it) {
        handler.doUndefinedAtom(**it);
      }
      for(auto it=file->sharedLibraryAtomsBegin(), end=file->sharedLibraryAtomsEnd();
                                 it != end; ++it) {
        handler.doSharedLibraryAtom(**it);
      }
      for(auto it=file->absoluteAtomsBegin(),end=file->absoluteAtomsEnd();
                                 it != end; ++it) {
        handler.doAbsoluteAtom(**it);
      }
    }
  }

  virtual bool searchLibraries(llvm::StringRef name, bool searchDylibs,
                               bool searchArchives, bool dataSymbolOnly,
                               InputFiles::Handler &) const {
    return false;
  }

private:
  std::vector<const File*>&        _files;
};
}

llvm::cl::opt<std::string>
gInputFilePath(llvm::cl::Positional,
              llvm::cl::desc("<input file>"),
              llvm::cl::init("-"));

llvm::cl::opt<std::string>
gOutputFilePath("o",
              llvm::cl::desc("Specify output filename"),
              llvm::cl::value_desc("filename"));

llvm::cl::opt<bool>
gDoStubsPass("stubs_pass",
          llvm::cl::desc("Run pass to create stub atoms"));

llvm::cl::opt<bool>
gDoGotPass("got_pass",
          llvm::cl::desc("Run pass to create GOT atoms"));

int main(int argc, char *argv[]) {
  // Print a stack trace if we signal out.
  llvm::sys::PrintStackTraceOnErrorSignal();
  llvm::PrettyStackTraceProgram X(argc, argv);
  llvm::llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  // parse options
  llvm::cl::ParseCommandLineOptions(argc, argv);

  // create platform for testing
  TestingPlatform testingPlatform;

  // read input YAML doc into object file(s)
  std::vector<const File *> files;
  if (error(yaml::parseObjectTextFileOrSTDIN(gInputFilePath,
                                            testingPlatform, files))) {
    return 1;
  }

  // create object to mange input files
  TestingInputFiles inputFiles(files);

  // merge all atom graphs
  Resolver resolver(testingPlatform, inputFiles);
  resolver.resolve();

  // run passes
  if ( gDoGotPass ) {
    GOTPass  addGot(resolver.resultFile(), testingPlatform);
    addGot.perform();
  }
  if ( gDoStubsPass ) {
    StubsPass  addStubs(resolver.resultFile(), testingPlatform);
    addStubs.perform();
  }

  // write new atom graph out as YAML doc
  std::string errorInfo;
  const char* outPath = gOutputFilePath.empty() ? "-" : gOutputFilePath.c_str();
  llvm::raw_fd_ostream out(outPath, errorInfo);
//  yaml::writeObjectText(resolver.resultFile(), out);

  // make unique temp .o file to put generated object file
  int fd;
  llvm::SmallString<128> tempPath;
  llvm::sys::fs::unique_file("temp%%%%%.o", fd, tempPath);
  llvm::raw_fd_ostream  binaryOut(fd, /*shouldClose=*/true);

  // write native file
  writeNativeObjectFile(resolver.resultFile(), binaryOut);
  binaryOut.close();  // manually close so that file can be read next

//  out << "native file: " << tempPath.str() << "\n";

  // read native file
  llvm::OwningPtr<lld::File> natFile;
  if ( error(parseNativeObjectFileOrSTDIN(tempPath, natFile)) )
	return 1;

  // write new atom graph out as YAML doc
  yaml::writeObjectText(*natFile, testingPlatform, out);

  // delete temp .o file
  bool existed;
  llvm::sys::fs::remove(tempPath.str(), existed);

  return 0;
}
<|endoftext|>


<commit_before>/*
 *    Copyright (c) 2019, The OpenThread Authors.
 *    All rights reserved.
 *
 *    Redistribution and use in source and binary forms, with or without
 *    modification, are permitted provided that the following conditions are met:
 *    1. Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *    2. Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *    3. Neither the name of the copyright holder nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *    POSSIBILITY OF SUCH DAMAGE.
 */

#include "agent/ncp_openthread.hpp"

#include <assert.h>
#include <stdio.h>
#include <string.h>

#include <openthread/cli.h>
#include <openthread/dataset.h>
#include <openthread/tasklet.h>
#include <openthread/thread.h>
#include <openthread/thread_ftd.h>
#include <openthread/platform/logging.h>
#include <openthread/platform/misc.h>
#include <openthread/platform/settings.h>

#include "common/code_utils.hpp"
#include "common/types.hpp"

static bool sReset;
using std::chrono::duration_cast;
using std::chrono::microseconds;
using std::chrono::seconds;
using std::chrono::steady_clock;

#if OTBR_ENABLE_NCP_OPENTHREAD
namespace otbr {
namespace Ncp {

ControllerOpenThread::ControllerOpenThread(const char *aInterfaceName, char *aRadioFile, char *aRadioConfig)
{
    memset(&mConfig, 0, sizeof(mConfig));

    mConfig.mInterfaceName = aInterfaceName;
    mConfig.mRadioConfig   = aRadioConfig;
    mConfig.mRadioFile     = aRadioFile;
    mConfig.mResetRadio    = true;
    mConfig.mSpeedUpFactor = 1;
}

ControllerOpenThread::~ControllerOpenThread(void)
{
    otInstanceFinalize(mInstance);
    otSysDeinit();
}

otbrError ControllerOpenThread::Init(void)
{
    otbrError err = OTBR_ERROR_NONE;

    mInstance = otSysInit(&mConfig);
    otCliUartInit(mInstance);
    otSetStateChangedCallback(mInstance, &ControllerOpenThread::HandleStateChanged, this);
    mThreadHelper = std::unique_ptr<otbr::agent::ThreadHelper>(new otbr::agent::ThreadHelper(mInstance, this));
    VerifyOrExit(mThreadHelper->Init() == OT_ERROR_NONE, err = OTBR_ERROR_OPENTHREAD);
exit:
    return err;
}

void ControllerOpenThread::HandleStateChanged(otChangedFlags aFlags)
{
    if (aFlags | OT_CHANGED_THREAD_NETWORK_NAME)
    {
        EventEmitter::Emit(kEventNetworkName, otThreadGetNetworkName(mInstance));
    }

    if (aFlags | OT_CHANGED_THREAD_EXT_PANID)
    {
        EventEmitter::Emit(kEventExtPanId, otThreadGetExtendedPanId(mInstance));
    }

    if (aFlags | OT_CHANGED_THREAD_ROLE)
    {
        bool attached = false;

        switch (otThreadGetDeviceRole(mInstance))
        {
        case OT_DEVICE_ROLE_CHILD:
        case OT_DEVICE_ROLE_ROUTER:
        case OT_DEVICE_ROLE_LEADER:
            attached = true;
            break;
        default:
            break;
        }

        EventEmitter::Emit(kEventThreadState, attached);
    }
}

static struct timeval ToTimeVal(const microseconds &aTime)
{
    constexpr int  kUsPerSecond = 1000000;
    struct timeval val;

    val.tv_sec  = aTime.count() / kUsPerSecond;
    val.tv_usec = aTime.count() % kUsPerSecond;

    return val;
};

void ControllerOpenThread::UpdateFdSet(otSysMainloopContext &aMainloop)
{
    microseconds timeout = microseconds(aMainloop.mTimeout.tv_usec) + seconds(aMainloop.mTimeout.tv_sec);
    auto         now     = steady_clock::now();

    if (otTaskletsArePending(mInstance))
    {
        timeout = microseconds::zero();
    }
    else if (!mTimers.empty())
    {
        if (mTimers.begin()->first < now)
        {
            timeout = microseconds::zero();
        }
        else
        {
            timeout = std::min(timeout, duration_cast<microseconds>(mTimers.begin()->first - now));
        }
    }

    aMainloop.mTimeout = ToTimeVal(timeout);

    otSysMainloopUpdate(mInstance, &aMainloop);
}

void ControllerOpenThread::Process(const otSysMainloopContext &aMainloop)
{
    auto now = steady_clock::now();

    otTaskletsProcess(mInstance);

    otSysMainloopProcess(mInstance, &aMainloop);

    while (!mTimers.empty() && mTimers.begin()->first <= now)
    {
        mTimers.begin()->second();
        mTimers.erase(mTimers.begin());
    }
}

void ControllerOpenThread::Reset(void)
{
    otInstanceFinalize(mInstance);
    otSysDeinit();
    Init();
    sReset = false;
}

bool ControllerOpenThread::IsResetRequested(void)
{
    return sReset;
}

otbrError ControllerOpenThread::RequestEvent(int aEvent)
{
    otbrError ret = OTBR_ERROR_NONE;

    switch (aEvent)
    {
    case kEventExtPanId:
    {
        EventEmitter::Emit(kEventExtPanId, otThreadGetExtendedPanId(mInstance));
        break;
    }
    case kEventThreadState:
    {
        bool attached = false;

        switch (otThreadGetDeviceRole(mInstance))
        {
        case OT_DEVICE_ROLE_CHILD:
        case OT_DEVICE_ROLE_ROUTER:
        case OT_DEVICE_ROLE_LEADER:
            attached = true;
            break;
        default:
            break;
        }

        EventEmitter::Emit(kEventThreadState, attached);
        break;
    }
    case kEventNetworkName:
    {
        EventEmitter::Emit(kEventNetworkName, otThreadGetNetworkName(mInstance));
        break;
    }
    case kEventPSKc:
    {
        EventEmitter::Emit(kEventPSKc, otThreadGetPskc(mInstance));
        break;
    }
    case kEventThreadVersion:
    {
        EventEmitter::Emit(kEventThreadVersion, otThreadGetVersion());
        break;
    }
    default:
        assert(false);
        break;
    }

    return ret;
}

void ControllerOpenThread::PostTimerTask(std::chrono::steady_clock::time_point aTimePoint,
                                         const std::function<void(void)> &     aTask)
{
    mTimers.insert({aTimePoint, aTask});
}

Controller *Controller::Create(const char *aInterfaceName, char *aRadioFile, char *aRadioConfig)
{
    return new ControllerOpenThread(aInterfaceName, aRadioFile, aRadioConfig);
}

/*
 * Provide, if required an "otPlatLog()" function
 */
extern "C" void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
{
    OT_UNUSED_VARIABLE(aLogLevel);
    OT_UNUSED_VARIABLE(aLogRegion);
    OT_UNUSED_VARIABLE(aFormat);

    va_list ap;
    va_start(ap, aFormat);
    otCliPlatLogv(aLogLevel, aLogRegion, aFormat, ap);
    va_end(ap);
}

} // namespace Ncp
} // namespace otbr

void otPlatReset(otInstance *aInstance)
{
    OT_UNUSED_VARIABLE(aInstance);
    sReset = true;
}

#endif // OTBR_ENABLE_NCP_OPENTHREAD
<commit_msg>[agent] use otbr log for OpenThread ncp (#383)<commit_after>/*
 *    Copyright (c) 2019, The OpenThread Authors.
 *    All rights reserved.
 *
 *    Redistribution and use in source and binary forms, with or without
 *    modification, are permitted provided that the following conditions are met:
 *    1. Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *    2. Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *    3. Neither the name of the copyright holder nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *    POSSIBILITY OF SUCH DAMAGE.
 */

#include "agent/ncp_openthread.hpp"

#include <assert.h>
#include <stdio.h>
#include <string.h>

#include <openthread/cli.h>
#include <openthread/dataset.h>
#include <openthread/tasklet.h>
#include <openthread/thread.h>
#include <openthread/thread_ftd.h>
#include <openthread/platform/logging.h>
#include <openthread/platform/misc.h>
#include <openthread/platform/settings.h>

#include "common/code_utils.hpp"
#include "common/logging.hpp"
#include "common/types.hpp"

static bool sReset;
using std::chrono::duration_cast;
using std::chrono::microseconds;
using std::chrono::seconds;
using std::chrono::steady_clock;

#if OTBR_ENABLE_NCP_OPENTHREAD
namespace otbr {
namespace Ncp {

ControllerOpenThread::ControllerOpenThread(const char *aInterfaceName, char *aRadioFile, char *aRadioConfig)
{
    memset(&mConfig, 0, sizeof(mConfig));

    mConfig.mInterfaceName = aInterfaceName;
    mConfig.mRadioConfig   = aRadioConfig;
    mConfig.mRadioFile     = aRadioFile;
    mConfig.mResetRadio    = true;
    mConfig.mSpeedUpFactor = 1;
}

ControllerOpenThread::~ControllerOpenThread(void)
{
    otInstanceFinalize(mInstance);
    otSysDeinit();
}

otbrError ControllerOpenThread::Init(void)
{
    otbrError err = OTBR_ERROR_NONE;

    mInstance = otSysInit(&mConfig);
    otCliUartInit(mInstance);
    otSetStateChangedCallback(mInstance, &ControllerOpenThread::HandleStateChanged, this);
    mThreadHelper = std::unique_ptr<otbr::agent::ThreadHelper>(new otbr::agent::ThreadHelper(mInstance, this));
    VerifyOrExit(mThreadHelper->Init() == OT_ERROR_NONE, err = OTBR_ERROR_OPENTHREAD);
exit:
    return err;
}

void ControllerOpenThread::HandleStateChanged(otChangedFlags aFlags)
{
    if (aFlags | OT_CHANGED_THREAD_NETWORK_NAME)
    {
        EventEmitter::Emit(kEventNetworkName, otThreadGetNetworkName(mInstance));
    }

    if (aFlags | OT_CHANGED_THREAD_EXT_PANID)
    {
        EventEmitter::Emit(kEventExtPanId, otThreadGetExtendedPanId(mInstance));
    }

    if (aFlags | OT_CHANGED_THREAD_ROLE)
    {
        bool attached = false;

        switch (otThreadGetDeviceRole(mInstance))
        {
        case OT_DEVICE_ROLE_CHILD:
        case OT_DEVICE_ROLE_ROUTER:
        case OT_DEVICE_ROLE_LEADER:
            attached = true;
            break;
        default:
            break;
        }

        EventEmitter::Emit(kEventThreadState, attached);
    }
}

static struct timeval ToTimeVal(const microseconds &aTime)
{
    constexpr int  kUsPerSecond = 1000000;
    struct timeval val;

    val.tv_sec  = aTime.count() / kUsPerSecond;
    val.tv_usec = aTime.count() % kUsPerSecond;

    return val;
};

void ControllerOpenThread::UpdateFdSet(otSysMainloopContext &aMainloop)
{
    microseconds timeout = microseconds(aMainloop.mTimeout.tv_usec) + seconds(aMainloop.mTimeout.tv_sec);
    auto         now     = steady_clock::now();

    if (otTaskletsArePending(mInstance))
    {
        timeout = microseconds::zero();
    }
    else if (!mTimers.empty())
    {
        if (mTimers.begin()->first < now)
        {
            timeout = microseconds::zero();
        }
        else
        {
            timeout = std::min(timeout, duration_cast<microseconds>(mTimers.begin()->first - now));
        }
    }

    aMainloop.mTimeout = ToTimeVal(timeout);

    otSysMainloopUpdate(mInstance, &aMainloop);
}

void ControllerOpenThread::Process(const otSysMainloopContext &aMainloop)
{
    auto now = steady_clock::now();

    otTaskletsProcess(mInstance);

    otSysMainloopProcess(mInstance, &aMainloop);

    while (!mTimers.empty() && mTimers.begin()->first <= now)
    {
        mTimers.begin()->second();
        mTimers.erase(mTimers.begin());
    }
}

void ControllerOpenThread::Reset(void)
{
    otInstanceFinalize(mInstance);
    otSysDeinit();
    Init();
    sReset = false;
}

bool ControllerOpenThread::IsResetRequested(void)
{
    return sReset;
}

otbrError ControllerOpenThread::RequestEvent(int aEvent)
{
    otbrError ret = OTBR_ERROR_NONE;

    switch (aEvent)
    {
    case kEventExtPanId:
    {
        EventEmitter::Emit(kEventExtPanId, otThreadGetExtendedPanId(mInstance));
        break;
    }
    case kEventThreadState:
    {
        bool attached = false;

        switch (otThreadGetDeviceRole(mInstance))
        {
        case OT_DEVICE_ROLE_CHILD:
        case OT_DEVICE_ROLE_ROUTER:
        case OT_DEVICE_ROLE_LEADER:
            attached = true;
            break;
        default:
            break;
        }

        EventEmitter::Emit(kEventThreadState, attached);
        break;
    }
    case kEventNetworkName:
    {
        EventEmitter::Emit(kEventNetworkName, otThreadGetNetworkName(mInstance));
        break;
    }
    case kEventPSKc:
    {
        EventEmitter::Emit(kEventPSKc, otThreadGetPskc(mInstance));
        break;
    }
    case kEventThreadVersion:
    {
        EventEmitter::Emit(kEventThreadVersion, otThreadGetVersion());
        break;
    }
    default:
        assert(false);
        break;
    }

    return ret;
}

void ControllerOpenThread::PostTimerTask(std::chrono::steady_clock::time_point aTimePoint,
                                         const std::function<void(void)> &     aTask)
{
    mTimers.insert({aTimePoint, aTask});
}

Controller *Controller::Create(const char *aInterfaceName, char *aRadioFile, char *aRadioConfig)
{
    return new ControllerOpenThread(aInterfaceName, aRadioFile, aRadioConfig);
}

/*
 * Provide, if required an "otPlatLog()" function
 */
extern "C" void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
{
    OT_UNUSED_VARIABLE(aLogRegion);

    int otbrLogLevel;

    switch (aLogLevel)
    {
    case OT_LOG_LEVEL_NONE:
        otbrLogLevel = OTBR_LOG_EMERG;
        break;
    case OT_LOG_LEVEL_CRIT:
        otbrLogLevel = OTBR_LOG_CRIT;
        break;
    case OT_LOG_LEVEL_WARN:
        otbrLogLevel = OTBR_LOG_WARNING;
        break;
    case OT_LOG_LEVEL_NOTE:
        otbrLogLevel = OTBR_LOG_NOTICE;
        break;
    case OT_LOG_LEVEL_INFO:
        otbrLogLevel = OTBR_LOG_INFO;
        break;
    case OT_LOG_LEVEL_DEBG:
        otbrLogLevel = OTBR_LOG_DEBUG;
        break;
    default:
        otbrLogLevel = OTBR_LOG_DEBUG;
        break;
    }

    va_list ap;
    va_start(ap, aFormat);
    otbrLogv(otbrLogLevel, aFormat, ap);
    va_end(ap);
}

} // namespace Ncp
} // namespace otbr

void otPlatReset(otInstance *aInstance)
{
    OT_UNUSED_VARIABLE(aInstance);
    sReset = true;
}

#endif // OTBR_ENABLE_NCP_OPENTHREAD
<|endoftext|>


<commit_before>
#include "formats.h"

#include "utils.h"

#include <iostream>
#include <iomanip>

void list_formats (const std::vector<VideoFormatDescription>& available_formats)
{
    for (const VideoFormatDescription& f : available_formats)
    {
        auto desc = f.getFormatDescription();

        std::cout << "Format: " << desc.description << " - Fourcc(" << desc.fourcc << ")" //<< std::endl
                  << std::endl;
        for (const auto& s : f.getResolutionsFramesrates())
        {
            std::cout << "\tResolution: " << s.resolution.width << "x" << s.resolution.height << std::endl;
            for (const auto& fps : s.fps)
            {
                std::cout << "\t\t" << std::setw(8) << std::fixed << std::setprecision(4)<< fps << " fps" << std::endl;
            }
        }
        std::cout << std::endl;
    }
}

void print_active_format (const VideoFormat& format)
{
    std::cout << "Active format:" << std::endl;
    std::cout << fourcc2description(format.getFourcc()) << std::endl
              << format.getSize().width << "x" << format.getSize().height << std::endl
              << format.getFramerate() << std::endl
              << format.getBinning() << std::endl << std::endl;
}

bool set_active_format (CaptureDevice& g, const std::string& new_format)
{
    VideoFormat v;

    bool ret = v.fromString(new_format);

    if (ret)
    {
        ret = g.setVideoFormat(v);

        return ret;
    }
    else
    {
        std::cout << "Invalid string description!" << std::endl;
    }
    return false;
}
<commit_msg>Updated output<commit_after>
#include "formats.h"

#include "utils.h"

#include <iostream>
#include <iomanip>

void list_formats (const std::vector<VideoFormatDescription>& available_formats)
{
    std::cout << "Available format settings:" << std::endl;
    for (const VideoFormatDescription& f : available_formats)
    {
        auto desc = f.getFormatDescription();

        std::cout << "Format: " << desc.description << " - Fourcc(" << desc.fourcc << ")"
                  << std::endl;
        for (const auto& s : f.getResolutionsFramesrates())
        {
            std::cout << "\tResolution: " << s.resolution.width << "x" << s.resolution.height << std::endl;
            for (const auto& fps : s.fps)
            {
                std::cout << "\t\t" << std::setw(8) << std::fixed << std::setprecision(4)<< fps << " fps" << std::endl;
            }
        }
        std::cout << std::endl;
    }
}

void print_active_format (const VideoFormat& format)
{
    std::cout << "Active format:\n"
              << "Format: \t" << fourcc2description(format.getFourcc())
              << "\nResolution: \t" << format.getSize().width << "x" << format.getSize().height
              << "\nBinning: \t" << format.getBinning()
              << "\nFramerate: \t" << format.getFramerate() << "\n" << std::endl;
}

bool set_active_format (CaptureDevice& g, const std::string& new_format)
{
    VideoFormat v;

    bool ret = v.fromString(new_format);

    if (ret)
    {
        return g.setVideoFormat(v);
    }
    else
    {
        std::cout << "Invalid string description!" << std::endl;
    }
    return false;
}
<|endoftext|>


<commit_before>#include "page_repl_random.hpp"
#include "buffer_cache/mirrored/mirrored.hpp"

page_repl_random_t::page_repl_random_t(unsigned int _unload_threshold, cache_t *_cache)
    : unload_threshold(_unload_threshold),
      cache(_cache)
    {}

page_repl_random_t::local_buf_t::local_buf_t(inner_buf_t *gbuf) : gbuf(gbuf) {
    index = gbuf->cache->page_repl.array.size();
    gbuf->cache->page_repl.array.set(index, gbuf);
}

page_repl_random_t::local_buf_t::~local_buf_t() {
    unsigned int last_index = gbuf->cache->page_repl.array.size() - 1;

    if (index == last_index) {
        gbuf->cache->page_repl.array.set(index, NULL);
    } else {
        inner_buf_t *replacement = gbuf->cache->page_repl.array.get(last_index);
        replacement->page_repl_buf.index = index;
        gbuf->cache->page_repl.array.set(index, replacement);
        gbuf->cache->page_repl.array.set(last_index, NULL);
        index = -1;
    }
}

bool page_repl_random_t::is_full(unsigned int space_needed) {
    return array.size() + space_needed > unload_threshold;
}

perfmon_counter_t pm_n_blocks_evicted("blocks_evicted");

// make_space tries to make sure that the number of blocks currently in memory is at least
// 'space_needed' less than the user-specified memory limit.
void page_repl_random_t::make_space(unsigned int space_needed) {
    unsigned int target;
    if (space_needed > unload_threshold) target = unload_threshold;
    else target = unload_threshold - space_needed;

    while (array.size() > target) {
        // Try to find a block we can unload. Blocks are ineligible to be unloaded if they are
        // dirty or in use.
        inner_buf_t *block_to_unload = NULL;
        for (int tries = PAGE_REPL_NUM_TRIES; tries > 0; tries --) {
            /* Choose a block in memory at random. */
            unsigned int n = random() % array.size();
            inner_buf_t *block = array.get(n);

            if (block->safe_to_unload()) {
                block_to_unload = block;
                break;
            }
        }

        if (block_to_unload) {
            //printf("Unloading: %ld\n", block_to_unload->block_id);

            /* inner_buf_t's destructor, and the destructors of the local_buf_ts, take care of the
            details */
            delete block_to_unload;

            pm_n_blocks_evicted++;

        } else {
            if (array.size() > target + (target / 100) + 10) {
                logDBG("cache %p exceeding memory target. %d blocks in memory, %d dirty, target is %d.\n",
                       cache, array.size(), cache->writeback.num_dirty_blocks(), target);
            }
            break;
        }
    }
}

mc_inner_buf_t *page_repl_random_t::get_first_buf() {
    if (array.size() == 0) return NULL;
    return array.get(0);
}

mc_inner_buf_t *page_repl_random_t::get_next_buf(inner_buf_t *buf) {
    if (buf->page_repl_buf.index == array.size() - 1) return NULL;
    else return array.get(buf->page_repl_buf.index + 1);
}
<commit_msg>add note regarding page_repl_random randomness<commit_after>#include "page_repl_random.hpp"
#include "buffer_cache/mirrored/mirrored.hpp"

page_repl_random_t::page_repl_random_t(unsigned int _unload_threshold, cache_t *_cache)
    : unload_threshold(_unload_threshold),
      cache(_cache)
    {}

page_repl_random_t::local_buf_t::local_buf_t(inner_buf_t *gbuf) : gbuf(gbuf) {
    index = gbuf->cache->page_repl.array.size();
    gbuf->cache->page_repl.array.set(index, gbuf);
}

page_repl_random_t::local_buf_t::~local_buf_t() {
    unsigned int last_index = gbuf->cache->page_repl.array.size() - 1;

    if (index == last_index) {
        gbuf->cache->page_repl.array.set(index, NULL);
    } else {
        inner_buf_t *replacement = gbuf->cache->page_repl.array.get(last_index);
        replacement->page_repl_buf.index = index;
        gbuf->cache->page_repl.array.set(index, replacement);
        gbuf->cache->page_repl.array.set(last_index, NULL);
        index = -1;
    }
}

bool page_repl_random_t::is_full(unsigned int space_needed) {
    return array.size() + space_needed > unload_threshold;
}

perfmon_counter_t pm_n_blocks_evicted("blocks_evicted");

// make_space tries to make sure that the number of blocks currently in memory is at least
// 'space_needed' less than the user-specified memory limit.
void page_repl_random_t::make_space(unsigned int space_needed) {
    unsigned int target;
    if (space_needed > unload_threshold) target = unload_threshold;
    else target = unload_threshold - space_needed;

    while (array.size() > target) {
        // Try to find a block we can unload. Blocks are ineligible to be unloaded if they are
        // dirty or in use.
        inner_buf_t *block_to_unload = NULL;
        for (int tries = PAGE_REPL_NUM_TRIES; tries > 0; tries --) {
            /* Choose a block in memory at random. */
            // NOTE: this method of random selection is slightly biased towards lower indices, I
            // think. @rntz
            unsigned int n = random() % array.size();
            inner_buf_t *block = array.get(n);

            if (block->safe_to_unload()) {
                block_to_unload = block;
                break;
            }
        }

        if (block_to_unload) {
            //printf("Unloading: %ld\n", block_to_unload->block_id);

            /* inner_buf_t's destructor, and the destructors of the local_buf_ts, take care of the
            details */
            delete block_to_unload;

            pm_n_blocks_evicted++;

        } else {
            if (array.size() > target + (target / 100) + 10) {
                logDBG("cache %p exceeding memory target. %d blocks in memory, %d dirty, target is %d.\n",
                       cache, array.size(), cache->writeback.num_dirty_blocks(), target);
            }
            break;
        }
    }
}

mc_inner_buf_t *page_repl_random_t::get_first_buf() {
    if (array.size() == 0) return NULL;
    return array.get(0);
}

mc_inner_buf_t *page_repl_random_t::get_next_buf(inner_buf_t *buf) {
    if (buf->page_repl_buf.index == array.size() - 1) return NULL;
    else return array.get(buf->page_repl_buf.index + 1);
}
<|endoftext|>


<commit_before>/*
    This file is part of Magnum.

    Copyright © 2010, 2011, 2012, 2013, 2014, 2015
              Vladimír Vondruš <mosra@centrum.cz>

    Permission is hereby granted, free of charge, to any person obtaining a
    copy of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation
    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included
    in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    DEALINGS IN THE SOFTWARE.
*/

#include "CompressIndices.h"

#include <cstring>
#include <algorithm>
#include <Corrade/Containers/Array.h>

#include "Magnum/Math/Functions.h"

namespace Magnum { namespace MeshTools {

namespace {

template<class> constexpr Mesh::IndexType indexType();
template<> constexpr Mesh::IndexType indexType<UnsignedByte>() { return Mesh::IndexType::UnsignedByte; }
template<> constexpr Mesh::IndexType indexType<UnsignedShort>() { return Mesh::IndexType::UnsignedShort; }
template<> constexpr Mesh::IndexType indexType<UnsignedInt>() { return Mesh::IndexType::UnsignedInt; }

template<class T> inline std::pair<Containers::Array<char>, Mesh::IndexType> compress(const std::vector<UnsignedInt>& indices) {
    Containers::Array<char> buffer(indices.size()*sizeof(T));
    for(std::size_t i = 0; i != indices.size(); ++i) {
        T index = static_cast<T>(indices[i]);
        std::memcpy(buffer.begin()+i*sizeof(T), &index, sizeof(T));
    }

    return {std::move(buffer), indexType<T>()};
}

}

std::tuple<Containers::Array<char>, Mesh::IndexType, UnsignedInt, UnsignedInt> compressIndices(const std::vector<UnsignedInt>& indices) {
    /** @todo Performance hint when range can be represented by smaller value? */
    auto minmax = std::minmax_element(indices.begin(), indices.end());
    std::pair<Containers::Array<char>, Mesh::IndexType> typeData;
    switch(Math::log(256, *minmax.second)) {
        case 0:
            typeData = compress<UnsignedByte>(indices);
            break;
        case 1:
            typeData = compress<UnsignedShort>(indices);
            break;
        case 2:
        case 3:
            typeData = compress<UnsignedInt>(indices);
            break;

        default:
            CORRADE_ASSERT(false, "MeshTools::compressIndices(): no type able to index" << *minmax.second << "elements.", {});
    }

    return std::make_tuple(std::move(typeData.first), typeData.second, *minmax.first, *minmax.second);
}

}}
<commit_msg>MeshTools: simplify internal implementation of compressIndices().<commit_after>/*
    This file is part of Magnum.

    Copyright © 2010, 2011, 2012, 2013, 2014, 2015
              Vladimír Vondruš <mosra@centrum.cz>

    Permission is hereby granted, free of charge, to any person obtaining a
    copy of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation
    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included
    in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    DEALINGS IN THE SOFTWARE.
*/

#include "CompressIndices.h"

#include <cstring>
#include <algorithm>
#include <Corrade/Containers/Array.h>

#include "Magnum/Math/Functions.h"

namespace Magnum { namespace MeshTools {

namespace {

template<class T> inline Containers::Array<char> compress(const std::vector<UnsignedInt>& indices) {
    Containers::Array<char> buffer(indices.size()*sizeof(T));
    for(std::size_t i = 0; i != indices.size(); ++i) {
        T index = static_cast<T>(indices[i]);
        std::memcpy(buffer.begin()+i*sizeof(T), &index, sizeof(T));
    }

    return buffer;
}

}

std::tuple<Containers::Array<char>, Mesh::IndexType, UnsignedInt, UnsignedInt> compressIndices(const std::vector<UnsignedInt>& indices) {
    /** @todo Performance hint when range can be represented by smaller value? */
    auto minmax = std::minmax_element(indices.begin(), indices.end());
    Containers::Array<char> data;
    Mesh::IndexType type;
    switch(Math::log(256, *minmax.second)) {
        case 0:
            data = compress<UnsignedByte>(indices);
            type = Mesh::IndexType::UnsignedByte;
            break;
        case 1:
            data = compress<UnsignedShort>(indices);
            type = Mesh::IndexType::UnsignedShort;
            break;
        case 2:
        case 3:
            data = compress<UnsignedInt>(indices);
            type = Mesh::IndexType::UnsignedInt;
            break;

        default:
            CORRADE_ASSERT(false, "MeshTools::compressIndices(): no type able to index" << *minmax.second << "elements.", {});
    }

    return std::make_tuple(std::move(data), type, *minmax.first, *minmax.second);
}

}}
<|endoftext|>


<commit_before>#include <QApplication>
#include "ddMainWindow.h"
#include "ddPythonManager.h"

#define USE_TDX 0
#if USE_TDX
  #include <QVTKApplication.h>
#endif

int main(int argc, char **argv)
{
#if USE_TDX
  QVTKApplication app(argc, argv);
#else
  QApplication app(argc, argv);
#endif

  ddPythonManager* pythonManager = new ddPythonManager;

  ddMainWindow* window = new ddMainWindow;
  window->setPythonManager(pythonManager);
  window->resize(1800, 1000);
  window->show();

  int result = app.exec();

  delete window;

#ifdef Q_OS_MAC
  // On MacOSX, there is a crash during PythonQt's finalization cleanup
  // while destructing class metadata objects.
#else
  delete pythonManager;
#endif

  return result;
}
<commit_msg>avoid crash at application shutdown with Ubuntu 14.04's version Qt 4.8.6<commit_after>#include <QApplication>
#include "ddMainWindow.h"
#include "ddPythonManager.h"

#define USE_TDX 0
#if USE_TDX
  #include <QVTKApplication.h>
#endif

int main(int argc, char **argv)
{
#if USE_TDX
  QVTKApplication app(argc, argv);
#else
  QApplication app(argc, argv);
#endif

  ddPythonManager* pythonManager = new ddPythonManager;

  ddMainWindow* window = new ddMainWindow;
  window->setPythonManager(pythonManager);
  window->resize(1800, 1000);
  window->show();

  int result = app.exec();

  delete window;

#ifdef Q_OS_MAC
  // On MacOSX, there is a crash during PythonQt's finalization cleanup
  // while destructing class metadata objects.
#else
  // crashes on Ubuntu 14.04 with Qt version 4.8.6
  // this is a bug in PythonQt's finalize I think, to be investigated
  //delete pythonManager;
#endif

  return result;
}
<|endoftext|>


<commit_before>#include "LineGrid.h"
#include <iostream>

void fillData(float * vertice, glm::vec3 position, glm::vec3 color) {
	vertice[0] = position.x;
	vertice[1] = position.y;
	vertice[2] = position.z;
	vertice[3] = color.x;
	vertice[4] = color.y;
	vertice[5] = color.z;
}

void fillElement(GLuint* elements, int index) {
	elements[index] = index;
}

LineGrid::LineGrid(int xCount, float deltaX, float offsetX, int yCount, float deltaY, float offsetY) :
	Object3D(), lineWidth(1.0f)
{
	int elementCount = (xCount + yCount) * 2;
	int vertexCount = elementCount * 6;
	GLfloat* vertices = new GLfloat[ vertexCount ];

	float endX = offsetX * 2 + deltaX * (xCount - 1);
	float endY = offsetY * 2 + deltaY * (yCount - 1);
	for (int i = 0; i < xCount; i++) {
		float x = offsetX + deltaX * i;
		fillData(&vertices[(i * 2) * 6],	{ x,0.0f,0.0f }, { 0.0f,x/endX,1.0f });	// Start
		fillData(&vertices[(i * 2 +1) * 6],	{ x,endY,0.0f }, { 0.0f,1.0f,1.0f });	// End
	}

	int indexOffset = xCount * 2 * 6;
	int elementIndexOffset = xCount * 2;
	for (int i = 0; i < yCount; i++) {
		float y = offsetY + deltaY * i;
		fillData(&vertices[indexOffset + (i * 2) * 6],		{ 0.0f,y,0.0f }, { 1.0f,y/endY,0.0f });	// Start
		fillData(&vertices[indexOffset + (i * 2 + 1) * 6],	{ endX,y,0.0f }, { 1.0f,1.0f,0.0f });	// End
	}

	GLuint* elements = new GLuint[elementCount];
	for (int i = 0; i < elementCount; i++) {
		elements[i] = i;
	}

	initializeVBO(vertices, vertexCount * sizeof(GLfloat), elements, elementCount * sizeof(GLuint), GL_LINES);

	delete[] vertices;
	delete[] elements;
}

LineGrid::LineGrid( float length, float lineWidth ) : Object3D(), lineWidth(lineWidth)
{
	int elementCount = 18;
	int vertexCount = 12 * 6;
	GLfloat* vertices = new GLfloat[vertexCount];
	GLuint* elements = new GLuint[elementCount];

	float arrowEnd = length * 0.9f;
	float arrowOffset = length * 0.07f;

	// x-Axis
	fillData(&vertices[0], { -length,0.0f,0.0f }, { 1.0,0.0f,0.0f });
	fillData(&vertices[1*6], { length,0.0,0.0f }, { 1.0f,0.0f,0.0f });
	fillData(&vertices[2*6], { arrowEnd,0.0f,arrowOffset }, { 1.0,0.0f,0.0f });
	fillData(&vertices[3*6], { arrowEnd,0.0f,-arrowOffset }, { 1.0f,0.0f,0.0f });

	elements[0] = 0;
	elements[1] = 1;
	elements[2] = 1;
	elements[3] = 2;
	elements[4] = 1;
	elements[5] = 3;

	// y-Axis
	fillData(&vertices[4*6], { 0.0f,-length,0.0f }, { 0.0,1.0f,0.0f });
	fillData(&vertices[5*6], { 0.0f,length,0.0f }, { 0.0f,1.0f,0.0f });
	fillData(&vertices[6*6], { arrowOffset,arrowEnd,0.0f }, { 0.0,1.0f,0.0f });
	fillData(&vertices[7*6], { -arrowOffset,arrowEnd,0.0f }, { 0.0f,1.0f,0.0f });

	elements[6] = 4;
	elements[7] = 5;
	elements[8] = 5;
	elements[9] = 6;
	elements[10] = 5;
	elements[11] = 7;

	// z-Axis
	fillData(&vertices[8*6], { 0.0f,0.0f,-length }, { 0.0,0.0f,1.0f });
	fillData(&vertices[9*6], { 0.0f,0.0f,length }, { 0.0f,0.0f,1.0f });
	fillData(&vertices[10*6], { 0.0f,arrowOffset,arrowEnd }, { 0.0,0.0f,1.0f });
	fillData(&vertices[11*6], { 0.0f,-arrowOffset,arrowEnd }, { 0.0f,0.0f,1.0f });

	elements[12] = 8;
	elements[13] = 9;
	elements[14] = 9;
	elements[15] = 10;
	elements[16] = 9;
	elements[17] = 11;

	initializeVBO(vertices, vertexCount * sizeof(GLfloat), elements, elementCount * sizeof(GLuint), GL_LINES);

	delete[] vertices;
	delete[] elements;
}

LineGrid::~LineGrid()
{
}

void LineGrid::draw(const glm::mat4 & viewProjection)
{
	glLineWidth(lineWidth);
	Object3D::draw(viewProjection);
	glLineWidth(1.0f);
}
<commit_msg>LineGrid formatting.<commit_after>#include "LineGrid.h"
#include <iostream>

void fillData(float * vertice, glm::vec3 position, glm::vec3 color)
{
	vertice[0] = position.x;
	vertice[1] = position.y;
	vertice[2] = position.z;
	vertice[3] = color.x;
	vertice[4] = color.y;
	vertice[5] = color.z;
}

void fillElement(GLuint* elements, int index)
{
	elements[index] = index;
}

LineGrid::LineGrid(int xCount, float deltaX, float offsetX, int yCount, float deltaY, float offsetY) :
	Object3D(), lineWidth(1.0f)
{
	int elementCount = (xCount + yCount) * 2;
	int vertexCount = elementCount * 6;
	GLfloat* vertices = new GLfloat[ vertexCount ];

	float endX = offsetX * 2 + deltaX * (xCount - 1);
	float endY = offsetY * 2 + deltaY * (yCount - 1);
	for (int i = 0; i < xCount; i++) {
		float x = offsetX + deltaX * i;
		fillData(&vertices[(i * 2) * 6],	{ x,0.0f,0.0f }, { 0.0f,x/endX,1.0f });	// Start
		fillData(&vertices[(i * 2 +1) * 6],	{ x,endY,0.0f }, { 0.0f,1.0f,1.0f });	// End
	}

	int indexOffset = xCount * 2 * 6;
	int elementIndexOffset = xCount * 2;
	for (int i = 0; i < yCount; i++) {
		float y = offsetY + deltaY * i;
		fillData(&vertices[indexOffset + (i * 2) * 6],		{ 0.0f,y,0.0f }, { 1.0f,y/endY,0.0f });	// Start
		fillData(&vertices[indexOffset + (i * 2 + 1) * 6],	{ endX,y,0.0f }, { 1.0f,1.0f,0.0f });	// End
	}

	GLuint* elements = new GLuint[elementCount];
	for (int i = 0; i < elementCount; i++) {
		elements[i] = i;
	}

	initializeVBO(vertices, vertexCount * sizeof(GLfloat), elements, elementCount * sizeof(GLuint), GL_LINES);

	delete[] vertices;
	delete[] elements;
}

LineGrid::LineGrid( float length, float lineWidth ) :
	Object3D(), lineWidth(lineWidth)
{
	int elementCount = 18;
	int vertexCount = 12 * 6;
	GLfloat* vertices = new GLfloat[vertexCount];
	GLuint* elements = new GLuint[elementCount];

	float arrowEnd = length * 0.9f;
	float arrowOffset = length * 0.07f;

	// x-Axis
	fillData(&vertices[0], { -length,0.0f,0.0f }, { 1.0,0.0f,0.0f });
	fillData(&vertices[1*6], { length,0.0,0.0f }, { 1.0f,0.0f,0.0f });
	fillData(&vertices[2*6], { arrowEnd,0.0f,arrowOffset }, { 1.0,0.0f,0.0f });
	fillData(&vertices[3*6], { arrowEnd,0.0f,-arrowOffset }, { 1.0f,0.0f,0.0f });

	elements[0] = 0;
	elements[1] = 1;
	elements[2] = 1;
	elements[3] = 2;
	elements[4] = 1;
	elements[5] = 3;

	// y-Axis
	fillData(&vertices[4*6], { 0.0f,-length,0.0f }, { 0.0,1.0f,0.0f });
	fillData(&vertices[5*6], { 0.0f,length,0.0f }, { 0.0f,1.0f,0.0f });
	fillData(&vertices[6*6], { arrowOffset,arrowEnd,0.0f }, { 0.0,1.0f,0.0f });
	fillData(&vertices[7*6], { -arrowOffset,arrowEnd,0.0f }, { 0.0f,1.0f,0.0f });

	elements[6] = 4;
	elements[7] = 5;
	elements[8] = 5;
	elements[9] = 6;
	elements[10] = 5;
	elements[11] = 7;

	// z-Axis
	fillData(&vertices[8*6], { 0.0f,0.0f,-length }, { 0.0,0.0f,1.0f });
	fillData(&vertices[9*6], { 0.0f,0.0f,length }, { 0.0f,0.0f,1.0f });
	fillData(&vertices[10*6], { 0.0f,arrowOffset,arrowEnd }, { 0.0,0.0f,1.0f });
	fillData(&vertices[11*6], { 0.0f,-arrowOffset,arrowEnd }, { 0.0f,0.0f,1.0f });

	elements[12] = 8;
	elements[13] = 9;
	elements[14] = 9;
	elements[15] = 10;
	elements[16] = 9;
	elements[17] = 11;

	initializeVBO(vertices, vertexCount * sizeof(GLfloat), elements, elementCount * sizeof(GLuint), GL_LINES);

	delete[] vertices;
	delete[] elements;
}

LineGrid::~LineGrid()
{
}

void LineGrid::draw(const glm::mat4 & viewProjection)
{
	glLineWidth(lineWidth);
	Object3D::draw(viewProjection);
	glLineWidth(1.0f);
}
<|endoftext|>


<commit_before>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkVtkInteractorCameraController.h"
#include "mitkRenderWindow.h"
#include "mitkVtkRenderWindowInteractor.h"
#include "mitkInteractionConst.h"
#include <vtkInteractorStyleSwitch.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCommand.h>
#include "mitkVtkRenderWindow.h"
#include "mitkAction.h"
#include "mitkOpenGLRenderer.h"

mitk::VtkInteractorCameraController::VtkInteractorCameraController(const char * type) : CameraController(type), m_VtkInteractor(NULL)
{
  m_VtkInteractor = vtkRenderWindowInteractor::New();
  vtkInteractorStyleSwitch* interactorswitch = dynamic_cast<vtkInteractorStyleSwitch*>(m_VtkInteractor->GetInteractorStyle());

  if(interactorswitch!=NULL)
    interactorswitch->SetCurrentStyleToTrackballCamera();
}

mitk::VtkInteractorCameraController::~VtkInteractorCameraController()
{
  m_VtkInteractor->SetRenderWindow(NULL);
  m_VtkInteractor->Delete();
}

void mitk::VtkInteractorCameraController::Resize(int w, int h)
{
  if(m_VtkInteractor)
    m_VtkInteractor->SetSize(w, h);
}

void mitk::VtkInteractorCameraController::MousePressEvent(mitk::MouseEvent *me)
{
  if(m_VtkInteractor)
  {
    if (!m_VtkInteractor->GetEnabled())
    {
      return;
    }
    int ctrl  = me->GetButtonState() & BS_ControlButton;
    int shift = me->GetButtonState() & BS_ShiftButton;
#if ((VTK_MAJOR_VERSION>4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=2)))
    int xp = (int)me->GetDisplayPosition()[0];
    int yp = (int)me->GetDisplayPosition()[1];
    m_VtkInteractor->SetEventInformationFlipY(xp, yp, ctrl, shift);

    switch (me->GetButton())
    {
    case BS_LeftButton:
      m_VtkInteractor->InvokeEvent(vtkCommand::LeftButtonPressEvent,NULL);
      break;
    case BS_MidButton:
      m_VtkInteractor->InvokeEvent(vtkCommand::MiddleButtonPressEvent,NULL);
      break;
    case BS_RightButton:
      m_VtkInteractor->InvokeEvent(vtkCommand::RightButtonPressEvent,NULL);
      break;
    default:
      return;
    }
#else
    if(me->GetButton() & BS_LeftButton)
    {
      //    SetCapture(wnd);
      m_VtkInteractor->InteractorStyle->OnLeftButtonDown(ctrl, shift,
          me->GetDisplayPosition().x, m_VtkInteractor->Size[1] - me->GetDisplayPosition().y - 1);
    }
    else
      if(me->button() & BS_MidButton)
      {
        //    SetCapture(wnd);
        m_VtkInteractor->InteractorStyle->OnMiddleButtonDown(ctrl, shift,
            me->GetDisplayPosition().x, m_VtkInteractor->Size[1] - me->GetDisplayPosition().y - 1);
      }
      else
        if(me->button() & BS_RightButton)
        {
          //    SetCapture(wnd);
          m_VtkInteractor->InteractorStyle->OnRightButtonDown(ctrl, shift,
              me->GetDisplayPosition().x, m_VtkInteractor->Size[1] - me->GetDisplayPosition().y - 1);
        }
#endif

  }
}

void mitk::VtkInteractorCameraController::MouseReleaseEvent(mitk::MouseEvent *me)
{
  if(m_VtkInteractor)
  {
    if (!m_VtkInteractor->GetEnabled())
    {
      return;
    }
    int ctrl  = me->GetButtonState() & BS_ControlButton;
    int shift = me->GetButtonState() & BS_ShiftButton;
#if ((VTK_MAJOR_VERSION>4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=2)))
    int xp = (int)me->GetDisplayPosition()[0];
    int yp = (int)me->GetDisplayPosition()[1];
    m_VtkInteractor->SetEventInformationFlipY(xp, yp, ctrl, shift);

    switch (me->GetButton())
    {
    case BS_LeftButton:
      m_VtkInteractor->InvokeEvent(vtkCommand::LeftButtonReleaseEvent,NULL);
      break;
    case BS_MidButton:
      m_VtkInteractor->InvokeEvent(vtkCommand::MiddleButtonReleaseEvent,NULL);
      break;
    case BS_RightButton:
      m_VtkInteractor->InvokeEvent(vtkCommand::RightButtonReleaseEvent,NULL);
      break;
    default:
      return;
    }
#else
    if(me->button() & BS_LeftButton)
    {
      m_VtkInteractor->InteractorStyle->OnLeftButtonUp(ctrl, shift,
          me->GetDisplayPosition().x, m_VtkInteractor->Size[1] - me->GetDisplayPosition().y - 1);
      //ReleaseCapture( );
    }
    else
      if(me->button() & BS_MidButton)
      {
        m_VtkInteractor->InteractorStyle->OnMiddleButtonUp(ctrl, shift,
            me->GetDisplayPosition().x, m_VtkInteractor->Size[1] - me->GetDisplayPosition().y - 1);
        //ReleaseCapture( );
      }
      else
        if(me->button() & BS_RightButton)
        {
          m_VtkInteractor->InteractorStyle->OnRightButtonUp(ctrl, shift,
              me->GetDisplayPosition().x, m_VtkInteractor->Size[1] - me->GetDisplayPosition().y - 1);
          //ReleaseCapture( );
        }
#endif

  }
}

void mitk::VtkInteractorCameraController::MouseMoveEvent(mitk::MouseEvent *me)
{
  if(m_VtkInteractor)
  {
    if (!m_VtkInteractor->GetEnabled())
    {
      return;
    }
    int ctrl  = me->GetButtonState() & BS_ControlButton;
    int shift = me->GetButtonState() & BS_ShiftButton;
#if ((VTK_MAJOR_VERSION>4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=2)))
    int xp = (int)me->GetDisplayPosition()[0];
    int yp = (int)me->GetDisplayPosition()[1];
    m_VtkInteractor->SetEventInformationFlipY(xp, yp, ctrl, shift);
    m_VtkInteractor->InvokeEvent(vtkCommand::MouseMoveEvent, NULL);
#else
    if (!m_VtkInteractor->MouseInWindow &&
        ((me->GetDisplayPosition().x >= 0) && (me->GetDisplayPosition().x < m_VtkInteractor->Size[0]) && (me->GetDisplayPosition().y >= 0) && (me->GetDisplayPosition().y < m_VtkInteractor->Size[1])))
    {
      m_VtkInteractor->InteractorStyle->OnEnter(ctrl, shift,
          me->GetDisplayPosition().x, m_VtkInteractor->Size[1] - me->GetDisplayPosition().y - 1);
      m_VtkInteractor->MouseInWindow = 1;
    }

    if (m_VtkInteractor->MouseInWindow &&
        ((me->GetDisplayPosition().x < 0) || (me->GetDisplayPosition().x >= m_VtkInteractor->Size[0]) || (me->GetDisplayPosition().y < 0) || (me->GetDisplayPosition().y >= m_VtkInteractor->Size[1])))
    {
      m_VtkInteractor->InteractorStyle->OnLeave(ctrl, shift,
          me->GetDisplayPosition().x, m_VtkInteractor->Size[1] - me->GetDisplayPosition().y - 1);
      m_VtkInteractor->MouseInWindow = 0;
    }

    m_VtkInteractor->InteractorStyle->OnMouseMove(ctrl, shift,
        me->GetDisplayPosition().x, m_VtkInteractor->Size[1] - me->GetDisplayPosition().y - 1);
#endif

  }
}

void mitk::VtkInteractorCameraController::KeyPressEvent(mitk::KeyEvent *ke)
{
  if(m_VtkInteractor)
  {
    if (!m_VtkInteractor->GetEnabled())
    {
      return;
    }
    int ctrl  = ke->state() & BS_ControlButton;
    int shift = ke->state() & BS_ShiftButton;
#if ((VTK_MAJOR_VERSION>4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=2)))
    int xp = ke->x();
    int yp = ke->y();
    m_VtkInteractor->SetEventInformationFlipY(xp, yp, ctrl, shift, (char) tolower(ke->ascii()), 1, (const char *) ke->text());
    m_VtkInteractor->InvokeEvent(vtkCommand::KeyPressEvent, NULL);
    m_VtkInteractor->InvokeEvent(vtkCommand::CharEvent, NULL);
#else
    m_VtkInteractor->InteractorStyle->OnChar(ctrl, shift, (char)ke->ascii(), ke->count());
#endif

  }

}

bool mitk::VtkInteractorCameraController::SetRenderer(mitk::BaseRenderer* renderer)
{
  if (renderer)
  {
    Superclass::SetRenderer(renderer);

    VtkRenderWindowInteractor* windowInteractor =
    dynamic_cast<VtkRenderWindowInteractor*>(m_VtkInteractor);
    if (windowInteractor == NULL)
    {
      itkWarningMacro(<< "renderwindow is not an mitk::VtkRenderWindow");
    }
    else
    {
      windowInteractor->SetMitkRenderer(const_cast<mitk::BaseRenderer*>(this->GetRenderer()));
    }
    m_VtkInteractor->Initialize();
    mitk::OpenGLRenderer* glRenderer = dynamic_cast<mitk::OpenGLRenderer*>(renderer);
    if (glRenderer)
    {
      m_VtkInteractor->SetRenderWindow(glRenderer->GetVtkRenderWindow());
    }
    }
  else
  {
    m_VtkInteractor->Delete();
  }
  return true;
}

vtkRenderWindowInteractor* mitk::VtkInteractorCameraController::GetVtkInteractor()
{
  return m_VtkInteractor;
}

bool mitk::VtkInteractorCameraController::ExecuteAction(Action*, mitk::StateEvent const * /*stateEvent*/)
{
  return false;
}

<commit_msg>BUG The function ExecuteAction() should not be overridden here<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkVtkInteractorCameraController.h"
#include "mitkRenderWindow.h"
#include "mitkVtkRenderWindowInteractor.h"
#include "mitkInteractionConst.h"
#include <vtkInteractorStyleSwitch.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCommand.h>
#include "mitkVtkRenderWindow.h"
#include "mitkAction.h"
#include "mitkOpenGLRenderer.h"

mitk::VtkInteractorCameraController::VtkInteractorCameraController(const char * type) : CameraController(type), m_VtkInteractor(NULL)
{
  m_VtkInteractor = vtkRenderWindowInteractor::New();
  vtkInteractorStyleSwitch* interactorswitch = dynamic_cast<vtkInteractorStyleSwitch*>(m_VtkInteractor->GetInteractorStyle());

  if(interactorswitch!=NULL)
    interactorswitch->SetCurrentStyleToTrackballCamera();
}

mitk::VtkInteractorCameraController::~VtkInteractorCameraController()
{
  m_VtkInteractor->SetRenderWindow(NULL);
  m_VtkInteractor->Delete();
}

void mitk::VtkInteractorCameraController::Resize(int w, int h)
{
  if(m_VtkInteractor)
    m_VtkInteractor->SetSize(w, h);
}

void mitk::VtkInteractorCameraController::MousePressEvent(mitk::MouseEvent *me)
{
  if(m_VtkInteractor)
  {
    if (!m_VtkInteractor->GetEnabled())
    {
      return;
    }
    int ctrl  = me->GetButtonState() & BS_ControlButton;
    int shift = me->GetButtonState() & BS_ShiftButton;
#if ((VTK_MAJOR_VERSION>4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=2)))
    int xp = (int)me->GetDisplayPosition()[0];
    int yp = (int)me->GetDisplayPosition()[1];
    m_VtkInteractor->SetEventInformationFlipY(xp, yp, ctrl, shift);

    switch (me->GetButton())
    {
    case BS_LeftButton:
      m_VtkInteractor->InvokeEvent(vtkCommand::LeftButtonPressEvent,NULL);
      break;
    case BS_MidButton:
      m_VtkInteractor->InvokeEvent(vtkCommand::MiddleButtonPressEvent,NULL);
      break;
    case BS_RightButton:
      m_VtkInteractor->InvokeEvent(vtkCommand::RightButtonPressEvent,NULL);
      break;
    default:
      return;
    }
#else
    if(me->GetButton() & BS_LeftButton)
    {
      //    SetCapture(wnd);
      m_VtkInteractor->InteractorStyle->OnLeftButtonDown(ctrl, shift,
          me->GetDisplayPosition().x, m_VtkInteractor->Size[1] - me->GetDisplayPosition().y - 1);
    }
    else
      if(me->button() & BS_MidButton)
      {
        //    SetCapture(wnd);
        m_VtkInteractor->InteractorStyle->OnMiddleButtonDown(ctrl, shift,
            me->GetDisplayPosition().x, m_VtkInteractor->Size[1] - me->GetDisplayPosition().y - 1);
      }
      else
        if(me->button() & BS_RightButton)
        {
          //    SetCapture(wnd);
          m_VtkInteractor->InteractorStyle->OnRightButtonDown(ctrl, shift,
              me->GetDisplayPosition().x, m_VtkInteractor->Size[1] - me->GetDisplayPosition().y - 1);
        }
#endif

  }
}

void mitk::VtkInteractorCameraController::MouseReleaseEvent(mitk::MouseEvent *me)
{
  if(m_VtkInteractor)
  {
    if (!m_VtkInteractor->GetEnabled())
    {
      return;
    }
    int ctrl  = me->GetButtonState() & BS_ControlButton;
    int shift = me->GetButtonState() & BS_ShiftButton;
#if ((VTK_MAJOR_VERSION>4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=2)))
    int xp = (int)me->GetDisplayPosition()[0];
    int yp = (int)me->GetDisplayPosition()[1];
    m_VtkInteractor->SetEventInformationFlipY(xp, yp, ctrl, shift);

    switch (me->GetButton())
    {
    case BS_LeftButton:
      m_VtkInteractor->InvokeEvent(vtkCommand::LeftButtonReleaseEvent,NULL);
      break;
    case BS_MidButton:
      m_VtkInteractor->InvokeEvent(vtkCommand::MiddleButtonReleaseEvent,NULL);
      break;
    case BS_RightButton:
      m_VtkInteractor->InvokeEvent(vtkCommand::RightButtonReleaseEvent,NULL);
      break;
    default:
      return;
    }
#else
    if(me->button() & BS_LeftButton)
    {
      m_VtkInteractor->InteractorStyle->OnLeftButtonUp(ctrl, shift,
          me->GetDisplayPosition().x, m_VtkInteractor->Size[1] - me->GetDisplayPosition().y - 1);
      //ReleaseCapture( );
    }
    else
      if(me->button() & BS_MidButton)
      {
        m_VtkInteractor->InteractorStyle->OnMiddleButtonUp(ctrl, shift,
            me->GetDisplayPosition().x, m_VtkInteractor->Size[1] - me->GetDisplayPosition().y - 1);
        //ReleaseCapture( );
      }
      else
        if(me->button() & BS_RightButton)
        {
          m_VtkInteractor->InteractorStyle->OnRightButtonUp(ctrl, shift,
              me->GetDisplayPosition().x, m_VtkInteractor->Size[1] - me->GetDisplayPosition().y - 1);
          //ReleaseCapture( );
        }
#endif

  }
}

void mitk::VtkInteractorCameraController::MouseMoveEvent(mitk::MouseEvent *me)
{
  if(m_VtkInteractor)
  {
    if (!m_VtkInteractor->GetEnabled())
    {
      return;
    }
    int ctrl  = me->GetButtonState() & BS_ControlButton;
    int shift = me->GetButtonState() & BS_ShiftButton;
#if ((VTK_MAJOR_VERSION>4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=2)))
    int xp = (int)me->GetDisplayPosition()[0];
    int yp = (int)me->GetDisplayPosition()[1];
    m_VtkInteractor->SetEventInformationFlipY(xp, yp, ctrl, shift);
    m_VtkInteractor->InvokeEvent(vtkCommand::MouseMoveEvent, NULL);
#else
    if (!m_VtkInteractor->MouseInWindow &&
        ((me->GetDisplayPosition().x >= 0) && (me->GetDisplayPosition().x < m_VtkInteractor->Size[0]) && (me->GetDisplayPosition().y >= 0) && (me->GetDisplayPosition().y < m_VtkInteractor->Size[1])))
    {
      m_VtkInteractor->InteractorStyle->OnEnter(ctrl, shift,
          me->GetDisplayPosition().x, m_VtkInteractor->Size[1] - me->GetDisplayPosition().y - 1);
      m_VtkInteractor->MouseInWindow = 1;
    }

    if (m_VtkInteractor->MouseInWindow &&
        ((me->GetDisplayPosition().x < 0) || (me->GetDisplayPosition().x >= m_VtkInteractor->Size[0]) || (me->GetDisplayPosition().y < 0) || (me->GetDisplayPosition().y >= m_VtkInteractor->Size[1])))
    {
      m_VtkInteractor->InteractorStyle->OnLeave(ctrl, shift,
          me->GetDisplayPosition().x, m_VtkInteractor->Size[1] - me->GetDisplayPosition().y - 1);
      m_VtkInteractor->MouseInWindow = 0;
    }

    m_VtkInteractor->InteractorStyle->OnMouseMove(ctrl, shift,
        me->GetDisplayPosition().x, m_VtkInteractor->Size[1] - me->GetDisplayPosition().y - 1);
#endif

  }
}

void mitk::VtkInteractorCameraController::KeyPressEvent(mitk::KeyEvent *ke)
{
  if(m_VtkInteractor)
  {
    if (!m_VtkInteractor->GetEnabled())
    {
      return;
    }
    int ctrl  = ke->state() & BS_ControlButton;
    int shift = ke->state() & BS_ShiftButton;
#if ((VTK_MAJOR_VERSION>4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=2)))
    int xp = ke->x();
    int yp = ke->y();
    m_VtkInteractor->SetEventInformationFlipY(xp, yp, ctrl, shift, (char) tolower(ke->ascii()), 1, (const char *) ke->text());
    m_VtkInteractor->InvokeEvent(vtkCommand::KeyPressEvent, NULL);
    m_VtkInteractor->InvokeEvent(vtkCommand::CharEvent, NULL);
#else
    m_VtkInteractor->InteractorStyle->OnChar(ctrl, shift, (char)ke->ascii(), ke->count());
#endif

  }

}

bool mitk::VtkInteractorCameraController::SetRenderer(mitk::BaseRenderer* renderer)
{
  if (renderer)
  {
    Superclass::SetRenderer(renderer);

    VtkRenderWindowInteractor* windowInteractor =
    dynamic_cast<VtkRenderWindowInteractor*>(m_VtkInteractor);
    if (windowInteractor == NULL)
    {
      itkWarningMacro(<< "renderwindow is not an mitk::VtkRenderWindow");
    }
    else
    {
      windowInteractor->SetMitkRenderer(const_cast<mitk::BaseRenderer*>(this->GetRenderer()));
    }
    m_VtkInteractor->Initialize();
    mitk::OpenGLRenderer* glRenderer = dynamic_cast<mitk::OpenGLRenderer*>(renderer);
    if (glRenderer)
    {
      m_VtkInteractor->SetRenderWindow(glRenderer->GetVtkRenderWindow());
    }
    }
  else
  {
    m_VtkInteractor->Delete();
  }
  return true;
}

vtkRenderWindowInteractor* mitk::VtkInteractorCameraController::GetVtkInteractor()
{
  return m_VtkInteractor;
}

///*
//bool mitk::VtkInteractorCameraController::ExecuteAction(Action*, mitk::StateEvent const * /*stateEvent*/)
//{
//  return false;
//}
//*/
<|endoftext|>


<commit_before>#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/core.hpp"
#include <stdio.h>
#include <cv.h>
#include <highgui.h>

CvHaarClassifierCascade *cascade;
CvMemStorage            *storage;

void detect(IplImage *img);

int main(int argc, char** argv)
{
  CvCapture *capture;
  IplImage  *frame;
  int input_resize_percent = 100;

  if(argc < 3)
  {
    std::cout << "Usage " << argv[0] << " path_to_cars3.xml path_to_video.avi" << std::endl;
    return 0;
  }

  if(argc == 4)
  {
    input_resize_percent = atoi(argv[3]);
    std::cout << "Resizing to: " << input_resize_percent << "%" << std::endl;
  }

  cascade = (CvHaarClassifierCascade*) cvLoad(argv[1], 0, 0, 0);
  storage = cvCreateMemStorage(0);
  capture = cvCaptureFromAVI(argv[2]);

  assert(cascade && storage && capture);

  cvNamedWindow("video", 1);

  IplImage* frame1 = cvQueryFrame(capture);
  frame = cvCreateImage(cvSize((int)((frame1->width*input_resize_percent)/100) , (int)((frame1->height*input_resize_percent)/100)), frame1->depth, frame1->nChannels);

  const int KEY_SPACE  = 32;
  const int KEY_ESC    = 27;

  int key = 0;
  do
  {
    frame1 = cvQueryFrame(capture);

    if(!frame1)
      break;

    cvResize(frame1, frame);

    detect(frame);

    key = cvWaitKey(10);

    if(key == KEY_SPACE)
      key = cvWaitKey(0);

    if(key == KEY_ESC)
      break;

  }while(1);

  cvDestroyAllWindows();
  cvReleaseImage(&frame);
  cvReleaseCapture(&capture);
  cvReleaseHaarClassifierCascade(&cascade);
  cvReleaseMemStorage(&storage);

  return 0;
}

void detect(IplImage *img)
{
  cv::Mat img_mat(img);
  // Create ROI to desired area
  imshow("original frame", img_mat);
  // cv::Mat roi_image = img_mat(cv::Rect(img_mat.cols*1/2.6,img_mat.rows*1/3.5,img_mat.cols - img_mat.cols/2.6,img_mat.rows*2/3.1));
  // imshow("roi_image",roi_image);
  // std::cout << "img_mat.cols" << img_mat.cols << std::endl;

  // IplImage ipl_img = img_mat;

  cvSetImageROI(img, cvRect(img->width*1/2.6, img->height*1/3.5, img->width - img->width*1/2.6, img->height*2/3.1));
  IplImage *img2 = cvCreateImage(cvGetSize(img),
                           img->depth,
                           img->nChannels);

  // std::cout << "img->width" << img->width << std::endl;

  cvCopy(img, img2, NULL);
  cvResetImageROI(img);

  CvSize img_size = cvGetSize(img2);
  CvSeq *object = cvHaarDetectObjects(
    img2,
    cascade,
    storage,
    1.1, //1.1,//1.5, //-------------------SCALE FACTOR
    1, //2        //------------------MIN NEIGHBOURS
    0, //CV_HAAR_DO_CANNY_PRUNING
    cvSize(0,0),//cvSize( 30,30), // ------MINSIZE
    img_size //cvSize(70,70)//cvSize(640,480)  //---------MAXSIZE
    );

  std::cout << "Total: " << object->total << " cars" << std::endl;
  for(int i = 0 ; i < ( object ? object->total : 0 ) ; i++)
  {
    CvRect *r = (CvRect*)cvGetSeqElem(object, i);
    cvRectangle(img2,
      cvPoint(r->x, r->y),
      cvPoint(r->x + r->width, r->y + r->height),
      CV_RGB(255, 0, 0), 2, 8, 0);
  }

  cvShowImage("ROI", img2);
  cvWaitKey(0);
}<commit_msg>Haarcascade: write found cars to .txt file<commit_after>#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/core.hpp"
#include <stdio.h>
#include <cv.h>
#include <highgui.h>
#include <sstream>
#include <fstream>

CvHaarClassifierCascade *cascade;
CvMemStorage            *storage;

void detect(IplImage *img, char** argv, int frame_number);

int main(int argc, char** argv)
{
  CvCapture *capture;
  IplImage  *frame;
  int input_resize_percent = 100;

  if(argc < 3)
  {
    std::cout << "Usage " << argv[0] << " path_to_cars3.xml path_to_video.avi" << std::endl;
    return 0;
  }

  if(argc == 4)
  {
    input_resize_percent = atoi(argv[3]);
    std::cout << "Resizing to: " << input_resize_percent << "%" << std::endl;
  }

  cascade = (CvHaarClassifierCascade*) cvLoad(argv[1], 0, 0, 0);
  storage = cvCreateMemStorage(0);
  capture = cvCaptureFromAVI(argv[2]);

  assert(cascade && storage && capture);

  //cvNamedWindow("video", 1);

  IplImage* frame1 = cvQueryFrame(capture);
  frame = cvCreateImage(cvSize((int)((frame1->width*input_resize_percent)/100) , (int)((frame1->height*input_resize_percent)/100)), frame1->depth, frame1->nChannels);

  const int KEY_SPACE  = 32;
  const int KEY_ESC    = 27;

  int frame_number = 0;

  int key = 0;
  do
  {
    frame1 = cvQueryFrame(capture);

    if(!frame1)
      break;

    cvResize(frame1, frame);

    detect(frame, argv, frame_number);
    frame_number++;

    key = cvWaitKey(10);

    if(key == KEY_SPACE)
      key = cvWaitKey(0);

    if(key == KEY_ESC)
      break;

  }while(1);

  cvDestroyAllWindows();
  cvReleaseImage(&frame);
  cvReleaseCapture(&capture);
  cvReleaseHaarClassifierCascade(&cascade);
  cvReleaseMemStorage(&storage);

  return 0;
}

void detect(IplImage *img, char** argv, int frame_number)
{

  std::ofstream detected_cars_datafile;
  std::string detected_cars_filename;
  detected_cars_filename = argv[2];
  detected_cars_filename.erase(0,detected_cars_filename.find_last_of("/")+1);
  detected_cars_filename += ".txt";
  std::cout << "cars file name: " << detected_cars_filename << std::endl;
  detected_cars_datafile.open (detected_cars_filename.c_str(), std::ios::app);

  // cv::Mat implementation to debug ROI and also show original image
  cv::Mat img_mat(img);
  // Create ROI to desired area
  imshow("original frame", img_mat);
  // cv::Mat roi_image = img_mat(cv::Rect(img_mat.cols*1/2.6,img_mat.rows*1/3.5,img_mat.cols - img_mat.cols/2.6,img_mat.rows*2/3.1));
  // imshow("roi_image",roi_image);

  // IplImage ipl_img = img_mat;

  cvSetImageROI(img, cvRect(img->width*1/2.6, img->height*1/3.5, img->width - img->width*1/2.6, img->height*2/3.1));
  IplImage *img2 = cvCreateImage(cvGetSize(img),
                           img->depth,
                           img->nChannels);

  // std::cout << "img->width" << img->width << std::endl;

  cvCopy(img, img2, NULL);
  cvResetImageROI(img);

  CvSize img_size = cvGetSize(img2);
  CvSeq *object = cvHaarDetectObjects(
    img2,
    cascade,
    storage,
    1.1, //1.1,//1.5, //-------------------SCALE FACTOR
    1, //2        //------------------MIN NEIGHBOURS
    0, //CV_HAAR_DO_CANNY_PRUNING
    cvSize(0,0),//cvSize( 30,30), // ------MINSIZE
    img_size //cvSize(70,70)//cvSize(640,480)  //---------MAXSIZE
    );

  std::cout << "Total: " << object->total << " cars" << std::endl;
  for(int i = 0 ; i < ( object ? object->total : 0 ) ; i++)
  {
    CvRect *r = (CvRect*)cvGetSeqElem(object, i);
    cvRectangle(img2,
      cvPoint(r->x, r->y),
      cvPoint(r->x + r->width, r->y + r->height),
      CV_RGB(255, 0, 0), 2, 8, 0);

    // write rectangles to file
    detected_cars_datafile << frame_number << ";" << r->x << ";" << r->y << ";" << r->x + r->width << ";" << r->y + r->height << ";" << std::endl;
  }

  detected_cars_datafile.close();

  cvShowImage("ROI", img2);
  cvWaitKey(0);
}<|endoftext|>


<commit_before>#include "TATUInterpreter.h"

void TATUInterpreter::Interpreter(unsigned char *string, unsigned int length){
    int i;

    switch(string[0]){
        case COMMAND_SET:
            cmd.OBJ.TYPE = TATU_SET;

            if(string[4] == CODE_INFO){
                cmd.OBJ.CODE = TATU_CODE_INFO;
                // Not implemented yet
            }
            else if(string[4] == CODE_STATE){
                cmd.OBJ.CODE = TATU_CODE_STATE;
                cmd.OBJ.PIN = ((unsigned int) string[10]) - 49;
                cmd.OBJ.STATE = ((unsigned int) string[12]) - 49;
            }
            else break;

            ERROR = false;
            return;
        case cmd_GET:
            cmd.OBJ.TYPE = TATU_GET;

            if(string[4] == CODE_ALL){
                cmd.OBJ.CODE = TATU_CODE_ALL;
            }
            else if(string[4] == CODE_INFO){
                cmd.OBJ.CODE = TATU_CODE_INFO;
                // Not implemented yet
            }
            else if(string[4] == CODE_STATE){
                cmd.OBJ.CODE = TATU_CODE_STATE;
                cmd.OBJ.PIN = ((unsigned int) string[9]) - 49;
            }
            else break;

            ERROR = false;
            return;
        case cmd_EDIT:
            cmd.OBJ.TYPE = TATU_EDIT;
            if(string[5] == CODE_INFO){
                cmd.OBJ.CODE = TATU_CODE_INFO;
                // Not implemented yet
            }
            else if(string[5] == CODE_STATE){
                cmd.OBJ.CODE = TATU_CODE_STATE;
                cmd.OBJ.PIN = ((unsigned int) string[11]) - 49;
                cmd.OBJ.STATE = ((unsigned int) string[13]) - 49;
            }
            else break;

            ERROR = false;
            return;
        case cmd_POST:
            cmd.OBJ.TYPE = TATU_POST;
            ERROR = false;
            return;
    }

    ERROR = true;
}
bool TATUInterpreter::getERROR(){
    return ERROR;
}
<commit_msg>A little change<commit_after>#include "TATUInterpreter.h"

void TATUInterpreter::Interpreter(unsigned char *string, unsigned int length){
    switch(string[0]){
        case COMMAND_SET:
            cmd.OBJ.TYPE = TATU_SET;

            if(string[4] == CODE_INFO){
                cmd.OBJ.CODE = TATU_CODE_INFO;
                // Not implemented yet
            }
            else if(string[4] == CODE_STATE){
                cmd.OBJ.CODE = TATU_CODE_STATE;
                cmd.OBJ.PIN = ((unsigned int) string[10]) - 49;
                cmd.OBJ.STATE = ((unsigned int) string[12]) - 49;
            }
            else break;

            ERROR = false;
            return;
        case cmd_GET:
            cmd.OBJ.TYPE = TATU_GET;

            if(string[4] == CODE_ALL){
                cmd.OBJ.CODE = TATU_CODE_ALL;
            }
            else if(string[4] == CODE_INFO){
                cmd.OBJ.CODE = TATU_CODE_INFO;
                // Not implemented yet
            }
            else if(string[4] == CODE_STATE){
                cmd.OBJ.CODE = TATU_CODE_STATE;
                cmd.OBJ.PIN = ((unsigned int) string[9]) - 49;
            }
            else break;

            ERROR = false;
            return;
        case cmd_EDIT:
            cmd.OBJ.TYPE = TATU_EDIT;
            if(string[5] == CODE_INFO){
                cmd.OBJ.CODE = TATU_CODE_INFO;
                // Not implemented yet
            }
            else if(string[5] == CODE_STATE){
                cmd.OBJ.CODE = TATU_CODE_STATE;
                cmd.OBJ.PIN = ((unsigned int) string[11]) - 49;
                cmd.OBJ.STATE = ((unsigned int) string[13]) - 49;
            }
            else break;

            ERROR = false;
            return;
        case cmd_POST:
            cmd.OBJ.TYPE = TATU_POST;
            ERROR = false;
            return;
    }

    ERROR = true;
}

bool TATUInterpreter::getERROR(){
    return ERROR;
}
<|endoftext|>