<commit_before>#include <babylon/misc/file_tools.h>
#include <babylon/asio/asio.h>

#define STB_IMAGE_IMPLEMENTATION
#if defined(__GNUC__) || defined(__MINGW32__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
#pragma GCC diagnostic ignored "-Wconversion"
#if __GNUC__ > 5
#pragma GCC diagnostic ignored "-Wmisleading-indentation"
#pragma GCC diagnostic ignored "-Wshift-negative-value"
#endif
#if __GNUC__ > 6
// Use of GNU statement expression extension
#endif
#pragma GCC diagnostic ignored "-Wswitch-default"
#endif
#if _MSC_VER && !__INTEL_COMPILER
#ifndef NOMINMAX
#define NOMINMAX
#endif
#pragma warning(push)
#pragma warning(disable : 4244)
#endif
#include <stb_image/stb_image.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#if defined(__GNUC__) || defined(__MINGW32__)
#pragma GCC diagnostic pop
#endif

#include <babylon/core/array_buffer_view.h>
#include <babylon/core/filesystem.h>
#include <babylon/core/logging.h>
#include <babylon/core/string.h>
#include <babylon/interfaces/igl_rendering_context.h>
#include <babylon/loading/progress_event.h>
#include <babylon/utils/base64.h>

#include <stdexcept>

namespace BABYLON {

std::string FileTools::PreprocessUrl(const std::string& url)
{
  return url;
}

std::string FileTools::_CleanUrl(std::string url)
{
  String::replaceInPlace(url, "#", "%23");
  return url;
}

void FileTools::LoadImageFromUrl(
  std::string url, const std::function<void(const Image& img)>& onLoad,
  const std::function<void(const std::string& message, const std::string& exception)>& onError,
  bool flipVertically)
{
  url = FileTools::_CleanUrl(url);
  url = FileTools::PreprocessUrl(url);

  std::string filename = url;

  auto onArrayBufferReceived = [=](const ArrayBuffer & buffer) {
    auto image = ArrayBufferToImage(buffer, flipVertically);
    onLoad(image);
  };
  auto onErrorWrapper = [=](const std::string& errorMessage) {
    onError(errorMessage, "");
  };

  asio::LoadUrlAsync_Binary(url, onArrayBufferReceived, onErrorWrapper);
}

void FileTools::LoadImageFromBuffer(
  const std::variant<std::string, ArrayBuffer, ArrayBufferView, Image>& input, bool invertY,
  const std::function<void(const Image& img)>& onLoad,
  const std::function<void(const std::string& message, const std::string& exception)>& onError)
{
  if (!onLoad) {
    return;
  }

  if (std::holds_alternative<std::string>(input)) {
    onLoad(FileTools::StringToImage(std::get<std::string>(input), invertY));
  }
  else if (std::holds_alternative<ArrayBuffer>(input)) {
    onLoad(FileTools::ArrayBufferToImage(std::get<ArrayBuffer>(input), invertY));
  }
  else if (std::holds_alternative<ArrayBufferView>(input)) {
    onLoad(FileTools::ArrayBufferToImage(std::get<ArrayBufferView>(input).uint8Array, invertY));
  }
  else if (std::holds_alternative<Image>(input)) {
    onLoad(std::get<Image>(input));
  }
  else {
    auto errorMessage = "Loading image from url not supported";
    if (onError) {
      onError(errorMessage, "");
    }
    else {
      throw std::runtime_error(errorMessage);
    }
  }
}

Image FileTools::ArrayBufferToImage(const ArrayBuffer& buffer, bool flipVertically)
{
  if (buffer.empty()) {
    return Image();
  }
  auto bufferSize = static_cast<int>(buffer.size());
  int w = -1, h = -1, n = -1;
  int req_comp = STBI_rgb_alpha;

  stbi_set_flip_vertically_on_load(flipVertically);
  unsigned char * ucharBuffer = stbi_load_from_memory(buffer.data(), bufferSize, &w, &h, &n, req_comp);
  stbi_set_flip_vertically_on_load(false);

  if (!ucharBuffer)
    return Image();

  n = STBI_rgb_alpha;
  Image image (ucharBuffer, w * h * n, w, h, n, (n == 3) ? GL::RGB : GL::RGBA);
  stbi_image_free(ucharBuffer);
  return image;
}

Image FileTools::StringToImage(const std::string& uri, bool flipVertically)
{
  const auto IsDataURI = [](const std::string& in) -> bool {
    std::string header = "data:application/octet-stream;base64,";
    if (in.find(header) == 0) {
      return true;
    }

    header = "data:image/jpeg;base64,";
    if (in.find(header) == 0) {
      return true;
    }

    header = "data:image/png;base64,";
    if (in.find(header) == 0) {
      return true;
    }

    header = "data:image/bmp;base64,";
    if (in.find(header) == 0) {
      return true;
    }

    header = "data:image/gif;base64,";
    if (in.find(header) == 0) {
      return true;
    }

    header = "data:text/plain;base64,";
    if (in.find(header) == 0) {
      return true;
    }

    header = "data:application/gltf-buffer;base64,";
    return in.find(header) == 0;
  };

  const auto DecodeDataURI = [](std::vector<unsigned char>* out, std::string& mime_type,
                                const std::string& in, size_t reqBytes, bool checkSize) -> bool {
    std::string header = "data:application/octet-stream;base64,";
    std::string data;
    if (in.find(header) == 0) {
      data = Base64::decode(in.substr(header.size())); // cut mime string.
    }

    if (data.empty()) {
      header = "data:image/jpeg;base64,";
      if (in.find(header) == 0) {
        mime_type = "image/jpeg";
        data      = Base64::decode(in.substr(header.size())); // cut mime string.
      }
    }

    if (data.empty()) {
      header = "data:image/png;base64,";
      if (in.find(header) == 0) {
        mime_type = "image/png";
        data      = Base64::decode(in.substr(header.size())); // cut mime string.
      }
    }

    if (data.empty()) {
      header = "data:image/bmp;base64,";
      if (in.find(header) == 0) {
        mime_type = "image/bmp";
        data      = Base64::decode(in.substr(header.size())); // cut mime string.
      }
    }

    if (data.empty()) {
      header = "data:image/gif;base64,";
      if (in.find(header) == 0) {
        mime_type = "image/gif";
        data      = Base64::decode(in.substr(header.size())); // cut mime string.
      }
    }

    if (data.empty()) {
      header = "data:text/plain;base64,";
      if (in.find(header) == 0) {
        mime_type = "text/plain";
        data      = Base64::decode(in.substr(header.size()));
      }
    }

    if (data.empty()) {
      header = "data:application/gltf-buffer;base64,";
      if (in.find(header) == 0) {
        data = Base64::decode(in.substr(header.size()));
      }
    }

    if (data.empty()) {
      return false;
    }

    if (checkSize) {
      if (data.size() != reqBytes) {
        return false;
      }
      out->resize(reqBytes);
    }
    else {
      out->resize(data.size());
    }
    std::copy(data.begin(), data.end(), out->begin());
    return true;
  };

  const auto LoadImageData = [](Image& image, int req_width, int req_height,
                                const unsigned char* bytes, int size, bool flipVertically) -> bool {
    int w = 0, h = 0, comp = 0, req_comp = 0;

    unsigned char* data = nullptr;

    // force 32-bit textures for common Vulkan compatibility. It appears that
    // some GPU drivers do not support 24-bit images for Vulkan
    req_comp = 4;
    int bits = 8;

    stbi_set_flip_vertically_on_load(flipVertically);

    // It is possible that the image we want to load is a 16bit per channel
    // image We are going to attempt to load it as 16bit per channel, and if it
    // worked, set the image data accodingly. We are casting the returned
    // pointer into unsigned char, because we are representing "bytes". But we
    // are updating the Image metadata to signal that this image uses 2 bytes
    // (16bits) per channel:
    if (stbi_is_16_bit_from_memory(bytes, size)) {
      data = reinterpret_cast<unsigned char*>(
        stbi_load_16_from_memory(bytes, size, &w, &h, &comp, req_comp));
      if (data) {
        bits = 16;
      }
    }

    // at this point, if data is still NULL, it means that the image wasn't
    // 16bit per channel, we are going to load it as a normal 8bit per channel
    // mage as we used to do:
    // if image cannot be decoded, ignore parsing and keep it by its path
    // don't break in this case
    // FIXME we should only enter this function if the image is embedded. If
    // image->uri references
    // an image file, it should be left as it is. Image loading should not be
    // mandatory (to support other formats)
    if (!data)
      data = stbi_load_from_memory(bytes, size, &w, &h, &comp, req_comp);
    if (!data) {
      BABYLON_LOG_WARN("StringToImage",
                       "Unknown image format. STB cannot decode image data for image")
      return false;
    }

    stbi_set_flip_vertically_on_load(false);

    if ((w < 1) || (h < 1)) {
      stbi_image_free(data);
      BABYLON_LOG_ERROR("StringToImage", "Invalid image data for image")
      return false;
    }

    if (req_width > 0) {
      if (req_width != w) {
        stbi_image_free(data);
        BABYLON_LOG_ERROR("StringToImage", "Image width mismatch for image")
        return false;
      }
    }

    if (req_height > 0) {
      if (req_height != h) {
        stbi_image_free(data);
        BABYLON_LOG_ERROR("StringToImage", "Image height mismatch. for image")
        return false;
      }
    }

    image.width  = w;
    image.height = h;
    image.depth  = req_comp;
    image.mode   = (req_comp == 3) ? GL::RGB : GL::RGBA;
    image.data.resize(static_cast<size_t>(w * h * req_comp) * size_t(bits / 8));
    std::copy(data, data + w * h * req_comp * (bits / 8), image.data.begin());
    stbi_image_free(data);

    return true;
  };

  Image image;
  std::vector<unsigned char> img;
  std::string mimeType;
  if (IsDataURI(uri)) {
    if (!DecodeDataURI(&img, mimeType, uri, 0, false)) {
      BABYLON_LOG_ERROR("Failed to decode image from uri: %s", uri.c_str())
      return Image();
    }
  }

  if (LoadImageData(image, 0, 0, &img.at(0), static_cast<int>(img.size()), flipVertically)) {
    return image;
  }

  return Image();
}

// Superfluous params?
constexpr const char* dummyResponseUrl     = "";
constexpr const char* dummyExceptionString = "";
constexpr const char* dummyProgressType    = "";

void FileTools::LoadFile(
  const std::string& url,
  const std::function<void(const std::variant<std::string, ArrayBuffer>& data,
                           const std::string& responseURL)>& onSuccess,
  const std::function<void(const ProgressEvent& event)>& onProgress,
  bool useArrayBuffer,
  const std::function<void(const std::string& message, const std::string& exception)>& onError)
{
  // LoadFile's signature is extremely complicated for no good reason
  // Let's write some wrappers from the simple callbacks of BABYLON::asio
  // We will need to refactor this later

  std::string url_clean = FileTools::_CleanUrl(url);
  url_clean = FileTools::PreprocessUrl(url);

  auto onErrorWrapper = [onError](const std::string& errorMessage) {
    if (onError)
      onError(errorMessage, dummyExceptionString);
  };
  auto onProgressWrapper = [onProgress](bool lengthComputable, size_t loaded, size_t total) {
    if (onProgress)
      onProgress({dummyProgressType, lengthComputable, loaded, total});
  };

  if (useArrayBuffer)
  {
    auto onSuccessWrapper = [onSuccess](const ArrayBuffer& data) {
      if (onSuccess)
        onSuccess(data, dummyResponseUrl);
    };
    asio::LoadUrlAsync_Binary(url_clean, onSuccessWrapper, onErrorWrapper, onProgressWrapper);
  }
  else
  {
    auto onSuccessWrapper = [onSuccess](const std::string& data) {
      if (onSuccess) {
        onSuccess(data, dummyResponseUrl);
      }
    };
    asio::LoadUrlAsync_Text(url_clean, onSuccessWrapper, onErrorWrapper, onProgressWrapper);
  }

  asio::Service_WaitAll_Sync();
  //std::cout << "WaitAll finished\n";
}

} // end of namespace BABYLON
<commit_msg>FileTools::LoadFile / don't call Service_WaitAll_Sync<commit_after>#include <babylon/misc/file_tools.h>
#include <babylon/asio/asio.h>

