<commit_before>#include"TextInputWidget.hpp"
#include<iostream>

gsf::TextInputWidget::TextInputWidget(float width, float height, sf::Font &font)
: Widget{ width, height }
, m_isFocused{ false }
, m_cursorPos{ 0 }
{
    m_text.setFont(font);
    m_text.setCharacterSize(12);
    m_text.setFillColor(sf::Color::Black);
}

void gsf::TextInputWidget::setText(const std::string &text)
{
   m_text.setString(text);
}

std::string gsf::TextInputWidget::getText() const
{
   return m_text.getString().toAnsiString();
}

void gsf::TextInputWidget::setCharacterSize(const unsigned int size)
{
   m_text.setCharacterSize(size);
}

unsigned int gsf::TextInputWidget::getCharacterSize() const
{
   return m_text.getCharacterSize();
}

void gsf::TextInputWidget::setTextColor(const sf::Color color)
{
   m_text.setFillColor(color);
}

sf::Color gsf::TextInputWidget::getTextColor() const
{
   return m_text.getFillColor();
}

bool gsf::TextInputWidget::isFocused() const
{
    return m_isFocused;
}

void gsf::TextInputWidget::drawWidget(sf::RenderTarget &target,
        sf::RenderStates states) const
{
    target.draw(m_text, states);
}

void gsf::TextInputWidget::update(float dt)
{
    // Add cursor
    std::wstring text{ m_actualText };
    text.insert(m_cursorPos, L"|");
    // Draw text
    m_text.setString(text);
}

bool gsf::TextInputWidget::handleEvent(sf::Event &event)
{
    bool handled{ Widget::handleEvent(event) };
    // Check if actual Widget is focused
    if (event.type == sf::Event::MouseButtonPressed)
    {
        sf::Vector2f mousePos{ (float) event.mouseButton.x,
        (float) event.mouseButton.y };
        bool isMouseInShownArea{ getShownArea().contains(mousePos) };
        bool intersecting{ isIntersecting(mousePos) };
        if (isMouseInShownArea && intersecting)
        {
            m_isFocused = true;
        }
        else
        {
            m_isFocused = false;
        }
    }
    // If Widget is focused and Text entered, handle entered text
    if (m_isFocused && event.type == sf::Event::TextEntered)
    {
        // To handle umlauts and other 'exotic' chars we use widestring
        // and wide char
        //std::wstring actualTxt{ m_text.getString().toWideString() };
        wchar_t c{ static_cast<wchar_t>(event.text.unicode) };
        switch (c)
        {
            // Backspace
            case 8:
                if (m_actualText.length() > 0)
                {
                    // When cursos is at the end of the text, p
                    // place cursor behind char which we want to delete,
                    if (m_cursorPos == m_actualText.length())
                    {
                        m_cursorPos--;
                    }
                    // Delete last char
                    m_actualText.pop_back();
                }
                break;
            // Enter key
            case 13: m_actualText += '\n'; m_cursorPos++; break;
            // Add char to text
            default: m_actualText += c; m_cursorPos++;
        }

        // sf::String can handle widechars so we usw it
        //sf::String txtNew(actualTxt);
        //m_text.setString(txtNew);

        return true;
    }
    return handled;
}
<commit_msg>cursor is now moveable<commit_after>#include"TextInputWidget.hpp"
#include<iostream>

gsf::TextInputWidget::TextInputWidget(float width, float height, sf::Font &font)
: Widget{ width, height }
, m_isFocused{ false }
, m_cursorPos{ 0 }
{
    m_text.setFont(font);
    m_text.setCharacterSize(12);
    m_text.setFillColor(sf::Color::Black);
}

void gsf::TextInputWidget::setText(const std::string &text)
{
   m_text.setString(text);
}

std::string gsf::TextInputWidget::getText() const
{
   return m_text.getString().toAnsiString();
}

void gsf::TextInputWidget::setCharacterSize(const unsigned int size)
{
   m_text.setCharacterSize(size);
}

unsigned int gsf::TextInputWidget::getCharacterSize() const
{
   return m_text.getCharacterSize();
}

void gsf::TextInputWidget::setTextColor(const sf::Color color)
{
   m_text.setFillColor(color);
}

sf::Color gsf::TextInputWidget::getTextColor() const
{
   return m_text.getFillColor();
}

bool gsf::TextInputWidget::isFocused() const
{
    return m_isFocused;
}

void gsf::TextInputWidget::drawWidget(sf::RenderTarget &target,
        sf::RenderStates states) const
{
    target.draw(m_text, states);
}

void gsf::TextInputWidget::update(float dt)
{
    // Add cursor
    std::wstring text{ m_actualText };
    text.insert(m_cursorPos, L"|");
    // Draw text
    m_text.setString(text);
}

bool gsf::TextInputWidget::handleEvent(sf::Event &event)
{
    bool handled{ Widget::handleEvent(event) };
    // Check if actual Widget is focused
    if (event.type == sf::Event::MouseButtonPressed)
    {
        sf::Vector2f mousePos{ (float) event.mouseButton.x,
        (float) event.mouseButton.y };
        bool isMouseInShownArea{ getShownArea().contains(mousePos) };
        bool intersecting{ isIntersecting(mousePos) };
        if (isMouseInShownArea && intersecting)
        {
            m_isFocused = true;
        }
        else
        {
            m_isFocused = false;
        }
    }
    if (event.type == sf::Event::KeyPressed && m_isFocused)
    {
        switch (event.key.code)
        {
            case sf::Keyboard::Left:
                if (m_cursorPos > 0)
                {
                    m_cursorPos--;
                }
                return true;
            case sf::Keyboard::Right:
                if (m_cursorPos < m_actualText.length())
                {
                    m_cursorPos++;
                }
                return true;
            default: break;
        }
    }
    // If Widget is focused and Text entered, handle entered text
    if (m_isFocused && event.type == sf::Event::TextEntered)
    {
        // To handle umlauts and other 'exotic' chars we use widestring
        // and wide char
        //std::wstring actualTxt{ m_text.getString().toWideString() };
        wchar_t c{ static_cast<wchar_t>(event.text.unicode) };
        std::cout << "Entered: " << c << std::endl;
        switch (c)
        {
        // Backspace
        case 8:
            if (m_actualText.length() > 0)
            {
                // When cursos is at the end of the text, p
                // place cursor behind char which we want to delete,
                if (m_cursorPos == m_actualText.length())
                {
                    m_cursorPos--;
                }
                // Delete last char
                m_actualText.pop_back();
            }
            break;
        // Enter key
        case 13: m_actualText += '\n'; m_cursorPos++; break;
        // Add char to text
        default: m_actualText += c; m_cursorPos++;
        }

        return true;
    }
    return handled;
}
<|endoftext|>


<commit_before>//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Roman Zulak
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "cling/Utils/Output.h"
#include "cling/Utils/UTF8.h"

#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Format.h"

#ifdef LLVM_ON_WIN32
#include <Shlwapi.h>
#define strcasestr StrStrIA
#pragma comment(lib, "Shlwapi.lib")
#endif

namespace cling {
namespace utils {
namespace utf8 {

// Adapted from utf8++

enum {
  LEAD_SURROGATE_MIN  = 0xd800u,
  TRAIL_SURROGATE_MIN = 0xdc00u,
  TRAIL_SURROGATE_MAX = 0xdfffu,
  LEAD_OFFSET         = LEAD_SURROGATE_MIN - (0x10000 >> 10),
  CODE_POINT_MAX      = 0x0010ffffu
};

static uint8_t mask8(char Octet) {
  return static_cast<uint8_t>(Octet); //  & 0xff
}

bool Validate(const char* Str, size_t N, const std::locale& LC, bool& isPrint) {
  for (size_t i = 0, N1 = (N-1); i < N; ++i) {
    uint8_t n;
    uint8_t C = mask8(Str[i]);
    isPrint = isPrint ? std::isprint(Str[i], LC) : false;

    if (C <= 0x7f)
      n = 0; // 0bbbbbbb
    else if ((C & 0xe0) == 0xc0)
      n = 1; // 110bbbbb
    else if ( C==0xed && i < N1 && (mask8(Str[i+1]) & 0xa0) == 0xa0)
      return false; //U+d800 to U+dfff
    else if ((C & 0xf0) == 0xe0)
      n = 2; // 1110bbbb
    else if ((C & 0xf8) == 0xf0)
      n = 3; // 11110bbb
#if 0 // unnecessary in 4 byte UTF-8
    else if ((C & 0xfc) == 0xf8)
      n = 4; // 111110bb //byte 5
    else if ((C & 0xfe) == 0xfc) n = 5;
      // 1111110b //byte 6
#endif
    else
      return false;

    // n bytes matching 10bbbbbb follow ?
    for (uint8_t j = 0; j < n && i < N; ++j) {
      if (++i == N)
        return false;
      C = mask8(Str[i]);
      if ((C & 0xc0) != 0x80)
        return false;
    }
  }
  return true;
}

static uint8_t sequenceLength(const char* Ptr) {
  uint8_t lead = mask8(*Ptr);
  if (lead < 0x80)
    return 1;
  else if ((lead >> 5) == 0x6)
    return 2;
  else if ((lead >> 4) == 0xe)
    return 3;
  else if ((lead >> 3) == 0x1e)
    return 4;
  return 0;
}

static char32_t next(const char*& Ptr) {
  char32_t CP = mask8(*Ptr);
  switch (sequenceLength(Ptr)) {
    case 1: break;
    case 2:
      ++Ptr;
      CP = ((CP << 6) & 0x7ff) + ((*Ptr) & 0x3f);
      break;
    case 3:
      ++Ptr;
      CP = ((CP << 12) & 0xffff) + ((mask8(*Ptr) << 6) & 0xfff);
      ++Ptr;
      CP += (*Ptr) & 0x3f;
      break;
    case 4:
      ++Ptr;
      CP = ((CP << 18) & 0x1fffff) + ((mask8(*Ptr) << 12) & 0x3ffff);
      ++Ptr;
      CP += (mask8(*Ptr) << 6) & 0xfff;
      ++Ptr;
      CP += (*Ptr) & 0x3f;
      break;
  }
  ++Ptr;
  return CP;
}

// mimic isprint() for Unicode codepoints
static bool isPrint(char32_t CP, const std::locale&) {
  // C0
  if (CP <= 0x1F || CP == 0x7F)
    return false;

  // C1
  if (CP >= 0x80 && CP <= 0x9F)
    return false;

  // line/paragraph separators
  if (CP == 0x2028 || CP == 0x2029)
    return false;

  // bidirectional text control
  if (CP == 0x200E || CP == 0x200F || (CP >= 0x202A && CP <= 0x202E))
    return false;

  // interlinears and generally specials
  if (CP >= 0xFFF9 && CP <= 0xFFFF)
    return false;

  return true;
}

namespace {
  enum HexState {
    kText,
    kEsc,
    kHex,
    kEnd
  };
}

class EscapeSequence::ByteDumper {
  enum { kBufSize = 1024 };
  llvm::SmallString<kBufSize> m_Buf;

