<commit_before>/* The MIT License (MIT)
 *
 * Copyright (c) 2014-2017 David Medina and Tim Warburton
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 */

#include "occa/defines.hpp"

#if OCCA_CUDA_ENABLED

#include "occa/modes/cuda/device.hpp"
#include "occa/modes/cuda/kernel.hpp"
#include "occa/modes/cuda/memory.hpp"
#include "occa/modes/cuda/utils.hpp"
#include "occa/tools/env.hpp"
#include "occa/tools/sys.hpp"
#include "occa/base.hpp"

namespace occa {
  namespace cuda {
    device::device(const occa::properties &properties_) :
      occa::device_v(properties_) {

      OCCA_ERROR("[CUDA] device not given [deviceID]",
                 properties.has("deviceID"));

      const int deviceID = properties.get<int>("deviceID");

      OCCA_CUDA_ERROR("Device: Creating Device",
                      cuDeviceGet(&handle, deviceID));

      OCCA_CUDA_ERROR("Device: Creating Context",
                      cuCtxCreate(&context, CU_CTX_SCHED_AUTO, handle));

      p2pEnabled = false;

      std::string compiler = properties["compiler"].getString();
      std::string compilerFlags = properties["compilerFlags"].getString();

      if (!compiler.size()) {
        if (env::var("OCCA_CUDA_COMPILER").size()) {
          compiler = env::var("OCCA_CUDA_COMPILER");
        } else {
          compiler = "nvcc";
        }
      }

      if (!compilerFlags.size()) {
        if (env::var("OCCA_CUDA_COMPILER_FLAGS").size()) {
          compilerFlags = env::var("OCCA_CUDA_COMPILER_FLAGS");
        } else {
#if OCCA_DEBUG_ENABLED
          compilerFlags = "-g";
#else
          compilerFlags = "";
#endif
        }
      }

      properties["compiler"]      = compiler;
      properties["compilerFlags"] = compilerFlags;

      OCCA_CUDA_ERROR("Device: Getting CUDA Device Arch",
                      cuDeviceComputeCapability(&archMajorVersion,
                                                &archMinorVersion,
                                                handle) );
    }

    device::~device() {}

    void device::free() {
      OCCA_CUDA_ERROR("Device: Freeing Context",
                      cuCtxDestroy(context) );
    }

    void* device::getHandle(const occa::properties &props) {
      if (props.get<std::string>("type", "") == "context") {
        return (void*) context;
      }
      return (void*) (uintptr_t) handle;
    }

    void device::finish() {
      OCCA_CUDA_ERROR("Device: Finish",
                      cuStreamSynchronize(*((CUstream*) currentStream)) );
    }

    bool device::hasSeparateMemorySpace() {
      return true;
    }

    hash_t device::hash() {
      if (!hash_.initialized) {
        hash_ ^= occa::hash(properties);
        hash_ ^= occa::hash(archMajorVersion);
        hash_ ^= occa::hash(archMinorVersion);
      }
      return hash_;
    }

    //  |---[ Stream ]----------------
    stream_t device::createStream() {
      CUstream *retStream = new CUstream;

      OCCA_CUDA_ERROR("Device: Setting Context",
                      cuCtxSetCurrent(context));
      OCCA_CUDA_ERROR("Device: createStream",
                      cuStreamCreate(retStream, CU_STREAM_DEFAULT));

      return retStream;
    }

    void device::freeStream(stream_t s) {
      OCCA_CUDA_ERROR("Device: freeStream",
                      cuStreamDestroy( *((CUstream*) s) ));
      delete (CUstream*) s;
    }

    streamTag device::tagStream() {
      streamTag ret;

      OCCA_CUDA_ERROR("Device: Setting Context",
                      cuCtxSetCurrent(context));
      OCCA_CUDA_ERROR("Device: Tagging Stream (Creating Tag)",
                      cuEventCreate(&cuda::event(ret), CU_EVENT_DEFAULT));
      OCCA_CUDA_ERROR("Device: Tagging Stream",
                      cuEventRecord(cuda::event(ret), 0));

      return ret;
    }

    void device::waitFor(streamTag tag) {
      OCCA_CUDA_ERROR("Device: Waiting For Tag",
                      cuEventSynchronize(cuda::event(tag)));
    }

    double device::timeBetween(const streamTag &startTag, const streamTag &endTag) {
      OCCA_CUDA_ERROR("Device: Waiting for endTag",
                      cuEventSynchronize(cuda::event(endTag)));

      float msTimeTaken;
      OCCA_CUDA_ERROR("Device: Timing Between Tags",
                      cuEventElapsedTime(&msTimeTaken, cuda::event(startTag), cuda::event(endTag)));

      return (double) (1.0e-3 * (double) msTimeTaken);
    }

    stream_t device::wrapStream(void *handle_, const occa::properties &props) {
      return handle_;
    }
    //  |===============================

    //  |---[ Kernel ]------------------
    kernel_v* device::buildKernel(const std::string &filename,
                                  const std::string &kernelName,
                                  const occa::properties &props) {
      cuda::kernel *k = new cuda::kernel(props);

      k->dHandle = this;
      k->context = context;

      k->build(filename, kernelName, props);

      return k;
    }

    kernel_v* device::buildKernelFromBinary(const std::string &filename,
                                            const std::string &kernelName,
                                            const occa::properties &props) {
      cuda::kernel *k = new cuda::kernel();

      k->dHandle = this;
      k->context = context;

      k->buildFromBinary(filename, kernelName, props);

      return k;
    }
    //  |===============================

    //  |---[ Memory ]------------------
    memory_v* device::malloc(const udim_t bytes,
                             void *src,
                             const occa::properties &props) {

      if (props.get<bool>("mapped")) {
        return mappedAlloc(bytes, src);
      }

      cuda::memory *mem = new cuda::memory();
      mem->dHandle = this;
      mem->handle  = new CUdeviceptr;
      mem->size    = bytes;

      OCCA_CUDA_ERROR("Device: Setting Context",
                      cuCtxSetCurrent(context));

      OCCA_CUDA_ERROR("Device: malloc",
                      cuMemAlloc((CUdeviceptr*) mem->handle, bytes));

      if (src != NULL) {
        mem->copyFrom(src, bytes, 0);
      }
      return mem;
    }

    memory_v* device::mappedAlloc(const udim_t bytes,
                                  void *src) {

      cuda::memory *mem = new cuda::memory();
      mem->dHandle = this;
      mem->handle  = new CUdeviceptr;
      mem->size    = bytes;

      OCCA_CUDA_ERROR("Device: Setting Context",
                      cuCtxSetCurrent(context));
      OCCA_CUDA_ERROR("Device: malloc host",
                      cuMemAllocHost((void**) &(mem->mappedPtr), bytes));
      OCCA_CUDA_ERROR("Device: get device pointer from host",
                      cuMemHostGetDevicePointer((CUdeviceptr*) mem->handle,
                                                mem->mappedPtr,
                                                0));

      if (src != NULL) {
        ::memcpy(mem->mappedPtr, src, bytes);
      }
      return mem;
    }

    memory_v* device::wrapMemory(void *handle_,
                                 const udim_t bytes,
                                 const occa::properties &props) {
      cuda::memory *mem = new cuda::memory();
      mem->dHandle = this;
      mem->handle  = new CUdeviceptr;
      mem->size    = bytes;
      ::memcpy(mem->handle, &handle_, sizeof(CUdeviceptr));
      return mem;
    }

    udim_t device::memorySize() {
      return cuda::getDeviceMemorySize(handle);
    }
    //  |===============================
  }
}

#endif
<commit_msg>[CUDA] Updated device::getHandle()<commit_after>/* The MIT License (MIT)
 *
 * Copyright (c) 2014-2017 David Medina and Tim Warburton
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 */

#include "occa/defines.hpp"

#if OCCA_CUDA_ENABLED

#include "occa/modes/cuda/device.hpp"
#include "occa/modes/cuda/kernel.hpp"
#include "occa/modes/cuda/memory.hpp"
#include "occa/modes/cuda/utils.hpp"
#include "occa/tools/env.hpp"
#include "occa/tools/sys.hpp"
#include "occa/base.hpp"

namespace occa {
  namespace cuda {
    device::device(const occa::properties &properties_) :
      occa::device_v(properties_) {

      OCCA_ERROR("[CUDA] device not given [deviceID]",
                 properties.has("deviceID"));

      const int deviceID = properties.get<int>("deviceID");

      OCCA_CUDA_ERROR("Device: Creating Device",
                      cuDeviceGet(&handle, deviceID));

      OCCA_CUDA_ERROR("Device: Creating Context",
                      cuCtxCreate(&context, CU_CTX_SCHED_AUTO, handle));

      p2pEnabled = false;

      std::string compiler = properties["compiler"].getString();
      std::string compilerFlags = properties["compilerFlags"].getString();

      if (!compiler.size()) {
        if (env::var("OCCA_CUDA_COMPILER").size()) {
          compiler = env::var("OCCA_CUDA_COMPILER");
        } else {
          compiler = "nvcc";
        }
      }

      if (!compilerFlags.size()) {
        if (env::var("OCCA_CUDA_COMPILER_FLAGS").size()) {
          compilerFlags = env::var("OCCA_CUDA_COMPILER_FLAGS");
        } else {
#if OCCA_DEBUG_ENABLED
          compilerFlags = "-g";
#else
          compilerFlags = "";
#endif
        }
      }

      properties["compiler"]      = compiler;
      properties["compilerFlags"] = compilerFlags;

      OCCA_CUDA_ERROR("Device: Getting CUDA Device Arch",
                      cuDeviceComputeCapability(&archMajorVersion,
                                                &archMinorVersion,
                                                handle) );
    }

    device::~device() {}

    void device::free() {
      OCCA_CUDA_ERROR("Device: Freeing Context",
                      cuCtxDestroy(context) );
    }

    void* device::getHandle(const occa::properties &props) {
      if (props.get<std::string>("type", "") == "context") {
        return (void*) context;
      }
      return &handle;
    }

    void device::finish() {
      OCCA_CUDA_ERROR("Device: Finish",
                      cuStreamSynchronize(*((CUstream*) currentStream)) );
    }

    bool device::hasSeparateMemorySpace() {
      return true;
    }

    hash_t device::hash() {
      if (!hash_.initialized) {
        hash_ ^= occa::hash(properties);
        hash_ ^= occa::hash(archMajorVersion);
        hash_ ^= occa::hash(archMinorVersion);
      }
      return hash_;
    }

    //  |---[ Stream ]----------------
    stream_t device::createStream() {
      CUstream *retStream = new CUstream;

      OCCA_CUDA_ERROR("Device: Setting Context",
                      cuCtxSetCurrent(context));
      OCCA_CUDA_ERROR("Device: createStream",
                      cuStreamCreate(retStream, CU_STREAM_DEFAULT));

      return retStream;
    }

