<commit_before>#include <iostream>

#ifdef ENABLE_AUDIO
#include "SDL_mixer.h"
#endif

#include "misc/audiomanager.h"
#include "resources/resourcemanager.h"

namespace Zabbr {
	#ifdef ENABLE_AUDIO
	/**
	 * Callback called when a channel stops playing.
	 *
	 * @param channel
	*/
	void onFinishChannel(int channel) {
		// We can not free the resource here
		// Chances are that it is freed by the resource manager
		// and we can't call SDL_Mixer function in this callback...
		// (according to SDL_Mixer docs)
		AudioManager::get().fFreedResources.push_back(AudioManager::get().fSoundResources[channel]);
		AudioManager::get().fSoundResources[channel] = 0;
	}
	#endif

	/**
	 * Constructor.
	*/
	AudioManager::AudioManager(): fMuted(false), fPlayMusic(false) {
		#ifdef ENABLE_AUDIO
		//Mix_Init(MIX_INIT_OGG);
		int error = Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 4096);
		if (error != 0) {
			std::cerr << "Could not load audio: " << Mix_GetError() << std::endl;
		}
		Mix_ChannelFinished(&onFinishChannel);
		#endif
	}

	AudioManager::~AudioManager() {
		#ifdef ENABLE_AUDIO
		freeResources();
		Mix_CloseAudio();
		#endif
		//Mix_Quit();
	}

	void AudioManager::playQueue() {
		#ifdef ENABLE_AUDIO
		if (!Mix_PlayingMusic() && fPlayMusic && fMusicResources.size() > 0) {
			fMusicResources[rand() % fMusicResources.size()]->play();
		}
		#endif
	}

	void AudioManager::addMusicFile(std::string file) {
		#ifdef ENABLE_AUDIO
		fMusicResources.push_back(ResourceManager::manager().music(file));
		#endif
	}

	void AudioManager::startMusic() {
		#ifdef ENABLE_AUDIO
		fPlayMusic = true;
		#endif
	}

	void AudioManager::stopMusic() {
		#ifdef ENABLE_AUDIO
		fPlayMusic = false;
		Mix_HaltMusic();
		#endif
	}

	/**
	 * Plays an audio file.
	 *
	 * @param fName The name of the audio file
	 * @param repeat How many times it should be repeated (-1 indefenitely)
	*/
	void AudioManager::play(std::string fName, int repeat) {
		#ifdef ENABLE_AUDIO
		if (! fMuted) {
			freeResources();
			SoundResource* sound = ResourceManager::manager().sound(fName);
			int ch = sound->play(repeat);
			if (ch != -1) {
				fSoundResources[ch] = sound;
			}
		}
		#endif
	}

	/**
	 * Mute all sounds. It will also stop playing all sounds and free them.
	 * When you unmute all channels will have stopped.
	*/
	void AudioManager::mute() {
		#ifdef ENABLE_AUDIO
		Mix_HaltChannel(-1);
		fMuted = true;
		freeResources();
		#endif
	}

	/**
	 * Unmute all sounds.
	*/
	void AudioManager::unmute() {
		fMuted = false;
	}

	/**
	 * Close the audio manager, this should be called before
	 * SDL is unitialized.
	*/
	void AudioManager::close() {
		delete fkAudioManager;
		fkAudioManager = 0;
	}

	/**
	 * Returns an instance of the audio manager.
	 *
	 * @return An instance (the only current one) of the audio manager.
	*/
	AudioManager& AudioManager::get() {
		if (fkAudioManager == 0) {
			fkAudioManager = new AudioManager();
		}
		return *fkAudioManager;
	}

	/**
	 * Free all outstanding resources in the audio manager.
	*/
	void AudioManager::freeResources() {
		#ifdef ENABLE_AUDIO
		for(std::vector<SoundResource*>::iterator it = fFreedResources.begin(); it != fFreedResources.end(); it++) {
			ResourceManager::manager().free(*it);
		}
		fFreedResources.clear();

		for(std::vector<MusicResource*>::iterator it = fMusicResources.begin(); it != fMusicResources.end(); it++) {
			ResourceManager::manager().free(*it);
		}
		fMusicResources.clear();
		#endif
	}

	AudioManager* AudioManager::fkAudioManager = 0;
}
<commit_msg>Play songs for bullets and clusterbombs<commit_after>#include <iostream>

#ifdef ENABLE_AUDIO
#include "SDL_mixer.h"
#endif

#include "misc/audiomanager.h"
#include "resources/resourcemanager.h"

namespace Zabbr {
	#ifdef ENABLE_AUDIO
	/**
	 * Callback called when a channel stops playing.
	 *
	 * @param channel
	*/
	void onFinishChannel(int channel) {
		// We can not free the resource here
		// Chances are that it is freed by the resource manager
		// and we can't call SDL_Mixer function in this callback...
		// (according to SDL_Mixer docs)
		AudioManager::get().fFreedResources.push_back(AudioManager::get().fSoundResources[channel]);
		AudioManager::get().fSoundResources[channel] = 0;
	}
	#endif

	/**
	 * Constructor.
	*/
	AudioManager::AudioManager(): fMuted(false), fPlayMusic(false) {
		#ifdef ENABLE_AUDIO
		//Mix_Init(MIX_INIT_OGG);
		int error = Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 2048);
		if (error != 0) {
			std::cerr << "Could not load audio: " << Mix_GetError() << std::endl;
		}
		Mix_ChannelFinished(&onFinishChannel);
		#endif
	}

	AudioManager::~AudioManager() {
		#ifdef ENABLE_AUDIO
		freeResources();
		Mix_CloseAudio();
		#endif
		//Mix_Quit();
	}

	void AudioManager::playQueue() {
		#ifdef ENABLE_AUDIO
		if (!Mix_PlayingMusic() && fPlayMusic && fMusicResources.size() > 0) {
			fMusicResources[rand() % fMusicResources.size()]->play();
		}
		#endif
	}

	void AudioManager::addMusicFile(std::string file) {
		#ifdef ENABLE_AUDIO
		fMusicResources.push_back(ResourceManager::manager().music(file));
		#endif
	}

	void AudioManager::startMusic() {
		#ifdef ENABLE_AUDIO
		fPlayMusic = true;
		#endif
	}

	void AudioManager::stopMusic() {
		#ifdef ENABLE_AUDIO
		fPlayMusic = false;
		Mix_HaltMusic();
		#endif
	}

	/**
	 * Plays an audio file.
	 *
	 * @param fName The name of the audio file
	 * @param repeat How many times it should be repeated (-1 indefenitely)
	*/
	void AudioManager::play(std::string fName, int repeat) {
		#ifdef ENABLE_AUDIO
		if (! fMuted) {
			freeResources();
			SoundResource* sound = ResourceManager::manager().sound(fName);
			int ch = sound->play(repeat);
			if (ch != -1) {
				fSoundResources[ch] = sound;
			}
		}
		#endif
	}

	/**
	 * Mute all sounds. It will also stop playing all sounds and free them.
	 * When you unmute all channels will have stopped.
	*/
	void AudioManager::mute() {
		#ifdef ENABLE_AUDIO
		Mix_HaltChannel(-1);
		fMuted = true;
		freeResources();
		#endif
	}

	/**
	 * Unmute all sounds.
	*/
	void AudioManager::unmute() {
		fMuted = false;
	}

	/**
	 * Close the audio manager, this should be called before
	 * SDL is unitialized.
	*/
	void AudioManager::close() {
		delete fkAudioManager;
		fkAudioManager = 0;
	}

	/**
	 * Returns an instance of the audio manager.
	 *
	 * @return An instance (the only current one) of the audio manager.
	*/
	AudioManager& AudioManager::get() {
		if (fkAudioManager == 0) {
			fkAudioManager = new AudioManager();
		}
		return *fkAudioManager;
	}

	/**
	 * Free all outstanding resources in the audio manager.
	*/
	void AudioManager::freeResources() {
		#ifdef ENABLE_AUDIO
		for(std::vector<SoundResource*>::iterator it = fFreedResources.begin(); it != fFreedResources.end(); it++) {
			ResourceManager::manager().free(*it);
		}
		fFreedResources.clear();

		for(std::vector<MusicResource*>::iterator it = fMusicResources.begin(); it != fMusicResources.end(); it++) {
			ResourceManager::manager().free(*it);
		}
		fMusicResources.clear();
		#endif
	}

	AudioManager* AudioManager::fkAudioManager = 0;
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/hwpf/fapi2/include/target_states.H $               */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2012,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/**
 * @file target_states.H
 * @brief common state for fapi2 targets
 */

#ifndef __FAPI2_TARGET_STATES__
#define __FAPI2_TARGET_STATES__

namespace fapi2
{
    ///
    /// @brief Enumeration of target state values (bitmask values)
    ///
    enum TargetState
    {
        TARGET_STATE_PRESENT    = 0x00000001,
        TARGET_STATE_FUNCTIONAL = 0x00000002,
    };
}

#endif
<commit_msg>Fix all incorrect copyright prologs<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/hwpf/fapi2/include/target_states.H $               */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2012,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/**
 * @file target_states.H
 * @brief common state for fapi2 targets
 */

#ifndef __FAPI2_TARGET_STATES__
#define __FAPI2_TARGET_STATES__

namespace fapi2
{
///
/// @brief Enumeration of target state values (bitmask values)
///
enum TargetState
{
    TARGET_STATE_PRESENT    = 0x00000001,
    TARGET_STATE_FUNCTIONAL = 0x00000002,
};
}

#endif
<|endoftext|>


<commit_before><commit_msg>planning: changed sidepass dispatch in scenario manager.<commit_after><|endoftext|>


<commit_before>#include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cassert>
#define DSET_SIZE 64

// https://en.wikipedia.org/wiki/Disjoint-set_data_structure
// run it as:
// g++ disjoint_set.cpp -o disjoint_set && ./disjoint_set | dot -Tpng > /tmp/dot_image.png && eog /tmp/dot_image.png
// where eog is your picture viewer.

