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

#include "flutter/flow/raster_cache.h"

#include <vector>

#include "flutter/common/threads.h"
#include "flutter/flow/paint_utils.h"
#include "flutter/glue/trace_event.h"
#include "lib/ftl/logging.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkSurface.h"

namespace flow {

RasterCache::RasterCache(size_t threshold)
    : threshold_(threshold), checkerboard_images_(false), weak_factory_(this) {}

RasterCache::~RasterCache() = default;

static bool CanRasterizePicture(SkPicture* picture) {
  if (picture == nullptr) {
    return false;
  }

  const SkRect cull_rect = picture->cullRect();

  if (cull_rect.isEmpty()) {
    // No point in ever rasterizing an empty picture.
    return false;
  }

  if (!cull_rect.isFinite()) {
    // Cannot attempt to rasterize into an infinitely large surface.
    return false;
  }

  return true;
}

static bool IsPictureWorthRasterizing(SkPicture* picture,
                                      bool will_change,
                                      bool is_complex) {
  if (will_change) {
    // If the picture is going to change in the future, there is no point in
    // doing to extra work to rasterize.
    return false;
  }

  if (!CanRasterizePicture(picture)) {
    // No point in deciding whether the picture is worth rasterizing if it
    // cannot be rasterized at all.
    return false;
  }

  if (is_complex) {
    // The caller seems to have extra information about the picture and thinks
    // the picture is always worth rasterizing.
    return true;
  }

  // TODO(abarth): We should find a better heuristic here that lets us avoid
  // wasting memory on trivial layers that are easy to re-rasterize every frame.
  return picture->approximateOpCount() > 10;
}

RasterCacheResult RasterizePicture(SkPicture* picture,
                                   GrContext* context,
                                   const MatrixDecomposition& matrix,
                                   bool checkerboard) {
  TRACE_EVENT0("flutter", "RasterCachePopulate");

  const SkVector3& scale = matrix.scale();

  const SkRect logical_rect = picture->cullRect();
  const SkRect physical_rect =
      SkRect::MakeWH(std::ceil(std::labs(logical_rect.width() * scale.x())),
                     std::ceil(std::labs(logical_rect.height() * scale.y())));

  const SkImageInfo image_info =
      SkImageInfo::MakeN32Premul(physical_rect.width(),   // physical width
                                 physical_rect.height(),  // physical height
                                 nullptr                  // colorspace
                                 );

  sk_sp<SkSurface> surface =
      context
          ? SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, image_info)
          : SkSurface::MakeRaster(image_info);

  if (!surface) {
    FTL_DCHECK(false);
    return {};
  }

  SkCanvas* canvas = surface->getCanvas();

  canvas->clear(SK_ColorTRANSPARENT);
  canvas->scale(std::abs(scale.x()), std::abs(scale.y()));
  canvas->translate(-logical_rect.left(), -logical_rect.top());
  canvas->drawPicture(picture);

  if (checkerboard) {
    DrawCheckerboard(canvas, logical_rect);
  }

  return {
      surface->makeImageSnapshot(),  // image
      physical_rect,                 // source rect
      logical_rect                   // destination rect
  };
}

static inline size_t ClampSize(size_t value, size_t min, size_t max) {
  if (value > max) {
    return max;
  }

  if (value < min) {
    return min;
  }

  return value;
}

RasterCacheResult RasterCache::GetPrerolledImage(
    GrContext* context,
    SkPicture* picture,
    const SkMatrix& transformation_matrix,
    bool is_complex,
    bool will_change) {
  if (!IsPictureWorthRasterizing(picture, will_change, is_complex)) {
    // We only deal with pictures that are worthy of rasterization.
    return {};
  }

  // Decompose the matrix (once) for all subsequent operations. We want to make
  // sure to avoid volumetric distortions while accounting for scaling.
  const MatrixDecomposition matrix(transformation_matrix);

  if (!matrix.IsValid()) {
    // The matrix was singular. No point in going further.
    return {};
  }

  RasterCacheKey cache_key(*picture, matrix);

  Entry& entry = cache_[cache_key];
  entry.access_count = ClampSize(entry.access_count + 1, 0, threshold_);
  entry.used_this_frame = true;

  if (entry.access_count < threshold_ || threshold_ == 0) {
    // Frame threshold has not yet been reached.
    return {};
  }

  if (!entry.image.is_valid()) {
    entry.image =
        RasterizePicture(picture, context, matrix, checkerboard_images_);
  }

  // We are not considering unrasterizable images. So if we don't have an image
  // by now, we know that rasterization itself failed.
  FTL_DCHECK(entry.image.is_valid());

  return entry.image;
}

void RasterCache::SweepAfterFrame() {
  std::vector<RasterCacheKey::Map<Entry>::iterator> dead;

  for (auto it = cache_.begin(); it != cache_.end(); ++it) {
    Entry& entry = it->second;
    if (!entry.used_this_frame) {
      dead.push_back(it);
    }
    entry.used_this_frame = false;
  }

  for (auto it : dead) {
    cache_.erase(it);
  }
}

void RasterCache::Clear() {
  cache_.clear();
}

void RasterCache::SetCheckboardCacheImages(bool checkerboard) {
  if (checkerboard_images_ == checkerboard) {
    return;
  }

  checkerboard_images_ = checkerboard;

  // Clear all existing entries so previously rasterized items (with or without
  // a checkerboard) will be refreshed in subsequent passes.
  Clear();
}

}  // namespace flow
<commit_msg>Fix usage of std::labs (#3891)<commit_after>// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/flow/raster_cache.h"

#include <vector>

#include "flutter/common/threads.h"
#include "flutter/flow/paint_utils.h"
#include "flutter/glue/trace_event.h"
#include "lib/ftl/logging.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkSurface.h"

namespace flow {

RasterCache::RasterCache(size_t threshold)
    : threshold_(threshold), checkerboard_images_(false), weak_factory_(this) {}

RasterCache::~RasterCache() = default;

static bool CanRasterizePicture(SkPicture* picture) {
  if (picture == nullptr) {
    return false;
  }

  const SkRect cull_rect = picture->cullRect();

  if (cull_rect.isEmpty()) {
    // No point in ever rasterizing an empty picture.
    return false;
  }

  if (!cull_rect.isFinite()) {
    // Cannot attempt to rasterize into an infinitely large surface.
    return false;
  }

  return true;
}

static bool IsPictureWorthRasterizing(SkPicture* picture,
                                      bool will_change,
                                      bool is_complex) {
  if (will_change) {
    // If the picture is going to change in the future, there is no point in
    // doing to extra work to rasterize.
    return false;
  }

  if (!CanRasterizePicture(picture)) {
    // No point in deciding whether the picture is worth rasterizing if it
    // cannot be rasterized at all.
    return false;
  }

  if (is_complex) {
    // The caller seems to have extra information about the picture and thinks
    // the picture is always worth rasterizing.
    return true;
  }

  // TODO(abarth): We should find a better heuristic here that lets us avoid
  // wasting memory on trivial layers that are easy to re-rasterize every frame.
  return picture->approximateOpCount() > 10;
}

RasterCacheResult RasterizePicture(SkPicture* picture,
                                   GrContext* context,
                                   const MatrixDecomposition& matrix,
                                   bool checkerboard) {
  TRACE_EVENT0("flutter", "RasterCachePopulate");

  const SkVector3& scale = matrix.scale();

  const SkRect logical_rect = picture->cullRect();
  const SkRect physical_rect =
      SkRect::MakeWH(std::ceil(std::fabs(logical_rect.width() * scale.x())),
                     std::ceil(std::fabs(logical_rect.height() * scale.y())));

  const SkImageInfo image_info =
      SkImageInfo::MakeN32Premul(physical_rect.width(),   // physical width
                                 physical_rect.height(),  // physical height
                                 nullptr                  // colorspace
                                 );

  sk_sp<SkSurface> surface =
      context
          ? SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, image_info)
          : SkSurface::MakeRaster(image_info);

  if (!surface) {
    FTL_DCHECK(false);
    return {};
  }

  SkCanvas* canvas = surface->getCanvas();

  canvas->clear(SK_ColorTRANSPARENT);
  canvas->scale(std::abs(scale.x()), std::abs(scale.y()));
  canvas->translate(-logical_rect.left(), -logical_rect.top());
  canvas->drawPicture(picture);

  if (checkerboard) {
    DrawCheckerboard(canvas, logical_rect);
  }

  return {
      surface->makeImageSnapshot(),  // image
      physical_rect,                 // source rect
      logical_rect                   // destination rect
  };
}

static inline size_t ClampSize(size_t value, size_t min, size_t max) {
  if (value > max) {
    return max;
  }

  if (value < min) {
    return min;
  }

  return value;
}

RasterCacheResult RasterCache::GetPrerolledImage(
    GrContext* context,
    SkPicture* picture,
    const SkMatrix& transformation_matrix,
    bool is_complex,
    bool will_change) {
  if (!IsPictureWorthRasterizing(picture, will_change, is_complex)) {
    // We only deal with pictures that are worthy of rasterization.
    return {};
  }

  // Decompose the matrix (once) for all subsequent operations. We want to make
  // sure to avoid volumetric distortions while accounting for scaling.
  const MatrixDecomposition matrix(transformation_matrix);

  if (!matrix.IsValid()) {
    // The matrix was singular. No point in going further.
    return {};
  }

  RasterCacheKey cache_key(*picture, matrix);

  Entry& entry = cache_[cache_key];
  entry.access_count = ClampSize(entry.access_count + 1, 0, threshold_);
  entry.used_this_frame = true;

  if (entry.access_count < threshold_ || threshold_ == 0) {
    // Frame threshold has not yet been reached.
    return {};
  }

  if (!entry.image.is_valid()) {
    entry.image =
        RasterizePicture(picture, context, matrix, checkerboard_images_);
  }

  // We are not considering unrasterizable images. So if we don't have an image
  // by now, we know that rasterization itself failed.
  FTL_DCHECK(entry.image.is_valid());

  return entry.image;
}

void RasterCache::SweepAfterFrame() {
  std::vector<RasterCacheKey::Map<Entry>::iterator> dead;

  for (auto it = cache_.begin(); it != cache_.end(); ++it) {
    Entry& entry = it->second;
    if (!entry.used_this_frame) {
      dead.push_back(it);
    }
    entry.used_this_frame = false;
  }

  for (auto it : dead) {
    cache_.erase(it);
  }
}

void RasterCache::Clear() {
  cache_.clear();
}

void RasterCache::SetCheckboardCacheImages(bool checkerboard) {
  if (checkerboard_images_ == checkerboard) {
    return;
  }

  checkerboard_images_ = checkerboard;

  // Clear all existing entries so previously rasterized items (with or without
  // a checkerboard) will be refreshed in subsequent passes.
  Clear();
}

}  // namespace flow
<|endoftext|>


<commit_before><commit_msg>sd/source/ui/dlg/dlgolbul.cxx comment translation and cleanup<commit_after><|endoftext|>


<commit_before>#include "SDL2/Sdl2Window.h"

#include <iostream>
#include <string>

#include <SDL2/SDL.h>
#include <GL/glew.h>

#include "GUI/AllWidgets.h"
#include "SDL2/SdlMouse.h"

using namespace std;

namespace Core
{

bool Sdl2Window::mGlewInit = false;

Sdl2Window::Sdl2Window(const string& title, uint width, uint height)
    : mTitle(title),
      mVisible(false),
      mWindow(nullptr)
{
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);

