<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <fcntl.h>
#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <unistd.h>

#include "base/file_util.h"
#include "base/third_party/valgrind/valgrind.h"
#include "sandbox/linux/tests/unit_tests.h"

namespace {
std::string TestFailedMessage(const std::string& msg) {
  return msg.empty() ? "" : "Actual test failure: " + msg;
}

int GetSubProcessTimeoutTimeInSeconds() {
  // 10s ought to be enough for anybody.
  return 10;
}

// Returns the number of threads of the current process or -1.
int CountThreads() {
  struct stat task_stat;
  int task_d = stat("/proc/self/task", &task_stat);
  // task_stat.st_nlink should be the number of tasks + 2 (accounting for
  // "." and "..".
  if (task_d != 0 || task_stat.st_nlink < 3)
    return -1;
  return task_stat.st_nlink - 2;
}

}  // namespace

namespace sandbox {

static const int kExpectedValue = 42;
static const int kIgnoreThisTest = 43;
static const int kExitWithAssertionFailure = 1;
static const int kExitForTimeout = 2;

static void SigAlrmHandler(int) {
    const char failure_message[] = "Timeout reached!\n";
    // Make sure that we never block here.
    if (!fcntl(2, F_SETFL,  O_NONBLOCK)) {
      if (write(2, failure_message, sizeof(failure_message) - 1) < 0) {
      }
    }
    _exit(kExitForTimeout);
}

// Set a timeout with a handler that will automatically fail the
// test.
static void SetProcessTimeout(int time_in_seconds) {
  struct sigaction act = {};
  act.sa_handler = SigAlrmHandler;
  SANDBOX_ASSERT(sigemptyset(&act.sa_mask) == 0);
  act.sa_flags = 0;

  struct sigaction old_act;
  SANDBOX_ASSERT(sigaction(SIGALRM, &act, &old_act) == 0);

  // We don't implemenet signal chaining, so make sure that nothing else
  // is expecting to handle SIGALRM.
  SANDBOX_ASSERT((old_act.sa_flags & SA_SIGINFO) == 0);
  SANDBOX_ASSERT(old_act.sa_handler == SIG_DFL);
  sigset_t sigalrm_set;
  SANDBOX_ASSERT(sigemptyset(&sigalrm_set) == 0);
  SANDBOX_ASSERT(sigaddset(&sigalrm_set, SIGALRM) == 0);
  SANDBOX_ASSERT(sigprocmask(SIG_UNBLOCK, &sigalrm_set, NULL) == 0);
  SANDBOX_ASSERT(alarm(time_in_seconds) == 0);  // There should be no previous
                                                // alarm.
}

// Runs a test in a sub-process. This is necessary for most of the code
// in the BPF sandbox, as it potentially makes global state changes and as
// it also tends to raise fatal errors, if the code has been used in an
// insecure manner.
void UnitTests::RunTestInProcess(UnitTests::Test test, void *arg,
                                 DeathCheck death, const void *death_aux) {
  if (CountThreads() != 1) {
    // We need to use fork(), so we can't be multi-threaded.
    // TODO(jln): change this to a fatal error once we can launch
    // Android tests with --exe.
    fprintf(stderr, "WARNING: running sandbox tests with multiple threads"
                    " is not supported and will make the tests flaky.\n");
  }
  int fds[2];
  ASSERT_EQ(0, pipe(fds));
  // Check that our pipe is not on one of the standard file descriptor.
  SANDBOX_ASSERT(fds[0] > 2 && fds[1] > 2);

  pid_t pid;
  ASSERT_LE(0, (pid = fork()));
  if (!pid) {
    // In child process
    // Redirect stderr to our pipe. This way, we can capture all error
    // messages, if we decide we want to do so in our tests.
    SANDBOX_ASSERT(dup2(fds[1], 2) == 2);
    SANDBOX_ASSERT(!close(fds[0]));
    SANDBOX_ASSERT(!close(fds[1]));

    // Don't set a timeout if running on Valgrind, since it's generally much
    // slower.
    if (!RUNNING_ON_VALGRIND) {
      SetProcessTimeout(GetSubProcessTimeoutTimeInSeconds());
    }

    // Disable core files. They are not very useful for our individual test
    // cases.
    struct rlimit no_core = { 0 };
    setrlimit(RLIMIT_CORE, &no_core);

    test(arg);
    _exit(kExpectedValue);
  }

  (void)HANDLE_EINTR(close(fds[1]));
  std::vector<char> msg_buf;
  ssize_t rc;

  // Make sure read() will never block as we'll use poll() to
  // block with a timeout instead.
  const int fcntl_ret = fcntl(fds[0], F_SETFL,  O_NONBLOCK);
  ASSERT_EQ(fcntl_ret, 0);
  struct pollfd poll_fd = { fds[0], POLLIN | POLLRDHUP, 0 };

  int poll_ret;
  // We prefer the SIGALRM timeout to trigger in the child than this timeout
  // so we double the common value here.
  int poll_timeout = GetSubProcessTimeoutTimeInSeconds() * 2 * 1000;
  while ((poll_ret = poll(&poll_fd, 1, poll_timeout) > 0)) {
    const size_t kCapacity = 256;
    const size_t len = msg_buf.size();
    msg_buf.resize(len + kCapacity);
    rc = HANDLE_EINTR(read(fds[0], &msg_buf[len], kCapacity));
    msg_buf.resize(len + std::max(rc, static_cast<ssize_t>(0)));
    if (rc <= 0)
      break;
  }
  ASSERT_NE(poll_ret, -1) << "poll() failed";
  ASSERT_NE(poll_ret, 0) << "Timeout while reading child state";
  (void)HANDLE_EINTR(close(fds[0]));
  std::string msg(msg_buf.begin(), msg_buf.end());

  int status = 0;
  int waitpid_returned = HANDLE_EINTR(waitpid(pid, &status, 0));
  ASSERT_EQ(pid, waitpid_returned) << TestFailedMessage(msg);

  // At run-time, we sometimes decide that a test shouldn't actually
  // run (e.g. when testing sandbox features on a kernel that doesn't
  // have sandboxing support). When that happens, don't attempt to
  // call the "death" function, as it might be looking for a
  // death-test condition that would never have triggered.
  if (!WIFEXITED(status) || WEXITSTATUS(status) != kIgnoreThisTest ||
      !msg.empty()) {
    // We use gtest's ASSERT_XXX() macros instead of the DeathCheck
    // functions.  This means, on failure, "return" is called. This
    // only works correctly, if the call of the "death" callback is
    // the very last thing in our function.
    death(status, msg, death_aux);
  }
}

void UnitTests::DeathSuccess(int status, const std::string& msg,
                             const void *) {
  std::string details(TestFailedMessage(msg));

  bool subprocess_terminated_normally = WIFEXITED(status);
  ASSERT_TRUE(subprocess_terminated_normally) << details;
  int subprocess_exit_status = WEXITSTATUS(status);
  ASSERT_EQ(kExpectedValue, subprocess_exit_status) << details;
  bool subprocess_exited_but_printed_messages = !msg.empty();
  EXPECT_FALSE(subprocess_exited_but_printed_messages) << details;
}

void UnitTests::DeathMessage(int status, const std::string& msg,
                             const void *aux) {
  std::string details(TestFailedMessage(msg));
  const char *expected_msg = static_cast<const char *>(aux);

  bool subprocess_terminated_normally = WIFEXITED(status);
  ASSERT_TRUE(subprocess_terminated_normally) << details;
  int subprocess_exit_status = WEXITSTATUS(status);
  ASSERT_EQ(kExitWithAssertionFailure, subprocess_exit_status) << details;
  bool subprocess_exited_without_matching_message =
    msg.find(expected_msg) == std::string::npos;
  EXPECT_FALSE(subprocess_exited_without_matching_message) << details;
}

void UnitTests::DeathExitCode(int status, const std::string& msg,
                              const void *aux) {
  int expected_exit_code = static_cast<int>(reinterpret_cast<intptr_t>(aux));
  std::string details(TestFailedMessage(msg));

  bool subprocess_terminated_normally = WIFEXITED(status);
  ASSERT_TRUE(subprocess_terminated_normally) << details;
  int subprocess_exit_status = WEXITSTATUS(status);
  ASSERT_EQ(subprocess_exit_status, expected_exit_code) << details;
}

void UnitTests::DeathBySignal(int status, const std::string& msg,
                              const void *aux) {
  int expected_signo = static_cast<int>(reinterpret_cast<intptr_t>(aux));
  std::string details(TestFailedMessage(msg));

  bool subprocess_terminated_by_signal = WIFSIGNALED(status);
  ASSERT_TRUE(subprocess_terminated_by_signal) << details;
  int subprocess_signal_number = WTERMSIG(status);
  ASSERT_EQ(subprocess_signal_number, expected_signo) << details;
}

void UnitTests::AssertionFailure(const char *expr, const char *file,
                                 int line) {
  fprintf(stderr, "%s:%d:%s", file, line, expr);
  fflush(stderr);
  _exit(kExitWithAssertionFailure);
}

void UnitTests::IgnoreThisTest() {
  fflush(stderr);
  _exit(kIgnoreThisTest);
}

}  // namespace
<commit_msg>Linux Sandbox: assert monothreaded in tests<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <fcntl.h>
#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <unistd.h>

#include "base/file_util.h"
#include "base/third_party/valgrind/valgrind.h"
#include "sandbox/linux/tests/unit_tests.h"

namespace {
std::string TestFailedMessage(const std::string& msg) {
  return msg.empty() ? "" : "Actual test failure: " + msg;
}

int GetSubProcessTimeoutTimeInSeconds() {
  // 10s ought to be enough for anybody.
  return 10;
}

// Returns the number of threads of the current process or -1.
int CountThreads() {
  struct stat task_stat;
  int task_d = stat("/proc/self/task", &task_stat);
  // task_stat.st_nlink should be the number of tasks + 2 (accounting for
  // "." and "..".
  if (task_d != 0 || task_stat.st_nlink < 3)
    return -1;
  return task_stat.st_nlink - 2;
}

}  // namespace