struct ListNode {
  int val;
  int len;
  ListNode * parent;
};

class DisjointSet {
  public:
    DisjointSet() {
      alloc_size = DSET_SIZE;
      array = new ListNode*[alloc_size]();
      for (int i=0; i<alloc_size; ++i) {
        assert(array[i]==NULL);
      }
      set_size = 0;
    }

    ListNode * Find(int x) {
      assert(x<alloc_size);
      ListNode * node = array[x];
      while (node != node->parent) {
        node = node->parent;
      }
      return node;
    }

    // This variant keeps the tree flat.
    // It's still incomplete.
    ListNode * Find2(int x) {
      assert(x<alloc_size);
      ListNode * node = array[x];
      if (node != node->parent) {
        node->parent = Find2(node->parent->val);
        // A child attached to the root has len==1.
        node->len = 1;
      }
      // TODO how do you determine the new len at the root?
      // It's not necessarily 2, as you might start searching the list from the
      // middle, then attaching directly to the root only the nodes above that
      // point, but not the ones below it.
      return node->parent;
    }

    // This version tries to determine the new len at the root.
    // TODO: It doesn't work, as you might compress one branch up to the root, but
    // there might still be another branch for the same root that is longer.
    // Then you cannot infer from the compressed branch only if the len from
    // the root has changed or not.
    ListNode * Find3(int x) {
      assert(x<alloc_size);
      ListNode * node = array[x];
      int node_compressed = 0;
      if (node != node->parent) {
        ListNode * parent = InternalFind3(node->parent->val, node_compressed);
        node->parent = parent;
        // A child attached to the root has len==1.
        node->len = 1;
      }
      if (node_compressed > 0) {
        node->len -= node_compressed;
      }
      return node;
    }

    bool Union(int x, int y) {
      assert(x<alloc_size);
      assert(y<alloc_size);
      ListNode * root_x = Find(x);
      ListNode * root_y = Find(y);
      if (root_x->val != root_y->val) {
        // merge them
        if (root_x->len > root_y->len) {
          root_y->parent = root_x;
          // root_x->len unchanged as root_y->len is shorter than
          // root_x->len, then this doesn't increase the longest path
          // from root_x to any of its leaves.
        } else if (root_y->len > root_x->len) {
          root_x->parent = root_y;
          // root_y->len doesn't change for the same reasons as above.
        } else {
          // root_x->len == root_y->len
          root_x->parent = root_y;
          root_y->len += 1;
        }
        //root_x->parent = root_y;
        set_size -= 1;
        return true;
      }
      return false;
    }

    void MakeSet(int x) {
      assert(x<alloc_size);
      if (array[x]!=NULL) return;
      ListNode * node = new ListNode;
      node->val = x;
      node->len = 1;
      node->parent = node;
      array[x] = node;
      set_size += 1;
      return;
    }

    std::string toDot() {
      std::ostringstream out;
      bool * visited = new bool[alloc_size];
      for (int i=0; i<alloc_size; ++i) visited[i] = false;

      out << "digraph DisjointSet {\n";
      for (int i=0; i<alloc_size; ++i) {
        ListNode * node = array[i];
        while (node != node->parent && !visited[node->val]) {
          out << node->val << " -> " << node->parent->val << ";\n";
          visited[node->val] = true;
          //visited[node->parent->val] = true;
          node = node->parent;
        }
      }
      for (int i=0; i<alloc_size; ++i) {
        ListNode * node = array[i];
        if (!visited[node->val]) {
          out << node->val << ";\n";
          visited[node->val] = true;
        }
        out << node->val << "[label=\"" << node->val <<
                            " len=" << node->len <<
                            "\"];\n";
      }
      delete[] visited;
      out << "}";
      return out.str();
    }

    int size() {
      return set_size;
    }

  private:
    // As explained above this is not working at the moment.
    ListNode * InternalFind3(int x, int & node_compressed) {
      assert(x<alloc_size);
      ListNode * node = array[x];
      if (node != node->parent) {
        node_compressed += 1;
        node->parent = InternalFind3(node->parent->val, node_compressed);
        // A child attached to the root has len==1.
        node->len = 1;
      }
      // TODO how do you determine the new len at the root?
      // It's not necessarily 2, as you might start searching the list from the
      // middle, then attaching directly to the root only the nodes above that
      // point, but not the ones below it.
      return node->parent;
    }

    ListNode ** array;
    size_t set_size;
    size_t alloc_size;
};

int main(int argc, char *argv[]) {
  DisjointSet ds;
  for (int set_number=0; set_number<DSET_SIZE; ++set_number) {
    ds.MakeSet(set_number);
  }
  srand(123);
  int unions = 0;
  int attempts = 0;
  while (ds.size() > 1) {
    // generate random couples and do Union operations, up to when there is
    // only a single set left.
    int x = rand() % DSET_SIZE;
    int y = rand() % DSET_SIZE;
    if (ds.Union(x,y)) {
      unions += 1;
    } else {
      attempts += 1;
    }
    //std::cout << ds.toDot() << std::endl;
  }
  std::cerr << "unions=" << unions << ", attempts=" << attempts << std::endl;
  std::cout << ds.toDot() << std::endl;
  return 0;
}
<commit_msg>Implemented optimization based on tree size and path compression.<commit_after>#include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cassert>
#define DSET_SIZE 64

// https://en.wikipedia.org/wiki/Disjoint-set_data_structure
// run it as:
// g++ disjoint_set.cpp -o disjoint_set && ./disjoint_set | dot -Tpng > /tmp/dot_image.png && eog /tmp/dot_image.png
// where eog is your picture viewer.

struct ListNode {
  int val;
  int subtree_size;
  ListNode * parent;
};

class DisjointSet {
  public:
    DisjointSet() {
      alloc_size = DSET_SIZE;
      array = new ListNode*[alloc_size]();
      for (int i=0; i<alloc_size; ++i) {
        assert(array[i]==NULL);
      }
      set_size = 0;
    }

    ListNode * Find(int x) {
      assert(x<alloc_size);
      ListNode * node = array[x];
      while (node != node->parent) {
        node = node->parent;
      }
      return node;
    }

    // This variant keeps the tree flat applying path compression.
    ListNode * Find2(int x) {
      assert(x<alloc_size);
      ListNode * node = array[x];
      if (node != node->parent) {
        node->parent = Find2(node->parent->val);
      }
      return node->parent;
    }

    // This version tries to determine the new subtree high at the root.
    // TODO: It doesn't work, as you might compress one branch up to the root, but
    // there might still be another branch for the same root that is longer.
    // Then you cannot infer from the compressed branch only if the subtree high from
    // the root has changed or not.
    /*
    ListNode * Find3(int x) {
      assert(x<alloc_size);
      ListNode * node = array[x];
      int node_compressed = 0;
      if (node != node->parent) {
        ListNode * parent = InternalFind3(node->parent->val, node_compressed);
        node->parent = parent;
        // A child attached to the root has subtree high==1.
        node->subtree_high = 1;
      }
      if (node_compressed > 0) {
        node->subtree_high -= node_compressed;
      }
      return node;
    }
    */

    bool Union(int x, int y) {
      assert(x<alloc_size);
      assert(y<alloc_size);
      ListNode * root_x = Find2(x);
      ListNode * root_y = Find2(y);
      if (root_x->val != root_y->val) {
        // merge them
        if (root_x->subtree_size > root_y->subtree_size) {
          root_y->parent = root_x;
          root_x->subtree_size += root_y->subtree_size;
          // root_x->subtree_size unchanged as root_y->subtree_size is shorter than
          // root_x->subtree_size, then this doesn't increase the longest path
          // from root_x to any of its leaves.
        } else { //if (root_y->subtree_size > root_x->subtree_size) {
          root_x->parent = root_y;
          root_y->subtree_size += root_x->subtree_size;
          // root_y->subtree_size doesn't change for the same reasons as above.
        }
        /*
        else {
          // root_x->subtree_size == root_y->subtree_size
          root_x->parent = root_y;
          root_y->subtree_size += 1;
        }
        */
        //root_x->parent = root_y;
        set_size -= 1;
        return true;
      }
      return false;
    }

    void MakeSet(int x) {
      assert(x<alloc_size);
      if (array[x]!=NULL) return;
      ListNode * node = new ListNode;
      node->val = x;
      node->subtree_size = 1;
      node->parent = node;
      array[x] = node;
      set_size += 1;
      return;
    }

    std::string toDot() {
      std::ostringstream out;
      bool * visited = new bool[alloc_size];
      for (int i=0; i<alloc_size; ++i) visited[i] = false;

      out << "digraph DisjointSet {\n";
      for (int i=0; i<alloc_size; ++i) {
        ListNode * node = array[i];
        while (node != node->parent && !visited[node->val]) {
          out << node->val << " -> " << node->parent->val << ";\n";
          visited[node->val] = true;
          //visited[node->parent->val] = true;
          node = node->parent;
        }
      }
      for (int i=0; i<alloc_size; ++i) {
        ListNode * node = array[i];
        if (!visited[node->val]) {
          out << node->val << ";\n";
          visited[node->val] = true;
        }
        out << node->val << "[label=\"" << node->val <<
                            " size=" << node->subtree_size <<
                            "\"];\n";
      }
      delete[] visited;
      out << "}";
      return out.str();
    }

    int size() {
      return set_size;
    }

  private:
    // As explained above this is not working at the moment.
    /*
    ListNode * InternalFind3(int x, int & node_compressed) {
      assert(x<alloc_size);
      ListNode * node = array[x];
      if (node != node->parent) {
        node_compressed += 1;
        node->parent = InternalFind3(node->parent->val, node_compressed);
        // A child attached to the root has subtree_high==1.
        node->subtree_high = 1;
      }
      // TODO how do you determine the new subtree_high at the root?
      // It's not necessarily 2, as you might start searching the list from the
      // middle, then attaching directly to the root only the nodes above that
      // point, but not the ones below it.
      return node->parent;
    }
    */
    ListNode ** array;
    size_t set_size;
    size_t alloc_size;
};

