<commit_before>/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * 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 "itkScalableAffineTransform.h"
#include "otbStreamingResampleImageFilter.h"
#include "otbBCOInterpolateImageFunction.h"
#include "otbKeyPointSetsMatchingFilter.h"
#include "otbSiftFastImageFilter.h"
#include "otbImageToSIFTKeyPointSetFilter.h"
#include "otbImageToSURFKeyPointSetFilter.h"
#include "itkPointSet.h"

#include <tuple>

using ImageType          = otb::Image<double>;
using ReaderType         = otb::ImageFileReader<ImageType>;
using TransformType      = itk::ScalableAffineTransform<double, 2>;
using ResamplerType      = otb::StreamingResampleImageFilter<ImageType, ImageType, double>;
using InterpolatorType   = otb::BCOInterpolateImageFunction<ImageType, double>;
using VectorType         = itk::VariableLengthVector<double>;
using PointSetType       = itk::PointSet<VectorType, 2>;
using SiftFastFilterType = otb::SiftFastImageFilter<ImageType, PointSetType>;
using SiftFilterType     = otb::ImageToSIFTKeyPointSetFilter<ImageType, PointSetType>;
using SurfFilterType     = otb::ImageToSURFKeyPointSetFilter<ImageType, PointSetType>;
using MatchingFilterType = otb::KeyPointSetsMatchingFilter<PointSetType>;

/** Generate a pair of images, one beeing slightly warped wrt the
 * other */
auto generateImagePair(const std::string& infname, double rotation, double scaling)
{
  // Read reference image
  auto reader = ReaderType::New();
  reader->SetFileName(infname);
  reader->Update();
  ImageType::Pointer reference = reader->GetOutput();

  // Create secondary image

  // Setup transform
  auto transform = TransformType::New();

  // Set rotation center as image center
  auto origin  = reference->GetOrigin();
  auto spacing = reference->GetSpacing();
  auto size    = reference->GetLargestPossibleRegion().GetSize();
  auto center  = origin;
  center[0] += 0.5 * spacing[0] * size[0];
  center[1] += 0.5 * spacing[1] * size[1];
  transform->SetCenter(center);

  // Set rotation angle
  transform->Rotate2D(rotation * otb::CONST_PI_180);

  // Set scale
  ImageType::SpacingType scalingVector;
  scalingVector.Fill(scaling);
  transform->Scale(scalingVector);

  // Invert transform
  auto inverse = TransformType::New();
  bool ok      = transform->GetInverse(inverse);
  if (!ok)
    throw std::logic_error("Could not inverse transform");
  // Setup interpolator
  auto interpolator = InterpolatorType::New();

  // Setup resampler
  auto resampler = ResamplerType::New();
  resampler->SetInput(reference);
  resampler->SetTransform(transform);
  resampler->SetInterpolator(interpolator);

  // Since rotation and scaling are small, use same image parameter
  // for secondary image
  resampler->SetOutputOrigin(origin);
  resampler->SetOutputSize(size);
  resampler->SetOutputSpacing(spacing);
  resampler->Update();
  ImageType::Pointer secondary = resampler->GetOutput();

  return std::make_tuple(reference, secondary, transform);
}

/** Perform checks for one keypoints algorithm */
template <typename TKeyPointsFilter, typename TParameterSetter>
                                                                                bool checkKeyPointsFilter(const ImageType* reference, const ImageType* secondary, const TransformType* transform, const TParameterSetter& configureFilter, double match_rate_thresh, double good_match_rate_thresh)
{
  // Keypoints on first image
  auto filterReference = TKeyPointsFilter::New();
  filterReference->SetInput(reference);
  configureFilter(filterReference);

  // Keypoints on secondary image
  auto filterSecondary = TKeyPointsFilter::New();
  filterSecondary->SetInput(secondary);
  configureFilter(filterSecondary);

  // Match keypoints
  auto matcher = MatchingFilterType::New();
  matcher->SetUseBackMatching(false);
  matcher->SetDistanceThreshold(0.6);
  matcher->SetInput1(filterReference->GetOutput());
  matcher->SetInput2(filterSecondary->GetOutput());
  matcher->Update();

  PointSetType::Pointer         referencePoints   = filterReference->GetOutput();
  const size_t nbReferencePoints = referencePoints->GetPoints()->Size();

  typename PointSetType::Pointer secondaryPoints   = filterSecondary->GetOutput();
  const size_t nbSecondaryPoints = secondaryPoints->GetPoints()->Size();

  std::cout << "Found " << nbReferencePoints << " points in reference image and " << nbSecondaryPoints << " points in secondary image" << std::endl;

  auto         matches    = matcher->GetOutput();
  const size_t nb_matches = matches->Size();

  size_t       good_matches             = 0;
  const double threshold_for_good_match = 0.5; // pixels

  // Count good and bad matches
  for (auto it = matches->Begin(); it != matches->End(); ++it)
  {
    const auto p1 = it.Get()->GetPoint1();
    const auto p2 = it.Get()->GetPoint2();

    const auto p2_mapped = transform->TransformPoint(p2);

    // Check that matches are good up to 0.1 pixel
    if (std::sqrt((p1[0] - p2_mapped[0]) * (p1[0] - p2_mapped[0]) + (p1[1] - p2_mapped[1]) * (p1[1] - p2_mapped[1])) <= threshold_for_good_match)
      ++good_matches;
  }

  // Performances metrics
  const float reference_match_rate = nb_matches / static_cast<float>(nbReferencePoints);
  const float secondary_match_rate = nb_matches / static_cast<float>(nbSecondaryPoints);
  const float good_match_rate      = good_matches / static_cast<float>(nb_matches);

  std::cout << "Found " << nb_matches << " matches with " << good_matches << " valid matches (tolerance of 0.5 pixels)"<< std::endl;

  // Quality gate
  auto printResult = [](bool value) { return value ? "Ok" : "Nok"; };

  bool current_test = reference_match_rate > match_rate_thresh;
  bool overall_status = current_test;
  std::cout << "More than "<<100*match_rate_thresh<<"% of reference points have a match:\t" << printResult(current_test)<<" ("<< 100*reference_match_rate<<"%)"<<std::endl;

  current_test = secondary_match_rate > match_rate_thresh;
  std::cout << "More than "<<100*match_rate_thresh<<"% of secondary points have a match:\t" << printResult(current_test)<<" ("<< 100*secondary_match_rate<<"%)"<<std::endl;
  overall_status = overall_status && current_test;

  current_test = good_match_rate > good_match_rate_thresh;
  std::cout << "More than "<<good_match_rate_thresh*100<<"% of matches are good:             \t" << printResult(current_test) << " ("<< 100*good_match_rate<< "% at 0.5 pixel accuracy)"
            << "\n";
  overall_status = overall_status && current_test;
  return overall_status;
}

int otbKeyPointsAlgorithmsTest(int argc, char* argv[])
{
  if (argc != 2)
  {
    std::cerr << "Usage: " << argv[0] << " infname" << std::endl;
    return EXIT_FAILURE;
  }
  const char* infname = argv[1];

  // Generate reference and secondary image
  ImageType::Pointer     reference, secondary;
  TransformType::Pointer transform;

  // Small rotation and scaling
  const double rotation = 2.5; // 5°
  const double scaling  = 0.99;

  std::tie(reference, secondary, transform) = generateImagePair(infname,rotation, scaling);

  std::cout << "Secondary image generated by applying a rotation of "<<rotation<<" degrees and scaling of "<<scaling<< "."<<std::endl;

  bool status = true;

  // Test Surf filter
  std::cout << "Checking Surf implementation:" << std::endl;
  std::cout << "=============================" << std::endl;

  // Lambda to configure surf algorithm
  auto configureSurf = [](SurfFilterType* filter) {
    filter->SetOctavesNumber(4);
    filter->SetScalesNumber(8);
  };

  status = checkKeyPointsFilter<SurfFilterType>(reference, secondary, transform, configureSurf,0.15,0.65) && status;

  // Test Sift filter
  std::cout << "Checking Sift implementation:" << std::endl;
  std::cout << "=============================" << std::endl;

  // Lambda to configure sift algorithm
  auto configureSift = [](SiftFilterType* filter) {
    filter->SetOctavesNumber(4);
    filter->SetScalesNumber(8);
    filter->SetDoGThreshold(0.01);
    filter->SetEdgeThreshold(10.);
  };

  status = checkKeyPointsFilter<SiftFilterType>(reference, secondary, transform, configureSift,0.45,0.85) && status;

#ifdef OTB_USE_SIFTFAST
  // Test SiftFast filter
  std::cout << "Checking SiftFast implementation:" << std::endl;
  std::cout << "=================================" << std::endl;

  // lambda to set specific filter parameter
  auto configureSiftFast = [](SiftFastFilterType* filter)
    {
      filter->SetScalesNumber(8);
    };

  status = checkKeyPointsFilter<SiftFastFilterType>(reference, secondary, transform, configureSiftFast,0.65,0.95) && status;
#endif

  return status ? EXIT_SUCCESS : EXIT_FAILURE;
}
<commit_msg>ENH: avoid call to sqrt (from review)<commit_after>/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * 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 "itkScalableAffineTransform.h"
#include "otbStreamingResampleImageFilter.h"
#include "otbBCOInterpolateImageFunction.h"
#include "otbKeyPointSetsMatchingFilter.h"
#include "otbSiftFastImageFilter.h"
#include "otbImageToSIFTKeyPointSetFilter.h"
#include "otbImageToSURFKeyPointSetFilter.h"
#include "itkPointSet.h"

#include <tuple>

using ImageType          = otb::Image<double>;
using ReaderType         = otb::ImageFileReader<ImageType>;
using TransformType      = itk::ScalableAffineTransform<double, 2>;
using ResamplerType      = otb::StreamingResampleImageFilter<ImageType, ImageType, double>;
using InterpolatorType   = otb::BCOInterpolateImageFunction<ImageType, double>;
using VectorType         = itk::VariableLengthVector<double>;
using PointSetType       = itk::PointSet<VectorType, 2>;
using SiftFastFilterType = otb::SiftFastImageFilter<ImageType, PointSetType>;
using SiftFilterType     = otb::ImageToSIFTKeyPointSetFilter<ImageType, PointSetType>;
using SurfFilterType     = otb::ImageToSURFKeyPointSetFilter<ImageType, PointSetType>;
using MatchingFilterType = otb::KeyPointSetsMatchingFilter<PointSetType>;

/** Generate a pair of images, one beeing slightly warped wrt the
 * other */
auto generateImagePair(const std::string& infname, double rotation, double scaling)
{
  // Read reference image
  auto reader = ReaderType::New();
  reader->SetFileName(infname);
  reader->Update();
  ImageType::Pointer reference = reader->GetOutput();

  // Create secondary image

  // Setup transform
  auto transform = TransformType::New();

  // Set rotation center as image center
  auto origin  = reference->GetOrigin();
  auto spacing = reference->GetSpacing();
  auto size    = reference->GetLargestPossibleRegion().GetSize();
  auto center  = origin;
  center[0] += 0.5 * spacing[0] * size[0];
  center[1] += 0.5 * spacing[1] * size[1];
  transform->SetCenter(center);

  // Set rotation angle
  transform->Rotate2D(rotation * otb::CONST_PI_180);

  // Set scale
  ImageType::SpacingType scalingVector;
  scalingVector.Fill(scaling);
  transform->Scale(scalingVector);

  // Invert transform
  auto inverse = TransformType::New();
  bool ok      = transform->GetInverse(inverse);
  if (!ok)
    throw std::logic_error("Could not inverse transform");
  // Setup interpolator
  auto interpolator = InterpolatorType::New();

  // Setup resampler
  auto resampler = ResamplerType::New();
  resampler->SetInput(reference);
  resampler->SetTransform(transform);
  resampler->SetInterpolator(interpolator);

  // Since rotation and scaling are small, use same image parameter
  // for secondary image
  resampler->SetOutputOrigin(origin);
  resampler->SetOutputSize(size);
  resampler->SetOutputSpacing(spacing);
  resampler->Update();
  ImageType::Pointer secondary = resampler->GetOutput();

  return std::make_tuple(reference, secondary, transform);
}