namespace sandbox {

static const int kExpectedValue = 42;
static const int kIgnoreThisTest = 43;
static const int kExitWithAssertionFailure = 1;
static const int kExitForTimeout = 2;

static void SigAlrmHandler(int) {
    const char failure_message[] = "Timeout reached!\n";
    // Make sure that we never block here.
    if (!fcntl(2, F_SETFL,  O_NONBLOCK)) {
      if (write(2, failure_message, sizeof(failure_message) - 1) < 0) {
      }
    }
    _exit(kExitForTimeout);
}

// Set a timeout with a handler that will automatically fail the
// test.
static void SetProcessTimeout(int time_in_seconds) {
  struct sigaction act = {};
  act.sa_handler = SigAlrmHandler;
  SANDBOX_ASSERT(sigemptyset(&act.sa_mask) == 0);
  act.sa_flags = 0;

  struct sigaction old_act;
  SANDBOX_ASSERT(sigaction(SIGALRM, &act, &old_act) == 0);

  // We don't implemenet signal chaining, so make sure that nothing else
  // is expecting to handle SIGALRM.
  SANDBOX_ASSERT((old_act.sa_flags & SA_SIGINFO) == 0);
  SANDBOX_ASSERT(old_act.sa_handler == SIG_DFL);
  sigset_t sigalrm_set;
  SANDBOX_ASSERT(sigemptyset(&sigalrm_set) == 0);
  SANDBOX_ASSERT(sigaddset(&sigalrm_set, SIGALRM) == 0);
  SANDBOX_ASSERT(sigprocmask(SIG_UNBLOCK, &sigalrm_set, NULL) == 0);
  SANDBOX_ASSERT(alarm(time_in_seconds) == 0);  // There should be no previous
                                                // alarm.
}

// Runs a test in a sub-process. This is necessary for most of the code
// in the BPF sandbox, as it potentially makes global state changes and as
// it also tends to raise fatal errors, if the code has been used in an
// insecure manner.
void UnitTests::RunTestInProcess(UnitTests::Test test, void *arg,
                                 DeathCheck death, const void *death_aux) {
  // We need to fork(), so we can't be multi-threaded, as threads could hold
  // locks.
  ASSERT_EQ(1, CountThreads()) << "Running sandbox tests with multiple threads "
                               << "is not supported and will make the tests "
                               << "flaky.\n";
  int fds[2];
  ASSERT_EQ(0, pipe(fds));
  // Check that our pipe is not on one of the standard file descriptor.
  SANDBOX_ASSERT(fds[0] > 2 && fds[1] > 2);

  pid_t pid;
  ASSERT_LE(0, (pid = fork()));
  if (!pid) {
    // In child process
    // Redirect stderr to our pipe. This way, we can capture all error
    // messages, if we decide we want to do so in our tests.
    SANDBOX_ASSERT(dup2(fds[1], 2) == 2);
    SANDBOX_ASSERT(!close(fds[0]));
    SANDBOX_ASSERT(!close(fds[1]));

    // Don't set a timeout if running on Valgrind, since it's generally much
    // slower.
    if (!RUNNING_ON_VALGRIND) {
      SetProcessTimeout(GetSubProcessTimeoutTimeInSeconds());
    }

    // Disable core files. They are not very useful for our individual test
    // cases.
    struct rlimit no_core = { 0 };
    setrlimit(RLIMIT_CORE, &no_core);

    test(arg);
    _exit(kExpectedValue);
  }

  (void)HANDLE_EINTR(close(fds[1]));
  std::vector<char> msg_buf;
  ssize_t rc;

  // Make sure read() will never block as we'll use poll() to
  // block with a timeout instead.
  const int fcntl_ret = fcntl(fds[0], F_SETFL,  O_NONBLOCK);
  ASSERT_EQ(fcntl_ret, 0);
  struct pollfd poll_fd = { fds[0], POLLIN | POLLRDHUP, 0 };

  int poll_ret;
  // We prefer the SIGALRM timeout to trigger in the child than this timeout
  // so we double the common value here.
  int poll_timeout = GetSubProcessTimeoutTimeInSeconds() * 2 * 1000;
  while ((poll_ret = poll(&poll_fd, 1, poll_timeout) > 0)) {
    const size_t kCapacity = 256;
    const size_t len = msg_buf.size();
    msg_buf.resize(len + kCapacity);
    rc = HANDLE_EINTR(read(fds[0], &msg_buf[len], kCapacity));
    msg_buf.resize(len + std::max(rc, static_cast<ssize_t>(0)));
    if (rc <= 0)
      break;
  }
  ASSERT_NE(poll_ret, -1) << "poll() failed";
  ASSERT_NE(poll_ret, 0) << "Timeout while reading child state";
  (void)HANDLE_EINTR(close(fds[0]));
  std::string msg(msg_buf.begin(), msg_buf.end());

  int status = 0;
  int waitpid_returned = HANDLE_EINTR(waitpid(pid, &status, 0));
  ASSERT_EQ(pid, waitpid_returned) << TestFailedMessage(msg);

  // At run-time, we sometimes decide that a test shouldn't actually
  // run (e.g. when testing sandbox features on a kernel that doesn't
  // have sandboxing support). When that happens, don't attempt to
  // call the "death" function, as it might be looking for a
  // death-test condition that would never have triggered.
  if (!WIFEXITED(status) || WEXITSTATUS(status) != kIgnoreThisTest ||
      !msg.empty()) {
    // We use gtest's ASSERT_XXX() macros instead of the DeathCheck
    // functions.  This means, on failure, "return" is called. This
    // only works correctly, if the call of the "death" callback is
    // the very last thing in our function.
    death(status, msg, death_aux);
  }
}

void UnitTests::DeathSuccess(int status, const std::string& msg,
                             const void *) {
  std::string details(TestFailedMessage(msg));

  bool subprocess_terminated_normally = WIFEXITED(status);
  ASSERT_TRUE(subprocess_terminated_normally) << details;
  int subprocess_exit_status = WEXITSTATUS(status);
  ASSERT_EQ(kExpectedValue, subprocess_exit_status) << details;
  bool subprocess_exited_but_printed_messages = !msg.empty();
  EXPECT_FALSE(subprocess_exited_but_printed_messages) << details;
}

void UnitTests::DeathMessage(int status, const std::string& msg,
                             const void *aux) {
  std::string details(TestFailedMessage(msg));
  const char *expected_msg = static_cast<const char *>(aux);

  bool subprocess_terminated_normally = WIFEXITED(status);
  ASSERT_TRUE(subprocess_terminated_normally) << details;
  int subprocess_exit_status = WEXITSTATUS(status);
  ASSERT_EQ(kExitWithAssertionFailure, subprocess_exit_status) << details;
  bool subprocess_exited_without_matching_message =
    msg.find(expected_msg) == std::string::npos;
  EXPECT_FALSE(subprocess_exited_without_matching_message) << details;
}

void UnitTests::DeathExitCode(int status, const std::string& msg,
                              const void *aux) {
  int expected_exit_code = static_cast<int>(reinterpret_cast<intptr_t>(aux));
  std::string details(TestFailedMessage(msg));

  bool subprocess_terminated_normally = WIFEXITED(status);
  ASSERT_TRUE(subprocess_terminated_normally) << details;
  int subprocess_exit_status = WEXITSTATUS(status);
  ASSERT_EQ(subprocess_exit_status, expected_exit_code) << details;
}

void UnitTests::DeathBySignal(int status, const std::string& msg,
                              const void *aux) {
  int expected_signo = static_cast<int>(reinterpret_cast<intptr_t>(aux));
  std::string details(TestFailedMessage(msg));

  bool subprocess_terminated_by_signal = WIFSIGNALED(status);
  ASSERT_TRUE(subprocess_terminated_by_signal) << details;
  int subprocess_signal_number = WTERMSIG(status);
  ASSERT_EQ(subprocess_signal_number, expected_signo) << details;
}

void UnitTests::AssertionFailure(const char *expr, const char *file,
                                 int line) {
  fprintf(stderr, "%s:%d:%s", file, line, expr);
  fflush(stderr);
  _exit(kExitWithAssertionFailure);
}

void UnitTests::IgnoreThisTest() {
  fflush(stderr);
  _exit(kIgnoreThisTest);
}

}  // namespace
<|endoftext|>


<commit_before>/**
   m30c10 keyboard firmware for TeensyLC
   https://github.com/hoosierEE/m30c10
*/
#include <Arduino.h>
const uint32_t MS_OUT{10}; elapsedMillis t; // min. output period

//// Model
static const uint8_t COLS{5}; // 2 columns for index finger, 1 each for middle/ring/pinkie
static const uint8_t ROWS{6}; // 3 rows per hand
const int TEENSY_ROW_PIN[ROWS]{10,11,12,14,20,21};
const int TEENSY_COL_PIN[COLS]{2,5,6,7,8}; // pin 9 is also available if more switches req'd
struct Grid { bool keys[COLS][ROWS]; } raw_grid;

//// Key Layers
char *default_layer[]{"qwert","yuiop","asdfg","hjkl'" ,"zxcvb","nm,.-"};
char *shifted_layer[]{"QWERT","YUIOP","ASDFG","HJKL\"","ZXCVB","NM?!:"};
char *numeric_layer[]{"75319","02468","12345","67890" ,"():,%",".+-*/"};
char *symbol_layer []{"@#$%[","]^&*|"," -+=(",");:/\\","_~`!{","}<,.>"};

//// Functions
void set_pins(void)
{
    for (int i=0;i<COLS;++i) {
        pinMode(TEENSY_COL_PIN[i], OUTPUT);
        for (int j=0;j<ROWS;++j) {
            pinMode(TEENSY_ROW_PIN[j], INPUT_PULLUP);
        }
    }
}

Grid scan(void)
{
    Grid g;
    for (int i=0;i<COLS;++i) {
        digitalWrite(TEENSY_COL_PIN[i],LOW); // pull column low
        for (int j=0;j<ROWS;++j) {
            g.keys[i][j] = digitalRead(TEENSY_ROW_PIN[i]); // populate grid
        }
        digitalWrite(TEENSY_COL_PIN[i],HIGH); // restore column
    }
    return g;
}

void print_grid(Grid g)
{
    // for debugging
    for (int i=0;i<COLS;++i) {
        for (int j=0;j<ROWS;++j) {
            if (g.keys[i][j]) { Serial.print(default_layer[i][j]); }
        }
    }
    Serial.println("");
}

void setup() {
    set_pins();
}
void loop() {
    print_grid(scan()); // read inputs

    if (t >= MS_OUT) {
        t -= MS_OUT;
        // TODO: output if changed
    }
}
<commit_msg>Update main.cpp<commit_after>/**
   m30c10 keyboard firmware for TeensyLC
   https://github.com/hoosierEE/m30c10
*/
#include <Arduino.h>
const uint32_t MS_OUT{10}; elapsedMillis t; // min. output period

//// Model
static const uint8_t COLS{5}; // 2 columns for index finger, 1 each for middle/ring/pinkie
static const uint8_t ROWS{6}; // 3 rows per hand
const int TEENSY_ROW_PIN[ROWS]{10,11,12,14,20,21};
const int TEENSY_COL_PIN[COLS]{2,5,6,7,8}; // pin 9 is also available if more switches req'd
struct Grid { bool keys[COLS][ROWS]; } raw_grid;

//// Key Layers
char *default_layer[]{"qwert","yuiop","asdfg","hjkl'","zxcvb","nm,.-"};
char *shifted_layer[]{"QWERT","YUIOP","ASDFG","HJKL\"","ZXCVB","NM?!:"};
char *numeric_layer[]{"75319","02468","12345","67890","():,%",".+-*/"};
char *symbol_layer []{"@#$%[","]^&*|"," -+=(",");:/\\","_~`!{","}<,.>"};

//// Functions
void set_pins(void)
{
    for (int i=0;i<COLS;++i) {
        pinMode(TEENSY_COL_PIN[i], OUTPUT);
        for (int j=0;j<ROWS;++j) {
            pinMode(TEENSY_ROW_PIN[j], INPUT_PULLUP);
        }
    }
}

Grid scan(void)
{
    Grid g;
    for (int i=0;i<COLS;++i) {
        digitalWrite(TEENSY_COL_PIN[i],LOW); // pull column low
        for (int j=0;j<ROWS;++j) {
            g.keys[i][j] = digitalRead(TEENSY_ROW_PIN[i]); // populate grid
        }
        digitalWrite(TEENSY_COL_PIN[i],HIGH); // restore column
    }
    return g;
}

void print_grid(Grid g)
{
    // for debugging
    for (int i=0;i<COLS;++i) {
        for (int j=0;j<ROWS;++j) {
            if (g.keys[i][j]) { Serial.print(default_layer[i][j]); }
        }
    }
    Serial.println("");
}

void setup() {
    set_pins();
}
void loop() {
    print_grid(scan()); // read inputs

    if (t >= MS_OUT) {
        t -= MS_OUT;
        // TODO: output if changed
    }
}
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2012, Willow Garage, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * 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.
 *   * Neither the name of Willow Garage, Inc. 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 OWNER 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.
 *
 *
 *
 */

#ifndef PCL_SEGMENTATION_IMPL_ORGANIZED_CONNECTED_COMPONENT_SEGMENTATION_H_
#define PCL_SEGMENTATION_IMPL_ORGANIZED_CONNECTED_COMPONENT_SEGMENTATION_H_