#define STB_IMAGE_IMPLEMENTATION
#if defined(__GNUC__) || defined(__MINGW32__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
#pragma GCC diagnostic ignored "-Wconversion"
#if __GNUC__ > 5
#pragma GCC diagnostic ignored "-Wmisleading-indentation"
#pragma GCC diagnostic ignored "-Wshift-negative-value"
#endif
#if __GNUC__ > 6
// Use of GNU statement expression extension
#endif
#pragma GCC diagnostic ignored "-Wswitch-default"
#endif
#if _MSC_VER && !__INTEL_COMPILER
#ifndef NOMINMAX
#define NOMINMAX
#endif
#pragma warning(push)
#pragma warning(disable : 4244)
#endif
#include <stb_image/stb_image.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#if defined(__GNUC__) || defined(__MINGW32__)
#pragma GCC diagnostic pop
#endif

#include <babylon/core/array_buffer_view.h>
#include <babylon/core/filesystem.h>
#include <babylon/core/logging.h>
#include <babylon/core/string.h>
#include <babylon/interfaces/igl_rendering_context.h>
#include <babylon/loading/progress_event.h>
#include <babylon/utils/base64.h>

#include <stdexcept>

namespace BABYLON {

std::string FileTools::PreprocessUrl(const std::string& url)
{
  return url;
}

std::string FileTools::_CleanUrl(std::string url)
{
  String::replaceInPlace(url, "#", "%23");
  return url;
}

void FileTools::LoadImageFromUrl(
  std::string url, const std::function<void(const Image& img)>& onLoad,
  const std::function<void(const std::string& message, const std::string& exception)>& onError,
  bool flipVertically)
{
  url = FileTools::_CleanUrl(url);
  url = FileTools::PreprocessUrl(url);

  std::string filename = url;

  auto onArrayBufferReceived = [=](const ArrayBuffer & buffer) {
    auto image = ArrayBufferToImage(buffer, flipVertically);
    onLoad(image);
  };
  auto onErrorWrapper = [=](const std::string& errorMessage) {
    onError(errorMessage, "");
  };

  asio::LoadUrlAsync_Binary(url, onArrayBufferReceived, onErrorWrapper);
}

void FileTools::LoadImageFromBuffer(
  const std::variant<std::string, ArrayBuffer, ArrayBufferView, Image>& input, bool invertY,
  const std::function<void(const Image& img)>& onLoad,
  const std::function<void(const std::string& message, const std::string& exception)>& onError)
{
  if (!onLoad) {
    return;
  }

  if (std::holds_alternative<std::string>(input)) {
    onLoad(FileTools::StringToImage(std::get<std::string>(input), invertY));
  }
  else if (std::holds_alternative<ArrayBuffer>(input)) {
    onLoad(FileTools::ArrayBufferToImage(std::get<ArrayBuffer>(input), invertY));
  }
  else if (std::holds_alternative<ArrayBufferView>(input)) {
    onLoad(FileTools::ArrayBufferToImage(std::get<ArrayBufferView>(input).uint8Array, invertY));
  }
  else if (std::holds_alternative<Image>(input)) {
    onLoad(std::get<Image>(input));
  }
  else {
    auto errorMessage = "Loading image from url not supported";
    if (onError) {
      onError(errorMessage, "");
    }
    else {
      throw std::runtime_error(errorMessage);
    }
  }
}

Image FileTools::ArrayBufferToImage(const ArrayBuffer& buffer, bool flipVertically)
{
  if (buffer.empty()) {
    return Image();
  }
  auto bufferSize = static_cast<int>(buffer.size());
  int w = -1, h = -1, n = -1;
  int req_comp = STBI_rgb_alpha;

  stbi_set_flip_vertically_on_load(flipVertically);
  unsigned char * ucharBuffer = stbi_load_from_memory(buffer.data(), bufferSize, &w, &h, &n, req_comp);
  stbi_set_flip_vertically_on_load(false);

  if (!ucharBuffer)
    return Image();

  n = STBI_rgb_alpha;
  Image image (ucharBuffer, w * h * n, w, h, n, (n == 3) ? GL::RGB : GL::RGBA);
  stbi_image_free(ucharBuffer);
  return image;
}

Image FileTools::StringToImage(const std::string& uri, bool flipVertically)
{
  const auto IsDataURI = [](const std::string& in) -> bool {
    std::string header = "data:application/octet-stream;base64,";
    if (in.find(header) == 0) {
      return true;
    }

    header = "data:image/jpeg;base64,";
    if (in.find(header) == 0) {
      return true;
    }

    header = "data:image/png;base64,";
    if (in.find(header) == 0) {
      return true;
    }

    header = "data:image/bmp;base64,";
    if (in.find(header) == 0) {
      return true;
    }

    header = "data:image/gif;base64,";
    if (in.find(header) == 0) {
      return true;
    }

    header = "data:text/plain;base64,";
    if (in.find(header) == 0) {
      return true;
    }

    header = "data:application/gltf-buffer;base64,";
    return in.find(header) == 0;
  };

  const auto DecodeDataURI = [](std::vector<unsigned char>* out, std::string& mime_type,
                                const std::string& in, size_t reqBytes, bool checkSize) -> bool {
    std::string header = "data:application/octet-stream;base64,";
    std::string data;
    if (in.find(header) == 0) {
      data = Base64::decode(in.substr(header.size())); // cut mime string.
    }

    if (data.empty()) {
      header = "data:image/jpeg;base64,";
      if (in.find(header) == 0) {
        mime_type = "image/jpeg";
        data      = Base64::decode(in.substr(header.size())); // cut mime string.
      }
    }

    if (data.empty()) {
      header = "data:image/png;base64,";
      if (in.find(header) == 0) {
        mime_type = "image/png";
        data      = Base64::decode(in.substr(header.size())); // cut mime string.
      }
    }

    if (data.empty()) {
      header = "data:image/bmp;base64,";
      if (in.find(header) == 0) {
        mime_type = "image/bmp";
        data      = Base64::decode(in.substr(header.size())); // cut mime string.
      }
    }

    if (data.empty()) {
      header = "data:image/gif;base64,";
      if (in.find(header) == 0) {
        mime_type = "image/gif";
        data      = Base64::decode(in.substr(header.size())); // cut mime string.
      }
    }

    if (data.empty()) {
      header = "data:text/plain;base64,";
      if (in.find(header) == 0) {
        mime_type = "text/plain";
        data      = Base64::decode(in.substr(header.size()));
      }
    }

    if (data.empty()) {
      header = "data:application/gltf-buffer;base64,";
      if (in.find(header) == 0) {
        data = Base64::decode(in.substr(header.size()));
      }
    }

    if (data.empty()) {
      return false;
    }

    if (checkSize) {
      if (data.size() != reqBytes) {
        return false;
      }
      out->resize(reqBytes);
    }
    else {
      out->resize(data.size());
    }
    std::copy(data.begin(), data.end(), out->begin());
    return true;
  };

  const auto LoadImageData = [](Image& image, int req_width, int req_height,
                                const unsigned char* bytes, int size, bool flipVertically) -> bool {
    int w = 0, h = 0, comp = 0, req_comp = 0;

    unsigned char* data = nullptr;

    // force 32-bit textures for common Vulkan compatibility. It appears that
    // some GPU drivers do not support 24-bit images for Vulkan
    req_comp = 4;
    int bits = 8;

    stbi_set_flip_vertically_on_load(flipVertically);

    // It is possible that the image we want to load is a 16bit per channel
    // image We are going to attempt to load it as 16bit per channel, and if it
    // worked, set the image data accodingly. We are casting the returned
    // pointer into unsigned char, because we are representing "bytes". But we
    // are updating the Image metadata to signal that this image uses 2 bytes
    // (16bits) per channel:
    if (stbi_is_16_bit_from_memory(bytes, size)) {
      data = reinterpret_cast<unsigned char*>(
        stbi_load_16_from_memory(bytes, size, &w, &h, &comp, req_comp));
      if (data) {
        bits = 16;
      }
    }

    // at this point, if data is still NULL, it means that the image wasn't
    // 16bit per channel, we are going to load it as a normal 8bit per channel
    // mage as we used to do:
    // if image cannot be decoded, ignore parsing and keep it by its path
    // don't break in this case
    // FIXME we should only enter this function if the image is embedded. If
    // image->uri references
    // an image file, it should be left as it is. Image loading should not be
    // mandatory (to support other formats)
    if (!data)
      data = stbi_load_from_memory(bytes, size, &w, &h, &comp, req_comp);
    if (!data) {
      BABYLON_LOG_WARN("StringToImage",
                       "Unknown image format. STB cannot decode image data for image")
      return false;
    }

    stbi_set_flip_vertically_on_load(false);

    if ((w < 1) || (h < 1)) {
      stbi_image_free(data);
      BABYLON_LOG_ERROR("StringToImage", "Invalid image data for image")
      return false;
    }

    if (req_width > 0) {
      if (req_width != w) {
        stbi_image_free(data);
        BABYLON_LOG_ERROR("StringToImage", "Image width mismatch for image")
        return false;
      }
    }

    if (req_height > 0) {
      if (req_height != h) {
        stbi_image_free(data);
        BABYLON_LOG_ERROR("StringToImage", "Image height mismatch. for image")
        return false;
      }
    }

    image.width  = w;
    image.height = h;
    image.depth  = req_comp;
    image.mode   = (req_comp == 3) ? GL::RGB : GL::RGBA;
    image.data.resize(static_cast<size_t>(w * h * req_comp) * size_t(bits / 8));
    std::copy(data, data + w * h * req_comp * (bits / 8), image.data.begin());
    stbi_image_free(data);

    return true;
  };

  Image image;
  std::vector<unsigned char> img;
  std::string mimeType;
  if (IsDataURI(uri)) {
    if (!DecodeDataURI(&img, mimeType, uri, 0, false)) {
      BABYLON_LOG_ERROR("Failed to decode image from uri: %s", uri.c_str())
      return Image();
    }
  }

  if (LoadImageData(image, 0, 0, &img.at(0), static_cast<int>(img.size()), flipVertically)) {
    return image;
  }

  return Image();
}

// Superfluous params?
constexpr const char* dummyResponseUrl     = "";
constexpr const char* dummyExceptionString = "";
constexpr const char* dummyProgressType    = "";

void FileTools::LoadFile(
  const std::string& url,
  const std::function<void(const std::variant<std::string, ArrayBuffer>& data,
                           const std::string& responseURL)>& onSuccess,
  const std::function<void(const ProgressEvent& event)>& onProgress,
  bool useArrayBuffer,
  const std::function<void(const std::string& message, const std::string& exception)>& onError)
{
  // LoadFile's signature is extremely complicated for no good reason
  // Let's write some wrappers from the simple callbacks of BABYLON::asio
  // We will need to refactor this later

  std::string url_clean = FileTools::_CleanUrl(url);
  url_clean = FileTools::PreprocessUrl(url);

  auto onErrorWrapper = [onError](const std::string& errorMessage) {
    if (onError)
      onError(errorMessage, dummyExceptionString);
  };
  auto onProgressWrapper = [onProgress](bool lengthComputable, size_t loaded, size_t total) {
    if (onProgress)
      onProgress({dummyProgressType, lengthComputable, loaded, total});
  };

  if (useArrayBuffer)
  {
    auto onSuccessWrapper = [onSuccess](const ArrayBuffer& data) {
      if (onSuccess)
        onSuccess(data, dummyResponseUrl);
    };
    asio::LoadUrlAsync_Binary(url_clean, onSuccessWrapper, onErrorWrapper, onProgressWrapper);
  }
  else
  {
    auto onSuccessWrapper = [onSuccess](const std::string& data) {
      if (onSuccess) {
        onSuccess(data, dummyResponseUrl);
      }
    };
    asio::LoadUrlAsync_Text(url_clean, onSuccessWrapper, onErrorWrapper, onProgressWrapper);
  }

  // asio::Service_WaitAll_Sync();
  //std::cout << "WaitAll finished\n";
}

} // end of namespace BABYLON
<|endoftext|>