/** Perform checks for one keypoints algorithm */
template <typename TKeyPointsFilter, typename TParameterSetter>
                                                                                bool checkKeyPointsFilter(const ImageType* reference, const ImageType* secondary, const TransformType* transform, const TParameterSetter& configureFilter, double match_rate_thresh, double good_match_rate_thresh)
{
  // Keypoints on first image
  auto filterReference = TKeyPointsFilter::New();
  filterReference->SetInput(reference);
  configureFilter(filterReference);

  // Keypoints on secondary image
  auto filterSecondary = TKeyPointsFilter::New();
  filterSecondary->SetInput(secondary);
  configureFilter(filterSecondary);

  // Match keypoints
  auto matcher = MatchingFilterType::New();
  matcher->SetUseBackMatching(false);
  matcher->SetDistanceThreshold(0.6);
  matcher->SetInput1(filterReference->GetOutput());
  matcher->SetInput2(filterSecondary->GetOutput());
  matcher->Update();

  PointSetType::Pointer         referencePoints   = filterReference->GetOutput();
  const size_t nbReferencePoints = referencePoints->GetPoints()->Size();

  typename PointSetType::Pointer secondaryPoints   = filterSecondary->GetOutput();
  const size_t nbSecondaryPoints = secondaryPoints->GetPoints()->Size();

  std::cout << "Found " << nbReferencePoints << " points in reference image and " << nbSecondaryPoints << " points in secondary image" << std::endl;

  auto         matches    = matcher->GetOutput();
  const size_t nb_matches = matches->Size();

  size_t       good_matches             = 0;
  const double threshold_for_good_match = 0.5; // pixels

  // Count good and bad matches
  for (auto it = matches->Begin(); it != matches->End(); ++it)
  {
    const auto p1 = it.Get()->GetPoint1();
    const auto p2 = it.Get()->GetPoint2();

    const auto p2_mapped = transform->TransformPoint(p2);

    // Check that matches are good up to 0.1 pixel
    if ((p1[0] - p2_mapped[0]) * (p1[0] - p2_mapped[0]) + (p1[1] - p2_mapped[1]) * (p1[1] - p2_mapped[1]) <= threshold_for_good_match * threshold_for_good_match)
      ++good_matches;
  }

  // Performances metrics
  const float reference_match_rate = nb_matches / static_cast<float>(nbReferencePoints);
  const float secondary_match_rate = nb_matches / static_cast<float>(nbSecondaryPoints);
  const float good_match_rate      = good_matches / static_cast<float>(nb_matches);

  std::cout << "Found " << nb_matches << " matches with " << good_matches << " valid matches (tolerance of 0.5 pixels)"<< std::endl;

  // Quality gate
  auto printResult = [](bool value) { return value ? "Ok" : "Nok"; };

  bool current_test = reference_match_rate > match_rate_thresh;
  bool overall_status = current_test;
  std::cout << "More than "<<100*match_rate_thresh<<"% of reference points have a match:\t" << printResult(current_test)<<" ("<< 100*reference_match_rate<<"%)"<<std::endl;

  current_test = secondary_match_rate > match_rate_thresh;
  std::cout << "More than "<<100*match_rate_thresh<<"% of secondary points have a match:\t" << printResult(current_test)<<" ("<< 100*secondary_match_rate<<"%)"<<std::endl;
  overall_status = overall_status && current_test;

  current_test = good_match_rate > good_match_rate_thresh;
  std::cout << "More than "<<good_match_rate_thresh*100<<"% of matches are good:             \t" << printResult(current_test) << " ("<< 100*good_match_rate<< "% at 0.5 pixel accuracy)"
            << "\n";
  overall_status = overall_status && current_test;
  return overall_status;
}

int otbKeyPointsAlgorithmsTest(int argc, char* argv[])
{
  if (argc != 2)
  {
    std::cerr << "Usage: " << argv[0] << " infname" << std::endl;
    return EXIT_FAILURE;
  }
  const char* infname = argv[1];

  // Generate reference and secondary image
  ImageType::Pointer     reference, secondary;
  TransformType::Pointer transform;

  // Small rotation and scaling
  const double rotation = 2.5; // 5°
  const double scaling  = 0.99;

  std::tie(reference, secondary, transform) = generateImagePair(infname,rotation, scaling);

  std::cout << "Secondary image generated by applying a rotation of "<<rotation<<" degrees and scaling of "<<scaling<< "."<<std::endl;

  bool status = true;

  // Test Surf filter
  std::cout << "Checking Surf implementation:" << std::endl;
  std::cout << "=============================" << std::endl;

  // Lambda to configure surf algorithm
  auto configureSurf = [](SurfFilterType* filter) {
    filter->SetOctavesNumber(4);
    filter->SetScalesNumber(8);
  };

  status = checkKeyPointsFilter<SurfFilterType>(reference, secondary, transform, configureSurf,0.15,0.65) && status;

  // Test Sift filter
  std::cout << "Checking Sift implementation:" << std::endl;
  std::cout << "=============================" << std::endl;

  // Lambda to configure sift algorithm
  auto configureSift = [](SiftFilterType* filter) {
    filter->SetOctavesNumber(4);
    filter->SetScalesNumber(8);
    filter->SetDoGThreshold(0.01);
    filter->SetEdgeThreshold(10.);
  };

  status = checkKeyPointsFilter<SiftFilterType>(reference, secondary, transform, configureSift,0.45,0.85) && status;

#ifdef OTB_USE_SIFTFAST
  // Test SiftFast filter
  std::cout << "Checking SiftFast implementation:" << std::endl;
  std::cout << "=================================" << std::endl;

  // lambda to set specific filter parameter
  auto configureSiftFast = [](SiftFastFilterType* filter)
    {
      filter->SetScalesNumber(8);
    };

  status = checkKeyPointsFilter<SiftFastFilterType>(reference, secondary, transform, configureSiftFast,0.65,0.95) && status;
#endif

  return status ? EXIT_SUCCESS : EXIT_FAILURE;
}
<|endoftext|>


<commit_before>#include <dlfcn.h>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <cstdlib>

#include <iostream>
#include <fstream>
#include <vector>
#include <array>
#include <string>

#define cursor_forward(x) printf("\033[%dC", static_cast<int>(x))
#define cursor_backward(x) printf("\033[%dD", static_cast<int>(x))

typedef ssize_t (*ReadSignature)(int, void*, size_t);

thread_local std::array<char, 1024> lineBuffer;
thread_local auto lineBufferPos = lineBuffer.begin();

thread_local std::string printBuffer;
thread_local std::string::iterator printBufferPos;

thread_local std::vector<std::string> history;
thread_local std::vector<std::string>::iterator historyPos;

static void readHistory() {

    if (history.size()) return;

    std::string historyFileName(getenv("HOME"));
    historyFileName += "/.bash_history";

    std::ifstream historyFile(historyFileName);
    std::string line;

    while (std::getline(historyFile, line))
        history.push_back(line); // TODO: maybe reverse order?

}

static void newlineHandler() {

    lineBuffer.fill(0);
    lineBufferPos = lineBuffer.begin();

}

static void backspaceHandler() {

    if (lineBufferPos != lineBuffer.begin())
        *(--lineBufferPos) = 0;

}

std::string findCompletion(std::vector<std::string>::iterator start, const std::string &pattern) {

    for (auto it = start - 1; it > history.begin(); it--) {
        if (it->compare(0, pattern.length(), pattern) == 0) {
            historyPos = it;
            return *it;
        }
    }

    historyPos = history.end();
    return pattern;

}

void printCompletion(std::vector<std::string>::iterator startIterator) {

    std::string pattern(lineBuffer.data());
    auto completion = findCompletion(startIterator, pattern);

    cursor_forward(1);
    printf("\e[1;30m%s\e[0m", completion.c_str() + pattern.length());
    cursor_backward(completion.length() - pattern.length() + 1);
    fflush(stdout);

}

void regularCharHandler(char c) {

    *lineBufferPos = c;
    lineBufferPos++;

    printCompletion(history.end());

}

void tabHandler() {

    printCompletion(historyPos);

}

static unsigned char yebash(unsigned char c) {

    static char arrowIndicator = 0;
    // TODO: uncomment later
    //if (!getenv("YEBASH"))
    //    return;

    readHistory();

    switch (c) {

        case 0x06: // ctrl+f
            // FIXME: SEGFAULT
            tabHandler();
            c = 0;
            break;

        case 0x0d: // newline
            newlineHandler();
            break;

        case 0x1b: // first arrow char
            arrowIndicator = 1;
            break;

        case 0x5b: // second ...
            if (arrowIndicator == 1)
                arrowIndicator = 2;
            else regularCharHandler(c);
            break;

        case 0x43: // third ...
            if (arrowIndicator == 2) {
                arrowIndicator = 0;
            } else regularCharHandler(c);
            printBuffer = historyPos->substr(lineBufferPos - lineBuffer.begin());
            printBufferPos = printBuffer.begin();
            break;

        case 0x17: // ctrl+w
            newlineHandler(); // TODO: this has to clear lineBuffer
            break;

        case 0x7f: // backspace
            backspaceHandler();
            break;

        default: // regular char or other special chars
            if (c < 0x20)
                newlineHandler();
            else
                regularCharHandler(c);
            break;

    }

    return c;

}

ssize_t read(int fd, void *buf, size_t count) {

    ssize_t returnValue;
    static thread_local ReadSignature realRead = nullptr;

    if (fd == 0) {
        if (printBuffer.length()) {
            *reinterpret_cast<char *>(buf) = *printBufferPos;
            *lineBufferPos =  *printBufferPos++; // TODO: reapeted code
            lineBufferPos++;
            if (printBufferPos == printBuffer.end()) {
                printBuffer.erase(printBuffer.begin(), printBuffer.end());
            }
            return 1;
        }
    }

    if (!realRead)
        realRead = reinterpret_cast<ReadSignature>(dlsym(RTLD_NEXT, "read"));

    returnValue = realRead(fd, buf, count);

    if (fd == 0 && isatty(fileno(stdin)))
        *reinterpret_cast<unsigned char *>(buf) = yebash(*reinterpret_cast<unsigned char *>(buf));

    return returnValue;

}

<commit_msg>Add one try-catch block<commit_after>#include <dlfcn.h>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <cstdlib>

#include <iostream>
#include <fstream>
#include <vector>
#include <array>
#include <string>

#define cursor_forward(x) printf("\033[%dC", static_cast<int>(x))
#define cursor_backward(x) printf("\033[%dD", static_cast<int>(x))

typedef ssize_t (*ReadSignature)(int, void*, size_t);

thread_local std::array<char, 1024> lineBuffer;
thread_local auto lineBufferPos = lineBuffer.begin();

thread_local std::string printBuffer;
thread_local std::string::iterator printBufferPos;

thread_local std::vector<std::string> history;
thread_local std::vector<std::string>::iterator historyPos;

static void readHistory() {

    if (history.size()) return;

    std::string historyFileName(getenv("HOME"));
    historyFileName += "/.bash_history";

    std::ifstream historyFile(historyFileName);
    std::string line;

    while (std::getline(historyFile, line))
        history.push_back(line); // TODO: maybe reverse order?

}

static void newlineHandler() {

    lineBuffer.fill(0);
    lineBufferPos = lineBuffer.begin();

}