    void device::freeStream(stream_t s) {
      OCCA_CUDA_ERROR("Device: freeStream",
                      cuStreamDestroy( *((CUstream*) s) ));
      delete (CUstream*) s;
    }

    streamTag device::tagStream() {
      streamTag ret;

      OCCA_CUDA_ERROR("Device: Setting Context",
                      cuCtxSetCurrent(context));
      OCCA_CUDA_ERROR("Device: Tagging Stream (Creating Tag)",
                      cuEventCreate(&cuda::event(ret), CU_EVENT_DEFAULT));
      OCCA_CUDA_ERROR("Device: Tagging Stream",
                      cuEventRecord(cuda::event(ret), 0));

      return ret;
    }

    void device::waitFor(streamTag tag) {
      OCCA_CUDA_ERROR("Device: Waiting For Tag",
                      cuEventSynchronize(cuda::event(tag)));
    }

    double device::timeBetween(const streamTag &startTag, const streamTag &endTag) {
      OCCA_CUDA_ERROR("Device: Waiting for endTag",
                      cuEventSynchronize(cuda::event(endTag)));

      float msTimeTaken;
      OCCA_CUDA_ERROR("Device: Timing Between Tags",
                      cuEventElapsedTime(&msTimeTaken, cuda::event(startTag), cuda::event(endTag)));

      return (double) (1.0e-3 * (double) msTimeTaken);
    }

    stream_t device::wrapStream(void *handle_, const occa::properties &props) {
      return handle_;
    }
    //  |===============================

    //  |---[ Kernel ]------------------
    kernel_v* device::buildKernel(const std::string &filename,
                                  const std::string &kernelName,
                                  const occa::properties &props) {
      cuda::kernel *k = new cuda::kernel(props);

      k->dHandle = this;
      k->context = context;

      k->build(filename, kernelName, props);

      return k;
    }

    kernel_v* device::buildKernelFromBinary(const std::string &filename,
                                            const std::string &kernelName,
                                            const occa::properties &props) {
      cuda::kernel *k = new cuda::kernel();

      k->dHandle = this;
      k->context = context;

      k->buildFromBinary(filename, kernelName, props);

      return k;
    }
    //  |===============================

    //  |---[ Memory ]------------------
    memory_v* device::malloc(const udim_t bytes,
                             void *src,
                             const occa::properties &props) {

      if (props.get<bool>("mapped")) {
        return mappedAlloc(bytes, src);
      }

      cuda::memory *mem = new cuda::memory();
      mem->dHandle = this;
      mem->handle  = new CUdeviceptr;
      mem->size    = bytes;

      OCCA_CUDA_ERROR("Device: Setting Context",
                      cuCtxSetCurrent(context));

      OCCA_CUDA_ERROR("Device: malloc",
                      cuMemAlloc((CUdeviceptr*) mem->handle, bytes));

      if (src != NULL) {
        mem->copyFrom(src, bytes, 0);
      }
      return mem;
    }

    memory_v* device::mappedAlloc(const udim_t bytes,
                                  void *src) {

      cuda::memory *mem = new cuda::memory();
      mem->dHandle = this;
      mem->handle  = new CUdeviceptr;
      mem->size    = bytes;

      OCCA_CUDA_ERROR("Device: Setting Context",
                      cuCtxSetCurrent(context));
      OCCA_CUDA_ERROR("Device: malloc host",
                      cuMemAllocHost((void**) &(mem->mappedPtr), bytes));
      OCCA_CUDA_ERROR("Device: get device pointer from host",
                      cuMemHostGetDevicePointer((CUdeviceptr*) mem->handle,
                                                mem->mappedPtr,
                                                0));

      if (src != NULL) {
        ::memcpy(mem->mappedPtr, src, bytes);
      }
      return mem;
    }

    memory_v* device::wrapMemory(void *handle_,
                                 const udim_t bytes,
                                 const occa::properties &props) {
      cuda::memory *mem = new cuda::memory();
      mem->dHandle = this;
      mem->handle  = new CUdeviceptr;
      mem->size    = bytes;
      ::memcpy(mem->handle, &handle_, sizeof(CUdeviceptr));
      return mem;
    }

    udim_t device::memorySize() {
      return cuda::getDeviceMemorySize(handle);
    }
    //  |===============================
  }
}

#endif
<|endoftext|>


<commit_before>#include "TCPStream.h"

#include <iostream>

namespace SnakeServer {

    namespace Network {

        TCPStream::TCPStream() {}

        TCPStream::TCPStream(const int t_sd, const struct sockaddr_in *t_address) : m_sd(t_sd) {
            char ip[50];
            inet_ntop(PF_INET, (struct in_addr *) &(t_address->sin_addr.s_addr), ip, sizeof(ip) - 1);
            m_peerIP = *ip;
            m_peerPort = ntohs(t_address->sin_port);
        }

        TCPStream::~TCPStream() {
            closeStream();
        }

        std::string TCPStream::receive() {
            char buff[BUFFER_SIZE];
            ssize_t received = recv(m_sd, buff, BUFFER_SIZE - 1, 0);

            if (received == -1) {
                if (errno != EWOULDBLOCK) {
                    closeStream();
                    throw new std::runtime_error("connection_lost");
                }

                return "";
            }

            return std::string(buff, received);
        }

        ssize_t TCPStream::send() {
            return ::send(m_sd, NULL, 0, 0);
        }

        std::string TCPStream::getPeerIP() {
            return m_peerIP;
        }

        int TCPStream::getPeerPort() {
            return m_peerPort;
        }

        void TCPStream::closeStream() {
            ::close(m_sd);
        }

    } // endnamespace Network

} // end namespace SnakeServer<commit_msg>Upravení vyhazování vyjímky v TCPStreamu<commit_after>#include "TCPStream.h"

#include <iostream>

namespace SnakeServer {

    namespace Network {

        TCPStream::TCPStream() {}

        TCPStream::TCPStream(const int t_sd, const struct sockaddr_in *t_address) : m_sd(t_sd) {
            char ip[50];
            inet_ntop(PF_INET, (struct in_addr *) &(t_address->sin_addr.s_addr), ip, sizeof(ip) - 1);
            m_peerIP = *ip;
            m_peerPort = ntohs(t_address->sin_port);
        }

        TCPStream::~TCPStream() {
            closeStream();
        }

        std::string TCPStream::receive() {
            char buff[BUFFER_SIZE];
            ssize_t received = recv(m_sd, buff, BUFFER_SIZE - 1, 0);

            if (received == -1) {
                if (errno != EWOULDBLOCK) {
                    closeStream();
                    throw std::runtime_error("connection_lost");
                }

                return "";
            }

            return std::string(buff, received);
        }

        ssize_t TCPStream::send() {
            return ::send(m_sd, NULL, 0, 0);
        }

        std::string TCPStream::getPeerIP() {
            return m_peerIP;
        }

        int TCPStream::getPeerPort() {
            return m_peerPort;
        }

        void TCPStream::closeStream() {
            ::close(m_sd);
        }

    } // endnamespace Network

} // end namespace SnakeServer<|endoftext|>


<commit_before>#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <fcntl.h>
#include <time.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdlib.h>
#include <string>
#include <b5m-manager/image_server_client.h>
#include <boost/program_options.hpp>
#include <boost/algorithm/string.hpp>
#include <glog/logging.h>

#define MAX_STORAGE_COUNT 2
#define STAT_FILENAME_BY_STORAGE_IP  "stat_upload_by_storage"
#define STAT_FILENAME_BY_OVERALL "stat_upload_by_overall"
#define FILENAME_FILE_ID  "success_upload"
#define FILENAME_FAIL  "fail_upload"
#define TIME_SUB_MS(tv1, tv2)  ((tv1.tv_sec - tv2.tv_sec) * 1000 + (tv1.tv_usec - tv2.tv_usec) / 1000)
#define INT64_PRINTF_FORMAT   "%lld"

using namespace std;
namespace po = boost::program_options;
using namespace sf1r;

typedef struct {
    int total_count;
    int success_count;
    int64_t time_used;
} StorageStat;

const char* nsip = "172.16.0.168:8108";

static StorageStat storages[MAX_STORAGE_COUNT];
static int storage_count = 0;
static time_t start_time;
static int total_count = 0;
static int success_count = 0;
static FILE *fpSuccess = NULL;
static FILE *fpFail = NULL;

static int test_init();
static int save_stats_by_overall();
static int save_stats_by_storage_ip();
static int add_to_storage_stat(int storage_i, const int result, const int time_used);

bool read_file_data(const char* local_file, char* buf, size_t bufsize)
{
    int fd;
    if (NULL == local_file)
    {
        return false;
    }
    else if ((fd = ::open(local_file, O_RDONLY)) < 0)
    {
        printf("open local file %s fail: %s", local_file, strerror(errno));
        return false;
    }
    else
    {
        int64_t read_len = 0;
        while (true)
        {
            if ((read_len = ::read(fd, buf, bufsize)) < 0)
            {
                if (EAGAIN == errno)
                {
                    continue;
                }
                printf("read local file %s fail, error: %s", local_file, strerror(errno));
                ::close(fd);
                return false;
            }
            if (0 == read_len)
            {
                assert(bufsize == 0);
                break;
            }

            buf += read_len;
            bufsize -= read_len;
            if (bufsize == 0)
            {
                break;
            }
            assert(bufsize > 0);
        }
    }
    ::close(fd);
    return true;
}