int main(int argc, char *argv[]) {
  DisjointSet ds;
  for (int set_number=0; set_number<DSET_SIZE; ++set_number) {
    ds.MakeSet(set_number);
  }
  srand(time(NULL));
  int unions = 0;
  int attempts = 0;
  while (ds.size() > 1) {
    // generate random couples and do Union operations, up to when there is
    // only a single set left.
    int x = rand() % DSET_SIZE;
    int y = rand() % DSET_SIZE;
    if (ds.Union(x,y)) {
      unions += 1;
    } else {
      attempts += 1;
    }
    //std::cout << ds.toDot() << std::endl;
  }
  std::cerr << "unions=" << unions << ", attempts=" << attempts << std::endl;
  std::cout << ds.toDot() << std::endl;
  return 0;
}
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include <cmath>

#include "modules/prediction/common/prediction_gflags.h"

// System gflags
DEFINE_string(prediction_module_name, "prediction",
              "Default prediciton module name");
DEFINE_string(prediction_conf_file,
              "modules/prediction/conf/prediction_conf.pb.txt",
              "Default conf file for prediction");
DEFINE_string(prediction_adapter_config_filename,
              "modules/prediction/conf/adapter.conf",
              "Default conf file for prediction");
DEFINE_string(prediction_data_file_prefix, "data/prediction/feature",
              "Prefix of files to store feature data");
DEFINE_bool(prediction_test_mode, false, "Set prediction to test mode");
DEFINE_double(
    prediction_test_duration, -1.0,
    "The runtime duration in test mode (in seconds). Negative value will not "
    "restrict the runtime duration.");

DEFINE_bool(prediction_offline_mode, false, "Prediction offline mode");

DEFINE_double(prediction_duration, 5.0, "Prediction duration (in seconds)");
DEFINE_double(prediction_period, 0.1, "Prediction period (in seconds");
DEFINE_double(double_precision, 1e-6, "precision of double");
DEFINE_double(min_prediction_length, 20.0,
              "Minimal length of prediction trajectory");

// Bag replay timestamp gap
DEFINE_double(replay_timestamp_gap, 10.0,
              "Max timestamp gap for rosbag replay");

// Map
DEFINE_double(lane_search_radius, 3.0, "Search radius for a candidate lane");
DEFINE_double(junction_search_radius, 1.0, "Search radius for a junction");

// Obstacle features
DEFINE_bool(enable_kf_tracking, false, "Use measurements with KF tracking");
DEFINE_double(max_acc, 4.0, "Upper bound of acceleration");
DEFINE_double(min_acc, -4.0, "Lower bound of deceleration");
DEFINE_double(max_speed, 35.0, "Max speed");
DEFINE_double(q_var, 0.01, "Processing noise covariance");
DEFINE_double(r_var, 0.25, "Measurement noise covariance");
DEFINE_double(p_var, 0.1, "Error covariance");
DEFINE_double(go_approach_rate, 0.995,
              "The rate to approach to the reference line of going straight");
DEFINE_double(cutin_approach_rate, 0.9,
              "The rate to approach to the reference line of lane change");
DEFINE_int32(still_obstacle_history_length, 10,
             "Min # historical frames for still obstacles");
DEFINE_double(still_obstacle_speed_threshold, 2.0,
              "Speed threshold for still obstacles");
DEFINE_double(still_pedestrian_speed_threshold, 0.5,
              "Speed threshold for still pedestrians");
DEFINE_double(still_obstacle_position_std, 1.0,
              "Position standard deviation for still obstacles");
DEFINE_double(still_pedestrian_position_std, 0.5,
              "Position standard deviation for still obstacles");
DEFINE_double(max_history_time, 7.0, "Obstacles' maximal historical time.");
DEFINE_double(target_lane_gap, 2.0, "gap between two lane points.");
DEFINE_int32(max_num_current_lane, 1, "Max number to search current lanes");
DEFINE_int32(max_num_nearby_lane, 2, "Max number to search nearby lanes");
DEFINE_double(max_lane_angle_diff, M_PI / 2.0,
              "Max angle difference for a candiate lane");
DEFINE_bool(enable_pedestrian_acc, false, "Enable calculating speed by acc");
DEFINE_double(coeff_mul_sigma, 2.0, "coefficient multiply standard deviation");
DEFINE_double(pedestrian_max_speed, 10.0, "speed upper bound for pedestrian");
DEFINE_double(pedestrian_max_acc, 2.0, "maximum pedestrian acceleration");
DEFINE_double(prediction_pedestrian_total_time, 10.0,
              "Total prediction time for pedestrians");
DEFINE_double(still_speed, 0.01, "speed considered to be still");
DEFINE_string(evaluator_vehicle_mlp_file,
              "modules/prediction/data/mlp_vehicle_model.bin",
              "mlp model file for vehicle evaluator");
DEFINE_string(evaluator_vehicle_rnn_file,
              "modules/prediction/data/rnn_vehicle_model.bin",
              "rnn model file for vehicle evaluator");
DEFINE_int32(max_num_obstacles, 100,
             "maximal number of obstacles stored in obstacles container.");
DEFINE_double(valid_position_diff_threshold, 0.5,
              "threshold of valid position difference");
DEFINE_double(valid_position_diff_rate_threshold, 0.075,
              "threshold of valid position difference rate");
DEFINE_double(split_rate, 0.5, "obstacle split rate for adjusting velocity");
DEFINE_double(rnn_min_lane_relatice_s, 5.0,
              "Minimal relative s for RNN model.");
DEFINE_bool(enable_adjust_velocity_heading, false,
            "adjust velocity heading to lane heading");
DEFINE_double(heading_filter_param, 0.99, "heading filter parameter");

// Obstacle trajectory
DEFINE_double(lane_sequence_threshold, 0.5,
              "Threshold for trimming lane sequence trajectories");
DEFINE_double(lane_change_dist, 10.0, "Lane change distance with ADC");
DEFINE_bool(enable_lane_sequence_acc, false,
            "If use acceleration in lane sequence.");
DEFINE_bool(enable_trim_prediction_trajectory, false,
            "If trim the prediction trajectory to avoid crossing"
            "protected adc planning trajectory.");
DEFINE_double(distance_beyond_junction, 0.5,
              "If the obstacle is in junction more than this threshold,"
              "consider it in junction.");
DEFINE_double(adc_trajectory_search_length, 10.0,
              "How far to search junction along adc planning trajectory");
DEFINE_double(virtual_lane_radius, 0.5, "Radius to search virtual lanes");
DEFINE_double(default_lateral_approach_speed, 0.5,
              "Default lateral speed approaching to center of lane");

// move sequence prediction
DEFINE_double(time_upper_bound_to_lane_center, 5.0,
              "Upper bound of time to get to the lane center");
DEFINE_double(time_lower_bound_to_lane_center, 1.0,
              "Lower bound of time to get to the lane center");
DEFINE_double(sample_time_gap, 0.2,
              "Gap of time to sample time to get to the lane center");
DEFINE_double(cost_alpha, 100.0,
              "The coefficient of lateral acceleration in cost function");
DEFINE_double(default_time_to_lane_center, 5.0,
              "The default time to lane center");
<commit_msg>Prediction: set default number of current lane as 2<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include <cmath>

#include "modules/prediction/common/prediction_gflags.h"

// System gflags
DEFINE_string(prediction_module_name, "prediction",
              "Default prediciton module name");
DEFINE_string(prediction_conf_file,
              "modules/prediction/conf/prediction_conf.pb.txt",
              "Default conf file for prediction");
DEFINE_string(prediction_adapter_config_filename,
              "modules/prediction/conf/adapter.conf",
              "Default conf file for prediction");
DEFINE_string(prediction_data_file_prefix, "data/prediction/feature",
              "Prefix of files to store feature data");
DEFINE_bool(prediction_test_mode, false, "Set prediction to test mode");
DEFINE_double(
    prediction_test_duration, -1.0,
    "The runtime duration in test mode (in seconds). Negative value will not "
    "restrict the runtime duration.");

DEFINE_bool(prediction_offline_mode, false, "Prediction offline mode");

DEFINE_double(prediction_duration, 5.0, "Prediction duration (in seconds)");
DEFINE_double(prediction_period, 0.1, "Prediction period (in seconds");
DEFINE_double(double_precision, 1e-6, "precision of double");
DEFINE_double(min_prediction_length, 20.0,
              "Minimal length of prediction trajectory");

// Bag replay timestamp gap
DEFINE_double(replay_timestamp_gap, 10.0,
              "Max timestamp gap for rosbag replay");

// Map
DEFINE_double(lane_search_radius, 3.0, "Search radius for a candidate lane");
DEFINE_double(junction_search_radius, 1.0, "Search radius for a junction");

// Obstacle features
DEFINE_bool(enable_kf_tracking, false, "Use measurements with KF tracking");
DEFINE_double(max_acc, 4.0, "Upper bound of acceleration");
DEFINE_double(min_acc, -4.0, "Lower bound of deceleration");
DEFINE_double(max_speed, 35.0, "Max speed");
DEFINE_double(q_var, 0.01, "Processing noise covariance");
DEFINE_double(r_var, 0.25, "Measurement noise covariance");
DEFINE_double(p_var, 0.1, "Error covariance");
DEFINE_double(go_approach_rate, 0.995,
              "The rate to approach to the reference line of going straight");
DEFINE_double(cutin_approach_rate, 0.9,
              "The rate to approach to the reference line of lane change");
DEFINE_int32(still_obstacle_history_length, 10,
             "Min # historical frames for still obstacles");
DEFINE_double(still_obstacle_speed_threshold, 2.0,
              "Speed threshold for still obstacles");
DEFINE_double(still_pedestrian_speed_threshold, 0.5,
              "Speed threshold for still pedestrians");