static void backspaceHandler() {

    if (lineBufferPos != lineBuffer.begin())
        *(--lineBufferPos) = 0;

}

std::string findCompletion(std::vector<std::string>::iterator start, const std::string &pattern) {

    for (auto it = start - 1; it > history.begin(); it--) {
        if (it->compare(0, pattern.length(), pattern) == 0) {
            historyPos = it;
            return *it;
        }
    }

    historyPos = history.end();
    return pattern;

}

void printCompletion(std::vector<std::string>::iterator startIterator) {

    std::string pattern(lineBuffer.data());
    auto completion = findCompletion(startIterator, pattern);

    cursor_forward(1);
    printf("\e[1;30m%s\e[0m", completion.c_str() + pattern.length());
    cursor_backward(completion.length() - pattern.length() + 1);
    fflush(stdout);

}

void regularCharHandler(char c) {

    *lineBufferPos = c;
    lineBufferPos++;

    printCompletion(history.end());

}

void tabHandler() {

    printCompletion(historyPos);

}

static unsigned char yebash(unsigned char c) {

    static char arrowIndicator = 0;
    // TODO: uncomment later
    //if (!getenv("YEBASH"))
    //    return;

    readHistory();

    switch (c) {

        case 0x06: // ctrl+f
            // FIXME: SEGFAULT
            tabHandler();
            c = 0;
            break;

        case 0x0d: // newline
            newlineHandler();
            break;

        case 0x1b: // first arrow char
            arrowIndicator = 1;
            break;

        case 0x5b: // second ...
            if (arrowIndicator == 1)
                arrowIndicator = 2;
            else regularCharHandler(c);
            break;

        case 0x43: // third ...
            if (arrowIndicator == 2) {
                arrowIndicator = 0;
            } else regularCharHandler(c);
            try {
                printBuffer = historyPos->substr(lineBufferPos - lineBuffer.begin());
                printBufferPos = printBuffer.begin();
            } catch (...) {
                // FIXME:
            }
            break;

        case 0x17: // ctrl+w
            newlineHandler(); // TODO: this has to clear lineBuffer
            break;

        case 0x7f: // backspace
            backspaceHandler();
            break;

        default: // regular char or other special chars
            if (c < 0x20)
                newlineHandler();
            else
                regularCharHandler(c);
            break;

    }

    return c;

}

ssize_t read(int fd, void *buf, size_t count) {

    ssize_t returnValue;
    static thread_local ReadSignature realRead = nullptr;

    if (fd == 0) {
        if (printBuffer.length()) {
            *reinterpret_cast<char *>(buf) = *printBufferPos;
            *lineBufferPos =  *printBufferPos++; // TODO: reapeted code
            lineBufferPos++;
            if (printBufferPos == printBuffer.end()) {
                printBuffer.erase(printBuffer.begin(), printBuffer.end());
            }
            return 1;
        }
    }

    if (!realRead)
        realRead = reinterpret_cast<ReadSignature>(dlsym(RTLD_NEXT, "read"));

    returnValue = realRead(fd, buf, count);

    if (fd == 0 && isatty(fileno(stdin)))
        *reinterpret_cast<unsigned char *>(buf) = yebash(*reinterpret_cast<unsigned char *>(buf));

    return returnValue;

}

<|endoftext|>


<commit_before>#include "CosSliderCtrl.h"
#include "item_string.h"
#include "ps_config.h"

namespace eparticle2d
{

CosSliderCtrl::CosSliderCtrl(wxPanel* parent, const char* title, UICallback* cb)
	: wxPanel(parent, wxID_ANY)
	, m_cb(cb)
{
 	wxStaticBox* bounding = new wxStaticBox(this, wxID_ANY, title);
 	wxBoxSizer* top_sizer = new wxStaticBoxSizer(bounding, wxVERTICAL);

 	m_amplitude_ctrl = new SliderCtrlTwo(this, "", ITEM_COS_AMPLITUDE, this, PS_COS_AMPLITUDE,
		SliderItem(ITEM_ATTR_CENTER, ITEM_ATTR_CENTER, 0, 0, 200), SliderItem(ITEM_ATTR_OFFSET, ITEM_ATTR_OFFSET, 0, 0, 100));
	top_sizer->Add(m_amplitude_ctrl);

	top_sizer->AddSpacer(5);

	m_frequency_ctrl = new SliderCtrlTwo(this, "Ƶ", ITEM_COS_FREQUENCY, this, PS_COS_FREQUENCY,
		SliderItem(ITEM_ATTR_CENTER, ITEM_ATTR_CENTER, 0, 0, 100), SliderItem(ITEM_ATTR_OFFSET, ITEM_ATTR_OFFSET, 0, 0, 100));
	top_sizer->Add(m_frequency_ctrl);

 	SetSizer(top_sizer);
}

void CosSliderCtrl::Update()
{
	m_amplitude_ctrl->Update();
	m_frequency_ctrl->Update();
}

void CosSliderCtrl::Load(const Json::Value& val)
{
	m_amplitude_ctrl->Load(val[ITEM_COS]);
	m_frequency_ctrl->Load(val[ITEM_COS]);
}

void CosSliderCtrl::Store(Json::Value& val)
{
	m_amplitude_ctrl->Store(val[ITEM_COS]);
	m_frequency_ctrl->Store(val[ITEM_COS]);
}

void CosSliderCtrl::Load()
{
	m_amplitude_ctrl->Load();
	m_frequency_ctrl->Load();
}

void CosSliderCtrl::SetValue(int key, const Data& data)
{
	m_cb->SetValue(key, data);
}

void CosSliderCtrl::GetValue(int key, Data& data)
{
	m_cb->GetValue(key, data);
}

}<commit_msg>SliderCtrlOne SliderCtrlTwo分开<commit_after>#include "CosSliderCtrl.h"
#include "SliderItem.h"
#include "SliderCtrlTwo.h"
#include "item_string.h"
#include "ps_config.h"

namespace eparticle2d
{

CosSliderCtrl::CosSliderCtrl(wxPanel* parent, const char* title, UICallback* cb)
	: wxPanel(parent, wxID_ANY)
	, m_cb(cb)
{
 	wxStaticBox* bounding = new wxStaticBox(this, wxID_ANY, title);
 	wxBoxSizer* top_sizer = new wxStaticBoxSizer(bounding, wxVERTICAL);

 	m_amplitude_ctrl = new SliderCtrlTwo(this, "", ITEM_COS_AMPLITUDE, this, PS_COS_AMPLITUDE,
		SliderItem(ITEM_ATTR_CENTER, ITEM_ATTR_CENTER, 0, 0, 200), SliderItem(ITEM_ATTR_OFFSET, ITEM_ATTR_OFFSET, 0, 0, 100));
	top_sizer->Add(m_amplitude_ctrl);

	top_sizer->AddSpacer(5);

	m_frequency_ctrl = new SliderCtrlTwo(this, "Ƶ", ITEM_COS_FREQUENCY, this, PS_COS_FREQUENCY,
		SliderItem(ITEM_ATTR_CENTER, ITEM_ATTR_CENTER, 0, 0, 100), SliderItem(ITEM_ATTR_OFFSET, ITEM_ATTR_OFFSET, 0, 0, 100));
	top_sizer->Add(m_frequency_ctrl);

 	SetSizer(top_sizer);
}

void CosSliderCtrl::Update()
{
	m_amplitude_ctrl->Update();
	m_frequency_ctrl->Update();
}

void CosSliderCtrl::Load(const Json::Value& val)
{
	m_amplitude_ctrl->Load(val[ITEM_COS]);
	m_frequency_ctrl->Load(val[ITEM_COS]);
}

void CosSliderCtrl::Store(Json::Value& val)
{
	m_amplitude_ctrl->Store(val[ITEM_COS]);
	m_frequency_ctrl->Store(val[ITEM_COS]);
}

void CosSliderCtrl::Load()
{
	m_amplitude_ctrl->Load();
	m_frequency_ctrl->Load();
}

void CosSliderCtrl::SetValue(int key, const Data& data)
{
	m_cb->SetValue(key, data);
}

void CosSliderCtrl::GetValue(int key, Data& data)
{
	m_cb->GetValue(key, data);
}

}<|endoftext|>


<commit_before>// Copyright (C) 2018 Elviss Strazdins
// This file is part of the Ouzel engine.

#include "SpriteFrame.hpp"
#include "core/Engine.hpp"
#include "assets/Cache.hpp"
#include "files/FileSystem.hpp"
#include "utils/JSON.hpp"
#include "utils/Log.hpp"
#include "utils/Utils.hpp"

namespace ouzel
{
    namespace scene
    {
        SpriteFrame::SpriteFrame(const std::string& frameName,
                                 const Size2& textureSize,
                                 const Rect& frameRectangle,
                                 bool rotated,
                                 const Size2& sourceSize,
                                 const Vector2& sourceOffset,
                                 const Vector2& pivot):
            name(frameName)
        {
            std::vector<uint16_t> indices = {0, 1, 2, 1, 3, 2};

            Vector2 textCoords[4];
            Vector2 finalOffset(-sourceSize.width * pivot.x + sourceOffset.x,
                                -sourceSize.height * pivot.y + (sourceSize.height - frameRectangle.size.height - sourceOffset.y));

            if (!rotated)
            {
                Vector2 leftTop(sourceOffset.x / textureSize.width,
                                sourceOffset.y / textureSize.height);

                Vector2 rightBottom((sourceOffset.x + sourceSize.width) / textureSize.width,
                                    (sourceOffset.y + sourceSize.height) / textureSize.height);

                textCoords[0] = Vector2(leftTop.x, rightBottom.y);
                textCoords[1] = Vector2(rightBottom.x, rightBottom.y);
                textCoords[2] = Vector2(leftTop.x, leftTop.y);
                textCoords[3] = Vector2(rightBottom.x, leftTop.y);
            }
            else
            {
                Vector2 leftTop = Vector2(sourceOffset.x / textureSize.width,
                                          sourceOffset.y / textureSize.height);

                Vector2 rightBottom = Vector2((sourceOffset.x + sourceSize.height) / textureSize.width,
                                              (sourceOffset.y + sourceSize.width) / textureSize.height);

                textCoords[0] = Vector2(leftTop.x, leftTop.y);
                textCoords[1] = Vector2(leftTop.x, rightBottom.y);
                textCoords[2] = Vector2(rightBottom.x, leftTop.y);
                textCoords[3] = Vector2(rightBottom.x, rightBottom.y);
            }

            std::vector<graphics::Vertex> vertices = {
                graphics::Vertex(Vector3(finalOffset.x, finalOffset.y, 0.0f), Color::WHITE,
                                 textCoords[0], Vector3(0.0f, 0.0f, -1.0f)),
                graphics::Vertex(Vector3(finalOffset.x + frameRectangle.size.width, finalOffset.y, 0.0f), Color::WHITE,
                                 textCoords[1], Vector3(0.0f, 0.0f, -1.0f)),
                graphics::Vertex(Vector3(finalOffset.x, finalOffset.y + frameRectangle.size.height, 0.0f),  Color::WHITE,
                                 textCoords[2], Vector3(0.0f, 0.0f, -1.0f)),
                graphics::Vertex(Vector3(finalOffset.x + frameRectangle.size.width, finalOffset.y + frameRectangle.size.height, 0.0f),  Color::WHITE,
                                 textCoords[3], Vector3(0.0f, 0.0f, -1.0f))
            };

            boundingBox.set(finalOffset, finalOffset + Vector2(frameRectangle.size.width, frameRectangle.size.height));

            rectangle = Rect(finalOffset.x, finalOffset.y,
                             sourceSize.width, sourceSize.height);

            indexBuffer = std::make_shared<graphics::Buffer>();
            indexBuffer->init(graphics::Buffer::Usage::INDEX, indices.data(), static_cast<uint32_t>(getVectorSize(indices)), 0);

            vertexBuffer = std::make_shared<graphics::Buffer>();
            vertexBuffer->init(graphics::Buffer::Usage::VERTEX, vertices.data(), static_cast<uint32_t>(getVectorSize(vertices)), 0);

            meshBuffer = std::make_shared<graphics::MeshBuffer>();
            meshBuffer->init(sizeof(uint16_t), indexBuffer, vertexBuffer);
        }