bool write_dir(const std::string& dir)
{
    std::string file_id;
    int result = 0;
	struct timeval tv_start;
	struct timeval tv_end;
	int time_used;

    char dirpath[1024];
    strcpy(dirpath, dir.c_str());
    if(dirpath[strlen(dirpath)-1]=='/'){
    }else{
        strcat(dirpath,"/");
    }
    DIR *d;
    struct dirent *file;
    struct stat sb;
    if(!(d=opendir(dirpath))){
        return false;
    }
    std::string filepath;
    while((file=readdir(d))!=NULL){
        if(strncmp(file->d_name,".",1)==0){
            continue;
        }
        filepath = dirpath;
        filepath += file->d_name;
        if(stat(filepath.c_str(), &sb)>=0){
            if(!S_ISDIR(sb.st_mode)){

                if(filepath.find(".pic") == std::string::npos &&
                    filepath.find(".jpeg") == std::string::npos &&
                    filepath.find(".jpg") == std::string::npos &&
                    filepath.find(".png") == std::string::npos&&
                    filepath.find(".bmp") == std::string::npos )
                    continue;

                if( sb.st_size == 0 )
                    continue;
                total_count++;

                gettimeofday(&tv_start, NULL);

                // read file content.
                char* filedata = new char[sb.st_size];
                if(!read_file_data(filepath.c_str(), filedata, sb.st_size))
                {
                    result = -1;
                }
                else
                {
                    try
                    {
                        result = ImageServerClient::UploadImageData(std::string(filedata, sb.st_size), file_id) ? 0:-1;
                    }
                    catch(std::exception& e)
                    {
                        cout << "upload caught exception." << endl;
                        cout << e.what() << endl;
                        gettimeofday(&tv_end, NULL);
                        cout << "time: " << TIME_SUB_MS(tv_end, tv_start) << endl;
                        continue;
                    }
                }
                delete[] filedata;
                gettimeofday(&tv_end, NULL);
                time_used = TIME_SUB_MS(tv_end, tv_start);
                add_to_storage_stat(0, result, time_used);

                if (result == 0) //success
                {
                    success_count++;
                    fprintf(fpSuccess, "%d %s %zu %s %d\n",
                        (int)tv_end.tv_sec, filepath.c_str(), sb.st_size,
                        file_id.c_str(), time_used);
                }
                else //fail
                {
                    fprintf(fpFail, "%d %s %d\n", (int)tv_end.tv_sec,
                        filepath.c_str(), result);
                    fflush(fpFail);
                    fflush(fpSuccess);
                    //if(total_count - success_count > 100)
                    //    exit(-1);
                }

                if (total_count % 100 == 0)
                {
                    if ((result=save_stats_by_overall()) != 0)
                    {
                        break;
                    }

                    if ((result=save_stats_by_storage_ip()) != 0)
                    {
                        break;
                    }
                    fflush(fpSuccess);
                }
            }
            else
            {
                write_dir(filepath);
            }
        }
    }
    closedir(d);
    return true;
}

void write_file(const std::string& image_path)
{
    int result = 0;

	if ((result=test_init()) != 0)
	{
		return;
	}

    if(image_path.empty())
    {
        std::cout << "empty local image path, no images will be uploaded." << std::endl;
        return;
    }
	memset(&storages, 0, sizeof(storages));
	start_time = time(NULL);
	result = 0;
	total_count = 0;
    success_count = 0;

    write_dir(image_path);

    save_stats_by_overall();
    save_stats_by_storage_ip();

    fclose(fpSuccess);
    fclose(fpFail);

    printf("time used: %ds\n", (int)(time(NULL) - start_time));
    return;

}

int main(int argc, char **argv)
{
    po::options_description desc("Allowed options");
    desc.add_options()
        ("help", "produce help message")
        ("imgserver-config", po::value<std::string>(), "image server config string(ip|port)")
        ("localimagepath", po::value<std::string>(), "specify the root path of local image that need to be uploaded.")
    ;
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);
    if (vm.count("help")) {
        std::cout << desc << std::endl;
        return 1;
    }

    boost::shared_ptr<RpcServerConnectionConfig> imgserver_config;
    if(vm.count("imgserver-config"))
    {
        std::string config_string = vm["imgserver-config"].as<std::string>();
        std::vector<std::string> vec;
        boost::algorithm::split( vec, config_string, boost::algorithm::is_any_of("|") );
        if(vec.size()==2)
        {
            std::string host = vec[0];
            uint32_t rpc_port = boost::lexical_cast<uint32_t>(vec[1]);
            imgserver_config.reset(new RpcServerConnectionConfig(host, rpc_port));
        }
        else
        {
            std::cout << "image server configure string invalid" << std::endl;
            return EXIT_FAILURE;
        }
    }

    if(!imgserver_config)
    {
        std::cout << "image server must be configured" << std::endl;
        return -1;
    }

    if(!ImageServerClient::Init(*(imgserver_config.get())))
    {
        LOG(ERROR) << "Image Server Client Init failed." << std::endl;
        return -1;
    }
    if(!ImageServerClient::Test())
    {
        LOG(ERROR) << "Image Server Client Test failed." << std::endl;
        return -1;
    }

    std::string local_image_path;
    if(vm.count("localimagepath"))
    {
        local_image_path = vm["localimagepath"].as<std::string>();
    }
    write_file(local_image_path);
    return 0;
}

static int save_stats_by_storage_ip()
{
	int k;
	char filename[256];
	FILE *fp;

	sprintf(filename, "%s", STAT_FILENAME_BY_STORAGE_IP);
	if ((fp=fopen(filename, "wb")) == NULL)
	{
		printf("open file %s fail \n",
			filename);
        perror("error:");
		return errno != 0 ? errno : EPERM;
	}

	fprintf(fp, "#ip_addr total_count success_count time_used(ms)\n");
	for (k=0; k<storage_count; k++)
	{
		fprintf(fp, "%d %d "INT64_PRINTF_FORMAT"\n", \
			storages[k].total_count, \
			storages[k].success_count, storages[k].time_used);
	}

	fclose(fp);
	return 0;
}

static int save_stats_by_overall()
{
	char filename[256];
	FILE *fp;

	sprintf(filename, "%s", STAT_FILENAME_BY_OVERALL);
	if ((fp=fopen(filename, "wb")) == NULL)
	{
		printf("open file %s fail\n",
			filename);
        perror("error:");
		return errno != 0 ? errno : EPERM;
	}

	fprintf(fp, "#total_count success_count  time_used(s)\n");
	fprintf(fp, "%d %d %d\n", total_count, success_count, (int)(time(NULL) - start_time));

	fclose(fp);
	return 0;
}

static int add_to_storage_stat(int storage_i, const int result, const int time_used)
{
	StorageStat *pStorage;
    pStorage = storages + storage_i;

    storage_count = storage_i + 1;

	pStorage->time_used += time_used;
	pStorage->total_count++;
	if (result == 0)
	{
		pStorage->success_count++;
	}

	return 0;
}

static int test_init()
{
	char filename[256];

	if (access("tfs_upload", 0) != 0 && mkdir("tfs_upload", 0755) != 0)
	{
	}

	if (chdir("tfs_upload") != 0)
	{
		printf("chdir fail\n");
        perror("err:");
		return errno != 0 ? errno : EPERM;
	}

	sprintf(filename, "%s", FILENAME_FILE_ID);
	if ((fpSuccess=fopen(filename, "wb")) == NULL)
	{
		printf("open file %s fail\n",
			filename);
        perror("err:");
		return errno != 0 ? errno : EPERM;
	}

	sprintf(filename, "%s", FILENAME_FAIL);
	if ((fpFail=fopen(filename, "wb")) == NULL)
	{
		printf("open file %s fail\n",
			filename);
        perror("err:");
		return errno != 0 ? errno : EPERM;
	}

	return 0;
}

<commit_msg>fix memory leak in image uploader<commit_after>#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <fcntl.h>
#include <time.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdlib.h>
#include <string>
#include <b5m-manager/image_server_client.h>
#include <boost/program_options.hpp>
#include <boost/algorithm/string.hpp>
#include <glog/logging.h>

#define MAX_STORAGE_COUNT 2
#define STAT_FILENAME_BY_STORAGE_IP  "stat_upload_by_storage"
#define STAT_FILENAME_BY_OVERALL "stat_upload_by_overall"
#define FILENAME_FILE_ID  "success_upload"
#define FILENAME_FAIL  "fail_upload"
#define TIME_SUB_MS(tv1, tv2)  ((tv1.tv_sec - tv2.tv_sec) * 1000 + (tv1.tv_usec - tv2.tv_usec) / 1000)
#define INT64_PRINTF_FORMAT   "%lld"

using namespace std;
namespace po = boost::program_options;
using namespace sf1r;

typedef struct {
    int total_count;
    int success_count;
    int64_t time_used;
} StorageStat;

const char* nsip = "172.16.0.168:8108";

static StorageStat storages[MAX_STORAGE_COUNT];
static int storage_count = 0;
static time_t start_time;
static int total_count = 0;
static int success_count = 0;
static FILE *fpSuccess = NULL;
static FILE *fpFail = NULL;

static int test_init();
static int save_stats_by_overall();
static int save_stats_by_storage_ip();
static int add_to_storage_stat(int storage_i, const int result, const int time_used);

bool read_file_data(const char* local_file, char* buf, size_t bufsize)
{
    int fd;
    if (NULL == local_file)
    {
        return false;
    }
    else if ((fd = ::open(local_file, O_RDONLY)) < 0)
    {
        printf("open local file %s fail: %s", local_file, strerror(errno));
        return false;
    }
    else
    {
        int64_t read_len = 0;
        while (true)
        {
            if ((read_len = ::read(fd, buf, bufsize)) < 0)
            {
                if (EAGAIN == errno)
                {
                    continue;
                }
                printf("read local file %s fail, error: %s", local_file, strerror(errno));
                ::close(fd);
                return false;
            }
            if (0 == read_len)
            {
                assert(bufsize == 0);
                break;
            }

            buf += read_len;
            bufsize -= read_len;
            if (bufsize == 0)
            {
                break;
            }
            assert(bufsize > 0);
        }
    }
    ::close(fd);
    return true;
}

bool write_dir(const std::string& dir)
{
    std::string file_id;
    int result = 0;
	struct timeval tv_start;
	struct timeval tv_end;
	int time_used;

    char dirpath[1024];
    strcpy(dirpath, dir.c_str());
    if(dirpath[strlen(dirpath)-1]=='/'){
    }else{
        strcat(dirpath,"/");
    }
    DIR *d;
    struct dirent *file;
    struct stat sb;
    if(!(d=opendir(dirpath))){
        return false;
    }
    std::string filepath;
    while((file=readdir(d))!=NULL){
        if(strncmp(file->d_name,".",1)==0){
            continue;
        }
        filepath = dirpath;
        filepath += file->d_name;
        if(stat(filepath.c_str(), &sb)>=0){
            if(!S_ISDIR(sb.st_mode)){

                if(filepath.find(".pic") == std::string::npos &&
                    filepath.find(".jpeg") == std::string::npos &&
                    filepath.find(".jpg") == std::string::npos &&
                    filepath.find(".png") == std::string::npos&&
                    filepath.find(".bmp") == std::string::npos )
                    continue;

                if( sb.st_size == 0 )
                    continue;
                total_count++;

                gettimeofday(&tv_start, NULL);

                // read file content.
                char* filedata = new char[sb.st_size];
                if(!read_file_data(filepath.c_str(), filedata, sb.st_size))
                {
                    result = -1;
                }
                else
                {
                    try
                    {
                        result = ImageServerClient::UploadImageData(std::string(filedata, sb.st_size), file_id) ? 0:-1;
                    }
                    catch(std::exception& e)
                    {
                        cout << "upload caught exception." << endl;
                        cout << e.what() << endl;
                        gettimeofday(&tv_end, NULL);
                        cout << "time: " << TIME_SUB_MS(tv_end, tv_start) << endl;
                        delete[] filedata;
                        continue;
                    }
                }
                delete[] filedata;
                gettimeofday(&tv_end, NULL);
                time_used = TIME_SUB_MS(tv_end, tv_start);
                add_to_storage_stat(0, result, time_used);

                if (result == 0) //success
                {
                    success_count++;
                    fprintf(fpSuccess, "%d %s %zu %s %d\n",
                        (int)tv_end.tv_sec, filepath.c_str(), sb.st_size,
                        file_id.c_str(), time_used);
                }
                else //fail
                {
                    fprintf(fpFail, "%d %s %d\n", (int)tv_end.tv_sec,
                        filepath.c_str(), result);
                    fflush(fpFail);
                    fflush(fpSuccess);
                    //if(total_count - success_count > 100)
                    //    exit(-1);
                }

                if (total_count % 100 == 0)
                {
                    if ((result=save_stats_by_overall()) != 0)
                    {
                        break;
                    }

                    if ((result=save_stats_by_storage_ip()) != 0)
                    {
                        break;
                    }
                    fflush(fpSuccess);
                }
            }
            else
            {
                write_dir(filepath);
            }
        }
    }
    closedir(d);
    return true;
}