    mWindow = SDL_CreateWindow
    (
            title.c_str(),
            SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
            width, height,
            SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
    );

    mContext = SDL_GL_CreateContext(mWindow);

    GUInterface::RootWidget* root = new GUInterface::RootWidget(0,0,0,0);//GetWidth(),GetHeight());
    mEnv = new GUInterface::Environment(root);
    mMouse = new SdlMouse();

    const char* version = (const char*)glGetString(GL_VERSION);
//    std::cout << version << std::endl;
    delete[] version;

    version = (const char*)glGetString(GL_RENDERER);
//    std::cout << version << std::endl;
    delete[] version;
}

Sdl2Window::~Sdl2Window()
{
    SDL_GL_DeleteContext(mContext);
    SDL_DestroyWindow(mWindow);
    mWindow = NULL;
}

void Sdl2Window::SetTitle(const std::string& title)
{
    // TODO
}

void Sdl2Window::SetSize(uint width, uint height)
{
    // TODO
}

void Sdl2Window::PollEvents()
{
	SDL_Event e;

	mMouse->SetClicks(0,0,0);
	mMouse->SetRelativePosition(0,0);

    while (SDL_PollEvent(&e))
    {
        if (e.type == SDL_QUIT)
        {
            SetVisible(false);
        }
        else if(e.type == SDL_MOUSEBUTTONUP)
        {
        	std::cout << "\n*********Click*********\n";
        	int32 button = (int)e.button.button;
        	int32 x = e.button.x;
        	int32 y = GetHeight() - e.button.y - 1;
        	int32 clicks = (int)e.button.clicks;

        	//std::cout << "X: " << x << ", Y: " << y << std::endl;
        	mMouse->SetPosition(x,y);

        	if(button == 1) mMouse->SetLeftClicks(clicks);
        	else if(button == 2) mMouse->SetMiddleClicks(clicks);
        	else mMouse->SetRightClicks(clicks);

        	mEnv->OnMouseButton(x,y,button,true);
        }
        else if(e.type == SDL_MOUSEMOTION)
        {
        	int32 x = e.motion.x;
        	int32 y = GetHeight() - e.motion.y - 1;
        	int32 xRel = e.motion.xrel;
        	int32 yRel = e.motion.yrel;

        	mMouse->SetPosition(x,y);
        	mMouse->SetRelativePosition(xRel,yRel);
        }
    }

}

void Sdl2Window::SwapBuffers()
{
    SDL_GL_SwapWindow(mWindow);
    int width, height;
    SDL_GetWindowSize(mWindow, &width, &height);
    glViewport(0, 0, width, height);

}

void Sdl2Window::SetVisible(bool visible)
{
    if (mVisible == visible) return;

    mVisible = visible;
    if (mVisible)
    {
        SDL_ShowWindow(mWindow);
        InitGlew();
    }
    else
    {
        SDL_HideWindow(mWindow);
    }
}

void Sdl2Window::InitGlew()
{
    if (mGlewInit) return;

    mGlewInit = true;

    glewExperimental = GL_TRUE;
    glewInit();
}

SdlMouse* Sdl2Window::GetMouse()
{
	return mMouse;
}

GUInterface::Environment* Sdl2Window::GetEnvironment()
{
	return mEnv;
}

}
<commit_msg>Remove invalid delete[]s<commit_after>#include "SDL2/Sdl2Window.h"

#include <iostream>
#include <string>

#include <SDL2/SDL.h>
#include <GL/glew.h>

#include "GUI/AllWidgets.h"
#include "SDL2/SdlMouse.h"

using namespace std;

namespace Core
{

bool Sdl2Window::mGlewInit = false;

Sdl2Window::Sdl2Window(const string& title, uint width, uint height)
    : mTitle(title),
      mVisible(false),
      mWindow(nullptr)
{
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);

    mWindow = SDL_CreateWindow
    (
            title.c_str(),
            SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
            width, height,
            SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
    );

    mContext = SDL_GL_CreateContext(mWindow);

    GUInterface::RootWidget* root = new GUInterface::RootWidget(0,0,0,0);//GetWidth(),GetHeight());
    mEnv = new GUInterface::Environment(root);
    mMouse = new SdlMouse();

    const char* version = (const char*)glGetString(GL_VERSION);
//    std::cout << version << std::endl;
//    delete[] version;

    version = (const char*)glGetString(GL_RENDERER);
//    std::cout << version << std::endl;
//    delete[] version;
}

Sdl2Window::~Sdl2Window()
{
    SDL_GL_DeleteContext(mContext);
    SDL_DestroyWindow(mWindow);
    mWindow = NULL;
}

void Sdl2Window::SetTitle(const std::string& title)
{
    // TODO
}

void Sdl2Window::SetSize(uint width, uint height)
{
    // TODO
}

void Sdl2Window::PollEvents()
{
	SDL_Event e;

	mMouse->SetClicks(0,0,0);
	mMouse->SetRelativePosition(0,0);

    while (SDL_PollEvent(&e))
    {
        if (e.type == SDL_QUIT)
        {
            SetVisible(false);
        }
        else if(e.type == SDL_MOUSEBUTTONUP)
        {
        	std::cout << "\n*********Click*********\n";
        	int32 button = (int)e.button.button;
        	int32 x = e.button.x;
        	int32 y = GetHeight() - e.button.y - 1;
        	int32 clicks = (int)e.button.clicks;

        	//std::cout << "X: " << x << ", Y: " << y << std::endl;
        	mMouse->SetPosition(x,y);

        	if(button == 1) mMouse->SetLeftClicks(clicks);
        	else if(button == 2) mMouse->SetMiddleClicks(clicks);
        	else mMouse->SetRightClicks(clicks);

        	mEnv->OnMouseButton(x,y,button,true);
        }
        else if(e.type == SDL_MOUSEMOTION)
        {
        	int32 x = e.motion.x;
        	int32 y = GetHeight() - e.motion.y - 1;
        	int32 xRel = e.motion.xrel;
        	int32 yRel = e.motion.yrel;

        	mMouse->SetPosition(x,y);
        	mMouse->SetRelativePosition(xRel,yRel);
        }
    }

}

void Sdl2Window::SwapBuffers()
{
    SDL_GL_SwapWindow(mWindow);
    int width, height;
    SDL_GetWindowSize(mWindow, &width, &height);
    glViewport(0, 0, width, height);

}

void Sdl2Window::SetVisible(bool visible)
{
    if (mVisible == visible) return;

    mVisible = visible;
    if (mVisible)
    {
        SDL_ShowWindow(mWindow);
        InitGlew();
    }
    else
    {
        SDL_HideWindow(mWindow);
    }
}

void Sdl2Window::InitGlew()
{
    if (mGlewInit) return;

    mGlewInit = true;

    glewExperimental = GL_TRUE;
    glewInit();
}

SdlMouse* Sdl2Window::GetMouse()
{
	return mMouse;
}

GUInterface::Environment* Sdl2Window::GetEnvironment()
{
	return mEnv;
}

}
<|endoftext|>


<commit_before><commit_msg>use snap rectangle instead of logic rectangle<commit_after><|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2018.  All rights reserved
 */
#include "../../../StroikaPreComp.h"

#include "../../../Characters/FloatConversion.h"
#include "../../../Characters/StringBuilder.h"
#include "../../../Characters/String_Constant.h"
#include "../../../Streams/TextWriter.h"

#include "Writer.h"

using namespace Stroika::Foundation;
using namespace Stroika::Foundation::DataExchange;
using namespace Stroika::Foundation::Streams;

using Characters::Character;
using Characters::String_Constant;
using Memory::Byte;

/*
 * TODO:
 *      No known issues
 */

namespace {
    // Just like Writer::Options but without opionals... fill those in
    struct Options_ {
        Options_ (const Variant::JSON::Writer::Options& o)
            : fFloatOptions{o.fFloatOptions.Value ()}
            , fJSONPrettyPrint (o.fJSONPrettyPrint.Value (true))
            , fSpacesPerIndent{o.fSpacesPerIndent.Value (4)}
            , fAllowNANInf{o.fAllowNANInf.Value (true)}
        {
            if (not fJSONPrettyPrint) {
                fSpacesPerIndent = 0;
            }
            if (fSpacesPerIndent != 0) {
                fIndentSpace = String_Constant{L" "}.Repeat (fSpacesPerIndent);
            }
        }
        Characters::Float2StringOptions fFloatOptions;
        bool                            fJSONPrettyPrint;
        unsigned int                    fSpacesPerIndent;
        String                          fIndentSpace;
        bool                            fAllowNANInf;
    };
}

/*
 ********************************************************************************
 ********************* DataExchange::JSON::PrettyPrint **************************
 ********************************************************************************
 */
