<commit_before>#include <iostream>
#include <array>
#include <vector>
#include <cassert>
#include <iterator>
#include "days.hpp"

namespace {
    std::array<int, 4> base_pattern{0, 1, 0, -1};

    int get_modifier(int rank, int pos) {
        pos += 1;
        pos /= rank + 1;

        return base_pattern[pos % 4];
    }

    std::vector<int> read_input(std::istream &input) {
        std::vector<int> result;

        for (char c; input >> c;) {
            assert(std::isdigit(c));
            result.push_back(c - '0');
        }

        return result;
    }

    std::vector<int> partial_sum(const std::vector<int> &numbers) {
        std::vector<int> partial_sums(numbers.size());
        partial_sums[0] = numbers[0];
        for (int j = 1; j < numbers.size(); ++j) {
            partial_sums[j] = partial_sums[j - 1] + numbers[j];
        }

        return partial_sums;
    }

    void next_phase(const std::vector<int>& numbers, std::vector<int> &new_numbers) {
        new_numbers.resize(numbers.size());

        for (int rank = 0; rank < numbers.size(); ++rank) {
            auto partial_sums = partial_sum(numbers);
            int n = 0;
            for (int pos = rank; pos < numbers.size(); pos += rank + 1) {
                int run = std::min(rank + 1, (int) numbers.size() - pos);
                if (int modifier = get_modifier(rank, pos); modifier) {
                    n += modifier * (partial_sums[pos + run - 1] - partial_sums[pos] + numbers[pos]);
                }
            }

            n = std::abs(n % 10);

            new_numbers[rank] = n;
        }
    }
}

void aoc2019::day16_part1(std::istream &input, std::ostream &output) {
    auto numbers = read_input(input);
    auto new_numbers = numbers;

    for (int i = 0; i < 100; ++i) {
        next_phase(numbers, new_numbers);
        std::swap(numbers, new_numbers);
    }

    std::copy(numbers.begin(), numbers.begin() + 8, std::ostream_iterator<int>(output));
    output << std::endl;
}

void aoc2019::day16_part2(std::istream &input, std::ostream &output) {
    auto numbers = read_input(input);
    const auto initial_size = numbers.size();

    constexpr auto repetitions = 10000;

    numbers.reserve(repetitions * numbers.size());

    int offset = 0;
    for (int i = 0; i < 7; ++i) {
        offset *= 10;
        offset += numbers[i];
    }

    for (int i = 1; i < repetitions; ++i) {
        std::copy(numbers.begin(), numbers.begin() + initial_size, std::back_inserter(numbers));
    }

    numbers = std::vector(numbers.begin() + offset, numbers.end());

    for (int i = 0; i < 100; ++i) {
        std::vector<int> partial_sums = partial_sum(numbers);
        std::vector<int> new_numbers(numbers.size());

        for (int j = 0; j < numbers.size(); ++j) {
            int n = partial_sums.back() - partial_sums[j] + numbers[j];
            new_numbers[j] = std::abs(n % 10);
        }

        numbers = new_numbers;
    }

    std::copy(numbers.begin(), numbers.begin() + 8, std::ostream_iterator<int>(output));
    output << std::endl;
}
<commit_msg>Reduce allocations even more.<commit_after>#include <iostream>
#include <array>
#include <vector>
#include <cassert>
#include <iterator>
#include "days.hpp"

namespace {
    std::array<int, 4> base_pattern{0, 1, 0, -1};

    int get_modifier(int rank, int pos) {
        pos += 1;
        pos /= rank + 1;

        return base_pattern[pos % 4];
    }

    std::vector<int> read_input(std::istream &input) {
        std::vector<int> result;

        for (char c; input >> c;) {
            assert(std::isdigit(c));
            result.push_back(c - '0');
        }

        return result;
    }

    std::vector<int> partial_sum(const std::vector<int> &numbers) {
        std::vector<int> partial_sums(numbers.size());
        partial_sums[0] = numbers[0];
        for (int j = 1; j < numbers.size(); ++j) {
            partial_sums[j] = partial_sums[j - 1] + numbers[j];
        }

        return partial_sums;
    }

    void next_phase(const std::vector<int>& numbers, std::vector<int> &new_numbers) {
        new_numbers.resize(numbers.size());

        for (int rank = 0; rank < numbers.size(); ++rank) {
            auto partial_sums = partial_sum(numbers);
            int n = 0;
            for (int pos = rank; pos < numbers.size(); pos += rank + 1) {
                int run = std::min(rank + 1, (int) numbers.size() - pos);
                if (int modifier = get_modifier(rank, pos); modifier) {
                    n += modifier * (partial_sums[pos + run - 1] - partial_sums[pos] + numbers[pos]);
                }
            }

            n = std::abs(n % 10);

            new_numbers[rank] = n;
        }
    }
}

void aoc2019::day16_part1(std::istream &input, std::ostream &output) {
    auto numbers = read_input(input);
    auto new_numbers = numbers;

    for (int i = 0; i < 100; ++i) {
        next_phase(numbers, new_numbers);
        std::swap(numbers, new_numbers);
    }

    std::copy(numbers.begin(), numbers.begin() + 8, std::ostream_iterator<int>(output));
    output << std::endl;
}

void aoc2019::day16_part2(std::istream &input, std::ostream &output) {
    auto numbers = read_input(input);
    const auto initial_size = numbers.size();

    constexpr auto repetitions = 10000;

    numbers.reserve(repetitions * numbers.size());

    int offset = 0;
    for (int i = 0; i < 7; ++i) {
        offset *= 10;
        offset += numbers[i];
    }

    for (int i = 1; i < repetitions; ++i) {
        std::copy(numbers.begin(), numbers.begin() + initial_size, std::back_inserter(numbers));
    }

    numbers = std::vector(numbers.begin() + offset, numbers.end());
    std::vector<int> new_numbers(numbers.size());

    for (int i = 0; i < 100; ++i) {
        std::vector<int> partial_sums = partial_sum(numbers);

        for (int j = 0; j < numbers.size(); ++j) {
            int n = partial_sums.back() - partial_sums[j] + numbers[j];
            new_numbers[j] = std::abs(n % 10);
        }

        std::swap(numbers, new_numbers);
    }

    std::copy(numbers.begin(), numbers.begin() + 8, std::ostream_iterator<int>(output));
    output << std::endl;
}
<|endoftext|>


<commit_before>// SPDX-License-Identifier: MIT
/**
   Copyright (c) 2015 - 2022 Beckhoff Automation GmbH & Co. KG
 */

#include "Sockets.h"
#include "Log.h"

#include <algorithm>
#include <climits>
#include <cstring>
#include <exception>
#include <sstream>
#include <system_error>

namespace bhf
{
namespace ads
{
/**
 * Splits the provided host string into host and port. If no port was found
 * in the host string, port is returned untouched acting as a default value.
 */
static void ParseHostAndPort(std::string& host, std::string& port)
{
	auto split = host.find_last_of(":");

	if (host.find_first_of(":") != split) {
		// more than one colon -> IPv6
		const auto closingBracket = host.find_last_of("]");
		if (closingBracket > split) {
			// IPv6 without port
			split = host.npos;
		}
	}
	if (split != host.npos) {
		port = host.substr(split + 1);
		host.resize(split);
	}
	// remove brackets
	if (*host.crbegin() == ']') {
		host.pop_back();
	}
	if (*host.begin() == '[') {
		host.erase(host.begin());
	}
}

AddressList GetListOfAddresses(const std::string& hostPort, const std::string& defaultPort)
{
    auto host = std::string(hostPort);
    auto service = std::string(defaultPort);
    ParseHostAndPort(host, service);

    struct addrinfo* results;
    if (getaddrinfo(host.c_str(), service.c_str(), nullptr, &results)) {
        throw std::runtime_error("Invalid or unknown host: " + host);
    }
    return AddressList { results, [](struct addrinfo* p) { freeaddrinfo(p); }};
}
}
}

static const struct addrinfo addrinfo = []() {
                                            struct addrinfo a;
                                            memset(&a, 0, sizeof(a));
                                            a.ai_family = AF_INET;
                                            a.ai_socktype = SOCK_STREAM;
                                            a.ai_protocol = IPPROTO_TCP;
                                            return a;
                                        } ();

uint32_t getIpv4(const std::string& addr)
{
    struct addrinfo* res;

    InitSocketLibrary();
    const auto status = getaddrinfo(addr.c_str(), nullptr, &addrinfo, &res);
    if (status) {
        throw std::runtime_error("Invalid IPv4 address or unknown hostname: " + addr);
    }

    const auto value = ((struct sockaddr_in*)res->ai_addr)->sin_addr.s_addr;
    freeaddrinfo(res);
    WSACleanup();
    return ntohl(value);
}

IpV4::IpV4(const std::string& addr)
    : value(getIpv4(addr))
{}

IpV4::IpV4(uint32_t __val)
    : value(__val)
{}

bool IpV4::operator<(const IpV4& ref) const
{
    return value < ref.value;
}

bool IpV4::operator==(const IpV4& ref) const
{
    return value == ref.value;
}

Socket::Socket(const struct addrinfo* const host, const int type)
    : m_WSAInitialized(!InitSocketLibrary()),
    m_DestAddr(SOCK_DGRAM == type ? reinterpret_cast<const struct sockaddr*>(&m_SockAddress) : nullptr),
    m_DestAddrLen(0)
{
    for (auto rp = host; rp; rp = rp->ai_next) {
        m_Socket = socket(rp->ai_family, type, 0);
        if (INVALID_SOCKET == m_Socket) {
            continue;
        }
        if (SOCK_STREAM == type) {
            if (::connect(m_Socket, rp->ai_addr, rp->ai_addrlen)) {
                LOG_WARN("Socket(): connect failed");
                closesocket(m_Socket);
                m_Socket = INVALID_SOCKET;
                continue;
            }
        } else { /*if (SOCK_DGRAM == type)*/
            m_DestAddrLen = rp->ai_addrlen;
        }
        memcpy(&m_SockAddress, rp->ai_addr, std::min<size_t>(sizeof(m_SockAddress), rp->ai_addrlen));
        return;
    }
    LOG_ERROR("Unable to create socket");
    throw std::system_error(WSAGetLastError(), std::system_category());
}

Socket::~Socket()
{
    Shutdown();
    closesocket(m_Socket);

    if (m_WSAInitialized) {
        WSACleanup();
    }
}

void Socket::Shutdown()
{
    shutdown(m_Socket, SHUT_RDWR);
}

size_t Socket::read(uint8_t* buffer, size_t maxBytes, timeval* timeout) const
{
    if (!Select(timeout)) {
        return 0;
    }

    maxBytes = static_cast<int>(std::min<size_t>(INT_MAX, maxBytes));
    const int bytesRead = recv(m_Socket, reinterpret_cast<char*>(buffer), maxBytes, 0);
    if (bytesRead > 0) {
        return bytesRead;
    }
    const auto lastError = WSAGetLastError();
    if ((0 == bytesRead) || (lastError == CONNECTION_CLOSED) || (lastError == CONNECTION_ABORTED)) {
        throw std::runtime_error("connection closed by remote");
    } else {
        LOG_ERROR("read frame failed with error: " << std::dec << std::strerror(lastError));
    }
    return 0;
}

Frame& Socket::read(Frame& frame, timeval* timeout) const
{
    const size_t bytesRead = read(frame.rawData(), frame.capacity(), timeout);
    if (bytesRead) {
        return frame.limit(bytesRead);
    }
    return frame.clear();
}

bool Socket::Select(timeval* timeout) const
{
    /* prepare socket set for select() */
    fd_set readSockets;
    FD_ZERO(&readSockets);
    FD_SET(m_Socket, &readSockets);

    /* wait for receive data */
    const int state = NATIVE_SELECT(m_Socket + 1, &readSockets, nullptr, nullptr, timeout);
    if (0 == state) {
        LOG_ERROR("select() timeout");
        throw TimeoutEx("select() timeout");
    }

    const auto lastError = WSAGetLastError();
    if (lastError == WSAENOTSOCK) {
        throw std::runtime_error("connection closed");
    }

    /* and check if socket was correct */
    if ((1 != state) || (!FD_ISSET(m_Socket, &readSockets))) {
        LOG_ERROR("something strange happen while waiting for socket in state: " <<
                  state << " with error: " << std::strerror(lastError));
        return false;
    }
    return true;
}

size_t Socket::write(const Frame& frame) const
{
    if (frame.size() > INT_MAX) {
        LOG_ERROR("frame length: " << frame.size() << " exceeds maximum length for sockets");
        return 0;
    }

    const int bufferLength = static_cast<int>(frame.size());
    const char* const buffer = reinterpret_cast<const char*>(frame.data());
    const int status = sendto(m_Socket, buffer, bufferLength, 0, m_DestAddr, m_DestAddrLen);

    if (SOCKET_ERROR == status) {
        LOG_ERROR("write frame failed with error: " << std::strerror(WSAGetLastError()));
        return 0;
    }
    return status;
}

TcpSocket::TcpSocket(const struct addrinfo* const host)
    : Socket(host, SOCK_STREAM)
{
    // AdsDll.lib seems to use TCP_NODELAY, we use it to be compatible
    const int enable = 0;
    if (setsockopt(m_Socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&enable, sizeof(enable))) {
        LOG_WARN("Enabling TCP_NODELAY failed");
    }
}