        SpriteFrame::SpriteFrame(const std::string& frameName,
                                 const std::vector<uint16_t>& indices,
                                 const std::vector<graphics::Vertex>& vertices,
                                 const Rect& frameRectangle,
                                 const Size2& sourceSize,
                                 const Vector2& sourceOffset,
                                 const Vector2& pivot):
            name(frameName)
        {
            for (const graphics::Vertex& vertex : vertices)
            {
                boundingBox.insertPoint(vertex.position);
            }

            Vector2 finalOffset(-sourceSize.width * pivot.x + sourceOffset.x,
                                -sourceSize.height * pivot.y + (sourceSize.height - frameRectangle.size.height - sourceOffset.y));

            rectangle = Rect(finalOffset.x, finalOffset.y,
                             sourceSize.width, sourceSize.height);

            indexBuffer = std::make_shared<graphics::Buffer>();
            indexBuffer->init(graphics::Buffer::Usage::INDEX, indices.data(), static_cast<uint32_t>(getVectorSize(indices)), 0);

            vertexBuffer = std::make_shared<graphics::Buffer>();
            vertexBuffer->init(graphics::Buffer::Usage::VERTEX, vertices.data(), static_cast<uint32_t>(getVectorSize(vertices)), 0);

            meshBuffer = std::make_shared<graphics::MeshBuffer>();
            meshBuffer->init(sizeof(uint16_t), indexBuffer, vertexBuffer);
        }

    } // scene
} // ouzel
<commit_msg>Revert "Fix the texcoord calculation for the sprite frame"<commit_after>// Copyright (C) 2018 Elviss Strazdins
// This file is part of the Ouzel engine.

#include "SpriteFrame.hpp"
#include "core/Engine.hpp"
#include "assets/Cache.hpp"
#include "files/FileSystem.hpp"
#include "utils/JSON.hpp"
#include "utils/Log.hpp"
#include "utils/Utils.hpp"

namespace ouzel
{
    namespace scene
    {
        SpriteFrame::SpriteFrame(const std::string& frameName,
                                 const Size2& textureSize,
                                 const Rect& frameRectangle,
                                 bool rotated,
                                 const Size2& sourceSize,
                                 const Vector2& sourceOffset,
                                 const Vector2& pivot):
            name(frameName)
        {
            std::vector<uint16_t> indices = {0, 1, 2, 1, 3, 2};

            Vector2 textCoords[4];
            Vector2 finalOffset(-sourceSize.width * pivot.x + sourceOffset.x,
                                -sourceSize.height * pivot.y + (sourceSize.height - frameRectangle.size.height - sourceOffset.y));

            if (!rotated)
            {
                Vector2 leftTop(frameRectangle.position.x / textureSize.width,
                                frameRectangle.position.y / textureSize.height);

                Vector2 rightBottom((frameRectangle.position.x + frameRectangle.size.width) / textureSize.width,
                                    (frameRectangle.position.y + frameRectangle.size.height) / textureSize.height);

                textCoords[0] = Vector2(leftTop.x, rightBottom.y);
                textCoords[1] = Vector2(rightBottom.x, rightBottom.y);
                textCoords[2] = Vector2(leftTop.x, leftTop.y);
                textCoords[3] = Vector2(rightBottom.x, leftTop.y);
            }
            else
            {
                Vector2 leftTop = Vector2(frameRectangle.position.x / textureSize.width,
                                          frameRectangle.position.y / textureSize.height);

                Vector2 rightBottom = Vector2((frameRectangle.position.x + frameRectangle.size.height) / textureSize.width,
                                              (frameRectangle.position.y + frameRectangle.size.width) / textureSize.height);

                textCoords[0] = Vector2(leftTop.x, leftTop.y);
                textCoords[1] = Vector2(leftTop.x, rightBottom.y);
                textCoords[2] = Vector2(rightBottom.x, leftTop.y);
                textCoords[3] = Vector2(rightBottom.x, rightBottom.y);
            }

            std::vector<graphics::Vertex> vertices = {
                graphics::Vertex(Vector3(finalOffset.x, finalOffset.y, 0.0f), Color::WHITE,
                                 textCoords[0], Vector3(0.0f, 0.0f, -1.0f)),
                graphics::Vertex(Vector3(finalOffset.x + frameRectangle.size.width, finalOffset.y, 0.0f), Color::WHITE,
                                 textCoords[1], Vector3(0.0f, 0.0f, -1.0f)),
                graphics::Vertex(Vector3(finalOffset.x, finalOffset.y + frameRectangle.size.height, 0.0f),  Color::WHITE,
                                 textCoords[2], Vector3(0.0f, 0.0f, -1.0f)),
                graphics::Vertex(Vector3(finalOffset.x + frameRectangle.size.width, finalOffset.y + frameRectangle.size.height, 0.0f),  Color::WHITE,
                                 textCoords[3], Vector3(0.0f, 0.0f, -1.0f))
            };

            boundingBox.set(finalOffset, finalOffset + Vector2(frameRectangle.size.width, frameRectangle.size.height));

            rectangle = Rect(finalOffset.x, finalOffset.y,
                             sourceSize.width, sourceSize.height);

            indexBuffer = std::make_shared<graphics::Buffer>();
            indexBuffer->init(graphics::Buffer::Usage::INDEX, indices.data(), static_cast<uint32_t>(getVectorSize(indices)), 0);

            vertexBuffer = std::make_shared<graphics::Buffer>();
            vertexBuffer->init(graphics::Buffer::Usage::VERTEX, vertices.data(), static_cast<uint32_t>(getVectorSize(vertices)), 0);

            meshBuffer = std::make_shared<graphics::MeshBuffer>();
            meshBuffer->init(sizeof(uint16_t), indexBuffer, vertexBuffer);
        }

        SpriteFrame::SpriteFrame(const std::string& frameName,
                                 const std::vector<uint16_t>& indices,
                                 const std::vector<graphics::Vertex>& vertices,
                                 const Rect& frameRectangle,
                                 const Size2& sourceSize,
                                 const Vector2& sourceOffset,
                                 const Vector2& pivot):
            name(frameName)
        {
            for (const graphics::Vertex& vertex : vertices)
            {
                boundingBox.insertPoint(vertex.position);
            }

            Vector2 finalOffset(-sourceSize.width * pivot.x + sourceOffset.x,
                                -sourceSize.height * pivot.y + (sourceSize.height - frameRectangle.size.height - sourceOffset.y));

            rectangle = Rect(finalOffset.x, finalOffset.y,
                             sourceSize.width, sourceSize.height);

            indexBuffer = std::make_shared<graphics::Buffer>();
            indexBuffer->init(graphics::Buffer::Usage::INDEX, indices.data(), static_cast<uint32_t>(getVectorSize(indices)), 0);

            vertexBuffer = std::make_shared<graphics::Buffer>();
            vertexBuffer->init(graphics::Buffer::Usage::VERTEX, vertices.data(), static_cast<uint32_t>(getVectorSize(vertices)), 0);

            meshBuffer = std::make_shared<graphics::MeshBuffer>();
            meshBuffer->init(sizeof(uint16_t), indexBuffer, vertexBuffer);
        }

    } // scene
} // ouzel
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2013.  All rights reserved
 */
#ifndef _Stroika_Foundation_Containers_Concrete_Set_LinkedList_inl_
#define _Stroika_Foundation_Containers_Concrete_Set_LinkedList_inl_

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include    "../../Memory/BlockAllocated.h"

#include    "../Private/IteratorImplHelper.h"
#include    "../Private/PatchingDataStructures/LinkedList.h"
#include    "../Private/SynchronizationUtils.h"

namespace   Stroika {
    namespace   Foundation {
        namespace   Containers {
            namespace   Concrete {

                /*
                 ********************************************************************************
                 ******************* Set_LinkedList<T, TRAITS>::Rep_ ****************************
                 ********************************************************************************
                 */
                template    <typename T, typename TRAITS>
                class   Set_LinkedList<T, TRAITS>::Rep_ : public Set<T, TRAITS>::_IRep {
                private:
                    typedef typename    Set<T, TRAITS>::_IRep  inherited;

                public:
                    Rep_ ();
                    Rep_ (const Rep_& from);
                    NO_ASSIGNMENT_OPERATOR(Rep_);

                public:
                    DECLARE_USE_BLOCK_ALLOCATION (Rep_);

                    // Iterable<T>::_IRep overrides
                public:
                    virtual typename Iterable<T>::_SharedPtrIRep    Clone () const override;
                    virtual Iterator<T>                             MakeIterator () const override;
                    virtual size_t                                  GetLength () const override;
                    virtual bool                                    IsEmpty () const override;
                    virtual void                                    Apply (typename Rep_::_APPLY_ARGTYPE doToElement) const override;
                    virtual Iterator<T>                             ApplyUntilTrue (typename Rep_::_APPLYUNTIL_ARGTYPE doToElement) const override;

                    // Set<T, TRAITS>::_IRep overrides
                public:
                    virtual bool                Equals (const typename Set<T, TRAITS>::_IRep& rhs) const override;
                    virtual bool                Contains (T item) const override;
                    virtual Memory::Optional<T> Lookup (T item) const override;
                    virtual void                RemoveAll () override;
                    virtual void                Add (T item) override;
                    virtual void                Remove (T item) override;
                    virtual void                Remove (const Iterator<T>& i) override;

                private:
                    typedef Private::PatchingDataStructures::LinkedList <
                    T,
                    Private::DataStructures::LinkedList_DefaultTraits<T, typename TRAITS::EqualsCompareFunctionType>
                    >       DataStructureImplType_;

                private:
                    typedef typename Private::IteratorImplHelper_<T, DataStructureImplType_>    IteratorRep_;

                private:
                    Private::ContainerRepLockDataSupport_   fLockSupport_;
                    DataStructureImplType_                  fData_;
                };