  const std::locale& m_Loc;
  const char* const m_End;
  const bool m_Utf8;
  bool m_HexRun;
  bool (* const isPrintable)(char32_t, const std::locale&);

  static bool stdIsPrintU(char32_t C, const std::locale& L) {
#if !defined(LLVM_ON_WIN32)
    static_assert(sizeof(wchar_t) == sizeof(char32_t), "Sizes don't match");
    return std::isprint(wchar_t(C), L);
#else
    // Each on their own report a lot of characters printable.
    return iswprint(C) && std::isprint(C, L);
#endif
  }

  static bool stdIsPrintA(char32_t C, const std::locale& L) {
#if defined(LLVM_ON_WIN32)
    // Windows Debug does not like being sent values > 255!
    if (C > 0xff)
      return false;
#endif
    return std::isprint(char(C), L);
  }

public:

  ByteDumper(EscapeSequence& Enc, const char* E, bool Utf8) :
    m_Loc(Enc.m_Loc), m_End(E), m_Utf8(Utf8),
    isPrintable(Enc.m_Utf8Out && m_Utf8 ? &utf8::isPrint :
                                         (Utf8 ? &stdIsPrintU : &stdIsPrintA)) {
    // Cached the correct isprint variant rather than checking in a loop.
    //
    // If output handles UTF-8 and string is UTF-8, then validate against UTF-8.
    // If string is UTF-8 validate printable against std::isprint<char32_t>.
    // If nothing is UTF-8 validate against std::isprint<char> .
  }

  HexState operator() (const char*& Ptr, llvm::raw_ostream& Stream,
                       bool ForceHex) {
    // Block allocate the next chunk
    if (!(m_Buf.size() % kBufSize))
      m_Buf.reserve(m_Buf.size() + kBufSize);

    HexState State = kText;
    const char* const Start = Ptr;
    char32_t Char;
    if (m_Utf8) {
      Char = utf8::next(Ptr);
      if (Ptr > m_End) {
        // Invalid/bad encoding: dump the remaining as hex
        Ptr = Start;
        while (Ptr < m_End)
          Stream << "\\x" << llvm::format_hex_no_prefix(uint8_t(*Ptr++), 2);
        m_HexRun = true;
        return kHex;
      }
    } else
      Char = (*Ptr++ & 0xff);

    // Assume more often than not -regular- strings are printed
    if (LLVM_UNLIKELY(!isPrintable(Char, m_Loc))) {
      m_HexRun = false;
      if (LLVM_UNLIKELY(ForceHex || !std::isspace(wchar_t(Char), m_Loc))) {
        if (Char > 0xffff)
          Stream << "\\U" << llvm::format_hex_no_prefix(uint32_t(Char), 8);
        else if (Char > 0xff)
          Stream << "\\u" << llvm::format_hex_no_prefix(uint16_t(Char), 4);
        else if (Char) {
          Stream << "\\x" << llvm::format_hex_no_prefix(uint8_t(Char), 2);
          m_HexRun = true;
          return kHex;
        } else
          Stream << "\\0";
        return kText;
      }

      switch (Char) {
        case '\b': Stream << "\\b"; return kEsc;
        // \r isn't so great on Unix, what about Windows?
        case '\r': Stream << "\\r"; return kEsc;
        default: break;
      }
      State = kEsc;
    }

    if (m_HexRun) {
      // If the last print was a hex code, and this is now a char that could
      // be interpreted as a continuation of that hex-sequence, close out
      // the string and use concatenation. {'\xea', 'B'} -> "\xea" "B"
      m_HexRun = false;
      if (std::isxdigit(wchar_t(Char), m_Loc))
        Stream << "\" \"";
    }
    if (m_Utf8)
      Stream << llvm::StringRef(Start, Ptr-Start);
    else
      Stream << char(Char);
    return State;
  }
  llvm::SmallString<kBufSize>& buf() { return m_Buf; }
};

EscapeSequence::EscapeSequence() : m_Utf8Out(false) {
#if !defined(LLVM_ON_WIN32)
  if (!::strcasestr(m_Loc.name().c_str(), "utf-8")) {
    if (const char* LANG = ::getenv("LANG")) {
      if (::strcasestr(LANG, "utf-8")) {
 #if !defined(__APPLE__) || !defined(__GLIBCXX__)
        m_Loc = std::locale(LANG);
 #endif
        m_Utf8Out = true;
      }
    }
  } else
    m_Utf8Out = true;
#else
  // Can other other codepages support UTF-8?
  m_Utf8Out = ::GetConsoleOutputCP() == 65001;
#endif
}

llvm::raw_ostream& EscapeSequence::encode(const char* const Start, size_t N,
                                          llvm::raw_ostream& Output) {
  const char* Ptr = Start;
  const char* const End = Start + N;

  bool isUtf8 = Start[0] != '\"';
  if (!isUtf8) {
    bool isPrint = true;
    // A const char* string may not neccessarily be utf8.
    // When the locale can output utf8 strings, validate it as utf8 first.
    if (!m_Utf8Out) {
      while (isPrint && Ptr < End)
        isPrint = std::isprint(*Ptr++, m_Loc);
    } else
      isUtf8 = Validate(Ptr, N, m_Loc, isPrint);

    // Simple printable string, just return it now.
    if (isPrint)
      return Output << llvm::StringRef(Start, N);

    Ptr = Start;
  } else {
    assert((Start[0] == 'u' || Start[0] == 'U' || Start[0] == 'L')
           && "Unkown string encoding");
    // Unicode string, assume valid
    isUtf8 = true;
  }

  ByteDumper Dump(*this, End, isUtf8);
  { // scope for llvm::raw_svector_ostream
    size_t LastGood = 0;
    HexState Hex = kText;
    llvm::raw_svector_ostream Strm(Dump.buf());
    while ((Hex < kEnd) && (Ptr < End)) {
      const size_t LastPos = Ptr - Start;
      switch (Dump(Ptr, Strm, Hex==kHex)) {
        case kHex:
          // Printed hex char
          // Keep doing it as long as no escaped char have been printed
          Hex = (Hex == kEsc) ? kEnd : kHex;
          break;
        case kEsc:
          assert(Hex <= kEsc && "Escape code after hex shouldn't occur");
          // Mark this as the last good character printed
          if (Hex == kText)
            LastGood = LastPos;
          Hex = kEsc;
        default:
          break;
      }
    }
    if (Hex != kEnd)
      return Output << Strm.str();

    Ptr = Start + LastGood;
    Dump.buf().resize(LastGood);
  }

  // Force hex output for the rest of the string
  llvm::raw_svector_ostream Strm(Dump.buf());
  while (Ptr < End)
    Dump(Ptr, Strm, true);

  return Output << Strm.str();
}

std::string EscapeSequence::encode(const char* const Start, size_t N) {
  stdstrstream Strm;
  encode(Start, N, Strm);
  return Strm.str();
}

} // namespace cling
} // namespace utils
} // namespace utf8
<commit_msg>Missing member init (thanks, Valgrind!).<commit_after>//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Roman Zulak
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "cling/Utils/Output.h"
#include "cling/Utils/UTF8.h"

#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Format.h"

#ifdef LLVM_ON_WIN32
#include <Shlwapi.h>
#define strcasestr StrStrIA
#pragma comment(lib, "Shlwapi.lib")
#endif

namespace cling {
namespace utils {
namespace utf8 {

// Adapted from utf8++

enum {
  LEAD_SURROGATE_MIN  = 0xd800u,
  TRAIL_SURROGATE_MIN = 0xdc00u,
  TRAIL_SURROGATE_MAX = 0xdfffu,
  LEAD_OFFSET         = LEAD_SURROGATE_MIN - (0x10000 >> 10),
  CODE_POINT_MAX      = 0x0010ffffu
};

static uint8_t mask8(char Octet) {
  return static_cast<uint8_t>(Octet); //  & 0xff
}

bool Validate(const char* Str, size_t N, const std::locale& LC, bool& isPrint) {
  for (size_t i = 0, N1 = (N-1); i < N; ++i) {
    uint8_t n;
    uint8_t C = mask8(Str[i]);
    isPrint = isPrint ? std::isprint(Str[i], LC) : false;

    if (C <= 0x7f)
      n = 0; // 0bbbbbbb
    else if ((C & 0xe0) == 0xc0)
      n = 1; // 110bbbbb
    else if ( C==0xed && i < N1 && (mask8(Str[i+1]) & 0xa0) == 0xa0)
      return false; //U+d800 to U+dfff
    else if ((C & 0xf0) == 0xe0)
      n = 2; // 1110bbbb
    else if ((C & 0xf8) == 0xf0)
      n = 3; // 11110bbb
#if 0 // unnecessary in 4 byte UTF-8
    else if ((C & 0xfc) == 0xf8)
      n = 4; // 111110bb //byte 5
    else if ((C & 0xfe) == 0xfc) n = 5;
      // 1111110b //byte 6
#endif
    else
      return false;

    // n bytes matching 10bbbbbb follow ?
    for (uint8_t j = 0; j < n && i < N; ++j) {
      if (++i == N)
        return false;
      C = mask8(Str[i]);
      if ((C & 0xc0) != 0x80)
        return false;
    }
  }
  return true;
}

static uint8_t sequenceLength(const char* Ptr) {
  uint8_t lead = mask8(*Ptr);
  if (lead < 0x80)
    return 1;
  else if ((lead >> 5) == 0x6)
    return 2;
  else if ((lead >> 4) == 0xe)
    return 3;
  else if ((lead >> 3) == 0x1e)
    return 4;
  return 0;
}

static char32_t next(const char*& Ptr) {
  char32_t CP = mask8(*Ptr);
  switch (sequenceLength(Ptr)) {
    case 1: break;
    case 2:
      ++Ptr;
      CP = ((CP << 6) & 0x7ff) + ((*Ptr) & 0x3f);
      break;
    case 3:
      ++Ptr;
      CP = ((CP << 12) & 0xffff) + ((mask8(*Ptr) << 6) & 0xfff);
      ++Ptr;
      CP += (*Ptr) & 0x3f;
      break;
    case 4:
      ++Ptr;
      CP = ((CP << 18) & 0x1fffff) + ((mask8(*Ptr) << 12) & 0x3ffff);
      ++Ptr;
      CP += (mask8(*Ptr) << 6) & 0xfff;
      ++Ptr;
      CP += (*Ptr) & 0x3f;
      break;
  }
  ++Ptr;
  return CP;
}

// mimic isprint() for Unicode codepoints
static bool isPrint(char32_t CP, const std::locale&) {
  // C0
  if (CP <= 0x1F || CP == 0x7F)
    return false;

  // C1
  if (CP >= 0x80 && CP <= 0x9F)
    return false;

  // line/paragraph separators
  if (CP == 0x2028 || CP == 0x2029)
    return false;

  // bidirectional text control
  if (CP == 0x200E || CP == 0x200F || (CP >= 0x202A && CP <= 0x202E))
    return false;

  // interlinears and generally specials
  if (CP >= 0xFFF9 && CP <= 0xFFFF)
    return false;

  return true;
}

namespace {
  enum HexState {
    kText,
    kEsc,
    kHex,
    kEnd
  };
}

class EscapeSequence::ByteDumper {
  enum { kBufSize = 1024 };
  llvm::SmallString<kBufSize> m_Buf;