namespace {
    void Indent_ (const Options_& options, const OutputStream<Character>::Ptr& out, int indentLevel)
    {
        // if test not needed, but speed tweak (especially since incorporates options.fJSONPrettyPrint check
        if (options.fSpacesPerIndent != 0) {
            out.Write (options.fIndentSpace.Repeat (indentLevel));
        }
    }
}
namespace {
    void PrettyPrint_ (const Options_& options, const VariantValue& v, const OutputStream<Character>::Ptr& out, int indentLevel);
    void PrettyPrint_Null_ (const Options_& options, const OutputStream<Character>::Ptr& out)
    {
        out.Write (L"null");
    }
    void PrettyPrint_ (const Options_& options, bool v, const OutputStream<Character>::Ptr& out)
    {
        if (v) {
            out.Write (L"true");
        }
        else {
            out.Write (L"false");
        }
    }
    void PrettyPrint_ (const Options_& options, long long int v, const OutputStream<Character>::Ptr& out)
    {
        wchar_t buf[1024];
        (void)::swprintf (buf, NEltsOf (buf), L"%lld", v);
        out.Write (buf);
    }
    void PrettyPrint_ (const Options_& options, unsigned long long int v, const OutputStream<Character>::Ptr& out)
    {
        wchar_t buf[1024];
        (void)::swprintf (buf, NEltsOf (buf), L"%llu", v);
        out.Write (buf);
    }
    void PrettyPrint_ (const Options_& options, const String& v, const OutputStream<Character>::Ptr& out);
    void PrettyPrint_ (const Options_& options, long double v, const OutputStream<Character>::Ptr& out)
    {
        String tmp{Characters::Float2String (v, options.fFloatOptions)};
        if (isnan (v) or isinf (v)) {
            Require (options.fAllowNANInf);
            PrettyPrint_ (options, tmp, out);
        }
        else {
            out.Write (tmp);
        }
    }
    template <typename CHARITERATOR>
    void PrettyPrint_ (const Options_& options, CHARITERATOR start, CHARITERATOR end, const OutputStream<Character>::Ptr& out)
    {
        // A backslash can be followed by "\/bfnrtu (@ see http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf)
        Characters::StringBuilder sb;
        sb.Append (L"\"");
        for (auto i = start; i != end; ++i) {
            switch (*i) {
                case '\"':
                    sb.Append (L"\\\"");
                    break;
                case '\b':
                    sb.Append (L"\\b");
                    break;
                case '\f':
                    sb.Append (L"\\f");
                    break;
                case '\n':
                    sb.Append (L"\\n");
                    break;
                case '\r':
                    sb.Append (L"\\r");
                    break;
                case '\t':
                    sb.Append (L"\\t");
                    break;
                case '\\':
                    sb.Append (L"\\\\");
                    break;
                default:
                    // JSON rule is Any code point except " or \ or control character. So OK to emit most large unicode chars - just not control chars
                    wchar_t c = *i;
                    if (std::iswcntrl (c)) {
                        wchar_t buf[10];
                        (void)::swprintf (buf, NEltsOf (buf), L"\\u%04x", static_cast<char16_t> (c));
                        sb.Append (buf);
                    }
                    else {
                        sb.Append (&c, &c + 1);
                    }
                    break;
            }
        }
        sb.Append (L"\"");
        out.Write (sb.begin (), sb.end ());
    }
    void PrettyPrint_ (const Options_& options, const wstring& v, const OutputStream<Character>::Ptr& out)
    {
        PrettyPrint_ (options, v.begin (), v.end (), out);
    }
    void PrettyPrint_ (const Options_& options, const String& v, const OutputStream<Character>::Ptr& out)
    {
        pair<const wchar_t*, const wchar_t*> p = v.GetData<wchar_t> ();
        static_assert (sizeof (Character) == sizeof (wchar_t), "sizeof(Character) == sizeof(wchar_t)");
        PrettyPrint_ (options, p.first, p.second, out);
    }
    void PrettyPrint_ (const Options_& options, const vector<VariantValue>& v, const OutputStream<Character>::Ptr& out, int indentLevel)
    {
        out.Write (options.fJSONPrettyPrint ? L"[\n" : L"[");
        for (auto i = v.begin (); i != v.end (); ++i) {
            Indent_ (options, out, indentLevel + 1);
            PrettyPrint_ (options, *i, out, indentLevel + 1);
            if (i + 1 != v.end ()) {
                out.Write (L",");
            }
            if (options.fJSONPrettyPrint) {
                out.Write (L"\n");
            }
        }
        Indent_ (options, out, indentLevel);
        out.Write (L"]");
    }
    void PrettyPrint_ (const Options_& options, const Mapping<String, VariantValue>& v, const OutputStream<Character>::Ptr& out, int indentLevel)
    {
        out.Write (options.fJSONPrettyPrint ? L"{\n" : L"{");
        for (auto i = v.begin (); i != v.end ();) {
            Indent_ (options, out, indentLevel + 1);
            PrettyPrint_ (options, i->fKey, out, indentLevel + 1);
            out.Write (L" : ");
            PrettyPrint_ (options, i->fValue, out, indentLevel + 1);
            ++i;
            if (i != v.end ()) {
                out.Write (L",");
            }
            if (options.fJSONPrettyPrint) {
                out.Write (L"\n");
            }
        }
        Indent_ (options, out, indentLevel);
        out.Write (L"}");
    }
    void PrettyPrint_ (const Options_& options, const VariantValue& v, const OutputStream<Character>::Ptr& out, int indentLevel)
    {
        switch (v.GetType ()) {
            case VariantValue::eNull:
                PrettyPrint_Null_ (options, out);
                break;
            case VariantValue::eBoolean:
                PrettyPrint_ (options, v.As<bool> (), out);
                break;
            case VariantValue::eBLOB:
                PrettyPrint_ (options, v.As<String> (), out);
                break;
            case VariantValue::eDate:
                PrettyPrint_ (options, v.As<wstring> (), out);
                break;
            case VariantValue::eDateTime:
                PrettyPrint_ (options, v.As<wstring> (), out);
                break;
            case VariantValue::eInteger:
                PrettyPrint_ (options, v.As<long long int> (), out);
                break;
            case VariantValue::eUnsignedInteger:
                PrettyPrint_ (options, v.As<unsigned long long int> (), out);
                break;
            case VariantValue::eFloat:
                PrettyPrint_ (options, v.As<long double> (), out);
                break;
            case VariantValue::eString:
                PrettyPrint_ (options, v.As<wstring> (), out);
                break;
            case VariantValue::eMap:
                PrettyPrint_ (options, v.As<Mapping<String, VariantValue>> (), out, indentLevel);
                break;
            case VariantValue::eArray:
                PrettyPrint_ (options, v.As<vector<VariantValue>> (), out, indentLevel);
                break;
            default:
                RequireNotReached (); // only certain types allowed
        }
    }
}

/*
 ********************************************************************************
 ************************** DataExchange::JSON::Writer **************************
 ********************************************************************************
 */
class Variant::JSON::Writer::Rep_ : public Variant::Writer::_IRep {
public:
    Options_ fOptions_;
    Rep_ (const Options& options)
        : fOptions_ (options)
    {
    }
    Rep_ (const Options_& options)
        : fOptions_ (options)
    {
    }
    virtual _SharedPtrIRep Clone () const override
    {
        return make_shared<Rep_> (fOptions_); // no instance data
    }
    virtual String GetDefaultFileSuffix () const override
    {
        return String_Constant (L".json");
    }
    virtual void Write (const VariantValue& v, const Streams::OutputStream<Byte>::Ptr& out) override
    {
        TextWriter::Ptr textOut = TextWriter::New (out, TextWriter::Format::eUTF8WithoutBOM);
        PrettyPrint_ (fOptions_, v, textOut, 0);
        if (fOptions_.fJSONPrettyPrint) {
            textOut.Write (L"\n"); // a single elt not LF terminated, but the entire doc should be.
        }
    }
    virtual void Write (const VariantValue& v, const Streams::OutputStream<Character>::Ptr& out) override
    {
        PrettyPrint_ (fOptions_, v, out, 0);
    }
};

Variant::JSON::Writer::Writer (const Options& options)
    : inherited (make_shared<Rep_> (options))
{
}
<commit_msg>JSONWriter - refactor a bunch of cases that write string to go through same case<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2018.  All rights reserved
 */
#include "../../../StroikaPreComp.h"

#include "../../../Characters/FloatConversion.h"
#include "../../../Characters/StringBuilder.h"
#include "../../../Characters/String_Constant.h"
#include "../../../Streams/TextWriter.h"

#include "Writer.h"

using namespace Stroika::Foundation;
using namespace Stroika::Foundation::DataExchange;
using namespace Stroika::Foundation::Streams;

using Characters::Character;
using Characters::String_Constant;
using Memory::Byte;

/*
 * TODO:
 *      No known issues
 */

namespace {
    // Just like Writer::Options but without opionals... fill those in
    struct Options_ {
        Options_ (const Variant::JSON::Writer::Options& o)
            : fFloatOptions{o.fFloatOptions.Value ()}
            , fJSONPrettyPrint (o.fJSONPrettyPrint.Value (true))
            , fSpacesPerIndent{o.fSpacesPerIndent.Value (4)}
            , fAllowNANInf{o.fAllowNANInf.Value (true)}
        {
            if (not fJSONPrettyPrint) {
                fSpacesPerIndent = 0;
            }
            if (fSpacesPerIndent != 0) {
                fIndentSpace = String_Constant{L" "}.Repeat (fSpacesPerIndent);
            }
        }
        Characters::Float2StringOptions fFloatOptions;
        bool                            fJSONPrettyPrint;
        unsigned int                    fSpacesPerIndent;
        String                          fIndentSpace;
        bool                            fAllowNANInf;
    };
}

/*
 ********************************************************************************
 ********************* DataExchange::JSON::PrettyPrint **************************
 ********************************************************************************
 */
namespace {
    void Indent_ (const Options_& options, const OutputStream<Character>::Ptr& out, int indentLevel)
    {
        // if test not needed, but speed tweak (especially since incorporates options.fJSONPrettyPrint check
        if (options.fSpacesPerIndent != 0) {
            out.Write (options.fIndentSpace.Repeat (indentLevel));
        }
    }
}
namespace {
    void PrettyPrint_ (const Options_& options, const VariantValue& v, const OutputStream<Character>::Ptr& out, int indentLevel);
    void PrettyPrint_Null_ (const Options_& options, const OutputStream<Character>::Ptr& out)
    {
        out.Write (L"null");
    }
    void PrettyPrint_ (const Options_& options, bool v, const OutputStream<Character>::Ptr& out)
    {
        if (v) {
            out.Write (L"true");
        }
        else {
            out.Write (L"false");
        }
    }
    void PrettyPrint_ (const Options_& options, long long int v, const OutputStream<Character>::Ptr& out)
    {
        wchar_t buf[1024];
        (void)::swprintf (buf, NEltsOf (buf), L"%lld", v);
        out.Write (buf);
    }
    void PrettyPrint_ (const Options_& options, unsigned long long int v, const OutputStream<Character>::Ptr& out)
    {
        wchar_t buf[1024];
        (void)::swprintf (buf, NEltsOf (buf), L"%llu", v);
        out.Write (buf);
    }
    void PrettyPrint_ (const Options_& options, const String& v, const OutputStream<Character>::Ptr& out);
    void PrettyPrint_ (const Options_& options, long double v, const OutputStream<Character>::Ptr& out)
    {
        String tmp{Characters::Float2String (v, options.fFloatOptions)};
        if (isnan (v) or isinf (v)) {
            Require (options.fAllowNANInf);
            PrettyPrint_ (options, tmp, out);
        }
        else {
            out.Write (tmp);
        }
    }
    template <typename CHARITERATOR>
    void PrettyPrint_ (const Options_& options, CHARITERATOR start, CHARITERATOR end, const OutputStream<Character>::Ptr& out)
    {
        // A backslash can be followed by "\/bfnrtu (@ see http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf)
        Characters::StringBuilder sb;
        sb.Append (L"\"");
        for (auto i = start; i != end; ++i) {
            switch (*i) {
                case '\"':
                    sb.Append (L"\\\"");
                    break;
                case '\b':
                    sb.Append (L"\\b");
                    break;
                case '\f':
                    sb.Append (L"\\f");
                    break;
                case '\n':
                    sb.Append (L"\\n");
                    break;
                case '\r':
                    sb.Append (L"\\r");
                    break;
                case '\t':
                    sb.Append (L"\\t");
                    break;
                case '\\':
                    sb.Append (L"\\\\");
                    break;
                default:
                    // JSON rule is Any code point except " or \ or control character. So OK to emit most large unicode chars - just not control chars
                    wchar_t c = *i;
                    if (std::iswcntrl (c)) {
                        wchar_t buf[10];
                        (void)::swprintf (buf, NEltsOf (buf), L"\\u%04x", static_cast<char16_t> (c));
                        sb.Append (buf);
                    }
                    else {
                        sb.Append (&c, &c + 1);
                    }
                    break;
            }
        }
        sb.Append (L"\"");
        out.Write (sb.begin (), sb.end ());
    }
    void PrettyPrint_ (const Options_& options, const wstring& v, const OutputStream<Character>::Ptr& out)
    {
        PrettyPrint_ (options, v.begin (), v.end (), out);
    }
    void PrettyPrint_ (const Options_& options, const String& v, const OutputStream<Character>::Ptr& out)
    {
        pair<const wchar_t*, const wchar_t*> p = v.GetData<wchar_t> ();
        static_assert (sizeof (Character) == sizeof (wchar_t), "sizeof(Character) == sizeof(wchar_t)");
        PrettyPrint_ (options, p.first, p.second, out);
    }
    void PrettyPrint_ (const Options_& options, const vector<VariantValue>& v, const OutputStream<Character>::Ptr& out, int indentLevel)
    {
        out.Write (options.fJSONPrettyPrint ? L"[\n" : L"[");
        for (auto i = v.begin (); i != v.end (); ++i) {
            Indent_ (options, out, indentLevel + 1);
            PrettyPrint_ (options, *i, out, indentLevel + 1);
            if (i + 1 != v.end ()) {
                out.Write (L",");
            }
            if (options.fJSONPrettyPrint) {
                out.Write (L"\n");
            }
        }
        Indent_ (options, out, indentLevel);
        out.Write (L"]");
    }
    void PrettyPrint_ (const Options_& options, const Mapping<String, VariantValue>& v, const OutputStream<Character>::Ptr& out, int indentLevel)
    {
        out.Write (options.fJSONPrettyPrint ? L"{\n" : L"{");
        for (auto i = v.begin (); i != v.end ();) {
            Indent_ (options, out, indentLevel + 1);
            PrettyPrint_ (options, i->fKey, out, indentLevel + 1);
            out.Write (L" : ");
            PrettyPrint_ (options, i->fValue, out, indentLevel + 1);
            ++i;
            if (i != v.end ()) {
                out.Write (L",");
            }
            if (options.fJSONPrettyPrint) {
                out.Write (L"\n");
            }
        }
        Indent_ (options, out, indentLevel);
        out.Write (L"}");
    }
    void PrettyPrint_ (const Options_& options, const VariantValue& v, const OutputStream<Character>::Ptr& out, int indentLevel)
    {
        switch (v.GetType ()) {
            case VariantValue::eNull:
                PrettyPrint_Null_ (options, out);
                break;
            case VariantValue::eBoolean:
                PrettyPrint_ (options, v.As<bool> (), out);
                break;
            case VariantValue::eInteger:
                PrettyPrint_ (options, v.As<long long int> (), out);
                break;
            case VariantValue::eUnsignedInteger:
                PrettyPrint_ (options, v.As<unsigned long long int> (), out);
                break;
            case VariantValue::eFloat:
                PrettyPrint_ (options, v.As<long double> (), out);
                break;
            case VariantValue::eMap:
                PrettyPrint_ (options, v.As<Mapping<String, VariantValue>> (), out, indentLevel);
                break;
            case VariantValue::eArray:
                PrettyPrint_ (options, v.As<vector<VariantValue>> (), out, indentLevel);
                break;
            default:
                PrettyPrint_ (options, v.As<String> (), out);
        }
    }
}