void write_file(const std::string& image_path)
{
    int result = 0;

	if ((result=test_init()) != 0)
	{
		return;
	}

    if(image_path.empty())
    {
        std::cout << "empty local image path, no images will be uploaded." << std::endl;
        return;
    }
	memset(&storages, 0, sizeof(storages));
	start_time = time(NULL);
	result = 0;
	total_count = 0;
    success_count = 0;

    write_dir(image_path);

    save_stats_by_overall();
    save_stats_by_storage_ip();

    fclose(fpSuccess);
    fclose(fpFail);

    printf("time used: %ds\n", (int)(time(NULL) - start_time));
    return;

}

int main(int argc, char **argv)
{
    po::options_description desc("Allowed options");
    desc.add_options()
        ("help", "produce help message")
        ("imgserver-config", po::value<std::string>(), "image server config string(ip|port)")
        ("localimagepath", po::value<std::string>(), "specify the root path of local image that need to be uploaded.")
    ;
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);
    if (vm.count("help")) {
        std::cout << desc << std::endl;
        return 1;
    }

    boost::shared_ptr<RpcServerConnectionConfig> imgserver_config;
    if(vm.count("imgserver-config"))
    {
        std::string config_string = vm["imgserver-config"].as<std::string>();
        std::vector<std::string> vec;
        boost::algorithm::split( vec, config_string, boost::algorithm::is_any_of("|") );
        if(vec.size()==2)
        {
            std::string host = vec[0];
            uint32_t rpc_port = boost::lexical_cast<uint32_t>(vec[1]);
            imgserver_config.reset(new RpcServerConnectionConfig(host, rpc_port));
        }
        else
        {
            std::cout << "image server configure string invalid" << std::endl;
            return EXIT_FAILURE;
        }
    }

    if(!imgserver_config)
    {
        std::cout << "image server must be configured" << std::endl;
        return -1;
    }

    if(!ImageServerClient::Init(*(imgserver_config.get())))
    {
        LOG(ERROR) << "Image Server Client Init failed." << std::endl;
        return -1;
    }
    if(!ImageServerClient::Test())
    {
        LOG(ERROR) << "Image Server Client Test failed." << std::endl;
        return -1;
    }

    std::string local_image_path;
    if(vm.count("localimagepath"))
    {
        local_image_path = vm["localimagepath"].as<std::string>();
    }
    write_file(local_image_path);
    return 0;
}

static int save_stats_by_storage_ip()
{
	int k;
	char filename[256];
	FILE *fp;

	sprintf(filename, "%s", STAT_FILENAME_BY_STORAGE_IP);
	if ((fp=fopen(filename, "wb")) == NULL)
	{
		printf("open file %s fail \n",
			filename);
        perror("error:");
		return errno != 0 ? errno : EPERM;
	}

	fprintf(fp, "#ip_addr total_count success_count time_used(ms)\n");
	for (k=0; k<storage_count; k++)
	{
		fprintf(fp, "%d %d "INT64_PRINTF_FORMAT"\n", \
			storages[k].total_count, \
			storages[k].success_count, storages[k].time_used);
	}

	fclose(fp);
	return 0;
}

static int save_stats_by_overall()
{
	char filename[256];
	FILE *fp;

	sprintf(filename, "%s", STAT_FILENAME_BY_OVERALL);
	if ((fp=fopen(filename, "wb")) == NULL)
	{
		printf("open file %s fail\n",
			filename);
        perror("error:");
		return errno != 0 ? errno : EPERM;
	}

	fprintf(fp, "#total_count success_count  time_used(s)\n");
	fprintf(fp, "%d %d %d\n", total_count, success_count, (int)(time(NULL) - start_time));

	fclose(fp);
	return 0;
}

static int add_to_storage_stat(int storage_i, const int result, const int time_used)
{
	StorageStat *pStorage;
    pStorage = storages + storage_i;

    storage_count = storage_i + 1;

	pStorage->time_used += time_used;
	pStorage->total_count++;
	if (result == 0)
	{
		pStorage->success_count++;
	}

	return 0;
}

static int test_init()
{
	char filename[256];

	if (access("tfs_upload", 0) != 0 && mkdir("tfs_upload", 0755) != 0)
	{
	}

	if (chdir("tfs_upload") != 0)
	{
		printf("chdir fail\n");
        perror("err:");
		return errno != 0 ? errno : EPERM;
	}

	sprintf(filename, "%s", FILENAME_FILE_ID);
	if ((fpSuccess=fopen(filename, "wb")) == NULL)
	{
		printf("open file %s fail\n",
			filename);
        perror("err:");
		return errno != 0 ? errno : EPERM;
	}

	sprintf(filename, "%s", FILENAME_FAIL);
	if ((fpFail=fopen(filename, "wb")) == NULL)
	{
		printf("open file %s fail\n",
			filename);
        perror("err:");
		return errno != 0 ? errno : EPERM;
	}

	return 0;
}

<|endoftext|>


<commit_before>// Copyright (c) 2017 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include <iostream>
#include <vector>
#include <string>
#include <chrono>
#include <array>
#include <iterator>
#include <random>
#include <algorithm>

#include <boost/program_options.hpp>

#include <hip/hip_runtime.h>
#include <rocrand.h>
#include <file_common.hpp>

extern "C" {
#include "bbattery.h"
}

#define HIP_CHECK(condition)         \
  {                                  \
    hipError_t error = condition;    \
    if(error != hipSuccess){         \
        std::cout << error << std::endl; \
        exit(error); \
    } \
  }

#define ROCRAND_CHECK(condition)                 \
  {                                              \
    rocrand_status status = condition;           \
    if(status != ROCRAND_STATUS_SUCCESS) {       \
        std::cout << status << std::endl; \
        exit(status); \
    } \
  }

#ifndef DEFAULT_RAND_N
const size_t DEFAULT_RAND_N = 1024 * 1024 * 64;
#endif

void run_crush_test(const size_t size, const rocrand_rng_type rng_type)
{
    std::string filename = "rocrand_generate.txt";
    char * file = new char[filename.length() + 1];
    std::strcpy(file, filename.c_str());

    unsigned int * data;
    unsigned int * h_data = new unsigned int[size];
    double * h_data_double = new double[size];
    HIP_CHECK(hipMalloc((void **)&data, size * sizeof(unsigned int)));

    rocrand_generator generator;
    ROCRAND_CHECK(rocrand_create_generator(&generator, rng_type));
    // Make sure memory is allocated
    HIP_CHECK(hipDeviceSynchronize());

    ROCRAND_CHECK(rocrand_generate(generator, (unsigned int *) data, size));
    HIP_CHECK(hipDeviceSynchronize());

    HIP_CHECK(hipMemcpy(h_data, data, size * sizeof(unsigned int), hipMemcpyDeviceToHost));
    HIP_CHECK(hipDeviceSynchronize());

    for(size_t i = 0; i < size; i++)
    {
        h_data_double[i] = static_cast<double>(h_data[i]) / (UINT_MAX + 1UL);
    }
    delete[] h_data;

    rocrand_file_write_results(filename, h_data_double, size);

    rocrand_destroy_generator(generator);
    HIP_CHECK(hipFree(data));
    delete[] h_data_double;

    bbattery_SmallCrushFile(file);
    delete[] file;
}

int main(int argc, char *argv[])
{
    namespace po = boost::program_options;
    po::options_description options("options");
    options.add_options()
        ("help", "show usage instructions")
        ("size", po::value<size_t>()->default_value(DEFAULT_RAND_N), "number of values")
        ("engine", po::value<std::string>()->default_value("philox"), "random number engine")
    ;
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, options), vm);
    po::notify(vm);

    if(vm.count("help")) {
        std::cout << options << std::endl;
        return 0;
    }

    const size_t size = vm["size"].as<size_t>();
    const std::string& engine = vm["engine"].as<std::string>();

    if(engine == "philox" || engine == "all"){
        std::cout << "philox4x32_10:" << std::endl;
        run_crush_test(size, ROCRAND_RNG_PSEUDO_PHILOX4_32_10);
        return 0;
    }

    std::cerr << "Error: unknown random number engine '" << engine << "'" << std::endl;
    return -1;
}
<commit_msg>Remove file after crush-test<commit_after>// Copyright (c) 2017 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include <iostream>
#include <vector>
#include <string>
#include <chrono>
#include <array>
#include <iterator>
#include <random>
#include <algorithm>

#include <boost/program_options.hpp>

#include <hip/hip_runtime.h>
#include <rocrand.h>
#include <file_common.hpp>

extern "C" {
#include "bbattery.h"
}

#define HIP_CHECK(condition)         \
  {                                  \
    hipError_t error = condition;    \
    if(error != hipSuccess){         \
        std::cout << error << std::endl; \
        exit(error); \
    } \
  }

#define ROCRAND_CHECK(condition)                 \
  {                                              \
    rocrand_status status = condition;           \
    if(status != ROCRAND_STATUS_SUCCESS) {       \
        std::cout << status << std::endl; \
        exit(status); \
    } \
  }

#ifndef DEFAULT_RAND_N
const size_t DEFAULT_RAND_N = 1024 * 1024 * 64;
#endif