DEFINE_double(still_obstacle_position_std, 1.0,
              "Position standard deviation for still obstacles");
DEFINE_double(still_pedestrian_position_std, 0.5,
              "Position standard deviation for still obstacles");
DEFINE_double(max_history_time, 7.0, "Obstacles' maximal historical time.");
DEFINE_double(target_lane_gap, 2.0, "gap between two lane points.");
DEFINE_int32(max_num_current_lane, 2, "Max number to search current lanes");
DEFINE_int32(max_num_nearby_lane, 2, "Max number to search nearby lanes");
DEFINE_double(max_lane_angle_diff, M_PI / 2.0,
              "Max angle difference for a candiate lane");
DEFINE_bool(enable_pedestrian_acc, false, "Enable calculating speed by acc");
DEFINE_double(coeff_mul_sigma, 2.0, "coefficient multiply standard deviation");
DEFINE_double(pedestrian_max_speed, 10.0, "speed upper bound for pedestrian");
DEFINE_double(pedestrian_max_acc, 2.0, "maximum pedestrian acceleration");
DEFINE_double(prediction_pedestrian_total_time, 10.0,
              "Total prediction time for pedestrians");
DEFINE_double(still_speed, 0.01, "speed considered to be still");
DEFINE_string(evaluator_vehicle_mlp_file,
              "modules/prediction/data/mlp_vehicle_model.bin",
              "mlp model file for vehicle evaluator");
DEFINE_string(evaluator_vehicle_rnn_file,
              "modules/prediction/data/rnn_vehicle_model.bin",
              "rnn model file for vehicle evaluator");
DEFINE_int32(max_num_obstacles, 100,
             "maximal number of obstacles stored in obstacles container.");
DEFINE_double(valid_position_diff_threshold, 0.5,
              "threshold of valid position difference");
DEFINE_double(valid_position_diff_rate_threshold, 0.075,
              "threshold of valid position difference rate");
DEFINE_double(split_rate, 0.5, "obstacle split rate for adjusting velocity");
DEFINE_double(rnn_min_lane_relatice_s, 5.0,
              "Minimal relative s for RNN model.");
DEFINE_bool(enable_adjust_velocity_heading, false,
            "adjust velocity heading to lane heading");
DEFINE_double(heading_filter_param, 0.99, "heading filter parameter");

// Obstacle trajectory
DEFINE_double(lane_sequence_threshold, 0.5,
              "Threshold for trimming lane sequence trajectories");
DEFINE_double(lane_change_dist, 10.0, "Lane change distance with ADC");
DEFINE_bool(enable_lane_sequence_acc, false,
            "If use acceleration in lane sequence.");
DEFINE_bool(enable_trim_prediction_trajectory, false,
            "If trim the prediction trajectory to avoid crossing"
            "protected adc planning trajectory.");
DEFINE_double(distance_beyond_junction, 0.5,
              "If the obstacle is in junction more than this threshold,"
              "consider it in junction.");
DEFINE_double(adc_trajectory_search_length, 10.0,
              "How far to search junction along adc planning trajectory");
DEFINE_double(virtual_lane_radius, 0.5, "Radius to search virtual lanes");
DEFINE_double(default_lateral_approach_speed, 0.5,
              "Default lateral speed approaching to center of lane");

// move sequence prediction
DEFINE_double(time_upper_bound_to_lane_center, 5.0,
              "Upper bound of time to get to the lane center");
DEFINE_double(time_lower_bound_to_lane_center, 1.0,
              "Lower bound of time to get to the lane center");
DEFINE_double(sample_time_gap, 0.2,
              "Gap of time to sample time to get to the lane center");
DEFINE_double(cost_alpha, 100.0,
              "The coefficient of lateral acceleration in cost function");
DEFINE_double(default_time_to_lane_center, 5.0,
              "The default time to lane center");
<|endoftext|>


<commit_before><commit_msg>Update Graph folder<commit_after><|endoftext|>


<commit_before>/*
 *  YABlobber.cpp
 *
 *  Created by Daniel Swain on 9/22/09.
 *
 */

#include "YABlobber.h"
#include "MT/MT_Core/support/mathsupport.h"

int YABlob::ref_count = 0;

YABlobber::YABlobber(bool UseBoundingBoxes)
    : m_bCopySequences(false)
{
    m_bUseBoundingBoxes = UseBoundingBoxes;
    m_BoundingBoxes.resize(0);
    m_blobs.resize(0);
}

std::vector<YABlob> YABlobber::FindBlobs(IplImage* BWFrame,
                                         int MinBlobPerimeter,
                                         int MinBlobArea,
                                         int MaxBlobPerimeter,
                                         int MaxBlobArea)
{

    double tA = MT_getTimeSec();
    double tB;

    m_blobs.resize(0);
    std::vector<double> perimeters;
    std::vector<double> areas;
    perimeters.resize(0);
    areas.resize(0);

    CvMemStorage* mem_storage = cvCreateMemStorage(0);
    CvSeq* contours = NULL;

	if(!mem_storage)
	{
		fprintf(stderr, "YABlobber error:  Could not allocate cvMemStorage\n");
		return m_blobs;
	}

	if(!BWFrame)
	{
		fprintf(stderr, "YABlobber error:  Image is NULL\n");
		return m_blobs;
	}

    CvContourScanner scanner = cvStartFindContours(BWFrame,
                                                   mem_storage,
                                                   sizeof(CvContour),
                                                   CV_RETR_EXTERNAL,
                                                   CV_CHAIN_APPROX_SIMPLE);

    // Throw out contours that are too small and approximate rest with polygons
    CvSeq* cs;
    int NFilteredContours = 0;
    double perimeter, area;

    tB = MT_getTimeSec();
    ////printf("Start Contour %f\n", tB-tA);
    tA = tB;

    while( (cs = cvFindNextContour( scanner )) != NULL){
        perimeter = cvContourPerimeter( cs );
        area = fabs(cvContourArea(cs));

        // Get rid of blobs that don't fit our criteria
        if (perimeter < MinBlobPerimeter)  /* blob filtering */
        {
            cvSubstituteContour( scanner, NULL );
        }
        else if((area == 0) || ((MinBlobArea != NO_AREA_THRESH) && (area < MinBlobArea)))
        {
            cvSubstituteContour(scanner, NULL);
        }
        else if((MaxBlobPerimeter != NO_MAX) && (perimeter > MaxBlobPerimeter))
        {
            cvSubstituteContour(scanner, NULL);
        }
        else if((MaxBlobArea != NO_MAX) && (area > MaxBlobArea))
        {
            cvSubstituteContour(scanner, NULL);
        }
        else /* done filtering blobs */
        {

            // Store the perimeter and area for output
            perimeters.push_back(perimeter);
            areas.push_back(area);

            // Smooth its edges if large enough
            CvSeq* cs_new;
            // Polygonal approximation
            cs_new = cvApproxPoly(
                cs,
                sizeof(CvContour),
                mem_storage,
                CV_POLY_APPROX_DP,
                CVCONTOUR_APPROX_LEVEL,
                0
                );
            cvSubstituteContour( scanner, cs_new );

            NFilteredContours++;
        }
    }
    tB = MT_getTimeSec();
    //printf("Filter Contour %f\n", tB-tA);
    tA = tB;

    contours = cvEndFindContours( &scanner );

    if(!contours)
    {
        cvClearMemStorage(mem_storage);
        cvReleaseMemStorage(&mem_storage);
        return m_blobs;
    }

    // Some convenience variables
    const CvScalar CVX_WHITE = CV_RGB(0xff, 0xff, 0xff);
    const CvScalar CVX_BLACK = CV_RGB(0x00, 0x00, 0x00);

    // Paint the found regions back into the image
    cvZero( BWFrame ); // sets the array to zero
    IplImage* maskTemp = cvCreateImage( cvGetSize(BWFrame), IPL_DEPTH_8U, 1 );
    CvScalar cont_color = cvScalar( 255, 0, 0 );

    // CALC CENTRE OF MASS AND/OR BOUNDING RECTANGLES
    /*  if (num != NULL) {
        int N = *num, numFilled = 0, i = 0;*/

    CvMoments moments;
    CvScalar zfZero = cvScalar( 0.0 );
    double M00, M01, M10, M11, M02, M20, M12, M21, M30, M03;
    double mu11, mu20, mu02, mu12, mu21, mu30, mu03;
    double s;
    double orientangle;
    double qx, qy;
    double x, y;
    double d, a, major, minor;
    cvZero( maskTemp );

    int i;
    int numFilled = 0;
    //double t0 = MT_getTimeSec();
    double tz;
    double ta = 0, tb = 0, tc = 0, td = 0, te = 0, tf = 0;

    tB = MT_getTimeSec();
    //printf("Middle %f\n", tB-tA);
    tA = tB;
    for (i = 0, cs = contours; cs != NULL; cs = cs->h_next, i++)
    {
        tz = MT_getTimeSec();
        // Only process up to *num of them
        cvDrawContours(
            maskTemp,
            cs,
            CVX_WHITE,
            CVX_WHITE,
            -1,
            CV_FILLED,
            8
            );
        ta += MT_getTimeSec() - tz;
        tz = MT_getTimeSec();

        // Update color
        cont_color.val[0] -= 5;

        CvRect BB = cvBoundingRect(cs);
        int x1 = BB.x;
        int y1 = BB.y;
        int w = BB.width;
        //int h = BB.height;

        BB.x = x1 - 0.5*w;
        BB.y = y1 - 0.5*w;
        BB.width = 2*w;
        BB.height = 2*w;

        cvSetImageROI(maskTemp, BB);
        /*cvDilate( maskTemp, maskTemp );
          cvErode( maskTemp, maskTemp );*/
        tb += MT_getTimeSec() - tz;
        tz = MT_getTimeSec();

        // Fill in the stats for each contour
        //if(centers != NULL && areas != NULL && orientAngle != NULL){
        cvMoments(cs, &moments, 1);
        tc += MT_getTimeSec() - tz;
        tz = MT_getTimeSec();

        // Spatial moments
        M00 = cvGetSpatialMoment(&moments, 0, 0);
        M10 = cvGetSpatialMoment(&moments, 1, 0);
        M01 = cvGetSpatialMoment(&moments, 0, 1);
        M11 = cvGetSpatialMoment(&moments, 1, 1);
        M20 = cvGetSpatialMoment(&moments, 2, 0);
        M02 = cvGetSpatialMoment(&moments, 0, 2);
        M12 = cvGetSpatialMoment(&moments, 1, 2);
        M21 = cvGetSpatialMoment(&moments, 2, 1);
        M30 = cvGetSpatialMoment(&moments, 3, 0);
        M03 = cvGetSpatialMoment(&moments, 0, 3);
        td += MT_getTimeSec() - tz;
        tz = MT_getTimeSec();

        // Center of each contour
        x = M10/M00;// + ((double) BB.x); // row/x  *indexed from top left, rows are x*
        y = M01/M00;// + ((double) BB.y); // column/y

        // Area and perimeter of each contour
        //areas[i] = M00;
        //perimeters[i] = lenstore[numCont-1-i];

        // Orientation of each contour

        // Central moments
        mu11 = M11/M00 - (M10/M00)*(M01/M00);
        mu20 = M20/M00 - (M10/M00)*(M10/M00);
        mu02 = M02/M00 - (M01/M00)*(M01/M00);
        mu12 = M12 - 2.0*(M01/M00)*M11 - (M10/M00)*M02 + 2.0*(M01/M00)*(M01/M00)*M10;
        mu21 = M21 - 2.0*(M10/M00)*M11 - (M01/M00)*M20 + 2.0*(M10/M00)*(M10/M00)*M01;
        mu30 = M30 - 3.0*(M10/M00)*M20 + 2.0*(M10/M00)*(M10/M00)*M10;
        mu03 = M03 - 3.0*(M01/M00)*M02 + 2.0*(M01/M00)*(M01/M00)*M01;

        d = sqrt(4.0*mu11*mu11 + (mu20 - mu02)*(mu20 - mu02));
        a = pow(16.0*MT_PI*MT_PI*(mu20*mu02 - mu11*mu11), 0.25);
        minor = sqrt(sqrt(M00)*(2.0*(mu20 + mu02 - d))/a);
        major = sqrt(sqrt(M00)*(2.0*(mu20 + mu02 + d))/a);

        orientangle =  180.0 - MT_RAD2DEG * 0.5*atan2( (mu11*2.0), (mu20-mu02) );

        qx = cos(MT_DEG2RAD*orientangle);
        qy = -sin(MT_DEG2RAD*orientangle);

        s = mu30*qx*qx*qx + 3.0*mu21*qx*qx*qy + 3.0*mu12*qx*qy*qy + mu03*qy*qy*qy;

        if (s > 0)      {
            orientangle += 180.0;
            qx = cos(MT_DEG2RAD*orientangle);
            qy = -sin(MT_DEG2RAD*orientangle);
        }
        //printf("%f, %f, %f\n", x, y, orientangle);

        // normalize orientation vectors
        /* why where you doing this?
           double mag = sqrt( orientVec[i][0]*orientVec[i][0] + orientVec[i][1]*orientVec[i][1] );
           orientVec[i][0] = orientVec[i][0]/mag;
           orientVec[i][1] = orientVec[i][1]/mag; */

        // Bounding rectangles around blobs
        if(m_bUseBoundingBoxes){
            m_BoundingBoxes.push_back(cvBoundingRect(cs));
        }

        te += MT_getTimeSec() - tz;
        tz = MT_getTimeSec();

        cvZero(maskTemp);
        cvResetImageROI(maskTemp);
        numFilled++;

        // Draw filled contours onto mask
        cvDrawContours(
            BWFrame,
            cs,
            cont_color,
            cont_color,
            -1,
            CV_FILLED,
            8
            );
        tf += MT_getTimeSec() - tz;
        tz = MT_getTimeSec();

        ////printf("area %f, perimeter %f\n", areas[i], perimeters[i]);
        m_blobs.push_back(
            YABlob(perimeters[i],
                   areas[i],
                   x, y, orientangle, mu20, mu11, mu02, qx, qy,
                   minor, major));
        if(m_bCopySequences)
        {
            m_blobs[m_blobs.size()-1].copySequence(cs);
        }

        // end looping over contours
        //*num = numFilled;
    }
    //printf("ta = %f\n", ta);
    //printf("tb = %f\n", tb);
    //printf("tc = %f\n", tc);
    //printf("td = %f\n", td);
    //printf("te = %f\n", te);
    //printf("tf = %f\n", tf);
    //printf("dt = %f\n", MT_getTimeSec() - t0);

    //free(lenstore);
    cvReleaseImage( &maskTemp );
/*    if( mem_storage != NULL ) cvClearMemStorage( mem_storage );
      if( contours != NULL ) cvClearSeq( contours );*/
    cvClearSeq(contours);

    cvClearMemStorage(mem_storage);
    cvReleaseMemStorage(&mem_storage);

    return m_blobs;

}
<commit_msg>Fix a really old bug in YABlobber's area/perimeter assignment :)<commit_after>/*
 *  YABlobber.cpp
 *
 *  Created by Daniel Swain on 9/22/09.
 *
 */