                /*
                ********************************************************************************
                ************************ Set_LinkedList<T, TRAITS>::Rep_ ***********************
                ********************************************************************************
                */
                template    <typename T, typename TRAITS>
                inline  Set_LinkedList<T, TRAITS>::Rep_::Rep_ ()
                    : inherited ()
                    , fLockSupport_ ()
                    , fData_ ()
                {
                }
                template    <typename T, typename TRAITS>
                inline  Set_LinkedList<T, TRAITS>::Rep_::Rep_ (const Rep_& from)
                    : inherited ()
                    , fLockSupport_ ()
                    , fData_ ()
                {
                    CONTAINER_LOCK_HELPER_START (from.fLockSupport_) {
                        fData_ = from.fData_;
                    }
                    CONTAINER_LOCK_HELPER_END ();
                }
                template    <typename T, typename TRAITS>
                typename Iterable<T>::_SharedPtrIRep  Set_LinkedList<T, TRAITS>::Rep_::Clone () const
                {
                    // no lock needed cuz src locked in Rep_ CTOR
                    return typename Iterable<T>::_SharedPtrIRep (new Rep_ (*this));
                }
                template    <typename T, typename TRAITS>
                Iterator<T>  Set_LinkedList<T, TRAITS>::Rep_::MakeIterator () const
                {
                    typename Iterator<T>::SharedIRepPtr tmpRep;
                    CONTAINER_LOCK_HELPER_START (fLockSupport_) {
                        Rep_*   NON_CONST_THIS  =   const_cast<Rep_*> (this);       // logically const, but non-const cast cuz re-using iterator API
                        tmpRep = typename Iterator<T>::SharedIRepPtr (new IteratorRep_ (&NON_CONST_THIS->fLockSupport_, &NON_CONST_THIS->fData_));
                    }
                    CONTAINER_LOCK_HELPER_END ();
                    return Iterator<T> (tmpRep);
                }
                template    <typename T, typename TRAITS>
                size_t  Set_LinkedList<T, TRAITS>::Rep_::GetLength () const
                {
                    CONTAINER_LOCK_HELPER_START (fLockSupport_) {
                        return (fData_.GetLength ());
                    }
                    CONTAINER_LOCK_HELPER_END ();
                }
                template    <typename T, typename TRAITS>
                bool  Set_LinkedList<T, TRAITS>::Rep_::IsEmpty () const
                {
                    CONTAINER_LOCK_HELPER_START (fLockSupport_) {
                        return (fData_.GetLength () == 0);
                    }
                    CONTAINER_LOCK_HELPER_END ();
                }
                template    <typename T, typename TRAITS>
                void      Set_LinkedList<T, TRAITS>::Rep_::Apply (typename Rep_::_APPLY_ARGTYPE doToElement) const
                {
                    this->_Apply (doToElement);
                }
                template    <typename T, typename TRAITS>
                Iterator<T>     Set_LinkedList<T, TRAITS>::Rep_::ApplyUntilTrue (typename Rep_::_APPLYUNTIL_ARGTYPE doToElement) const
                {
                    return this->_ApplyUntilTrue (doToElement);
                }
                template    <typename T, typename TRAITS>
                bool    Set_LinkedList<T, TRAITS>::Rep_::Equals (const typename Set<T, TRAITS>::_IRep& rhs) const
                {
                    return this->_Equals_Reference_Implementation (rhs);
                }
                template    <typename T, typename TRAITS>
                bool    Set_LinkedList<T, TRAITS>::Rep_::Contains (T item) const
                {
                    CONTAINER_LOCK_HELPER_START (fLockSupport_) {
                        return fData_.Lookup (item) != nullptr;
                    }
                    CONTAINER_LOCK_HELPER_END ();
                }
                template    <typename T, typename TRAITS>
                Memory::Optional<T> Set_LinkedList<T, TRAITS>::Rep_::Lookup (T item) const
                {
                    CONTAINER_LOCK_HELPER_START (fLockSupport_) {
                        const T*    l = fData_.Lookup (item);
                        return (l == nullptr) ? Memory::Optional<T> () : Memory::Optional<T> (*l);
                    }
                    CONTAINER_LOCK_HELPER_END ();
                }
                template    <typename T, typename TRAITS>
                void    Set_LinkedList<T, TRAITS>::Rep_::RemoveAll ()
                {
                    CONTAINER_LOCK_HELPER_START (fLockSupport_) {
                        fData_.RemoveAll ();
                    }
                    CONTAINER_LOCK_HELPER_END ();
                }
                template    <typename T, typename TRAITS>
                void    Set_LinkedList<T, TRAITS>::Rep_::Add (T item)
                {
                    CONTAINER_LOCK_HELPER_START (fLockSupport_) {
                        for (typename DataStructureImplType_::ForwardIterator it (&fData_); it.More (nullptr, true);) {
                            if (TRAITS::EqualsCompareFunctionType::Equals (it.Current (), item)) {
                                return;
                            }
                        }
                        fData_.Append (item);
                    }
                    CONTAINER_LOCK_HELPER_END ();
                }
                template    <typename T, typename TRAITS>
                void    Set_LinkedList<T, TRAITS>::Rep_::Remove (T item)
                {
                    CONTAINER_LOCK_HELPER_START (fLockSupport_) {
                        for (typename DataStructureImplType_::ForwardIterator it (&fData_); it.More (nullptr, true);) {
                            if (TRAITS::EqualsCompareFunctionType::Equals (it.Current (), item)) {
                                fData_.RemoveAt (it);
                                return;
                            }
                        }
                    }
                    CONTAINER_LOCK_HELPER_END ();
                }
                template    <typename T, typename TRAITS>
                void    Set_LinkedList<T, TRAITS>::Rep_::Remove (const Iterator<T>& i)
                {
                    const typename Iterator<T>::IRep&    ir  =   i.GetRep ();
                    AssertMember (&ir, IteratorRep_);
                    auto       mir =   dynamic_cast<const IteratorRep_&> (ir);
                    CONTAINER_LOCK_HELPER_START (fLockSupport_) {
                        fData_.RemoveAt (mir.fIterator);
                    }
                    CONTAINER_LOCK_HELPER_END ();
                }

                /*
                ********************************************************************************
                ************************ Set_LinkedList<T, TRAITS> *****************************
                ********************************************************************************
                */
                template    <typename T, typename TRAITS>
                Set_LinkedList<T, TRAITS>::Set_LinkedList ()
                    : inherited (typename inherited::_SharedPtrIRep (new Rep_ ()))
                {
                    AssertMember (&inherited::_GetRep (), Rep_);
                }
                template    <typename T, typename TRAITS>
                inline  Set_LinkedList<T, TRAITS>::Set_LinkedList (const Set_LinkedList<T, TRAITS>& src)
                    : inherited (static_cast<const inherited&> (src))
                {
                    AssertMember (&inherited::_GetRep (), Rep_);
                }
                template    <typename T, typename TRAITS>
                template    <typename CONTAINER_OF_T>
                inline  Set_LinkedList<T, TRAITS>::Set_LinkedList (const CONTAINER_OF_T& s)
                    : inherited (typename inherited::_SharedPtrIRep (new Rep_ ()))
                {
                    AssertMember (&inherited::_GetRep (), _IRep);
                    this->AddAll (s);
                }
                template    <typename T, typename TRAITS>
                template    <typename COPY_FROM_ITERATOR_OF_T>
                inline Set_LinkedList<T, TRAITS>::Set_LinkedList (COPY_FROM_ITERATOR_OF_T start, COPY_FROM_ITERATOR_OF_T end)
                    : inherited (typename inherited::_SharedPtrIRep (new Rep_ ()))
                {
                    AssertMember (&inherited::_GetRep (), _IRep);
                    AddAll (start, end);
                }
                template    <typename T, typename TRAITS>
                inline  Set_LinkedList<T, TRAITS>&   Set_LinkedList<T, TRAITS>::operator= (const Set_LinkedList<T, TRAITS>& rhs)
                {
                    inherited::operator= (static_cast<const inherited&> (rhs));
                    AssertMember (&inherited::_GetRep (), Rep_);
                    return *this;
                }
                template    <typename T, typename TRAITS>
                inline  const typename Set_LinkedList<T, TRAITS>::Rep_&  Set_LinkedList<T, TRAITS>::GetRep_ () const
                {
                    /*
                     * This cast is safe since we there is no Iterable<T>::_SetRep() - and so no way to ever change
                     * the type of rep our CTOR bases to Iterable<T>.
                     */
                    AssertMember (&inherited::_GetRep (), Rep_);
                    return (static_cast<const Rep_&> (inherited::_GetRep ()));
                }
                template    <typename T, typename TRAITS>
                inline  typename Set_LinkedList<T, TRAITS>::Rep_&    Set_LinkedList<T, TRAITS>::GetRep_ ()
                {
                    /*
                     * This cast is safe since we there is no Iterable<T>::_SetRep() - and so no way to ever change
                     * the type of rep our CTOR bases to Iterable<T>.
                     */
                    AssertMember (&inherited::_GetRep (), Rep_);
                    return (static_cast<Rep_&> (inherited::_GetRep ()));
                }

            }
        }
    }
}
#endif /* _Stroika_Foundation_Containers_Concrete_Set_LinkedList_inl_ */
<commit_msg>minor tweaks to Set_LinkedList<><commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2013.  All rights reserved
 */
#ifndef _Stroika_Foundation_Containers_Concrete_Set_LinkedList_inl_
#define _Stroika_Foundation_Containers_Concrete_Set_LinkedList_inl_

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include    "../../Memory/BlockAllocated.h"

#include    "../Private/IteratorImplHelper.h"
#include    "../Private/PatchingDataStructures/LinkedList.h"
#include    "../Private/SynchronizationUtils.h"

namespace   Stroika {
    namespace   Foundation {
        namespace   Containers {
            namespace   Concrete {

                /*
                 ********************************************************************************
                 ******************* Set_LinkedList<T, TRAITS>::Rep_ ****************************
                 ********************************************************************************
                 */
                template    <typename T, typename TRAITS>
                class   Set_LinkedList<T, TRAITS>::Rep_ : public Set<T, TRAITS>::_IRep {
                private:
                    typedef typename    Set<T, TRAITS>::_IRep  inherited;

                public:
                    Rep_ ();
                    Rep_ (const Rep_& from);
                    NO_ASSIGNMENT_OPERATOR(Rep_);

                public:
                    DECLARE_USE_BLOCK_ALLOCATION (Rep_);

                    // Iterable<T>::_IRep overrides
                public:
                    virtual typename Iterable<T>::_SharedPtrIRep    Clone () const override;
                    virtual Iterator<T>                             MakeIterator () const override;
                    virtual size_t                                  GetLength () const override;
                    virtual bool                                    IsEmpty () const override;
                    virtual void                                    Apply (typename Rep_::_APPLY_ARGTYPE doToElement) const override;
                    virtual Iterator<T>                             ApplyUntilTrue (typename Rep_::_APPLYUNTIL_ARGTYPE doToElement) const override;

                    // Set<T, TRAITS>::_IRep overrides
                public:
                    virtual bool                Equals (const typename Set<T, TRAITS>::_IRep& rhs) const override;
                    virtual bool                Contains (T item) const override;
                    virtual Memory::Optional<T> Lookup (T item) const override;
                    virtual void                RemoveAll () override;
                    virtual void                Add (T item) override;
                    virtual void                Remove (T item) override;
                    virtual void                Remove (const Iterator<T>& i) override;

                private:
                    typedef Private::PatchingDataStructures::LinkedList <
                    T,
                    Private::DataStructures::LinkedList_DefaultTraits<T, typename TRAITS::EqualsCompareFunctionType>
                    >       DataStructureImplType_;

                private:
                    typedef typename Private::IteratorImplHelper_<T, DataStructureImplType_>    IteratorRep_;

                private:
                    Private::ContainerRepLockDataSupport_   fLockSupport_;
                    DataStructureImplType_                  fData_;
                };