void run_crush_test(const size_t size, const rocrand_rng_type rng_type)
{
    std::string filename = "rocrand_generate.txt";
    char * file = new char[filename.length() + 1];
    std::strcpy(file, filename.c_str());

    unsigned int * data;
    unsigned int * h_data = new unsigned int[size];
    double * h_data_double = new double[size];
    HIP_CHECK(hipMalloc((void **)&data, size * sizeof(unsigned int)));

    rocrand_generator generator;
    ROCRAND_CHECK(rocrand_create_generator(&generator, rng_type));
    // Make sure memory is allocated
    HIP_CHECK(hipDeviceSynchronize());

    ROCRAND_CHECK(rocrand_generate(generator, (unsigned int *) data, size));
    HIP_CHECK(hipDeviceSynchronize());

    HIP_CHECK(hipMemcpy(h_data, data, size * sizeof(unsigned int), hipMemcpyDeviceToHost));
    HIP_CHECK(hipDeviceSynchronize());

    for(size_t i = 0; i < size; i++)
    {
        h_data_double[i] = static_cast<double>(h_data[i]) / (UINT_MAX + 1UL);
    }
    delete[] h_data;

    rocrand_file_write_results(filename, h_data_double, size);

    rocrand_destroy_generator(generator);
    HIP_CHECK(hipFree(data));
    delete[] h_data_double;

    bbattery_SmallCrushFile(file);
    std::remove(file);
    delete[] file;
}

int main(int argc, char *argv[])
{
    namespace po = boost::program_options;
    po::options_description options("options");
    options.add_options()
        ("help", "show usage instructions")
        ("size", po::value<size_t>()->default_value(DEFAULT_RAND_N), "number of values")
        ("engine", po::value<std::string>()->default_value("philox"), "random number engine")
    ;
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, options), vm);
    po::notify(vm);

    if(vm.count("help")) {
        std::cout << options << std::endl;
        return 0;
    }

    const size_t size = vm["size"].as<size_t>();
    const std::string& engine = vm["engine"].as<std::string>();

    if(engine == "philox" || engine == "all"){
        std::cout << "philox4x32_10:" << std::endl;
        run_crush_test(size, ROCRAND_RNG_PSEUDO_PHILOX4_32_10);
        return 0;
    }

    std::cerr << "Error: unknown random number engine '" << engine << "'" << std::endl;
    return -1;
}
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2007 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "common.h"

// system headers
#include <string>

// common headers
#include "bzfio.h"
#include "StateDatabase.h"
#include "bzfgl.h"
#include "OpenGLTexture.h"
#include "OpenGLGState.h"

#ifndef _WIN32
typedef int64_t s64;
#else
typedef __int64 s64;
#endif

//
// OpenGLTexture::Rep
//

const GLenum		OpenGLTexture::minifyFilter[] = {
				GL_NEAREST,
				GL_NEAREST,
				GL_LINEAR,
				GL_NEAREST_MIPMAP_NEAREST,
				GL_LINEAR_MIPMAP_NEAREST,
				GL_NEAREST_MIPMAP_LINEAR,
				GL_LINEAR_MIPMAP_LINEAR
			};
const GLenum		OpenGLTexture::magnifyFilter[] = {
				GL_NEAREST,
				GL_NEAREST,
				GL_LINEAR,
				GL_NEAREST,
				GL_LINEAR,
				GL_NEAREST,
				GL_LINEAR
			};
const char*		OpenGLTexture::configFilterNames[] = {
				"no",
				"nearest",
				"linear",
				"nearestmipmapnearest",
				"linearmipmapnearest",
				"nearestmipmaplinear",
				"linearmipmaplinear"
};

//
// OpenGLTexture
//

const int OpenGLTexture::filterCount = Max + 1;
OpenGLTexture::Filter OpenGLTexture::maxFilter = Default;

OpenGLTexture::OpenGLTexture(int _width, int _height, const GLvoid* pixels,
			     Filter _filter, bool _repeat, int _internalFormat) :
			   width(_width), height(_height)
{
  alpha = false;
  repeat = _repeat;
  internalFormat = _internalFormat;
  filter = _filter;
  list = INVALID_GL_TEXTURE_ID;

  // get internal format if not provided
  if (internalFormat == 0)
    internalFormat = getBestFormat(width, height, pixels);

  // copy/scale the original texture image
  setupImage((const GLubyte*)pixels);

  // build and bind the GL texture
  initContext();

  // watch for context recreation
  OpenGLGState::registerContextInitializer(static_freeContext,
					   static_initContext, (void*)this);
}

OpenGLTexture::~OpenGLTexture()
{
  OpenGLGState::unregisterContextInitializer(static_freeContext,
					     static_initContext, (void*)this);
  delete[] imageMemory;

  freeContext();
  return;
}

void OpenGLTexture::static_freeContext(void *that)
{
  ((OpenGLTexture*) that)->freeContext();
}

void OpenGLTexture::static_initContext(void *that)
{
  ((OpenGLTexture*) that)->initContext();
}

void OpenGLTexture::freeContext()
{
  // glDeleteTextures should set binding to 0 by itself when the texture
  //  is in use, but some stacks (Linux/glx/matrox) are broken, so play it safe
  glBindTexture(GL_TEXTURE_2D, 0);

  if (list != INVALID_GL_TEXTURE_ID) {
    glDeleteTextures(1, &list);
    list = INVALID_GL_TEXTURE_ID;
  }
  return;
}

void OpenGLTexture::initContext()
{
  // make texture map object/list
  glGenTextures(1, &list);

  // now make texture map display list (compute all mipmaps, if requested).
  // compute next mipmap from current mipmap to save time.
  setFilter(filter);
  glBindTexture(GL_TEXTURE_2D, list);
  gluBuild2DMipmaps(GL_TEXTURE_2D, internalFormat,
		    scaledWidth, scaledHeight,
		    GL_RGBA, GL_UNSIGNED_BYTE, image);
  glBindTexture(GL_TEXTURE_2D, 0);

  return;
}

bool OpenGLTexture::setupImage(const GLubyte* pixels)
{
  // align to a 2^N value
  scaledWidth = 1;
  scaledHeight = 1;
  while (scaledWidth < width) {
    scaledWidth <<= 1;
  }
  while (scaledHeight < height) {
    scaledHeight <<= 1;
  }

  // get maximum valid size for texture (boost to 2^m x 2^n)
  GLint maxTextureSize;
  glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);

  // hard limit, some drivers have problems with sizes greater
  // then this (espeically if you are using glTexSubImage2D)
  const GLint dbMaxTexSize = BZDB.evalInt("maxTextureSize");
  GLint bzMaxTexSize = 1;
  // align the max size to a power of two  (wasteful)
  while (bzMaxTexSize < dbMaxTexSize) {
    bzMaxTexSize <<= 1;
  }

  if ((maxTextureSize < 0) || (maxTextureSize > bzMaxTexSize)) {
    maxTextureSize = bzMaxTexSize;
  }

  // clamp to the maximum size
  if (scaledWidth > maxTextureSize) {
    scaledWidth = maxTextureSize;
  }
  if (scaledHeight > maxTextureSize) {
    scaledHeight = maxTextureSize;
  }

  // NOTE: why these are 4-byte aligned is beyond me...

  // copy the data into a 4-byte aligned buffer
  GLubyte* unaligned = new GLubyte[4 * width * height + 4];
  GLubyte* aligned = (GLubyte*)(((unsigned long)unaligned & ~3) + 4);
  ::memcpy(aligned, pixels, 4 * width * height);

  // scale the image if required
  if ((scaledWidth != width) || (scaledHeight != height)) {
    GLubyte* unalignedScaled = new GLubyte[4 * scaledWidth * scaledHeight + 4];
    GLubyte* alignedScaled = (GLubyte*)(((unsigned long)unalignedScaled & ~3) + 4);

    // FIXME: 0 is success, return false otherwise...
    gluScaleImage (GL_RGBA, width, height, GL_UNSIGNED_BYTE, aligned,
		   scaledWidth, scaledHeight, GL_UNSIGNED_BYTE, alignedScaled);

    delete[] unaligned;
    unaligned = unalignedScaled;
    aligned = alignedScaled;
    logDebugMessage(1,"Scaling texture from %ix%i to %ix%i\n",
	   width, height, scaledWidth, scaledHeight);
  }

  // set the image
  image = aligned;
  imageMemory = unaligned;

  // note if internal format uses alpha
  switch (internalFormat) {
    case GL_LUMINANCE_ALPHA:
#if defined(GL_LUMINANCE4_ALPHA4)
    case GL_LUMINANCE4_ALPHA4:
#elif defined(GL_LUMINANCE4_ALPHA4_EXT)
    case GL_LUMINANCE4_ALPHA4_EXT:
#endif
    case GL_RGBA:
#if defined(GL_INTENSITY4)
    case GL_INTENSITY4:
#elif defined(GL_INTENSITY4_EXT)
    case GL_INTENSITY4_EXT:
#endif
      alpha = true;
      break;
    default:
      alpha = false;
      break;
  }

  return true;
}

OpenGLTexture::Filter OpenGLTexture::getFilter()
{
  return filter;
}

void OpenGLTexture::setFilter(Filter _filter)
{
  filter = _filter;

  int filterIndex = (int) filter;
  // limit filter.  try to keep nearest... filters as nearest and
  // linear... as linear.
  if (filterIndex > maxFilter) {
    if ((filterIndex & 1) == 1)	{ // nearest...
      if ((maxFilter & 1) == 1) {
	filterIndex = maxFilter;
      } else {
	filterIndex = maxFilter > 0 ? maxFilter - 1 : 0;
      }
    }
    else { // linear...
      if ((maxFilter & 1) == 1) {
	filterIndex = maxFilter - 1;
      } else {
	filterIndex = maxFilter;
      }
    }
  }
  GLint binding;
  glGetIntegerv (GL_TEXTURE_BINDING_2D, &binding);
  glBindTexture(GL_TEXTURE_2D, list);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minifyFilter[filterIndex]);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magnifyFilter[filterIndex]);
#ifdef HAVE_GLEW
  if (GLEW_EXT_texture_filter_anisotropic) {
    GLint aniso = BZDB.evalInt("aniso");
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso);
  }
#endif
  glBindTexture(GL_TEXTURE_2D, binding);
}

OpenGLTexture::Filter OpenGLTexture::getMaxFilter()
{
  return maxFilter;
}

void OpenGLTexture::setMaxFilter(Filter _filter)
{
  maxFilter = _filter;
}

void OpenGLTexture::execute()
{
  bind();
}

const char* OpenGLTexture::getFilterName(OpenGLTexture::Filter filter)
{
  if ((filter < 0) || (filter > Max)) {
    return configFilterNames[Max];
  } else {
    return configFilterNames[filter];
  }
}

int OpenGLTexture::getFilterCount()
{
  return filterCount;
}

const char** OpenGLTexture::getFilterNames()
{
  return configFilterNames;
}