#include "YABlobber.h"
#include "MT/MT_Core/support/mathsupport.h"

int YABlob::ref_count = 0;

YABlobber::YABlobber(bool UseBoundingBoxes)
    : m_bCopySequences(false)
{
    m_bUseBoundingBoxes = UseBoundingBoxes;
    m_BoundingBoxes.resize(0);
    m_blobs.resize(0);
}

std::vector<YABlob> YABlobber::FindBlobs(IplImage* BWFrame,
                                         int MinBlobPerimeter,
                                         int MinBlobArea,
                                         int MaxBlobPerimeter,
                                         int MaxBlobArea)
{

    double tA = MT_getTimeSec();
    double tB;

    m_blobs.resize(0);
    std::vector<double> perimeters;
    std::vector<double> areas;
    perimeters.resize(0);
    areas.resize(0);

    CvMemStorage* mem_storage = cvCreateMemStorage(0);
    CvSeq* contours = NULL;

	if(!mem_storage)
	{
		fprintf(stderr, "YABlobber error:  Could not allocate cvMemStorage\n");
		return m_blobs;
	}

	if(!BWFrame)
	{
		fprintf(stderr, "YABlobber error:  Image is NULL\n");
		return m_blobs;
	}

    CvContourScanner scanner = cvStartFindContours(BWFrame,
                                                   mem_storage,
                                                   sizeof(CvContour),
                                                   CV_RETR_EXTERNAL,
                                                   CV_CHAIN_APPROX_SIMPLE);

    // Throw out contours that are too small and approximate rest with polygons
    CvSeq* cs;
    int NFilteredContours = 0;
    double perimeter, area;

    tB = MT_getTimeSec();
    ////printf("Start Contour %f\n", tB-tA);
    tA = tB;

    while( (cs = cvFindNextContour( scanner )) != NULL){
        perimeter = cvContourPerimeter( cs );
        area = fabs(cvContourArea(cs));

        // Get rid of blobs that don't fit our criteria
        if (perimeter < MinBlobPerimeter)  /* blob filtering */
        {
            cvSubstituteContour( scanner, NULL );
        }
        else if((area == 0) || ((MinBlobArea != NO_AREA_THRESH) && (area < MinBlobArea)))
        {
            cvSubstituteContour(scanner, NULL);
        }
        else if((MaxBlobPerimeter != NO_MAX) && (perimeter > MaxBlobPerimeter))
        {
            cvSubstituteContour(scanner, NULL);
        }
        else if((MaxBlobArea != NO_MAX) && (area > MaxBlobArea))
        {
            cvSubstituteContour(scanner, NULL);
        }
        else /* done filtering blobs */
        {

            // Store the perimeter and area for output
            perimeters.push_back(perimeter);
            areas.push_back(area);

            // Smooth its edges if large enough
            CvSeq* cs_new;
            // Polygonal approximation
            cs_new = cvApproxPoly(
                cs,
                sizeof(CvContour),
                mem_storage,
                CV_POLY_APPROX_DP,
                CVCONTOUR_APPROX_LEVEL,
                0
                );
            cvSubstituteContour( scanner, cs_new );

            NFilteredContours++;
        }
    }
    tB = MT_getTimeSec();
    //printf("Filter Contour %f\n", tB-tA);
    tA = tB;

    contours = cvEndFindContours( &scanner );

    if(!contours)
    {
        cvClearMemStorage(mem_storage);
        cvReleaseMemStorage(&mem_storage);
        return m_blobs;
    }

    // Some convenience variables
    const CvScalar CVX_WHITE = CV_RGB(0xff, 0xff, 0xff);
    const CvScalar CVX_BLACK = CV_RGB(0x00, 0x00, 0x00);

    // Paint the found regions back into the image
    cvZero( BWFrame ); // sets the array to zero
    IplImage* maskTemp = cvCreateImage( cvGetSize(BWFrame), IPL_DEPTH_8U, 1 );
    CvScalar cont_color = cvScalar( 255, 0, 0 );

    // CALC CENTRE OF MASS AND/OR BOUNDING RECTANGLES
    /*  if (num != NULL) {
        int N = *num, numFilled = 0, i = 0;*/

    CvMoments moments;
    CvScalar zfZero = cvScalar( 0.0 );
    double M00, M01, M10, M11, M02, M20, M12, M21, M30, M03;
    double mu11, mu20, mu02, mu12, mu21, mu30, mu03;
    double s;
    double orientangle;
    double qx, qy;
    double x, y;
    double d, a, major, minor;
    cvZero( maskTemp );

    int i;
    int numFilled = 0;
    //double t0 = MT_getTimeSec();
    double tz;
    double ta = 0, tb = 0, tc = 0, td = 0, te = 0, tf = 0;

    tB = MT_getTimeSec();
    //printf("Middle %f\n", tB-tA);
    tA = tB;
    for (i = 0, cs = contours; cs != NULL; cs = cs->h_next, i++)
    {
        tz = MT_getTimeSec();
        // Only process up to *num of them
        cvDrawContours(
            maskTemp,
            cs,
            CVX_WHITE,
            CVX_WHITE,
            -1,
            CV_FILLED,
            8
            );
        ta += MT_getTimeSec() - tz;
        tz = MT_getTimeSec();

        // Update color
        cont_color.val[0] -= 5;

        CvRect BB = cvBoundingRect(cs);
        int x1 = BB.x;
        int y1 = BB.y;
        int w = BB.width;
        //int h = BB.height;

        BB.x = x1 - 0.5*w;
        BB.y = y1 - 0.5*w;
        BB.width = 2*w;
        BB.height = 2*w;

        cvSetImageROI(maskTemp, BB);
        /*cvDilate( maskTemp, maskTemp );
          cvErode( maskTemp, maskTemp );*/
        tb += MT_getTimeSec() - tz;
        tz = MT_getTimeSec();

        // Fill in the stats for each contour
        //if(centers != NULL && areas != NULL && orientAngle != NULL){
        cvMoments(cs, &moments, 1);
        tc += MT_getTimeSec() - tz;
        tz = MT_getTimeSec();

        // Spatial moments
        M00 = cvGetSpatialMoment(&moments, 0, 0);
        M10 = cvGetSpatialMoment(&moments, 1, 0);
        M01 = cvGetSpatialMoment(&moments, 0, 1);
        M11 = cvGetSpatialMoment(&moments, 1, 1);
        M20 = cvGetSpatialMoment(&moments, 2, 0);
        M02 = cvGetSpatialMoment(&moments, 0, 2);
        M12 = cvGetSpatialMoment(&moments, 1, 2);
        M21 = cvGetSpatialMoment(&moments, 2, 1);
        M30 = cvGetSpatialMoment(&moments, 3, 0);
        M03 = cvGetSpatialMoment(&moments, 0, 3);
        td += MT_getTimeSec() - tz;
        tz = MT_getTimeSec();

        // Center of each contour
        x = M10/M00;// + ((double) BB.x); // row/x  *indexed from top left, rows are x*
        y = M01/M00;// + ((double) BB.y); // column/y

        // Area and perimeter of each contour
        //areas[i] = M00;
        //perimeters[i] = lenstore[numCont-1-i];

        // Orientation of each contour

        // Central moments
        mu11 = M11/M00 - (M10/M00)*(M01/M00);
        mu20 = M20/M00 - (M10/M00)*(M10/M00);
        mu02 = M02/M00 - (M01/M00)*(M01/M00);
        mu12 = M12 - 2.0*(M01/M00)*M11 - (M10/M00)*M02 + 2.0*(M01/M00)*(M01/M00)*M10;
        mu21 = M21 - 2.0*(M10/M00)*M11 - (M01/M00)*M20 + 2.0*(M10/M00)*(M10/M00)*M01;
        mu30 = M30 - 3.0*(M10/M00)*M20 + 2.0*(M10/M00)*(M10/M00)*M10;
        mu03 = M03 - 3.0*(M01/M00)*M02 + 2.0*(M01/M00)*(M01/M00)*M01;

        d = sqrt(4.0*mu11*mu11 + (mu20 - mu02)*(mu20 - mu02));
        a = pow(16.0*MT_PI*MT_PI*(mu20*mu02 - mu11*mu11), 0.25);
        minor = sqrt(sqrt(M00)*(2.0*(mu20 + mu02 - d))/a);
        major = sqrt(sqrt(M00)*(2.0*(mu20 + mu02 + d))/a);

        orientangle =  180.0 - MT_RAD2DEG * 0.5*atan2( (mu11*2.0), (mu20-mu02) );

        qx = cos(MT_DEG2RAD*orientangle);
        qy = -sin(MT_DEG2RAD*orientangle);

        s = mu30*qx*qx*qx + 3.0*mu21*qx*qx*qy + 3.0*mu12*qx*qy*qy + mu03*qy*qy*qy;

        if (s > 0)      {
            orientangle += 180.0;
            qx = cos(MT_DEG2RAD*orientangle);
            qy = -sin(MT_DEG2RAD*orientangle);
        }
        //printf("%f, %f, %f\n", x, y, orientangle);

        // normalize orientation vectors
        /* why where you doing this?
           double mag = sqrt( orientVec[i][0]*orientVec[i][0] + orientVec[i][1]*orientVec[i][1] );
           orientVec[i][0] = orientVec[i][0]/mag;
           orientVec[i][1] = orientVec[i][1]/mag; */

        // Bounding rectangles around blobs
        if(m_bUseBoundingBoxes){
            m_BoundingBoxes.push_back(cvBoundingRect(cs));
        }

        te += MT_getTimeSec() - tz;
        tz = MT_getTimeSec();

        cvZero(maskTemp);
        cvResetImageROI(maskTemp);
        numFilled++;

        // Draw filled contours onto mask
        cvDrawContours(
            BWFrame,
            cs,
            cont_color,
            cont_color,
            -1,
            CV_FILLED,
            8
            );
        tf += MT_getTimeSec() - tz;
        tz = MT_getTimeSec();

        double perimeter = cvContourPerimeter( cs );
        double area = fabs(cvContourArea(cs));

        ////printf("area %f, perimeter %f\n", areas[i], perimeters[i]);
        m_blobs.push_back(
            YABlob(perimeter,
                   area,
                   x, y, orientangle, mu20, mu11, mu02, qx, qy,
                   minor, major));
        if(m_bCopySequences)
        {
            m_blobs[m_blobs.size()-1].copySequence(cs);
        }

        // end looping over contours
        //*num = numFilled;
    }
    //printf("ta = %f\n", ta);
    //printf("tb = %f\n", tb);
    //printf("tc = %f\n", tc);
    //printf("td = %f\n", td);
    //printf("te = %f\n", te);
    //printf("tf = %f\n", tf);
    //printf("dt = %f\n", MT_getTimeSec() - t0);

    //free(lenstore);
    cvReleaseImage( &maskTemp );
/*    if( mem_storage != NULL ) cvClearMemStorage( mem_storage );
      if( contours != NULL ) cvClearSeq( contours );*/
    cvClearSeq(contours);

    cvClearMemStorage(mem_storage);
    cvReleaseMemStorage(&mem_storage);

    return m_blobs;

}
<|endoftext|>