<commit_before><commit_msg>Implements View::GetXXXDragThreshold on Linux.<commit_after><|endoftext|>


<commit_before><commit_msg>[SPIR-V] Handle 16/16, 16/16/16/16 (float and norm) and 32f<commit_after><|endoftext|>


<commit_before>#include "databaseconnectionstatuslabel.hxx"

#include <apps/app/app.hxx>

PROJECT_NAMESPACE_BEGIN
WIDGETS_NAMESPACE_BEGIN

DatabaseConnectionStatusLabel::DatabaseConnectionStatusLabel(QWidget* p)
    : StatusLabel(p)
{
    connect(APP_NAMESPACE::App::get(), &APP_NAMESPACE::App::databaseIsAvailable, this, &DatabaseConnectionStatusLabel::onDatabaseAvailable);
    connect(APP_NAMESPACE::App::get(), &APP_NAMESPACE::App::databaseIsUnavailable, this, &DatabaseConnectionStatusLabel::onDatabaseUnavailable);
}

void DatabaseConnectionStatusLabel::onDatabaseAvailable(const QString &msg)
{
    setText(msg);
}

void DatabaseConnectionStatusLabel::onDatabaseUnavailable(const QString &msg)
{
    setText(msg);
}

WIDGETS_NAMESPACE_END
PROJECT_NAMESPACE_END
<commit_msg>set initial status<commit_after>#include "databaseconnectionstatuslabel.hxx"

#include <apps/app/app.hxx>

PROJECT_NAMESPACE_BEGIN
WIDGETS_NAMESPACE_BEGIN

DatabaseConnectionStatusLabel::DatabaseConnectionStatusLabel(QWidget* p)
    : StatusLabel(p)
{
    connect(APP_NAMESPACE::App::get(), &APP_NAMESPACE::App::databaseIsAvailable, this, &DatabaseConnectionStatusLabel::onDatabaseAvailable);
    connect(APP_NAMESPACE::App::get(), &APP_NAMESPACE::App::databaseIsUnavailable, this, &DatabaseConnectionStatusLabel::onDatabaseUnavailable);

    onDatabaseUnavailable(tr("Database not available"));
}

void DatabaseConnectionStatusLabel::onDatabaseAvailable(const QString &msg)
{
    setText(msg);
}

void DatabaseConnectionStatusLabel::onDatabaseUnavailable(const QString &msg)
{
    setText(msg);
}

WIDGETS_NAMESPACE_END
PROJECT_NAMESPACE_END
<|endoftext|>


<commit_before>//===--- Stubs.cpp - Swift Language ABI Runtime Stubs ---------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Misc stubs for functions which should be in swift.swift, but are difficult
// or impossible to write in swift at the moment.
//
//===----------------------------------------------------------------------===//

#include <mach/mach_time.h>
#include <sys/resource.h>
#include <sys/errno.h>
#include <pthread.h>
#include <unistd.h>
#include <cstring>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <sys/stat.h> // stat
#include <fcntl.h>    // open
#include <unistd.h>  // read, close
#include <dirent.h>
#include <limits.h>
#include "llvm/ADT/StringExtras.h"

// FIXME: We shouldn't be writing implemenetations for functions in the swift
// module in C, and this isn't really an ideal place to put those
// implementations.
extern "C" void _TSs5printFT3valSi_T_(int64_t l) {
  printf("%lld", l);
}

extern "C" void _TSs5printFT3valSu_T_(uint64_t l) {
  printf("%llu", l);
}

extern "C" void _TSs5printFT3valSd_T_(double l) {
  char Buffer[256];
  sprintf(Buffer, "%g", l);
  if (strchr(Buffer, 'e') == nullptr && strchr(Buffer, '.') == nullptr)
    strcat(Buffer, ".0");
  printf("%s", Buffer);
}

// static func String(v : Int128, radix : Int) -> String
extern "C"
unsigned long long
print_int(char* TmpBuffer, __int64_t buf_len, __int128_t X, uint64_t Radix,
          bool uppercase) {
  assert(Radix != 0 && Radix <= 36 && "Invalid radix for string conversion");
  char *P = TmpBuffer;

  bool WasNeg = X < 0;
  __uint128_t Y = WasNeg ? -X : X;

  if (Y == 0) {
    *P++ = '0';
  } else if (Radix == 10) {
    while (Y) {
      *P++ = '0' + char(Y % 10);
      Y /= 10;
    }
  } else {
    unsigned Radix32 = Radix;
    while (Y) {
      *P++ = llvm::hexdigit(Y % Radix32, !uppercase);
      Y /= Radix32;
    }
  }

  if (WasNeg) *P++ = '-';
  std::reverse(TmpBuffer, P);
  return size_t(P - TmpBuffer);
}

// static func String(v : UInt128, radix : Int) -> String
extern "C"
unsigned long long
print_uint(char* TmpBuffer, __int64_t buf_len, __uint128_t Y, uint64_t Radix,
           bool uppercase) {
  assert(Radix != 0 && Radix <= 36 && "Invalid radix for string conversion");
  char *P = TmpBuffer;

  if (Y == 0) {
    *P++ = '0';
  } else if (Radix == 10) {
    while (Y) {
      *P++ = '0' + char(Y % 10);
      Y /= 10;
    }
  } else {
    unsigned Radix32 = Radix;
    while (Y) {
      *P++ = llvm::hexdigit(Y % Radix32, !uppercase);
      Y /= Radix32;
    }
  }

  std::reverse(TmpBuffer, P);
  return size_t(P - TmpBuffer);
}

// static func String(v : Double) -> String
extern "C"
unsigned long long
print_double(char* Buffer, double X) {
  long long i = sprintf(Buffer, "%g", X);
  if (strchr(Buffer, 'e') == nullptr && strchr(Buffer, '.') == nullptr) {
    Buffer[i++] = '.';
    Buffer[i++] = '0';
  }
  if (i < 0) {
    __builtin_trap();
  }
  return i;
}

extern "C" bool _TSb13getLogicValuefRSbFT_Bi1_(bool* b) {
  return *b;
}

extern "C" bool swift_getBool(bool b) {
  return b;
}

static bool
_swift_replOutputIsUTF8(void) {
  const char *lang = getenv("LANG");
  return lang && strstr(lang, "UTF-8");
}

extern "C"
uint32_t
swift_replOutputIsUTF8(void) {
  static auto rval = _swift_replOutputIsUTF8();
  return rval;
}

#if defined(__i386__) || defined(__x86_64__)
static inline uint64_t
rdtsc() {
  uint32_t lo, hi;
  asm("rdtsc" : "=a" (lo), "=d" (hi));
  return uint64_t(hi) << 32 | lo;
}
#else
#error "not supported"
#endif

static double interruptOverhead;
static double loopOverhead;

static uint64_t
_swift_startBenchmark(void) {
  return rdtsc();
}

extern "C"
void
swift_printBenchmark(uint64_t start, uint64_t laps, char *buffer, int64_t len) {
  double val = rdtsc() - start;
  val /= laps;
  val /= interruptOverhead;
  val -= loopOverhead;
  printf("%12.2f  %*s\n", val, (int)len, buffer);
}

extern "C"
__attribute__((noinline,used))
__typeof__(&_swift_startBenchmark)
_swift_initBenchmark() asm("_swift_startBenchmark");