/*
 ********************************************************************************
 ************************** DataExchange::JSON::Writer **************************
 ********************************************************************************
 */
class Variant::JSON::Writer::Rep_ : public Variant::Writer::_IRep {
public:
    Options_ fOptions_;
    Rep_ (const Options& options)
        : fOptions_ (options)
    {
    }
    Rep_ (const Options_& options)
        : fOptions_ (options)
    {
    }
    virtual _SharedPtrIRep Clone () const override
    {
        return make_shared<Rep_> (fOptions_); // no instance data
    }
    virtual String GetDefaultFileSuffix () const override
    {
        return String_Constant (L".json");
    }
    virtual void Write (const VariantValue& v, const Streams::OutputStream<Byte>::Ptr& out) override
    {
        TextWriter::Ptr textOut = TextWriter::New (out, TextWriter::Format::eUTF8WithoutBOM);
        PrettyPrint_ (fOptions_, v, textOut, 0);
        if (fOptions_.fJSONPrettyPrint) {
            textOut.Write (L"\n"); // a single elt not LF terminated, but the entire doc should be.
        }
    }
    virtual void Write (const VariantValue& v, const Streams::OutputStream<Character>::Ptr& out) override
    {
        PrettyPrint_ (fOptions_, v, out, 0);
    }
};