  const std::locale& m_Loc;
  const char* const m_End;
  const bool m_Utf8;
  bool m_HexRun;
  bool (* const isPrintable)(char32_t, const std::locale&);

  static bool stdIsPrintU(char32_t C, const std::locale& L) {
#if !defined(LLVM_ON_WIN32)
    static_assert(sizeof(wchar_t) == sizeof(char32_t), "Sizes don't match");
    return std::isprint(wchar_t(C), L);
#else
    // Each on their own report a lot of characters printable.
    return iswprint(C) && std::isprint(C, L);
#endif
  }

  static bool stdIsPrintA(char32_t C, const std::locale& L) {
#if defined(LLVM_ON_WIN32)
    // Windows Debug does not like being sent values > 255!
    if (C > 0xff)
      return false;
#endif
    return std::isprint(char(C), L);
  }

public:

  ByteDumper(EscapeSequence& Enc, const char* E, bool Utf8) :
    m_Loc(Enc.m_Loc), m_End(E), m_Utf8(Utf8), m_HexRun(false),
    isPrintable(Enc.m_Utf8Out && m_Utf8 ? &utf8::isPrint :
                                         (Utf8 ? &stdIsPrintU : &stdIsPrintA)) {
    // Cached the correct isprint variant rather than checking in a loop.
    //
    // If output handles UTF-8 and string is UTF-8, then validate against UTF-8.
    // If string is UTF-8 validate printable against std::isprint<char32_t>.
    // If nothing is UTF-8 validate against std::isprint<char> .
  }

  HexState operator() (const char*& Ptr, llvm::raw_ostream& Stream,
                       bool ForceHex) {
    // Block allocate the next chunk
    if (!(m_Buf.size() % kBufSize))
      m_Buf.reserve(m_Buf.size() + kBufSize);

    HexState State = kText;
    const char* const Start = Ptr;
    char32_t Char;
    if (m_Utf8) {
      Char = utf8::next(Ptr);
      if (Ptr > m_End) {
        // Invalid/bad encoding: dump the remaining as hex
        Ptr = Start;
        while (Ptr < m_End)
          Stream << "\\x" << llvm::format_hex_no_prefix(uint8_t(*Ptr++), 2);
        m_HexRun = true;
        return kHex;
      }
    } else
      Char = (*Ptr++ & 0xff);

    // Assume more often than not -regular- strings are printed
    if (LLVM_UNLIKELY(!isPrintable(Char, m_Loc))) {
      m_HexRun = false;
      if (LLVM_UNLIKELY(ForceHex || !std::isspace(wchar_t(Char), m_Loc))) {
        if (Char > 0xffff)
          Stream << "\\U" << llvm::format_hex_no_prefix(uint32_t(Char), 8);
        else if (Char > 0xff)
          Stream << "\\u" << llvm::format_hex_no_prefix(uint16_t(Char), 4);
        else if (Char) {
          Stream << "\\x" << llvm::format_hex_no_prefix(uint8_t(Char), 2);
          m_HexRun = true;
          return kHex;
        } else
          Stream << "\\0";
        return kText;
      }

      switch (Char) {
        case '\b': Stream << "\\b"; return kEsc;
        // \r isn't so great on Unix, what about Windows?
        case '\r': Stream << "\\r"; return kEsc;
        default: break;
      }
      State = kEsc;
    }

    if (m_HexRun) {
      // If the last print was a hex code, and this is now a char that could
      // be interpreted as a continuation of that hex-sequence, close out
      // the string and use concatenation. {'\xea', 'B'} -> "\xea" "B"
      m_HexRun = false;
      if (std::isxdigit(wchar_t(Char), m_Loc))
        Stream << "\" \"";
    }
    if (m_Utf8)
      Stream << llvm::StringRef(Start, Ptr-Start);
    else
      Stream << char(Char);
    return State;
  }
  llvm::SmallString<kBufSize>& buf() { return m_Buf; }
};

EscapeSequence::EscapeSequence() : m_Utf8Out(false) {
#if !defined(LLVM_ON_WIN32)
  if (!::strcasestr(m_Loc.name().c_str(), "utf-8")) {
    if (const char* LANG = ::getenv("LANG")) {
      if (::strcasestr(LANG, "utf-8")) {
 #if !defined(__APPLE__) || !defined(__GLIBCXX__)
        m_Loc = std::locale(LANG);
 #endif
        m_Utf8Out = true;
      }
    }
  } else
    m_Utf8Out = true;
#else
  // Can other other codepages support UTF-8?
  m_Utf8Out = ::GetConsoleOutputCP() == 65001;
#endif
}

llvm::raw_ostream& EscapeSequence::encode(const char* const Start, size_t N,
                                          llvm::raw_ostream& Output) {
  const char* Ptr = Start;
  const char* const End = Start + N;

  bool isUtf8 = Start[0] != '\"';
  if (!isUtf8) {
    bool isPrint = true;
    // A const char* string may not neccessarily be utf8.
    // When the locale can output utf8 strings, validate it as utf8 first.
    if (!m_Utf8Out) {
      while (isPrint && Ptr < End)
        isPrint = std::isprint(*Ptr++, m_Loc);
    } else
      isUtf8 = Validate(Ptr, N, m_Loc, isPrint);

    // Simple printable string, just return it now.
    if (isPrint)
      return Output << llvm::StringRef(Start, N);

    Ptr = Start;
  } else {
    assert((Start[0] == 'u' || Start[0] == 'U' || Start[0] == 'L')
           && "Unkown string encoding");
    // Unicode string, assume valid
    isUtf8 = true;
  }

  ByteDumper Dump(*this, End, isUtf8);
  { // scope for llvm::raw_svector_ostream
    size_t LastGood = 0;
    HexState Hex = kText;
    llvm::raw_svector_ostream Strm(Dump.buf());
    while ((Hex < kEnd) && (Ptr < End)) {
      const size_t LastPos = Ptr - Start;
      switch (Dump(Ptr, Strm, Hex==kHex)) {
        case kHex:
          // Printed hex char
          // Keep doing it as long as no escaped char have been printed
          Hex = (Hex == kEsc) ? kEnd : kHex;
          break;
        case kEsc:
          assert(Hex <= kEsc && "Escape code after hex shouldn't occur");
          // Mark this as the last good character printed
          if (Hex == kText)
            LastGood = LastPos;
          Hex = kEsc;
        default:
          break;
      }
    }
    if (Hex != kEnd)
      return Output << Strm.str();

    Ptr = Start + LastGood;
    Dump.buf().resize(LastGood);
  }

  // Force hex output for the rest of the string
  llvm::raw_svector_ostream Strm(Dump.buf());
  while (Ptr < End)
    Dump(Ptr, Strm, true);

  return Output << Strm.str();
}

std::string EscapeSequence::encode(const char* const Start, size_t N) {
  stdstrstream Strm;
  encode(Start, N, Strm);
  return Strm.str();
}

} // namespace cling
} // namespace utils
} // namespace utf8
<|endoftext|>


<commit_before>//===------------------------- chrono.cpp ---------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "chrono"
#include "cerrno"        // errno
#include "system_error"  // __throw_system_error
#include <time.h>        // clock_gettime, CLOCK_MONOTONIC and CLOCK_REALTIME
#include "include/apple_availability.h"

#if !defined(__APPLE__)
#define _LIBCPP_USE_CLOCK_GETTIME
#endif // __APPLE__

#if defined(_LIBCPP_WIN32API)
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRA_LEAN
#include <windows.h>
#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
#include <winapifamily.h>
#endif
#else
#if !defined(CLOCK_REALTIME) || !defined(_LIBCPP_USE_CLOCK_GETTIME)
#include <sys/time.h>        // for gettimeofday and timeval
#endif // !defined(CLOCK_REALTIME)
#endif // defined(_LIBCPP_WIN32API)

#if !defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK)
#if __APPLE__
#include <mach/mach_time.h>  // mach_absolute_time, mach_timebase_info_data_t
#elif !defined(_LIBCPP_WIN32API) && !defined(CLOCK_MONOTONIC)
#error "Monotonic clock not implemented"
#endif
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