float OpenGLTexture::getAspectRatio() const
{
  return ((float) height) / ((float) width);
}

void OpenGLTexture::bind()
{
  if (list != INVALID_GL_TEXTURE_ID) {
    glBindTexture(GL_TEXTURE_2D, list);
  } else {
    glBindTexture(GL_TEXTURE_2D, 0); // heh, it's the same call
  }
}

int OpenGLTexture::getBestFormat(int _width, int _height, const GLvoid* pixels)
{
  // see if all pixels are achromatic
  const GLubyte* scan = (const GLubyte*)pixels;
  const int size = _width * _height;
  int i;
  for (i = 0; i < size; scan += 4, i++)
    if (scan[0] != scan[1] || scan[0] != scan[2])
      break;
  const bool useLuminance = (i == size);

  // see if all pixels are opaque
  scan = (const GLubyte*)pixels;
  for (i = 0; i < size; scan += 4, i++)
    if (scan[3] != 0xff)
      break;
  const bool useAlpha = (i != size);

  // intensity format defined in 1.1 and an extension in 1.0
  static const bool hasTextureExt = true;

  // see if all pixels are r=g=b=a.  if so return intensity format.
  // SGI IMPACT systems don't support GL_INTENSITY.
  const char* const glRenderer = (const char*)glGetString(GL_RENDERER);
  static bool noIntensity =
    ((glRenderer == NULL) ||
     (strncmp(glRenderer, "IMPACT", 6) == 0));
  if (!noIntensity) {
    bool useIntensity = false;
    if (hasTextureExt && useLuminance) {
      scan = (const GLubyte*)pixels;
      for (i = 0; i < size; scan += 4, i++)
	if (scan[3] != scan[0])
	  break;
      useIntensity = (i == size);
    }
    if (useIntensity)
      return GL_INTENSITY;
  }

  // pick internal format
  return (useLuminance ?
		(useAlpha ? GL_LUMINANCE_ALPHA : GL_LUMINANCE) :
		(useAlpha ? GL_RGBA : GL_RGB));
}

bool OpenGLTexture::getColorAverages(float rgba[4], bool factorAlpha) const
{
  if ((image == NULL) || (scaledWidth <= 0) || (scaledHeight <= 0)) {
    return false;
  }

  factorAlpha = (factorAlpha && alpha);
  const int channelCount = alpha ? 4 : 3;

  // tally the values
  s64 rgbaTally[4] = {0, 0, 0, 0};
  for (int x = 0; x < scaledWidth; x++) {
    for (int y = 0; y < scaledHeight; y++) {
      for (int c = 0; c < channelCount; c++) {
	const int pixelBase = 4 * (x + (y * scaledWidth));
	if (factorAlpha) {
	  const GLubyte alphaVal = image[pixelBase + 3];
	  if (c == 3) {
	    rgbaTally[3] += alphaVal;
	  } else {
	    rgbaTally[c] += image[pixelBase + c] * alphaVal;
	  }
	} else {
	  rgbaTally[c] += image[pixelBase + c];
	}
      }
    }
  }

  // calculate the alpha average
  float maxTally = 255.0f * (scaledWidth * scaledHeight);
  if (channelCount == 3) {
    rgba[3] = 1.0f;
  } else {
    rgba[3] = (float)rgbaTally[3] / maxTally;
  }

  // adjust the maxTally for alpha weighting
  if (factorAlpha) {
    maxTally = maxTally * 255.0f;
  }

  // calcualte the color averages
  for (int c = 0; c < 3; c++) {
    rgba[c] = (float)rgbaTally[c] / maxTally;
  }

  return true;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>boo hiss, maxTextureSize is provided by the client so if this library is going to check for it, the check needs to be optional.  if maxTextureSize is unset, don't fall back to a texture size of 1 -- instead use whatever the texture size was to begin with.<commit_after>/* bzflag
 * Copyright (c) 1993 - 2007 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "common.h"

// system headers
#include <string>

// common headers
#include "bzfio.h"
#include "StateDatabase.h"
#include "bzfgl.h"
#include "OpenGLTexture.h"
#include "OpenGLGState.h"

#ifndef _WIN32
typedef int64_t s64;
#else
typedef __int64 s64;
#endif

//
// OpenGLTexture::Rep
//

const GLenum		OpenGLTexture::minifyFilter[] = {
				GL_NEAREST,
				GL_NEAREST,
				GL_LINEAR,
				GL_NEAREST_MIPMAP_NEAREST,
				GL_LINEAR_MIPMAP_NEAREST,
				GL_NEAREST_MIPMAP_LINEAR,
				GL_LINEAR_MIPMAP_LINEAR
			};
const GLenum		OpenGLTexture::magnifyFilter[] = {
				GL_NEAREST,
				GL_NEAREST,
				GL_LINEAR,
				GL_NEAREST,
				GL_LINEAR,
				GL_NEAREST,
				GL_LINEAR
			};
const char*		OpenGLTexture::configFilterNames[] = {
				"no",
				"nearest",
				"linear",
				"nearestmipmapnearest",
				"linearmipmapnearest",
				"nearestmipmaplinear",
				"linearmipmaplinear"
};

//
// OpenGLTexture
//

const int OpenGLTexture::filterCount = Max + 1;
OpenGLTexture::Filter OpenGLTexture::maxFilter = Default;

OpenGLTexture::OpenGLTexture(int _width, int _height, const GLvoid* pixels,
			     Filter _filter, bool _repeat, int _internalFormat) :
			   width(_width), height(_height)
{
  alpha = false;
  repeat = _repeat;
  internalFormat = _internalFormat;
  filter = _filter;
  list = INVALID_GL_TEXTURE_ID;

  // get internal format if not provided
  if (internalFormat == 0)
    internalFormat = getBestFormat(width, height, pixels);

  // copy/scale the original texture image
  setupImage((const GLubyte*)pixels);

  // build and bind the GL texture
  initContext();

  // watch for context recreation
  OpenGLGState::registerContextInitializer(static_freeContext,
					   static_initContext, (void*)this);
}

OpenGLTexture::~OpenGLTexture()
{
  OpenGLGState::unregisterContextInitializer(static_freeContext,
					     static_initContext, (void*)this);
  delete[] imageMemory;

  freeContext();
  return;
}

void OpenGLTexture::static_freeContext(void *that)
{
  ((OpenGLTexture*) that)->freeContext();
}

void OpenGLTexture::static_initContext(void *that)
{
  ((OpenGLTexture*) that)->initContext();
}

void OpenGLTexture::freeContext()
{
  // glDeleteTextures should set binding to 0 by itself when the texture
  //  is in use, but some stacks (Linux/glx/matrox) are broken, so play it safe
  glBindTexture(GL_TEXTURE_2D, 0);

  if (list != INVALID_GL_TEXTURE_ID) {
    glDeleteTextures(1, &list);
    list = INVALID_GL_TEXTURE_ID;
  }
  return;
}

void OpenGLTexture::initContext()
{
  // make texture map object/list
  glGenTextures(1, &list);

  // now make texture map display list (compute all mipmaps, if requested).
  // compute next mipmap from current mipmap to save time.
  setFilter(filter);
  glBindTexture(GL_TEXTURE_2D, list);
  gluBuild2DMipmaps(GL_TEXTURE_2D, internalFormat,
		    scaledWidth, scaledHeight,
		    GL_RGBA, GL_UNSIGNED_BYTE, image);
  glBindTexture(GL_TEXTURE_2D, 0);

  return;
}

bool OpenGLTexture::setupImage(const GLubyte* pixels)
{
  // align to a 2^N value
  scaledWidth = 1;
  scaledHeight = 1;
  while (scaledWidth < width) {
    scaledWidth <<= 1;
  }
  std::cout << "width is " << width << std::endl;
  std::cout << "scaledWidth is " << scaledWidth << std::endl;
  while (scaledHeight < height) {
    scaledHeight <<= 1;
  }
  std::cout << "height is " << height << std::endl;
  std::cout << "scaledHeight is " << scaledHeight << std::endl;

  // get maximum valid size for texture (boost to 2^m x 2^n)
  GLint maxTextureSize;
  glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);

  // hard limit, some drivers have problems with sizes greater
  // then this (espeically if you are using glTexSubImage2D)
  const GLint dbMaxTexSize = BZDB.evalInt("maxTextureSize");
  GLint bzMaxTexSize = 1;
  if (dbMaxTexSize > 0) {
    // align the max size to a power of two  (wasteful)
    while (bzMaxTexSize < dbMaxTexSize) {
      bzMaxTexSize <<= 1;
    }
  } else {
    bzMaxTexSize = scaledHeight > scaledWidth ? scaledHeight : scaledWidth;
  }

  if ((maxTextureSize < 0) || (maxTextureSize > bzMaxTexSize)) {
    maxTextureSize = bzMaxTexSize;
  }

  // clamp to the maximum size
  if (scaledWidth > maxTextureSize) {
    scaledWidth = maxTextureSize;
  }
  if (scaledHeight > maxTextureSize) {
    scaledHeight = maxTextureSize;
  }

  // NOTE: why these are 4-byte aligned is beyond me...

  // copy the data into a 4-byte aligned buffer
  GLubyte* unaligned = new GLubyte[4 * width * height + 4];
  GLubyte* aligned = (GLubyte*)(((unsigned long)unaligned & ~3) + 4);
  ::memcpy(aligned, pixels, 4 * width * height);

  // scale the image if required
  if ((scaledWidth != width) || (scaledHeight != height)) {
    GLubyte* unalignedScaled = new GLubyte[4 * scaledWidth * scaledHeight + 4];
    GLubyte* alignedScaled = (GLubyte*)(((unsigned long)unalignedScaled & ~3) + 4);

    // FIXME: 0 is success, return false otherwise...
    gluScaleImage (GL_RGBA, width, height, GL_UNSIGNED_BYTE, aligned,
		   scaledWidth, scaledHeight, GL_UNSIGNED_BYTE, alignedScaled);

    delete[] unaligned;
    unaligned = unalignedScaled;
    aligned = alignedScaled;
    logDebugMessage(1,"Scaling texture from %ix%i to %ix%i\n",
	   width, height, scaledWidth, scaledHeight);
  }

  // set the image
  image = aligned;
  imageMemory = unaligned;

  // note if internal format uses alpha
  switch (internalFormat) {
    case GL_LUMINANCE_ALPHA:
#if defined(GL_LUMINANCE4_ALPHA4)
    case GL_LUMINANCE4_ALPHA4:
#elif defined(GL_LUMINANCE4_ALPHA4_EXT)
    case GL_LUMINANCE4_ALPHA4_EXT:
#endif
    case GL_RGBA:
#if defined(GL_INTENSITY4)
    case GL_INTENSITY4:
#elif defined(GL_INTENSITY4_EXT)
    case GL_INTENSITY4_EXT:
#endif
      alpha = true;
      break;
    default:
      alpha = false;
      break;
  }

  return true;
}