Variant::JSON::Writer::Writer (const Options& options)
    : inherited (make_shared<Rep_> (options))
{
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2018 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*!
 * \file
 * \brief memory_slice_view expression implementation
 */

#pragma once

namespace etl {

/*!
 * \brief View that shows a slice of an expression
 * \tparam T The type of expression on which the view is made
 */
template <typename T, bool Aligned>
struct memory_slice_view {
    using sub_type          = T;                                                                    ///< The sub type
    using value_type        = value_t<sub_type>;                                                    ///< The value contained in the expression
    using memory_type       = value_type*;                                                          ///< The memory acess type
    using const_memory_type = const value_type*;                                                    ///< The const memory access type
    using return_type       = return_helper<sub_type, decltype(std::declval<sub_type>()[0])>;       ///< The type returned by the view
    using const_return_type = const_return_helper<sub_type, decltype(std::declval<sub_type>()[0])>; ///< The const type return by the view

private:
    T sub;              ///< The Sub expression
    const size_t first; ///< The index
    const size_t last;  ///< The last index

    friend struct etl_traits<memory_slice_view>;

public:

    /*!
     * \brief The vectorization type for V
     */
    template<typename V = default_vec>
    using vec_type               = typename V::template vec_type<value_type>;

    /*!
     * \brief Construct a new memory_slice_view over the given sub expression
     * \param sub The sub expression
     * \param first The first index
     * \param last The last index
     */
    memory_slice_view(sub_type sub, size_t first, size_t last)
            : sub(sub), first(first), last(last) {}

    /*!
     * \brief Returns the element at the given index
     * \param j The index
     * \return a reference to the element at the given index.
     */
    const_return_type operator[](size_t j) const {
        return sub[first + j];
    }

    /*!
     * \brief Returns the element at the given index
     * \param j The index
     * \return a reference to the element at the given index.
     */
    return_type operator[](size_t j) {
        return sub[first + j];
    }

    /*!
     * \brief Returns the value at the given index
     * This function never has side effects.
     * \param j The index
     * \return the value at the given index.
     */
    value_type read_flat(size_t j) const noexcept {
        return sub[first + j];
    }

    //Note(CPP17): Use if constexpr for alignment

    /*!
     * \brief Load several elements of the expression at once
     * \param x The position at which to start.
     * \tparam V The vectorization mode to use
     * \return a vector containing several elements of the expression
     */
    template <typename V = default_vec, bool A = Aligned, cpp_enable_iff(A)>
    auto load(size_t x) const noexcept {
        return sub.template load<V>(x + first );
    }

    /*!
     * \brief Load several elements of the expression at once
     * \param x The position at which to start.
     * \tparam V The vectorization mode to use
     * \return a vector containing several elements of the expression
     */
    template <typename V = default_vec, bool A = Aligned, cpp_disable_iff(A)>
    auto load(size_t x) const noexcept {
        return sub.template loadu<V>(x + first );
    }

    /*!
     * \brief Load several elements of the expression at once
     * \param x The position at which to start.
     * \tparam V The vectorization mode to use
     * \return a vector containing several elements of the expression
     */
    template <typename V = default_vec>
    auto loadu(size_t x) const noexcept {
        return sub.template loadu<V>(x + first );
    }

    /*!
     * \brief Store several elements in the matrix at once
     * \param in The several elements to store
     * \param i The position at which to start. This will be aligned from the beginning (multiple of the vector size).
     * \tparam V The vectorization mode to use
     */
    template <typename V = default_vec, bool A = Aligned, cpp_enable_iff(A)>
    void store(vec_type<V> in, size_t i) noexcept {
        sub.template store<V>(in, first + i);
    }

    /*!
     * \brief Store several elements in the matrix at once
     * \param in The several elements to store
     * \param i The position at which to start. This will be aligned from the beginning (multiple of the vector size).
     * \tparam V The vectorization mode to use
     */
    template <typename V = default_vec, bool A = Aligned, cpp_disable_iff(A)>
    void store(vec_type<V> in, size_t i) noexcept {
        sub.template storeu<V>(in, first + i);
    }

    /*!
     * \brief Store several elements in the matrix at once
     * \param in The several elements to store
     * \param i The position at which to start. This will be aligned from the beginning (multiple of the vector size).
     * \tparam V The vectorization mode to use
     */
    template <typename V = default_vec>
    void storeu(vec_type<V> in, size_t i) noexcept {
        sub.template storeu<V>(in, first + i);
    }

    /*!
     * \brief Store several elements in the matrix at once, using non-temporal store
     * \param in The several elements to store
     * \param i The position at which to start. This will be aligned from the beginning (multiple of the vector size).
     * \tparam V The vectorization mode to use
     */
    template <typename V = default_vec, bool A = Aligned, cpp_enable_iff(A)>
    void stream(vec_type<V> in, size_t i) noexcept {
        sub.template stream<V>(in, first + i);
    }

    /*!
     * \brief Store several elements in the matrix at once, using non-temporal store
     * \param in The several elements to store
     * \param i The position at which to start. This will be aligned from the beginning (multiple of the vector size).
     * \tparam V The vectorization mode to use
     */
    template <typename V = default_vec, bool A = Aligned, cpp_disable_iff(A)>
    void stream(vec_type<V> in, size_t i) noexcept {
        sub.template storeu<V>(in, first + i);
    }

    /*!
     * \brief Test if this expression aliases with the given expression
     * \param rhs The other expression to test
     * \return true if the two expressions aliases, false otherwise
     */
    template <typename E>
    bool alias(const E& rhs) const noexcept {
        return sub.alias(rhs);
    }

    /*!
     * \brief Returns a pointer to the first element in memory.
     * \return a pointer tot the first element in memory.
     */
    memory_type memory_start() noexcept {
        return sub.memory_start() + first ;
    }

    /*!
     * \brief Returns a pointer to the first element in memory.
     * \return a pointer tot the first element in memory.
     */
    const_memory_type memory_start() const noexcept {
        return sub.memory_start() + first ;
    }

    /*!
     * \brief Returns a pointer to the past-the-end element in memory.
     * \return a pointer tot the past-the-end element in memory.
     */
    memory_type memory_end() noexcept {
        return sub.memory_start() + last ;
    }

    /*!
     * \brief Returns a pointer to the past-the-end element in memory.
     * \return a pointer tot the past-the-end element in memory.
     */
    const_memory_type memory_end() const noexcept {
        return sub.memory_start() + last;
    }

    // Assignment functions

    /*!
     * \brief Assign to the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template<typename L>
    void assign_to(L&& lhs)  const {
        std_assign_evaluate(*this, lhs);
    }

    /*!
     * \brief Add to the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template<typename L>
    void assign_add_to(L&& lhs)  const {
        std_add_evaluate(*this, lhs);
    }

    /*!
     * \brief Sub from the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template<typename L>
    void assign_sub_to(L&& lhs)  const {
        std_sub_evaluate(*this, lhs);
    }

    /*!
     * \brief Multiply the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template<typename L>
    void assign_mul_to(L&& lhs)  const {
        std_mul_evaluate(*this, lhs);
    }

    /*!
     * \brief Divide the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template<typename L>
    void assign_div_to(L&& lhs)  const {
        std_div_evaluate(*this, lhs);
    }

    /*!
     * \brief Modulo the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template<typename L>
    void assign_mod_to(L&& lhs)  const {
        std_mod_evaluate(*this, lhs);
    }

    // Internals

    /*!
     * \brief Apply the given visitor to this expression and its descendants.
     * \param visitor The visitor to apply
     */
    void visit(detail::evaluator_visitor& visitor) const {
        sub.visit(visitor);
    }

    /*!
     * \brief Ensures that the GPU memory is allocated and that the GPU memory
     * is up to date (to undefined value).
     */
    void ensure_cpu_up_to_date() const {
        // The sub value must be ensured
        sub.ensure_cpu_up_to_date();
    }

    /*!
     * \brief Copy back from the GPU to the expression memory if
     * necessary.
     */
    void ensure_gpu_up_to_date() const {
        // The sub value must be ensured
        sub.ensure_gpu_up_to_date();
    }
};

/*!
 * \brief Specialization for memory_slice_view
 */
template <typename T, bool Aligned>
struct etl_traits<etl::memory_slice_view<T, Aligned>> {
    using expr_t     = etl::memory_slice_view<T, Aligned>;          ///< The expression type
    using sub_expr_t = std::decay_t<T>;                             ///< The sub expression type
    using value_type = typename etl_traits<sub_expr_t>::value_type; ///< The value type

    static constexpr bool is_etl          = true;                                    ///< Indicates if the type is an ETL expression
    static constexpr bool is_transformer  = false;                                   ///< Indicates if the type is a transformer
    static constexpr bool is_view         = true;                                    ///< Indicates if the type is a view
    static constexpr bool is_magic_view   = false;                                   ///< Indicates if the type is a magic view
    static constexpr bool is_fast         = false;                                   ///< Indicates if the expression is fast
    static constexpr bool is_linear       = etl_traits<sub_expr_t>::is_linear;       ///< Indicates if the expression is linear
    static constexpr bool is_thread_safe  = etl_traits<sub_expr_t>::is_thread_safe;  ///< Indicates if the expression is thread safe
    static constexpr bool is_value        = false;                                   ///< Indicates if the expression is of value type
    static constexpr bool is_direct       = etl_traits<sub_expr_t>::is_direct;       ///< Indicates if the expression has direct memory access
    static constexpr bool is_generator    = false;                                   ///< Indicates if the expression is a generator
    static constexpr bool is_padded       = false;                                   ///< Indicates if the expression is padded
    static constexpr bool is_aligned      = Aligned;                                   ///< Indicates if the expression is padded
    static constexpr bool is_temporary    = etl_traits<sub_expr_t>::is_temporary;      ///< Indicates if the exxpression needs a evaluator visitor
    static constexpr bool gpu_computable = false;                                         ///< Indicates if the expression can be computed on GPU
    static constexpr order storage_order  = etl_traits<sub_expr_t>::storage_order;   ///< The expression's storage order

    /*!
     * \brief Indicates if the expression is vectorizable using the
     * given vector mode
     * \tparam V The vector mode
     */
    template <vector_mode_t V>
    static constexpr bool vectorizable = etl_traits<sub_expr_t>::template vectorizable<V>;

    /*!
     * \brief Returns the size of the given expression
     * \param v The expression to get the size for
     * \returns the size of the given expression
     */
    static size_t size(const expr_t& v) {
        return v.last - v.first;
    }

    /*!
     * \brief Returns the dth dimension of the given expression
     * \param v The expression
     * \param d The dimension to get
     * \return The dth dimension of the given expression
     */
    static size_t dim(const expr_t& v, size_t d) {
        cpp_unused(d);
        return v.last - v.first;
    }

    /*!
     * \brief Returns the number of expressions for this type
     * \return the number of dimensions of this type
     */
    static constexpr size_t dimensions() {
        return 1;
    }
};

/*!
 * \brief Returns view representing a memory slice view of the given expression.
 * \param value The ETL expression
 * \param first The first index
 * \param last The last index
 * \return a view expression representing a sub dimensional view of the given expression
 */
template <bool Aligned = false, typename E>
auto memory_slice(E&& value, size_t first, size_t last) -> detail::identity_helper<E, memory_slice_view<detail::build_identity_type<E>, Aligned>> {
    static_assert(is_etl_expr<E>, "etl::memory_slice can only be used on ETL expressions");
    return detail::identity_helper<E, memory_slice_view<detail::build_identity_type<E>, Aligned>>{{value, first, last}};
}

} //end of namespace etl
<commit_msg>C++17: Use if constexpr<commit_after>//=======================================================================
// Copyright (c) 2014-2018 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*!
 * \file
 * \brief memory_slice_view expression implementation
 */

#pragma once

namespace etl {

/*!
 * \brief View that shows a slice of an expression
 * \tparam T The type of expression on which the view is made
 */
template <typename T, bool Aligned>
struct memory_slice_view {
    using sub_type          = T;                                                                    ///< The sub type
    using value_type        = value_t<sub_type>;                                                    ///< The value contained in the expression
    using memory_type       = value_type*;                                                          ///< The memory acess type
    using const_memory_type = const value_type*;                                                    ///< The const memory access type
    using return_type       = return_helper<sub_type, decltype(std::declval<sub_type>()[0])>;       ///< The type returned by the view
    using const_return_type = const_return_helper<sub_type, decltype(std::declval<sub_type>()[0])>; ///< The const type return by the view

private:
    T sub;              ///< The Sub expression
    const size_t first; ///< The index
    const size_t last;  ///< The last index

    friend struct etl_traits<memory_slice_view>;

public:

    /*!
     * \brief The vectorization type for V
     */
    template<typename V = default_vec>
    using vec_type               = typename V::template vec_type<value_type>;

    /*!
     * \brief Construct a new memory_slice_view over the given sub expression
     * \param sub The sub expression
     * \param first The first index
     * \param last The last index
     */
    memory_slice_view(sub_type sub, size_t first, size_t last)
            : sub(sub), first(first), last(last) {}

    /*!
     * \brief Returns the element at the given index
     * \param j The index
     * \return a reference to the element at the given index.
     */
    const_return_type operator[](size_t j) const {
        return sub[first + j];
    }

    /*!
     * \brief Returns the element at the given index
     * \param j The index
     * \return a reference to the element at the given index.
     */
    return_type operator[](size_t j) {
        return sub[first + j];
    }

    /*!
     * \brief Returns the value at the given index
     * This function never has side effects.
     * \param j The index
     * \return the value at the given index.
     */
    value_type read_flat(size_t j) const noexcept {
        return sub[first + j];
    }

    /*!
     * \brief Load several elements of the expression at once
     * \param x The position at which to start.
     * \tparam V The vectorization mode to use
     * \return a vector containing several elements of the expression
     */
    template <typename V = default_vec>
    auto load(size_t x) const noexcept {
        if constexpr (Aligned) {
            return sub.template load<V>(x + first);
        } else {
            return sub.template loadu<V>(x + first);
        }
    }

    /*!
     * \brief Load several elements of the expression at once
     * \param x The position at which to start.
     * \tparam V The vectorization mode to use
     * \return a vector containing several elements of the expression
     */
    template <typename V = default_vec>
    auto loadu(size_t x) const noexcept {
        return sub.template loadu<V>(x + first );
    }

    /*!
     * \brief Store several elements in the matrix at once
     * \param in The several elements to store
     * \param i The position at which to start. This will be aligned from the beginning (multiple of the vector size).
     * \tparam V The vectorization mode to use
     */
    template <typename V = default_vec>
    void store(vec_type<V> in, size_t i) noexcept {
        if constexpr (Aligned) {
            sub.template store<V>(in, first + i);
        } else {
            sub.template storeu<V>(in, first + i);
        }
    }

    /*!
     * \brief Store several elements in the matrix at once
     * \param in The several elements to store
     * \param i The position at which to start. This will be aligned from the beginning (multiple of the vector size).
     * \tparam V The vectorization mode to use
     */
    template <typename V = default_vec>
    void storeu(vec_type<V> in, size_t i) noexcept {
        sub.template storeu<V>(in, first + i);
    }

    /*!
     * \brief Store several elements in the matrix at once, using non-temporal store
     * \param in The several elements to store
     * \param i The position at which to start. This will be aligned from the beginning (multiple of the vector size).
     * \tparam V The vectorization mode to use
     */
    template <typename V = default_vec>
    void stream(vec_type<V> in, size_t i) noexcept {
        if constexpr (Aligned) {
            sub.template stream<V>(in, first + i);
        } else {
            sub.template storeu<V>(in, first + i);
        }
    }

    /*!
     * \brief Test if this expression aliases with the given expression
     * \param rhs The other expression to test
     * \return true if the two expressions aliases, false otherwise
     */
    template <typename E>
    bool alias(const E& rhs) const noexcept {
        return sub.alias(rhs);
    }

    /*!
     * \brief Returns a pointer to the first element in memory.
     * \return a pointer tot the first element in memory.
     */
    memory_type memory_start() noexcept {
        return sub.memory_start() + first ;
    }

    /*!
     * \brief Returns a pointer to the first element in memory.
     * \return a pointer tot the first element in memory.
     */
    const_memory_type memory_start() const noexcept {
        return sub.memory_start() + first ;
    }

    /*!
     * \brief Returns a pointer to the past-the-end element in memory.
     * \return a pointer tot the past-the-end element in memory.
     */
    memory_type memory_end() noexcept {
        return sub.memory_start() + last ;
    }

    /*!
     * \brief Returns a pointer to the past-the-end element in memory.
     * \return a pointer tot the past-the-end element in memory.
     */
    const_memory_type memory_end() const noexcept {
        return sub.memory_start() + last;
    }

    // Assignment functions

    /*!
     * \brief Assign to the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template<typename L>
    void assign_to(L&& lhs)  const {
        std_assign_evaluate(*this, lhs);
    }

    /*!
     * \brief Add to the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template<typename L>
    void assign_add_to(L&& lhs)  const {
        std_add_evaluate(*this, lhs);
    }

    /*!
     * \brief Sub from the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template<typename L>
    void assign_sub_to(L&& lhs)  const {
        std_sub_evaluate(*this, lhs);
    }

    /*!
     * \brief Multiply the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template<typename L>
    void assign_mul_to(L&& lhs)  const {
        std_mul_evaluate(*this, lhs);
    }

    /*!
     * \brief Divide the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template<typename L>
    void assign_div_to(L&& lhs)  const {
        std_div_evaluate(*this, lhs);
    }

    /*!
     * \brief Modulo the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template<typename L>
    void assign_mod_to(L&& lhs)  const {
        std_mod_evaluate(*this, lhs);
    }

    // Internals

    /*!
     * \brief Apply the given visitor to this expression and its descendants.
     * \param visitor The visitor to apply
     */
    void visit(detail::evaluator_visitor& visitor) const {
        sub.visit(visitor);
    }

    /*!
     * \brief Ensures that the GPU memory is allocated and that the GPU memory
     * is up to date (to undefined value).
     */
    void ensure_cpu_up_to_date() const {
        // The sub value must be ensured
        sub.ensure_cpu_up_to_date();
    }

    /*!
     * \brief Copy back from the GPU to the expression memory if
     * necessary.
     */
    void ensure_gpu_up_to_date() const {
        // The sub value must be ensured
        sub.ensure_gpu_up_to_date();
    }
};

/*!
 * \brief Specialization for memory_slice_view
 */
template <typename T, bool Aligned>
struct etl_traits<etl::memory_slice_view<T, Aligned>> {
    using expr_t     = etl::memory_slice_view<T, Aligned>;          ///< The expression type
    using sub_expr_t = std::decay_t<T>;                             ///< The sub expression type
    using value_type = typename etl_traits<sub_expr_t>::value_type; ///< The value type

    static constexpr bool is_etl          = true;                                    ///< Indicates if the type is an ETL expression
    static constexpr bool is_transformer  = false;                                   ///< Indicates if the type is a transformer
    static constexpr bool is_view         = true;                                    ///< Indicates if the type is a view
    static constexpr bool is_magic_view   = false;                                   ///< Indicates if the type is a magic view
    static constexpr bool is_fast         = false;                                   ///< Indicates if the expression is fast
    static constexpr bool is_linear       = etl_traits<sub_expr_t>::is_linear;       ///< Indicates if the expression is linear
    static constexpr bool is_thread_safe  = etl_traits<sub_expr_t>::is_thread_safe;  ///< Indicates if the expression is thread safe
    static constexpr bool is_value        = false;                                   ///< Indicates if the expression is of value type
    static constexpr bool is_direct       = etl_traits<sub_expr_t>::is_direct;       ///< Indicates if the expression has direct memory access
    static constexpr bool is_generator    = false;                                   ///< Indicates if the expression is a generator
    static constexpr bool is_padded       = false;                                   ///< Indicates if the expression is padded
    static constexpr bool is_aligned      = Aligned;                                   ///< Indicates if the expression is padded
    static constexpr bool is_temporary    = etl_traits<sub_expr_t>::is_temporary;      ///< Indicates if the exxpression needs a evaluator visitor
    static constexpr bool gpu_computable = false;                                         ///< Indicates if the expression can be computed on GPU
    static constexpr order storage_order  = etl_traits<sub_expr_t>::storage_order;   ///< The expression's storage order

    /*!
     * \brief Indicates if the expression is vectorizable using the
     * given vector mode
     * \tparam V The vector mode
     */
    template <vector_mode_t V>
    static constexpr bool vectorizable = etl_traits<sub_expr_t>::template vectorizable<V>;

    /*!
     * \brief Returns the size of the given expression
     * \param v The expression to get the size for
     * \returns the size of the given expression
     */
    static size_t size(const expr_t& v) {
        return v.last - v.first;
    }

    /*!
     * \brief Returns the dth dimension of the given expression
     * \param v The expression
     * \param d The dimension to get
     * \return The dth dimension of the given expression
     */
    static size_t dim(const expr_t& v, size_t d) {
        cpp_unused(d);
        return v.last - v.first;
    }

    /*!
     * \brief Returns the number of expressions for this type
     * \return the number of dimensions of this type
     */
    static constexpr size_t dimensions() {
        return 1;
    }
};

/*!
 * \brief Returns view representing a memory slice view of the given expression.
 * \param value The ETL expression
 * \param first The first index
 * \param last The last index
 * \return a view expression representing a sub dimensional view of the given expression
 */
template <bool Aligned = false, typename E>
auto memory_slice(E&& value, size_t first, size_t last) -> detail::identity_helper<E, memory_slice_view<detail::build_identity_type<E>, Aligned>> {
    static_assert(is_etl_expr<E>, "etl::memory_slice can only be used on ETL expressions");
    return detail::identity_helper<E, memory_slice_view<detail::build_identity_type<E>, Aligned>>{{value, first, last}};
}

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


<commit_before>//
//  client.hpp
//  fibio
//
//  Created by Chen Xu on 14-3-11.
//  Copyright (c) 2014 0d0a.com. All rights reserved.
//

#ifndef fiberized_io_http_client_client_hpp
#define fiberized_io_http_client_client_hpp

#include <string>
#include <functional>
#include <fibio/stream/iostream.hpp>
#include <fibio/http/client/request.hpp>
#include <fibio/http/client/response.hpp>

namespace fibio { namespace http { namespace client {
    struct client {
        typedef fibio::http::client::request request;
        typedef fibio::http::client::response response;

        client()=default;
        client(const std::string &server, const std::string &port);
        client(const std::string &server, int port);

        std::error_code connect(const std::string &server, const std::string &port);
        std::error_code connect(const std::string &server, int port);
        void disconnect();

        void set_auto_decompress(bool c);
        bool get_auto_decompress() const;

        bool send_request(request &req, response &resp);

        std::string server_;
        std::string port_;
        stream::tcp_stream stream_;
        bool auto_decompress_;
    };
}}} // End of namespace fibio::http::client

namespace fibio { namespace http {
    typedef client::client http_client;
}}  // End of namespace fibio::http

#endif
<commit_msg>disable auto decompress by default as it costs<commit_after>//
//  client.hpp
//  fibio
//
//  Created by Chen Xu on 14-3-11.
//  Copyright (c) 2014 0d0a.com. All rights reserved.
//

#ifndef fiberized_io_http_client_client_hpp
#define fiberized_io_http_client_client_hpp

#include <string>
#include <functional>
#include <fibio/stream/iostream.hpp>
#include <fibio/http/client/request.hpp>
#include <fibio/http/client/response.hpp>

namespace fibio { namespace http { namespace client {
    struct client {
        typedef fibio::http::client::request request;
        typedef fibio::http::client::response response;

        client()=default;
        client(const std::string &server, const std::string &port);
        client(const std::string &server, int port);

        std::error_code connect(const std::string &server, const std::string &port);
        std::error_code connect(const std::string &server, int port);
        void disconnect();

        void set_auto_decompress(bool c);
        bool get_auto_decompress() const;

        bool send_request(request &req, response &resp);

        std::string server_;
        std::string port_;
        stream::tcp_stream stream_;
        bool auto_decompress_=false;
    };
}}} // End of namespace fibio::http::client

namespace fibio { namespace http {
    typedef client::client http_client;
}}  // End of namespace fibio::http

#endif
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  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.txt
 *
 *  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.
 *
 *=========================================================================*/
/*=========================================================================
 *
 *  Portions of this file are subject to the VTK Toolkit Version 3 copyright.
 *
 *  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
 *
 *  For complete copyright, license and disclaimer of warranty information
 *  please refer to the NOTICE file at the top of the ITK source tree.
 *
 *=========================================================================*/
#ifndef itkInterpolateImagePointsFilter_hxx
#define itkInterpolateImagePointsFilter_hxx

#include "itkInterpolateImagePointsFilter.h"
#include "itkProgressReporter.h"

namespace itk
{
/**
 * Constructor
 */
template< typename TInputImage, typename TOutputImage, typename TCoordType, typename InterpolatorType >
InterpolateImagePointsFilter< TInputImage, TOutputImage, TCoordType, InterpolatorType >
::InterpolateImagePointsFilter()
{
  m_Interpolator = InterpolatorType::New();
  m_DefaultPixelValue = 0;

  this->SetNumberOfRequiredInputs(ImageDimension+1);
}

/**
 * Standard "PrintSelf" method
 */
template< typename TInputImage, typename TOutputImage, typename TCoordType, typename InterpolatorType >
void
InterpolateImagePointsFilter< TInputImage, TOutputImage, TCoordType, InterpolatorType >
::PrintSelf(
  std::ostream & os,
  Indent indent) const
{
  Superclass::PrintSelf(os, indent);
  os << indent << "Default (background) pixel level: " << m_DefaultPixelValue << std::endl;
}

template< typename TInputImage, typename TOutputImage, typename TCoordType, typename InterpolatorType >
void
InterpolateImagePointsFilter< TInputImage, TOutputImage, TCoordType, InterpolatorType >
::SetInputImage(const TInputImage *inputImage)
{
  this->SetInput(0, inputImage); // This is a data filter input
  // ***TODO:  Where should this be done?  During the filter update?
  //  should be converted to a filter.
  m_Interpolator->SetInputImage(inputImage);
}

template< typename TInputImage, typename TOutputImage, typename TCoordType, typename InterpolatorType >
void
InterpolateImagePointsFilter< TInputImage, TOutputImage, TCoordType, InterpolatorType >
::SetInterpolationCoordinate(const CoordImageType *coordinate, unsigned int setDimension)
{
  // Set each coordinate as an input.  Note that Input '0' is for the image.
  this->SetInput(setDimension + 1, coordinate); // This is a data filter input
}

template< typename TInputImage, typename TOutputImage, typename TCoordType, typename InterpolatorType >
void
InterpolateImagePointsFilter< TInputImage, TOutputImage, TCoordType, InterpolatorType >
::BeforeThreadedGenerateData()
{
  itkDebugMacro(<< "Actually Executing");

  // ***TODO: What needs to be done here? Should we set the input image at this
  // time?
  //  ** Also, where is the output allocated?

  // OutputImagePointer outputPtr = this->GetOutput();

  // outputPtr->SetBufferedRegion( outputPtr->GetRequestedRegion() );
  // outputPtr->Allocate();
}

template< typename TInputImage, typename TOutputImage, typename TCoordType, typename InterpolatorType >
void
InterpolateImagePointsFilter< TInputImage, TOutputImage, TCoordType, InterpolatorType >
::ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread,
                       ThreadIdType threadId)
{
  itkDebugMacro(<< "Actually Executing");

  OutputImagePointer outputPtr = this->GetOutput();

  // There is a direct mapping between the desired outputRegion and the
  // CoordRegion
  // coordRegion is set to outputRegionForThread.
  RegionCopierType     regionCopier;
  CoordImageRegionType coordRegion;
  regionCopier(coordRegion, outputRegionForThread);

  // Setup iterator for the output
  OutputImageIterator outIter(outputPtr, outputRegionForThread);
  //outIter.GoToBegin();  //Not sure if this is needed or inappropriate for
  // threading.

  // Setup an interator for each of the coordinate inputs.
  CoordImageIterator coordIter[ImageDimension];
  for ( unsigned int j = 0; j < ImageDimension; j++ )
    {
    CoordImageIterator temp(this->GetInput(j + 1), coordRegion);
//    temp.GoToBegin();   //Not sure if this is needed or inappropriate for
// threading.
    coordIter[j] = temp;
    }

  // Support for progress methods/callbacks
  ProgressReporter progress( this, threadId, outputRegionForThread.GetNumberOfPixels() );

  // Loop through each pixel and calculate interpolated value.
  ContinuousIndexType index;
  while ( !outIter.IsAtEnd() )
    {
    for ( unsigned int j = 0; j < ImageDimension; j++ )
      {
      index[j] = ( coordIter[j] ).Value();
      ++( coordIter[j] );
      }
    if ( m_Interpolator->IsInsideBuffer(index) )
      {
      outIter.Set( m_Interpolator->EvaluateAtContinuousIndex(index) );
      // TODO: How can we modify the code so that it could also interpolate
      //  from a set of point coordinates instead of Continuous Index
      // coordinates?
      //  If this line is used instead of the above line then this will
      //  calculate from points. ( PointType point must replace index throughout
      // this
      //  function.)
      // outIter.Set( m_Interpolator->Evaluate( point );
      }
    else
      {
      outIter.Set(m_DefaultPixelValue);
      }
    ++outIter;
    progress.CompletedPixel();
    }
}

/**
 *
 */
template< typename TInputImage, typename TOutputImage, typename TCoordType, typename InterpolatorType >
void
InterpolateImagePointsFilter< TInputImage, TOutputImage, TCoordType, InterpolatorType >
::GenerateInputRequestedRegion()
{
  // call the superclass' implementation of this method
  Superclass::GenerateInputRequestedRegion();

  if ( !this->GetInput(0) )
    {
    return;
    }

  // The coordinates may have arbitrary ordering so the entire image must be
  // available
  // for the filter.  The coordinates on the other hand have the default
  // requested
  // region size.
  InputImagePointer inputPtr = const_cast< TInputImage * >( this->GetInput(0) );
  inputPtr->SetRequestedRegionToLargestPossibleRegion();
}

/**
 *
 */
template< typename TInputImage, typename TOutputImage, typename TCoordType, typename InterpolatorType >
void
InterpolateImagePointsFilter< TInputImage, TOutputImage, TCoordType, InterpolatorType >
::GenerateOutputInformation()
{
  // call the superclass' implementation of this method
  Superclass::GenerateOutputInformation();

  //   This sets the largestPossibleRegion to ensure it is the same as
  //   the coordinates.  While this should be the default behavor, given the
  //   multiple inputs it may incorrectly default to the image
  // largestPossibleRegion
  //   thus this method was explicitly written.
  CoordImageTypePointer xCoordPtr = const_cast< TInputImage * >( this->GetInput(1) );
  OutputImagePointer    outputPtr = this->GetOutput();

  // we need to compute the output spacing, the output image size, and the
  // output image start index.  This is all determined by the coordinate data

  const typename TOutputImage::SpacingType &
  outputSpacing = xCoordPtr->GetSpacing();
  const typename TOutputImage::SizeType &   outputSize =
    xCoordPtr->GetLargestPossibleRegion().GetSize();
  const typename TOutputImage::IndexType &  outputStartIndex =
    xCoordPtr->GetLargestPossibleRegion().GetIndex();

  outputPtr->SetSpacing(outputSpacing);

  typename TOutputImage::RegionType outputLargestPossibleRegion;
  outputLargestPossibleRegion.SetSize(outputSize);
  outputLargestPossibleRegion.SetIndex(outputStartIndex);

  outputPtr->SetLargestPossibleRegion(outputLargestPossibleRegion);
}
} // namespace itk

#endif
<commit_msg>STYLE: Improve the class implementation file style.<commit_after>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  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.txt
 *
 *  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.
 *
 *=========================================================================*/
/*=========================================================================
 *
 *  Portions of this file are subject to the VTK Toolkit Version 3 copyright.
 *
 *  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
 *
 *  For complete copyright, license and disclaimer of warranty information
 *  please refer to the NOTICE file at the top of the ITK source tree.
 *
 *=========================================================================*/
#ifndef itkInterpolateImagePointsFilter_hxx
#define itkInterpolateImagePointsFilter_hxx

#include "itkInterpolateImagePointsFilter.h"
#include "itkProgressReporter.h"

namespace itk
{

template< typename TInputImage, typename TOutputImage, typename TCoordType, typename InterpolatorType >
InterpolateImagePointsFilter< TInputImage, TOutputImage, TCoordType, InterpolatorType >
::InterpolateImagePointsFilter()
{
  m_Interpolator = InterpolatorType::New();
  m_DefaultPixelValue = 0;

  this->SetNumberOfRequiredInputs(ImageDimension+1);
}

template< typename TInputImage, typename TOutputImage, typename TCoordType, typename InterpolatorType >
void
InterpolateImagePointsFilter< TInputImage, TOutputImage, TCoordType, InterpolatorType >
::SetInputImage(const TInputImage *inputImage)
{
  this->SetInput(0, inputImage); // This is a data filter input
  // ***TODO:  Where should this be done?  During the filter update?
  //  should be converted to a filter.
  m_Interpolator->SetInputImage(inputImage);
}

template< typename TInputImage, typename TOutputImage, typename TCoordType, typename InterpolatorType >
void
InterpolateImagePointsFilter< TInputImage, TOutputImage, TCoordType, InterpolatorType >
::SetInterpolationCoordinate(const CoordImageType *coordinate, unsigned int setDimension)
{
  // Set each coordinate as an input.  Note that Input '0' is for the image.
  this->SetInput(setDimension + 1, coordinate); // This is a data filter input
}

template< typename TInputImage, typename TOutputImage, typename TCoordType, typename InterpolatorType >
void
InterpolateImagePointsFilter< TInputImage, TOutputImage, TCoordType, InterpolatorType >
::BeforeThreadedGenerateData()
{
  itkDebugMacro(<< "Actually Executing");

  // ***TODO: What needs to be done here? Should we set the input image at this
  // time?
  //  ** Also, where is the output allocated?

  // OutputImagePointer outputPtr = this->GetOutput();

  // outputPtr->SetBufferedRegion( outputPtr->GetRequestedRegion() );
  // outputPtr->Allocate();
}

template< typename TInputImage, typename TOutputImage, typename TCoordType, typename InterpolatorType >
void
InterpolateImagePointsFilter< TInputImage, TOutputImage, TCoordType, InterpolatorType >
::ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread,
                       ThreadIdType threadId)
{
  itkDebugMacro(<< "Actually Executing");

  OutputImagePointer outputPtr = this->GetOutput();

  // There is a direct mapping between the desired outputRegion and the
  // CoordRegion
  // coordRegion is set to outputRegionForThread.
  RegionCopierType     regionCopier;
  CoordImageRegionType coordRegion;
  regionCopier(coordRegion, outputRegionForThread);

  // Setup iterator for the output
  OutputImageIterator outIter(outputPtr, outputRegionForThread);
  //outIter.GoToBegin();  //Not sure if this is needed or inappropriate for
  // threading.

  // Setup an interator for each of the coordinate inputs.
  CoordImageIterator coordIter[ImageDimension];
  for ( unsigned int j = 0; j < ImageDimension; j++ )
    {
    CoordImageIterator temp(this->GetInput(j + 1), coordRegion);
//    temp.GoToBegin();   //Not sure if this is needed or inappropriate for threading.
    coordIter[j] = temp;
    }

  // Support for progress methods/callbacks
  ProgressReporter progress( this, threadId, outputRegionForThread.GetNumberOfPixels() );

  // Loop through each pixel and calculate interpolated value.
  ContinuousIndexType index;
  while ( !outIter.IsAtEnd() )
    {
    for ( unsigned int j = 0; j < ImageDimension; j++ )
      {
      index[j] = ( coordIter[j] ).Value();
      ++( coordIter[j] );
      }
    if ( m_Interpolator->IsInsideBuffer(index) )
      {
      outIter.Set( m_Interpolator->EvaluateAtContinuousIndex(index) );
      // TODO: How can we modify the code so that it could also interpolate
      // from a set of point coordinates instead of Continuous Index
      // coordinates?
      // If this line is used instead of the above line then this will
      // calculate from points. ( PointType point must replace index throughout
      // this function.)
      // outIter.Set( m_Interpolator->Evaluate( point );
      }
    else
      {
      outIter.Set(m_DefaultPixelValue);
      }
    ++outIter;
    progress.CompletedPixel();
    }
}

template< typename TInputImage, typename TOutputImage, typename TCoordType, typename InterpolatorType >
void
InterpolateImagePointsFilter< TInputImage, TOutputImage, TCoordType, InterpolatorType >
::GenerateInputRequestedRegion()
{
  // Call the superclass' implementation of this method
  Superclass::GenerateInputRequestedRegion();

  if ( !this->GetInput(0) )
    {
    return;
    }

  // The coordinates may have arbitrary ordering so the entire image must be
  // available for the filter. The coordinates on the other hand have the default
  // requested region size.
  InputImagePointer inputPtr = const_cast< TInputImage * >( this->GetInput(0) );
  inputPtr->SetRequestedRegionToLargestPossibleRegion();
}

template< typename TInputImage, typename TOutputImage, typename TCoordType, typename InterpolatorType >
void
InterpolateImagePointsFilter< TInputImage, TOutputImage, TCoordType, InterpolatorType >
::GenerateOutputInformation()
{
  // Call the superclass' implementation of this method
  Superclass::GenerateOutputInformation();

  // This sets the largestPossibleRegion to ensure it is the same as
  // the coordinates. While this should be the default behavor, given the
  // multiple inputs it may incorrectly default to the image
  // largestPossibleRegion.
  // Thus this method was explicitly written.
  //
  CoordImageTypePointer xCoordPtr = const_cast< TInputImage * >( this->GetInput(1) );
  OutputImagePointer    outputPtr = this->GetOutput();

  // We need to compute the output spacing, the output image size, and the
  // output image start index. This is all determined by the coordinate data

  const typename TOutputImage::SpacingType &
  outputSpacing = xCoordPtr->GetSpacing();
  const typename TOutputImage::SizeType &   outputSize =
    xCoordPtr->GetLargestPossibleRegion().GetSize();
  const typename TOutputImage::IndexType &  outputStartIndex =
    xCoordPtr->GetLargestPossibleRegion().GetIndex();

  outputPtr->SetSpacing(outputSpacing);

  typename TOutputImage::RegionType outputLargestPossibleRegion;
  outputLargestPossibleRegion.SetSize(outputSize);
  outputLargestPossibleRegion.SetIndex(outputStartIndex);

  outputPtr->SetLargestPossibleRegion(outputLargestPossibleRegion);
}

template< typename TInputImage, typename TOutputImage, typename TCoordType, typename InterpolatorType >
void
InterpolateImagePointsFilter< TInputImage, TOutputImage, TCoordType, InterpolatorType >
::PrintSelf( std::ostream & os, Indent indent) const
{
  Superclass::PrintSelf( os, indent );

  os << indent << "Default (background) pixel level: " << m_DefaultPixelValue << std::endl;
}
} // namespace itk