<commit_before>//===-- CodeGen/AsmPrinter/Win64Exception.cpp - Dwarf Exception Impl ------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains support for writing Win64 exception info into asm files.
//
//===----------------------------------------------------------------------===//

#include "Win64Exception.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;

Win64Exception::Win64Exception(AsmPrinter *A)
  : EHStreamer(A), shouldEmitPersonality(false), shouldEmitLSDA(false),
    shouldEmitMoves(false) {}

Win64Exception::~Win64Exception() {}

/// endModule - Emit all exception information that should come after the
/// content.
void Win64Exception::endModule() {
}

/// beginFunction - Gather pre-function exception information. Assumes it's
/// being emitted immediately after the function entry point.
void Win64Exception::beginFunction(const MachineFunction *MF) {
  shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false;

  // If any landing pads survive, we need an EH table.
  bool hasLandingPads = !MMI->getLandingPads().empty();

  shouldEmitMoves = Asm->needsSEHMoves();

  const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
  unsigned PerEncoding = TLOF.getPersonalityEncoding();
  const Function *Per = MF->getMMI().getPersonality();

  shouldEmitPersonality = hasLandingPads &&
    PerEncoding != dwarf::DW_EH_PE_omit && Per;

  unsigned LSDAEncoding = TLOF.getLSDAEncoding();
  shouldEmitLSDA = shouldEmitPersonality &&
    LSDAEncoding != dwarf::DW_EH_PE_omit;

  if (!shouldEmitPersonality && !shouldEmitMoves)
    return;

  Asm->OutStreamer.EmitWinCFIStartProc(Asm->CurrentFnSym);

  if (!shouldEmitPersonality)
    return;

  const MCSymbol *PersHandlerSym =
      TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI);
  Asm->OutStreamer.EmitWinEHHandler(PersHandlerSym, true, true);

  Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
                                                Asm->getFunctionNumber()));
}

/// endFunction - Gather and emit post-function exception information.
///
void Win64Exception::endFunction(const MachineFunction *) {
  if (!shouldEmitPersonality && !shouldEmitMoves)
    return;

  Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end",
                                                Asm->getFunctionNumber()));

  // Map all labels and get rid of any dead landing pads.
  MMI->TidyLandingPads();

  if (shouldEmitPersonality) {
    Asm->OutStreamer.PushSection();

    // Emit an UNWIND_INFO struct describing the prologue.
    Asm->OutStreamer.EmitWinEHHandlerData();

    // Emit the tables appropriate to the personality function in use. If we
    // don't recognize the personality, assume it uses an Itanium-style LSDA.
    const Function *Per = MMI->getPersonality();
    if (Per->getName() == "__C_specific_handler")
      emitCSpecificHandlerTable();
    else
      emitExceptionTable();

    Asm->OutStreamer.PopSection();
  }
  Asm->OutStreamer.EmitWinCFIEndProc();
}

const MCSymbolRefExpr *Win64Exception::createImageRel32(const MCSymbol *Value) {
  return MCSymbolRefExpr::Create(Value, MCSymbolRefExpr::VK_COFF_IMGREL32,
                                 Asm->OutContext);
}