OpenGLTexture::Filter OpenGLTexture::getFilter()
{
  return filter;
}

void OpenGLTexture::setFilter(Filter _filter)
{
  filter = _filter;

  int filterIndex = (int) filter;
  // limit filter.  try to keep nearest... filters as nearest and
  // linear... as linear.
  if (filterIndex > maxFilter) {
    if ((filterIndex & 1) == 1)	{ // nearest...
      if ((maxFilter & 1) == 1) {
	filterIndex = maxFilter;
      } else {
	filterIndex = maxFilter > 0 ? maxFilter - 1 : 0;
      }
    }
    else { // linear...
      if ((maxFilter & 1) == 1) {
	filterIndex = maxFilter - 1;
      } else {
	filterIndex = maxFilter;
      }
    }
  }
  GLint binding;
  glGetIntegerv (GL_TEXTURE_BINDING_2D, &binding);
  glBindTexture(GL_TEXTURE_2D, list);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minifyFilter[filterIndex]);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magnifyFilter[filterIndex]);
#ifdef HAVE_GLEW
  if (GLEW_EXT_texture_filter_anisotropic) {
    GLint aniso = BZDB.evalInt("aniso");
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso);
  }
#endif
  glBindTexture(GL_TEXTURE_2D, binding);
}

OpenGLTexture::Filter OpenGLTexture::getMaxFilter()
{
  return maxFilter;
}

void OpenGLTexture::setMaxFilter(Filter _filter)
{
  maxFilter = _filter;
}

void OpenGLTexture::execute()
{
  bind();
}

const char* OpenGLTexture::getFilterName(OpenGLTexture::Filter filter)
{
  if ((filter < 0) || (filter > Max)) {
    return configFilterNames[Max];
  } else {
    return configFilterNames[filter];
  }
}

int OpenGLTexture::getFilterCount()
{
  return filterCount;
}

const char** OpenGLTexture::getFilterNames()
{
  return configFilterNames;
}

float OpenGLTexture::getAspectRatio() const
{
  return ((float) height) / ((float) width);
}

void OpenGLTexture::bind()
{
  if (list != INVALID_GL_TEXTURE_ID) {
    glBindTexture(GL_TEXTURE_2D, list);
  } else {
    glBindTexture(GL_TEXTURE_2D, 0); // heh, it's the same call
  }
}

int OpenGLTexture::getBestFormat(int _width, int _height, const GLvoid* pixels)
{
  // see if all pixels are achromatic
  const GLubyte* scan = (const GLubyte*)pixels;
  const int size = _width * _height;
  int i;
  for (i = 0; i < size; scan += 4, i++)
    if (scan[0] != scan[1] || scan[0] != scan[2])
      break;
  const bool useLuminance = (i == size);

  // see if all pixels are opaque
  scan = (const GLubyte*)pixels;
  for (i = 0; i < size; scan += 4, i++)
    if (scan[3] != 0xff)
      break;
  const bool useAlpha = (i != size);

  // intensity format defined in 1.1 and an extension in 1.0
  static const bool hasTextureExt = true;

  // see if all pixels are r=g=b=a.  if so return intensity format.
  // SGI IMPACT systems don't support GL_INTENSITY.
  const char* const glRenderer = (const char*)glGetString(GL_RENDERER);
  static bool noIntensity =
    ((glRenderer == NULL) ||
     (strncmp(glRenderer, "IMPACT", 6) == 0));
  if (!noIntensity) {
    bool useIntensity = false;
    if (hasTextureExt && useLuminance) {
      scan = (const GLubyte*)pixels;
      for (i = 0; i < size; scan += 4, i++)
	if (scan[3] != scan[0])
	  break;
      useIntensity = (i == size);
    }
    if (useIntensity)
      return GL_INTENSITY;
  }

  // pick internal format
  return (useLuminance ?
		(useAlpha ? GL_LUMINANCE_ALPHA : GL_LUMINANCE) :
		(useAlpha ? GL_RGBA : GL_RGB));
}

bool OpenGLTexture::getColorAverages(float rgba[4], bool factorAlpha) const
{
  if ((image == NULL) || (scaledWidth <= 0) || (scaledHeight <= 0)) {
    return false;
  }

  factorAlpha = (factorAlpha && alpha);
  const int channelCount = alpha ? 4 : 3;

  // tally the values
  s64 rgbaTally[4] = {0, 0, 0, 0};
  for (int x = 0; x < scaledWidth; x++) {
    for (int y = 0; y < scaledHeight; y++) {
      for (int c = 0; c < channelCount; c++) {
	const int pixelBase = 4 * (x + (y * scaledWidth));
	if (factorAlpha) {
	  const GLubyte alphaVal = image[pixelBase + 3];
	  if (c == 3) {
	    rgbaTally[3] += alphaVal;
	  } else {
	    rgbaTally[c] += image[pixelBase + c] * alphaVal;
	  }
	} else {
	  rgbaTally[c] += image[pixelBase + c];
	}
      }
    }
  }

  // calculate the alpha average
  float maxTally = 255.0f * (scaledWidth * scaledHeight);
  if (channelCount == 3) {
    rgba[3] = 1.0f;
  } else {
    rgba[3] = (float)rgbaTally[3] / maxTally;
  }

  // adjust the maxTally for alpha weighting
  if (factorAlpha) {
    maxTally = maxTally * 255.0f;
  }

  // calcualte the color averages
  for (int c = 0; c < 3; c++) {
    rgba[c] = (float)rgbaTally[c] / maxTally;
  }

  return true;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>#include "Platform.hpp"
#include "genome.pb.h"
#include "CellComponent.hpp"
#include "ActivityStats.hpp"
#include "Neuron.hpp"
#include "Branch.hpp"
#include "Synapse.hpp"
#include "Base64.hpp"
#include "Brain.hpp"
#include "SimpleProteinEnvironment.hpp"
#include "genome.pb.h"
#include <time.h>

namespace Elysia {
void testTwoConnectedNeurons() {
    ProteinEnvironment *myProteinEnvironment= new SimpleProteinEnvironment();

	Brain *brain= new Brain(myProteinEnvironment);
	for(float i=0;i<2;i++){
        Genome::Gene gene;//FIXME set source and target regions to match the desired behavior
        Genome::TemporalBoundingBox *sourcebb=gene.add_bounds();
        Genome::TemporalBoundingBox *targetbb=gene.add_bounds();
        sourcebb->set_minx(i);
        sourcebb->set_miny(i);
        sourcebb->set_minz(i);

        sourcebb->set_maxx(i);
        sourcebb->set_maxy(i);
        sourcebb->set_maxz(i);

        targetbb->set_minx(1-i);
        targetbb->set_miny(1-i);
        targetbb->set_minz(1-i);

        targetbb->set_maxx(1-i);
        targetbb->set_maxy(1-i);
        targetbb->set_maxz(1-i);

		Vector3f v;
		v.x = i;
		v.y = i;
		v.z = i;
		Neuron *n;
		srand(time(NULL));
		brain->mAllNeurons.insert(n = new Neuron(brain, 2, 3, 4, v,gene));
        n->developSynapse(n->getActivityStats());
        if(i == 1){
        FILE *dendriteTree=NULL;
        size_t parent;
        parent = 0;
        n->visualizeTree(dendriteTree, parent);
            //n->activateComponent(*brain,100);
            //n->tick();
        }
		//const Vector3f &location):  mNeuronLocation(location){));
	}

}

}

int runtest(){
    Elysia::testTwoConnectedNeurons();
	getchar();
	return 1;

}
<commit_msg><commit_after>#include "Platform.hpp"
#include "genome.pb.h"
#include "CellComponent.hpp"
#include "ActivityStats.hpp"
#include "Neuron.hpp"
#include "Branch.hpp"
#include "Synapse.hpp"
#include "Base64.hpp"
#include "Brain.hpp"
#include "SimpleProteinEnvironment.hpp"
#include "genome.pb.h"
#include <time.h>

namespace Elysia {
void testTwoConnectedNeurons() {
    ProteinEnvironment *myProteinEnvironment= new SimpleProteinEnvironment();

	Brain *brain= new Brain(myProteinEnvironment);
	for(float i=0;i<2;i++){
        Genome::Gene gene;//FIXME set source and target regions to match the desired behavior
        Genome::TemporalBoundingBox *sourcebb=gene.add_bounds();
        Genome::TemporalBoundingBox *targetbb=gene.add_bounds();
        sourcebb->set_minx(i);
        sourcebb->set_miny(i);
        sourcebb->set_minz(i);

        sourcebb->set_maxx(i);
        sourcebb->set_maxy(i);
        sourcebb->set_maxz(i);

        targetbb->set_minx(1-i);
        targetbb->set_miny(1-i);
        targetbb->set_minz(1-i);

        targetbb->set_maxx(1-i);
        targetbb->set_maxy(1-i);
        targetbb->set_maxz(1-i);

		Vector3f v;
		v.x = i;
		v.y = i;
		v.z = i;
		Neuron *n;
		srand(time(NULL));
		brain->mAllNeurons.insert(n = new Neuron(brain, 2, 3, 4, v,gene));
        n->developSynapse(n->getActivityStats());
        if(i == 1){
        FILE *dendriteTree=NULL;
        size_t parent;
        parent = 0;
        n->visualizeTree(dendriteTree, parent);
        n->activateComponent(*brain,100);
        n->tick();
        }
		//const Vector3f &location):  mNeuronLocation(location){));
	}

}

}

int runtest(){
    Elysia::testTwoConnectedNeurons();
	getchar();
	return 1;

}
<|endoftext|>


<commit_before>#include "omnicore/rpcrawtx.h"

#include "omnicore/omnicore.h"
#include "omnicore/rpc.h"
#include "omnicore/rpctxobject.h"
#include "omnicore/utilsbitcoin.h"

#include "coins.h"
#include "core_io.h"
#include "primitives/transaction.h"
#include "rpcserver.h"
#include "sync.h"
#include "uint256.h"

#include "json/json_spirit_value.h"

#include <boost/assign/list_of.hpp>
#include <boost/foreach.hpp>

#include <stdint.h>
#include <algorithm>
#include <stdexcept>
#include <string>

extern CCriticalSection cs_main;

using mastercore::GetHeight;
using mastercore::cs_tx_cache;
using mastercore::view;

using namespace json_spirit;

Value omni_decodetransaction(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 1 || params.size() > 2)
        throw std::runtime_error(
            "omni_decodetransaction \"txhex\" ( \"prevtxs\" )\n"

            "\nDecodes an Omni transaction.\n"

            "\nIf the inputs of the transaction are not in the chain, then they must be provided, because "
            "the transaction inputs are used to identify the sender of a transaction.\n"

            "\nArguments:\n"
            "1. txhex                (string, required) the raw transaction to decode\n"
            "2. prevtxs              (string, optional) a JSON array of transaction inputs (default: none)\n"
            "     [\n"
            "       {\n"
            "         \"txid\":\"hash\",          (string, required) the transaction hash\n"
            "         \"vout\":n,               (number, required) the output number\n"
            "         \"scriptPubKey\":\"hex\",   (string, required) the output script\n"
            "         \"value\":n.nnnnnnnn      (number, required) the output value\n"
            "       }\n"
            "       ,...\n"
            "     ]\n"

            "\nResult:\n"
            "{\n"
            "  \"txid\" : \"hash\",                  (string) the hex-encoded hash of the transaction\n"
            "  \"fee\" : \"n.nnnnnnnn\",             (string) the transaction fee in bitcoins\n"
            "  \"sendingaddress\" : \"address\",     (string) the Bitcoin address of the sender\n"
            "  \"referenceaddress\" : \"address\",   (string) a Bitcoin address used as reference (if any)\n"
            "  \"ismine\" : true|false,            (boolean) whether the transaction involes an address in the wallet\n"
            "  \"version\" : n,                    (number) the transaction version\n"
            "  \"type_int\" : n,                   (number) the transaction type as number\n"
            "  \"type\" : \"type\",                  (string) the transaction type as string\n"
            "  [...]                             (mixed) other transaction type specific properties\n"
            "}\n"

            "\nExamples:\n"
            + HelpExampleCli("omni_decodetransaction", "\"010000000163af14ce6d477e1c793507e32a5b7696288fa89705c0d02a3f66beb3c5b8afee0100000000ffffffff02ac020000000000004751210261ea979f6a06f9dafe00fb1263ea0aca959875a7073556a088cdfadcd494b3752102a3fd0a8a067e06941e066f78d930bfc47746f097fcd3f7ab27db8ddf37168b6b52ae22020000000000001976a914946cb2e08075bcbaf157e47bcb67eb2b2339d24288ac00000000\" \"[{\\\"txid\\\":\\\"eeafb8c5b3be663f2ad0c00597a88f2896765b2ae30735791c7e476dce14af63\\\",\\\"vout\\\":1,\\\"scriptPubKey\\\":\\\"76a9149084c0bd89289bc025d0264f7f23148fb683d56c88ac\\\",\\\"value\\\":0.0001123}]\"")
            + HelpExampleRpc("omni_decodetransaction", "\"010000000163af14ce6d477e1c793507e32a5b7696288fa89705c0d02a3f66beb3c5b8afee0100000000ffffffff02ac020000000000004751210261ea979f6a06f9dafe00fb1263ea0aca959875a7073556a088cdfadcd494b3752102a3fd0a8a067e06941e066f78d930bfc47746f097fcd3f7ab27db8ddf37168b6b52ae22020000000000001976a914946cb2e08075bcbaf157e47bcb67eb2b2339d24288ac00000000\", \"[{\\\"txid\\\":\\\"eeafb8c5b3be663f2ad0c00597a88f2896765b2ae30735791c7e476dce14af63\\\",\\\"vout\\\":1,\\\"scriptPubKey\\\":\\\"76a9149084c0bd89289bc025d0264f7f23148fb683d56c88ac\\\",\\\"value\\\":0.0001123}]\"")
        );

    CTransaction tx;
    if (!DecodeHexTx(tx, params[0].get_str())) {
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Transaction deserialization failed");
    }

    // use a dummy coins view to store the user provided transaction inputs
    CCoinsView viewDummyTemp;
    CCoinsViewCache viewTemp(&viewDummyTemp);

    if (params.size() > 1 && params[1].type() != json_spirit::null_type) {
        Array prevTxs = params[1].get_array();
        BOOST_FOREACH(Value& p, prevTxs) {
            if (p.type() != json_spirit::obj_type) {
                throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\",\"value\":n.nnnnnnnn}");
            }
            Object prevOut = p.get_obj();
            RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", json_spirit::str_type)("vout", json_spirit::int_type)("scriptPubKey", json_spirit::str_type)("value", json_spirit::real_type));

            uint256 txid = ParseHashO(prevOut, "txid");
            int nOut = json_spirit::find_value(prevOut, "vout").get_int();
            if (nOut < 0) {
                throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive");
            }
            std::vector<unsigned char> pkData(ParseHexO(prevOut, "scriptPubKey"));
            Value outputValue = json_spirit::find_value(prevOut, "value");
            {
                CCoinsModifier coins = viewTemp.ModifyCoins(txid);
                if ((size_t) nOut >= coins->vout.size()) {
                    coins->vout.resize(nOut+1);
                }
                coins->vout[nOut].scriptPubKey = CScript(pkData.begin(), pkData.end());
                coins->vout[nOut].nValue = AmountFromValue(outputValue);
            }
        }
    }

    Object txObj;
    int populateResult = -3331;
    {
        LOCK2(cs_main, cs_tx_cache);
        // temporarily switch global coins view cache for transaction inputs
        std::swap(view, viewTemp);
        // then get the results
        populateResult = populateRPCTransactionObject(tx, 0, txObj);
        // and restore the original, unpolluted coins view cache
        std::swap(viewTemp, view);
    }

    if (populateResult != 0) PopulateFailure(populateResult);

    return txObj;
}