uint32_t TcpSocket::Connect() const
{
    struct sockaddr_storage source;
    socklen_t len = sizeof(source);

    if (getsockname(m_Socket, reinterpret_cast<sockaddr*>(&source), &len)) {
        LOG_ERROR("Read local tcp/ip address failed");
        throw std::runtime_error("Read local tcp/ip address failed");
    }

    switch (source.ss_family) {
    case AF_INET:
        return ntohl(reinterpret_cast<sockaddr_in*>(&source)->sin_addr.s_addr);

    case AF_INET6:
        return 0xffffffff;

    default:
        return 0;
    }
}

bool TcpSocket::IsConnectedTo(const struct addrinfo* const targetAddresses) const
{
    for (auto rp = targetAddresses; rp; rp = rp->ai_next) {
        if (m_SockAddress.ss_family == rp->ai_family) {
            if (!memcmp(&m_SockAddress, rp->ai_addr, std::min<size_t>(sizeof(m_SockAddress), rp->ai_addrlen))) {
                return true;
            }
        }
    }
    return false;
}

UdpSocket::UdpSocket(const struct addrinfo* const host)
    : Socket(host, SOCK_DGRAM)
{}
<commit_msg>Sockets: uncrustify the source code<commit_after>// SPDX-License-Identifier: MIT
/**
   Copyright (c) 2015 - 2022 Beckhoff Automation GmbH & Co. KG
 */

#include "Sockets.h"
#include "Log.h"

#include <algorithm>
#include <climits>
#include <cstring>
#include <exception>
#include <sstream>
#include <system_error>

namespace bhf
{
namespace ads
{
/**
 * Splits the provided host string into host and port. If no port was found
 * in the host string, port is returned untouched acting as a default value.
 */
static void ParseHostAndPort(std::string& host, std::string& port)
{
    auto split = host.find_last_of(":");

    if (host.find_first_of(":") != split) {
        // more than one colon -> IPv6
        const auto closingBracket = host.find_last_of("]");
        if (closingBracket > split) {
            // IPv6 without port
            split = host.npos;
        }
    }
    if (split != host.npos) {
        port = host.substr(split + 1);
        host.resize(split);
    }
    // remove brackets
    if (*host.crbegin() == ']') {
        host.pop_back();
    }
    if (*host.begin() == '[') {
        host.erase(host.begin());
    }
}

AddressList GetListOfAddresses(const std::string& hostPort, const std::string& defaultPort)
{
    auto host = std::string(hostPort);
    auto service = std::string(defaultPort);
    ParseHostAndPort(host, service);

    struct addrinfo* results;
    if (getaddrinfo(host.c_str(), service.c_str(), nullptr, &results)) {
        throw std::runtime_error("Invalid or unknown host: " + host);
    }
    return AddressList { results, [](struct addrinfo* p) { freeaddrinfo(p); }};
}
}
}

static const struct addrinfo addrinfo = []() {
                                            struct addrinfo a;
                                            memset(&a, 0, sizeof(a));
                                            a.ai_family = AF_INET;
                                            a.ai_socktype = SOCK_STREAM;
                                            a.ai_protocol = IPPROTO_TCP;
                                            return a;
                                        } ();

uint32_t getIpv4(const std::string& addr)
{
    struct addrinfo* res;

    InitSocketLibrary();
    const auto status = getaddrinfo(addr.c_str(), nullptr, &addrinfo, &res);
    if (status) {
        throw std::runtime_error("Invalid IPv4 address or unknown hostname: " + addr);
    }

    const auto value = ((struct sockaddr_in*)res->ai_addr)->sin_addr.s_addr;
    freeaddrinfo(res);
    WSACleanup();
    return ntohl(value);
}

IpV4::IpV4(const std::string& addr)
    : value(getIpv4(addr))
{}

IpV4::IpV4(uint32_t __val)
    : value(__val)
{}

bool IpV4::operator<(const IpV4& ref) const
{
    return value < ref.value;
}

bool IpV4::operator==(const IpV4& ref) const
{
    return value == ref.value;
}

Socket::Socket(const struct addrinfo* const host, const int type)
    : m_WSAInitialized(!InitSocketLibrary()),
    m_DestAddr(SOCK_DGRAM == type ? reinterpret_cast<const struct sockaddr*>(&m_SockAddress) : nullptr),
    m_DestAddrLen(0)
{
    for (auto rp = host; rp; rp = rp->ai_next) {
        m_Socket = socket(rp->ai_family, type, 0);
        if (INVALID_SOCKET == m_Socket) {
            continue;
        }
        if (SOCK_STREAM == type) {
            if (::connect(m_Socket, rp->ai_addr, rp->ai_addrlen)) {
                LOG_WARN("Socket(): connect failed");
                closesocket(m_Socket);
                m_Socket = INVALID_SOCKET;
                continue;
            }
        } else { /*if (SOCK_DGRAM == type)*/
            m_DestAddrLen = rp->ai_addrlen;
        }
        memcpy(&m_SockAddress, rp->ai_addr, std::min<size_t>(sizeof(m_SockAddress), rp->ai_addrlen));
        return;
    }
    LOG_ERROR("Unable to create socket");
    throw std::system_error(WSAGetLastError(), std::system_category());
}

Socket::~Socket()
{
    Shutdown();
    closesocket(m_Socket);

    if (m_WSAInitialized) {
        WSACleanup();
    }
}

void Socket::Shutdown()
{
    shutdown(m_Socket, SHUT_RDWR);
}

size_t Socket::read(uint8_t* buffer, size_t maxBytes, timeval* timeout) const
{
    if (!Select(timeout)) {
        return 0;
    }

    maxBytes = static_cast<int>(std::min<size_t>(INT_MAX, maxBytes));
    const int bytesRead = recv(m_Socket, reinterpret_cast<char*>(buffer), maxBytes, 0);
    if (bytesRead > 0) {
        return bytesRead;
    }
    const auto lastError = WSAGetLastError();
    if ((0 == bytesRead) || (lastError == CONNECTION_CLOSED) || (lastError == CONNECTION_ABORTED)) {
        throw std::runtime_error("connection closed by remote");
    } else {
        LOG_ERROR("read frame failed with error: " << std::dec << std::strerror(lastError));
    }
    return 0;
}

Frame& Socket::read(Frame& frame, timeval* timeout) const
{
    const size_t bytesRead = read(frame.rawData(), frame.capacity(), timeout);
    if (bytesRead) {
        return frame.limit(bytesRead);
    }
    return frame.clear();
}

bool Socket::Select(timeval* timeout) const
{
    /* prepare socket set for select() */
    fd_set readSockets;
    FD_ZERO(&readSockets);
    FD_SET(m_Socket, &readSockets);

    /* wait for receive data */
    const int state = NATIVE_SELECT(m_Socket + 1, &readSockets, nullptr, nullptr, timeout);
    if (0 == state) {
        LOG_ERROR("select() timeout");
        throw TimeoutEx("select() timeout");
    }

    const auto lastError = WSAGetLastError();
    if (lastError == WSAENOTSOCK) {
        throw std::runtime_error("connection closed");
    }

    /* and check if socket was correct */
    if ((1 != state) || (!FD_ISSET(m_Socket, &readSockets))) {
        LOG_ERROR("something strange happen while waiting for socket in state: " <<
                  state << " with error: " << std::strerror(lastError));
        return false;
    }
    return true;
}

size_t Socket::write(const Frame& frame) const
{
    if (frame.size() > INT_MAX) {
        LOG_ERROR("frame length: " << frame.size() << " exceeds maximum length for sockets");
        return 0;
    }

    const int bufferLength = static_cast<int>(frame.size());
    const char* const buffer = reinterpret_cast<const char*>(frame.data());
    const int status = sendto(m_Socket, buffer, bufferLength, 0, m_DestAddr, m_DestAddrLen);

    if (SOCKET_ERROR == status) {
        LOG_ERROR("write frame failed with error: " << std::strerror(WSAGetLastError()));
        return 0;
    }
    return status;
}

TcpSocket::TcpSocket(const struct addrinfo* const host)
    : Socket(host, SOCK_STREAM)
{
    // AdsDll.lib seems to use TCP_NODELAY, we use it to be compatible
    const int enable = 0;
    if (setsockopt(m_Socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&enable, sizeof(enable))) {
        LOG_WARN("Enabling TCP_NODELAY failed");
    }
}

uint32_t TcpSocket::Connect() const
{
    struct sockaddr_storage source;
    socklen_t len = sizeof(source);

    if (getsockname(m_Socket, reinterpret_cast<sockaddr*>(&source), &len)) {
        LOG_ERROR("Read local tcp/ip address failed");
        throw std::runtime_error("Read local tcp/ip address failed");
    }

    switch (source.ss_family) {
    case AF_INET:
        return ntohl(reinterpret_cast<sockaddr_in*>(&source)->sin_addr.s_addr);

    case AF_INET6:
        return 0xffffffff;

    default:
        return 0;
    }
}

bool TcpSocket::IsConnectedTo(const struct addrinfo* const targetAddresses) const
{
    for (auto rp = targetAddresses; rp; rp = rp->ai_next) {
        if (m_SockAddress.ss_family == rp->ai_family) {
            if (!memcmp(&m_SockAddress, rp->ai_addr, std::min<size_t>(sizeof(m_SockAddress), rp->ai_addrlen))) {
                return true;
            }
        }
    }
    return false;
}

UdpSocket::UdpSocket(const struct addrinfo* const host)
    : Socket(host, SOCK_DGRAM)
{}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkJPEGReader.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkJPEGReader.h"

#include "vtkDataArray.h"
#include "vtkImageData.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkToolkits.h"

extern "C" {
#include "vtk_jpeg.h"
#if defined(__sgi) && !defined(__GNUC__)
#  if   (_COMPILER_VERSION >= 730)
#  pragma set woff 3505
#  endif
#endif
#include <setjmp.h>
}

vtkStandardNewMacro(vtkJPEGReader);

#if defined ( _MSC_VER )
#if defined ( _WIN64 )
#pragma warning ( disable : 4324 ) // structure was padded at end...
#endif
#endif

// create an error handler for jpeg that
// can longjmp out of the jpeg library
struct vtk_jpeg_error_mgr
{
  struct jpeg_error_mgr pub;    /* "public" fields */
  jmp_buf setjmp_buffer;        /* for return to caller */
  vtkJPEGReader* JPEGReader;
};

// this is called on jpeg error conditions
extern "C" void vtk_jpeg_error_exit (j_common_ptr cinfo)
{
  /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
  vtk_jpeg_error_mgr * err = reinterpret_cast<vtk_jpeg_error_mgr*>(cinfo->err);

  /* Return control to the setjmp point */
  longjmp(err->setjmp_buffer, 1);
}

extern "C" void vtk_jpeg_output_message (j_common_ptr cinfo)
{
  char buffer[JMSG_LENGTH_MAX];

  /* Create the message */
  (*cinfo->err->format_message) (cinfo, buffer);
  vtk_jpeg_error_mgr * err = reinterpret_cast<vtk_jpeg_error_mgr*>(cinfo->err);
  vtkWarningWithObjectMacro(err->JPEGReader,
                            "libjpeg error: " <<  buffer);
}

extern "C" void jpg_null (j_decompress_ptr vtkNotUsed(cinfo))
{
}

extern "C" boolean fill_input_buffer (j_decompress_ptr vtkNotUsed(cinfo))
{
  vtkGenericWarningMacro(<< "libjpeg error: unexpected end of JPEG data!");
  return TRUE;
}

extern "C" void skip_input_data (j_decompress_ptr cinfo, long num_bytes)
{
  struct jpeg_source_mgr* src = (struct jpeg_source_mgr*) cinfo->src;

  if (num_bytes > 0)
    {
    src->next_input_byte += (size_t) num_bytes;
    src->bytes_in_buffer -= (size_t) num_bytes;
    }
}

// Read JPEG image from a memory buffer
extern "C" void jpeg_mem_src (j_decompress_ptr cinfo, void* buffer, long nbytes)
{
  cinfo->src = (struct jpeg_source_mgr *)
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
      sizeof(struct jpeg_source_mgr));
  cinfo->src = (struct jpeg_source_mgr*) cinfo->src;
  cinfo->src->init_source = jpg_null;
  cinfo->src->fill_input_buffer = fill_input_buffer;
  cinfo->src->skip_input_data = skip_input_data;
  cinfo->src->resync_to_restart = jpeg_resync_to_restart;
  cinfo->src->term_source = jpg_null;
  cinfo->src->bytes_in_buffer = nbytes;
  cinfo->src->next_input_byte = (const JOCTET*)buffer;
}

#ifdef _MSC_VER
// Let us get rid of this funny warning on /W4:
// warning C4611: interaction between '_setjmp' and C++ object
// destruction is non-portable
#pragma warning( disable : 4611 )
#endif