                /*
                ********************************************************************************
                ************************ Set_LinkedList<T, TRAITS>::Rep_ ***********************
                ********************************************************************************
                */
                template    <typename T, typename TRAITS>
                inline  Set_LinkedList<T, TRAITS>::Rep_::Rep_ ()
                    : inherited ()
                    , fLockSupport_ ()
                    , fData_ ()
                {
                }
                template    <typename T, typename TRAITS>
                inline  Set_LinkedList<T, TRAITS>::Rep_::Rep_ (const Rep_& from)
                    : inherited ()
                    , fLockSupport_ ()
                    , fData_ ()
                {
                    CONTAINER_LOCK_HELPER_START (from.fLockSupport_) {
                        fData_ = from.fData_;
                    }
                    CONTAINER_LOCK_HELPER_END ();
                }
                template    <typename T, typename TRAITS>
                typename Iterable<T>::_SharedPtrIRep  Set_LinkedList<T, TRAITS>::Rep_::Clone () const
                {
                    // no lock needed cuz src locked in Rep_ CTOR
                    return typename Iterable<T>::_SharedPtrIRep (new Rep_ (*this));
                }
                template    <typename T, typename TRAITS>
                Iterator<T>  Set_LinkedList<T, TRAITS>::Rep_::MakeIterator () const
                {
                    typename Iterator<T>::SharedIRepPtr tmpRep;
                    CONTAINER_LOCK_HELPER_START (fLockSupport_) {
                        Rep_*   NON_CONST_THIS  =   const_cast<Rep_*> (this);       // logically const, but non-const cast cuz re-using iterator API
                        tmpRep = typename Iterator<T>::SharedIRepPtr (new IteratorRep_ (&NON_CONST_THIS->fLockSupport_, &NON_CONST_THIS->fData_));
                    }
                    CONTAINER_LOCK_HELPER_END ();
                    return Iterator<T> (tmpRep);
                }
                template    <typename T, typename TRAITS>
                size_t  Set_LinkedList<T, TRAITS>::Rep_::GetLength () const
                {
                    CONTAINER_LOCK_HELPER_START (fLockSupport_) {
                        return (fData_.GetLength ());
                    }
                    CONTAINER_LOCK_HELPER_END ();
                }
                template    <typename T, typename TRAITS>
                bool  Set_LinkedList<T, TRAITS>::Rep_::IsEmpty () const
                {
                    CONTAINER_LOCK_HELPER_START (fLockSupport_) {
                        return (fData_.GetLength () == 0);
                    }
                    CONTAINER_LOCK_HELPER_END ();
                }
                template    <typename T, typename TRAITS>
                void      Set_LinkedList<T, TRAITS>::Rep_::Apply (typename Rep_::_APPLY_ARGTYPE doToElement) const
                {
                    this->_Apply (doToElement);
                }
                template    <typename T, typename TRAITS>
                Iterator<T>     Set_LinkedList<T, TRAITS>::Rep_::ApplyUntilTrue (typename Rep_::_APPLYUNTIL_ARGTYPE doToElement) const
                {
                    return this->_ApplyUntilTrue (doToElement);
                }
                template    <typename T, typename TRAITS>
                bool    Set_LinkedList<T, TRAITS>::Rep_::Equals (const typename Set<T, TRAITS>::_IRep& rhs) const
                {
                    return this->_Equals_Reference_Implementation (rhs);
                }
                template    <typename T, typename TRAITS>
                bool    Set_LinkedList<T, TRAITS>::Rep_::Contains (T item) const
                {
                    CONTAINER_LOCK_HELPER_START (fLockSupport_) {
                        return fData_.Lookup (item) != nullptr;
                    }
                    CONTAINER_LOCK_HELPER_END ();
                }
                template    <typename T, typename TRAITS>
                Memory::Optional<T> Set_LinkedList<T, TRAITS>::Rep_::Lookup (T item) const
                {
                    CONTAINER_LOCK_HELPER_START (fLockSupport_) {
                        const T*    l = fData_.Lookup (item);
                        return (l == nullptr) ? Memory::Optional<T> () : Memory::Optional<T> (*l);
                    }
                    CONTAINER_LOCK_HELPER_END ();
                }
                template    <typename T, typename TRAITS>
                void    Set_LinkedList<T, TRAITS>::Rep_::RemoveAll ()
                {
                    CONTAINER_LOCK_HELPER_START (fLockSupport_) {
                        fData_.RemoveAll ();
                    }
                    CONTAINER_LOCK_HELPER_END ();
                }
                template    <typename T, typename TRAITS>
                void    Set_LinkedList<T, TRAITS>::Rep_::Add (T item)
                {
                    CONTAINER_LOCK_HELPER_START (fLockSupport_) {
                        for (typename DataStructureImplType_::ForwardIterator it (&fData_); it.More (nullptr, true);) {
                            if (TRAITS::EqualsCompareFunctionType::Equals (it.Current (), item)) {
                                return;
                            }
                        }
                        fData_.Append (item);
                    }
                    CONTAINER_LOCK_HELPER_END ();
                }
                template    <typename T, typename TRAITS>
                void    Set_LinkedList<T, TRAITS>::Rep_::Remove (T item)
                {
                    CONTAINER_LOCK_HELPER_START (fLockSupport_) {
                        for (typename DataStructureImplType_::ForwardIterator it (&fData_); it.More (nullptr, true);) {
                            if (TRAITS::EqualsCompareFunctionType::Equals (it.Current (), item)) {
                                fData_.RemoveAt (it);
                                return;
                            }
                        }
                    }
                    CONTAINER_LOCK_HELPER_END ();
                }
                template    <typename T, typename TRAITS>
                void    Set_LinkedList<T, TRAITS>::Rep_::Remove (const Iterator<T>& i)
                {
                    const typename Iterator<T>::IRep&    ir  =   i.GetRep ();
                    AssertMember (&ir, IteratorRep_);
                    auto       mir =   dynamic_cast<const IteratorRep_&> (ir);
                    CONTAINER_LOCK_HELPER_START (fLockSupport_) {
                        fData_.RemoveAt (mir.fIterator);
                    }
                    CONTAINER_LOCK_HELPER_END ();
                }

                /*
                ********************************************************************************
                ************************ Set_LinkedList<T, TRAITS> *****************************
                ********************************************************************************
                */
                template    <typename T, typename TRAITS>
                Set_LinkedList<T, TRAITS>::Set_LinkedList ()
                    : inherited (typename inherited::_SharedPtrIRep (new Rep_ ()))
                {
                    AssertMember (&inherited::_GetRep (), Rep_);
                }
                template    <typename T, typename TRAITS>
                inline  Set_LinkedList<T, TRAITS>::Set_LinkedList (const Set_LinkedList<T, TRAITS>& src)
                    : inherited (static_cast<const inherited&> (src))
                {
                    AssertMember (&inherited::_GetRep (), Rep_);
                }
                template    <typename T, typename TRAITS>
                template    <typename CONTAINER_OF_T>
                inline  Set_LinkedList<T, TRAITS>::Set_LinkedList (const CONTAINER_OF_T& s)
                    : inherited (typename inherited::_SharedPtrIRep (new Rep_ ()))
                {
                    AssertMember (&inherited::_GetRep (), Rep_);
                    this->AddAll (s);
                }
                template    <typename T, typename TRAITS>
                template    <typename COPY_FROM_ITERATOR_OF_T>
                inline Set_LinkedList<T, TRAITS>::Set_LinkedList (COPY_FROM_ITERATOR_OF_T start, COPY_FROM_ITERATOR_OF_T end)
                    : inherited (typename inherited::_SharedPtrIRep (new Rep_ ()))
                {
                    AssertMember (&inherited::_GetRep (), Rep_);
                    AddAll (start, end);
                }
                template    <typename T, typename TRAITS>
                inline  Set_LinkedList<T, TRAITS>&   Set_LinkedList<T, TRAITS>::operator= (const Set_LinkedList<T, TRAITS>& rhs)
                {
                    inherited::operator= (static_cast<const inherited&> (rhs));
                    AssertMember (&inherited::_GetRep (), Rep_);
                    return *this;
                }
                template    <typename T, typename TRAITS>
                inline  const typename Set_LinkedList<T, TRAITS>::Rep_&  Set_LinkedList<T, TRAITS>::GetRep_ () const
                {
                    /*
                     * This cast is safe since we there is no Iterable<T>::_SetRep() - and so no way to ever change
                     * the type of rep our CTOR bases to Iterable<T>.
                     */
                    AssertMember (&inherited::_GetRep (), Rep_);
                    return (static_cast<const Rep_&> (inherited::_GetRep ()));
                }
                template    <typename T, typename TRAITS>
                inline  typename Set_LinkedList<T, TRAITS>::Rep_&    Set_LinkedList<T, TRAITS>::GetRep_ ()
                {
                    /*
                     * This cast is safe since we there is no Iterable<T>::_SetRep() - and so no way to ever change
                     * the type of rep our CTOR bases to Iterable<T>.
                     */
                    AssertMember (&inherited::_GetRep (), Rep_);
                    return (static_cast<Rep_&> (inherited::_GetRep ()));
                }

            }
        }
    }
}
#endif /* _Stroika_Foundation_Containers_Concrete_Set_LinkedList_inl_ */
<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
const ll MOD = 1000000007;

typedef tuple<int, int> state;

int N, M;
vector<state> V[310];

ll DP[310][310][310];

int main () {
  cin >> N >> M;
  for (auto i = 0; i < M; ++i) {
    int l, r, x;
    cin >> l >> r >> x;
    V[r].push_back(state(l, x));
  }
  fill(&DP[0][0][0], &DP[0][0][0]+310*310*310, 0);
  DP[1][1][0] = 3;
  for (auto i = 1; i <= N; ++i) {
    for (auto e : V[i]) {
      int l = get<0>(e);
      int clr = get<1>(e);
      if (clr == 1) {
        for (auto j = l+1; j <= i; ++j) {
          for (auto k = 0; k < j; ++k) {
            DP[i][j][k] = 0;
          }
        }
      } else if (clr == 2) {
        for (auto j = 1; j <= i; ++j) {
          for (auto k = 0; k < j; ++k) {
            if (!(j > l && l >= k)) {
              DP[i][j][k] = 0;
            }
          }
        }
      } else {
        for (auto j = 1; j <= i; ++j) {
          for (auto k = l; k < j; ++k) {
            DP[i][j][k] = 0;
          }
        }
      }
    }
    for (auto j = 1; j <= i; ++j) {
      for (auto k = 0; k < j; ++k) {
        cerr << "DP[" << i << "][" << j << "][" << k << "] = "
             << DP[i][j][k] << endl;
      }
    }
    if (i == N) break;
    for (auto j = 1; j <= i; ++j) {
      for (auto k = 0; k < j; ++k) {
        DP[i+1][j][k] += DP[i][j][k];
        DP[i+1][j][k] %= MOD;
        DP[i+1][i+1][k] += DP[i][j][k];
        DP[i+1][i+1][k] %= MOD;
        DP[i+1][i+1][j] += DP[i][j][k];
        DP[i+1][i+1][j] %= MOD;
      }
    }
  }
  ll sum = 0;
  for (auto j = 1; j <= N; ++j) {
    for (auto k = 0; k < j; ++k) {
      cerr << "DP[" << N << "][" << j << "][" << k << "] = "
           << DP[N][j][k] << endl;
      sum += DP[N][j][k];
      sum %= MOD;
    }
  }
  cout << sum << endl;
}
<commit_msg>tried E.cpp to 'E'<commit_after>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
const ll MOD = 1000000007;

typedef tuple<int, int> state;

int N, M;
vector<state> V[310];

ll DP[310][310][310];

int main () {
  cin >> N >> M;
  for (auto i = 0; i < M; ++i) {
    int l, r, x;
    cin >> l >> r >> x;
    V[r].push_back(state(l, x));
  }
  fill(&DP[0][0][0], &DP[0][0][0]+310*310*310, 0);
  DP[1][1][0] = 3;
  for (auto i = 1; i <= N; ++i) {
    for (auto e : V[i]) {
      int l = get<0>(e);
      int clr = get<1>(e);
      if (clr == 1) {
        for (auto j = l+1; j <= i; ++j) {
          for (auto k = 0; k < j; ++k) {
            DP[i][j][k] = 0;
          }
        }
      } else if (clr == 2) {
        for (auto j = 1; j <= i; ++j) {
          for (auto k = 0; k < j; ++k) {
            if (!(j > l && l >= k)) {
              DP[i][j][k] = 0;
            }
          }
        }
      } else {
        for (auto j = 1; j <= i; ++j) {
          for (auto k = l; k < j; ++k) {
            DP[i][j][k] = 0;
            cerr << "make DP[" << i << "][" << j << "][" << k << "] = "
                 << DP[i][j][k] << endl;
          }
        }
      }
    }
    for (auto j = 1; j <= i; ++j) {
      for (auto k = 0; k < j; ++k) {
        cerr << "DP[" << i << "][" << j << "][" << k << "] = "
             << DP[i][j][k] << endl;
      }
    }
    if (i == N) break;
    for (auto j = 1; j <= i; ++j) {
      for (auto k = 0; k < j; ++k) {
        DP[i+1][j][k] += DP[i][j][k];
        DP[i+1][j][k] %= MOD;
        DP[i+1][i+1][k] += DP[i][j][k];
        DP[i+1][i+1][k] %= MOD;
        DP[i+1][i+1][j] += DP[i][j][k];
        DP[i+1][i+1][j] %= MOD;
      }
    }
  }
  ll sum = 0;
  for (auto j = 1; j <= N; ++j) {
    for (auto k = 0; k < j; ++k) {
      sum += DP[N][j][k];
      sum %= MOD;
    }
  }
  cout << sum << endl;
}
<|endoftext|>