#endif
<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

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

#include "mitkImageLiveWireContourModelFilter.h"

#include <itkShortestPathCostFunctionLiveWire.h>
#include <itkImageRegionIterator.h>
#include <itkShortestPathImageFilter.h>

mitk::ImageLiveWireContourModelFilter::ImageLiveWireContourModelFilter()
{
  OutputType::Pointer output = dynamic_cast<OutputType*> ( this->MakeOutput( 0 ).GetPointer() );
  this->SetNumberOfRequiredInputs(1);
  this->SetNumberOfOutputs( 1 );
  this->SetNthOutput(0, output.GetPointer());

}
mitk::ImageLiveWireContourModelFilter::~ImageLiveWireContourModelFilter()
{

}

mitk::ImageLiveWireContourModelFilter::OutputType* mitk::ImageLiveWireContourModelFilter::GetOutput()
{
  return Superclass::GetOutput();
}

void mitk::ImageLiveWireContourModelFilter::SetInput ( const mitk::ImageLiveWireContourModelFilter::InputType* input )
{
  this->SetInput( 0, input );
}

void mitk::ImageLiveWireContourModelFilter::SetInput ( unsigned int idx, const mitk::ImageLiveWireContourModelFilter::InputType* input )
{
  if ( idx + 1 > this->GetNumberOfInputs() )
  {
    this->SetNumberOfRequiredInputs(idx + 1);
  }
  if ( input != static_cast<InputType*> ( this->ProcessObject::GetInput ( idx ) ) )
  {
    this->ProcessObject::SetNthInput ( idx, const_cast<InputType*> ( input ) );
    this->Modified();
  }
}