void vtkJPEGReader::ExecuteInformation()
{
  this->ComputeInternalFileName(this->DataExtent[4]);
  if (this->InternalFileName == NULL && this->MemoryBuffer == NULL)
    {
    return;
    }

  FILE *fp = NULL;

  if (!this->MemoryBuffer)
    {
    fp = fopen(this->InternalFileName, "rb");
    if (!fp)
      {
      vtkErrorWithObjectMacro(this,
                              "Unable to open file "
                              << this->InternalFileName);
      return;
      }
    }
  else
    {
    if (this->MemoryBufferLength == 0)
      {
      vtkErrorWithObjectMacro(this,
                              "Trying to read a JPEG image from "
                              "a zero-length memory buffer!");
      return;
      }
    }

  // create jpeg decompression object and error handler
  struct jpeg_decompress_struct cinfo;
  struct vtk_jpeg_error_mgr jerr;
  jerr.JPEGReader = this;

  cinfo.err = jpeg_std_error(&jerr.pub);
  // for any jpeg error call vtk_jpeg_error_exit
  jerr.pub.error_exit = vtk_jpeg_error_exit;
  // for any output message call vtk_jpeg_output_message
  jerr.pub.output_message = vtk_jpeg_output_message;
  if (setjmp(jerr.setjmp_buffer))
    {
    // clean up
    jpeg_destroy_decompress(&cinfo);
    // close the file
    if (fp)
      {
      fclose(fp);
      // this is not a valid jpeg file
      vtkErrorWithObjectMacro(this, "libjpeg could not read file: "
                              << this->InternalFileName);
      }
    else
      {
      vtkErrorWithObjectMacro(this, "libjpeg could not read file from memory buffer: "
                              << static_cast<void*>(this->MemoryBuffer));
      }
    return;
    }
  jpeg_create_decompress(&cinfo);

  // set the source file
  if (fp)
    {
    jpeg_stdio_src(&cinfo, fp);
    }
  else
    {
    jpeg_mem_src(&cinfo, this->MemoryBuffer, this->MemoryBufferLength);
    }

  // read the header
  jpeg_read_header(&cinfo, TRUE);

  // force the output image size to be calculated (we could have used
  // cinfo.image_height etc. but that would preclude using libjpeg's
  // ability to scale an image on input).
  jpeg_calc_output_dimensions(&cinfo);

  // pull out the width/height, etc.
  this->DataExtent[0] = 0;
  this->DataExtent[1] = cinfo.output_width - 1;
  this->DataExtent[2] = 0;
  this->DataExtent[3] = cinfo.output_height - 1;

  this->SetDataScalarTypeToUnsignedChar();
  this->SetNumberOfScalarComponents( cinfo.output_components );

  this->vtkImageReader2::ExecuteInformation();

  // close the file
  jpeg_destroy_decompress(&cinfo);

  if (fp)
    {
    fclose(fp);
    }
}

template <class OT>
int vtkJPEGReaderUpdate2(vtkJPEGReader *self, OT *outPtr,
                          int *outExt, vtkIdType *outInc, long)
{
  unsigned int ui;
  int i;
  FILE *fp = 0;

  if (!self->GetMemoryBuffer())
    {
    fp = fopen(self->GetInternalFileName(), "rb");
    if (!fp)
      {
      return 1;
      }
    }

  // create jpeg decompression object and error handler
  struct jpeg_decompress_struct cinfo;
  struct vtk_jpeg_error_mgr jerr;
  jerr.JPEGReader = self;

  cinfo.err = jpeg_std_error(&jerr.pub);
  // for any jpeg error call vtk_jpeg_error_exit
  jerr.pub.error_exit = vtk_jpeg_error_exit;
  // for any output message call vtk_jpeg_output_message
  jerr.pub.output_message = vtk_jpeg_output_message;
  if (setjmp(jerr.setjmp_buffer))
    {
    // clean up
    jpeg_destroy_decompress(&cinfo);
    // close the file
    if (fp)
      {
      fclose(fp);
      }

    // this is not a valid jpeg file
    return 2;
    }
  jpeg_create_decompress(&cinfo);

  // set the source file
  if (fp)
    {
    jpeg_stdio_src(&cinfo, fp);
    }
  else
    {
    jpeg_mem_src(&cinfo, self->GetMemoryBuffer(), self->GetMemoryBufferLength());
    }

  // read the header
  jpeg_read_header(&cinfo, TRUE);

  // prepare to read the bulk data
  jpeg_start_decompress(&cinfo);

  int rowbytes = cinfo.output_components * cinfo.output_width;
  unsigned char *tempImage = new unsigned char [rowbytes*cinfo.output_height];
  JSAMPROW *row_pointers = new JSAMPROW [cinfo.output_height];
  for (ui = 0; ui < cinfo.output_height; ++ui)
    {
    row_pointers[ui] = tempImage + rowbytes*ui;
    }

  // read the bulk data
  unsigned int remainingRows;
  while (cinfo.output_scanline < cinfo.output_height)
    {
    remainingRows = cinfo.output_height - cinfo.output_scanline;
    jpeg_read_scanlines(&cinfo, &row_pointers[cinfo.output_scanline],
                        remainingRows);
    }

  // finish the decompression step
  jpeg_finish_decompress(&cinfo);

  // destroy the decompression object
  jpeg_destroy_decompress(&cinfo);

  // copy the data into the outPtr
  OT *outPtr2;
  outPtr2 = outPtr;
  long outSize = cinfo.output_components*(outExt[1] - outExt[0] + 1);
  for (i = outExt[2]; i <= outExt[3]; ++i)
    {
    memcpy(outPtr2,
           row_pointers[cinfo.output_height - i - 1]
           + outExt[0]*cinfo.output_components,
           outSize);
    outPtr2 += outInc[1];
    }
  delete [] tempImage;
  delete [] row_pointers;

  // close the file
  if (fp)
    {
    fclose(fp);
    }
  return 0;
}

//----------------------------------------------------------------------------
// This function reads in one data of data.
// templated to handle different data types.
template <class OT>
void vtkJPEGReaderUpdate(vtkJPEGReader *self, vtkImageData *data, OT *outPtr)
{
  vtkIdType outIncr[3];
  int outExtent[6];
  OT *outPtr2;

  data->GetExtent(outExtent);
  data->GetIncrements(outIncr);

  long pixSize = data->GetNumberOfScalarComponents()*sizeof(OT);

  outPtr2 = outPtr;
  int idx2;
  for (idx2 = outExtent[4]; idx2 <= outExtent[5]; ++idx2)
    {
    self->ComputeInternalFileName(idx2);
    // read in a JPEG file
    if ( vtkJPEGReaderUpdate2(self, outPtr2, outExtent, outIncr, pixSize) == 2 )
      {
      const char* fn = self->GetInternalFileName();
      vtkErrorWithObjectMacro(self, "libjpeg could not read file: " << fn);
      }

    self->UpdateProgress((idx2 - outExtent[4])/
                         (outExtent[5] - outExtent[4] + 1.0));
    outPtr2 += outIncr[2];
    }
}

//----------------------------------------------------------------------------
// This function reads a data from a file.  The datas extent/axes
// are assumed to be the same as the file extent/order.
void vtkJPEGReader::ExecuteDataWithInformation(vtkDataObject *output,
                                               vtkInformation *outInfo)
{
  vtkImageData *data = this->AllocateOutputData(output, outInfo);

  if (this->InternalFileName == NULL)
    {
    vtkErrorMacro(<< "Either a FileName or FilePrefix must be specified.");
    return;
    }

  this->ComputeDataIncrements();

  data->GetPointData()->GetScalars()->SetName("JPEGImage");

  // Call the correct templated function for the output
  void *outPtr;

  // Call the correct templated function for the input
  outPtr = data->GetScalarPointer();
  switch (data->GetScalarType())
    {
    vtkTemplateMacro(vtkJPEGReaderUpdate(this, data, (VTK_TT *)(outPtr)));
    default:
      vtkErrorMacro(<< "UpdateFromFile: Unknown data type");
    }
}

int vtkJPEGReader::CanReadFile(const char* fname)
{
  // open the file
  FILE *fp = fopen(fname, "rb");
  if (!fp)
    {
    return 0;
    }
  // read the first two bytes
  char magic[2];
  int n = static_cast<int>(fread(magic, sizeof(magic), 1, fp));
  if (n != 1)
    {
    fclose(fp);
    return 0;
    }
  // check for the magic stuff:
  // 0xFF followed by 0xD8
  if( ( (static_cast<unsigned char>(magic[0]) != 0xFF) ||
        (static_cast<unsigned char>(magic[1]) != 0xD8) ) )
    {
    fclose(fp);
    return 0;
    }
  // go back to the start of the file
  fseek(fp, 0, SEEK_SET);
  // magic number is ok, try and read the header
  struct vtk_jpeg_error_mgr jerr;
  jerr.JPEGReader = this;
  struct jpeg_decompress_struct cinfo;
  cinfo.err = jpeg_std_error(&jerr.pub);
  // for any jpeg error call vtk_jpeg_error_exit
  jerr.pub.error_exit = vtk_jpeg_error_exit;
  // for any output message call vtk_jpeg_error_exit
  jerr.pub.output_message = vtk_jpeg_error_exit;
  // set the jump point, if there is a jpeg error or warning
  // this will evaluate to true
  if (setjmp(jerr.setjmp_buffer))
    {
    // clean up
    jpeg_destroy_decompress(&cinfo);
    // close the file
    fclose(fp);
    // this is not a valid jpeg file
    return 0;
    }
  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress(&cinfo);
  /* Step 2: specify data source (eg, a file) */
  jpeg_stdio_src(&cinfo, fp);
  /* Step 3: read file parameters with jpeg_read_header() */
  jpeg_read_header(&cinfo, TRUE);

  // if no errors have occurred yet, then it must be jpeg
  jpeg_destroy_decompress(&cinfo);
  fclose(fp);
  return 3;
}
#ifdef _MSC_VER
// Put the warning back
#pragma warning( default : 4611 )
#endif

//----------------------------------------------------------------------------
void vtkJPEGReader::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}
<commit_msg>Fix to use newer libjpeg API.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkJPEGReader.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkJPEGReader.h"

#include "vtkDataArray.h"
#include "vtkImageData.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkToolkits.h"

extern "C" {
#include "vtk_jpeg.h"
#if defined(__sgi) && !defined(__GNUC__)
#  if   (_COMPILER_VERSION >= 730)
#  pragma set woff 3505
#  endif
#endif
#include <setjmp.h>
}

vtkStandardNewMacro(vtkJPEGReader);

#if defined ( _MSC_VER )
#if defined ( _WIN64 )
#pragma warning ( disable : 4324 ) // structure was padded at end...
#endif
#endif

// create an error handler for jpeg that
// can longjmp out of the jpeg library
struct vtk_jpeg_error_mgr
{
  struct jpeg_error_mgr pub;    /* "public" fields */
  jmp_buf setjmp_buffer;        /* for return to caller */
  vtkJPEGReader* JPEGReader;
};

// this is called on jpeg error conditions
extern "C" void vtk_jpeg_error_exit (j_common_ptr cinfo)
{
  /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
  vtk_jpeg_error_mgr * err = reinterpret_cast<vtk_jpeg_error_mgr*>(cinfo->err);

  /* Return control to the setjmp point */
  longjmp(err->setjmp_buffer, 1);
}

extern "C" void vtk_jpeg_output_message (j_common_ptr cinfo)
{
  char buffer[JMSG_LENGTH_MAX];

  /* Create the message */
  (*cinfo->err->format_message) (cinfo, buffer);
  vtk_jpeg_error_mgr * err = reinterpret_cast<vtk_jpeg_error_mgr*>(cinfo->err);
  vtkWarningWithObjectMacro(err->JPEGReader,
                            "libjpeg error: " <<  buffer);
}

extern "C" void jpg_null (j_decompress_ptr vtkNotUsed(cinfo))
{
}

extern "C" boolean fill_input_buffer (j_decompress_ptr vtkNotUsed(cinfo))
{
  vtkGenericWarningMacro(<< "libjpeg error: unexpected end of JPEG data!");
  return TRUE;
}

extern "C" void skip_input_data (j_decompress_ptr cinfo, long num_bytes)
{
  struct jpeg_source_mgr* src = (struct jpeg_source_mgr*) cinfo->src;

  if (num_bytes > 0)
    {
    src->next_input_byte += (size_t) num_bytes;
    src->bytes_in_buffer -= (size_t) num_bytes;
    }
}

// Read JPEG image from a memory buffer
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
extern "C" void jMemSrc (j_decompress_ptr cinfo, void* buffer, long nbytes)
#else
extern "C" void jpeg_mem_src (j_decompress_ptr cinfo, void* buffer, long nbytes)
#endif
{
  cinfo->src = (struct jpeg_source_mgr *)
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
      sizeof(struct jpeg_source_mgr));
  cinfo->src = (struct jpeg_source_mgr*) cinfo->src;
  cinfo->src->init_source = jpg_null;
  cinfo->src->fill_input_buffer = fill_input_buffer;
  cinfo->src->skip_input_data = skip_input_data;
  cinfo->src->resync_to_restart = jpeg_resync_to_restart;
  cinfo->src->term_source = jpg_null;
  cinfo->src->bytes_in_buffer = nbytes;
  cinfo->src->next_input_byte = (const JOCTET*)buffer;
}

#ifdef _MSC_VER
// Let us get rid of this funny warning on /W4:
// warning C4611: interaction between '_setjmp' and C++ object
// destruction is non-portable
#pragma warning( disable : 4611 )
#endif