<commit_before>// __BEGIN_LICENSE__
//  Copyright (c) 2009-2013, United States Government as represented by the
//  Administrator of the National Aeronautics and Space Administration. All
//  rights reserved.
//
//  The NGT platform is 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.
// __END_LICENSE__

/// \file DiskImageResourceDDD.cc
///
#ifdef _MSC_VER
#pragma warning(disable:4244)
#pragma warning(disable:4267)
#pragma warning(disable:4996)
#endif

#include <vw/Core/Exception.h>
#include <vw/Math/BBox.h>
#include <vw/Math/Vector.h>
#include <vw/Image/ImageResource.h>
#include <vw/Image/PixelTypeInfo.h>
#include <asp/IsisIO/DiskImageResourceIsis.h>

#include <string>

#include <Cube.h>
#include <Portal.h>
#include <SpecialPixel.h>

using namespace std;
using namespace boost;

namespace vw {

  // We use a fixed tile size of 2048x2048 pixels here.  Although this
  // may not be the native tile size of the ISIS cube, it seems to be
  // much faster to let the ISIS driver aggregate smaller blocks by
  // making a larger request rather than caching those blocks ourselves.
  Vector2i DiskImageResourceIsis::block_read_size() const {
    return Vector2i(2048,2048);
  }

  /// Bind the resource to a file for writing.
  void DiskImageResourceIsis::create(std::string const& /*filename*/,
                                     ImageFormat const& /*format*/)
  {
    throw NoImplErr() << "The Isis driver does not yet support creation of Isis files";
  }

  /// Bind the resource to a file for reading.  Confirm that we can open
  /// the file and that it has a sane pixel format.
  void DiskImageResourceIsis::open(std::string const& filename) {
    m_cube     = boost::shared_ptr<Isis::Cube>(new Isis::Cube());
    m_filename = filename;
    m_cube->open(QString::fromStdString(m_filename));
    VW_ASSERT(m_cube->isOpen(), IOErr() << "DiskImageResourceIsis: Could not open cube file: \"" << filename << "\".");

    // Code copied from DiskImageResourceGDAL.cc, with some modifications,
    // to fix a crash in loading an ISIS .cub file with 4 bands.

    // We do our best here to determine what pixel format the GDAL image is in.
    // Commented out the color interpretation checks because the reader (below)
    // can't really cope well with the the default multi-plane interpretation
    // and this is a quicker work-around than actually fixing the problem. -mdh
    if ( m_cube->bandCount() == 1) {
      m_format.pixel_format = VW_PIXEL_GRAY;
      m_format.planes = 1;
    } else if (m_cube->bandCount() == 2) {
      m_format.pixel_format = VW_PIXEL_GRAYA;
      m_format.planes = 1;
    } else if (m_cube->bandCount() == 3) {
      m_format.pixel_format = VW_PIXEL_RGB;
      m_format.planes = 1;
    } else if (m_cube->bandCount() == 4) {
      m_format.pixel_format = VW_PIXEL_RGBA;
      m_format.planes = 1;
    } else {
      m_format.pixel_format = VW_PIXEL_SCALAR;
      m_format.planes = m_cube->bandCount();
    }

    // Extract the dimensions of the image
    m_format.cols = m_cube->sampleCount();
    m_format.rows = m_cube->lineCount();

    // Set member variables according to the specified pixel type
    Isis::PixelType isis_ptype = m_cube->pixelType();
    switch (isis_ptype) {
      case Isis::UnsignedByte:    m_bytes_per_pixel = 1;  m_format.channel_type = VW_CHANNEL_UINT8;    break;
      case Isis::SignedByte:      m_bytes_per_pixel = 1;  m_format.channel_type = VW_CHANNEL_INT8;     break;
      case Isis::UnsignedWord:    m_bytes_per_pixel = 2;  m_format.channel_type = VW_CHANNEL_UINT16;   break;
      case Isis::SignedWord:      m_bytes_per_pixel = 2;  m_format.channel_type = VW_CHANNEL_INT16;    break;
      case Isis::UnsignedInteger: m_bytes_per_pixel = 4;  m_format.channel_type = VW_CHANNEL_UINT32;   break;
      case Isis::SignedInteger:   m_bytes_per_pixel = 4;  m_format.channel_type = VW_CHANNEL_INT32;    break;
      case Isis::Real:            m_bytes_per_pixel = 4;  m_format.channel_type = VW_CHANNEL_FLOAT32;  break;
      case Isis::Double:          m_bytes_per_pixel = 8;  m_format.channel_type = VW_CHANNEL_FLOAT64;  break;
      default:
        vw_throw(IOErr() << "DiskImageResourceIsis: Unknown pixel type.");
    }
  }

  /// Read the disk image into the given buffer.
  void DiskImageResourceIsis::read(ImageBuffer const& dest, BBox2i const& bbox) const {
    VW_ASSERT(bbox.max().x() <= m_cube->sampleCount() ||
              bbox.max().y() <= m_cube->lineCount(),
              IOErr() << "DiskImageResourceIsis: requested bbox " << bbox
              << " exceeds image dimensions [" << m_cube->sampleCount()
              << " " << m_cube->lineCount() << "]");

    // Read in the requested tile from the cube file.  Note that ISIS
    // cube pixel indices appear to be 1-based.
    Isis::Portal buffer(bbox.width(), bbox.height(), m_cube->pixelType());
    buffer.SetPosition(bbox.min().x()+1, bbox.min().y()+1, 1);
    m_cube->read(buffer);

    // Create generic image buffer from the Isis data.
    ImageBuffer src;
    src.data = buffer.RawBuffer();
    src.format = m_format;
    src.format.cols = bbox.width();
    src.format.rows = bbox.height();
    src.cstride = m_bytes_per_pixel;
    src.rstride = m_bytes_per_pixel * bbox.width();
    src.pstride = m_bytes_per_pixel * bbox.width() * bbox.height();

    convert(dest, src);
  }

  // Write the given buffer into the disk image.
  void DiskImageResourceIsis::write(ImageBuffer const& /*src*/, BBox2i const& /*bbox*/) {
    vw_throw ( NoImplErr() << "The Isis driver does not yet support creation of Isis files" );
  }

  // A FileIO hook to open a file for reading
  DiskImageResource* DiskImageResourceIsis::construct_open(std::string const& filename) {
    return new DiskImageResourceIsis(filename);
  }

  // A FileIO hook to open a file for writing
  DiskImageResource*
  DiskImageResourceIsis::construct_create(std::string const& filename,
                                          ImageFormat const& format)
  {
    return new DiskImageResourceIsis(filename, format);
  }

  /// Info about special pixel types in ISIS
  //  --------------------------------------
  double DiskImageResourceIsis::nodata_read() const {
    switch (m_format.channel_type) {
      case VW_CHANNEL_FLOAT64: return Isis::NULL8;
      case VW_CHANNEL_FLOAT32: return Isis::NULL4;
      case VW_CHANNEL_INT32:   return Isis::INULL4;
      case VW_CHANNEL_INT16:   return Isis::NULL2;
      default:                 return 0.0;
    }
  }
  double DiskImageResourceIsis::valid_minimum() const {
    switch (m_format.channel_type) {
      case VW_CHANNEL_FLOAT64: return Isis::ValidMinimum;
      case VW_CHANNEL_FLOAT32: return Isis::VALID_MIN4;
      case VW_CHANNEL_INT32:   return Isis::IVALID_MIN4;
      case VW_CHANNEL_INT16:   return Isis::VALID_MIN2;
      case VW_CHANNEL_UINT16:  return Isis::VALID_MINU2;
      default:                 return Isis::VALID_MIN1;
    }
  }
  double DiskImageResourceIsis::valid_maximum() const {
    switch (m_format.channel_type) {
      case VW_CHANNEL_FLOAT64: return Isis::ValidMaximum;
      case VW_CHANNEL_FLOAT32: return Isis::VALID_MAX4;
      case VW_CHANNEL_INT32:   return 2147483647;
      case VW_CHANNEL_INT16:   return Isis::VALID_MAX2;
      case VW_CHANNEL_UINT16:  return Isis::VALID_MAXU2;
      default:                 return Isis::VALID_MAX1;
    }
  }
  bool DiskImageResourceIsis::is_map_projected() const {
    // They used to have a HasProjection. I'm not sure if this fix is the correct method now.
    return m_cube->projection() != NULL;
  }
}
<commit_msg>Rm inapplicable comment<commit_after>// __BEGIN_LICENSE__
//  Copyright (c) 2009-2013, United States Government as represented by the
//  Administrator of the National Aeronautics and Space Administration. All
//  rights reserved.
//
//  The NGT platform is 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.
// __END_LICENSE__

/// \file DiskImageResourceDDD.cc
///
#ifdef _MSC_VER
#pragma warning(disable:4244)
#pragma warning(disable:4267)
#pragma warning(disable:4996)
#endif

#include <vw/Core/Exception.h>
#include <vw/Math/BBox.h>
#include <vw/Math/Vector.h>
#include <vw/Image/ImageResource.h>
#include <vw/Image/PixelTypeInfo.h>
#include <asp/IsisIO/DiskImageResourceIsis.h>

#include <string>

#include <Cube.h>
#include <Portal.h>
#include <SpecialPixel.h>

using namespace std;
using namespace boost;

namespace vw {

  // We use a fixed tile size of 2048x2048 pixels here.  Although this
  // may not be the native tile size of the ISIS cube, it seems to be
  // much faster to let the ISIS driver aggregate smaller blocks by
  // making a larger request rather than caching those blocks ourselves.
  Vector2i DiskImageResourceIsis::block_read_size() const {
    return Vector2i(2048,2048);
  }

  /// Bind the resource to a file for writing.
  void DiskImageResourceIsis::create(std::string const& /*filename*/,
                                     ImageFormat const& /*format*/)
  {
    throw NoImplErr() << "The Isis driver does not yet support creation of Isis files";
  }