__typeof__(&_swift_startBenchmark)
_swift_initBenchmark() {
  asm(".symbol_resolver _swift_startBenchmark");
  union {
    unsigned reg[4*3];
    char brand[48];
  } u;
  char brand[48];
  char *s2 = u.brand;
  char *s1 = brand;
  unsigned eax, ebx, ecx, edx;
  memset(&u, 0, sizeof(u));
  int r;

  // Let's not have the OS compete with our CPU time if we can avoid it
  r = setvbuf(stdout, 0, _IOFBF, 0);
  assert(r == 0);

  // XXX -- There doesn't seem to be an API to figure out the max value
  sched_param schedParam;
  schedParam.sched_priority = 79;
  r = pthread_setschedparam(pthread_self(), SCHED_FIFO, &schedParam);
  assert(r == 0);

  eax = 0x80000002;
  asm("cpuid" : "+a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx));
  u.reg[0] = eax;
  u.reg[1] = ebx;
  u.reg[2] = ecx;
  u.reg[3] = edx;

  eax = 0x80000003;
  asm("cpuid" : "+a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx));
  u.reg[4] = eax;
  u.reg[5] = ebx;
  u.reg[6] = ecx;
  u.reg[7] = edx;

  eax = 0x80000004;
  asm("cpuid" : "+a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx));
  u.reg[8] = eax;
  u.reg[9] = ebx;
  u.reg[10] = ecx;
  u.reg[11] = edx;

  while (*s2 == ' ') {
    s2++;
  }
  do {
    while (s2[0] == ' ' && s2[1] == ' ') {
      s2++;
    }
  } while ((*s1++ = *s2++));
  printf("Processor: %s\n\n", brand);

  uint64_t start = rdtsc();
  for (unsigned long i = 0; i < 1000000000ull; i++) {
    asm("");
  }
  double delta = (rdtsc() - start) / 1000000000.0;
  assert((delta >= 1.0 && delta < 1.05) || (delta >= 2.0 && delta < 2.05));
  if (delta >= 2.0) {
    loopOverhead = 2.0;
    interruptOverhead = delta / 2.0;
  } else {
    loopOverhead = 1.0;
    interruptOverhead = delta / 1.0;
  }
  assert((interruptOverhead - 1.0) < 0.01);

  eax = 6;
  asm("cpuid" : "+a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx));

  if (eax & 2) {
    fprintf(stderr, "WARNING: TurboBoost. Results will be less reliable.\n");
    fprintf(stderr, "         Consider: sudo /usr/local/bin/pstates -D\n\n");
  }

  if (geteuid()) {
    fprintf(stderr, "WARNING: Non-elevated priority. Results will be less reliable.\n");
    fprintf(stderr, "         Consider: sudo ./myBench\n\n");
  }

  return _swift_startBenchmark;
}

extern "C"
int
swift_file_open(const char* filename)
{
  return open(filename, O_RDONLY);
}

extern "C"
int
swift_file_close(int fd)
{
  return close(fd);
}

extern "C"
size_t
swift_file_read(int fd, char* buf, size_t nb)
{
  return read(fd, buf, nb);
}

extern "C"
size_t
swift_fd_size(int fd)
{
  struct stat buf;
  int err = fstat(fd, &buf);
  assert(err == 0);
  (void) err;
  return buf.st_size;
}

struct readdir_tuple_s {
  char *str;
  int64_t len;
};

extern "C"
struct readdir_tuple_s
posix_readdir_hack(DIR *d)
{
  struct readdir_tuple_s rval = { NULL, 0 };
  struct dirent *dp;
  if ((dp = readdir(d))) {
    rval.str = dp->d_name;
    rval.len = dp->d_namlen;
  }
  return rval;
}

extern "C"
int64_t
posix_isDirectory_hack(const char *path)
{
  struct stat sb;
  int r = stat(path, &sb);
  (void)r;
  assert(r != -1);
  return S_ISDIR(sb.st_mode);
}

extern "C"
int
posix_get_errno(void)
{
  return errno; // errno is not a global, but a macro
}

extern "C"
void
posix_set_errno(int value)
{
  errno = value; // errno is not a global, but a macro
}
<commit_msg>Don't append ".0" to "inf" and "-inf".<commit_after>//===--- Stubs.cpp - Swift Language ABI Runtime Stubs ---------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Misc stubs for functions which should be in swift.swift, but are difficult
// or impossible to write in swift at the moment.
//
//===----------------------------------------------------------------------===//

#include <mach/mach_time.h>
#include <sys/resource.h>
#include <sys/errno.h>
#include <pthread.h>
#include <unistd.h>
#include <cstring>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <sys/stat.h> // stat
#include <fcntl.h>    // open
#include <unistd.h>  // read, close
#include <dirent.h>
#include <limits.h>
#include "llvm/ADT/StringExtras.h"

// static func String(v : Int128, radix : Int) -> String
extern "C"
unsigned long long
print_int(char* TmpBuffer, __int64_t buf_len, __int128_t X, uint64_t Radix,
          bool uppercase) {
  assert(Radix != 0 && Radix <= 36 && "Invalid radix for string conversion");
  char *P = TmpBuffer;

  bool WasNeg = X < 0;
  __uint128_t Y = WasNeg ? -X : X;

  if (Y == 0) {
    *P++ = '0';
  } else if (Radix == 10) {
    while (Y) {
      *P++ = '0' + char(Y % 10);
      Y /= 10;
    }
  } else {
    unsigned Radix32 = Radix;
    while (Y) {
      *P++ = llvm::hexdigit(Y % Radix32, !uppercase);
      Y /= Radix32;
    }
  }

  if (WasNeg) *P++ = '-';
  std::reverse(TmpBuffer, P);
  return size_t(P - TmpBuffer);
}

// static func String(v : UInt128, radix : Int) -> String
extern "C"
unsigned long long
print_uint(char* TmpBuffer, __int64_t buf_len, __uint128_t Y, uint64_t Radix,
           bool uppercase) {
  assert(Radix != 0 && Radix <= 36 && "Invalid radix for string conversion");
  char *P = TmpBuffer;

  if (Y == 0) {
    *P++ = '0';
  } else if (Radix == 10) {
    while (Y) {
      *P++ = '0' + char(Y % 10);
      Y /= 10;
    }
  } else {
    unsigned Radix32 = Radix;
    while (Y) {
      *P++ = llvm::hexdigit(Y % Radix32, !uppercase);
      Y /= Radix32;
    }
  }

  std::reverse(TmpBuffer, P);
  return size_t(P - TmpBuffer);
}

// static func String(v : Double) -> String
extern "C"
unsigned long long
print_double(char* Buffer, double X) {
  long long i = sprintf(Buffer, "%g", X);
  // Add ".0" to a float that (a) is not in scientific notation, (b) does not
  // already have a fractional part, and (c) is not infinite.
  if (strchr(Buffer, 'e') == nullptr && strchr(Buffer, '.') == nullptr &&
      strchr(Buffer, 'n') == nullptr) {
    Buffer[i++] = '.';
    Buffer[i++] = '0';
  }
  if (i < 0) {
    __builtin_trap();
  }
  return i;
}

// FIXME: We shouldn't be writing implemenetations for functions in the swift
// module in C, and this isn't really an ideal place to put those
// implementations.
extern "C" void _TSs5printFT3valSi_T_(int64_t l) {
  printf("%lld", l);
}

extern "C" void _TSs5printFT3valSu_T_(uint64_t l) {
  printf("%llu", l);
}

extern "C" void _TSs5printFT3valSd_T_(double l) {
  char Buffer[256];
  unsigned long long i = print_double(Buffer, l);
  Buffer[i] = '\0';
  printf("%s", Buffer);
}

extern "C" bool _TSb13getLogicValuefRSbFT_Bi1_(bool* b) {
  return *b;
}

extern "C" bool swift_getBool(bool b) {
  return b;
}

static bool
_swift_replOutputIsUTF8(void) {
  const char *lang = getenv("LANG");
  return lang && strstr(lang, "UTF-8");
}

extern "C"
uint32_t
swift_replOutputIsUTF8(void) {
  static auto rval = _swift_replOutputIsUTF8();
  return rval;
}

#if defined(__i386__) || defined(__x86_64__)
static inline uint64_t
rdtsc() {
  uint32_t lo, hi;
  asm("rdtsc" : "=a" (lo), "=d" (hi));
  return uint64_t(hi) << 32 | lo;
}
#else
#error "not supported"
#endif

static double interruptOverhead;
static double loopOverhead;

static uint64_t
_swift_startBenchmark(void) {
  return rdtsc();
}

extern "C"
void
swift_printBenchmark(uint64_t start, uint64_t laps, char *buffer, int64_t len) {
  double val = rdtsc() - start;
  val /= laps;
  val /= interruptOverhead;
  val -= loopOverhead;
  printf("%12.2f  %*s\n", val, (int)len, buffer);
}

extern "C"
__attribute__((noinline,used))
__typeof__(&_swift_startBenchmark)
_swift_initBenchmark() asm("_swift_startBenchmark");

__typeof__(&_swift_startBenchmark)
_swift_initBenchmark() {
  asm(".symbol_resolver _swift_startBenchmark");
  union {
    unsigned reg[4*3];
    char brand[48];
  } u;
  char brand[48];
  char *s2 = u.brand;
  char *s1 = brand;
  unsigned eax, ebx, ecx, edx;
  memset(&u, 0, sizeof(u));
  int r;

  // Let's not have the OS compete with our CPU time if we can avoid it
  r = setvbuf(stdout, 0, _IOFBF, 0);
  assert(r == 0);

  // XXX -- There doesn't seem to be an API to figure out the max value
  sched_param schedParam;
  schedParam.sched_priority = 79;
  r = pthread_setschedparam(pthread_self(), SCHED_FIFO, &schedParam);
  assert(r == 0);

  eax = 0x80000002;
  asm("cpuid" : "+a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx));
  u.reg[0] = eax;
  u.reg[1] = ebx;
  u.reg[2] = ecx;
  u.reg[3] = edx;

  eax = 0x80000003;
  asm("cpuid" : "+a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx));
  u.reg[4] = eax;
  u.reg[5] = ebx;
  u.reg[6] = ecx;
  u.reg[7] = edx;

  eax = 0x80000004;
  asm("cpuid" : "+a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx));
  u.reg[8] = eax;
  u.reg[9] = ebx;
  u.reg[10] = ecx;
  u.reg[11] = edx;

  while (*s2 == ' ') {
    s2++;
  }
  do {
    while (s2[0] == ' ' && s2[1] == ' ') {
      s2++;
    }
  } while ((*s1++ = *s2++));
  printf("Processor: %s\n\n", brand);

  uint64_t start = rdtsc();
  for (unsigned long i = 0; i < 1000000000ull; i++) {
    asm("");
  }
  double delta = (rdtsc() - start) / 1000000000.0;
  assert((delta >= 1.0 && delta < 1.05) || (delta >= 2.0 && delta < 2.05));
  if (delta >= 2.0) {
    loopOverhead = 2.0;
    interruptOverhead = delta / 2.0;
  } else {
    loopOverhead = 1.0;
    interruptOverhead = delta / 1.0;
  }
  assert((interruptOverhead - 1.0) < 0.01);

  eax = 6;
  asm("cpuid" : "+a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx));

  if (eax & 2) {
    fprintf(stderr, "WARNING: TurboBoost. Results will be less reliable.\n");
    fprintf(stderr, "         Consider: sudo /usr/local/bin/pstates -D\n\n");
  }

  if (geteuid()) {
    fprintf(stderr, "WARNING: Non-elevated priority. Results will be less reliable.\n");
    fprintf(stderr, "         Consider: sudo ./myBench\n\n");
  }

  return _swift_startBenchmark;
}

extern "C"
int
swift_file_open(const char* filename)
{
  return open(filename, O_RDONLY);
}

extern "C"
int
swift_file_close(int fd)
{
  return close(fd);
}

extern "C"
size_t
swift_file_read(int fd, char* buf, size_t nb)
{
  return read(fd, buf, nb);
}

extern "C"
size_t
swift_fd_size(int fd)
{
  struct stat buf;
  int err = fstat(fd, &buf);
  assert(err == 0);
  (void) err;
  return buf.st_size;
}

struct readdir_tuple_s {
  char *str;
  int64_t len;
};

extern "C"
struct readdir_tuple_s
posix_readdir_hack(DIR *d)
{
  struct readdir_tuple_s rval = { NULL, 0 };
  struct dirent *dp;
  if ((dp = readdir(d))) {
    rval.str = dp->d_name;
    rval.len = dp->d_namlen;
  }
  return rval;
}

extern "C"
int64_t
posix_isDirectory_hack(const char *path)
{
  struct stat sb;
  int r = stat(path, &sb);
  (void)r;
  assert(r != -1);
  return S_ISDIR(sb.st_mode);
}

extern "C"
int
posix_get_errno(void)
{
  return errno; // errno is not a global, but a macro
}

extern "C"
void
posix_set_errno(int value)
{
  errno = value; // errno is not a global, but a macro
}
<|endoftext|>


<commit_before>/* Copyright (c) 2010-present Advanced Micro Devices, Inc.

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

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

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

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 3184
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<commit_msg>SWDEV-2 - Change OpenCL version number from  3184 to 3185<commit_after>/* Copyright (c) 2010-present Advanced Micro Devices, Inc.

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

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

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

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 3185
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<|endoftext|>


<commit_before>#include "hermes1d.h"

#include "legendre.h"
#include "quad_std.h"

// This test makes sure that Legendre polynomials
// are orthonormal.

#define ERROR_SUCCESS                               0
#define ERROR_FAILURE                               -1

int main(int argc, char* argv[])
{
  // maximum poly degree of Legendre polynomials tested
  int max_poly_degree = 29; //FIXME: should be 99

  // maximum allowed error
  double max_allowed_error = 1e-10;

  // loop over polynomial degrees, starting with 1
  double max_actual_error = 0;
  for (int poly_deg_1=0; poly_deg_1<max_poly_degree; poly_deg_1++) {
    for (int poly_deg_2=0; poly_deg_2<max_poly_degree; poly_deg_2++) {
      // integrating the Legendre polynomial of degree 'poly_deg'
      // from -1 to 1 using Gauss quadratures of orders 1, 2, ...
      // MAX_POLYORDER
      for (int quad_order=poly_deg_1 + poly_deg_2;
           quad_order<2*max_poly_degree; quad_order++) {
        int num_pts = g_quad_1d_std.get_num_points(quad_order);
        double2 *quad_tab = g_quad_1d_std.get_points(quad_order);
        double val = 0;
        for (int i=0; i<num_pts; i++) {
          double point_i = quad_tab[i][0];
          double weight_i = quad_tab[i][1];
          val += legendre_fn_tab_1d[poly_deg_1](point_i) *
                 legendre_fn_tab_1d[poly_deg_2](point_i) * weight_i;
        }
        if (poly_deg_1 == poly_deg_2) { // val must be one
          if (fabs(val - 1.) > max_actual_error)
            max_actual_error = fabs(val - 1.);
          if (max_actual_error > max_allowed_error) {
            printf("poly_deg_1 = %d, poly_deg_2 = %d, quad_order = %d, val - 1. = %g\n",
                   poly_deg_1, poly_deg_2, quad_order, val - 1.);
            return ERROR_FAILURE;
          }
        }
        else { // val must be zero
          if (fabs(val) > max_actual_error)
            max_actual_error = fabs(val);
          if (max_actual_error > max_allowed_error) {
            printf("poly_deg_1 = %d, poly_deg_2 = %d, quad_order = %d, val = %g\n",
                   poly_deg_1, poly_deg_2, quad_order, val);
            return ERROR_FAILURE;
          }
        }
      }
    }
  }

  printf("Success!\n");
  return ERROR_SUCCESS;
}
<commit_msg>Example legendre-2 now works for p = 0, 1, ..., 50.<commit_after>#include "hermes1d.h"

#include "legendre.h"
#include "quad_std.h"

// This test makes sure that Legendre polynomials
// are orthonormal. It takes a lot of time.

#define ERROR_SUCCESS                               0
#define ERROR_FAILURE                               -1

int main(int argc, char* argv[])
{
  // maximum poly degree of Legendre polynomials tested
  int max_test_poly_degree = 50;

  // maximum allowed error
  double max_allowed_error = 1e-12;

  // loop over polynomial degrees, starting with 1
  double max_actual_error = 0;
  for (int poly_deg_1=0; poly_deg_1 < max_test_poly_degree+1; poly_deg_1++) {
    for (int poly_deg_2=0; poly_deg_2<max_test_poly_degree+1; poly_deg_2++) {
      // integrating the product of Legendre polynomials of degrees
      // 'poly_deg_1' and 'poly_deg_2'from -1 to 1 using Gauss quadratures
      // of order poly_deg_1 + poly_deg_2
      for (int quad_order=poly_deg_1 + poly_deg_2;
           quad_order<2*max_test_poly_degree; quad_order++) {
        int num_pts = g_quad_1d_std.get_num_points(quad_order);
        double2 *quad_tab = g_quad_1d_std.get_points(quad_order);
        double val = 0;
        for (int i=0; i<num_pts; i++) {
          double point_i = quad_tab[i][0];
          double weight_i = quad_tab[i][1];
          val += calc_leg_pol_val(point_i, poly_deg_1) *
                 calc_leg_pol_val(point_i, poly_deg_2) * weight_i;
        }
        double val_final;
        if (poly_deg_1 == poly_deg_2) val_final = val - 1.0;
        else val_final = val;
        printf("poly_deg_1 = %d, poly_deg_2 = %d, quad_order = %d, val_final = %g\n", poly_deg_1, poly_deg_2, quad_order, val_final);
        if (fabs(val_final) > max_actual_error) {
          max_actual_error = fabs(val_final);
          if (max_actual_error > max_allowed_error) {
            printf("Failure!\n");
            return ERROR_FAILURE;
          }
        }
      }
    }
  }

  printf("Success!\n");
  return ERROR_SUCCESS;
}
<|endoftext|>


<commit_before>/* Copyright (c) 2010 - 2021 Advanced Micro Devices, Inc.

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

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

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

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 3530
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<commit_msg>SWDEV-2 - Change OpenCL version number from  3530 to 3531<commit_after>/* Copyright (c) 2010 - 2021 Advanced Micro Devices, Inc.

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

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

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

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 3531
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<|endoftext|>


<commit_before>#include "vision_thread.h"
#include "612.h"
#include "ranges.h"
#include "vision_alt.h"
#include "update.h"
#include "ports.h"
#include "particle_filter.h"
#include <Vision/AxisCamera.h>
#include <Vision/Threshold.h>
#include <Timer.h>
#include <Task.h>
#include <cstdio>
#include <vxWorks.h>
#include <nivision.h>

#include <algorithm>
#include <utility>
#include <fstream>

#if DEBUG_612
const int WRITE_IMAGE = 9;
#endif

//NI function
IMAQ_FUNC int Priv_SetWriteFileAllowed(UINT32 enable);

void update_targets(vision_thread&, ColorImage&);

vision_thread::vision_thread(AxisCamera& c, vision_processor p) : thread_obj("vision_processing", (FUNCPTR)thread_worker), cam(c) {
    callback = p;
    enabled = true;
    //initialize mutex
    target_lock = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
    //make new thread
    if (!thread_obj.Start((uinteger)this)) {
        std::printf("Vision: Error creating thread.\n");
    }
}

vision_thread::~vision_thread() {
    //destroy other thread
    std::printf("Destroying semaphore\n");
    semDelete(target_lock);
    thread_obj.Stop();
}

int vision_thread::thread_worker(uinteger obj) {
    ((vision_thread*)obj)->process_loop();
    //should never be reached
    return 0;
}

void vision_thread::process_loop() {
    //this the routine puts us in here.  Do vision processing
    while (true) {
        //YES, I KNOW GOTOS ARE SUPPOSED TO BE EVIL.  I AM USING THEM HERE
        //TO AVOID NEEDLESS SENTINEL VARIABLES.
        if (enabled) {
            //get picture from camera
#if DEBUG_612
                Timer process_time;
                process_time.Start();
#endif
            if (!camera().IsFreshImage()) {
                goto processing_footer; //no new image for us to process
            }
            if (!camera().GetImage(&image)) {
                perror_612("Cannot Recieve Image From Camera");
                goto processing_footer;
            }
            //do vision processing
            callback(*this, image);
#if DEBUG_612
                output_debug_info();
                //std::printf("Processing took %f sec\n", process_time.Get());
#endif
        }
        processing_footer:
        {
            Wait(0.05); //should be a trivial wait compared to processing wait
            //wait is here to keep sucking up processing power while polling the
            //camera object
        }
    }
}

void vision_thread::enable() {
    enabled = true;
}

void vision_thread::disable() {
    enabled = false;
}

void vision_thread::lock_targets() {
    semTake(target_lock, WAIT_FOREVER);
}

void vision_thread::release_targets() {
    semGive(target_lock);
}

//returns if thread is locked
bool vision_thread::lock_targets_nowait() {
    if (semTake(target_lock, NO_WAIT) == ERROR) {
        //unsuccessful
        return false;
    }
    else {
        //locked
        return true;
    }
}

vision_targets::vision_targets()
#ifdef VISION_ALT_HEURISTIC
    : bottom_t(bottom_basket), top_t(top_basket), left_t(midleft_basket), right_t(midright_basket) {
#else
{
    target t;
    for (unsigned i = 0; i < numtargets; i++) {
        targets_vec.push_back(t);
    }
#endif
    registry().register_func(update_helper, (void*)this);
}

vision_targets::~vision_targets() {
    registry().unregister_func(update_helper, (void*)this);
}

void vision_targets::update_helper(void * obj) {
    ((vision_targets*)obj)->update();
}

void vision_targets::update() {
    if (get_vision_thread().lock_targets_nowait()) {
#ifdef VISION_ALT_HEURISTIC
        bottom_t = bottom_basket;
        left_t = midleft_basket;
        right_t = midright_basket;
        top_t = top_basket;
#else
        for (unsigned i = 0; i < numtargets; i++) {
            targets_vec.at(i) = target_arr[i];
        }
#endif
        get_vision_thread().release_targets();
    }
}

#ifdef VISION_ALT_HEURISTIC

target& vision_targets::bottom() {
    return bottom_t;
}

target& vision_targets::top() {
    return top_t;
}

target& vision_targets::left() {
    return left_t;
}

target& vision_targets::right() {
    return right_t;
}

#else

std::vector<target> vision_targets::targets() {
    return targets_vec;
}

#endif

vision_thread& get_vision_thread() {
    static vision_thread t(camera(), update_targets);
    return t;
}

vision_targets& get_targets() {
    static vision_targets t;
    return t;
}

//FORCE INSTANTIATION
vision_thread& VISION_THREAD_INSTANCE = get_vision_thread();
vision_targets& VISION_TARGETS_INSTANCE = get_targets();

//MUST DELETE RETURN VALUE IN CALLER
std::pair<report_vector*, BinaryImage*> do_threshold(ColorImage& image) {
    //Threshold objects
    static Threshold HSL_THOLD(HSL_HMIN, HSL_HMAX, HSL_SMIN, HSL_SMAX, HSL_LMIN, HSL_LMAX);
    static Threshold HSI_THOLD(HSI_HMIN, HSI_HMAX, HSI_SMIN, HSI_SMAX, HSI_IMIN, HSI_IMAX);
    static Threshold HSV_THOLD(HSV_HMIN, HSV_HMAX, HSV_SMIN, HSV_SMAX, HSV_VMIN, HSV_VMAX);
    BinaryImage * result = NULL;
    if (COLOR_MODE == HSL) {
        result = image.ThresholdHSL(HSL_THOLD);
    }
    else if (COLOR_MODE == HSI) {
        result = image.ThresholdHSI(HSI_THOLD);
    }
    else if (COLOR_MODE == HSV) {
        result = image.ThresholdHSV(HSV_THOLD);
    }
    else {
        //color mode undefined.  Fall back to HSL
        result = image.ThresholdHSL(HSL_THOLD);
        perror_612("Invalid Color Mode - Falling Back to HSL");
    }
    if (!result) {
        //we have issues
        perror_612("Threshold Unsuccessful");
        return std::make_pair<report_vector*, BinaryImage*>(NULL, NULL);
    }
    report_vector * ret = result->GetOrderedParticleAnalysisReports();
    //delete result;//TODO: may be more efficient if we can allocate one binary
                    //image and call imaqColorThreshold.  leaving as is now
                    //cause it's prettier this way and POITROAE.
    return std::make_pair<report_vector*, BinaryImage*>(ret, result);
}

void do_particle_filter(report_vector * v, Image * img) {
    //filter particles
    particle_filter filt(img);
    v->erase(std::remove_if(v->begin(), v->end(), filt), v->end());
    if (v->size() > 4) { //more than four elements
        v->resize(4); //drop extra elements - get four biggest
    }
}

void write_particles(const char * fname, const report_vector * v) {
    //write particle analyses
    std::fstream o(fname, std::fstream::out | std::fstream::trunc);
    o << "#ifndef REPORT_H_INC\n"
         "#define REPORT_H_INC\n\n"
         "struct Rect {\n"
         "\tint top;\n"
         "\tint left;\n"
         "\tint height;\n"
         "\tint width;\n"
         "};\n\n"
         "struct ParticleAnalysisReport {\n"
         "\tint imageHeight;\n"
         "\tint imageWidth;\n"
         "\tdouble imageTimestamp;\n"
         "\tint particleIndex;\n"
         "\tint center_mass_x;\n"
         "\tint center_mass_y;\n"
         "\tdouble center_mass_x_normalized;\n"
         "\tdouble cneter_mass_y_normalized;\n"
         "\tdouble particleArea;\n"
         "\tRect boundingRect;\n"
         "\tdouble particleToImagePercent;\n"
         "\tdouble particleQuality;\n"
         "};\n\n"
         "ParticleAnalysisReport reports[] = {\n";
    if (v->size()) {
        report_vector::const_iterator it;
        for (it = v->begin(); it < v->end(); it++) {
            o << "\t{\n"
                 "\t\t" << it->imageHeight << ",\n"
                 "\t\t" << it->imageWidth << ",\n"
                 "\t\t" << it->imageTimestamp << ",\n"
                 "\t\t" << it->particleIndex << ",\n"
                 "\t\t" << it->center_mass_x << ",\n"
                 "\t\t" << it->center_mass_y << ",\n"
                 "\t\t" << it->center_mass_x_normalized << ",\n"
                 "\t\t" << it->center_mass_y_normalized << ",\n"
                 "\t\t" << it->particleArea << ",\n"
                 "\t\t{\n"
                 "\t\t\t" << it->boundingRect.top << ",\n"
                 "\t\t\t" << it->boundingRect.left << ",\n"
                 "\t\t\t" << it->boundingRect.height << ",\n"
                 "\t\t\t" << it->boundingRect.width << ",\n"
                 "\t\t},\n"
                 "\t\t" << it->particleToImagePercent << ",\n"
                 "\t\t" << it->particleQuality << ",\n"
                 "\t}";
            if (it + 1 != v->end()) {
                o << ',';
            }
            o << std::endl;
        }
    }
    o << "};\n\n"
         "#endif" << std::endl;
    //PHEW.
    o.close();
}

void update_targets(vision_thread& thread, ColorImage& image) {
    std::pair<report_vector*, BinaryImage*> ptrs = do_threshold(image);
    report_vector * reports = ptrs.first;
    BinaryImage * img = ptrs.second;
#if DEBUG_612
    if (left_joystick.GetRawButton(WRITE_IMAGE)) {
        std::printf("Writing...\n");
        char buffer[64];
        std::sprintf(buffer, "%f_clr.bmp", Timer::GetFPGATimestamp());
        image.Write(buffer);
        int x = std::strlen(buffer);
        buffer[x-6] = 'b';
        buffer[x-5] = 'i';
        buffer[x-4] = 'n';
        img->Write(buffer);
        buffer[x-7] = '.';
        buffer[x-6] = 'h';
        buffer[x-5] = '\0';
        write_particles(buffer, reports);
    }
#endif
    if (!reports) {
        //particle analysis failed.
        if (img) {
            delete img;
        }
        return;
    }
    do_particle_filter(reports, img->GetImaqImage());
    thread.lock_targets();
    target::id_and_process(reports);
    thread.release_targets();
    delete reports; //free vector
    delete img; //free image
}
<commit_msg>added include for cstring and fixed make_pair for c++0x<commit_after>#include "vision_thread.h"
#include "612.h"
#include "ranges.h"
#include "vision_alt.h"
#include "update.h"
#include "ports.h"
#include "particle_filter.h"
#include <Vision/AxisCamera.h>
#include <Vision/Threshold.h>
#include <Timer.h>
#include <Task.h>
#include <cstdio>
#include <cstring>
#include <vxWorks.h>
#include <nivision.h>

#include <algorithm>
#include <utility>
#include <fstream>

#if DEBUG_612
const int WRITE_IMAGE = 9;
#endif

//NI function
IMAQ_FUNC int Priv_SetWriteFileAllowed(UINT32 enable);

void update_targets(vision_thread&, ColorImage&);

vision_thread::vision_thread(AxisCamera& c, vision_processor p) : thread_obj("vision_processing", (FUNCPTR)thread_worker), cam(c) {
    callback = p;
    enabled = true;
    //initialize mutex
    target_lock = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
    //make new thread
    if (!thread_obj.Start((uinteger)this)) {
        std::printf("Vision: Error creating thread.\n");
    }
}

vision_thread::~vision_thread() {
    //destroy other thread
    std::printf("Destroying semaphore\n");
    semDelete(target_lock);
    thread_obj.Stop();
}

int vision_thread::thread_worker(uinteger obj) {
    ((vision_thread*)obj)->process_loop();
    //should never be reached
    return 0;
}

void vision_thread::process_loop() {
    //this the routine puts us in here.  Do vision processing
    while (true) {
        //YES, I KNOW GOTOS ARE SUPPOSED TO BE EVIL.  I AM USING THEM HERE
        //TO AVOID NEEDLESS SENTINEL VARIABLES.
        if (enabled) {
            //get picture from camera
#if DEBUG_612
                Timer process_time;
                process_time.Start();
#endif
            if (!camera().IsFreshImage()) {
                goto processing_footer; //no new image for us to process
            }
            if (!camera().GetImage(&image)) {
                perror_612("Cannot Recieve Image From Camera");
                goto processing_footer;
            }
            //do vision processing
            callback(*this, image);
#if DEBUG_612
                output_debug_info();
                //std::printf("Processing took %f sec\n", process_time.Get());
#endif
        }
        processing_footer:
        {
            Wait(0.05); //should be a trivial wait compared to processing wait
            //wait is here to keep sucking up processing power while polling the
            //camera object
        }
    }
}

void vision_thread::enable() {
    enabled = true;
}

void vision_thread::disable() {
    enabled = false;
}

void vision_thread::lock_targets() {
    semTake(target_lock, WAIT_FOREVER);
}

void vision_thread::release_targets() {
    semGive(target_lock);
}

//returns if thread is locked
bool vision_thread::lock_targets_nowait() {
    if (semTake(target_lock, NO_WAIT) == ERROR) {
        //unsuccessful
        return false;
    }
    else {
        //locked
        return true;
    }
}

vision_targets::vision_targets()
#ifdef VISION_ALT_HEURISTIC
    : bottom_t(bottom_basket), top_t(top_basket), left_t(midleft_basket), right_t(midright_basket) {
#else
{
    target t;
    for (unsigned i = 0; i < numtargets; i++) {
        targets_vec.push_back(t);
    }
#endif
    registry().register_func(update_helper, (void*)this);
}

vision_targets::~vision_targets() {
    registry().unregister_func(update_helper, (void*)this);
}

void vision_targets::update_helper(void * obj) {
    ((vision_targets*)obj)->update();
}

void vision_targets::update() {
    if (get_vision_thread().lock_targets_nowait()) {
#ifdef VISION_ALT_HEURISTIC
        bottom_t = bottom_basket;
        left_t = midleft_basket;
        right_t = midright_basket;
        top_t = top_basket;
#else
        for (unsigned i = 0; i < numtargets; i++) {
            targets_vec.at(i) = target_arr[i];
        }
#endif
        get_vision_thread().release_targets();
    }
}

#ifdef VISION_ALT_HEURISTIC

target& vision_targets::bottom() {
    return bottom_t;
}

target& vision_targets::top() {
    return top_t;
}

target& vision_targets::left() {
    return left_t;
}

target& vision_targets::right() {
    return right_t;
}

#else

std::vector<target> vision_targets::targets() {
    return targets_vec;
}

#endif

vision_thread& get_vision_thread() {
    static vision_thread t(camera(), update_targets);
    return t;
}

vision_targets& get_targets() {
    static vision_targets t;
    return t;
}

//FORCE INSTANTIATION
vision_thread& VISION_THREAD_INSTANCE = get_vision_thread();
vision_targets& VISION_TARGETS_INSTANCE = get_targets();

//MUST DELETE RETURN VALUE IN CALLER
std::pair<report_vector*&, BinaryImage*&> do_threshold(ColorImage& image) {
    //Threshold objects
    static Threshold HSL_THOLD(HSL_HMIN, HSL_HMAX, HSL_SMIN, HSL_SMAX, HSL_LMIN, HSL_LMAX);
    static Threshold HSI_THOLD(HSI_HMIN, HSI_HMAX, HSI_SMIN, HSI_SMAX, HSI_IMIN, HSI_IMAX);
    static Threshold HSV_THOLD(HSV_HMIN, HSV_HMAX, HSV_SMIN, HSV_SMAX, HSV_VMIN, HSV_VMAX);
    BinaryImage * result = NULL;
    if (COLOR_MODE == HSL) {
        result = image.ThresholdHSL(HSL_THOLD);
    }
    else if (COLOR_MODE == HSI) {
        result = image.ThresholdHSI(HSI_THOLD);
    }
    else if (COLOR_MODE == HSV) {
        result = image.ThresholdHSV(HSV_THOLD);
    }
    else {
        //color mode undefined.  Fall back to HSL
        result = image.ThresholdHSL(HSL_THOLD);
        perror_612("Invalid Color Mode - Falling Back to HSL");
    }
    if (!result) {
        //we have issues
        perror_612("Threshold Unsuccessful");
        return std::make_pair<report_vector*, BinaryImage*>(NULL, NULL);
    }
    report_vector * ret = result->GetOrderedParticleAnalysisReports();
    //delete result;//TODO: may be more efficient if we can allocate one binary
                    //image and call imaqColorThreshold.  leaving as is now
                    //cause it's prettier this way and POITROAE.
    return std::make_pair<report_vector*&, BinaryImage*&>(ret, result);
}

void do_particle_filter(report_vector * v, Image * img) {
    //filter particles
    particle_filter filt(img);
    v->erase(std::remove_if(v->begin(), v->end(), filt), v->end());
    if (v->size() > 4) { //more than four elements
        v->resize(4); //drop extra elements - get four biggest
    }
}

void write_particles(const char * fname, const report_vector * v) {
    //write particle analyses
    std::fstream o(fname, std::fstream::out | std::fstream::trunc);
    o << "#ifndef REPORT_H_INC\n"
         "#define REPORT_H_INC\n\n"
         "struct Rect {\n"
         "\tint top;\n"
         "\tint left;\n"
         "\tint height;\n"
         "\tint width;\n"
         "};\n\n"
         "struct ParticleAnalysisReport {\n"
         "\tint imageHeight;\n"
         "\tint imageWidth;\n"
         "\tdouble imageTimestamp;\n"
         "\tint particleIndex;\n"
         "\tint center_mass_x;\n"
         "\tint center_mass_y;\n"
         "\tdouble center_mass_x_normalized;\n"
         "\tdouble cneter_mass_y_normalized;\n"
         "\tdouble particleArea;\n"
         "\tRect boundingRect;\n"
         "\tdouble particleToImagePercent;\n"
         "\tdouble particleQuality;\n"
         "};\n\n"
         "ParticleAnalysisReport reports[] = {\n";
    if (v->size()) {
        report_vector::const_iterator it;
        for (it = v->begin(); it < v->end(); it++) {
            o << "\t{\n"
                 "\t\t" << it->imageHeight << ",\n"
                 "\t\t" << it->imageWidth << ",\n"
                 "\t\t" << it->imageTimestamp << ",\n"
                 "\t\t" << it->particleIndex << ",\n"
                 "\t\t" << it->center_mass_x << ",\n"
                 "\t\t" << it->center_mass_y << ",\n"
                 "\t\t" << it->center_mass_x_normalized << ",\n"
                 "\t\t" << it->center_mass_y_normalized << ",\n"
                 "\t\t" << it->particleArea << ",\n"
                 "\t\t{\n"
                 "\t\t\t" << it->boundingRect.top << ",\n"
                 "\t\t\t" << it->boundingRect.left << ",\n"
                 "\t\t\t" << it->boundingRect.height << ",\n"
                 "\t\t\t" << it->boundingRect.width << ",\n"
                 "\t\t},\n"
                 "\t\t" << it->particleToImagePercent << ",\n"
                 "\t\t" << it->particleQuality << ",\n"
                 "\t}";
            if (it + 1 != v->end()) {
                o << ',';
            }
            o << std::endl;
        }
    }
    o << "};\n\n"
         "#endif" << std::endl;
    //PHEW.
    o.close();
}

void update_targets(vision_thread& thread, ColorImage& image) {
    std::pair<report_vector*&, BinaryImage*&> ptrs = do_threshold(image);
    report_vector * reports = ptrs.first;
    BinaryImage * img = ptrs.second;
#if DEBUG_612
    if (left_joystick.GetRawButton(WRITE_IMAGE)) {
        std::printf("Writing...\n");
        char buffer[64];
        std::sprintf(buffer, "%f_clr.bmp", Timer::GetFPGATimestamp());
        image.Write(buffer);
        int x = std::strlen(buffer);
        buffer[x-6] = 'b';
        buffer[x-5] = 'i';
        buffer[x-4] = 'n';
        img->Write(buffer);
        buffer[x-7] = '.';
        buffer[x-6] = 'h';
        buffer[x-5] = '\0';
        write_particles(buffer, reports);
    }
#endif
    if (!reports) {
        //particle analysis failed.
        if (img) {
            delete img;
        }
        return;
    }
    do_particle_filter(reports, img->GetImaqImage());
    thread.lock_targets();
    target::id_and_process(reports);
    thread.release_targets();
    delete reports; //free vector
    delete img; //free image
}
<|endoftext|>


<commit_before><commit_msg>make running time of brpc_h2_unsent_message_unittest shorter<commit_after><|endoftext|>


<commit_before>/**
 ** \file scheduler/scheduler.cc
 ** \brief Implementation of scheduler::Scheduler.
 */

//#define ENABLE_DEBUG_TRACES

#include <cassert>
#include <cstdlib>

#include <libport/compiler.hh>
#include <libport/containers.hh>
#include <libport/foreach.hh>

#include "kernel/userver.hh"

#include "object/urbi-exception.hh"

#include "scheduler/scheduler.hh"
#include "scheduler/job.hh"

namespace scheduler
{

  // This function is required to start a new job using the libcoroutine.
  // Its only purpose is to create the context and start the execution
  // of the new job.
  static void
  run_job (void* job)
  {
    static_cast<Job*>(job)->run();
  }

  void
  Scheduler::add_job (Job* job)
  {
    assert (job);
    assert (!libport::has (jobs_, job));
    jobs_.push_back (job);
    jobs_to_start_ = true;
  }

  libport::utime_t
  Scheduler::work ()
  {
    ++cycle_;
    ECHO ("======================================================== cycle "
	  << cycle_);

    libport::utime_t deadline = execute_round (false);

    // If some jobs need to be stopped, do it as soon as possible.
    deadline = std::min (deadline, check_for_stopped_tags (deadline));

#ifdef ENABLE_DEBUG_TRACES
    if (deadline)
      ECHO ("Scheduler asking to be woken up in "
	    << (deadline - ::urbiserver->getTime ()) / 1000000L << " seconds");
    else
      ECHO ("Scheduler asking to be woken up ASAP");
#endif

    return deadline;
  }

  libport::utime_t
  Scheduler::execute_round (bool blocked_only)
  {
    // Run all the jobs in the run queue once. If any job declares upon entry or
    // return that it is not side-effect free, we remember that for the next
    // cycle.
    pending_.clear ();
    std::swap (pending_, jobs_);

    // By default, wake us up after one hour and consider that we have no
    // new job to start. Also, run waiting jobs only if the previous round
    // may have add a side effect and reset this indication for the current
    // job.
    libport::utime_t deadline = ::urbiserver->getTime () +  3600000000LL;
    jobs_to_start_ = false;
    bool start_waiting = possible_side_effect_;
    possible_side_effect_ = false;

    ECHO (pending_.size() << " jobs in the queue for this round");
    foreach (Job* job, pending_)
    {
      // Kill a job if needed. See explanation in job.hh.
      to_kill_ = 0;

      assert (job);
      assert (!job->terminated ());

      // Should the job be started?
      bool start = false;

      ECHO ("Considering " << *job << " in state " << state_name (job->state_get ()));

      switch (job->state_get ())
      {
      case to_start:
	// New job. Start its coroutine but do not start the job as it would be queued
	// twice otherwise. It will start doing real work at the next cycle, so set
	// deadline to 0. Note that we use "continue" here to avoid having the job
	// requeued because it hasn't been started by setting "start".
	ECHO ("Starting job " << *job);
	current_job_ = job;
	Coro_startCoro_ (coro_, job->coro_get(), job, run_job);
	current_job_ = 0;
	ECHO ("Job " << *job << " has been started");
	assert (job->state_get () != to_start);
	deadline = 0;
	continue;
      case zombie:
	assert (false);
	break;
      case running:
	start = !blocked_only || job->blocked ();
	break;
      case sleeping:
	{
	  libport::utime_t job_deadline = job->deadline_get ();
	  if (job_deadline <= ::urbiserver->getTime ())
	    start = true;
	  else
	    deadline = std::min (deadline, job_deadline);
	}
	break;
      case waiting:
	// Since jobs keep their orders in the queue, start waiting jobs if
	// previous jobs in the run have had a possible side effect or if
	// the previous run may have had some. Without it, we may miss some
	// changes if the watching job is after the modifying job in the queue
	// and the watched condition gets true for only one cycle.
	start = start_waiting | possible_side_effect_;
	break;
      case joining:
	break;
      }

      if (start)
      {
	ECHO ("will resume job " << *job
	      << (job->side_effect_free_get() ? " (side-effect free)" : ""));
	possible_side_effect_ |= !job->side_effect_free_get ();
	assert (!current_job_);
	Coro_switchTo_ (coro_, job->coro_get ());
	assert (!current_job_);
	possible_side_effect_ |= !job->side_effect_free_get ();
	ECHO ("back from job " << *job
	      << (job->side_effect_free_get() ? " (side-effect free)" : ""));
	switch (job->state_get ())
	{
	case running:
	  deadline = 0;
	  break;
	case sleeping:
	  deadline = std::min (deadline, job->deadline_get ());
	  break;
	default:
	  break;
	}
      }
      else
	jobs_.push_back (job);   // Job not started, keep it in queue
    }

    // Kill a job if needed. See explanation in job.hh.
    to_kill_ = 0;

    /// If during this cycle a new job has been created by an existing job,
    /// start it.
    if (jobs_to_start_)
      deadline = 0;

    return deadline;
  }

  libport::utime_t
  Scheduler::check_for_stopped_tags (libport::utime_t old_deadline)
  {
    bool blocked_job = false;

    // If we have had no stopped tag, return immediately.
    if (stopped_tags_.empty ())
      return old_deadline;

    // If some jobs have been blocked, mark them as running so that they will
    // handle the condition when they are resumed.
    foreach (Job* job, jobs_)
      if (job->blocked ())
      {
	job->state_set (running);
	blocked_job = true;
      }

    // Wake up blocked jobs.
    libport::utime_t deadline = execute_round (true);

    // Reset tags to their real blocked value and reset the list.
    foreach (tag_state_type t, stopped_tags_)
      t.first->set_blocked (t.second);
    stopped_tags_.clear ();

    return deadline;
  }

  void
  Scheduler::resume_scheduler (Job* job)
  {
    // If the job has not terminated and is side-effect free, then we
    // assume it will not take a long time as we are probably evaluating
    // a condition. In order to reduce the number of cycles spent to evaluate
    // the condition, continue until it asks to be suspended in another
    // way or until it is no longer side-effect free.

    bool side_effect_free_save = job->side_effect_free_get ();

    if (job->state_get () == running && side_effect_free_save)
      return;

    // We may have to suspend the job several time in case it makes no sense
    // to start it back. Let's do it in a loop and we'll break when we want
    // to resume the job.

    for (;;)
    {
      // Add the job at the end of the scheduler queue unless the job has
      // already terminated.
      if (!job->terminated ())
	jobs_.push_back (job);

      // Switch back to the scheduler.
      assert (current_job_ == job);
      current_job_ = 0;
      ECHO (*job << " has " << (job->terminated () ? "" : "not ") << "terminated\n\t"
	    << "state: " << state_name (job->state_get ()));
      Coro_switchTo_ (job->coro_get (), coro_);

      // We regained control, we are again in the context of the job.
      assert (!current_job_);
      current_job_ = job;
      ECHO ("job " << *job << " resumed");

      // Execute a deferred exception if any; this may break out of this loop
      job->check_for_pending_exception ();

      // If we are not frozen, it is time to resume regular execution
      if (!job->frozen ())
	break;

      // Ok, we are frozen. Let's requeue ourselves after setting
      // the side_effect_free flag, and we will be in waiting mode.
      job->side_effect_free_set (true);
      job->state_set (waiting);
    }

    // Check that we are not near exhausting the stack space.
    job->check_stack_space ();

    // Restore the side_effect_free flag
    job->side_effect_free_set (side_effect_free_save);

    // Resume job execution
  }

  void
  Scheduler::killall_jobs ()
  {
    ECHO ("killing all jobs!");

    foreach (Job* job, jobs_)
      kill_job (job);

    foreach (Job* job, pending_)
      kill_job (job);
  }

  void
  Scheduler::unschedule_job (Job* job)
  {
    assert (job);
    assert (job != current_job_);

    ECHO ("unscheduling job " << *job);

    // Remove the job from the queue.
    jobs_.remove (job);

    // Remove it from live queues as well if the job is destroyed.
    pending_.remove (job);
  }

  void
  Scheduler::kill_job (Job* job)
  {
    KillException ke;
    job->async_throw (ke);
  }

  void Scheduler::signal_stop (rTag t)
  {
    bool previous_state = t->own_blocked ();
    t->set_blocked (true);
    stopped_tags_.push_back (std::make_pair(t, previous_state));
  }

} // namespace scheduler
<commit_msg>Do not wait if there is a possible side effect<commit_after>/**
 ** \file scheduler/scheduler.cc
 ** \brief Implementation of scheduler::Scheduler.
 */

//#define ENABLE_DEBUG_TRACES

#include <cassert>
#include <cstdlib>

#include <libport/compiler.hh>
#include <libport/containers.hh>
#include <libport/foreach.hh>

#include "kernel/userver.hh"

#include "object/urbi-exception.hh"

#include "scheduler/scheduler.hh"
#include "scheduler/job.hh"

namespace scheduler
{

  // This function is required to start a new job using the libcoroutine.
  // Its only purpose is to create the context and start the execution
  // of the new job.
  static void
  run_job (void* job)
  {
    static_cast<Job*>(job)->run();
  }

  void
  Scheduler::add_job (Job* job)
  {
    assert (job);
    assert (!libport::has (jobs_, job));
    jobs_.push_back (job);
    jobs_to_start_ = true;
  }

  libport::utime_t
  Scheduler::work ()
  {
    ++cycle_;
    ECHO ("======================================================== cycle "
	  << cycle_);

    libport::utime_t deadline = execute_round (false);

    // If some jobs need to be stopped, do it as soon as possible.
    deadline = std::min (deadline, check_for_stopped_tags (deadline));

#ifdef ENABLE_DEBUG_TRACES
    if (deadline)
      ECHO ("Scheduler asking to be woken up in "
	    << (deadline - ::urbiserver->getTime ()) / 1000000L << " seconds");
    else
      ECHO ("Scheduler asking to be woken up ASAP");
#endif

    return deadline;
  }

  libport::utime_t
  Scheduler::execute_round (bool blocked_only)
  {
    // Run all the jobs in the run queue once. If any job declares upon entry or
    // return that it is not side-effect free, we remember that for the next
    // cycle.
    pending_.clear ();
    std::swap (pending_, jobs_);

    // By default, wake us up after one hour and consider that we have no
    // new job to start. Also, run waiting jobs only if the previous round
    // may have add a side effect and reset this indication for the current
    // job.
    libport::utime_t deadline = ::urbiserver->getTime () +  3600000000LL;
    jobs_to_start_ = false;
    bool start_waiting = possible_side_effect_;
    possible_side_effect_ = false;

    ECHO (pending_.size() << " jobs in the queue for this round");
    foreach (Job* job, pending_)
    {
      // Kill a job if needed. See explanation in job.hh.
      to_kill_ = 0;

      assert (job);
      assert (!job->terminated ());

      // Should the job be started?
      bool start = false;

      ECHO ("Considering " << *job << " in state " << state_name (job->state_get ()));

      switch (job->state_get ())
      {
      case to_start:
	// New job. Start its coroutine but do not start the job as it would be queued
	// twice otherwise. It will start doing real work at the next cycle, so set
	// deadline to 0. Note that we use "continue" here to avoid having the job
	// requeued because it hasn't been started by setting "start".
	ECHO ("Starting job " << *job);
	current_job_ = job;
	Coro_startCoro_ (coro_, job->coro_get(), job, run_job);
	current_job_ = 0;
	ECHO ("Job " << *job << " has been started");
	assert (job->state_get () != to_start);
	deadline = 0;
	continue;
      case zombie:
	assert (false);
	break;
      case running:
	start = !blocked_only || job->blocked ();
	break;
      case sleeping:
	{
	  libport::utime_t job_deadline = job->deadline_get ();
	  if (job_deadline <= ::urbiserver->getTime ())
	    start = true;
	  else
	    deadline = std::min (deadline, job_deadline);
	}
	break;
      case waiting:
	// Since jobs keep their orders in the queue, start waiting jobs if
	// previous jobs in the run have had a possible side effect or if
	// the previous run may have had some. Without it, we may miss some
	// changes if the watching job is after the modifying job in the queue
	// and the watched condition gets true for only one cycle.
	start = start_waiting | possible_side_effect_;
	break;
      case joining:
	break;
      }

      if (start)
      {
	ECHO ("will resume job " << *job
	      << (job->side_effect_free_get() ? " (side-effect free)" : ""));
	possible_side_effect_ |= !job->side_effect_free_get ();
	assert (!current_job_);
	Coro_switchTo_ (coro_, job->coro_get ());
	assert (!current_job_);
	possible_side_effect_ |= !job->side_effect_free_get ();
	ECHO ("back from job " << *job
	      << (job->side_effect_free_get() ? " (side-effect free)" : ""));
	switch (job->state_get ())
	{
	case running:
	  deadline = 0;
	  break;
	case sleeping:
	  deadline = std::min (deadline, job->deadline_get ());
	  break;
	default:
	  break;
	}
      }
      else
	jobs_.push_back (job);   // Job not started, keep it in queue
    }

    // Kill a job if needed. See explanation in job.hh.
    to_kill_ = 0;

    /// If during this cycle a new job has been created by an existing job,
    /// start it. Also start if a possible side effect happened, it may have
    /// occurred later then the waiting jobs in the cycle.
    if (jobs_to_start_ || possible_side_effect_)
      deadline = 0;

    return deadline;
  }

  libport::utime_t
  Scheduler::check_for_stopped_tags (libport::utime_t old_deadline)
  {
    bool blocked_job = false;

    // If we have had no stopped tag, return immediately.
    if (stopped_tags_.empty ())
      return old_deadline;

    // If some jobs have been blocked, mark them as running so that they will
    // handle the condition when they are resumed.
    foreach (Job* job, jobs_)
      if (job->blocked ())
      {
	job->state_set (running);
	blocked_job = true;
      }

    // Wake up blocked jobs.
    libport::utime_t deadline = execute_round (true);

    // Reset tags to their real blocked value and reset the list.
    foreach (tag_state_type t, stopped_tags_)
      t.first->set_blocked (t.second);
    stopped_tags_.clear ();

    return deadline;
  }

  void
  Scheduler::resume_scheduler (Job* job)
  {
    // If the job has not terminated and is side-effect free, then we
    // assume it will not take a long time as we are probably evaluating
    // a condition. In order to reduce the number of cycles spent to evaluate
    // the condition, continue until it asks to be suspended in another
    // way or until it is no longer side-effect free.

    bool side_effect_free_save = job->side_effect_free_get ();

    if (job->state_get () == running && side_effect_free_save)
      return;

    // We may have to suspend the job several time in case it makes no sense
    // to start it back. Let's do it in a loop and we'll break when we want
    // to resume the job.

    for (;;)
    {
      // Add the job at the end of the scheduler queue unless the job has
      // already terminated.
      if (!job->terminated ())
	jobs_.push_back (job);

      // Switch back to the scheduler.
      assert (current_job_ == job);
      current_job_ = 0;
      ECHO (*job << " has " << (job->terminated () ? "" : "not ") << "terminated\n\t"
	    << "state: " << state_name (job->state_get ()));
      Coro_switchTo_ (job->coro_get (), coro_);

      // We regained control, we are again in the context of the job.
      assert (!current_job_);
      current_job_ = job;
      ECHO ("job " << *job << " resumed");

      // Execute a deferred exception if any; this may break out of this loop
      job->check_for_pending_exception ();

      // If we are not frozen, it is time to resume regular execution
      if (!job->frozen ())
	break;

      // Ok, we are frozen. Let's requeue ourselves after setting
      // the side_effect_free flag, and we will be in waiting mode.
      job->side_effect_free_set (true);
      job->state_set (waiting);
    }

    // Check that we are not near exhausting the stack space.
    job->check_stack_space ();

    // Restore the side_effect_free flag
    job->side_effect_free_set (side_effect_free_save);

    // Resume job execution
  }

  void
  Scheduler::killall_jobs ()
  {
    ECHO ("killing all jobs!");

    foreach (Job* job, jobs_)
      kill_job (job);

    foreach (Job* job, pending_)
      kill_job (job);
  }

  void
  Scheduler::unschedule_job (Job* job)
  {
    assert (job);
    assert (job != current_job_);

    ECHO ("unscheduling job " << *job);

    // Remove the job from the queue.
    jobs_.remove (job);

    // Remove it from live queues as well if the job is destroyed.
    pending_.remove (job);
  }

  void
  Scheduler::kill_job (Job* job)
  {
    KillException ke;
    job->async_throw (ke);
  }

  void Scheduler::signal_stop (rTag t)
  {
    bool previous_state = t->own_blocked ();
    t->set_blocked (true);
    stopped_tags_.push_back (std::make_pair(t, previous_state));
  }

} // namespace scheduler
<|endoftext|>