void vtkJPEGReader::ExecuteInformation()
{
  this->ComputeInternalFileName(this->DataExtent[4]);
  if (this->InternalFileName == NULL && this->MemoryBuffer == NULL)
    {
    return;
    }

  FILE *fp = NULL;

  if (!this->MemoryBuffer)
    {
    fp = fopen(this->InternalFileName, "rb");
    if (!fp)
      {
      vtkErrorWithObjectMacro(this,
                              "Unable to open file "
                              << this->InternalFileName);
      return;
      }
    }
  else
    {
    if (this->MemoryBufferLength == 0)
      {
      vtkErrorWithObjectMacro(this,
                              "Trying to read a JPEG image from "
                              "a zero-length memory buffer!");
      return;
      }
    }

  // create jpeg decompression object and error handler
  struct jpeg_decompress_struct cinfo;
  struct vtk_jpeg_error_mgr jerr;
  jerr.JPEGReader = this;

  cinfo.err = jpeg_std_error(&jerr.pub);
  // for any jpeg error call vtk_jpeg_error_exit
  jerr.pub.error_exit = vtk_jpeg_error_exit;
  // for any output message call vtk_jpeg_output_message
  jerr.pub.output_message = vtk_jpeg_output_message;
  if (setjmp(jerr.setjmp_buffer))
    {
    // clean up
    jpeg_destroy_decompress(&cinfo);
    // close the file
    if (fp)
      {
      fclose(fp);
      // this is not a valid jpeg file
      vtkErrorWithObjectMacro(this, "libjpeg could not read file: "
                              << this->InternalFileName);
      }
    else
      {
      vtkErrorWithObjectMacro(this, "libjpeg could not read file from memory buffer: "
                              << static_cast<void*>(this->MemoryBuffer));
      }
    return;
    }
  jpeg_create_decompress(&cinfo);

  // set the source file
  if (fp)
    {
    jpeg_stdio_src(&cinfo, fp);
    }
  else
    {
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
    jMemSrc(&cinfo, this->MemoryBuffer, this->MemoryBufferLength);
#else
    jpeg_mem_src(&cinfo, this->MemoryBuffer, this->MemoryBufferLength);
#endif
    }

  // read the header
  jpeg_read_header(&cinfo, TRUE);

  // force the output image size to be calculated (we could have used
  // cinfo.image_height etc. but that would preclude using libjpeg's
  // ability to scale an image on input).
  jpeg_calc_output_dimensions(&cinfo);

  // pull out the width/height, etc.
  this->DataExtent[0] = 0;
  this->DataExtent[1] = cinfo.output_width - 1;
  this->DataExtent[2] = 0;
  this->DataExtent[3] = cinfo.output_height - 1;

  this->SetDataScalarTypeToUnsignedChar();
  this->SetNumberOfScalarComponents( cinfo.output_components );

  this->vtkImageReader2::ExecuteInformation();

  // close the file
  jpeg_destroy_decompress(&cinfo);

  if (fp)
    {
    fclose(fp);
    }
}

template <class OT>
int vtkJPEGReaderUpdate2(vtkJPEGReader *self, OT *outPtr,
                          int *outExt, vtkIdType *outInc, long)
{
  unsigned int ui;
  int i;
  FILE *fp = 0;

  if (!self->GetMemoryBuffer())
    {
    fp = fopen(self->GetInternalFileName(), "rb");
    if (!fp)
      {
      return 1;
      }
    }

  // create jpeg decompression object and error handler
  struct jpeg_decompress_struct cinfo;
  struct vtk_jpeg_error_mgr jerr;
  jerr.JPEGReader = self;

  cinfo.err = jpeg_std_error(&jerr.pub);
  // for any jpeg error call vtk_jpeg_error_exit
  jerr.pub.error_exit = vtk_jpeg_error_exit;
  // for any output message call vtk_jpeg_output_message
  jerr.pub.output_message = vtk_jpeg_output_message;
  if (setjmp(jerr.setjmp_buffer))
    {
    // clean up
    jpeg_destroy_decompress(&cinfo);
    // close the file
    if (fp)
      {
      fclose(fp);
      }

    // this is not a valid jpeg file
    return 2;
    }
  jpeg_create_decompress(&cinfo);

  // set the source file
  if (fp)
    {
    jpeg_stdio_src(&cinfo, fp);
    }
  else
    {
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
    jMemSrc(&cinfo, self->GetMemoryBuffer(), self->GetMemoryBufferLength());
#else
    jpeg_mem_src(&cinfo, self->GetMemoryBuffer(), self->GetMemoryBufferLength());
#endif
    }

  // read the header
  jpeg_read_header(&cinfo, TRUE);

  // prepare to read the bulk data
  jpeg_start_decompress(&cinfo);

  int rowbytes = cinfo.output_components * cinfo.output_width;
  unsigned char *tempImage = new unsigned char [rowbytes*cinfo.output_height];
  JSAMPROW *row_pointers = new JSAMPROW [cinfo.output_height];
  for (ui = 0; ui < cinfo.output_height; ++ui)
    {
    row_pointers[ui] = tempImage + rowbytes*ui;
    }

  // read the bulk data
  unsigned int remainingRows;
  while (cinfo.output_scanline < cinfo.output_height)
    {
    remainingRows = cinfo.output_height - cinfo.output_scanline;
    jpeg_read_scanlines(&cinfo, &row_pointers[cinfo.output_scanline],
                        remainingRows);
    }

  // finish the decompression step
  jpeg_finish_decompress(&cinfo);

  // destroy the decompression object
  jpeg_destroy_decompress(&cinfo);

  // copy the data into the outPtr
  OT *outPtr2;
  outPtr2 = outPtr;
  long outSize = cinfo.output_components*(outExt[1] - outExt[0] + 1);
  for (i = outExt[2]; i <= outExt[3]; ++i)
    {
    memcpy(outPtr2,
           row_pointers[cinfo.output_height - i - 1]
           + outExt[0]*cinfo.output_components,
           outSize);
    outPtr2 += outInc[1];
    }
  delete [] tempImage;
  delete [] row_pointers;

  // close the file
  if (fp)
    {
    fclose(fp);
    }
  return 0;
}

//----------------------------------------------------------------------------
// This function reads in one data of data.
// templated to handle different data types.
template <class OT>
void vtkJPEGReaderUpdate(vtkJPEGReader *self, vtkImageData *data, OT *outPtr)
{
  vtkIdType outIncr[3];
  int outExtent[6];
  OT *outPtr2;

  data->GetExtent(outExtent);
  data->GetIncrements(outIncr);

  long pixSize = data->GetNumberOfScalarComponents()*sizeof(OT);

  outPtr2 = outPtr;
  int idx2;
  for (idx2 = outExtent[4]; idx2 <= outExtent[5]; ++idx2)
    {
    self->ComputeInternalFileName(idx2);
    // read in a JPEG file
    if ( vtkJPEGReaderUpdate2(self, outPtr2, outExtent, outIncr, pixSize) == 2 )
      {
      const char* fn = self->GetInternalFileName();
      vtkErrorWithObjectMacro(self, "libjpeg could not read file: " << fn);
      }

    self->UpdateProgress((idx2 - outExtent[4])/
                         (outExtent[5] - outExtent[4] + 1.0));
    outPtr2 += outIncr[2];
    }
}

//----------------------------------------------------------------------------
// This function reads a data from a file.  The datas extent/axes
// are assumed to be the same as the file extent/order.
void vtkJPEGReader::ExecuteDataWithInformation(vtkDataObject *output,
                                               vtkInformation *outInfo)
{
  vtkImageData *data = this->AllocateOutputData(output, outInfo);

  if (this->InternalFileName == NULL)
    {
    vtkErrorMacro(<< "Either a FileName or FilePrefix must be specified.");
    return;
    }

  this->ComputeDataIncrements();

  data->GetPointData()->GetScalars()->SetName("JPEGImage");

  // Call the correct templated function for the output
  void *outPtr;

  // Call the correct templated function for the input
  outPtr = data->GetScalarPointer();
  switch (data->GetScalarType())
    {
    vtkTemplateMacro(vtkJPEGReaderUpdate(this, data, (VTK_TT *)(outPtr)));
    default:
      vtkErrorMacro(<< "UpdateFromFile: Unknown data type");
    }
}

int vtkJPEGReader::CanReadFile(const char* fname)
{
  // open the file
  FILE *fp = fopen(fname, "rb");
  if (!fp)
    {
    return 0;
    }
  // read the first two bytes
  char magic[2];
  int n = static_cast<int>(fread(magic, sizeof(magic), 1, fp));
  if (n != 1)
    {
    fclose(fp);
    return 0;
    }
  // check for the magic stuff:
  // 0xFF followed by 0xD8
  if( ( (static_cast<unsigned char>(magic[0]) != 0xFF) ||
        (static_cast<unsigned char>(magic[1]) != 0xD8) ) )
    {
    fclose(fp);
    return 0;
    }
  // go back to the start of the file
  fseek(fp, 0, SEEK_SET);
  // magic number is ok, try and read the header
  struct vtk_jpeg_error_mgr jerr;
  jerr.JPEGReader = this;
  struct jpeg_decompress_struct cinfo;
  cinfo.err = jpeg_std_error(&jerr.pub);
  // for any jpeg error call vtk_jpeg_error_exit
  jerr.pub.error_exit = vtk_jpeg_error_exit;
  // for any output message call vtk_jpeg_error_exit
  jerr.pub.output_message = vtk_jpeg_error_exit;
  // set the jump point, if there is a jpeg error or warning
  // this will evaluate to true
  if (setjmp(jerr.setjmp_buffer))
    {
    // clean up
    jpeg_destroy_decompress(&cinfo);
    // close the file
    fclose(fp);
    // this is not a valid jpeg file
    return 0;
    }
  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress(&cinfo);
  /* Step 2: specify data source (eg, a file) */
  jpeg_stdio_src(&cinfo, fp);
  /* Step 3: read file parameters with jpeg_read_header() */
  jpeg_read_header(&cinfo, TRUE);

  // if no errors have occurred yet, then it must be jpeg
  jpeg_destroy_decompress(&cinfo);
  fclose(fp);
  return 3;
}
#ifdef _MSC_VER
// Put the warning back
#pragma warning( default : 4611 )
#endif

//----------------------------------------------------------------------------
void vtkJPEGReader::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}
<|endoftext|>


<commit_before>#include "vtkXMLParser.h"
#include "vtkOutputWindow.h"
#include "vtkObjectFactory.h"

class vtkMyXML : public vtkXMLParser
{
public:
  vtkTypeMacro(vtkMyXML, vtkXMLParser);
  static vtkMyXML* New();

private:
  vtkMyXML() {}
  void StartElement(const char*, const char**) {}
  void EndElement(const char*) {}

  vtkMyXML(const vtkMyXML&); // Not implemented
  void operator=(const vtkMyXML&); // Not implemented
};

vtkStandardNewMacro(vtkMyXML);

int main(int argc, char **argv)
{
  int res = 0;
  vtkOutputWindow::GetInstance()->PromptUserOn();
  if ( argc <= 1 )
    {
    cout << "Usage: " << argv[0] << " <xml file>" << endl;
    return 1;
    }

  vtkMyXML *parser = vtkMyXML::New();
  parser->SetFileName(argv[1]);
  if ( ! parser->Parse() )
    {
    cout << "Cannot parse the file: " << argv[1] << endl;
    res = 1;
    }
  parser->SetFileName(0);

  if( !parser->Parse("<xml>This is an XML file</xml>") )
    {
    cout << "Cannot parse message" << endl;
    res = 1;
    }

  parser->Delete();

  return res;
}
<commit_msg>Remove warning<commit_after>#include "vtkXMLParser.h"
#include "vtkOutputWindow.h"
#include "vtkObjectFactory.h"

class vtkMyXML : public vtkXMLParser
{
public:
  vtkTypeMacro(vtkMyXML, vtkXMLParser);
  static vtkMyXML* New();

protected:
  vtkMyXML() {}
  void StartElement(const char*, const char**) {}
  void EndElement(const char*) {}

private:
  vtkMyXML(const vtkMyXML&); // Not implemented
  void operator=(const vtkMyXML&); // Not implemented
};

vtkStandardNewMacro(vtkMyXML);

int main(int argc, char **argv)
{
  int res = 0;
  vtkOutputWindow::GetInstance()->PromptUserOn();
  if ( argc <= 1 )
    {
    cout << "Usage: " << argv[0] << " <xml file>" << endl;
    return 1;
    }

  vtkMyXML *parser = vtkMyXML::New();
  parser->SetFileName(argv[1]);
  if ( ! parser->Parse() )
    {
    cout << "Cannot parse the file: " << argv[1] << endl;
    res = 1;
    }
  parser->SetFileName(0);

  if( !parser->Parse("<xml>This is an XML file</xml>") )
    {
    cout << "Cannot parse message" << endl;
    res = 1;
    }

  parser->Delete();

  return res;
}
<|endoftext|>