  /// Bind the resource to a file for reading.  Confirm that we can open
  /// the file and that it has a sane pixel format.
  void DiskImageResourceIsis::open(std::string const& filename) {
    m_cube     = boost::shared_ptr<Isis::Cube>(new Isis::Cube());
    m_filename = filename;
    m_cube->open(QString::fromStdString(m_filename));
    VW_ASSERT(m_cube->isOpen(), IOErr() << "DiskImageResourceIsis: Could not open cube file: \"" << filename << "\".");

    // Code copied from DiskImageResourceGDAL.cc, with some modifications,
    // to fix a crash in loading an ISIS .cub file with 4 bands.
    if ( m_cube->bandCount() == 1) {
      m_format.pixel_format = VW_PIXEL_GRAY;
      m_format.planes = 1;
    } else if (m_cube->bandCount() == 2) {
      m_format.pixel_format = VW_PIXEL_GRAYA;
      m_format.planes = 1;
    } else if (m_cube->bandCount() == 3) {
      m_format.pixel_format = VW_PIXEL_RGB;
      m_format.planes = 1;
    } else if (m_cube->bandCount() == 4) {
      m_format.pixel_format = VW_PIXEL_RGBA;
      m_format.planes = 1;
    } else {
      m_format.pixel_format = VW_PIXEL_SCALAR;
      m_format.planes = m_cube->bandCount();
    }

    // Extract the dimensions of the image
    m_format.cols = m_cube->sampleCount();
    m_format.rows = m_cube->lineCount();

    // Set member variables according to the specified pixel type
    Isis::PixelType isis_ptype = m_cube->pixelType();
    switch (isis_ptype) {
      case Isis::UnsignedByte:    m_bytes_per_pixel = 1;  m_format.channel_type = VW_CHANNEL_UINT8;    break;
      case Isis::SignedByte:      m_bytes_per_pixel = 1;  m_format.channel_type = VW_CHANNEL_INT8;     break;
      case Isis::UnsignedWord:    m_bytes_per_pixel = 2;  m_format.channel_type = VW_CHANNEL_UINT16;   break;
      case Isis::SignedWord:      m_bytes_per_pixel = 2;  m_format.channel_type = VW_CHANNEL_INT16;    break;
      case Isis::UnsignedInteger: m_bytes_per_pixel = 4;  m_format.channel_type = VW_CHANNEL_UINT32;   break;
      case Isis::SignedInteger:   m_bytes_per_pixel = 4;  m_format.channel_type = VW_CHANNEL_INT32;    break;
      case Isis::Real:            m_bytes_per_pixel = 4;  m_format.channel_type = VW_CHANNEL_FLOAT32;  break;
      case Isis::Double:          m_bytes_per_pixel = 8;  m_format.channel_type = VW_CHANNEL_FLOAT64;  break;
      default:
        vw_throw(IOErr() << "DiskImageResourceIsis: Unknown pixel type.");
    }
  }

  /// Read the disk image into the given buffer.
  void DiskImageResourceIsis::read(ImageBuffer const& dest, BBox2i const& bbox) const {
    VW_ASSERT(bbox.max().x() <= m_cube->sampleCount() ||
              bbox.max().y() <= m_cube->lineCount(),
              IOErr() << "DiskImageResourceIsis: requested bbox " << bbox
              << " exceeds image dimensions [" << m_cube->sampleCount()
              << " " << m_cube->lineCount() << "]");

    // Read in the requested tile from the cube file.  Note that ISIS
    // cube pixel indices appear to be 1-based.
    Isis::Portal buffer(bbox.width(), bbox.height(), m_cube->pixelType());
    buffer.SetPosition(bbox.min().x()+1, bbox.min().y()+1, 1);
    m_cube->read(buffer);

    // Create generic image buffer from the Isis data.
    ImageBuffer src;
    src.data = buffer.RawBuffer();
    src.format = m_format;
    src.format.cols = bbox.width();
    src.format.rows = bbox.height();
    src.cstride = m_bytes_per_pixel;
    src.rstride = m_bytes_per_pixel * bbox.width();
    src.pstride = m_bytes_per_pixel * bbox.width() * bbox.height();

    convert(dest, src);
  }

  // Write the given buffer into the disk image.
  void DiskImageResourceIsis::write(ImageBuffer const& /*src*/, BBox2i const& /*bbox*/) {
    vw_throw ( NoImplErr() << "The Isis driver does not yet support creation of Isis files" );
  }

  // A FileIO hook to open a file for reading
  DiskImageResource* DiskImageResourceIsis::construct_open(std::string const& filename) {
    return new DiskImageResourceIsis(filename);
  }

  // A FileIO hook to open a file for writing
  DiskImageResource*
  DiskImageResourceIsis::construct_create(std::string const& filename,
                                          ImageFormat const& format)
  {
    return new DiskImageResourceIsis(filename, format);
  }

  /// Info about special pixel types in ISIS
  //  --------------------------------------
  double DiskImageResourceIsis::nodata_read() const {
    switch (m_format.channel_type) {
      case VW_CHANNEL_FLOAT64: return Isis::NULL8;
      case VW_CHANNEL_FLOAT32: return Isis::NULL4;
      case VW_CHANNEL_INT32:   return Isis::INULL4;
      case VW_CHANNEL_INT16:   return Isis::NULL2;
      default:                 return 0.0;
    }
  }
  double DiskImageResourceIsis::valid_minimum() const {
    switch (m_format.channel_type) {
      case VW_CHANNEL_FLOAT64: return Isis::ValidMinimum;
      case VW_CHANNEL_FLOAT32: return Isis::VALID_MIN4;
      case VW_CHANNEL_INT32:   return Isis::IVALID_MIN4;
      case VW_CHANNEL_INT16:   return Isis::VALID_MIN2;
      case VW_CHANNEL_UINT16:  return Isis::VALID_MINU2;
      default:                 return Isis::VALID_MIN1;
    }
  }
  double DiskImageResourceIsis::valid_maximum() const {
    switch (m_format.channel_type) {
      case VW_CHANNEL_FLOAT64: return Isis::ValidMaximum;
      case VW_CHANNEL_FLOAT32: return Isis::VALID_MAX4;
      case VW_CHANNEL_INT32:   return 2147483647;
      case VW_CHANNEL_INT16:   return Isis::VALID_MAX2;
      case VW_CHANNEL_UINT16:  return Isis::VALID_MAXU2;
      default:                 return Isis::VALID_MAX1;
    }
  }
  bool DiskImageResourceIsis::is_map_projected() const {
    // They used to have a HasProjection. I'm not sure if this fix is the correct method now.
    return m_cube->projection() != NULL;
  }
}
<|endoftext|>


<commit_before>/*
    SWARM

    Copyright (C) 2012-2019 Torbjorn Rognes and Frederic Mahe

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

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Contact: Torbjorn Rognes <torognes@ifi.uio.no>,
    Department of Informatics, University of Oslo,
    PO Box 1080 Blindern, NO-0316 Oslo, Norway
*/

#include "swarm.h"

uint64_t * zobrist_tab_base = nullptr;

void zobrist_init(unsigned int n)
{
  /*
    Generate 4n random 64-bit numbers. They will represent the four
    different bases in any position (1 to n) of a sequence.
    They will be XOR'ed together to form the hash of that sequence.
    The number n should be the length of the longest sequence to be
    hashed including potential additional insertions.

    The number is generated by xor'ing together four shifted
    31-bit random numbers.
  */

  zobrist_tab_base = static_cast<uint64_t *>(xmalloc(4 * n * sizeof(uint64_t));

  for (unsigned int i = 0; i < 4 * n; i++)
    {
      uint64_t z;
      z = arch_random();
      z <<= 16;
      z ^= arch_random();
      z <<= 16;
      z ^= arch_random();
      z <<= 16;
      z ^= arch_random();
      zobrist_tab_base[i] = z;
    }
}

void zobrist_exit()
{
  xfree(zobrist_tab_base);
}

uint64_t zobrist_hash(unsigned char * s, unsigned int len)
{
  /* compute the Zobrist hash function of sequence s of length len. */
  /* len is the actual number of bases in the sequence */
  /* it is encoded in (len+3)/4 bytes */

  uint64_t * q = reinterpret_cast<uint64_t *>(s);
  uint64_t x = 0;
  uint64_t z = 0;
  for(unsigned int p = 0; p < len; p++)
    {
      if ((p & 31) == 0)
        x = q[p / 32];
      else
        x >>= 2;
      z ^= zobrist_value(p, x & 3);
    }
  return z;
}

uint64_t zobrist_hash_delete_first(unsigned char * s, unsigned int len)
{
  /* compute the Zobrist hash function of sequence s,
     but delete the first base */

  uint64_t * q = reinterpret_cast<uint64_t *>(s);
  uint64_t x = q[0];
  uint64_t z = 0;
  for(unsigned int p = 1; p < len; p++)
    {
      if ((p & 31) == 0)
        x = q[p / 32];
      else
        x >>= 2;
      z ^= zobrist_value(p - 1, x & 3);
    }
  return z;
}

uint64_t zobrist_hash_insert_first(unsigned char * s, unsigned int len)
{
  /* compute the Zobrist hash function of sequence s,
     but insert a gap (no value) before the first base */

  uint64_t * q = reinterpret_cast<uint64_t *>(s);
  uint64_t x = 0;
  uint64_t z = 0;
  for(unsigned int p = 0; p < len; p++)
    {
      if ((p & 31) == 0)
        x = q[p / 32];
      else
        x >>= 2;
      z ^= zobrist_value(p + 1, x & 3);
    }
  return z;
}
<commit_msg>Fix typo in zobrist.cc<commit_after>/*
    SWARM

    Copyright (C) 2012-2019 Torbjorn Rognes and Frederic Mahe

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

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Contact: Torbjorn Rognes <torognes@ifi.uio.no>,
    Department of Informatics, University of Oslo,
    PO Box 1080 Blindern, NO-0316 Oslo, Norway
*/

#include "swarm.h"

uint64_t * zobrist_tab_base = nullptr;

void zobrist_init(unsigned int n)
{
  /*
    Generate 4n random 64-bit numbers. They will represent the four
    different bases in any position (1 to n) of a sequence.
    They will be XOR'ed together to form the hash of that sequence.
    The number n should be the length of the longest sequence to be
    hashed including potential additional insertions.

    The number is generated by xor'ing together four shifted
    31-bit random numbers.
  */

  zobrist_tab_base = static_cast<uint64_t *>
    (xmalloc(4 * n * sizeof(uint64_t)));

  for (unsigned int i = 0; i < 4 * n; i++)
    {
      uint64_t z;
      z = arch_random();
      z <<= 16;
      z ^= arch_random();
      z <<= 16;
      z ^= arch_random();
      z <<= 16;
      z ^= arch_random();
      zobrist_tab_base[i] = z;
    }
}

void zobrist_exit()
{
  xfree(zobrist_tab_base);
}

uint64_t zobrist_hash(unsigned char * s, unsigned int len)
{
  /* compute the Zobrist hash function of sequence s of length len. */
  /* len is the actual number of bases in the sequence */
  /* it is encoded in (len+3)/4 bytes */

  uint64_t * q = reinterpret_cast<uint64_t *>(s);
  uint64_t x = 0;
  uint64_t z = 0;
  for(unsigned int p = 0; p < len; p++)
    {
      if ((p & 31) == 0)
        x = q[p / 32];
      else
        x >>= 2;
      z ^= zobrist_value(p, x & 3);
    }
  return z;
}

uint64_t zobrist_hash_delete_first(unsigned char * s, unsigned int len)
{
  /* compute the Zobrist hash function of sequence s,
     but delete the first base */

  uint64_t * q = reinterpret_cast<uint64_t *>(s);
  uint64_t x = q[0];
  uint64_t z = 0;
  for(unsigned int p = 1; p < len; p++)
    {
      if ((p & 31) == 0)
        x = q[p / 32];
      else
        x >>= 2;
      z ^= zobrist_value(p - 1, x & 3);
    }
  return z;
}

uint64_t zobrist_hash_insert_first(unsigned char * s, unsigned int len)
{
  /* compute the Zobrist hash function of sequence s,
     but insert a gap (no value) before the first base */

  uint64_t * q = reinterpret_cast<uint64_t *>(s);
  uint64_t x = 0;
  uint64_t z = 0;
  for(unsigned int p = 0; p < len; p++)
    {
      if ((p & 31) == 0)
        x = q[p / 32];
      else
        x >>= 2;
      z ^= zobrist_value(p + 1, x & 3);
    }
  return z;
}
<|endoftext|>