#include "pcl/segmentation/organized_connected_component_segmentation.h"

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename PointT, typename PointLT> void
pcl::OrganizedConnectedComponentSegmentation<PointT, PointLT>::getNextIdxs(int& p1, int& p2, int& p3, int curr_idx, int dir, int width){
  if(dir == 0){
    p2 = (curr_idx - width);
    p1 = p2 - 1;
    p3 = p2 + 1;
  } else if(dir == 1){
    p1 = (curr_idx - width) + 1;
    p2 = curr_idx + 1;
    p3 = (curr_idx + width) + 1;
  } else if(dir == 2){
    p2 = (curr_idx + width);
    p1 = p2 + 1;
    p3 = p2 - 1;
  } else if(dir == 3){
    p1 = (curr_idx + width) - 1;
    p2 = curr_idx - 1;
    p3 = (curr_idx - width) - 1;
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename PointT, typename PointLT> void
pcl::OrganizedConnectedComponentSegmentation<PointT, PointLT>::findLabeledRegionBoundary (int start_idx, PointCloudLPtr labels, pcl::PointIndices& boundary_indices)
{
  bool first_done = false;
  boundary_indices.indices.push_back (start_idx);
  int curr_idx = start_idx;
  int p1, p2, p3 = 0;
  int dir = 0;
  unsigned label = labels->points[start_idx].label;

  while (!first_done)
  {
    getNextIdxs(p1,p2,p3,curr_idx,dir,labels->width);
    if(labels->points[p1].label == label){
      boundary_indices.indices.push_back(p1);
      curr_idx = p1;
      first_done = true;
      dir = (dir-1);
      if(dir == -1)
        dir = 3;
    } else if(labels->points[p2].label == label){
      boundary_indices.indices.push_back(p2);
      curr_idx = p2;
      first_done = true;
    } else if(labels->points[p3].label == label){
      boundary_indices.indices.push_back(p3);
      curr_idx = p3;
      first_done = true;
    } else {
      dir = (dir+1) % 4;
    }
  }

  while((curr_idx != start_idx)){
    getNextIdxs(p1,p2,p3,curr_idx,dir,labels->width);
    if(labels->points[p1].label == label){
      boundary_indices.indices.push_back(p1);
      curr_idx = p1;
      dir = (dir-1);// % 4;
      if(dir == -1)
        dir=3;
    } else if(labels->points[p2].label == label){
      boundary_indices.indices.push_back(p2);
      curr_idx = p2;
    } else if(labels->points[p3].label == label){
      boundary_indices.indices.push_back(p3);
      curr_idx = p3;
    } else {
      dir = (dir+1) % 4;
    }
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename PointT, typename PointLT> unsigned
pcl::OrganizedConnectedComponentSegmentation<PointT, PointLT>::findRoot (const std::vector<unsigned>& runs, unsigned index)
{
  unsigned idx = index;
  while (runs[idx] != idx)
    idx = runs[idx];

  return (idx);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename PointT, typename PointLT> void
pcl::OrganizedConnectedComponentSegmentation<PointT, PointLT>::segment (pcl::PointCloud<PointLT>& labels, std::vector<pcl::PointIndices>& label_indices)
{
  std::vector<unsigned> run_ids;

  unsigned invalid_label = std::numeric_limits<unsigned>::max ();
  pcl::Label invalid_pt;
  invalid_pt.label = std::numeric_limits<unsigned>::max ();
  labels.points.resize (input_->points.size (), invalid_pt);
  labels.width = input_->width;
  labels.height = input_->height;
  unsigned int clust_id = 0;

  // First row
  for (size_t colIdx = 1; colIdx < input_->width; ++colIdx)
  {
    if (!pcl_isfinite (input_->points[colIdx].x))
      continue;
    else if (compare_->compare (colIdx, colIdx - 1 ))
    {
      labels[colIdx].label = labels[colIdx - 1].label;
    }
    else
    {
      labels[colIdx].label = clust_id++;
      run_ids.push_back (labels[colIdx].label );
    }
  }

  // Everything else
  unsigned int current_row = input_->width;
  unsigned int previous_row = 0;
  for (size_t rowIdx = 1; rowIdx < input_->height; ++rowIdx, previous_row = current_row, current_row += input_->width)
  {
    // First pixel
    if (pcl_isfinite (input_->points[current_row].x))
    {
      if (compare_->compare (current_row, previous_row))
      {
        labels[current_row].label = labels[previous_row].label;
      }
      else
      {
        labels[current_row].label = clust_id++;
        run_ids.push_back (labels[current_row].label);
      }
    }

    // Rest of row
    for (size_t colIdx = 1; colIdx < input_->width; ++colIdx)
    {
      if (pcl_isfinite (input_->points[current_row + colIdx].x))
      {
        if (compare_->compare (current_row + colIdx, current_row + colIdx - 1))
        {
          labels[current_row + colIdx].label = labels[current_row + colIdx - 1].label;
        }
        if (compare_->compare (current_row + colIdx, previous_row + colIdx) )
        {
          if (labels[current_row + colIdx].label == invalid_label)
            labels[current_row + colIdx].label = labels[previous_row + colIdx].label;
          else
          {
            unsigned root1 = findRoot (run_ids, labels[current_row + colIdx].label);
            unsigned root2 = findRoot (run_ids, labels[previous_row + colIdx].label);

            if (root1 < root2)
              run_ids[root2] = root1;
            else
              run_ids[root1] = root2;
          }
        }

        if (labels[current_row + colIdx].label == invalid_label)
        {
          labels[current_row + colIdx].label = clust_id++;
          run_ids.push_back (labels[current_row + colIdx].label);
        }

      }
    }
  }

  std::vector<unsigned> map (clust_id);
  unsigned max_id = 0;
  for (unsigned runIdx = 0; runIdx < run_ids.size (); ++runIdx)
  {
    if (run_ids[runIdx] == runIdx)
      map[runIdx] = max_id++;
  }
  label_indices.resize (max_id + 1);
  for (unsigned idx = 0; idx < input_->points.size (); idx++)
  {
    if (labels[idx].label != invalid_label)
    {
      labels[idx].label = map[findRoot (run_ids, labels[idx].label)];
      label_indices[labels[idx].label].indices.push_back (idx);
    }
  }
}

#define PCL_INSTANTIATE_OrganizedConnectedComponentSegmentation(T,LT) template class PCL_EXPORTS pcl::OrganizedConnectedComponentSegmentation<T,LT>;

#endif //#ifndef PCL_SEGMENTATION_IMPL_ORGANIZED_CONNECTED_COMPONENT_SEGMENTATION_H_
<commit_msg>fixed warnings<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2012, Willow Garage, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * 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.
 *   * Neither the name of Willow Garage, Inc. 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 OWNER 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.
 *
 *
 *
 */

#ifndef PCL_SEGMENTATION_IMPL_ORGANIZED_CONNECTED_COMPONENT_SEGMENTATION_H_
#define PCL_SEGMENTATION_IMPL_ORGANIZED_CONNECTED_COMPONENT_SEGMENTATION_H_

#include "pcl/segmentation/organized_connected_component_segmentation.h"

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename PointT, typename PointLT> void
pcl::OrganizedConnectedComponentSegmentation<PointT, PointLT>::getNextIdxs(int& p1, int& p2, int& p3, int curr_idx, int dir, int width){
  if(dir == 0){
    p2 = (curr_idx - width);
    p1 = p2 - 1;
    p3 = p2 + 1;
  } else if(dir == 1){
    p1 = (curr_idx - width) + 1;
    p2 = curr_idx + 1;
    p3 = (curr_idx + width) + 1;
  } else if(dir == 2){
    p2 = (curr_idx + width);
    p1 = p2 + 1;
    p3 = p2 - 1;
  } else if(dir == 3){
    p1 = (curr_idx + width) - 1;
    p2 = curr_idx - 1;
    p3 = (curr_idx - width) - 1;
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename PointT, typename PointLT> void
pcl::OrganizedConnectedComponentSegmentation<PointT, PointLT>::findLabeledRegionBoundary (int start_idx, PointCloudLPtr labels, pcl::PointIndices& boundary_indices)
{
  bool first_done = false;
  boundary_indices.indices.push_back (start_idx);
  int curr_idx = start_idx;
  int p1, p2, p3 = 0;
  int dir = 0;
  unsigned label = labels->points[start_idx].label;

  while (!first_done)
  {
    getNextIdxs(p1,p2,p3,curr_idx,dir,labels->width);
    if(labels->points[p1].label == label){
      boundary_indices.indices.push_back(p1);
      curr_idx = p1;
      first_done = true;
      dir = (dir-1);
      if(dir == -1)
        dir = 3;
    } else if(labels->points[p2].label == label){
      boundary_indices.indices.push_back(p2);
      curr_idx = p2;
      first_done = true;
    } else if(labels->points[p3].label == label){
      boundary_indices.indices.push_back(p3);
      curr_idx = p3;
      first_done = true;
    } else {
      dir = (dir+1) % 4;
    }
  }

  while((curr_idx != start_idx)){
    getNextIdxs(p1,p2,p3,curr_idx,dir,labels->width);
    if(labels->points[p1].label == label){
      boundary_indices.indices.push_back(p1);
      curr_idx = p1;
      dir = (dir-1);// % 4;
      if(dir == -1)
        dir=3;
    } else if(labels->points[p2].label == label){
      boundary_indices.indices.push_back(p2);
      curr_idx = p2;
    } else if(labels->points[p3].label == label){
      boundary_indices.indices.push_back(p3);
      curr_idx = p3;
    } else {
      dir = (dir+1) % 4;
    }
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename PointT, typename PointLT> unsigned
pcl::OrganizedConnectedComponentSegmentation<PointT, PointLT>::findRoot (const std::vector<unsigned>& runs, unsigned index)
{
  unsigned idx = index;
  while (runs[idx] != idx)
    idx = runs[idx];

  return (idx);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename PointT, typename PointLT> void
pcl::OrganizedConnectedComponentSegmentation<PointT, PointLT>::segment (pcl::PointCloud<PointLT>& labels, std::vector<pcl::PointIndices>& label_indices)
{
  std::vector<unsigned> run_ids;

  unsigned invalid_label = std::numeric_limits<unsigned>::max ();
  pcl::Label invalid_pt;
  invalid_pt.label = std::numeric_limits<unsigned>::max ();
  labels.points.resize (input_->points.size (), invalid_pt);
  labels.width = input_->width;
  labels.height = input_->height;
  unsigned int clust_id = 0;

  // First row
  for (int colIdx = 1; colIdx < static_cast<int> (input_->width); ++colIdx)
  {
    if (!pcl_isfinite (input_->points[colIdx].x))
      continue;
    else if (compare_->compare (colIdx, colIdx - 1 ))
    {
      labels[colIdx].label = labels[colIdx - 1].label;
    }
    else
    {
      labels[colIdx].label = clust_id++;
      run_ids.push_back (labels[colIdx].label );
    }
  }

  // Everything else
  unsigned int current_row = input_->width;
  unsigned int previous_row = 0;
  for (size_t rowIdx = 1; rowIdx < input_->height; ++rowIdx, previous_row = current_row, current_row += input_->width)
  {
    // First pixel
    if (pcl_isfinite (input_->points[current_row].x))
    {
      if (compare_->compare (current_row, previous_row))
      {
        labels[current_row].label = labels[previous_row].label;
      }
      else
      {
        labels[current_row].label = clust_id++;
        run_ids.push_back (labels[current_row].label);
      }
    }

    // Rest of row
    for (int colIdx = 1; colIdx < static_cast<int> (input_->width); ++colIdx)
    {
      if (pcl_isfinite (input_->points[current_row + colIdx].x))
      {
        if (compare_->compare (current_row + colIdx, current_row + colIdx - 1))
        {
          labels[current_row + colIdx].label = labels[current_row + colIdx - 1].label;
        }
        if (compare_->compare (current_row + colIdx, previous_row + colIdx) )
        {
          if (labels[current_row + colIdx].label == invalid_label)
            labels[current_row + colIdx].label = labels[previous_row + colIdx].label;
          else
          {
            unsigned root1 = findRoot (run_ids, labels[current_row + colIdx].label);
            unsigned root2 = findRoot (run_ids, labels[previous_row + colIdx].label);

            if (root1 < root2)
              run_ids[root2] = root1;
            else
              run_ids[root1] = root2;
          }
        }

        if (labels[current_row + colIdx].label == invalid_label)
        {
          labels[current_row + colIdx].label = clust_id++;
          run_ids.push_back (labels[current_row + colIdx].label);
        }

      }
    }
  }

  std::vector<unsigned> map (clust_id);
  unsigned max_id = 0;
  for (unsigned runIdx = 0; runIdx < run_ids.size (); ++runIdx)
  {
    if (run_ids[runIdx] == runIdx)
      map[runIdx] = max_id++;
  }
  label_indices.resize (max_id + 1);
  for (unsigned idx = 0; idx < input_->points.size (); idx++)
  {
    if (labels[idx].label != invalid_label)
    {
      labels[idx].label = map[findRoot (run_ids, labels[idx].label)];
      label_indices[labels[idx].label].indices.push_back (idx);
    }
  }
}

#define PCL_INSTANTIATE_OrganizedConnectedComponentSegmentation(T,LT) template class PCL_EXPORTS pcl::OrganizedConnectedComponentSegmentation<T,LT>;

#endif //#ifndef PCL_SEGMENTATION_IMPL_ORGANIZED_CONNECTED_COMPONENT_SEGMENTATION_H_
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: graphsh.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: ihi $ $Date: 2006-11-14 15:53:30 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

//------------------------------------------------------------------

#include <sfx2/app.hxx>
#include <sfx2/objface.hxx>
#include <sfx2/request.hxx>
#include <svtools/whiter.hxx>
#include <svx/svdograf.hxx>
#include <svx/grfflt.hxx>
#include <svx/grafctrl.hxx>

#include "graphsh.hxx"
#include "sc.hrc"
#include "viewdata.hxx"
#include "drawview.hxx"
#include "scresid.hxx"

#define ScGraphicShell
#include "scslots.hxx"

#define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue()

SFX_IMPL_INTERFACE(ScGraphicShell, ScDrawShell, ScResId(SCSTR_GRAPHICSHELL) )
{
    SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT|SFX_VISIBILITY_STANDARD|SFX_VISIBILITY_SERVER,
                                ScResId(RID_GRAPHIC_OBJECTBAR) );
    SFX_POPUPMENU_REGISTRATION( ScResId(RID_POPUP_GRAPHIC) );
}

TYPEINIT1( ScGraphicShell, ScDrawShell );

ScGraphicShell::ScGraphicShell(ScViewData* pData) :
    ScDrawShell(pData)
{
    SetHelpId(HID_SCSHELL_GRAPHIC);
    SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("GraphicObject")));
}

ScGraphicShell::~ScGraphicShell()
{
}

void ScGraphicShell::GetAttrState( SfxItemSet& rSet )
{
    ScDrawView* pView = GetViewData()->GetScDrawView();

    if( pView )
        SvxGrafAttrHelper::GetGrafAttrState( rSet, *pView );
}

void ScGraphicShell::Execute( SfxRequest& rReq )
{
    ScDrawView* pView = GetViewData()->GetScDrawView();

    if( pView )
    {
        SvxGrafAttrHelper::ExecuteGrafAttr( rReq, *pView );
        Invalidate();
    }
}

void ScGraphicShell::GetFilterState( SfxItemSet& rSet )
{
    ScDrawView* pView = GetViewData()->GetScDrawView();
    const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
    BOOL bEnable = FALSE;

    if( rMarkList.GetMarkCount() == 1 )
    {
        SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();

        if( pObj && pObj->ISA( SdrGrafObj ) && ( ( (SdrGrafObj*) pObj )->GetGraphicType() == GRAPHIC_BITMAP ) )
            bEnable = TRUE;
    }

    if( !bEnable )
        SvxGraphicFilter::DisableGraphicFilterSlots( rSet );
}

void ScGraphicShell::ExecuteFilter( SfxRequest& rReq )
{
    ScDrawView* pView = GetViewData()->GetScDrawView();
    const SdrMarkList& rMarkList = pView->GetMarkedObjectList();

    if( rMarkList.GetMarkCount() == 1 )
    {
        SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();

        if( pObj && pObj->ISA( SdrGrafObj ) && ( (SdrGrafObj*) pObj )->GetGraphicType() == GRAPHIC_BITMAP )
        {
            GraphicObject aFilterObj( ( (SdrGrafObj*) pObj )->GetGraphicObject() );

            if( SVX_GRAPHICFILTER_ERRCODE_NONE ==
                SvxGraphicFilter::ExecuteGrfFilterSlot( rReq, aFilterObj ) )
            {
                SdrPageView* pPageView = pView->GetSdrPageView();

                if( pPageView )
                {
                    SdrGrafObj* pFilteredObj = (SdrGrafObj*) pObj->Clone();
                    String      aStr( pView->GetDescriptionOfMarkedObjects() );

                    aStr.Append( sal_Unicode(' ') );
                    aStr.Append( String( ScResId( SCSTR_UNDO_GRAFFILTER ) ) );
                    pView->BegUndo( aStr );
                    pFilteredObj->SetGraphicObject( aFilterObj );
                    pView->ReplaceObjectAtView( pObj, *pPageView, pFilteredObj );
                    pView->EndUndo();
                }
            }
        }
    }

    Invalidate();
}

<commit_msg>INTEGRATION: CWS changefileheader (1.10.406); FILE MERGED 2008/03/31 17:15:32 rt 1.10.406.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: graphsh.cxx,v $
 * $Revision: 1.11 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

//------------------------------------------------------------------

#include <sfx2/app.hxx>
#include <sfx2/objface.hxx>
#include <sfx2/request.hxx>
#include <svtools/whiter.hxx>
#include <svx/svdograf.hxx>
#include <svx/grfflt.hxx>
#include <svx/grafctrl.hxx>

#include "graphsh.hxx"
#include "sc.hrc"
#include "viewdata.hxx"
#include "drawview.hxx"
#include "scresid.hxx"

#define ScGraphicShell
#include "scslots.hxx"

#define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue()

SFX_IMPL_INTERFACE(ScGraphicShell, ScDrawShell, ScResId(SCSTR_GRAPHICSHELL) )
{
    SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT|SFX_VISIBILITY_STANDARD|SFX_VISIBILITY_SERVER,
                                ScResId(RID_GRAPHIC_OBJECTBAR) );
    SFX_POPUPMENU_REGISTRATION( ScResId(RID_POPUP_GRAPHIC) );
}

TYPEINIT1( ScGraphicShell, ScDrawShell );

ScGraphicShell::ScGraphicShell(ScViewData* pData) :
    ScDrawShell(pData)
{
    SetHelpId(HID_SCSHELL_GRAPHIC);
    SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("GraphicObject")));
}

ScGraphicShell::~ScGraphicShell()
{
}

void ScGraphicShell::GetAttrState( SfxItemSet& rSet )
{
    ScDrawView* pView = GetViewData()->GetScDrawView();

    if( pView )
        SvxGrafAttrHelper::GetGrafAttrState( rSet, *pView );
}

void ScGraphicShell::Execute( SfxRequest& rReq )
{
    ScDrawView* pView = GetViewData()->GetScDrawView();

    if( pView )
    {
        SvxGrafAttrHelper::ExecuteGrafAttr( rReq, *pView );
        Invalidate();
    }
}

void ScGraphicShell::GetFilterState( SfxItemSet& rSet )
{
    ScDrawView* pView = GetViewData()->GetScDrawView();
    const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
    BOOL bEnable = FALSE;

    if( rMarkList.GetMarkCount() == 1 )
    {
        SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();

        if( pObj && pObj->ISA( SdrGrafObj ) && ( ( (SdrGrafObj*) pObj )->GetGraphicType() == GRAPHIC_BITMAP ) )
            bEnable = TRUE;
    }

    if( !bEnable )
        SvxGraphicFilter::DisableGraphicFilterSlots( rSet );
}

void ScGraphicShell::ExecuteFilter( SfxRequest& rReq )
{
    ScDrawView* pView = GetViewData()->GetScDrawView();
    const SdrMarkList& rMarkList = pView->GetMarkedObjectList();

    if( rMarkList.GetMarkCount() == 1 )
    {
        SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();

        if( pObj && pObj->ISA( SdrGrafObj ) && ( (SdrGrafObj*) pObj )->GetGraphicType() == GRAPHIC_BITMAP )
        {
            GraphicObject aFilterObj( ( (SdrGrafObj*) pObj )->GetGraphicObject() );

            if( SVX_GRAPHICFILTER_ERRCODE_NONE ==
                SvxGraphicFilter::ExecuteGrfFilterSlot( rReq, aFilterObj ) )
            {
                SdrPageView* pPageView = pView->GetSdrPageView();

                if( pPageView )
                {
                    SdrGrafObj* pFilteredObj = (SdrGrafObj*) pObj->Clone();
                    String      aStr( pView->GetDescriptionOfMarkedObjects() );

                    aStr.Append( sal_Unicode(' ') );
                    aStr.Append( String( ScResId( SCSTR_UNDO_GRAFFILTER ) ) );
                    pView->BegUndo( aStr );
                    pFilteredObj->SetGraphicObject( aFilterObj );
                    pView->ReplaceObjectAtView( pObj, *pPageView, pFilteredObj );
                    pView->EndUndo();
                }
            }
        }
    }

    Invalidate();
}

<|endoftext|>


<commit_before><commit_msg>some fixes<commit_after><|endoftext|>


<commit_before>#include "Cache.h"

#include <mutex>

#include "preprocessor/llvm_includes_start.h"
#include <llvm/IR/Module.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Instructions.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/Support/Path.h>
#include <llvm/Support/FileSystem.h>
#include <llvm/Support/raw_os_ostream.h>
#include "preprocessor/llvm_includes_end.h"

#include "support/Path.h"
#include "ExecStats.h"
#include "Utils.h"
#include "BuildInfo.gen.h"

namespace dev
{
namespace evmjit
{

namespace
{
	using Guard = std::lock_guard<std::mutex>;
	std::mutex x_cacheMutex;
	CacheMode g_mode;
	std::unique_ptr<llvm::MemoryBuffer> g_lastObject;
	JITListener* g_listener;

	llvm::StringRef getLibVersionStamp()
	{
		return EVMJIT_VERSION;
	}

	std::string getVersionedCacheDir()
	{
		llvm::SmallString<256> path{path::user_cache_directory()};
		static const auto c_ethereumAppName = UTILS_OS_LINUX ? "ethereum" : "Ethereum";
		llvm::sys::path::append(path, c_ethereumAppName, "evmjit", EVMJIT_VERSION);
		return path.str();
	}

}

ObjectCache* Cache::init(CacheMode _mode, JITListener* _listener)
{
	auto userCacheDir = getVersionedCacheDir();
	std::cerr << "User cache dir: " << userCacheDir << "\n";

	Guard g{x_cacheMutex};

	g_mode = _mode;
	g_listener = _listener;

	if (g_mode == CacheMode::clear)
	{
		Cache::clear();
		g_mode = CacheMode::off;
	}

	if (g_mode != CacheMode::off)
	{
		static ObjectCache objectCache;
		return &objectCache;
	}
	return nullptr;
}

void Cache::clear()
{
	Guard g{x_cacheMutex};

	namespace path = llvm::sys::path;
	namespace fs = llvm::sys::fs;
	llvm::SmallString<256> cachePath;
	path::system_temp_directory(false, cachePath);
	path::append(cachePath, "evm_objs");

	std::error_code err;
	for (auto it = fs::directory_iterator{cachePath.str(), err}; it != fs::directory_iterator{}; it.increment(err))
		fs::remove(it->path());
}

void Cache::preload(llvm::ExecutionEngine& _ee, std::unordered_map<std::string, uint64_t>& _funcCache)
{
	Guard g{x_cacheMutex};

	// TODO: Cache dir should be in one place
	namespace path = llvm::sys::path;
	namespace fs = llvm::sys::fs;
	llvm::SmallString<256> cachePath;
	path::system_temp_directory(false, cachePath);
	path::append(cachePath, "evm_objs");

	// Disable listener
	auto listener = g_listener;
	g_listener = nullptr;

	std::error_code err;
	for (auto it = fs::directory_iterator{cachePath.str(), err}; it != fs::directory_iterator{}; it.increment(err))
	{
		auto name = it->path().substr(cachePath.size() + 1);
		if (auto module = getObject(name))
		{
			DLOG(cache) << "Preload: " << name << "\n";
			_ee.addModule(std::move(module));
			auto addr = _ee.getFunctionAddress(name);
			assert(addr);
			_funcCache[std::move(name)] = addr;
		}
	}

	g_listener = listener;
}

std::unique_ptr<llvm::Module> Cache::getObject(std::string const& id)
{
	Guard g{x_cacheMutex};

	if (g_mode != CacheMode::on && g_mode != CacheMode::read)
		return nullptr;

	// TODO: Disabled because is not thread-safe.
	//if (g_listener)
	//	g_listener->stateChanged(ExecState::CacheLoad);

	DLOG(cache) << id << ": search\n";
	if (!CHECK(!g_lastObject))
		g_lastObject = nullptr;

	llvm::SmallString<256> cachePath;
	llvm::sys::path::system_temp_directory(false, cachePath);
	llvm::sys::path::append(cachePath, "evm_objs", id);

	if (auto r = llvm::MemoryBuffer::getFile(cachePath.str(), -1, false))
	{
		auto& buf = r.get();
		auto expectedStamp = getLibVersionStamp();
		auto stampSize = expectedStamp.size();
		auto objStamp = buf->getBufferSize() >= stampSize ? llvm::StringRef{buf->getBufferEnd() - stampSize, stampSize} : llvm::StringRef{};
		if (objStamp == expectedStamp)
			g_lastObject = llvm::MemoryBuffer::getMemBufferCopy(r.get()->getBuffer());
		else
			DLOG(cache) << "Unmatched version: " << objStamp.str() << ", expected " << expectedStamp.str() << "\n";
	}
	else if (r.getError() != std::make_error_code(std::errc::no_such_file_or_directory))
		DLOG(cache) << r.getError().message(); // TODO: Add warning log

	if (g_lastObject)  // if object found create fake module
	{
		DLOG(cache) << id << ": found\n";
		auto&& context = llvm::getGlobalContext();
		auto module = std::unique_ptr<llvm::Module>(new llvm::Module(id, context));
		auto mainFuncType = llvm::FunctionType::get(llvm::Type::getVoidTy(context), {}, false);
		auto mainFunc = llvm::Function::Create(mainFuncType, llvm::Function::ExternalLinkage, id, module.get());
		auto bb = llvm::BasicBlock::Create(context, {}, mainFunc);
		bb->getInstList().push_back(new llvm::UnreachableInst{context});
		return module;
	}
	DLOG(cache) << id << ": not found\n";
	return nullptr;
}

void ObjectCache::notifyObjectCompiled(llvm::Module const* _module, llvm::MemoryBufferRef _object)
{
	Guard g{x_cacheMutex};

	// Only in "on" and "write" mode
	if (g_mode != CacheMode::on && g_mode != CacheMode::write)
		return;

	// TODO: Disabled because is not thread-safe.
	// if (g_listener)
		// g_listener->stateChanged(ExecState::CacheWrite);

	auto&& id = _module->getModuleIdentifier();
	llvm::SmallString<256> cachePath;
	llvm::sys::path::system_temp_directory(false, cachePath);
	llvm::sys::path::append(cachePath, "evm_objs");

	if (llvm::sys::fs::create_directory(cachePath.str()))
		DLOG(cache) << "Cannot create cache dir " << cachePath.str().str() << "\n";

	llvm::sys::path::append(cachePath, id);

	DLOG(cache) << id << ": write\n";
	std::error_code error;
	llvm::raw_fd_ostream cacheFile(cachePath.c_str(), error, llvm::sys::fs::F_None);
	cacheFile << _object.getBuffer() << getLibVersionStamp();
}

std::unique_ptr<llvm::MemoryBuffer> ObjectCache::getObject(llvm::Module const* _module)
{
	Guard g{x_cacheMutex};

	DLOG(cache) << _module->getModuleIdentifier() << ": use\n";
	return std::move(g_lastObject);
}

}
}
<commit_msg>User versioned cache dir instead of using verion stamp attached to cached files.<commit_after>#include "Cache.h"

#include <mutex>

#include "preprocessor/llvm_includes_start.h"
#include <llvm/IR/Module.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Instructions.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/Support/Path.h>
#include <llvm/Support/FileSystem.h>
#include <llvm/Support/raw_os_ostream.h>
#include "preprocessor/llvm_includes_end.h"

#include "support/Path.h"
#include "ExecStats.h"
#include "Utils.h"
#include "BuildInfo.gen.h"

namespace dev
{
namespace evmjit
{

namespace
{
	using Guard = std::lock_guard<std::mutex>;
	std::mutex x_cacheMutex;
	CacheMode g_mode;
	std::unique_ptr<llvm::MemoryBuffer> g_lastObject;
	JITListener* g_listener;

	std::string getVersionedCacheDir()
	{
		llvm::SmallString<256> path{path::user_cache_directory()};
		static const auto c_ethereumAppName = UTILS_OS_LINUX ? "ethereum" : "Ethereum";
		llvm::sys::path::append(path, c_ethereumAppName, "evmjit", EVMJIT_VERSION);
		return path.str();
	}

}

ObjectCache* Cache::init(CacheMode _mode, JITListener* _listener)
{
	DLOG(cache) << "Cache dir: " << getVersionedCacheDir() << "\n";

	Guard g{x_cacheMutex};

	g_mode = _mode;
	g_listener = _listener;

	if (g_mode == CacheMode::clear)
	{
		Cache::clear();
		g_mode = CacheMode::off;
	}

	if (g_mode != CacheMode::off)
	{
		static ObjectCache objectCache;
		return &objectCache;
	}
	return nullptr;
}

void Cache::clear()
{
	Guard g{x_cacheMutex};

	auto cachePath = getVersionedCacheDir();
	std::error_code err;
	for (auto it = llvm::sys::fs::directory_iterator{cachePath, err}; it != decltype(it){}; it.increment(err))
		llvm::sys::fs::remove(it->path());
}

void Cache::preload(llvm::ExecutionEngine& _ee, std::unordered_map<std::string, uint64_t>& _funcCache)
{
	Guard g{x_cacheMutex};

	// Disable listener
	auto listener = g_listener;
	g_listener = nullptr;

	auto cachePath = getVersionedCacheDir();
	std::error_code err;
	for (auto it = llvm::sys::fs::directory_iterator{cachePath, err}; it != decltype(it){}; it.increment(err))
	{
		auto name = it->path().substr(cachePath.size() + 1);
		if (auto module = getObject(name))
		{
			DLOG(cache) << "Preload: " << name << "\n";
			_ee.addModule(std::move(module));
			auto addr = _ee.getFunctionAddress(name);
			assert(addr);
			_funcCache[std::move(name)] = addr;
		}
	}

	g_listener = listener;
}

std::unique_ptr<llvm::Module> Cache::getObject(std::string const& id)
{
	Guard g{x_cacheMutex};

	if (g_mode != CacheMode::on && g_mode != CacheMode::read)
		return nullptr;

	// TODO: Disabled because is not thread-safe.
	//if (g_listener)
	//	g_listener->stateChanged(ExecState::CacheLoad);

	DLOG(cache) << id << ": search\n";
	if (!CHECK(!g_lastObject))
		g_lastObject = nullptr;

	llvm::SmallString<256> cachePath{getVersionedCacheDir()};
	llvm::sys::path::append(cachePath, id);

	if (auto r = llvm::MemoryBuffer::getFile(cachePath, -1, false))
		g_lastObject = llvm::MemoryBuffer::getMemBufferCopy(r.get()->getBuffer());
	else if (r.getError() != std::make_error_code(std::errc::no_such_file_or_directory))
		DLOG(cache) << r.getError().message(); // TODO: Add warning log

	if (g_lastObject)  // if object found create fake module
	{
		DLOG(cache) << id << ": found\n";
		auto&& context = llvm::getGlobalContext();
		auto module = std::unique_ptr<llvm::Module>(new llvm::Module(id, context));
		auto mainFuncType = llvm::FunctionType::get(llvm::Type::getVoidTy(context), {}, false);
		auto mainFunc = llvm::Function::Create(mainFuncType, llvm::Function::ExternalLinkage, id, module.get());
		auto bb = llvm::BasicBlock::Create(context, {}, mainFunc);
		bb->getInstList().push_back(new llvm::UnreachableInst{context});
		return module;
	}
	DLOG(cache) << id << ": not found\n";
	return nullptr;
}

void ObjectCache::notifyObjectCompiled(llvm::Module const* _module, llvm::MemoryBufferRef _object)
{
	Guard g{x_cacheMutex};

	// Only in "on" and "write" mode
	if (g_mode != CacheMode::on && g_mode != CacheMode::write)
		return;

	// TODO: Disabled because is not thread-safe.
	// if (g_listener)
		// g_listener->stateChanged(ExecState::CacheWrite);

	auto&& id = _module->getModuleIdentifier();
	llvm::SmallString<256> cachePath{getVersionedCacheDir()};
	if (llvm::sys::fs::create_directories(cachePath))
		DLOG(cache) << "Cannot create cache dir " << cachePath.str().str() << "\n";

	llvm::sys::path::append(cachePath, id);

	DLOG(cache) << id << ": write\n";
	std::error_code error;
	llvm::raw_fd_ostream cacheFile(cachePath, error, llvm::sys::fs::F_None);
	cacheFile << _object.getBuffer();
}

std::unique_ptr<llvm::MemoryBuffer> ObjectCache::getObject(llvm::Module const* _module)
{
	Guard g{x_cacheMutex};

	DLOG(cache) << _module->getModuleIdentifier() << ": use\n";
	return std::move(g_lastObject);
}

}
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: structpg.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: kz $ $Date: 2006-07-21 13:58:50 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

//----------------------------------------------------------------------------

#include "scitems.hxx"
#include <sfx2/dispatch.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/objsh.hxx>
#include <svtools/zforlist.hxx>

#ifndef _SFXSTRITEM_HXX //autogen
#include <svtools/stritem.hxx>
#endif

#include "structpg.hxx"
#include "formdlgs.hrc"
#include "formdata.hxx"
#include "globstr.hrc"
#include "scresid.hxx"
#include "reffact.hxx"
#include "document.hxx"
#include "cell.hxx"
#include "scmod.hxx"
#include "inputhdl.hxx"
#include "tabvwsh.hxx"
#include "appoptio.hxx"

//----------------------------------------------------------------------------

ScStructListBox::ScStructListBox(Window* pParent, const ResId& rResId ):
    SvTreeListBox(pParent,rResId )
{
    bActiveFlag=FALSE;

    Font aFont( GetFont() );
    Size aSize = aFont.GetSize();
    aSize.Height() -= 2;
    aFont.SetSize( aSize );
    SetFont( aFont );
}

SvLBoxEntry* ScStructListBox::InsertStaticEntry(
        const XubString& rText,
        const Image& rEntryImg, const Image& rEntryImgHC,
        SvLBoxEntry* pParent, ULONG nPos, ScToken* pToken )
{
    SvLBoxEntry* pEntry = InsertEntry( rText, rEntryImg, rEntryImg, pParent, FALSE, nPos, pToken );
    SvLBoxContextBmp* pBmpItem = static_cast< SvLBoxContextBmp* >( pEntry->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP ) );
    DBG_ASSERT( pBmpItem, "ScStructListBox::InsertStaticEntry - missing item" );
    pBmpItem->SetBitmap1( rEntryImgHC, BMP_COLOR_HIGHCONTRAST );
    pBmpItem->SetBitmap2( rEntryImgHC, BMP_COLOR_HIGHCONTRAST );
    return pEntry;
}

void ScStructListBox::SetActiveFlag(BOOL bFlag)
{
    bActiveFlag=bFlag;
}

BOOL ScStructListBox::GetActiveFlag()
{
    return bActiveFlag;
}

void ScStructListBox::MouseButtonDown( const MouseEvent& rMEvt )
{
    bActiveFlag=TRUE;
    SvTreeListBox::MouseButtonDown(rMEvt);
}

void ScStructListBox::GetFocus()
{
    bActiveFlag=TRUE;
    SvTreeListBox::GetFocus();
}

void ScStructListBox::LoseFocus()
{
    bActiveFlag=FALSE;
    SvTreeListBox::LoseFocus();
}

//==============================================================================

ScStructPage::ScStructPage(Window* pParent):
    TabPage(pParent,ScResId(RID_SCTAB_STRUCT)),
    //
    aFtStruct       ( this, ScResId( FT_STRUCT ) ),
    aTlbStruct      ( this, ScResId( TLB_STRUCT ) ),
    maImgEnd        ( ScResId( BMP_STR_END ) ),
    maImgError      ( ScResId( BMP_STR_ERROR ) ),
    maImgEndHC      ( ScResId( BMP_STR_END_H ) ),
    maImgErrorHC    ( ScResId( BMP_STR_ERROR_H ) ),
    pSelectedToken  ( NULL )
{
    aTlbStruct.SetWindowBits(WB_HASLINES|WB_CLIPCHILDREN|
                        WB_HASBUTTONS|WB_HSCROLL|WB_NOINITIALSELECTION);

    aTlbStruct.SetNodeDefaultImages();
    aTlbStruct.SetDefaultExpandedEntryBmp( Image( ScResId( BMP_STR_OPEN ) ) );
    aTlbStruct.SetDefaultCollapsedEntryBmp( Image( ScResId( BMP_STR_CLOSE ) ) );
    aTlbStruct.SetDefaultExpandedEntryBmp( Image( ScResId( BMP_STR_OPEN_H ) ), BMP_COLOR_HIGHCONTRAST );
    aTlbStruct.SetDefaultCollapsedEntryBmp( Image( ScResId( BMP_STR_CLOSE_H ) ), BMP_COLOR_HIGHCONTRAST );

    FreeResource();

    aTlbStruct.SetSelectHdl(LINK( this, ScStructPage, SelectHdl ) );
}

void ScStructPage::ClearStruct()
{
    aTlbStruct.SetActiveFlag(FALSE);
    aTlbStruct.Clear();
}

SvLBoxEntry* ScStructPage::InsertEntry( const XubString& rText, SvLBoxEntry* pParent,
                                       USHORT nFlag,ULONG nPos,ScToken* pScToken)
{
    aTlbStruct.SetActiveFlag( FALSE );

    SvLBoxEntry* pEntry = NULL;
    switch( nFlag )
    {
        case STRUCT_FOLDER:
            pEntry = aTlbStruct.InsertEntry( rText, pParent, FALSE, nPos, pScToken );
        break;
        case STRUCT_END:
            pEntry = aTlbStruct.InsertStaticEntry( rText, maImgEnd, maImgEndHC, pParent, nPos, pScToken );
        break;
        case STRUCT_ERROR:
            pEntry = aTlbStruct.InsertStaticEntry( rText, maImgError, maImgErrorHC, pParent, nPos, pScToken );
        break;
    }

    if( pEntry && pParent )
        aTlbStruct.Expand( pParent );
    return pEntry;
}

String ScStructPage::GetEntryText(SvLBoxEntry* pEntry)
{
    String aString;
    if(pEntry!=NULL)
        aString=aTlbStruct.GetEntryText(pEntry);
    return  aString;
}

ScToken* ScStructPage::GetFunctionEntry(SvLBoxEntry* pEntry)
{
    if(pEntry!=NULL)
    {
        ScToken * pToken=(ScToken *)pEntry->GetUserData();
        if(pToken!=NULL)
        {
            OpCode eOp = pToken->GetOpCode();
            if(!(pToken->IsFunction()|| ocArcTan2<=eOp))
            {
                return GetFunctionEntry(aTlbStruct.GetParent(pEntry));
            }
            else
            {
                return pToken;
            }
        }
    }
    return NULL;
}

IMPL_LINK( ScStructPage, SelectHdl, SvTreeListBox*, pTlb )
{
    if(aTlbStruct.GetActiveFlag())
    {
        if(pTlb==&aTlbStruct)
        {
            SvLBoxEntry*    pCurEntry=aTlbStruct.GetCurEntry();
            if(pCurEntry!=NULL)
            {
                pSelectedToken=(ScToken *)pCurEntry->GetUserData();
                if(pSelectedToken!=NULL)
                {
                    OpCode eOp = pSelectedToken->GetOpCode();
                    if(!(pSelectedToken->IsFunction()|| ocArcTan2<=eOp))
                    {
                        pSelectedToken=GetFunctionEntry(pCurEntry);
                    }
                }
            }
        }

        aSelLink.Call(this);
    }
    return 0;
}

ScToken * ScStructPage::GetSelectedToken()
{
    return pSelectedToken;
}

String ScStructPage::GetSelectedEntryText()
{
    return aTlbStruct.GetEntryText(aTlbStruct.GetCurEntry());
}

<commit_msg>INTEGRATION: CWS changefileheader (1.8.492); FILE MERGED 2008/04/01 15:30:47 thb 1.8.492.2: #i85898# Stripping all external header guards 2008/03/31 17:15:37 rt 1.8.492.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: structpg.cxx,v $
 * $Revision: 1.9 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

//----------------------------------------------------------------------------

#include "scitems.hxx"
#include <sfx2/dispatch.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/objsh.hxx>
#include <svtools/zforlist.hxx>
#include <svtools/stritem.hxx>

#include "structpg.hxx"
#include "formdlgs.hrc"
#include "formdata.hxx"
#include "globstr.hrc"
#include "scresid.hxx"
#include "reffact.hxx"
#include "document.hxx"
#include "cell.hxx"
#include "scmod.hxx"
#include "inputhdl.hxx"
#include "tabvwsh.hxx"
#include "appoptio.hxx"

//----------------------------------------------------------------------------

ScStructListBox::ScStructListBox(Window* pParent, const ResId& rResId ):
    SvTreeListBox(pParent,rResId )
{
    bActiveFlag=FALSE;

    Font aFont( GetFont() );
    Size aSize = aFont.GetSize();
    aSize.Height() -= 2;
    aFont.SetSize( aSize );
    SetFont( aFont );
}

SvLBoxEntry* ScStructListBox::InsertStaticEntry(
        const XubString& rText,
        const Image& rEntryImg, const Image& rEntryImgHC,
        SvLBoxEntry* pParent, ULONG nPos, ScToken* pToken )
{
    SvLBoxEntry* pEntry = InsertEntry( rText, rEntryImg, rEntryImg, pParent, FALSE, nPos, pToken );
    SvLBoxContextBmp* pBmpItem = static_cast< SvLBoxContextBmp* >( pEntry->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP ) );
    DBG_ASSERT( pBmpItem, "ScStructListBox::InsertStaticEntry - missing item" );
    pBmpItem->SetBitmap1( rEntryImgHC, BMP_COLOR_HIGHCONTRAST );
    pBmpItem->SetBitmap2( rEntryImgHC, BMP_COLOR_HIGHCONTRAST );
    return pEntry;
}

void ScStructListBox::SetActiveFlag(BOOL bFlag)
{
    bActiveFlag=bFlag;
}

BOOL ScStructListBox::GetActiveFlag()
{
    return bActiveFlag;
}

void ScStructListBox::MouseButtonDown( const MouseEvent& rMEvt )
{
    bActiveFlag=TRUE;
    SvTreeListBox::MouseButtonDown(rMEvt);
}

void ScStructListBox::GetFocus()
{
    bActiveFlag=TRUE;
    SvTreeListBox::GetFocus();
}

void ScStructListBox::LoseFocus()
{
    bActiveFlag=FALSE;
    SvTreeListBox::LoseFocus();
}

//==============================================================================

ScStructPage::ScStructPage(Window* pParent):
    TabPage(pParent,ScResId(RID_SCTAB_STRUCT)),
    //
    aFtStruct       ( this, ScResId( FT_STRUCT ) ),
    aTlbStruct      ( this, ScResId( TLB_STRUCT ) ),
    maImgEnd        ( ScResId( BMP_STR_END ) ),
    maImgError      ( ScResId( BMP_STR_ERROR ) ),
    maImgEndHC      ( ScResId( BMP_STR_END_H ) ),
    maImgErrorHC    ( ScResId( BMP_STR_ERROR_H ) ),
    pSelectedToken  ( NULL )
{
    aTlbStruct.SetWindowBits(WB_HASLINES|WB_CLIPCHILDREN|
                        WB_HASBUTTONS|WB_HSCROLL|WB_NOINITIALSELECTION);

    aTlbStruct.SetNodeDefaultImages();
    aTlbStruct.SetDefaultExpandedEntryBmp( Image( ScResId( BMP_STR_OPEN ) ) );
    aTlbStruct.SetDefaultCollapsedEntryBmp( Image( ScResId( BMP_STR_CLOSE ) ) );
    aTlbStruct.SetDefaultExpandedEntryBmp( Image( ScResId( BMP_STR_OPEN_H ) ), BMP_COLOR_HIGHCONTRAST );
    aTlbStruct.SetDefaultCollapsedEntryBmp( Image( ScResId( BMP_STR_CLOSE_H ) ), BMP_COLOR_HIGHCONTRAST );

    FreeResource();

    aTlbStruct.SetSelectHdl(LINK( this, ScStructPage, SelectHdl ) );
}

void ScStructPage::ClearStruct()
{
    aTlbStruct.SetActiveFlag(FALSE);
    aTlbStruct.Clear();
}

SvLBoxEntry* ScStructPage::InsertEntry( const XubString& rText, SvLBoxEntry* pParent,
                                       USHORT nFlag,ULONG nPos,ScToken* pScToken)
{
    aTlbStruct.SetActiveFlag( FALSE );

    SvLBoxEntry* pEntry = NULL;
    switch( nFlag )
    {
        case STRUCT_FOLDER:
            pEntry = aTlbStruct.InsertEntry( rText, pParent, FALSE, nPos, pScToken );
        break;
        case STRUCT_END:
            pEntry = aTlbStruct.InsertStaticEntry( rText, maImgEnd, maImgEndHC, pParent, nPos, pScToken );
        break;
        case STRUCT_ERROR:
            pEntry = aTlbStruct.InsertStaticEntry( rText, maImgError, maImgErrorHC, pParent, nPos, pScToken );
        break;
    }

    if( pEntry && pParent )
        aTlbStruct.Expand( pParent );
    return pEntry;
}

String ScStructPage::GetEntryText(SvLBoxEntry* pEntry)
{
    String aString;
    if(pEntry!=NULL)
        aString=aTlbStruct.GetEntryText(pEntry);
    return  aString;
}

ScToken* ScStructPage::GetFunctionEntry(SvLBoxEntry* pEntry)
{
    if(pEntry!=NULL)
    {
        ScToken * pToken=(ScToken *)pEntry->GetUserData();
        if(pToken!=NULL)
        {
            OpCode eOp = pToken->GetOpCode();
            if(!(pToken->IsFunction()|| ocArcTan2<=eOp))
            {
                return GetFunctionEntry(aTlbStruct.GetParent(pEntry));
            }
            else
            {
                return pToken;
            }
        }
    }
    return NULL;
}

IMPL_LINK( ScStructPage, SelectHdl, SvTreeListBox*, pTlb )
{
    if(aTlbStruct.GetActiveFlag())
    {
        if(pTlb==&aTlbStruct)
        {
            SvLBoxEntry*    pCurEntry=aTlbStruct.GetCurEntry();
            if(pCurEntry!=NULL)
            {
                pSelectedToken=(ScToken *)pCurEntry->GetUserData();
                if(pSelectedToken!=NULL)
                {
                    OpCode eOp = pSelectedToken->GetOpCode();
                    if(!(pSelectedToken->IsFunction()|| ocArcTan2<=eOp))
                    {
                        pSelectedToken=GetFunctionEntry(pCurEntry);
                    }
                }
            }
        }

        aSelLink.Call(this);
    }
    return 0;
}

ScToken * ScStructPage::GetSelectedToken()
{
    return pSelectedToken;
}

String ScStructPage::GetSelectedEntryText()
{
    return aTlbStruct.GetEntryText(aTlbStruct.GetCurEntry());
}

<|endoftext|>


<commit_before><commit_msg>argument offsets added<commit_after><|endoftext|>


<commit_before>/*
    This file is part of the "pfkutils" tools written by Phil Knaack
    (pknaack1@netscape.net).
    Copyright (C) 2008  Phillip F Knaack

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

/** \file extract.C
 * \brief Extract files from a backup.
 * \author Phillip F Knaack
 */

#include "database_elements.H"
#include "params.H"
#include "protos.H"
#include "FileList.H"

#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <zlib.h>

#define BAIL() \
    do { \
    fprintf(stderr, "%s:%s:%d: error\n", __FILE__, __FUNCTION__, __LINE__); \
    return; \
    } while (0)

/** a helper function which ensures directories exist when opening a file.
 * if the component directories don't exist, this function creates them.
 * it's sort of like "mkdir -p <path>".
 *
 * @param in_path   the path (relative to current working dir) to file to open.
 * @param mode      the file mode to open the file with.
 * @return a file descriptor or negative if there was a failure. errno is
 *         set in the event of a failure.
 */
static int
openfile( char *in_path, UINT16 mode )
{
    int len = strlen(in_path)+1;
    int num_comps = 1;
    int i, j;
    char * p;

    // count the path components.
    for (p = in_path; *p; p++)
        if (*p == '/')
            num_comps++;

    // copy the path into all of them
    char comps[num_comps][len];
    for (i = 0; i < num_comps; i++)
        memcpy(comps[i], in_path, len);

    // search for slashes and null them out
    for (i = j = 0; j < len; j++)
        if (in_path[j] == '/')
            comps[i++][j] = 0;

    // create component directories if they don't exist
    for (i=0; i < (num_comps-1); i++)
        if (mkdir( comps[i], 0700 ) < 0)
            if (errno != EEXIST)
                fprintf(stderr, "mkdir '%s': %s\n",
                        comps[i], strerror(errno));

    // and open the final file.
    return open( comps[i], O_WRONLY | O_CREAT, mode );
}

/** extract files from a backup.
 *
 * \todo currently argc and argv are ignored, this should be implemented.
 *
 * @param baknum the backup ID number.
 * @param gen_num which generation number to extract from the backup.
 * @param argc  count of arguments following on the command line. if argc is
 *              zero, it means extract everything.
 * @param argv  array of arguments on the command line; each arg represents
 *              a file to be extracted.
 */
void
pfkbak_extract       ( UINT32 baknum,
                       UINT32 gen_num, int argc, char ** argv )
{
    PfkBackupInfo back_info(pfkbak_meta);

    back_info.key.backup_number.v = baknum;

    if (!back_info.get())
        BAIL();

    int idx;
    {
        // validate that this gen# actually exists in this backup.

        BST_ARRAY <PfkBakGenInfo> * gens = &back_info.data.generations;
        for (idx = 0; idx < gens->num_items; idx++)
            if (gens->array[idx]->generation_number.v == gen_num)
                break;

        if (idx == gens->num_items)
        {
            fprintf(stderr, "generation %d not found in backup\n", gen_num);
            return;
        }
    }

    (void) umask( 000 );

    if (mkdir( back_info.data.name.string, 0700 ) < 0)
    {
        fprintf(stderr, "unable to create directory '%s': %s\n",
                back_info.data.name.string,
                strerror(errno));
        return;
    }
    (void) chdir( back_info.data.name.string );

    UINT32 num_files = back_info.data.file_count.v;
    UINT32 file_number;
    for (file_number = 0; file_number < num_files; file_number++)
    {
        PfkBackupFileInfo file_info(pfkbak_meta);

        file_info.key.backup_number.v = baknum;
        file_info.key.file_number.v = file_number;

        if (!file_info.get())
            // deleted files will leave holes, that's okay.
            continue;

        BST_ARRAY <BST_UINT32_t> * gens = &file_info.data.generations;

        // validate this file is actually part of this generation.

        for (idx = 0; idx < gens->num_items; idx++)
            if (gens->array[idx]->v == gen_num)
                break;

        if (idx == gens->num_items)
            // this file is not part of this generation.
            continue;

        char * file_path = file_info.data.file_path.string;

        // do a tar-like display, show the file name without
        // newline; don't display the newline until extraction
        // of the file is complete.

        /** \todo support extracting individual files */

        if (pfkbak_verb > VERB_QUIET)
        {
            printf("%s", file_path);
            fflush(stdout);
        }

        int fd = openfile(file_path, file_info.data.mode.v);

        if (fd < 0)
        {
            printf(": unable to create: %s\n", strerror(errno));
            continue;
        }

        PfkBackupFilePieceInfo piece_info(pfkbak_meta);
        PfkBackupFilePieceData piece_data(pfkbak_meta);
        UINT32 piece_number;

        for (piece_number = 0; ; piece_number++)
        {
            piece_info.key.backup_number.v = baknum;
            piece_info.key.file_number.v = file_number;
            piece_info.key.piece_number.v = piece_number;

            if (!piece_info.get())
                // end of file? probably.
                break;

            BST_ARRAY <PfkBackupVersion> * v = &piece_info.data.versions;

            for (idx = 0; idx < v->num_items; idx++)
                if (v->array[idx]->gen_number.v == gen_num)
                    break;

            if (idx == v->num_items)
            {
                // this is not really a bug; if a file gets shorter
                // from one gen to the next, later pieces will not be
                // tagged with this generation#, and so this is an
                // expected result.
                if (pfkbak_verb > VERB_QUIET)
                    printf(": piece %d info not found\n", piece_number);
            }
            else
            {
                piece_data.key.backup_number.v = baknum;
                piece_data.key.file_number.v = file_number;
                piece_data.key.piece_number.v = piece_number;
                piece_data.key.md5hash.alloc(MD5_DIGEST_SIZE);
                memcpy( piece_data.key.md5hash.binary,
                        v->array[idx]->md5hash.binary,
                        MD5_DIGEST_SIZE );

                if (!piece_data.get())
                {
                    printf(": piece %d data not found\n", piece_number);
                }
                else
                {
                    UINT32 fbn = piece_data.data.data_fbn.v;
                    UINT16 usize = piece_data.data.usize.v;
                    UINT16 csize = piece_data.data.csize.v;

                    FileBlock * fb = pfkbak_data->get( fbn );

                    if (!fb)
                    {
                        printf(": unable to fetch data for piece %d\n",
                               piece_number);
                    }
                    else
                    {
                        UCHAR ubuf[ usize ];
                        uLongf ulen = usize;

                        if (usize == csize)
                        {
                            (void) write( fd, fb->get_ptr(), csize );
                        }
                        else
                        {
                            (void) uncompress( (Bytef*)ubuf, &ulen,
                                               fb->get_ptr(), csize );
                            (void) write( fd, ubuf, ulen );
                        }
                        pfkbak_data->release( fb );
                    }
                }
            }
        }

        close(fd);
        if (pfkbak_verb > VERB_QUIET)
            printf("\n");
    }
}
<commit_msg>pfkbak extract to relative dir<commit_after>/*
    This file is part of the "pfkutils" tools written by Phil Knaack
    (pknaack1@netscape.net).
    Copyright (C) 2008  Phillip F Knaack

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

/** \file extract.C
 * \brief Extract files from a backup.
 * \author Phillip F Knaack
 */

#include "database_elements.H"
#include "params.H"
#include "protos.H"
#include "FileList.H"

#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <zlib.h>

#define BAIL() \
    do { \
    fprintf(stderr, "%s:%s:%d: error\n", __FILE__, __FUNCTION__, __LINE__); \
    return; \
    } while (0)

/** a helper function which ensures directories exist when opening a file.
 * if the component directories don't exist, this function creates them.
 * it's sort of like "mkdir -p <path>".
 *
 * @param in_path   the path (relative to current working dir) to file to open.
 * @param mode      the file mode to open the file with.
 * @return a file descriptor or negative if there was a failure. errno is
 *         set in the event of a failure.
 */
static int
openfile( char *in_path, UINT16 mode )
{
    int len = strlen(in_path)+1;
    int num_comps = 1;
    int i, j;
    char * p;

    // count the path components.
    for (p = in_path; *p; p++)
        if (*p == '/')
            num_comps++;

    // copy the path into all of them
    char comps[num_comps][len];
    for (i = 0; i < num_comps; i++)
        memcpy(comps[i], in_path, len);

    // search for slashes and null them out
    for (i = j = 0; j < len; j++)
        if (in_path[j] == '/')
            comps[i++][j] = 0;

    // create component directories if they don't exist
    for (i=0; i < (num_comps-1); i++)
        if (mkdir( comps[i], 0700 ) < 0)
            if (errno != EEXIST)
                fprintf(stderr, "mkdir '%s': %s\n",
                        comps[i], strerror(errno));

    // and open the final file.
    return open( comps[i], O_WRONLY | O_CREAT, mode );
}

/** extract files from a backup.
 *
 * \todo currently argc and argv are ignored, this should be implemented.
 *
 * @param baknum the backup ID number.
 * @param gen_num which generation number to extract from the backup.
 * @param argc  count of arguments following on the command line. if argc is
 *              zero, it means extract everything.
 * @param argv  array of arguments on the command line; each arg represents
 *              a file to be extracted.
 */
void
pfkbak_extract       ( UINT32 baknum,
                       UINT32 gen_num, int argc, char ** argv )
{
    PfkBackupInfo back_info(pfkbak_meta);

    back_info.key.backup_number.v = baknum;

    if (!back_info.get())
        BAIL();

    int idx;
    {
        // validate that this gen# actually exists in this backup.

        BST_ARRAY <PfkBakGenInfo> * gens = &back_info.data.generations;
        for (idx = 0; idx < gens->num_items; idx++)
            if (gens->array[idx]->generation_number.v == gen_num)
                break;

        if (idx == gens->num_items)
        {
            fprintf(stderr, "generation %d not found in backup\n", gen_num);
            return;
        }
    }

    (void) umask( 000 );

#if 0
    if (mkdir( back_info.data.name.string, 0700 ) < 0)
    {
        fprintf(stderr, "unable to create directory '%s': %s\n",
                back_info.data.name.string,
                strerror(errno));
        return;
    }
    (void) chdir( back_info.data.name.string );
#endif

    UINT32 num_files = back_info.data.file_count.v;
    UINT32 file_number;
    for (file_number = 0; file_number < num_files; file_number++)
    {
        PfkBackupFileInfo file_info(pfkbak_meta);

        file_info.key.backup_number.v = baknum;
        file_info.key.file_number.v = file_number;

        if (!file_info.get())
            // deleted files will leave holes, that's okay.
            continue;

        BST_ARRAY <BST_UINT32_t> * gens = &file_info.data.generations;

        // validate this file is actually part of this generation.

        for (idx = 0; idx < gens->num_items; idx++)
            if (gens->array[idx]->v == gen_num)
                break;

        if (idx == gens->num_items)
            // this file is not part of this generation.
            continue;

        char * file_path = file_info.data.file_path.string;

        // do a tar-like display, show the file name without
        // newline; don't display the newline until extraction
        // of the file is complete.

        /** \todo support extracting individual files */

        if (pfkbak_verb > VERB_QUIET)
        {
            printf("%s", file_path);
            fflush(stdout);
        }

        int fd = openfile(file_path, file_info.data.mode.v);

        if (fd < 0)
        {
            printf(": unable to create: %s\n", strerror(errno));
            continue;
        }

        PfkBackupFilePieceInfo piece_info(pfkbak_meta);
        PfkBackupFilePieceData piece_data(pfkbak_meta);
        UINT32 piece_number;

        for (piece_number = 0; ; piece_number++)
        {
            piece_info.key.backup_number.v = baknum;
            piece_info.key.file_number.v = file_number;
            piece_info.key.piece_number.v = piece_number;

            if (!piece_info.get())
                // end of file? probably.
                break;

            BST_ARRAY <PfkBackupVersion> * v = &piece_info.data.versions;

            for (idx = 0; idx < v->num_items; idx++)
                if (v->array[idx]->gen_number.v == gen_num)
                    break;

            if (idx == v->num_items)
            {
                // this is not really a bug; if a file gets shorter
                // from one gen to the next, later pieces will not be
                // tagged with this generation#, and so this is an
                // expected result.
                if (pfkbak_verb > VERB_QUIET)
                    printf(": piece %d info not found\n", piece_number);
            }
            else
            {
                piece_data.key.backup_number.v = baknum;
                piece_data.key.file_number.v = file_number;
                piece_data.key.piece_number.v = piece_number;
                piece_data.key.md5hash.alloc(MD5_DIGEST_SIZE);
                memcpy( piece_data.key.md5hash.binary,
                        v->array[idx]->md5hash.binary,
                        MD5_DIGEST_SIZE );

                if (!piece_data.get())
                {
                    printf(": piece %d data not found\n", piece_number);
                }
                else
                {
                    UINT32 fbn = piece_data.data.data_fbn.v;
                    UINT16 usize = piece_data.data.usize.v;
                    UINT16 csize = piece_data.data.csize.v;

                    FileBlock * fb = pfkbak_data->get( fbn );

                    if (!fb)
                    {
                        printf(": unable to fetch data for piece %d\n",
                               piece_number);
                    }
                    else
                    {
                        UCHAR ubuf[ usize ];
                        uLongf ulen = usize;

                        if (usize == csize)
                        {
                            (void) write( fd, fb->get_ptr(), csize );
                        }
                        else
                        {
                            (void) uncompress( (Bytef*)ubuf, &ulen,
                                               fb->get_ptr(), csize );
                            (void) write( fd, ubuf, ulen );
                        }
                        pfkbak_data->release( fb );
                    }
                }
            }
        }

        close(fd);
        if (pfkbak_verb > VERB_QUIET)
            printf("\n");
    }
}
<|endoftext|>


<commit_before>#include "utils.h"
#include "contours.h"

auto	contoursArea( const cv::Mat & mat, double thresh )
-> double {
	if ( mat.empty() ) {
		return 0.0;
	}

	threshold( mat, mat, thresh, 255, cv::THRESH_BINARY );
	//adaptiveThreshold(in, in, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 3, 1);

	Contours contours;
	findContours( toGray( mat ), contours, cv::RETR_LIST, cv::CHAIN_APPROX_TC89_L1 );

	auto data = 0.0;
	for ( auto && i : contours ) {
		cv::approxPolyDP( i, i, 1.0, false );
		//convexHull( i, i );
		data += cv::contourArea( i );
		//data += arcLength( i, 0 );
	}

	/*
	for ( auto && i : contours ) {
		cv::drawContours( mat, i, { 255, 255, 255 } );
	}
	*/
	return data;
}

auto	maskToContour( const cv::Mat & mat )
-> Contour {
	Contours contours;
	cv::findContours( toGray( mat ), contours, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE );
	if ( !contours.empty() ) {
		return contours[ 0 ];
	}
	return{};
}

auto	getOptimalThresh( const cv::Mat & mat1, const cv::Mat & mat2, double smin, double thresh_min, double thresh_max )
-> double {
	auto thresh = thresh_max, s = 0.0;
	for ( ; s < smin && thresh >= thresh_min; --thresh ) {
		s = contoursArea( cv::abs( mat1 - mat2 ), thresh );
	}
	return thresh;
}<commit_msg>Delete contours.cpp<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/base/resource/resource_bundle.h"

#include "base/command_line.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "ui/base/layout.h"
#include "ui/base/resource/resource_handle.h"
#include "ui/base/ui_base_paths.h"
#include "ui/base/ui_base_switches.h"
#include "ui/gfx/image/image.h"

namespace {

FilePath GetResourcesPakFilePath(const std::string& pak_name) {
  FilePath path;
  if (PathService::Get(base::DIR_MODULE, &path))
    return path.AppendASCII(pak_name.c_str());

  // Return just the name of the pack file.
  return FilePath(pak_name.c_str());
}

}  // namespace

namespace ui {

void ResourceBundle::LoadCommonResources() {
  // Always load the 1x data pack first as the 2x data pack contains both 1x and
  // 2x images. The 1x data pack only has 1x images, thus passes in an accurate
  // scale factor to gfx::ImageSkia::AddBitmapForScale.
  // TODO(pkotwicz): Fix this in cases where it is intended for the 2x bitmap
  // not to be 2 * size of the 1x bitmap for HDA.
  // TODO(oshima): Fix this where it is unintended.

  AddDataPack(GetResourcesPakFilePath("chrome.pak"),
              SCALE_FACTOR_100P);

  if (ui::GetDisplayLayout() == ui::LAYOUT_TOUCH) {
    // 1x touch
    AddDataPack(GetResourcesPakFilePath("theme_resources_touch_1x.pak"),
                SCALE_FACTOR_100P);
    AddDataPack(GetResourcesPakFilePath("ui_resources_touch.pak"),
                SCALE_FACTOR_100P);
    if (CommandLine::ForCurrentProcess()->HasSwitch(
            switches::kLoad2xResources)) {
      // 2x touch
      AddDataPack(GetResourcesPakFilePath("theme_resources_touch_2x.pak"),
                  SCALE_FACTOR_200P);
      AddDataPack(GetResourcesPakFilePath("ui_resources_touch_2x.pak"),
                  SCALE_FACTOR_200P);
    }
  } else {
    // 1x non touch
    AddDataPack(GetResourcesPakFilePath("theme_resources_standard.pak"),
                SCALE_FACTOR_100P);
    AddDataPack(GetResourcesPakFilePath("ui_resources_standard.pak"),
                SCALE_FACTOR_100P);
    if (CommandLine::ForCurrentProcess()->HasSwitch(
            switches::kLoad2xResources)) {
      // 2x non touch
      AddDataPack(GetResourcesPakFilePath("theme_resources_standard_2x.pak"),
                  SCALE_FACTOR_200P);
      AddDataPack(GetResourcesPakFilePath("ui_resources_2x.pak"),
                  SCALE_FACTOR_200P);
    }
  }
}

gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id, ImageRTL rtl) {
  // Flipped image is not used on ChromeOS.
  DCHECK_EQ(rtl, RTL_DISABLED);
  return GetImageNamed(resource_id);
}

}  // namespace ui
<commit_msg>Load 2x resources whenever --default-device-scale-factor=2 is set<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/base/resource/resource_bundle.h"

#include "base/command_line.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "ui/base/layout.h"
#include "ui/base/resource/resource_handle.h"
#include "ui/base/ui_base_paths.h"
#include "ui/base/ui_base_switches.h"
#include "ui/gfx/display.h"
#include "ui/gfx/image/image.h"

namespace {

FilePath GetResourcesPakFilePath(const std::string& pak_name) {
  FilePath path;
  if (PathService::Get(base::DIR_MODULE, &path))
    return path.AppendASCII(pak_name.c_str());

  // Return just the name of the pack file.
  return FilePath(pak_name.c_str());
}

bool ShouldLoad2xResources() {
  return (gfx::Display::GetDefaultDeviceScaleFactor() > 1.0f ||
      CommandLine::ForCurrentProcess()->HasSwitch(switches::kLoad2xResources));
}

}  // namespace

namespace ui {

void ResourceBundle::LoadCommonResources() {
  // Always load the 1x data pack first as the 2x data pack contains both 1x and
  // 2x images. The 1x data pack only has 1x images, thus passes in an accurate
  // scale factor to gfx::ImageSkia::AddBitmapForScale.
  // TODO(pkotwicz): Fix this in cases where it is intended for the 2x bitmap
  // not to be 2 * size of the 1x bitmap for HDA.
  // TODO(oshima): Fix this where it is unintended.

  AddDataPack(GetResourcesPakFilePath("chrome.pak"),
              SCALE_FACTOR_100P);

  if (ui::GetDisplayLayout() == ui::LAYOUT_TOUCH) {
    // 1x touch
    AddDataPack(GetResourcesPakFilePath("theme_resources_touch_1x.pak"),
                SCALE_FACTOR_100P);
    AddDataPack(GetResourcesPakFilePath("ui_resources_touch.pak"),
                SCALE_FACTOR_100P);
    if (ShouldLoad2xResources()) {
      // 2x touch
      AddDataPack(GetResourcesPakFilePath("theme_resources_touch_2x.pak"),
                  SCALE_FACTOR_200P);
      AddDataPack(GetResourcesPakFilePath("ui_resources_touch_2x.pak"),
                  SCALE_FACTOR_200P);
    }
  } else {
    // 1x non touch
    AddDataPack(GetResourcesPakFilePath("theme_resources_standard.pak"),
                SCALE_FACTOR_100P);
    AddDataPack(GetResourcesPakFilePath("ui_resources_standard.pak"),
                SCALE_FACTOR_100P);
    if (ShouldLoad2xResources()) {
      // 2x non touch
      AddDataPack(GetResourcesPakFilePath("theme_resources_standard_2x.pak"),
                  SCALE_FACTOR_200P);
      AddDataPack(GetResourcesPakFilePath("ui_resources_2x.pak"),
                  SCALE_FACTOR_200P);
    }
  }
}

gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id, ImageRTL rtl) {
  // Flipped image is not used on ChromeOS.
  DCHECK_EQ(rtl, RTL_DISABLED);
  return GetImageNamed(resource_id);
}

}  // namespace ui
<|endoftext|>