<commit_before>void readClusters(int nev=-1,int evStart=0)
{

  gSystem->Load("libITSUpgradeBase");
  gSystem->Load("libITSUpgradeRec");
  gROOT->SetStyle("Plain");

  gAlice=NULL;
  AliRunLoader* runLoader = AliRunLoader::Open("galice.root");
  runLoader->LoadgAlice();

  gAlice = runLoader->GetAliRun();

  runLoader->LoadHeader();
  runLoader->LoadKinematics();
  runLoader->LoadRecPoints();

  AliLoader *dl = runLoader->GetDetectorLoader("ITS");

  AliGeomManager::LoadGeometry("geometry.root");
  AliITSUGeomTGeo* gm = new AliITSUGeomTGeo(kTRUE);
  Int_t nLayers = gm->GetNLayers();
  AliITSUClusterPix::SetGeom(gm);
  AliITSURecoDet *its = new AliITSURecoDet(gm, "ITSinterface");
  its->CreateClusterArrays();
  //
  TH2F *xyGlob = new TH2F("xyGlob"," X - Y Global coordinates ",500,-50,50,500,-50,50);
  xyGlob->SetXTitle("cm");
  xyGlob->SetMarkerStyle(7);
  TH1F *zGlob  = new TH1F("zGlob", " Z Global coordinates ",200, -50,50 );
  zGlob->SetXTitle("cm");
  //
  TH1F* rGlob = new TH1F("rGlob","R global", 5000, 0,50.);

  TTree * cluTree = 0x0;

  int nevTot = (Int_t)runLoader->GetNumberOfEvents();
  printf("N Events : %i \n",nevTot);
  evStart = evStart<nevTot ? evStart : nevTot-1;
  if (evStart<0) evStart = 0;
  //
  int lastEv = nev<0 ? nevTot : evStart+nev;
  if (lastEv > nevTot) lastEv = nevTot;
  //
  for (Int_t iEvent = evStart; iEvent < lastEv; iEvent++) {
    printf("\n Event %i \n",iEvent);
    runLoader->GetEvent(iEvent);
    //   AliStack *stack = runLoader->Stack();
    cluTree=dl->TreeR();
    int nlr=0;
    while(1) {
      TBranch* br = cluTree->GetBranch(Form("ITSRecPoints%d",nlr));
      if (!br) break;
      br->SetAddress(its->GetLayerActive(nlr)->GetClustersAddress());
      nlr++;
    }
    printf(" tree entries: %d\n",cluTree->GetEntries());
    cluTree->GetEntry(0);
    AliITSUClusterPix::SetSortMode( AliITSUClusterPix::SortModeIdTrkYZ());
    for (int ilr=0;ilr<nlr;ilr++) {its->GetLayerActive(ilr)->GetClusters()->Sort();}
    its->ProcessClusters();
    //
    for (int ilr=0;ilr<nlr;ilr++) {
      AliITSURecoLayer* lr = its->GetLayerActive(ilr);
      TClonesArray* clr = lr->GetClusters();

      int nClu = clr->GetEntries();
      printf("Layer %d : %d clusters\n",ilr,nClu);
      //
      for (int icl=0;icl<nClu;icl++) {
	AliITSUClusterPix *cl = (AliITSUClusterPix*)clr->At(icl);
	printf("#%4d | ",icl); cl->Print("glo");
	Float_t loc[3];
	cl->GetLocalXYZ(loc);
	Float_t glob[3];
	cl->GetGlobalXYZ(glob);
	//printf("%d: mod %d: loc(%.4lf,%.4lf,%.4lf); glob(%.4lf,%.4lf,%.4lf); \n",icl,cl->GetVolumeId(),
	//       loc[0],loc[1],loc[2],glob[0],glob[1],glob[2]);
	xyGlob->Fill(glob[0],glob[1]);
	zGlob->Fill(glob[2]);
	rGlob->Fill(TMath::Sqrt(glob[0]*glob[0]+glob[1]*glob[1]));
      }
    }
  }//event loop

  Int_t size = 400;

  TCanvas *xyCanv =  new TCanvas("xvCanvClus","RecPoint X-Y Positions",10,10,size,size);
  xyCanv->cd();
  xyGlob->Draw("P");

  TCanvas *zCanv =  new TCanvas("zCanvClus","RecPoint Z Positions",size+20,10,size,size);
  zCanv->cd();
  zGlob->Draw();

  TCanvas *rCanv =  new TCanvas("rCanvClus","RecPoint R Positions",size+20,10,size,size);
  rCanv->cd();
  rGlob->Draw();

}
<commit_msg>Print also cluster pattern in readClusters<commit_after>void readClusters(int nev=-1,int evStart=0)
{

  gSystem->Load("libITSUpgradeBase");
  gSystem->Load("libITSUpgradeRec");
  gROOT->SetStyle("Plain");

  gAlice=NULL;
  AliRunLoader* runLoader = AliRunLoader::Open("galice.root");
  runLoader->LoadgAlice();

  gAlice = runLoader->GetAliRun();

  runLoader->LoadHeader();
  runLoader->LoadKinematics();
  runLoader->LoadRecPoints();

  AliLoader *dl = runLoader->GetDetectorLoader("ITS");

  AliGeomManager::LoadGeometry("geometry.root");
  AliITSUGeomTGeo* gm = new AliITSUGeomTGeo(kTRUE);
  Int_t nLayers = gm->GetNLayers();
  AliITSUClusterPix::SetGeom(gm);
  AliITSURecoDet *its = new AliITSURecoDet(gm, "ITSinterface");
  its->CreateClusterArrays();
  //
  TH2F *xyGlob = new TH2F("xyGlob"," X - Y Global coordinates ",500,-50,50,500,-50,50);
  xyGlob->SetXTitle("cm");
  xyGlob->SetMarkerStyle(7);
  TH1F *zGlob  = new TH1F("zGlob", " Z Global coordinates ",200, -50,50 );
  zGlob->SetXTitle("cm");
  //
  TH1F* rGlob = new TH1F("rGlob","R global", 5000, 0,50.);

  TTree * cluTree = 0x0;

  int nevTot = (Int_t)runLoader->GetNumberOfEvents();
  printf("N Events : %i \n",nevTot);
  evStart = evStart<nevTot ? evStart : nevTot-1;
  if (evStart<0) evStart = 0;
  //
  int lastEv = nev<0 ? nevTot : evStart+nev;
  if (lastEv > nevTot) lastEv = nevTot;
  //
  for (Int_t iEvent = evStart; iEvent < lastEv; iEvent++) {
    printf("\n Event %i \n",iEvent);
    runLoader->GetEvent(iEvent);
    //   AliStack *stack = runLoader->Stack();
    cluTree=dl->TreeR();
    int nlr=0;
    while(1) {
      TBranch* br = cluTree->GetBranch(Form("ITSRecPoints%d",nlr));
      if (!br) break;
      br->SetAddress(its->GetLayerActive(nlr)->GetClustersAddress());
      nlr++;
    }
    printf(" tree entries: %d\n",cluTree->GetEntries());
    cluTree->GetEntry(0);
    AliITSUClusterPix::SetSortMode( AliITSUClusterPix::SortModeIdTrkYZ());
    for (int ilr=0;ilr<nlr;ilr++) {its->GetLayerActive(ilr)->GetClusters()->Sort();}
    its->ProcessClusters();
    //
    for (int ilr=0;ilr<nlr;ilr++) {
      AliITSURecoLayer* lr = its->GetLayerActive(ilr);
      TClonesArray* clr = lr->GetClusters();

      int nClu = clr->GetEntries();
      printf("Layer %d : %d clusters\n",ilr,nClu);
      //
      for (int icl=0;icl<nClu;icl++) {
	AliITSUClusterPix *cl = (AliITSUClusterPix*)clr->At(icl);
	printf("#%4d | ",icl); cl->Print("glo p");
	Float_t loc[3];
	cl->GetLocalXYZ(loc);
	Float_t glob[3];
	cl->GetGlobalXYZ(glob);
	//printf("%d: mod %d: loc(%.4lf,%.4lf,%.4lf); glob(%.4lf,%.4lf,%.4lf); \n",icl,cl->GetVolumeId(),
	//       loc[0],loc[1],loc[2],glob[0],glob[1],glob[2]);
	xyGlob->Fill(glob[0],glob[1]);
	zGlob->Fill(glob[2]);
	rGlob->Fill(TMath::Sqrt(glob[0]*glob[0]+glob[1]*glob[1]));
      }
    }
  }//event loop

  Int_t size = 400;

  TCanvas *xyCanv =  new TCanvas("xvCanvClus","RecPoint X-Y Positions",10,10,size,size);
  xyCanv->cd();
  xyGlob->Draw("P");

  TCanvas *zCanv =  new TCanvas("zCanvClus","RecPoint Z Positions",size+20,10,size,size);
  zCanv->cd();
  zGlob->Draw();

  TCanvas *rCanv =  new TCanvas("rCanvClus","RecPoint R Positions",size+20,10,size,size);
  rCanv->cd();
  rGlob->Draw();

}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkImageImport.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkImageImport.h"

#include "vtkByteSwap.h"
#include "vtkDataArray.h"
#include "vtkImageData.h"
#include "vtkImageImportExecutive.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkPointData.h"

#include <ctype.h>
#include <vtkstd/exception>

vtkCxxRevisionMacro(vtkImageImport, "1.52");
vtkStandardNewMacro(vtkImageImport);

#define tryCatchMacro(invocation, messagePrepend)\
    try\
      {\
      invocation;\
      }\
    catch (vtkstd::exception &_e)\
      {\
      vtkErrorMacro(<<messagePrepend <<_e.what());\
      }\
    catch (...)\
      {\
      vtkErrorMacro(<<"Unknown exception.");\
      }\

//----------------------------------------------------------------------------
vtkImageImport::vtkImageImport()
{
  int idx;

  this->ImportVoidPointer = 0;

  this->DataScalarType = VTK_SHORT;
  this->NumberOfScalarComponents = 1;

  for (idx = 0; idx < 3; ++idx)
    {
    this->DataExtent[idx*2] = this->DataExtent[idx*2 + 1] = 0;
    this->WholeExtent[idx*2] = this->WholeExtent[idx*2 + 1] = 0;
    this->DataSpacing[idx] = 1.0;
    this->DataOrigin[idx] = 0.0;
    }
  this->SaveUserArray = 0;

  this->CallbackUserData = 0;

  this->UpdateInformationCallback = 0;
  this->PipelineModifiedCallback = 0;
  this->WholeExtentCallback = 0;
  this->SpacingCallback = 0;
  this->OriginCallback = 0;
  this->ScalarTypeCallback = 0;
  this->NumberOfComponentsCallback = 0;
  this->PropagateUpdateExtentCallback = 0;
  this->UpdateDataCallback = 0;
  this->DataExtentCallback = 0;
  this->BufferPointerCallback = 0;

  this->SetNumberOfInputPorts(0);

  vtkExecutive *exec = vtkImageImportExecutive::New();
  this->SetExecutive(exec);
  exec->Delete();

  this->SetScalarArrayName("ImageFile");
}

//----------------------------------------------------------------------------
vtkImageImport::~vtkImageImport()
{
  if ((this->ImportVoidPointer) && (!this->SaveUserArray))
    {
    delete [] static_cast<char *>(this->ImportVoidPointer);
    }
  this->SetScalarArrayName(NULL);
}

//----------------------------------------------------------------------------
void vtkImageImport::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  int idx;

  os << indent << "ImportVoidPointer: " << this->ImportVoidPointer << "\n";

  os << indent << "DataScalarType: "
     << vtkImageScalarTypeNameMacro(this->DataScalarType) << "\n";

  os << indent << "NumberOfScalarComponents: "
     << this->NumberOfScalarComponents << "\n";

  os << indent << "WholeExtent: (" << this->WholeExtent[0];
  for (idx = 1; idx < 6; ++idx)
    {
    os << ", " << this->WholeExtent[idx];
    }
  os << ")\n";

  os << indent << "DataExtent: (" << this->DataExtent[0];
  for (idx = 1; idx < 6; ++idx)
    {
    os << ", " << this->DataExtent[idx];
    }
  os << ")\n";

  os << indent << "DataSpacing: (" << this->DataSpacing[0];
  for (idx = 1; idx < 3; ++idx)
    {
    os << ", " << this->DataSpacing[idx];
    }
  os << ")\n";

  os << indent << "DataOrigin: (" << this->DataOrigin[0];
  for (idx = 1; idx < 3; ++idx)
    {
    os << ", " << this->DataOrigin[idx];
    }
  os << ")\n";

  os << indent << "CallbackUserData: "
     << (this->CallbackUserData? "Set" : "Not Set") << "\n";

  os << indent << "UpdateInformationCallback: "
     << (this->UpdateInformationCallback? "Set" : "Not Set") << "\n";

  os << indent << "PipelineModifiedCallback: "
     << (this->PipelineModifiedCallback? "Set" : "Not Set") << "\n";

  os << indent << "WholeExtentCallback: "
     << (this->WholeExtentCallback? "Set" : "Not Set") << "\n";

  os << indent << "SpacingCallback: "
     << (this->SpacingCallback? "Set" : "Not Set") << "\n";

  os << indent << "OriginCallback: "
     << (this->OriginCallback? "Set" : "Not Set") << "\n";

  os << indent << "ScalarTypeCallback: "
     << (this->ScalarTypeCallback? "Set" : "Not Set") << "\n";

  os << indent << "NumberOfComponentsCallback: "
     << (this->NumberOfComponentsCallback? "Set" : "Not Set") << "\n";

  os << indent << "PropagateUpdateExtentCallback: "
     << (this->PropagateUpdateExtentCallback? "Set" : "Not Set") << "\n";

  os << indent << "UpdateDataCallback: "
     << (this->UpdateDataCallback? "Set" : "Not Set") << "\n";

  os << indent << "DataExtentCallback: "
     << (this->DataExtentCallback? "Set" : "Not Set") << "\n";

  os << indent << "BufferPointerCallback: "
     << (this->BufferPointerCallback? "Set" : "Not Set") << "\n";

  os << indent << "ScalarArrayName: ";
  if(this->ScalarArrayName!=0)
    {
      os  << this->ScalarArrayName << endl;
    }
  else
    {
      os  << "(none)" << endl;
    }
}