/// Emit the language-specific data that __C_specific_handler expects.  This
/// handler lives in the x64 Microsoft C runtime and allows catching or cleaning
/// up after faults with __try, __except, and __finally.  The typeinfo values
/// are not really RTTI data, but pointers to filter functions that return an
/// integer (1, 0, or -1) indicating how to handle the exception. For __finally
/// blocks and other cleanups, the landing pad label is zero, and the filter
/// function is actually a cleanup handler with the same prototype.  A catch-all
/// entry is modeled with a null filter function field and a non-zero landing
/// pad label.
///
/// Possible filter function return values:
///   EXCEPTION_EXECUTE_HANDLER (1):
///     Jump to the landing pad label after cleanups.
///   EXCEPTION_CONTINUE_SEARCH (0):
///     Continue searching this table or continue unwinding.
///   EXCEPTION_CONTINUE_EXECUTION (-1):
///     Resume execution at the trapping PC.
///
/// Inferred table structure:
///   struct Table {
///     int NumEntries;
///     struct Entry {
///       imagerel32 LabelStart;
///       imagerel32 LabelEnd;
///       imagerel32 FilterOrFinally;  // Zero means catch-all.
///       imagerel32 LabelLPad;        // Zero means __finally.
///     } Entries[NumEntries];
///   };
void Win64Exception::emitCSpecificHandlerTable() {
  const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();

  // Simplifying assumptions for first implementation:
  // - Cleanups are not implemented.
  // - Filters are not implemented.

  // The Itanium LSDA table sorts similar landing pads together to simplify the
  // actions table, but we don't need that.
  SmallVector<const LandingPadInfo *, 64> LandingPads;
  LandingPads.reserve(PadInfos.size());
  for (const auto &LP : PadInfos)
    LandingPads.push_back(&LP);

  // Compute label ranges for call sites as we would for the Itanium LSDA, but
  // use an all zero action table because we aren't using these actions.
  SmallVector<unsigned, 64> FirstActions;
  FirstActions.resize(LandingPads.size());
  SmallVector<CallSiteEntry, 64> CallSites;
  computeCallSiteTable(CallSites, LandingPads, FirstActions);

  MCSymbol *EHFuncBeginSym =
      Asm->GetTempSymbol("eh_func_begin", Asm->getFunctionNumber());
  MCSymbol *EHFuncEndSym =
      Asm->GetTempSymbol("eh_func_end", Asm->getFunctionNumber());

  // Emit the number of table entries.
  unsigned NumEntries = 0;
  for (const CallSiteEntry &CSE : CallSites) {
    if (!CSE.LPad)
      continue; // Ignore gaps.
    for (int Selector : CSE.LPad->TypeIds) {
      // Ignore C++ filter clauses in SEH.
      // FIXME: Implement cleanup clauses.
      if (isCatchEHSelector(Selector))
        ++NumEntries;
    }
  }
  Asm->OutStreamer.EmitIntValue(NumEntries, 4);

  // Emit the four-label records for each call site entry. The table has to be
  // sorted in layout order, and the call sites should already be sorted.
  for (const CallSiteEntry &CSE : CallSites) {
    // Ignore gaps. Unlike the Itanium model, unwinding through a frame without
    // an EH table entry will propagate the exception rather than terminating
    // the program.
    if (!CSE.LPad)
      continue;
    const LandingPadInfo *LPad = CSE.LPad;

    // Compute the label range. We may reuse the function begin and end labels
    // rather than forming new ones.
    const MCExpr *Begin =
        createImageRel32(CSE.BeginLabel ? CSE.BeginLabel : EHFuncBeginSym);
    const MCExpr *End;
    if (CSE.EndLabel) {
      // The interval is half-open, so we have to add one to include the return
      // address of the last invoke in the range.
      End = MCBinaryExpr::CreateAdd(createImageRel32(CSE.EndLabel),
                                    MCConstantExpr::Create(1, Asm->OutContext),
                                    Asm->OutContext);
    } else {
      End = createImageRel32(EHFuncEndSym);
    }

    // These aren't really type info globals, they are actually pointers to
    // filter functions ordered by selector. The zero selector is used for
    // cleanups, so slot zero corresponds to selector 1.
    const std::vector<const GlobalValue *> &SelectorToFilter = MMI->getTypeInfos();

    // Do a parallel iteration across typeids and clause labels, skipping filter
    // clauses.
    assert(LPad->TypeIds.size() == LPad->ClauseLabels.size());
    for (size_t I = 0, E = LPad->TypeIds.size(); I < E; ++I) {
      // AddLandingPadInfo stores the clauses in reverse, but there is a FIXME
      // to change that.
      int Selector = LPad->TypeIds[E - I - 1];
      MCSymbol *ClauseLabel = LPad->ClauseLabels[I];

      // Ignore C++ filter clauses in SEH.
      // FIXME: Implement cleanup clauses.
      if (!isCatchEHSelector(Selector))
        continue;

      Asm->OutStreamer.EmitValue(Begin, 4);
      Asm->OutStreamer.EmitValue(End, 4);
      if (isCatchEHSelector(Selector)) {
        assert(unsigned(Selector - 1) < SelectorToFilter.size());
        const GlobalValue *TI = SelectorToFilter[Selector - 1];
        if (TI) // Emit the filter function pointer.
          Asm->OutStreamer.EmitValue(createImageRel32(Asm->getSymbol(TI)), 4);
        else  // Otherwise, this is a "catch i8* null", or catch all.
          Asm->OutStreamer.EmitIntValue(0, 4);
      }
      Asm->OutStreamer.EmitValue(createImageRel32(ClauseLabel), 4);
    }
  }
}
<commit_msg>Win64Exception.cpp: Try to fix crash for x64 EH. "Per" might be null there.<commit_after>//===-- CodeGen/AsmPrinter/Win64Exception.cpp - Dwarf Exception Impl ------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains support for writing Win64 exception info into asm files.
//
//===----------------------------------------------------------------------===//

#include "Win64Exception.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;

Win64Exception::Win64Exception(AsmPrinter *A)
  : EHStreamer(A), shouldEmitPersonality(false), shouldEmitLSDA(false),
    shouldEmitMoves(false) {}

Win64Exception::~Win64Exception() {}

/// endModule - Emit all exception information that should come after the
/// content.
void Win64Exception::endModule() {
}

/// beginFunction - Gather pre-function exception information. Assumes it's
/// being emitted immediately after the function entry point.
void Win64Exception::beginFunction(const MachineFunction *MF) {
  shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false;

  // If any landing pads survive, we need an EH table.
  bool hasLandingPads = !MMI->getLandingPads().empty();

  shouldEmitMoves = Asm->needsSEHMoves();

  const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
  unsigned PerEncoding = TLOF.getPersonalityEncoding();
  const Function *Per = MF->getMMI().getPersonality();

  shouldEmitPersonality = hasLandingPads &&
    PerEncoding != dwarf::DW_EH_PE_omit && Per;

  unsigned LSDAEncoding = TLOF.getLSDAEncoding();
  shouldEmitLSDA = shouldEmitPersonality &&
    LSDAEncoding != dwarf::DW_EH_PE_omit;

  if (!shouldEmitPersonality && !shouldEmitMoves)
    return;

  Asm->OutStreamer.EmitWinCFIStartProc(Asm->CurrentFnSym);

  if (!shouldEmitPersonality)
    return;

  const MCSymbol *PersHandlerSym =
      TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI);
  Asm->OutStreamer.EmitWinEHHandler(PersHandlerSym, true, true);

  Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
                                                Asm->getFunctionNumber()));
}

/// endFunction - Gather and emit post-function exception information.
///
void Win64Exception::endFunction(const MachineFunction *) {
  if (!shouldEmitPersonality && !shouldEmitMoves)
    return;

  Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end",
                                                Asm->getFunctionNumber()));

  // Map all labels and get rid of any dead landing pads.
  MMI->TidyLandingPads();

  if (shouldEmitPersonality) {
    Asm->OutStreamer.PushSection();

    // Emit an UNWIND_INFO struct describing the prologue.
    Asm->OutStreamer.EmitWinEHHandlerData();

    // Emit the tables appropriate to the personality function in use. If we
    // don't recognize the personality, assume it uses an Itanium-style LSDA.
    const Function *Per = MMI->getPersonality();
    if (Per && Per->getName() == "__C_specific_handler")
      emitCSpecificHandlerTable();
    else
      emitExceptionTable();

    Asm->OutStreamer.PopSection();
  }
  Asm->OutStreamer.EmitWinCFIEndProc();
}

const MCSymbolRefExpr *Win64Exception::createImageRel32(const MCSymbol *Value) {
  return MCSymbolRefExpr::Create(Value, MCSymbolRefExpr::VK_COFF_IMGREL32,
                                 Asm->OutContext);
}