namespace chrono
{

// system_clock

const bool system_clock::is_steady;

system_clock::time_point
system_clock::now() _NOEXCEPT
{
#if defined(_LIBCPP_WIN32API)
  // FILETIME is in 100ns units
  using filetime_duration =
      _VSTD::chrono::duration<__int64,
                              _VSTD::ratio_multiply<_VSTD::ratio<100, 1>,
                                                    nanoseconds::period>>;

  // The Windows epoch is Jan 1 1601, the Unix epoch Jan 1 1970.
  static _LIBCPP_CONSTEXPR const seconds nt_to_unix_epoch{11644473600};

  FILETIME ft;
#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
  GetSystemTimePreciseAsFileTime(&ft);
#else
  GetSystemTimeAsFileTime(&ft);
#endif
#else
  GetSystemTimeAsFileTime(&ft);
#endif

  filetime_duration d{(static_cast<__int64>(ft.dwHighDateTime) << 32) |
                       static_cast<__int64>(ft.dwLowDateTime)};
  return time_point(duration_cast<duration>(d - nt_to_unix_epoch));
#else
#if defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_REALTIME)
  struct timespec tp;
  if (0 != clock_gettime(CLOCK_REALTIME, &tp))
    __throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed");
  return time_point(seconds(tp.tv_sec) + microseconds(tp.tv_nsec / 1000));
#else
    timeval tv;
    gettimeofday(&tv, 0);
    return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
#endif // _LIBCPP_USE_CLOCK_GETTIME && CLOCK_REALTIME
#endif
}

time_t
system_clock::to_time_t(const time_point& t) _NOEXCEPT
{
    return time_t(duration_cast<seconds>(t.time_since_epoch()).count());
}

system_clock::time_point
system_clock::from_time_t(time_t t) _NOEXCEPT
{
    return system_clock::time_point(seconds(t));
}

#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK
// steady_clock
//
// Warning:  If this is not truly steady, then it is non-conforming.  It is
//  better for it to not exist and have the rest of libc++ use system_clock
//  instead.

const bool steady_clock::is_steady;

#if defined(__APPLE__)

// Darwin libc versions >= 1133 provide ns precision via CLOCK_UPTIME_RAW
#if defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_UPTIME_RAW)
steady_clock::time_point
steady_clock::now() _NOEXCEPT
{
    struct timespec tp;
    if (0 != clock_gettime(CLOCK_UPTIME_RAW, &tp))
        __throw_system_error(errno, "clock_gettime(CLOCK_UPTIME_RAW) failed");
    return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
}

#else
//   mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of
//   nanoseconds since the computer booted up.  MachInfo.numer and MachInfo.denom
//   are run time constants supplied by the OS.  This clock has no relationship
//   to the Gregorian calendar.  It's main use is as a high resolution timer.

// MachInfo.numer / MachInfo.denom is often 1 on the latest equipment.  Specialize
//   for that case as an optimization.

static
steady_clock::rep
steady_simplified()
{
    return static_cast<steady_clock::rep>(mach_absolute_time());
}

static
double
compute_steady_factor()
{
    mach_timebase_info_data_t MachInfo;
    mach_timebase_info(&MachInfo);
    return static_cast<double>(MachInfo.numer) / MachInfo.denom;
}

static
steady_clock::rep
steady_full()
{
    static const double factor = compute_steady_factor();
    return static_cast<steady_clock::rep>(mach_absolute_time() * factor);
}

typedef steady_clock::rep (*FP)();

static
FP
init_steady_clock()
{
    mach_timebase_info_data_t MachInfo;
    mach_timebase_info(&MachInfo);
    if (MachInfo.numer == MachInfo.denom)
        return &steady_simplified;
    return &steady_full;
}

steady_clock::time_point
steady_clock::now() _NOEXCEPT
{
    static FP fp = init_steady_clock();
    return time_point(duration(fp()));
}
#endif // defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_UPTIME_RAW)

#elif defined(_LIBCPP_WIN32API)

// https://msdn.microsoft.com/en-us/library/windows/desktop/ms644905(v=vs.85).aspx says:
//    If the function fails, the return value is zero. <snip>
//    On systems that run Windows XP or later, the function will always succeed
//      and will thus never return zero.

static LARGE_INTEGER
__QueryPerformanceFrequency()
{
	LARGE_INTEGER val;
	(void) QueryPerformanceFrequency(&val);
	return val;
}

steady_clock::time_point
steady_clock::now() _NOEXCEPT
{
  static const LARGE_INTEGER freq = __QueryPerformanceFrequency();

  LARGE_INTEGER counter = __QueryPerformanceFrequency();
  return time_point(duration(counter.QuadPart * nano::den / freq.QuadPart));
}

#elif defined(CLOCK_MONOTONIC)

// On Apple platforms only CLOCK_UPTIME_RAW or mach_absolute_time are able to
// time functions in the nanosecond range. Thus, they are the only acceptable
// implementations of steady_clock.
#ifdef __APPLE__
#error "Never use CLOCK_MONOTONIC for steady_clock::now on Apple platforms"
#endif

steady_clock::time_point
steady_clock::now() _NOEXCEPT
{
    struct timespec tp;
    if (0 != clock_gettime(CLOCK_MONOTONIC, &tp))
        __throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC) failed");
    return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
}

#else
#error "Monotonic clock not implemented"
#endif

#endif // !_LIBCPP_HAS_NO_MONOTONIC_CLOCK

}

_LIBCPP_END_NAMESPACE_STD
<commit_msg>Fix typo that I introduced in r357413. Thanks to ensadc@mailnesia.com for the catch.<commit_after>//===------------------------- chrono.cpp ---------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "chrono"
#include "cerrno"        // errno
#include "system_error"  // __throw_system_error
#include <time.h>        // clock_gettime, CLOCK_MONOTONIC and CLOCK_REALTIME
#include "include/apple_availability.h"

#if !defined(__APPLE__)
#define _LIBCPP_USE_CLOCK_GETTIME
#endif // __APPLE__

#if defined(_LIBCPP_WIN32API)
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRA_LEAN
#include <windows.h>
#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
#include <winapifamily.h>
#endif
#else
#if !defined(CLOCK_REALTIME) || !defined(_LIBCPP_USE_CLOCK_GETTIME)
#include <sys/time.h>        // for gettimeofday and timeval
#endif // !defined(CLOCK_REALTIME)
#endif // defined(_LIBCPP_WIN32API)

#if !defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK)
#if __APPLE__
#include <mach/mach_time.h>  // mach_absolute_time, mach_timebase_info_data_t
#elif !defined(_LIBCPP_WIN32API) && !defined(CLOCK_MONOTONIC)
#error "Monotonic clock not implemented"
#endif
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

namespace chrono
{

// system_clock

const bool system_clock::is_steady;

system_clock::time_point
system_clock::now() _NOEXCEPT
{
#if defined(_LIBCPP_WIN32API)
  // FILETIME is in 100ns units
  using filetime_duration =
      _VSTD::chrono::duration<__int64,
                              _VSTD::ratio_multiply<_VSTD::ratio<100, 1>,
                                                    nanoseconds::period>>;

  // The Windows epoch is Jan 1 1601, the Unix epoch Jan 1 1970.
  static _LIBCPP_CONSTEXPR const seconds nt_to_unix_epoch{11644473600};

  FILETIME ft;
#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
  GetSystemTimePreciseAsFileTime(&ft);
#else
  GetSystemTimeAsFileTime(&ft);
#endif
#else
  GetSystemTimeAsFileTime(&ft);
#endif

  filetime_duration d{(static_cast<__int64>(ft.dwHighDateTime) << 32) |
                       static_cast<__int64>(ft.dwLowDateTime)};
  return time_point(duration_cast<duration>(d - nt_to_unix_epoch));
#else
#if defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_REALTIME)
  struct timespec tp;
  if (0 != clock_gettime(CLOCK_REALTIME, &tp))
    __throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed");
  return time_point(seconds(tp.tv_sec) + microseconds(tp.tv_nsec / 1000));
#else
    timeval tv;
    gettimeofday(&tv, 0);
    return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
#endif // _LIBCPP_USE_CLOCK_GETTIME && CLOCK_REALTIME
#endif
}

time_t
system_clock::to_time_t(const time_point& t) _NOEXCEPT
{
    return time_t(duration_cast<seconds>(t.time_since_epoch()).count());
}

system_clock::time_point
system_clock::from_time_t(time_t t) _NOEXCEPT
{
    return system_clock::time_point(seconds(t));
}

#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK
// steady_clock
//
// Warning:  If this is not truly steady, then it is non-conforming.  It is
//  better for it to not exist and have the rest of libc++ use system_clock
//  instead.

const bool steady_clock::is_steady;

#if defined(__APPLE__)

// Darwin libc versions >= 1133 provide ns precision via CLOCK_UPTIME_RAW
#if defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_UPTIME_RAW)
steady_clock::time_point
steady_clock::now() _NOEXCEPT
{
    struct timespec tp;
    if (0 != clock_gettime(CLOCK_UPTIME_RAW, &tp))
        __throw_system_error(errno, "clock_gettime(CLOCK_UPTIME_RAW) failed");
    return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
}

#else
//   mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of
//   nanoseconds since the computer booted up.  MachInfo.numer and MachInfo.denom
//   are run time constants supplied by the OS.  This clock has no relationship
//   to the Gregorian calendar.  It's main use is as a high resolution timer.

// MachInfo.numer / MachInfo.denom is often 1 on the latest equipment.  Specialize
//   for that case as an optimization.

static
steady_clock::rep
steady_simplified()
{
    return static_cast<steady_clock::rep>(mach_absolute_time());
}

static
double
compute_steady_factor()
{
    mach_timebase_info_data_t MachInfo;
    mach_timebase_info(&MachInfo);
    return static_cast<double>(MachInfo.numer) / MachInfo.denom;
}

static
steady_clock::rep
steady_full()
{
    static const double factor = compute_steady_factor();
    return static_cast<steady_clock::rep>(mach_absolute_time() * factor);
}

typedef steady_clock::rep (*FP)();

static
FP
init_steady_clock()
{
    mach_timebase_info_data_t MachInfo;
    mach_timebase_info(&MachInfo);
    if (MachInfo.numer == MachInfo.denom)
        return &steady_simplified;
    return &steady_full;
}

steady_clock::time_point
steady_clock::now() _NOEXCEPT
{
    static FP fp = init_steady_clock();
    return time_point(duration(fp()));
}
#endif // defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_UPTIME_RAW)

#elif defined(_LIBCPP_WIN32API)

// https://msdn.microsoft.com/en-us/library/windows/desktop/ms644905(v=vs.85).aspx says:
//    If the function fails, the return value is zero. <snip>
//    On systems that run Windows XP or later, the function will always succeed
//      and will thus never return zero.

static LARGE_INTEGER
__QueryPerformanceFrequency()
{
	LARGE_INTEGER val;
	(void) QueryPerformanceFrequency(&val);
	return val;
}

steady_clock::time_point
steady_clock::now() _NOEXCEPT
{
  static const LARGE_INTEGER freq = __QueryPerformanceFrequency();

  LARGE_INTEGER counter;
  (void) QueryPerformanceCounter(&counter);
  return time_point(duration(counter.QuadPart * nano::den / freq.QuadPart));
}

#elif defined(CLOCK_MONOTONIC)

// On Apple platforms only CLOCK_UPTIME_RAW or mach_absolute_time are able to
// time functions in the nanosecond range. Thus, they are the only acceptable
// implementations of steady_clock.
#ifdef __APPLE__
#error "Never use CLOCK_MONOTONIC for steady_clock::now on Apple platforms"
#endif

steady_clock::time_point
steady_clock::now() _NOEXCEPT
{
    struct timespec tp;
    if (0 != clock_gettime(CLOCK_MONOTONIC, &tp))
        __throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC) failed");
    return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
}

#else
#error "Monotonic clock not implemented"
#endif

#endif // !_LIBCPP_HAS_NO_MONOTONIC_CLOCK

}

_LIBCPP_END_NAMESPACE_STD
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: AutoBuffer.cxx,v $
 *
 *  $Revision: 1.1 $
 *
 *  last change: $Author: tra $ $Date: 2001-06-28 11:11:06 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

//------------------------------------------------------------------------
// includes
//------------------------------------------------------------------------

#ifndef _AUTO_BUFFER_HXX_
#include "AutoBuffer.hxx"
#endif

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

#include <windows.h>

//------------------------------------------------------------------------
// namespace directives
//------------------------------------------------------------------------

using rtl::OUString;

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

CAutoUnicodeBuffer::CAutoUnicodeBuffer( size_t size, sal_Bool bLazyCreation ) :
    m_buffSize( size ),
    m_pBuff( NULL )
{
    if ( !bLazyCreation )
        init( );
}

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

CAutoUnicodeBuffer::~CAutoUnicodeBuffer( )
{
    delete [] m_pBuff;
}

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

sal_Bool SAL_CALL CAutoUnicodeBuffer::resize( size_t new_size )
{
    OSL_ASSERT( new_size >= 0 );

    if ( new_size != m_buffSize )
    {
        if ( new_size > m_buffSize )
        {
            delete [] m_pBuff;
            m_pBuff = NULL;
        }

        m_buffSize = new_size;
    }

    return sal_True;
}

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