const mitk::ImageLiveWireContourModelFilter::InputType* mitk::ImageLiveWireContourModelFilter::GetInput( void )
{
  if (this->GetNumberOfInputs() < 1)
    return NULL;
  return static_cast<const mitk::ImageLiveWireContourModelFilter::InputType*>(this->ProcessObject::GetInput(0));
}

const mitk::ImageLiveWireContourModelFilter::InputType* mitk::ImageLiveWireContourModelFilter::GetInput( unsigned int idx )
{
  if (this->GetNumberOfInputs() < 1)
    return NULL;
  return static_cast<const mitk::ImageLiveWireContourModelFilter::InputType*>(this->ProcessObject::GetInput(idx));
}

void mitk::ImageLiveWireContourModelFilter::GenerateData()
{
    mitk::Image::ConstPointer input = dynamic_cast<const mitk::Image*>(this->GetInput());

  if(!input)
  {
    MITK_ERROR << "No input available.";
    itkExceptionMacro("mitk::ImageToLiveWireContourFilter: No input available. Please set the input!");
    return;
  }

  if( input->GetDimension() != 2 )
  {
    MITK_ERROR << "Filter is only working on 2D images.";
    itkExceptionMacro("mitk::ImageToLiveWireContourFilter: Filter is only working on 2D images.. Please make sure that the input is 2D!");
    return;
  }

  input->GetGeometry()->WorldToIndex(m_StartPoint, m_StartPointInIndex);
  input->GetGeometry()->WorldToIndex(m_EndPoint, m_EndPointInIndex);

  AccessFixedDimensionByItk(input, ItkProcessImage, 2);
}