/// Emit the language-specific data that __C_specific_handler expects.  This
/// handler lives in the x64 Microsoft C runtime and allows catching or cleaning
/// up after faults with __try, __except, and __finally.  The typeinfo values
/// are not really RTTI data, but pointers to filter functions that return an
/// integer (1, 0, or -1) indicating how to handle the exception. For __finally
/// blocks and other cleanups, the landing pad label is zero, and the filter
/// function is actually a cleanup handler with the same prototype.  A catch-all
/// entry is modeled with a null filter function field and a non-zero landing
/// pad label.
///
/// Possible filter function return values:
///   EXCEPTION_EXECUTE_HANDLER (1):
///     Jump to the landing pad label after cleanups.
///   EXCEPTION_CONTINUE_SEARCH (0):
///     Continue searching this table or continue unwinding.
///   EXCEPTION_CONTINUE_EXECUTION (-1):
///     Resume execution at the trapping PC.
///
/// Inferred table structure:
///   struct Table {
///     int NumEntries;
///     struct Entry {
///       imagerel32 LabelStart;
///       imagerel32 LabelEnd;
///       imagerel32 FilterOrFinally;  // Zero means catch-all.
///       imagerel32 LabelLPad;        // Zero means __finally.
///     } Entries[NumEntries];
///   };
void Win64Exception::emitCSpecificHandlerTable() {
  const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();

  // Simplifying assumptions for first implementation:
  // - Cleanups are not implemented.
  // - Filters are not implemented.

  // The Itanium LSDA table sorts similar landing pads together to simplify the
  // actions table, but we don't need that.
  SmallVector<const LandingPadInfo *, 64> LandingPads;
  LandingPads.reserve(PadInfos.size());
  for (const auto &LP : PadInfos)
    LandingPads.push_back(&LP);

  // Compute label ranges for call sites as we would for the Itanium LSDA, but
  // use an all zero action table because we aren't using these actions.
  SmallVector<unsigned, 64> FirstActions;
  FirstActions.resize(LandingPads.size());
  SmallVector<CallSiteEntry, 64> CallSites;
  computeCallSiteTable(CallSites, LandingPads, FirstActions);

  MCSymbol *EHFuncBeginSym =
      Asm->GetTempSymbol("eh_func_begin", Asm->getFunctionNumber());
  MCSymbol *EHFuncEndSym =
      Asm->GetTempSymbol("eh_func_end", Asm->getFunctionNumber());

  // Emit the number of table entries.
  unsigned NumEntries = 0;
  for (const CallSiteEntry &CSE : CallSites) {
    if (!CSE.LPad)
      continue; // Ignore gaps.
    for (int Selector : CSE.LPad->TypeIds) {
      // Ignore C++ filter clauses in SEH.
      // FIXME: Implement cleanup clauses.
      if (isCatchEHSelector(Selector))
        ++NumEntries;
    }
  }
  Asm->OutStreamer.EmitIntValue(NumEntries, 4);

  // Emit the four-label records for each call site entry. The table has to be
  // sorted in layout order, and the call sites should already be sorted.
  for (const CallSiteEntry &CSE : CallSites) {
    // Ignore gaps. Unlike the Itanium model, unwinding through a frame without
    // an EH table entry will propagate the exception rather than terminating
    // the program.
    if (!CSE.LPad)
      continue;
    const LandingPadInfo *LPad = CSE.LPad;

    // Compute the label range. We may reuse the function begin and end labels
    // rather than forming new ones.
    const MCExpr *Begin =
        createImageRel32(CSE.BeginLabel ? CSE.BeginLabel : EHFuncBeginSym);
    const MCExpr *End;
    if (CSE.EndLabel) {
      // The interval is half-open, so we have to add one to include the return
      // address of the last invoke in the range.
      End = MCBinaryExpr::CreateAdd(createImageRel32(CSE.EndLabel),
                                    MCConstantExpr::Create(1, Asm->OutContext),
                                    Asm->OutContext);
    } else {
      End = createImageRel32(EHFuncEndSym);
    }

    // These aren't really type info globals, they are actually pointers to
    // filter functions ordered by selector. The zero selector is used for
    // cleanups, so slot zero corresponds to selector 1.
    const std::vector<const GlobalValue *> &SelectorToFilter = MMI->getTypeInfos();

    // Do a parallel iteration across typeids and clause labels, skipping filter
    // clauses.
    assert(LPad->TypeIds.size() == LPad->ClauseLabels.size());
    for (size_t I = 0, E = LPad->TypeIds.size(); I < E; ++I) {
      // AddLandingPadInfo stores the clauses in reverse, but there is a FIXME
      // to change that.
      int Selector = LPad->TypeIds[E - I - 1];
      MCSymbol *ClauseLabel = LPad->ClauseLabels[I];

      // Ignore C++ filter clauses in SEH.
      // FIXME: Implement cleanup clauses.
      if (!isCatchEHSelector(Selector))
        continue;

      Asm->OutStreamer.EmitValue(Begin, 4);
      Asm->OutStreamer.EmitValue(End, 4);
      if (isCatchEHSelector(Selector)) {
        assert(unsigned(Selector - 1) < SelectorToFilter.size());
        const GlobalValue *TI = SelectorToFilter[Selector - 1];
        if (TI) // Emit the filter function pointer.
          Asm->OutStreamer.EmitValue(createImageRel32(Asm->getSymbol(TI)), 4);
        else  // Otherwise, this is a "catch i8* null", or catch all.
          Asm->OutStreamer.EmitIntValue(0, 4);
      }
      Asm->OutStreamer.EmitValue(createImageRel32(ClauseLabel), 4);
    }
  }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SdUnoOutlineView.hxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 05:13:43 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SD_UNO_OUTLINE_VIEW_HXX
#define SD_UNO_OUTLINE_VIEW_HXX

#ifndef SD_DRAW_CONTROLLER_HXX
#include "DrawController.hxx"
#endif

class SdPage;

namespace sd {

class OutlineViewShell;
class View;

/**
 * This class implements the view component for a SdOutlineViewShell
 */
class SdUnoOutlineView
    : public DrawController
{
public:
    enum properties
    {
        PROPERTY__BEGIN = DrawController::PROPERTY__END,
        PROPERTY_CURRENTPAGE = PROPERTY__BEGIN,
        PROPERTY__END
    };
    SdUnoOutlineView (
        ViewShellBase& rBase,
        OutlineViewShell& rViewShell,
        View& rView) throw();
    virtual ~SdUnoOutlineView() throw();

    virtual void FireSwitchCurrentPage (SdPage* pCurrentPage) throw();

    // XTypeProvider
    virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId(  ) throw(::com::sun::star::uno::RuntimeException);

    // XServiceInfo
    virtual ::rtl::OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);

    // XSelectionSupplier
    virtual sal_Bool SAL_CALL select( const ::com::sun::star::uno::Any& aSelection ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Any SAL_CALL getSelection(  ) throw(::com::sun::star::uno::RuntimeException);

    // XDrawView
    virtual void SAL_CALL setCurrentPage( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >& xPage ) throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > SAL_CALL getCurrentPage(  ) throw(::com::sun::star::uno::RuntimeException);

protected:
    virtual void FillPropertyTable (
        ::std::vector< ::com::sun::star::beans::Property>& rProperties);

    virtual sal_Bool SAL_CALL convertFastPropertyValue(
        ::com::sun::star::uno::Any & rConvertedValue,
        ::com::sun::star::uno::Any & rOldValue,
        sal_Int32 nHandle,
        const ::com::sun::star::uno::Any& rValue )
        throw (::com::sun::star::lang::IllegalArgumentException);
    virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
        sal_Int32 nHandle,
        const ::com::sun::star::uno::Any& rValue )
        throw (::com::sun::star::uno::Exception);
    virtual void SAL_CALL getFastPropertyValue(
        ::com::sun::star::uno::Any& rValue,
        sal_Int32 nHandle ) const;

private:
    SdPage* mpCurrentPage;

    /** This is a shortcut for accessing the view shell data member of
        the base class casted to the correct class.
        @return
            The returned pointer may be NULL.
    */
    OutlineViewShell* GetDrawViewShell (void) const;
};

} // end of namespace sd

#endif
<commit_msg>INTEGRATION: CWS impress73 (1.11.38); FILE MERGED 2005/10/24 14:25:32 af 1.11.38.1: #126153# Changed mpCurrentPage into UNO reference mxCurrentPage.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SdUnoOutlineView.hxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: rt $ $Date: 2005-11-08 09:04:36 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SD_UNO_OUTLINE_VIEW_HXX
#define SD_UNO_OUTLINE_VIEW_HXX

#ifndef SD_DRAW_CONTROLLER_HXX
#include "DrawController.hxx"
#endif

class SdPage;

namespace sd {

class OutlineViewShell;
class View;

/**
 * This class implements the view component for a SdOutlineViewShell
 */
class SdUnoOutlineView
    : public DrawController
{
public:
    enum properties
    {
        PROPERTY__BEGIN = DrawController::PROPERTY__END,
        PROPERTY_CURRENTPAGE = PROPERTY__BEGIN,
        PROPERTY__END
    };
    SdUnoOutlineView (
        ViewShellBase& rBase,
        OutlineViewShell& rViewShell,
        View& rView) throw();
    virtual ~SdUnoOutlineView() throw();

    virtual void FireSwitchCurrentPage (SdPage* pCurrentPage) throw();

    // XComponent
    virtual void SAL_CALL dispose() throw( ::com::sun::star::uno::RuntimeException );

    // XTypeProvider
    virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId(  ) throw(::com::sun::star::uno::RuntimeException);

    // XServiceInfo
    virtual ::rtl::OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);

    // XSelectionSupplier
    virtual sal_Bool SAL_CALL select( const ::com::sun::star::uno::Any& aSelection ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Any SAL_CALL getSelection(  ) throw(::com::sun::star::uno::RuntimeException);

    // XDrawView
    virtual void SAL_CALL setCurrentPage( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >& xPage ) throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > SAL_CALL getCurrentPage(  ) throw(::com::sun::star::uno::RuntimeException);

protected:
    virtual void FillPropertyTable (
        ::std::vector< ::com::sun::star::beans::Property>& rProperties);

    virtual sal_Bool SAL_CALL convertFastPropertyValue(
        ::com::sun::star::uno::Any & rConvertedValue,
        ::com::sun::star::uno::Any & rOldValue,
        sal_Int32 nHandle,
        const ::com::sun::star::uno::Any& rValue )
        throw (::com::sun::star::lang::IllegalArgumentException);
    virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
        sal_Int32 nHandle,
        const ::com::sun::star::uno::Any& rValue )
        throw (::com::sun::star::uno::Exception);
    virtual void SAL_CALL getFastPropertyValue(
        ::com::sun::star::uno::Any& rValue,
        sal_Int32 nHandle ) const;

    // lang::XEventListener
    virtual void SAL_CALL
        disposing (const ::com::sun::star::lang::EventObject& rEventObject)
        throw (::com::sun::star::uno::RuntimeException);

private:
    ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage> mxCurrentPage;

    /** This is a shortcut for accessing the view shell data member of
        the base class casted to the correct class.
        @return
            The returned pointer may be NULL.
    */
    OutlineViewShell* GetDrawViewShell (void) const;
};

} // end of namespace sd

#endif
<|endoftext|>