void SAL_CALL CAutoUnicodeBuffer::empty( )
{
    if ( m_pBuff )
        ZeroMemory( m_pBuff, m_buffSize * sizeof( sal_Unicode ) );
}

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

sal_Bool SAL_CALL CAutoUnicodeBuffer::fill( const sal_Unicode* pContent, size_t nLen )
{
    OSL_ASSERT( pContent && m_buffSize && (m_buffSize >= nLen) );

    init( );

    sal_Bool bRet = sal_False;

    if ( m_pBuff && pContent && nLen )
    {
        CopyMemory( m_pBuff, pContent, nLen * sizeof( sal_Unicode ) );
        bRet = sal_True;
    }

    return bRet;
}

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

size_t SAL_CALL CAutoUnicodeBuffer::size( ) const
{
    return m_buffSize;
}

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

CAutoUnicodeBuffer::operator sal_Unicode*( )
{
    return m_pBuff;
}

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

sal_Unicode* CAutoUnicodeBuffer::operator&( )
{
    return m_pBuff;
}

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

const sal_Unicode* CAutoUnicodeBuffer::operator&( ) const
{
    return m_pBuff;
}

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

void SAL_CALL CAutoUnicodeBuffer::init( )
{
    if ( !m_pBuff && (m_buffSize > 0) )
        m_pBuff = new sal_Unicode[ m_buffSize ];

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

//------------------------------------------------------------------------
// includes
//------------------------------------------------------------------------

#ifndef _AUTO_BUFFER_HXX_
#include "AutoBuffer.hxx"
#endif

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

#include <windows.h>

//------------------------------------------------------------------------
// namespace directives
//------------------------------------------------------------------------

using rtl::OUString;

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

CAutoUnicodeBuffer::CAutoUnicodeBuffer( size_t size, sal_Bool bLazyCreation ) :
    m_buffSize( size ),
    m_pBuff( NULL )
{
    if ( !bLazyCreation )
        init( );
}

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

CAutoUnicodeBuffer::~CAutoUnicodeBuffer( )
{
    delete [] m_pBuff;
}

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

sal_Bool SAL_CALL CAutoUnicodeBuffer::resize( size_t new_size )
{
    OSL_ASSERT( new_size >= 0 );

    if ( new_size != m_buffSize )
    {
        if ( new_size > m_buffSize )
        {
            delete [] m_pBuff;
            m_pBuff = NULL;
        }

        m_buffSize = new_size;
    }

    return sal_True;
}

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

void SAL_CALL CAutoUnicodeBuffer::empty( )
{
    if ( m_pBuff )
        ZeroMemory( m_pBuff, m_buffSize * sizeof( sal_Unicode ) );
}

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

sal_Bool SAL_CALL CAutoUnicodeBuffer::fill( const sal_Unicode* pContent, size_t nLen )
{
    OSL_ASSERT( pContent && m_buffSize && (m_buffSize >= nLen) );

    init( );

    sal_Bool bRet = sal_False;

    if ( m_pBuff && pContent && nLen )
    {
        CopyMemory( m_pBuff, pContent, nLen * sizeof( sal_Unicode ) );
        bRet = sal_True;
    }

    return bRet;
}

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

size_t SAL_CALL CAutoUnicodeBuffer::size( ) const
{
    return m_buffSize;
}

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

CAutoUnicodeBuffer::operator sal_Unicode*( )
{
    return m_pBuff;
}

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

sal_Unicode* CAutoUnicodeBuffer::operator&( )
{
    return m_pBuff;
}

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

const sal_Unicode* CAutoUnicodeBuffer::operator&( ) const
{
    return m_pBuff;
}

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

void SAL_CALL CAutoUnicodeBuffer::init( )
{
    if ( !m_pBuff && (m_buffSize > 0) )
        m_pBuff = new sal_Unicode[ m_buffSize ];

    empty( );
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#if !defined(XALAN_NODESORTER_HEADER_GUARD)
#define XALAN_NODESORTER_HEADER_GUARD

/**
 * @author Scott Boag (scott_boag@lotus.com)
 * @author David N. Bertoni (david_n_bertoni@lotus.com)
 */

// Base include file.  Must be first.
#include "XSLTDefinitions.hpp"

#include <functional>
#include <vector>

#include <XPath/XObject.hpp>

#include <XSLT/NodeSortKey.hpp>

class MutableNodeRefList;
class StylesheetExecutionContext;
class XalanNode;
class XPath;

/**
 * This class can sort vectors of nodes according to a select pattern.
 */
class NodeSorter
{
public:

	struct VectorEntry
	{
	public:

		VectorEntry(
			XalanNode*		theNode,
			unsigned int	thePosition) :
			m_node(theNode),
			m_position(thePosition)
		{
		}

		XalanNode*		m_node;
		unsigned int	m_position;
	};

#if defined(XALAN_NO_NAMESPACES)
	typedef vector<VectorEntry>			NodeVectorType;
	typedef vector<NodeSortKey>			NodeSortKeyVectorType;
#else
	typedef std::vector<VectorEntry>	NodeVectorType;
	typedef std::vector<NodeSortKey>	NodeSortKeyVectorType;
#endif

	explicit
	NodeSorter();

	~NodeSorter();

	NodeSortKeyVectorType&
	getSortKeys()
	{
		return m_keys;
	}

	/**
	 * Given a list of nodes, sort each node according to the criteria in the
	 * keys.  The list is assumed to be in document order.
	 *
	 * @param executionContext current execution context
	 * @param v    list of Nodes
	 */
	void
	sort(
			StylesheetExecutionContext&		executionContext,
			MutableNodeRefList&				theList);

	/**
	 * Return the results of a compare of two nodes.
	 */
#if defined(XALAN_NO_NAMESPACES)
	struct NodeSortKeyCompare : public binary_function<const NodeVectorType::value_type&, const NodeVectorType::value_type&, bool>
#else
	struct NodeSortKeyCompare : public std::binary_function<const NodeVectorType::value_type&, const NodeVectorType::value_type&, bool>
#endif
	{
	public:

	/**
	 * Construct a NodeSortKeyCompare object, to perform the sort
	 *
	 * @param executionContext current execution context
	 * @param theNodes        vector or nodes to be sorted
	 * @param theNodeSortKeys vector of keys upon which to sort
	 */
		NodeSortKeyCompare(
				StylesheetExecutionContext&		executionContext,
				NodeSorter&						theSorter,
				const NodeVectorType&			theNodes,
				const NodeSortKeyVectorType&	theNodeSortKeys) :
			m_executionContext(executionContext),
			m_sorter(theSorter),
			m_nodes(theNodes),
			m_nodeSortKeys(theNodeSortKeys)
		{
		}

		/**
		 * Compare two nodes, returning a value to indicate the
		 * result
		 *
		 * @param theLHS the first node to compare
		 * @param theRHS the second node to compare
		 * @param theKeyIndex the index of the key to use
		 * @result < 0 if theLHS is less than theRHS, 0 if they are equal, and > 0 if theLHS is greater than theRHS
		 */
		int
		compare(
				first_argument_type		theLHS,
				second_argument_type	theRHS,
				unsigned int			theKeyIndex = 0) const;

		/**
		 * Compare two nodes as a less predicate.
		 *
		 * @param theLHS the first node to compare
		 * @param theRHS the second node to compare
		 * @param theKeyIndex the index of the key to use
		 * @return true if theLHS is less than theRHS
		 */
		result_type
		operator()(
				first_argument_type		theLHS,
				second_argument_type	theRHS,
				unsigned int			theKeyIndex = 0) const
		{
			return compare(theLHS, theRHS, theKeyIndex) < 0 ? true : false;
		}

	protected:

		double
		getNumberResult(
				const NodeSortKey&		theKey,
				unsigned int			theKeyIndex,
				first_argument_type		theEntry) const;

		const XObjectPtr&
		getStringResult(
				const NodeSortKey&		theKey,
				unsigned int			theKeyIndex,
				first_argument_type		theEntry) const;

	private:

		StylesheetExecutionContext&		m_executionContext;
		NodeSorter&						m_sorter;
		const NodeVectorType&			m_nodes;
		const NodeSortKeyVectorType&	m_nodeSortKeys;
	};

	friend struct NodeSortKeyCompare;

#if defined(XALAN_NO_NAMESPACES)
	typedef	vector<double>		NumberResultsCacheVectorType;

	typedef	vector<XObjectPtr>	StringResultsCacheMapType;

	typedef vector<NumberResultsCacheVectorType>	NumberResultsCacheType;
	typedef vector<StringResultsCacheVectorType>	StringResultsCacheType;
#else
	typedef	std::vector<double>			NumberResultsCacheVectorType;
	typedef	std::vector<XObjectPtr>		StringResultsCacheVectorType;

	typedef std::vector<NumberResultsCacheVectorType>	NumberResultsCacheType;
	typedef std::vector<StringResultsCacheVectorType>	StringResultsCacheType;
#endif

private:

	/**
	 * Given a vector of nodes, sort each node according to the criteria in the
	 * keys.
	 *
	 * @param executionContext current execution context
	 */
	void
	sort(StylesheetExecutionContext&	executionContext);

	// Data members...
	NumberResultsCacheType	m_numberResultsCache;

	StringResultsCacheType	m_stringResultsCache;

	NodeSortKeyVectorType	m_keys;

	NodeVectorType			m_scratchVector;
};

#endif	// XALAN_NODESORTER_HEADER_GUARD
<commit_msg>Fixed typo.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#if !defined(XALAN_NODESORTER_HEADER_GUARD)
#define XALAN_NODESORTER_HEADER_GUARD

/**
 * @author Scott Boag (scott_boag@lotus.com)
 * @author David N. Bertoni (david_n_bertoni@lotus.com)
 */

// Base include file.  Must be first.
#include "XSLTDefinitions.hpp"

#include <functional>
#include <vector>

#include <XPath/XObject.hpp>

#include <XSLT/NodeSortKey.hpp>

class MutableNodeRefList;
class StylesheetExecutionContext;
class XalanNode;
class XPath;

/**
 * This class can sort vectors of nodes according to a select pattern.
 */
class NodeSorter
{
public:

	struct VectorEntry
	{
	public:

		VectorEntry(
			XalanNode*		theNode,
			unsigned int	thePosition) :
			m_node(theNode),
			m_position(thePosition)
		{
		}

		XalanNode*		m_node;
		unsigned int	m_position;
	};

#if defined(XALAN_NO_NAMESPACES)
	typedef vector<VectorEntry>			NodeVectorType;
	typedef vector<NodeSortKey>			NodeSortKeyVectorType;
#else
	typedef std::vector<VectorEntry>	NodeVectorType;
	typedef std::vector<NodeSortKey>	NodeSortKeyVectorType;
#endif

	explicit
	NodeSorter();

	~NodeSorter();

	NodeSortKeyVectorType&
	getSortKeys()
	{
		return m_keys;
	}

	/**
	 * Given a list of nodes, sort each node according to the criteria in the
	 * keys.  The list is assumed to be in document order.
	 *
	 * @param executionContext current execution context
	 * @param v    list of Nodes
	 */
	void
	sort(
			StylesheetExecutionContext&		executionContext,
			MutableNodeRefList&				theList);

	/**
	 * Return the results of a compare of two nodes.
	 */
#if defined(XALAN_NO_NAMESPACES)
	struct NodeSortKeyCompare : public binary_function<const NodeVectorType::value_type&, const NodeVectorType::value_type&, bool>
#else
	struct NodeSortKeyCompare : public std::binary_function<const NodeVectorType::value_type&, const NodeVectorType::value_type&, bool>
#endif
	{
	public:

	/**
	 * Construct a NodeSortKeyCompare object, to perform the sort
	 *
	 * @param executionContext current execution context
	 * @param theNodes        vector or nodes to be sorted
	 * @param theNodeSortKeys vector of keys upon which to sort
	 */
		NodeSortKeyCompare(
				StylesheetExecutionContext&		executionContext,
				NodeSorter&						theSorter,
				const NodeVectorType&			theNodes,
				const NodeSortKeyVectorType&	theNodeSortKeys) :
			m_executionContext(executionContext),
			m_sorter(theSorter),
			m_nodes(theNodes),
			m_nodeSortKeys(theNodeSortKeys)
		{
		}

		/**
		 * Compare two nodes, returning a value to indicate the
		 * result
		 *
		 * @param theLHS the first node to compare
		 * @param theRHS the second node to compare
		 * @param theKeyIndex the index of the key to use
		 * @result < 0 if theLHS is less than theRHS, 0 if they are equal, and > 0 if theLHS is greater than theRHS
		 */
		int
		compare(
				first_argument_type		theLHS,
				second_argument_type	theRHS,
				unsigned int			theKeyIndex = 0) const;

		/**
		 * Compare two nodes as a less predicate.
		 *
		 * @param theLHS the first node to compare
		 * @param theRHS the second node to compare
		 * @param theKeyIndex the index of the key to use
		 * @return true if theLHS is less than theRHS
		 */
		result_type
		operator()(
				first_argument_type		theLHS,
				second_argument_type	theRHS,
				unsigned int			theKeyIndex = 0) const
		{
			return compare(theLHS, theRHS, theKeyIndex) < 0 ? true : false;
		}

	protected:

		double
		getNumberResult(
				const NodeSortKey&		theKey,
				unsigned int			theKeyIndex,
				first_argument_type		theEntry) const;

		const XObjectPtr&
		getStringResult(
				const NodeSortKey&		theKey,
				unsigned int			theKeyIndex,
				first_argument_type		theEntry) const;

	private:

		StylesheetExecutionContext&		m_executionContext;
		NodeSorter&						m_sorter;
		const NodeVectorType&			m_nodes;
		const NodeSortKeyVectorType&	m_nodeSortKeys;
	};

	friend struct NodeSortKeyCompare;

#if defined(XALAN_NO_NAMESPACES)
	typedef	vector<double>		NumberResultsCacheVectorType;

	typedef	vector<XObjectPtr>	StringResultsCacheVectorType;

	typedef vector<NumberResultsCacheVectorType>	NumberResultsCacheType;
	typedef vector<StringResultsCacheVectorType>	StringResultsCacheType;
#else
	typedef	std::vector<double>			NumberResultsCacheVectorType;
	typedef	std::vector<XObjectPtr>		StringResultsCacheVectorType;

	typedef std::vector<NumberResultsCacheVectorType>	NumberResultsCacheType;
	typedef std::vector<StringResultsCacheVectorType>	StringResultsCacheType;
#endif

private:

	/**
	 * Given a vector of nodes, sort each node according to the criteria in the
	 * keys.
	 *
	 * @param executionContext current execution context
	 */
	void
	sort(StylesheetExecutionContext&	executionContext);

	// Data members...
	NumberResultsCacheType	m_numberResultsCache;

	StringResultsCacheType	m_stringResultsCache;

	NodeSortKeyVectorType	m_keys;

	NodeVectorType			m_scratchVector;
};

#endif	// XALAN_NODESORTER_HEADER_GUARD
<|endoftext|>


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

   Copyright 2011 David Dubois
   Contributed to ORFEO Toolbox under license Apache 2

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

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

#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbStreamingImageFileWriter.h"
#include "otbImageFileWriter.h"
#include "otbExtractROI.h"
#include "itkImageRegionIteratorWithIndex.h"

#include "otbGenericRSTransform.h"
#include "otbLeastSquareAffineTransformEstimator.h"

#include "otbWindowedSincInterpolateImageBlackmanFunction.h"
#include "otbComplexInterpolateImageFunction.h"

#include "itkPointSet.h"
#include "otbGridIntersectionPointSetSource.h"
#include "itkFFTComplexToComplexImageFilter.h"

#include "otbStreamingResampleImageFilter.h"
#include "otbStandardWriterWatcher.h"

#include "itkFFTShiftImageFilter.h"
#include "itkConstantPadImageFilter.h"
#include "itkBinaryFunctorImageFilter.h"
#include "itkMinimumMaximumImageCalculator.h"
#include "itkComplexToModulusImageFilter.h"
#include "itkDivideImageFilter.h"

typedef std::complex< double >                                         PixelType;
typedef otb::Image< PixelType,2 >                                      ImageType;
typedef ImageType::SizeType                                            SizeType;
typedef ImageType::IndexType                                           IndexType;
typedef ImageType::RegionType                                          RegionType;

typedef itk::PointSet< PixelType, ImageType::ImageDimension >          PointSetType;
typedef otb::GridIntersectionPointSetSource< PointSetType >            PointSetSourceType;
typedef PointSetType::PointsContainer                                  PointsContainerType;
typedef PointSetType::PointType                                        PointType;

typedef otb::ImageFileReader< ImageType >                              ReaderType;
typedef otb::StreamingImageFileWriter< ImageType >                     WriterType;

typedef otb::GenericRSTransform<  >                                    TransformType; // Default is Double, 2 dimensions
typedef otb::ExtractROI< PixelType, PixelType >                        ExtractFilterType;
typedef otb::StreamingResampleImageFilter< ImageType, ImageType >      ResampleFilterType;
typedef itk::Point< PixelType::value_type,ImageType::ImageDimension >  LSQPointType;
typedef otb::LeastSquareAffineTransformEstimator< LSQPointType >       EstimateFilterType;
typedef otb::Function::BlackmanWindowFunction< PixelType::value_type > FunctionType;
typedef itk::ConstantBoundaryCondition< ImageType >                    BoundaryConditionType;
typedef PixelType::value_type                                          CoordRepType;
typedef otb::ComplexInterpolateImageFunction< ImageType,FunctionType,
                                 BoundaryConditionType, CoordRepType > InterpolatorType;

typedef itk::FFTComplexToComplexImageFilter< PixelType::value_type,
                                           ImageType::ImageDimension > FFTType;
typedef FFTType::OutputImageType                                       FFTOutputImageType;
typedef FFTType::TransformDirectionType                                FFTDirectionType;

typedef itk::FFTShiftImageFilter<FFTOutputImageType,FFTOutputImageType> ShiftFilterType;
typedef itk::ConstantPadImageFilter<ImageType,ImageType>          PadFilterType;
typedef otb::Image<double,2>                                           RealImageType;
typedef itk::ComplexToModulusImageFilter<FFTOutputImageType,RealImageType>      ModulusFilterType;
typedef itk::DivideImageFilter<FFTOutputImageType,RealImageType,FFTOutputImageType> DivideFilterType;
typedef itk::MinimumMaximumImageCalculator<RealImageType>              MinMaxCalculatorType;

//==================================== FOR VALIDATION PURPOSES ===========================================
typedef otb::ImageFileWriter<FFTOutputImageType>                       FFTWriterType;
//========================================================================================================
typedef itk::ImageRegionIteratorWithIndex< FFTOutputImageType >        ImageRegionIteratorType;

class ComplexConjugateProduct
{
public:
  inline PixelType operator()(const PixelType & a, const PixelType & b) const
  {
    return a * vcl_conj(b);
  }
};

typedef itk::BinaryFunctorImageFilter<FFTOutputImageType,FFTOutputImageType,FFTOutputImageType,ComplexConjugateProduct> ConjugateProductFilterType;

int main(int argc, char* argv[])
{

  if (argc != 13)
    {
    std::cerr << "Usage: " << argv[0] << " masterImage slaveImage tiePointsPerDim patchSizePerDim dem startx starty sizex sizey outfname1 outfname2 coherency_threshold";
    return EXIT_FAILURE;
    }
  ImageType::SizeType size;
  ImageType::IndexType index;

  const char * masterImage = argv[1];
  const char * slaveImage = argv[2];
  unsigned int tiePointsPerDim = atoi(argv[3]);
  unsigned int patchSizePerDim = atoi(argv[4]);
  const char * demdir  = argv[5];
  index[0] = atoi(argv[6]);
  index[1] = atoi(argv[7]);
  size[0] = atoi(argv[8]);
  size[1] = atoi(argv[9]);
  const char * outfname1 = argv[10];
  const char * outfname2 = argv[11];
  double coherency_threshold = atof(argv[12]);

  ReaderType::Pointer master = ReaderType::New();
  ReaderType::Pointer slave = ReaderType::New();

  master->SetFileName(masterImage);
  slave->SetFileName(slaveImage);

  master->GenerateOutputInformation();
  slave->GenerateOutputInformation();

  ExtractFilterType::Pointer mstExtract = ExtractFilterType::New();
  ExtractFilterType::Pointer slvExtract = ExtractFilterType::New();

  mstExtract->SetInput(master->GetOutput());
  slvExtract->SetInput(slave->GetOutput());

  SizeType mstSize = master->GetOutput()->GetLargestPossibleRegion().GetSize();

  TransformType::Pointer transform = TransformType::New();

  EstimateFilterType::Pointer estimate = EstimateFilterType::New();

  ResampleFilterType::Pointer resample = ResampleFilterType::New();

  PointSetSourceType::Pointer pointSet = PointSetSourceType::New();
  PointSetType::PointType minPoint, maxPoint;
  minPoint[0] = (mstSize[0] - ((mstSize[0] - 1) % tiePointsPerDim) - 1) / tiePointsPerDim;
  minPoint[1] = (mstSize[1] - ((mstSize[1] - 1) % tiePointsPerDim) - 1) / tiePointsPerDim;
  pointSet->SetMinPoint(minPoint);
  maxPoint[0] = mstSize[0] - ((mstSize[0] - 1) % tiePointsPerDim) - 1;
  maxPoint[1] = mstSize[1] - ((mstSize[1] - 1) % tiePointsPerDim) - 1;
  pointSet->SetMaxPoint(maxPoint);

  pointSet->SetNumberOfPoints(tiePointsPerDim);
  pointSet->Update();

  // Get the the point container
  PointSetSourceType::PointsContainerPointer
  points = pointSet->GetOutput()->GetPoints();

  ///////////////////////////////////////////////////
  // Perform genericRSTransform here if needed
  transform->SetInputKeywordList(master->GetOutput()->GetImageKeywordlist());
  transform->SetOutputKeywordList(slave->GetOutput()->GetImageKeywordlist());
  transform->SetDEMDirectory(demdir);

  transform->InstanciateTransform();
  ///////////////////////////////////////////////////

  IndexType currentIndex;
  IndexType slvIndex;
  RegionType curMstRegion;
  RegionType curSlvRegion;
  SizeType currentSize;
  currentSize[0] = patchSizePerDim;
  currentSize[1] = patchSizePerDim;

  PointsContainerType::ConstIterator it = points->Begin();
  while (it != points->End())
  {
        PointType mstPoint = it.Value();
	PointType slvPoint = transform->TransformPoint(mstPoint);
	slvPoint[0] = floor(slvPoint[0]);
	slvPoint[1] = floor(slvPoint[1]);

	currentIndex[0] = mstPoint[0] - (patchSizePerDim / 2);
	currentIndex[1] = mstPoint[1] - (patchSizePerDim / 2);
	curMstRegion.SetIndex(currentIndex);
	curMstRegion.SetSize(currentSize);

	//slvExtract->SetExtractionRegion(currentRegion); // Should take into account GenericRSTransform-calculated initial offset (if genericRS is used)
	currentIndex[0] = slvPoint[0] - (patchSizePerDim / 2);
	currentIndex[1] = slvPoint[1] - (patchSizePerDim / 2);
	curSlvRegion.SetIndex(currentIndex);
	curSlvRegion.SetSize(currentSize);
	if(!(slave->GetOutput()->GetLargestPossibleRegion().IsInside(curSlvRegion)) || !(master->GetOutput()->GetLargestPossibleRegion().IsInside(curMstRegion)))
	{
		++it;
		continue;
	}
	mstExtract->SetExtractionRegion(curMstRegion);
	slvExtract->SetExtractionRegion(curSlvRegion);

        ImageType::SizeType paddsize;
        paddsize.Fill(patchSizePerDim/2);

        PadFilterType::Pointer pad1 = PadFilterType::New();
        pad1->SetInput(mstExtract->GetOutput());
        pad1->SetPadBound(paddsize);

        PadFilterType::Pointer pad2 = PadFilterType::New();
        pad2->SetInput(slvExtract->GetOutput());
        pad2->SetPadBound(paddsize);

        FFTType::Pointer fft = FFTType::New();
        fft->SetInput(pad1->GetOutput());
        fft->Update();

        FFTOutputImageType::Pointer fft1 = fft->GetOutput();

        fft = FFTType::New();
        fft->SetInput(pad2->GetOutput());
        fft->Update();

        FFTOutputImageType::Pointer fft2 = fft->GetOutput();

        ConjugateProductFilterType::Pointer conjProd = ConjugateProductFilterType::New();
        conjProd->SetInput1(fft1);
        conjProd->SetInput2(fft2);

        // Try to normalise to get the normalized coherence coeff
        ModulusFilterType::Pointer conjProdMod = ModulusFilterType::New();
        conjProdMod->SetInput(conjProd->GetOutput());

        DivideFilterType::Pointer conjProdNorm = DivideFilterType::New();
        conjProdNorm->SetInput1(conjProd->GetOutput());
        conjProdNorm->SetInput2(conjProdMod->GetOutput());

        fft = FFTType::New();
        fft->SetInput(conjProdNorm->GetOutput());
        fft->SetTransformDirection(FFTType::INVERSE);
        fft->Update();

        FFTOutputImageType::Pointer ifft = fft->GetOutput();

        ShiftFilterType::Pointer shifter = ShiftFilterType::New();
        shifter->SetInput(ifft);

        ModulusFilterType::Pointer modulus = ModulusFilterType::New();
        modulus->SetInput(shifter->GetOutput());
        modulus->Update();

        MinMaxCalculatorType::Pointer minMax = MinMaxCalculatorType::New();
        minMax->SetImage(modulus->GetOutput());
        minMax->ComputeMaximum();

        slvIndex = minMax->GetIndexOfMaximum();

	slvPoint[0] = slvPoint[0] - slvIndex[0] + (patchSizePerDim / 2);
	slvPoint[1] = slvPoint[1] - slvIndex[1] + (patchSizePerDim / 2);

	std::cout << "Master: " << mstPoint[0] << ", " << mstPoint[1];
	std::cout << " - Slave: " << slvPoint[0] << ", " << slvPoint[1] << std::endl;
	std::cout << "Final offset: " << slvIndex[0] - (patchSizePerDim / 2) << ", " << slvIndex[1] - (patchSizePerDim / 2) << std::endl;
        std::cout<<"Coherency: "<<minMax->GetMaximum()<<std::endl;

        if(minMax->GetMaximum()>coherency_threshold)
          {
          estimate->AddTiePoints(mstPoint, slvPoint);
          std::cout<<"Tie points added"<<std::endl;
          }
        std::cout<<"==================================="<<std::endl;
        ++it;
  }

  estimate->Compute();

  EstimateFilterType::CovariantVectorType rmsError = estimate->GetRMSError();
  EstimateFilterType::CovariantVectorType relResidual = estimate->GetRelativeResidual();

  std::cout << "RMS error is:" << rmsError[0] << " in range and " << rmsError[1] << " in azimuth." << std::endl;
  std::cout << "Relative residual is:" << relResidual[0] << " in range and " << relResidual[1] << " in azimuth." << std::endl;

  InterpolatorType::Pointer interpolator = InterpolatorType::New();
  interpolator->SetInputImage(slave->GetOutput());
  interpolator->SetRadius(3);
  interpolator->SetNormalizeZeroFrequency(0.01);

  std::cout<<"Transform matrix: "<<std::endl;
  std::cout<<estimate->GetAffineTransform()->GetMatrix()<<std::endl;

  std::cout<<"Transform offset: "<<std::endl;
  std::cout<<estimate->GetAffineTransform()->GetTranslation()<<std::endl;

  resample->SetTransform(estimate->GetAffineTransform());
  resample->SetInterpolator(interpolator);
  resample->SetInput(slave->GetOutput());
  resample->SetOutputSize(mstSize);
  resample->SetOutputOrigin(master->GetOutput()->GetOrigin());
  resample->SetOutputSpacing(master->GetOutput()->GetSpacing());

  ExtractFilterType::Pointer extract = ExtractFilterType::New();
  ImageType::RegionType region;
  region.SetSize(size);
  region.SetIndex(index);
  extract->SetExtractionRegion(region);
  extract->SetInput(master->GetOutput());

  typedef otb::StreamingImageFileWriter< ImageType > WriterFixedType;
  WriterFixedType::Pointer writer = WriterFixedType::New();
  writer->SetFileName(outfname1);
  writer->SetInput(extract->GetOutput());

  otb::StandardWriterWatcher watcher1(writer,extract,"Extracting from master image.");

  writer->Update();

  extract = ExtractFilterType::New();
  extract->SetExtractionRegion(region);
  extract->SetInput(resample->GetOutput());

  writer = WriterFixedType::New();
  writer->SetFileName(outfname2);
  writer->SetInput(extract->GetOutput());

  otb::StandardWriterWatcher watcher2(writer,resample,"Extracting from registered slave image.");
  writer->Update();

  return EXIT_SUCCESS;
}

<commit_msg>ENH: right "final offset" value<commit_after>/*=========================================================================

   Copyright 2011 David Dubois
   Contributed to ORFEO Toolbox under license Apache 2

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

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

#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbStreamingImageFileWriter.h"
#include "otbImageFileWriter.h"
#include "otbExtractROI.h"
#include "itkImageRegionIteratorWithIndex.h"

#include "otbGenericRSTransform.h"
#include "otbLeastSquareAffineTransformEstimator.h"

#include "otbWindowedSincInterpolateImageBlackmanFunction.h"
#include "otbComplexInterpolateImageFunction.h"

#include "itkPointSet.h"
#include "otbGridIntersectionPointSetSource.h"
#include "itkFFTComplexToComplexImageFilter.h"

#include "otbStreamingResampleImageFilter.h"
#include "otbStandardWriterWatcher.h"

#include "itkFFTShiftImageFilter.h"
#include "itkConstantPadImageFilter.h"
#include "itkBinaryFunctorImageFilter.h"
#include "itkMinimumMaximumImageCalculator.h"
#include "itkComplexToModulusImageFilter.h"
#include "itkDivideImageFilter.h"

typedef std::complex< double >                                         PixelType;
typedef otb::Image< PixelType,2 >                                      ImageType;
typedef ImageType::SizeType                                            SizeType;
typedef ImageType::IndexType                                           IndexType;
typedef ImageType::RegionType                                          RegionType;

typedef itk::PointSet< PixelType, ImageType::ImageDimension >          PointSetType;
typedef otb::GridIntersectionPointSetSource< PointSetType >            PointSetSourceType;
typedef PointSetType::PointsContainer                                  PointsContainerType;
typedef PointSetType::PointType                                        PointType;

typedef otb::ImageFileReader< ImageType >                              ReaderType;
typedef otb::StreamingImageFileWriter< ImageType >                     WriterType;

typedef otb::GenericRSTransform<  >                                    TransformType; // Default is Double, 2 dimensions
typedef otb::ExtractROI< PixelType, PixelType >                        ExtractFilterType;
typedef otb::StreamingResampleImageFilter< ImageType, ImageType >      ResampleFilterType;
typedef itk::Point< PixelType::value_type,ImageType::ImageDimension >  LSQPointType;
typedef otb::LeastSquareAffineTransformEstimator< LSQPointType >       EstimateFilterType;
typedef otb::Function::BlackmanWindowFunction< PixelType::value_type > FunctionType;
typedef itk::ConstantBoundaryCondition< ImageType >                    BoundaryConditionType;
typedef PixelType::value_type                                          CoordRepType;
typedef otb::ComplexInterpolateImageFunction< ImageType,FunctionType,
                                 BoundaryConditionType, CoordRepType > InterpolatorType;

typedef itk::FFTComplexToComplexImageFilter< PixelType::value_type,
                                           ImageType::ImageDimension > FFTType;
typedef FFTType::OutputImageType                                       FFTOutputImageType;
typedef FFTType::TransformDirectionType                                FFTDirectionType;

typedef itk::FFTShiftImageFilter<FFTOutputImageType,FFTOutputImageType> ShiftFilterType;
typedef itk::ConstantPadImageFilter<ImageType,ImageType>          PadFilterType;
typedef otb::Image<double,2>                                           RealImageType;
typedef itk::ComplexToModulusImageFilter<FFTOutputImageType,RealImageType>      ModulusFilterType;
typedef itk::DivideImageFilter<FFTOutputImageType,RealImageType,FFTOutputImageType> DivideFilterType;
typedef itk::MinimumMaximumImageCalculator<RealImageType>              MinMaxCalculatorType;

//==================================== FOR VALIDATION PURPOSES ===========================================
typedef otb::ImageFileWriter<FFTOutputImageType>                       FFTWriterType;
//========================================================================================================
typedef itk::ImageRegionIteratorWithIndex< FFTOutputImageType >        ImageRegionIteratorType;

class ComplexConjugateProduct
{
public:
  inline PixelType operator()(const PixelType & a, const PixelType & b) const
  {
    return a * vcl_conj(b);
  }
};

typedef itk::BinaryFunctorImageFilter<FFTOutputImageType,FFTOutputImageType,FFTOutputImageType,ComplexConjugateProduct> ConjugateProductFilterType;

int main(int argc, char* argv[])
{

  if (argc != 13)
    {
    std::cerr << "Usage: " << argv[0] << " masterImage slaveImage tiePointsPerDim patchSizePerDim dem startx starty sizex sizey outfname1 outfname2 coherency_threshold";
    return EXIT_FAILURE;
    }
  ImageType::SizeType size;
  ImageType::IndexType index;

  const char * masterImage = argv[1];
  const char * slaveImage = argv[2];
  unsigned int tiePointsPerDim = atoi(argv[3]);
  unsigned int patchSizePerDim = atoi(argv[4]);
  const char * demdir  = argv[5];
  index[0] = atoi(argv[6]);
  index[1] = atoi(argv[7]);
  size[0] = atoi(argv[8]);
  size[1] = atoi(argv[9]);
  const char * outfname1 = argv[10];
  const char * outfname2 = argv[11];
  double coherency_threshold = atof(argv[12]);

  ReaderType::Pointer master = ReaderType::New();
  ReaderType::Pointer slave = ReaderType::New();

  master->SetFileName(masterImage);
  slave->SetFileName(slaveImage);

  master->GenerateOutputInformation();
  slave->GenerateOutputInformation();

  ExtractFilterType::Pointer mstExtract = ExtractFilterType::New();
  ExtractFilterType::Pointer slvExtract = ExtractFilterType::New();

  mstExtract->SetInput(master->GetOutput());
  slvExtract->SetInput(slave->GetOutput());

  SizeType mstSize = master->GetOutput()->GetLargestPossibleRegion().GetSize();

  TransformType::Pointer transform = TransformType::New();

  EstimateFilterType::Pointer estimate = EstimateFilterType::New();

  ResampleFilterType::Pointer resample = ResampleFilterType::New();

  PointSetSourceType::Pointer pointSet = PointSetSourceType::New();
  PointSetType::PointType minPoint, maxPoint;
  minPoint[0] = (mstSize[0] - ((mstSize[0] - 1) % tiePointsPerDim) - 1) / tiePointsPerDim;
  minPoint[1] = (mstSize[1] - ((mstSize[1] - 1) % tiePointsPerDim) - 1) / tiePointsPerDim;
  pointSet->SetMinPoint(minPoint);
  maxPoint[0] = mstSize[0] - ((mstSize[0] - 1) % tiePointsPerDim) - 1;
  maxPoint[1] = mstSize[1] - ((mstSize[1] - 1) % tiePointsPerDim) - 1;
  pointSet->SetMaxPoint(maxPoint);

  pointSet->SetNumberOfPoints(tiePointsPerDim);
  pointSet->Update();

  // Get the the point container
  PointSetSourceType::PointsContainerPointer
  points = pointSet->GetOutput()->GetPoints();

  ///////////////////////////////////////////////////
  // Perform genericRSTransform here if needed
  transform->SetInputKeywordList(master->GetOutput()->GetImageKeywordlist());
  transform->SetOutputKeywordList(slave->GetOutput()->GetImageKeywordlist());
  transform->SetDEMDirectory(demdir);

  transform->InstanciateTransform();
  ///////////////////////////////////////////////////

  IndexType currentIndex;
  IndexType slvIndex;
  RegionType curMstRegion;
  RegionType curSlvRegion;
  SizeType currentSize;
  currentSize[0] = patchSizePerDim;
  currentSize[1] = patchSizePerDim;

  PointsContainerType::ConstIterator it = points->Begin();
  while (it != points->End())
  {
        PointType mstPoint = it.Value();
	PointType slvPoint = transform->TransformPoint(mstPoint);
	slvPoint[0] = floor(slvPoint[0]);
	slvPoint[1] = floor(slvPoint[1]);

	currentIndex[0] = mstPoint[0] - (patchSizePerDim / 2);
	currentIndex[1] = mstPoint[1] - (patchSizePerDim / 2);
	curMstRegion.SetIndex(currentIndex);
	curMstRegion.SetSize(currentSize);

	//slvExtract->SetExtractionRegion(currentRegion); // Should take into account GenericRSTransform-calculated initial offset (if genericRS is used)
	currentIndex[0] = slvPoint[0] - (patchSizePerDim / 2);
	currentIndex[1] = slvPoint[1] - (patchSizePerDim / 2);
	curSlvRegion.SetIndex(currentIndex);
	curSlvRegion.SetSize(currentSize);
	if(!(slave->GetOutput()->GetLargestPossibleRegion().IsInside(curSlvRegion)) || !(master->GetOutput()->GetLargestPossibleRegion().IsInside(curMstRegion)))
	{
		++it;
		continue;
	}
	mstExtract->SetExtractionRegion(curMstRegion);
	slvExtract->SetExtractionRegion(curSlvRegion);

        ImageType::SizeType paddsize;
        paddsize.Fill(patchSizePerDim/2);

        PadFilterType::Pointer pad1 = PadFilterType::New();
        pad1->SetInput(mstExtract->GetOutput());
        pad1->SetPadBound(paddsize);

        PadFilterType::Pointer pad2 = PadFilterType::New();
        pad2->SetInput(slvExtract->GetOutput());
        pad2->SetPadBound(paddsize);

        FFTType::Pointer fft = FFTType::New();
        fft->SetInput(pad1->GetOutput());
        fft->Update();

        FFTOutputImageType::Pointer fft1 = fft->GetOutput();

        fft = FFTType::New();
        fft->SetInput(pad2->GetOutput());
        fft->Update();

        FFTOutputImageType::Pointer fft2 = fft->GetOutput();

        ConjugateProductFilterType::Pointer conjProd = ConjugateProductFilterType::New();
        conjProd->SetInput1(fft1);
        conjProd->SetInput2(fft2);

        // Try to normalise to get the normalized coherence coeff
        ModulusFilterType::Pointer conjProdMod = ModulusFilterType::New();
        conjProdMod->SetInput(conjProd->GetOutput());

        DivideFilterType::Pointer conjProdNorm = DivideFilterType::New();
        conjProdNorm->SetInput1(conjProd->GetOutput());
        conjProdNorm->SetInput2(conjProdMod->GetOutput());

        fft = FFTType::New();
        fft->SetInput(conjProdNorm->GetOutput());
        fft->SetTransformDirection(FFTType::INVERSE);
        fft->Update();

        FFTOutputImageType::Pointer ifft = fft->GetOutput();

        ShiftFilterType::Pointer shifter = ShiftFilterType::New();
        shifter->SetInput(ifft);

        ModulusFilterType::Pointer modulus = ModulusFilterType::New();
        modulus->SetInput(shifter->GetOutput());
        modulus->Update();

        MinMaxCalculatorType::Pointer minMax = MinMaxCalculatorType::New();
        minMax->SetImage(modulus->GetOutput());
        minMax->ComputeMaximum();

        slvIndex = minMax->GetIndexOfMaximum();

	slvPoint[0] = slvPoint[0] - slvIndex[0] + (patchSizePerDim / 2);
	slvPoint[1] = slvPoint[1] - slvIndex[1] + (patchSizePerDim / 2);

	std::cout << "Master: " << mstPoint[0] << ", " << mstPoint[1];
	std::cout << " - Slave: " << slvPoint[0] << ", " << slvPoint[1] << std::endl;
	std::cout << "Final offset: " << slvIndex[0] - (patchSizePerDim / 2.) << ", " << slvIndex[1] - (patchSizePerDim / 2.) << std::endl;
        std::cout<<"Coherency: "<<minMax->GetMaximum()<<std::endl;

        if(minMax->GetMaximum()>coherency_threshold)
          {
          estimate->AddTiePoints(mstPoint, slvPoint);
          std::cout<<"Tie points added"<<std::endl;
          }
        std::cout<<"==================================="<<std::endl;
        ++it;
  }

  estimate->Compute();

  EstimateFilterType::CovariantVectorType rmsError = estimate->GetRMSError();
  EstimateFilterType::CovariantVectorType relResidual = estimate->GetRelativeResidual();

  std::cout << "RMS error is:" << rmsError[0] << " in range and " << rmsError[1] << " in azimuth." << std::endl;
  std::cout << "Relative residual is:" << relResidual[0] << " in range and " << relResidual[1] << " in azimuth." << std::endl;

  InterpolatorType::Pointer interpolator = InterpolatorType::New();
  interpolator->SetInputImage(slave->GetOutput());
  interpolator->SetRadius(3);
  interpolator->SetNormalizeZeroFrequency(0.01);

  std::cout<<"Transform matrix: "<<std::endl;
  std::cout<<estimate->GetAffineTransform()->GetMatrix()<<std::endl;

  std::cout<<"Transform offset: "<<std::endl;
  std::cout<<estimate->GetAffineTransform()->GetTranslation()<<std::endl;

  resample->SetTransform(estimate->GetAffineTransform());
  resample->SetInterpolator(interpolator);
  resample->SetInput(slave->GetOutput());
  resample->SetOutputSize(mstSize);
  resample->SetOutputOrigin(master->GetOutput()->GetOrigin());
  resample->SetOutputSpacing(master->GetOutput()->GetSpacing());

  ExtractFilterType::Pointer extract = ExtractFilterType::New();
  ImageType::RegionType region;
  region.SetSize(size);
  region.SetIndex(index);
  extract->SetExtractionRegion(region);
  extract->SetInput(master->GetOutput());

  typedef otb::StreamingImageFileWriter< ImageType > WriterFixedType;
  WriterFixedType::Pointer writer = WriterFixedType::New();
  writer->SetFileName(outfname1);
  writer->SetInput(extract->GetOutput());

  otb::StandardWriterWatcher watcher1(writer,extract,"Extracting from master image.");

  writer->Update();

  extract = ExtractFilterType::New();
  extract->SetExtractionRegion(region);
  extract->SetInput(resample->GetOutput());

  writer = WriterFixedType::New();
  writer->SetFileName(outfname2);
  writer->SetInput(extract->GetOutput());

  otb::StandardWriterWatcher watcher2(writer,resample,"Extracting from registered slave image.");
  writer->Update();

  return EXIT_SUCCESS;
}

<|endoftext|>