//----------------------------------------------------------------------------
int vtkImageImport::RequestUpdateExtent(
  vtkInformation* vtkNotUsed(request),
  vtkInformationVector** vtkNotUsed(inputVector),
  vtkInformationVector* outputVector)
{
  if (this->PropagateUpdateExtentCallback)
    {
    int uExt[6];

    vtkInformation* outInfo = outputVector->GetInformationObject(0);
    outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(),uExt);
    tryCatchMacro(
      (this->PropagateUpdateExtentCallback)(this->CallbackUserData,uExt),
      "PropagateUpdateExtentCallback: ");
    }

  return 1;
}

//----------------------------------------------------------------------------
int vtkImageImport::RequestInformation (
  vtkInformation * vtkNotUsed(request),
  vtkInformationVector ** vtkNotUsed( inputVector ),
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation* outInfo = outputVector->GetInformationObject(0);

  // If set, use the callbacks to fill in our data members.
  this->InvokeExecuteInformationCallbacks();

  // Legacy support for code that sets only DataExtent.
  this->LegacyCheckWholeExtent();

  // set the whole extent
  outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
               this->WholeExtent,6);

  // set the spacing
  outInfo->Set(vtkDataObject::SPACING(),this->DataSpacing,3);

  // set the origin.
  outInfo->Set(vtkDataObject::ORIGIN(),this->DataOrigin,3);

  // set data type
  vtkDataObject::SetPointDataActiveScalarInfo(outInfo, this->DataScalarType,
    this->NumberOfScalarComponents);
  return 1;
}

//----------------------------------------------------------------------------
void vtkImageImport::ExecuteData(vtkDataObject *output)
{
  // If set, use the callbacks to prepare our input data.
  this->InvokeExecuteDataCallbacks();

  vtkImageData *data = vtkImageData::SafeDownCast(output);
  data->SetExtent(0,0,0,0,0,0);
  data->AllocateScalars();
  void *ptr = this->GetImportVoidPointer();
  int size =
    (this->DataExtent[1] - this->DataExtent[0]+1) *
    (this->DataExtent[3] - this->DataExtent[2]+1) *
    (this->DataExtent[5] - this->DataExtent[4]+1) *
    this->NumberOfScalarComponents;

  data->SetExtent(this->DataExtent);
  data->GetPointData()->GetScalars()->SetVoidArray(ptr,size,1);
  data->GetPointData()->GetScalars()->SetName(this->ScalarArrayName);
}

//----------------------------------------------------------------------------
void vtkImageImport::CopyImportVoidPointer(void *ptr, int size)
{
  unsigned char *mem = new unsigned char [size];
  memcpy(mem,ptr,size);
  this->SetImportVoidPointer(mem,0);
}

//----------------------------------------------------------------------------
void vtkImageImport::SetImportVoidPointer(void *ptr)
{
  this->SetImportVoidPointer(ptr,1);
}

//----------------------------------------------------------------------------
void vtkImageImport::SetImportVoidPointer(void *ptr, int save)
{
  if (ptr != this->ImportVoidPointer)
    {
    if ((this->ImportVoidPointer) && (!this->SaveUserArray))
      {
      vtkDebugMacro (<< "Deleting the array...");
      delete [] static_cast<char *>(this->ImportVoidPointer);
      }
    else
      {
      vtkDebugMacro (<<"Warning, array not deleted, but will point to new array.");
      }
    this->Modified();
    }
  this->SaveUserArray = save;
  this->ImportVoidPointer = ptr;
}

//----------------------------------------------------------------------------
int vtkImageImport::InvokePipelineModifiedCallbacks()
{
  if (this->PipelineModifiedCallback)
    {
    int ret;
    try
      {
      ret = (this->PipelineModifiedCallback)(this->CallbackUserData);
      }
    catch (vtkstd::exception &_e)
      {
      vtkErrorMacro(<<"Calling PipelineModifiedCallback: " << _e.what());
      // if an error occurred, we don't want the pipeline to run again
      // until the error has been rectified.  It can be assumed that
      // the rectifying actions will set the modified flag.
      ret = 0;
      }
    catch (...)
      {
      vtkErrorMacro(<<"Unknown exception.");
      // same logic as above
      ret = 0;
      }

    return ret;
    }
  else
    {
    // if there's no PipelineModified installed, we return 0
    return 0;
    }

}

//----------------------------------------------------------------------------
void vtkImageImport::InvokeUpdateInformationCallbacks()
{
  if (this->UpdateInformationCallback)
    {
    tryCatchMacro((this->UpdateInformationCallback)(this->CallbackUserData),
                  "Calling UpdateInformationCallback: ");
    }

  if (this->InvokePipelineModifiedCallbacks())
    {
    this->Modified();
    }
}

//----------------------------------------------------------------------------
void vtkImageImport::InvokeExecuteInformationCallbacks()
{
  if (this->WholeExtentCallback)
    {
    tryCatchMacro(
      this->SetWholeExtent(
        (this->WholeExtentCallback)(this->CallbackUserData)),
      "Calling WholeExtentCallback: ");
    }
  if (this->SpacingCallback)
    {
    tryCatchMacro(
      this->SetDataSpacing((this->SpacingCallback)(this->CallbackUserData)),
      "Calling SpacingCallback: ");
    }
  if (this->OriginCallback)
    {
    tryCatchMacro(
      this->SetDataOrigin((this->OriginCallback)(this->CallbackUserData)),
      "Calling OriginCallback: ");
    }
  if (this->NumberOfComponentsCallback)
    {
    tryCatchMacro(
      this->SetNumberOfScalarComponents(
        (this->NumberOfComponentsCallback)(this->CallbackUserData)),
      "Calling NumberOfComponentsCallback: ");
    }
  if (this->ScalarTypeCallback)
    {
    const char* scalarType = "double"; // default
    tryCatchMacro(
      scalarType = (this->ScalarTypeCallback)(this->CallbackUserData),
      "Calling ScalarTypeCallback: ");

    if (strcmp(scalarType, "double")==0)
      {
      this->SetDataScalarType(VTK_DOUBLE);
      }
    else if (strcmp(scalarType, "float")==0)
      {
      this->SetDataScalarType(VTK_FLOAT);
      }
    else if (strcmp(scalarType, "long")==0)
      {
      this->SetDataScalarType(VTK_LONG);
      }
    else if (strcmp(scalarType, "unsigned long")==0)
      {
      this->SetDataScalarType(VTK_UNSIGNED_LONG);
      }
    else if (strcmp(scalarType, "int")==0)
      {
      this->SetDataScalarType(VTK_INT);
      }
    else if (strcmp(scalarType, "unsigned int")==0)
      {
      this->SetDataScalarType(VTK_UNSIGNED_INT);
      }
    else if (strcmp(scalarType, "short")==0)
      {
      this->SetDataScalarType(VTK_SHORT);
      }
    else if (strcmp(scalarType, "unsigned short")==0)
      {
      this->SetDataScalarType(VTK_UNSIGNED_SHORT);
      }
    else if (strcmp(scalarType, "char")==0)
      {
      this->SetDataScalarType(VTK_CHAR);
      }
    else if (strcmp(scalarType, "unsigned char")==0)
      {
      this->SetDataScalarType(VTK_UNSIGNED_CHAR);
      }
    else if (strcmp(scalarType, "signed char")==0)
      {
      this->SetDataScalarType(VTK_SIGNED_CHAR);
      }
    }
}

//----------------------------------------------------------------------------
void vtkImageImport::InvokeExecuteDataCallbacks()
{
  if (this->UpdateDataCallback)
    {
    tryCatchMacro(
      (this->UpdateDataCallback)(this->CallbackUserData),
      "Calling UpdateDataCallback: ");
    }
  if (this->DataExtentCallback)
    {
    tryCatchMacro(
      this->SetDataExtent((this->DataExtentCallback)(this->CallbackUserData)),
      "Calling DataExtentCallback: ");
    }
  if (this->BufferPointerCallback)
    {
    tryCatchMacro(
      this->SetImportVoidPointer(
        (this->BufferPointerCallback)(this->CallbackUserData)),
      "Calling BufferPointerCallback: ");
    }
}

//----------------------------------------------------------------------------
// In the past, this class made no distinction between whole extent and
// buffered extent, so only SetDataExtent also set the whole extent of
// the output.  Now, there is a separate SetWholeExtent which should be
// called as well.
void vtkImageImport::LegacyCheckWholeExtent()
{
  // If the WholeExtentCallback is set, this must not be legacy code.
  if (this->WholeExtentCallback)
    {
    return;
    }
  int i;
  // Check whether the whole extent has been set.
  for(i=0; i < 6; ++i)
    {
    if (this->WholeExtent[i] != 0)
      {
      return;
      }
    }

  // The whole extent has not been set.  Copy it from the data extent
  // and issue a warning.
  for(i=0; i < 6; ++i)
    {
    this->WholeExtent[i] = this->DataExtent[i];
    }

  vtkWarningMacro("\n"
    "There is a distinction between the whole extent and the buffered\n"
    "extent of an imported image.  Use SetWholeExtent to set the extent\n"
    "of the entire image.  Use SetDataExtent to set the extent of the\n"
    "portion of the image that is in the buffer set with\n"
    "SetImportVoidPointer.  Both should be called even if the extents are\n"
    "the same.");
}
<commit_msg>BUG:No idea why my Linux box did not catch this one.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkImageImport.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkImageImport.h"

#include "vtkByteSwap.h"
#include "vtkDataArray.h"
#include "vtkImageData.h"
#include "vtkImageImportExecutive.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkPointData.h"

#include <ctype.h>
#include <vtkstd/exception>

vtkCxxRevisionMacro(vtkImageImport, "1.53");
vtkStandardNewMacro(vtkImageImport);

#define tryCatchMacro(invocation, messagePrepend)\
    try\
      {\
      invocation;\
      }\
    catch (vtkstd::exception &_e)\
      {\
      vtkErrorMacro(<<messagePrepend <<_e.what());\
      }\
    catch (...)\
      {\
      vtkErrorMacro(<<"Unknown exception.");\
      }\

//----------------------------------------------------------------------------
vtkImageImport::vtkImageImport()
{
  int idx;

  this->ImportVoidPointer = 0;

  this->DataScalarType = VTK_SHORT;
  this->NumberOfScalarComponents = 1;

  for (idx = 0; idx < 3; ++idx)
    {
    this->DataExtent[idx*2] = this->DataExtent[idx*2 + 1] = 0;
    this->WholeExtent[idx*2] = this->WholeExtent[idx*2 + 1] = 0;
    this->DataSpacing[idx] = 1.0;
    this->DataOrigin[idx] = 0.0;
    }
  this->SaveUserArray = 0;

  this->CallbackUserData = 0;

  this->UpdateInformationCallback = 0;
  this->PipelineModifiedCallback = 0;
  this->WholeExtentCallback = 0;
  this->SpacingCallback = 0;
  this->OriginCallback = 0;
  this->ScalarTypeCallback = 0;
  this->NumberOfComponentsCallback = 0;
  this->PropagateUpdateExtentCallback = 0;
  this->UpdateDataCallback = 0;
  this->DataExtentCallback = 0;
  this->BufferPointerCallback = 0;

  this->SetNumberOfInputPorts(0);

  vtkExecutive *exec = vtkImageImportExecutive::New();
  this->SetExecutive(exec);
  exec->Delete();

  this->ScalarArrayName=0;
  this->SetScalarArrayName("");
}

//----------------------------------------------------------------------------
vtkImageImport::~vtkImageImport()
{
  if ((this->ImportVoidPointer) && (!this->SaveUserArray))
    {
    delete [] static_cast<char *>(this->ImportVoidPointer);
    }
  this->SetScalarArrayName(NULL);
}