<commit_msg>Update "omni_decodetransaction", use new helpers and fix example<commit_after>#include "omnicore/rpcrawtx.h"

#include "omnicore/omnicore.h"
#include "omnicore/rpc.h"
#include "omnicore/rpctxobject.h"
#include "omnicore/rpcvalues.h"

#include "coins.h"
#include "core_io.h"
#include "primitives/transaction.h"
#include "rpcserver.h"
#include "sync.h"
#include "uint256.h"

#include "json/json_spirit_value.h"

#include <stdint.h>
#include <stdexcept>
#include <string>

extern CCriticalSection cs_main;

using mastercore::cs_tx_cache;
using mastercore::view;

using namespace json_spirit;

Value omni_decodetransaction(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 1 || params.size() > 2)
        throw std::runtime_error(
            "omni_decodetransaction \"rawtx\" ( \"prevtxs\" )\n"

            "\nDecodes an Omni transaction.\n"

            "\nIf the inputs of the transaction are not in the chain, then they must be provided, because "
            "the transaction inputs are used to identify the sender of a transaction.\n"

            "\nArguments:\n"
            "1. rawtx                (string, required) the raw transaction to decode\n"
            "2. prevtxs              (string, optional) a JSON array of transaction inputs (default: none)\n"
            "     [\n"
            "       {\n"
            "         \"txid\":\"hash\",          (string, required) the transaction hash\n"
            "         \"vout\":n,               (number, required) the output number\n"
            "         \"scriptPubKey\":\"hex\",   (string, required) the output script\n"
            "         \"value\":n.nnnnnnnn      (number, required) the output value\n"
            "       }\n"
            "       ,...\n"
            "     ]\n"

            "\nResult:\n"
            "{\n"
            "  \"txid\" : \"hash\",                  (string) the hex-encoded hash of the transaction\n"
            "  \"fee\" : \"n.nnnnnnnn\",             (string) the transaction fee in bitcoins\n"
            "  \"sendingaddress\" : \"address\",     (string) the Bitcoin address of the sender\n"
            "  \"referenceaddress\" : \"address\",   (string) a Bitcoin address used as reference (if any)\n"
            "  \"ismine\" : true|false,            (boolean) whether the transaction involes an address in the wallet\n"
            "  \"version\" : n,                    (number) the transaction version\n"
            "  \"type_int\" : n,                   (number) the transaction type as number\n"
            "  \"type\" : \"type\",                  (string) the transaction type as string\n"
            "  [...]                             (mixed) other transaction type specific properties\n"
            "}\n"

            "\nExamples:\n"
            + HelpExampleCli("omni_decodetransaction", "\"010000000163af14ce6d477e1c793507e32a5b7696288fa89705c0d02a3f66beb3c5b8afee0100000000ffffffff02ac020000000000004751210261ea979f6a06f9dafe00fb1263ea0aca959875a7073556a088cdfadcd494b3752102a3fd0a8a067e06941e066f78d930bfc47746f097fcd3f7ab27db8ddf37168b6b52ae22020000000000001976a914946cb2e08075bcbaf157e47bcb67eb2b2339d24288ac00000000\" \"[{\\\"txid\\\":\\\"eeafb8c5b3be663f2ad0c00597a88f2896765b2ae30735791c7e476dce14af63\\\",\\\"vout\\\":1,\\\"scriptPubKey\\\":\\\"76a9149084c0bd89289bc025d0264f7f23148fb683d56c88ac\\\",\\\"value\\\":0.0001123}]\"")
            + HelpExampleRpc("omni_decodetransaction", "\"010000000163af14ce6d477e1c793507e32a5b7696288fa89705c0d02a3f66beb3c5b8afee0100000000ffffffff02ac020000000000004751210261ea979f6a06f9dafe00fb1263ea0aca959875a7073556a088cdfadcd494b3752102a3fd0a8a067e06941e066f78d930bfc47746f097fcd3f7ab27db8ddf37168b6b52ae22020000000000001976a914946cb2e08075bcbaf157e47bcb67eb2b2339d24288ac00000000\", [{\"txid\":\"eeafb8c5b3be663f2ad0c00597a88f2896765b2ae30735791c7e476dce14af63\",\"vout\":1,\"scriptPubKey\":\"76a9149084c0bd89289bc025d0264f7f23148fb683d56c88ac\",\"value\":0.0001123}]")
        );

    CTransaction tx = ParseTransaction(params[0]);

    // use a dummy coins view to store the user provided transaction inputs
    CCoinsView viewDummyTemp;
    CCoinsViewCache viewTemp(&viewDummyTemp);

    if (params.size() > 1) {
        std::vector<PrevTxsEntry> prevTxsParsed = ParsePrevTxs(params[1]);
        InputsToView(prevTxsParsed, viewTemp);
    }

    Object txObj;
    int populateResult = -3331;
    {
        LOCK2(cs_main, cs_tx_cache);
        // temporarily switch global coins view cache for transaction inputs
        std::swap(view, viewTemp);
        // then get the results
        populateResult = populateRPCTransactionObject(tx, 0, txObj);
        // and restore the original, unpolluted coins view cache
        std::swap(viewTemp, view);
    }

    if (populateResult != 0) PopulateFailure(populateResult);

    return txObj;
}

<|endoftext|>