template<typename TPixel, unsigned int VImageDimension>
void mitk::ImageLiveWireContourModelFilter::ItkProcessImage (itk::Image<TPixel, VImageDimension>* inputImage)
{
  typedef itk::Image< TPixel, VImageDimension >                              InputImageType;
  typedef itk::Image< float,  2 >                                          FloatImageType;

  typedef typename itk::ShortestPathImageFilter< InputImageType, InputImageType >     ShortestPathImageFilterType;
  typedef typename itk::ShortestPathCostFunctionLiveWire< InputImageType >   CostFunctionType;

  typedef InputImageType::IndexType                                        IndexType;

  /* compute the requested region for itk filters */

  typename IndexType startPoint, endPoint;

  startPoint[0] = m_StartPointInIndex[0];
  startPoint[1] = m_StartPointInIndex[1];

  endPoint[0] = m_EndPointInIndex[0];
  endPoint[1] = m_EndPointInIndex[1];

  //minimum value in each direction for startRegion
  typename IndexType startRegion;
  startRegion[0] = startPoint[0] < endPoint[0] ? startPoint[0] : endPoint[0];
  startRegion[1] = startPoint[1] < endPoint[1] ? startPoint[1] : endPoint[1];

  //maximum value in each direction for size
  typename InputImageType::SizeType size;
  size[0] = startPoint[0] > endPoint[0] ? startPoint[0] : endPoint[0];
  size[1] = startPoint[1] > endPoint[1] ? startPoint[1] : endPoint[1];

  typename InputImageType::RegionType region;
  region.SetSize( size );
  region.SetIndex( startRegion );
  /*---------------------------------------------*/

  /* extracts features from image and calculates costs */
  typename CostFunctionType::Pointer costFunction = CostFunctionType::New();
  costFunction->SetImage(inputImage);
  costFunction->SetStartIndex(startPoint);
  costFunction->SetEndIndex(endPoint);
  //costFunction->SetRequestedRegion(region);
  /*---------------------------------------------*/

  /* calculate shortest path between start and end point */
  ShortestPathImageFilterType::Pointer shortestPathFilter = ShortestPathImageFilterType::New();
  shortestPathFilter->SetFullNeighborsMode(true);
  shortestPathFilter->SetInput(inputImage);
  shortestPathFilter->SetMakeOutputImage(false);

  //shortestPathFilter->SetCalcAllDistances(true);
  shortestPathFilter->SetStartIndex(startPoint);
  shortestPathFilter->SetEndIndex(endPoint);

  shortestPathFilter->SetCostFunction(costFunction);

  shortestPathFilter->Update();

  /*---------------------------------------------*/

  /* construct contour from path image */
  //get the shortest path as vector
  typename std::vector< ShortestPathImageFilterType::IndexType> shortestPath = shortestPathFilter->GetVectorPath();

  //fill the output contour with controll points from the path
  OutputType::Pointer output = dynamic_cast<OutputType*> ( this->MakeOutput( 0 ).GetPointer() );
  this->SetNthOutput(0, output.GetPointer());

  mitk::Image::ConstPointer input = dynamic_cast<const mitk::Image*>(this->GetInput());

  typename std::vector< ShortestPathImageFilterType::IndexType>::iterator pathIterator = shortestPath.begin();

  while(pathIterator != shortestPath.end())
  {
    mitk::Point2D currentPoint;
    currentPoint[0] = (*pathIterator)[0];
    currentPoint[1] = (*pathIterator)[1];

    mitk::Point3D currentPoint3D;

    m_Geo2D->IndexToWorld(currentPoint, currentPoint);
    m_Geo2D->Map(currentPoint, currentPoint3D);
    output->AddVertex(currentPoint3D);

    pathIterator++;
  }
  /*---------------------------------------------*/

}<commit_msg>cost function typedefinition<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

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

#include "mitkImageLiveWireContourModelFilter.h"

#include <itkShortestPathCostFunctionLiveWire.h>
#include <itkImageRegionIterator.h>
#include <itkShortestPathImageFilter.h>

mitk::ImageLiveWireContourModelFilter::ImageLiveWireContourModelFilter()
{
  OutputType::Pointer output = dynamic_cast<OutputType*> ( this->MakeOutput( 0 ).GetPointer() );
  this->SetNumberOfRequiredInputs(1);
  this->SetNumberOfOutputs( 1 );
  this->SetNthOutput(0, output.GetPointer());

}
mitk::ImageLiveWireContourModelFilter::~ImageLiveWireContourModelFilter()
{

}

mitk::ImageLiveWireContourModelFilter::OutputType* mitk::ImageLiveWireContourModelFilter::GetOutput()
{
  return Superclass::GetOutput();
}

void mitk::ImageLiveWireContourModelFilter::SetInput ( const mitk::ImageLiveWireContourModelFilter::InputType* input )
{
  this->SetInput( 0, input );
}

void mitk::ImageLiveWireContourModelFilter::SetInput ( unsigned int idx, const mitk::ImageLiveWireContourModelFilter::InputType* input )
{
  if ( idx + 1 > this->GetNumberOfInputs() )
  {
    this->SetNumberOfRequiredInputs(idx + 1);
  }
  if ( input != static_cast<InputType*> ( this->ProcessObject::GetInput ( idx ) ) )
  {
    this->ProcessObject::SetNthInput ( idx, const_cast<InputType*> ( input ) );
    this->Modified();
  }
}

const mitk::ImageLiveWireContourModelFilter::InputType* mitk::ImageLiveWireContourModelFilter::GetInput( void )
{
  if (this->GetNumberOfInputs() < 1)
    return NULL;
  return static_cast<const mitk::ImageLiveWireContourModelFilter::InputType*>(this->ProcessObject::GetInput(0));
}

const mitk::ImageLiveWireContourModelFilter::InputType* mitk::ImageLiveWireContourModelFilter::GetInput( unsigned int idx )
{
  if (this->GetNumberOfInputs() < 1)
    return NULL;
  return static_cast<const mitk::ImageLiveWireContourModelFilter::InputType*>(this->ProcessObject::GetInput(idx));
}

void mitk::ImageLiveWireContourModelFilter::GenerateData()
{
    mitk::Image::ConstPointer input = dynamic_cast<const mitk::Image*>(this->GetInput());

  if(!input)
  {
    MITK_ERROR << "No input available.";
    itkExceptionMacro("mitk::ImageToLiveWireContourFilter: No input available. Please set the input!");
    return;
  }

  if( input->GetDimension() != 2 )
  {
    MITK_ERROR << "Filter is only working on 2D images.";
    itkExceptionMacro("mitk::ImageToLiveWireContourFilter: Filter is only working on 2D images.. Please make sure that the input is 2D!");
    return;
  }

  input->GetGeometry()->WorldToIndex(m_StartPoint, m_StartPointInIndex);
  input->GetGeometry()->WorldToIndex(m_EndPoint, m_EndPointInIndex);

  AccessFixedDimensionByItk(input, ItkProcessImage, 2);
}

template<typename TPixel, unsigned int VImageDimension>
void mitk::ImageLiveWireContourModelFilter::ItkProcessImage (itk::Image<TPixel, VImageDimension>* inputImage)
{
  typedef itk::Image< TPixel, VImageDimension >                              InputImageType;
  typedef itk::Image< float,  2 >                                          FloatImageType;

  typedef  itk::ShortestPathImageFilter< typename InputImageType, typename InputImageType >     ShortestPathImageFilterType;
  typedef  itk::ShortestPathCostFunctionLiveWire< itk::Image< TPixel, VImageDimension > >   CostFunctionType;

  typedef InputImageType::IndexType                                        IndexType;

  /* compute the requested region for itk filters */

  typename IndexType startPoint, endPoint;

  startPoint[0] = m_StartPointInIndex[0];
  startPoint[1] = m_StartPointInIndex[1];

  endPoint[0] = m_EndPointInIndex[0];
  endPoint[1] = m_EndPointInIndex[1];

  //minimum value in each direction for startRegion
  typename IndexType startRegion;
  startRegion[0] = startPoint[0] < endPoint[0] ? startPoint[0] : endPoint[0];
  startRegion[1] = startPoint[1] < endPoint[1] ? startPoint[1] : endPoint[1];

  //maximum value in each direction for size
  typename InputImageType::SizeType size;
  size[0] = startPoint[0] > endPoint[0] ? startPoint[0] : endPoint[0];
  size[1] = startPoint[1] > endPoint[1] ? startPoint[1] : endPoint[1];

  typename CostFunctionType::RegionType region;
  region.SetSize( size );
  region.SetIndex( startRegion );
  /*---------------------------------------------*/

  /* extracts features from image and calculates costs */
  typename CostFunctionType::Pointer costFunction = CostFunctionType::New();
  costFunction->SetImage(inputImage);
  costFunction->SetStartIndex(startPoint);
  costFunction->SetEndIndex(endPoint);
  costFunction->SetRequestedRegion(region);
  /*---------------------------------------------*/

  /* calculate shortest path between start and end point */
  ShortestPathImageFilterType::Pointer shortestPathFilter = ShortestPathImageFilterType::New();
  shortestPathFilter->SetFullNeighborsMode(true);
  shortestPathFilter->SetInput(inputImage);
  shortestPathFilter->SetMakeOutputImage(false);

  //shortestPathFilter->SetCalcAllDistances(true);
  shortestPathFilter->SetStartIndex(startPoint);
  shortestPathFilter->SetEndIndex(endPoint);

  shortestPathFilter->SetCostFunction(costFunction);

  shortestPathFilter->Update();

  /*---------------------------------------------*/

  /* construct contour from path image */
  //get the shortest path as vector
  typename std::vector< ShortestPathImageFilterType::IndexType> shortestPath = shortestPathFilter->GetVectorPath();

  //fill the output contour with controll points from the path
  OutputType::Pointer output = dynamic_cast<OutputType*> ( this->MakeOutput( 0 ).GetPointer() );
  this->SetNthOutput(0, output.GetPointer());

  mitk::Image::ConstPointer input = dynamic_cast<const mitk::Image*>(this->GetInput());

  typename std::vector< ShortestPathImageFilterType::IndexType>::iterator pathIterator = shortestPath.begin();

  while(pathIterator != shortestPath.end())
  {
    mitk::Point2D currentPoint;
    currentPoint[0] = (*pathIterator)[0];
    currentPoint[1] = (*pathIterator)[1];

    mitk::Point3D currentPoint3D;

    m_Geo2D->IndexToWorld(currentPoint, currentPoint);
    m_Geo2D->Map(currentPoint, currentPoint3D);
    output->AddVertex(currentPoint3D);

    pathIterator++;
  }
  /*---------------------------------------------*/

}<|endoftext|>