//----------------------------------------------------------------------------
void vtkImageImport::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  int idx;

  os << indent << "ImportVoidPointer: " << this->ImportVoidPointer << "\n";

  os << indent << "DataScalarType: "
     << vtkImageScalarTypeNameMacro(this->DataScalarType) << "\n";

  os << indent << "NumberOfScalarComponents: "
     << this->NumberOfScalarComponents << "\n";

  os << indent << "WholeExtent: (" << this->WholeExtent[0];
  for (idx = 1; idx < 6; ++idx)
    {
    os << ", " << this->WholeExtent[idx];
    }
  os << ")\n";

  os << indent << "DataExtent: (" << this->DataExtent[0];
  for (idx = 1; idx < 6; ++idx)
    {
    os << ", " << this->DataExtent[idx];
    }
  os << ")\n";

  os << indent << "DataSpacing: (" << this->DataSpacing[0];
  for (idx = 1; idx < 3; ++idx)
    {
    os << ", " << this->DataSpacing[idx];
    }
  os << ")\n";

  os << indent << "DataOrigin: (" << this->DataOrigin[0];
  for (idx = 1; idx < 3; ++idx)
    {
    os << ", " << this->DataOrigin[idx];
    }
  os << ")\n";

  os << indent << "CallbackUserData: "
     << (this->CallbackUserData? "Set" : "Not Set") << "\n";

  os << indent << "UpdateInformationCallback: "
     << (this->UpdateInformationCallback? "Set" : "Not Set") << "\n";

  os << indent << "PipelineModifiedCallback: "
     << (this->PipelineModifiedCallback? "Set" : "Not Set") << "\n";

  os << indent << "WholeExtentCallback: "
     << (this->WholeExtentCallback? "Set" : "Not Set") << "\n";

  os << indent << "SpacingCallback: "
     << (this->SpacingCallback? "Set" : "Not Set") << "\n";

  os << indent << "OriginCallback: "
     << (this->OriginCallback? "Set" : "Not Set") << "\n";

  os << indent << "ScalarTypeCallback: "
     << (this->ScalarTypeCallback? "Set" : "Not Set") << "\n";

  os << indent << "NumberOfComponentsCallback: "
     << (this->NumberOfComponentsCallback? "Set" : "Not Set") << "\n";

  os << indent << "PropagateUpdateExtentCallback: "
     << (this->PropagateUpdateExtentCallback? "Set" : "Not Set") << "\n";

  os << indent << "UpdateDataCallback: "
     << (this->UpdateDataCallback? "Set" : "Not Set") << "\n";

  os << indent << "DataExtentCallback: "
     << (this->DataExtentCallback? "Set" : "Not Set") << "\n";

  os << indent << "BufferPointerCallback: "
     << (this->BufferPointerCallback? "Set" : "Not Set") << "\n";

  os << indent << "ScalarArrayName: ";
  if(this->ScalarArrayName!=0)
    {
      os  << this->ScalarArrayName << endl;
    }
  else
    {
      os  << "(none)" << endl;
    }
}

//----------------------------------------------------------------------------
int vtkImageImport::RequestUpdateExtent(
  vtkInformation* vtkNotUsed(request),
  vtkInformationVector** vtkNotUsed(inputVector),
  vtkInformationVector* outputVector)
{
  if (this->PropagateUpdateExtentCallback)
    {
    int uExt[6];

    vtkInformation* outInfo = outputVector->GetInformationObject(0);
    outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(),uExt);
    tryCatchMacro(
      (this->PropagateUpdateExtentCallback)(this->CallbackUserData,uExt),
      "PropagateUpdateExtentCallback: ");
    }

  return 1;
}

//----------------------------------------------------------------------------
int vtkImageImport::RequestInformation (
  vtkInformation * vtkNotUsed(request),
  vtkInformationVector ** vtkNotUsed( inputVector ),
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation* outInfo = outputVector->GetInformationObject(0);

  // If set, use the callbacks to fill in our data members.
  this->InvokeExecuteInformationCallbacks();

  // Legacy support for code that sets only DataExtent.
  this->LegacyCheckWholeExtent();

  // set the whole extent
  outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
               this->WholeExtent,6);

  // set the spacing
  outInfo->Set(vtkDataObject::SPACING(),this->DataSpacing,3);

  // set the origin.
  outInfo->Set(vtkDataObject::ORIGIN(),this->DataOrigin,3);

  // set data type
  vtkDataObject::SetPointDataActiveScalarInfo(outInfo, this->DataScalarType,
    this->NumberOfScalarComponents);
  return 1;
}

//----------------------------------------------------------------------------
void vtkImageImport::ExecuteData(vtkDataObject *output)
{
  // If set, use the callbacks to prepare our input data.
  this->InvokeExecuteDataCallbacks();

  vtkImageData *data = vtkImageData::SafeDownCast(output);
  data->SetExtent(0,0,0,0,0,0);
  data->AllocateScalars();
  void *ptr = this->GetImportVoidPointer();
  int size =
    (this->DataExtent[1] - this->DataExtent[0]+1) *
    (this->DataExtent[3] - this->DataExtent[2]+1) *
    (this->DataExtent[5] - this->DataExtent[4]+1) *
    this->NumberOfScalarComponents;

  data->SetExtent(this->DataExtent);
  data->GetPointData()->GetScalars()->SetVoidArray(ptr,size,1);
  data->GetPointData()->GetScalars()->SetName(this->ScalarArrayName);
}

//----------------------------------------------------------------------------
void vtkImageImport::CopyImportVoidPointer(void *ptr, int size)
{
  unsigned char *mem = new unsigned char [size];
  memcpy(mem,ptr,size);
  this->SetImportVoidPointer(mem,0);
}

//----------------------------------------------------------------------------
void vtkImageImport::SetImportVoidPointer(void *ptr)
{
  this->SetImportVoidPointer(ptr,1);
}

//----------------------------------------------------------------------------
void vtkImageImport::SetImportVoidPointer(void *ptr, int save)
{
  if (ptr != this->ImportVoidPointer)
    {
    if ((this->ImportVoidPointer) && (!this->SaveUserArray))
      {
      vtkDebugMacro (<< "Deleting the array...");
      delete [] static_cast<char *>(this->ImportVoidPointer);
      }
    else
      {
      vtkDebugMacro (<<"Warning, array not deleted, but will point to new array.");
      }
    this->Modified();
    }
  this->SaveUserArray = save;
  this->ImportVoidPointer = ptr;
}

//----------------------------------------------------------------------------
int vtkImageImport::InvokePipelineModifiedCallbacks()
{
  if (this->PipelineModifiedCallback)
    {
    int ret;
    try
      {
      ret = (this->PipelineModifiedCallback)(this->CallbackUserData);
      }
    catch (vtkstd::exception &_e)
      {
      vtkErrorMacro(<<"Calling PipelineModifiedCallback: " << _e.what());
      // if an error occurred, we don't want the pipeline to run again
      // until the error has been rectified.  It can be assumed that
      // the rectifying actions will set the modified flag.
      ret = 0;
      }
    catch (...)
      {
      vtkErrorMacro(<<"Unknown exception.");
      // same logic as above
      ret = 0;
      }

    return ret;
    }
  else
    {
    // if there's no PipelineModified installed, we return 0
    return 0;
    }

}

//----------------------------------------------------------------------------
void vtkImageImport::InvokeUpdateInformationCallbacks()
{
  if (this->UpdateInformationCallback)
    {
    tryCatchMacro((this->UpdateInformationCallback)(this->CallbackUserData),
                  "Calling UpdateInformationCallback: ");
    }

  if (this->InvokePipelineModifiedCallbacks())
    {
    this->Modified();
    }
}

//----------------------------------------------------------------------------
void vtkImageImport::InvokeExecuteInformationCallbacks()
{
  if (this->WholeExtentCallback)
    {
    tryCatchMacro(
      this->SetWholeExtent(
        (this->WholeExtentCallback)(this->CallbackUserData)),
      "Calling WholeExtentCallback: ");
    }
  if (this->SpacingCallback)
    {
    tryCatchMacro(
      this->SetDataSpacing((this->SpacingCallback)(this->CallbackUserData)),
      "Calling SpacingCallback: ");
    }
  if (this->OriginCallback)
    {
    tryCatchMacro(
      this->SetDataOrigin((this->OriginCallback)(this->CallbackUserData)),
      "Calling OriginCallback: ");
    }
  if (this->NumberOfComponentsCallback)
    {
    tryCatchMacro(
      this->SetNumberOfScalarComponents(
        (this->NumberOfComponentsCallback)(this->CallbackUserData)),
      "Calling NumberOfComponentsCallback: ");
    }
  if (this->ScalarTypeCallback)
    {
    const char* scalarType = "double"; // default
    tryCatchMacro(
      scalarType = (this->ScalarTypeCallback)(this->CallbackUserData),
      "Calling ScalarTypeCallback: ");

    if (strcmp(scalarType, "double")==0)
      {
      this->SetDataScalarType(VTK_DOUBLE);
      }
    else if (strcmp(scalarType, "float")==0)
      {
      this->SetDataScalarType(VTK_FLOAT);
      }
    else if (strcmp(scalarType, "long")==0)
      {
      this->SetDataScalarType(VTK_LONG);
      }
    else if (strcmp(scalarType, "unsigned long")==0)
      {
      this->SetDataScalarType(VTK_UNSIGNED_LONG);
      }
    else if (strcmp(scalarType, "int")==0)
      {
      this->SetDataScalarType(VTK_INT);
      }
    else if (strcmp(scalarType, "unsigned int")==0)
      {
      this->SetDataScalarType(VTK_UNSIGNED_INT);
      }
    else if (strcmp(scalarType, "short")==0)
      {
      this->SetDataScalarType(VTK_SHORT);
      }
    else if (strcmp(scalarType, "unsigned short")==0)
      {
      this->SetDataScalarType(VTK_UNSIGNED_SHORT);
      }
    else if (strcmp(scalarType, "char")==0)
      {
      this->SetDataScalarType(VTK_CHAR);
      }
    else if (strcmp(scalarType, "unsigned char")==0)
      {
      this->SetDataScalarType(VTK_UNSIGNED_CHAR);
      }
    else if (strcmp(scalarType, "signed char")==0)
      {
      this->SetDataScalarType(VTK_SIGNED_CHAR);
      }
    }
}

//----------------------------------------------------------------------------
void vtkImageImport::InvokeExecuteDataCallbacks()
{
  if (this->UpdateDataCallback)
    {
    tryCatchMacro(
      (this->UpdateDataCallback)(this->CallbackUserData),
      "Calling UpdateDataCallback: ");
    }
  if (this->DataExtentCallback)
    {
    tryCatchMacro(
      this->SetDataExtent((this->DataExtentCallback)(this->CallbackUserData)),
      "Calling DataExtentCallback: ");
    }
  if (this->BufferPointerCallback)
    {
    tryCatchMacro(
      this->SetImportVoidPointer(
        (this->BufferPointerCallback)(this->CallbackUserData)),
      "Calling BufferPointerCallback: ");
    }
}

//----------------------------------------------------------------------------
// In the past, this class made no distinction between whole extent and
// buffered extent, so only SetDataExtent also set the whole extent of
// the output.  Now, there is a separate SetWholeExtent which should be
// called as well.
void vtkImageImport::LegacyCheckWholeExtent()
{
  // If the WholeExtentCallback is set, this must not be legacy code.
  if (this->WholeExtentCallback)
    {
    return;
    }
  int i;
  // Check whether the whole extent has been set.
  for(i=0; i < 6; ++i)
    {
    if (this->WholeExtent[i] != 0)
      {
      return;
      }
    }

  // The whole extent has not been set.  Copy it from the data extent
  // and issue a warning.
  for(i=0; i < 6; ++i)
    {
    this->WholeExtent[i] = this->DataExtent[i];
    }

  vtkWarningMacro("\n"
    "There is a distinction between the whole extent and the buffered\n"
    "extent of an imported image.  Use SetWholeExtent to set the extent\n"
    "of the entire image.  Use SetDataExtent to set the extent of the\n"
    "portion of the image that is in the buffer set with\n"
    "SetImportVoidPointer.  Both should be called even if the extents are\n"
    "the same.");
}
<|endoftext|>


<commit_before>#pragma once

#include <ArduinoJson.h>

namespace HomieInternals {
  const char VERSION[] = "1.0.0";
  const int BAUD_RATE = 115200;

  const uint16_t DEFAULT_MQTT_PORT = 1883;
  const uint16_t DEFAULT_OTA_PORT = 80;
  const char DEFAULT_MQTT_BASE_TOPIC[] = "devices/";
  const char DEFAULT_OTA_PATH[] = "/ota";

  const uint8_t DEFAULT_RESET_PIN = 0; // == D3 on nodeMCU
  const byte DEFAULT_RESET_STATE = LOW;
  const uint16_t DEFAULT_RESET_TIME = 5 * 1000;

  const char DEFAULT_BRAND[] = "Homie";
  const char DEFAULT_FW_NAME[] = "undefined";
  const char DEFAULT_FW_VERSION[] = "undefined";

  const unsigned int CONFIG_SCAN_INTERVAL = 20 * 1000;
  const unsigned int WIFI_RECONNECT_INTERVAL = 20 * 1000;
  const unsigned int MQTT_RECONNECT_INTERVAL = 5 * 1000;
  const unsigned long SIGNAL_QUALITY_SEND_INTERVAL = 300 * 1000;

  const float LED_WIFI_DELAY = 1;
  const float LED_MQTT_DELAY = 0.2;

  const unsigned int JSON_CONFIG_MAX_BUFFER_SIZE = JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(7) + JSON_OBJECT_SIZE(6); // Max 4 elements at root, 2 elements in nested, etc...
  const char CONFIG_FILE_PATH[] = "/homie/config.json";
  const char CONFIG_OTA_PATH[] = "/homie/ota";
  const unsigned int MAX_LENGTH_WIFI_SSID = 32 + 1;

  enum BootMode : byte {
    BOOT_NORMAL = 1,
    BOOT_CONFIG = 2,
    BOOT_OTA = 3
  };
}
<commit_msg>Update version in constants<commit_after>#pragma once

#include <ArduinoJson.h>

namespace HomieInternals {
  const char VERSION[] = "1.3.0";
  const int BAUD_RATE = 115200;

  const uint16_t DEFAULT_MQTT_PORT = 1883;
  const uint16_t DEFAULT_OTA_PORT = 80;
  const char DEFAULT_MQTT_BASE_TOPIC[] = "devices/";
  const char DEFAULT_OTA_PATH[] = "/ota";

  const uint8_t DEFAULT_RESET_PIN = 0; // == D3 on nodeMCU
  const byte DEFAULT_RESET_STATE = LOW;
  const uint16_t DEFAULT_RESET_TIME = 5 * 1000;

  const char DEFAULT_BRAND[] = "Homie";
  const char DEFAULT_FW_NAME[] = "undefined";
  const char DEFAULT_FW_VERSION[] = "undefined";

  const unsigned int CONFIG_SCAN_INTERVAL = 20 * 1000;
  const unsigned int WIFI_RECONNECT_INTERVAL = 20 * 1000;
  const unsigned int MQTT_RECONNECT_INTERVAL = 5 * 1000;
  const unsigned long SIGNAL_QUALITY_SEND_INTERVAL = 300 * 1000;

  const float LED_WIFI_DELAY = 1;
  const float LED_MQTT_DELAY = 0.2;

  const unsigned int JSON_CONFIG_MAX_BUFFER_SIZE = JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(7) + JSON_OBJECT_SIZE(6); // Max 4 elements at root, 2 elements in nested, etc...
  const char CONFIG_FILE_PATH[] = "/homie/config.json";
  const char CONFIG_OTA_PATH[] = "/homie/ota";
  const unsigned int MAX_LENGTH_WIFI_SSID = 32 + 1;

  enum BootMode : byte {
    BOOT_NORMAL = 1,
    BOOT_CONFIG = 2,
    BOOT_OTA = 3
  };
}
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright 2011-2013 The University of North Carolina at Chapel Hill
 *  All rights reserved.
 *
 *  Licensed under the MADAI Software License. You may obtain a copy of
 *  this license at
 *
 *         https://madai-public.cs.unc.edu/visualization/software-license/
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include "LangevinSampler.h"

#include <cassert>
#include <algorithm>
#include <cmath>

namespace madai {

std::vector< double >
LangevinSampler
::GetGradient( const std::vector< double > Parameters, const Model * m)
{
  std::vector< double > Gradient;
  m->GetScalarAndGradientOutputs(
    Parameters, m_ActiveParameterIndices,
    m_CurrentOutputs, Gradient );
  double gradient_size = 0;
  for ( unsigned int i = 0; i < Gradient.size(); i++ ) {
    Gradient[i] *= ( m_UpperLimit[i] - m_LowerLimit[i] ); // Scale gradient
    gradient_size += Gradient[i] * Gradient[i]; // Determine size of gradient
  }
  gradient_size = std::sqrt( gradient_size );
  if ( gradient_size > m_LargestGradient ) { // Check to see if updating largest gradient and step size is necessary
    m_LargestGradient = gradient_size;
    m_StepSize = 1.0 / ( 10.0 * m_LargestGradient );
  }
  if ( m_NumberOfElementsInAverage < (Parameters.size() * 2000) ) {
    m_AverageGradient = ( double( m_NumberOfElementsInAverage ) * m_AverageGradient + gradient_size )
                        / double( m_NumberOfElementsInAverage + 1 );
    m_GaussianWidth = m_LargestGradient;
    m_NumberOfElementsInAverage++;
    // Reset gradient in order to sample space randomly ( no weighting )
    for ( unsigned int i = 0; i < Gradient.size(); i++ ) {
      Gradient[i] = 0;
    }
  } else if ( m_NumberOfElementsInAverage == (Parameters.size() * 2000) ) {
    m_GaussianWidth = 2.0 * m_AverageGradient;
  }

  return Gradient;
}

LangevinSampler
::LangevinSampler() :
  Sampler()
{
}

LangevinSampler
::~LangevinSampler()
{
}

void
LangevinSampler
::Initialize( const Model * model )
{
  assert( model != NULL );
  m_Model = model;

  Sampler::Initialize( model );

  m_UpperLimit.clear();
  m_LowerLimit.clear();
  size_t t = m_Model->GetNumberOfParameters();
  // Random initial starting point
  const std::vector< Parameter > & params = m_Model->GetParameters();
  for ( unsigned int i = 0; i < t; i++ ) {
    const Distribution * priorDist = params[i].GetPriorDistribution();
    m_CurrentParameters[i] = priorDist->GetSample(m_Random);
    double upper = priorDist->GetPercentile( 0.9 );
    double lower = priorDist->GetPercentile( 0.1 );
    m_LowerLimit.push_back( lower - ( upper - lower ) / 8.0 );
    m_UpperLimit.push_back( upper + ( upper - lower ) / 8.0 );
  }
  m_StepSize = 0.1;
  m_LargestGradient = 1.0;
  m_GaussianWidth = 1.0;
  m_AverageGradient = 0;
  m_NumberOfElementsInAverage = 0;
}

Sample
LangevinSampler
::NextSample()
{
  Model * m = const_cast< Model * >(m_Model);

  assert( static_cast<unsigned int> (
              std::count( m_ActiveParameterIndices.begin(),
                          m_ActiveParameterIndices.end(), true ))
          == this->GetNumberOfActiveParameters());

  // Get the gradient of the log likelihood at the current point
  std::vector< double > CurrentGradient = this->GetGradient( m_CurrentParameters, m );

  // Scale parameters by parameterspace
  for ( unsigned int i = 0; i < m_CurrentParameters.size(); i++ ) {
    m_CurrentParameters[i] = ( m_CurrentParameters[i] - m_LowerLimit[i] ) / ( m_UpperLimit[i] - m_LowerLimit[i] );
  }

  // Take a half step
  std::vector< double > NewParameters = m_CurrentParameters;
  for ( unsigned int i = 0; i < NewParameters.size(); i++ ) {
    NewParameters[i] += m_StepSize * ( CurrentGradient[i] + m_Random.Gaussian( 0., m_GaussianWidth ) ) / 2.0;
    NewParameters[i] = NewParameters[i] * ( m_UpperLimit[i] - m_LowerLimit[i] ) + m_LowerLimit[i];
  }
  // Get Gradient of LL at the new point
  std::vector< double > NewGradient = this->GetGradient( NewParameters, m );

  // Take final step and scale back to original units
  for ( unsigned int i = 0; i < m_CurrentParameters.size(); i++ ) {
    m_CurrentParameters[i] += m_StepSize * ( NewGradient[i] + m_Random.Gaussian( 0., m_GaussianWidth ) );
    m_CurrentParameters[i] = m_CurrentParameters[i] * ( m_UpperLimit[i] - m_LowerLimit[i] ) + m_LowerLimit[i];
  }

  // Reflect if past the upper and lower limits
  for ( unsigned int i = 0; i < m_CurrentParameters.size(); i++ ) {
    if ( m_CurrentParameters[i] < m_LowerLimit[i] ) {
      m_CurrentParameters[i] = m_LowerLimit[i] + ( m_LowerLimit[i] - m_CurrentParameters[i] );
    } else if ( m_CurrentParameters[i] > m_UpperLimit[i] ) {
      m_CurrentParameters[i] = m_UpperLimit[i] - ( m_CurrentParameters[i] - m_UpperLimit[i] );
    }
  }

  // Get loglikelihood at the new parameters
  double LogLikelihood;
  m->GetScalarOutputsAndLogLikelihood(
    m_CurrentParameters, m_CurrentOutputs, LogLikelihood );

  // Check for NaN
  assert( LogLikelihood == LogLikelihood );

  return Sample( m_CurrentParameters,
                 m_CurrentOutputs,
                 LogLikelihood );
}

} // end namespace madai
<commit_msg>Moved GetGradient function to the end of the document<commit_after>/*=========================================================================
 *
 *  Copyright 2011-2013 The University of North Carolina at Chapel Hill
 *  All rights reserved.
 *
 *  Licensed under the MADAI Software License. You may obtain a copy of
 *  this license at
 *
 *         https://madai-public.cs.unc.edu/visualization/software-license/
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include "LangevinSampler.h"

#include <cassert>
#include <algorithm>
#include <cmath>

namespace madai {

LangevinSampler
::LangevinSampler() :
  Sampler()
{
}

LangevinSampler
::~LangevinSampler()
{
}

void
LangevinSampler
::Initialize( const Model * model )
{
  assert( model != NULL );
  m_Model = model;

  Sampler::Initialize( model );

  m_UpperLimit.clear();
  m_LowerLimit.clear();
  size_t t = m_Model->GetNumberOfParameters();
  // Random initial starting point
  const std::vector< Parameter > & params = m_Model->GetParameters();
  for ( unsigned int i = 0; i < t; i++ ) {
    const Distribution * priorDist = params[i].GetPriorDistribution();
    m_CurrentParameters[i] = priorDist->GetSample(m_Random);
    double upper = priorDist->GetPercentile( 0.9 );
    double lower = priorDist->GetPercentile( 0.1 );
    m_LowerLimit.push_back( lower - ( upper - lower ) / 8.0 );
    m_UpperLimit.push_back( upper + ( upper - lower ) / 8.0 );
  }
  m_StepSize = 0.1;
  m_LargestGradient = 1.0;
  m_GaussianWidth = 1.0;
  m_AverageGradient = 0;
  m_NumberOfElementsInAverage = 0;
}

Sample
LangevinSampler
::NextSample()
{
  Model * m = const_cast< Model * >(m_Model);

  assert( static_cast<unsigned int> (
              std::count( m_ActiveParameterIndices.begin(),
                          m_ActiveParameterIndices.end(), true ))
          == this->GetNumberOfActiveParameters());

  // Get the gradient of the log likelihood at the current point
  std::vector< double > CurrentGradient = this->GetGradient( m_CurrentParameters, m );

  // Scale parameters by parameterspace
  for ( unsigned int i = 0; i < m_CurrentParameters.size(); i++ ) {
    m_CurrentParameters[i] = ( m_CurrentParameters[i] - m_LowerLimit[i] ) / ( m_UpperLimit[i] - m_LowerLimit[i] );
  }

  // Take a half step
  std::vector< double > NewParameters = m_CurrentParameters;
  for ( unsigned int i = 0; i < NewParameters.size(); i++ ) {
    NewParameters[i] += m_StepSize * ( CurrentGradient[i] + m_Random.Gaussian( 0., m_GaussianWidth ) ) / 2.0;
    NewParameters[i] = NewParameters[i] * ( m_UpperLimit[i] - m_LowerLimit[i] ) + m_LowerLimit[i];
  }
  // Get Gradient of LL at the new point
  std::vector< double > NewGradient = this->GetGradient( NewParameters, m );

  // Take final step and scale back to original units
  for ( unsigned int i = 0; i < m_CurrentParameters.size(); i++ ) {
    m_CurrentParameters[i] += m_StepSize * ( NewGradient[i] + m_Random.Gaussian( 0., m_GaussianWidth ) );
    m_CurrentParameters[i] = m_CurrentParameters[i] * ( m_UpperLimit[i] - m_LowerLimit[i] ) + m_LowerLimit[i];
  }

  // Reflect if past the upper and lower limits
  for ( unsigned int i = 0; i < m_CurrentParameters.size(); i++ ) {
    if ( m_CurrentParameters[i] < m_LowerLimit[i] ) {
      m_CurrentParameters[i] = m_LowerLimit[i] + ( m_LowerLimit[i] - m_CurrentParameters[i] );
    } else if ( m_CurrentParameters[i] > m_UpperLimit[i] ) {
      m_CurrentParameters[i] = m_UpperLimit[i] - ( m_CurrentParameters[i] - m_UpperLimit[i] );
    }
  }

  // Get loglikelihood at the new parameters
  double LogLikelihood;
  m->GetScalarOutputsAndLogLikelihood(
    m_CurrentParameters, m_CurrentOutputs, LogLikelihood );

  // Check for NaN
  assert( LogLikelihood == LogLikelihood );

  return Sample( m_CurrentParameters,
                 m_CurrentOutputs,
                 LogLikelihood );
}

std::vector< double >
LangevinSampler
::GetGradient( const std::vector< double > Parameters, const Model * m)
{
  std::vector< double > Gradient;
  m->GetScalarAndGradientOutputs(
    Parameters, m_ActiveParameterIndices,
    m_CurrentOutputs, Gradient );
  double gradient_size = 0;
  for ( unsigned int i = 0; i < Gradient.size(); i++ ) {
    Gradient[i] *= ( m_UpperLimit[i] - m_LowerLimit[i] ); // Scale gradient
    gradient_size += Gradient[i] * Gradient[i]; // Determine size of gradient
  }
  gradient_size = std::sqrt( gradient_size );
  if ( gradient_size > m_LargestGradient ) { // Check to see if updating largest gradient and step size is necessary
    m_LargestGradient = gradient_size;
    m_StepSize = 1.0 / ( 10.0 * m_LargestGradient );
  }
  if ( m_NumberOfElementsInAverage < (Parameters.size() * 2000) ) {
    m_AverageGradient = ( double( m_NumberOfElementsInAverage ) * m_AverageGradient + gradient_size )
    / double( m_NumberOfElementsInAverage + 1 );
    m_GaussianWidth = m_LargestGradient;
    m_NumberOfElementsInAverage++;
    // Reset gradient in order to sample space randomly ( no weighting )
    for ( unsigned int i = 0; i < Gradient.size(); i++ ) {
      Gradient[i] = 0;
    }
  } else if ( m_NumberOfElementsInAverage == (Parameters.size() * 2000) ) {
    m_GaussianWidth = 2.0 * m_AverageGradient;
  }

  return Gradient;
}

} // end namespace madai
<|endoftext|>