<commit_before>#include "cvm.h"

void DabValue::dump(FILE *file) const
{
    static const char *types[] = {"INVA", "FIXN", "STRI", "BOOL", "NIL ", "SYMB", "CLAS", "OBJE",
                                  "ARRY", "UIN8", "UI32", "UI64", "IN32", "METH", "PTR*", "BYT*"};
    assert((int)data.type >= 0 && (int)data.type < (int)countof(types));
    fprintf(file, "%s ", types[data.type]);
    print(file, true);
}

int DabValue::class_index() const
{
    switch (data.type)
    {
    case TYPE_FIXNUM:
        return CLASS_FIXNUM;
        break;
    case TYPE_STRING:
        return CLASS_STRING;
        break;
    case TYPE_SYMBOL:
        return CLASS_INT_SYMBOL;
        break;
    case TYPE_BOOLEAN:
        return CLASS_BOOLEAN;
        break;
    case TYPE_NIL:
        return CLASS_NILCLASS;
        break;
    case TYPE_ARRAY:
        return CLASS_ARRAY;
        break;
    case TYPE_CLASS:
        return data.fixnum;
        break;
    case TYPE_OBJECT:
        return this->data.object->object->klass;
        break;
    case TYPE_UINT8:
        return CLASS_UINT8;
        break;
    case TYPE_UINT32:
        return CLASS_UINT32;
        break;
    case TYPE_UINT64:
        return CLASS_UINT64;
        break;
    case TYPE_INT32:
        return CLASS_INT32;
        break;
    case TYPE_METHOD:
        return CLASS_METHOD;
        break;
    case TYPE_INTPTR:
        return CLASS_INTPTR;
        break;
    case TYPE_BYTEBUFFER:
        return CLASS_BYTEBUFFER;
        break;
    default:
        fprintf(stderr, "Unknown data.type %d.\n", (int)data.type);
        assert(false);
        break;
    }
}

std::string DabValue::class_name() const
{
    return get_class().name;
}

DabClass &DabValue::get_class() const
{
    return $VM->get_class(class_index());
}

bool DabValue::is_a(const DabClass &klass) const
{
    return get_class().is_subclass_of(klass);
}

void DabValue::print(FILE *out, bool debug) const
{
    fprintf(out, "%s", print_value(debug).c_str());
}

std::string DabValue::print_value(bool debug) const
{
    char        buffer[32] = {0};
    std::string ret;
    bool        use_ret = false;
    switch (data.type)
    {
    case TYPE_FIXNUM:
        snprintf(buffer, sizeof(buffer), "%" PRId64, data.fixnum);
        break;
    case TYPE_UINT8:
        snprintf(buffer, sizeof(buffer), "%" PRIu8, data.num_uint8);
        break;
    case TYPE_UINT32:
        snprintf(buffer, sizeof(buffer), "%" PRIu32, data.num_uint32);
        break;
    case TYPE_UINT64:
        snprintf(buffer, sizeof(buffer), "%" PRIu64, data.num_uint64);
        break;
    case TYPE_INT32:
        snprintf(buffer, sizeof(buffer), "%" PRId32, data.num_int32);
        break;
    case TYPE_STRING:
    {
        use_ret = true;
        ret     = data.string;
        if (debug)
        {
            ret = "\"" + ret + "\"";
        }
    }
    break;
    case TYPE_SYMBOL:
        snprintf(buffer, sizeof(buffer), ":%s", data.string.c_str());
        break;
    case TYPE_BOOLEAN:
        snprintf(buffer, sizeof(buffer), "%s", data.boolean ? "true" : "false");
        break;
    case TYPE_NIL:
        snprintf(buffer, sizeof(buffer), "nil");
        break;
    case TYPE_CLASS:
        snprintf(buffer, sizeof(buffer), "%s", class_name().c_str());
        break;
    case TYPE_OBJECT:
        snprintf(buffer, sizeof(buffer), "#%s", class_name().c_str());
        break;
    case TYPE_INTPTR:
        snprintf(buffer, sizeof(buffer), "%p", data.intptr);
        break;
    case TYPE_ARRAY:
    {
        use_ret  = true;
        ret      = "[";
        size_t i = 0;
        for (auto &item : array())
        {
            if (i)
                ret += ", ";
            ret += item.print_value(debug);
            i++;
        }
        ret += "]";
    }
    break;
    default:
        snprintf(buffer, sizeof(buffer), "?");
        break;
    }
    if (!use_ret)
    {
        ret = buffer;
    }
    if (debug && data.object)
    {
        char extra[64] = {0};
        snprintf(extra, sizeof(extra), " [%d strong]", (int)data.object->count_strong);
        ret += extra;
    }
    return ret;
}

std::vector<DabValue> &DabValue::array() const
{
    assert(data.type == TYPE_ARRAY);
    auto *obj = (DabArray *)data.object->object;
    return obj->array;
}

std::vector<uint8_t> &DabValue::bytebuffer() const
{
    assert(data.type == TYPE_BYTEBUFFER);
    auto *obj = (DabByteBuffer *)data.object->object;
    return obj->bytebuffer;
}

bool DabValue::truthy() const
{
    switch (data.type)
    {
    case TYPE_FIXNUM:
        return data.fixnum;
    case TYPE_UINT8:
        return data.num_uint8;
    case TYPE_UINT32:
        return data.num_uint32;
    case TYPE_UINT64:
        return data.num_uint64;
    case TYPE_INT32:
        return data.num_int32;
    case TYPE_STRING:
        return data.string.length();
        break;
    case TYPE_BOOLEAN:
        return data.boolean;
    case TYPE_INTPTR:
        return data.intptr;
    case TYPE_NIL:
        return false;
    case TYPE_ARRAY:
        return array().size() > 0;
    default:
        return true;
    }
}

DabValue DabValue::create_instance() const
{
    assert(data.type == TYPE_CLASS);

    DabBaseObject *object = nullptr;
    auto           type   = TYPE_OBJECT;
    if (data.fixnum == CLASS_ARRAY)
    {
        object = new DabArray;
        type   = TYPE_ARRAY;
    }
    else if (data.fixnum == CLASS_BYTEBUFFER)
    {
        object = new DabByteBuffer;
        type   = TYPE_BYTEBUFFER;
    }
    else
    {
        object = new DabObject;
    }

    DabObjectProxy *proxy = new DabObjectProxy;
    proxy->object         = object;
    proxy->count_strong   = 1;
    proxy->object->klass  = this->data.fixnum;

    DabValue ret;
    ret.data.type   = type;
    ret.data.object = proxy;

    if ($VM->verbose)
    {
        fprintf(stderr, "vm: proxy %p (strong %d): ! created\n", proxy, (int)proxy->count_strong);
    }

    return ret;
}

DabValue DabValue::_get_instvar(const std::string &name)
{
    assert(this->data.type == TYPE_OBJECT);
    assert(this->data.object);

    if (!this->data.object->object)
    {
        return DabValue(nullptr);
    }

    auto  object   = (DabObject *)this->data.object->object;
    auto &instvars = object->instvars;

    if (!instvars.count(name))
    {
        return DabValue(nullptr);
    }
    return instvars[name];
}

DabValue DabValue::get_instvar(const std::string &name)
{
    auto ret = _get_instvar(name);
    if ($VM->verbose)
    {
        fprintf(stderr, "vm: proxy %p (strong %d): Get instvar <%s> -> ", this->data.object,
                (int)this->data.object->count_strong, name.c_str());
        ret.print(stderr);
        fprintf(stderr, "\n");
    }
    return ret;
}

void DabValue::set_instvar(const std::string &name, const DabValue &value)
{
    assert(this->data.type == TYPE_OBJECT);
    assert(this->data.object);

    if ($VM->verbose)
    {
        fprintf(stderr, "vm: proxy %p (strong %d): Set instvar <%s> to ", this->data.object,
                (int)this->data.object->count_strong, name.c_str());
        value.print(stderr);
        fprintf(stderr, "\n");
    }

    if (!this->data.object->object)
    {
        return;
    }

    auto  object   = (DabObject *)this->data.object->object;
    auto &instvars = object->instvars;
    instvars[name] = value;
}

void DabValue::set_data(const DabValueData &other_data)
{
    data = other_data;
    if ($VM->autorelease)
    {
        retain();
    }
}

DabValue::DabValue(const DabValue &other)
{
    set_data(other.data);
}

DabValue &DabValue::operator=(const DabValue &other)
{
    set_data(other.data);
    return *this;
}

DabValue::~DabValue()
{
    if ($VM->autorelease)
    {
        release();
    }
}

void DabValue::release()
{
    if (this->data.type == TYPE_OBJECT || data.type == TYPE_ARRAY)
    {
        this->data.object->release(this);
        this->data.object = nullptr;
    }
    this->data.type = TYPE_NIL;
}

void DabValue::retain()
{
    if (data.type == TYPE_OBJECT || data.type == TYPE_ARRAY)
    {
        data.object->retain(this);
    }
}

//

void DabObjectProxy::retain(DabValue *value)
{
    (void)value;
    if (this->destroying)
        return;
    count_strong += 1;
    if ($VM->verbose)
    {
        fprintf(stderr, "vm: proxy %p (strong %d): + retained\n", this, (int)this->count_strong);
    }
}

void DabObjectProxy::release(DabValue *value)
{
    if (this->destroying)
        return;
    count_strong -= 1;
    if ($VM->verbose)
    {
        fprintf(stderr, "vm: proxy %p (strong %d): - released\n", this, (int)this->count_strong);
    }
    if (count_strong == 0)
    {
        destroy(value);
    }
}

void DabObjectProxy::destroy(DabValue *value)
{
    (void)value;
    this->destroying = true;
    fprintf(stderr, "vm: proxy %p (strong %d): X destroy\n", this, (int)this->count_strong);
    delete object;
    delete this;
}

size_t DabValue::use_count() const
{
    if (data.object)
    {
        return data.object->count_strong;
    }
    else
    {
        return 65535;
    }
}
<commit_msg>vm: extra debug info for reference counting<commit_after>#include "cvm.h"

void DabValue::dump(FILE *file) const
{
    static const char *types[] = {"INVA", "FIXN", "STRI", "BOOL", "NIL ", "SYMB", "CLAS", "OBJE",
                                  "ARRY", "UIN8", "UI32", "UI64", "IN32", "METH", "PTR*", "BYT*"};
    assert((int)data.type >= 0 && (int)data.type < (int)countof(types));
    fprintf(file, "%s ", types[data.type]);
    print(file, true);
}

int DabValue::class_index() const
{
    switch (data.type)
    {
    case TYPE_FIXNUM:
        return CLASS_FIXNUM;
        break;
    case TYPE_STRING:
        return CLASS_STRING;
        break;
    case TYPE_SYMBOL:
        return CLASS_INT_SYMBOL;
        break;
    case TYPE_BOOLEAN:
        return CLASS_BOOLEAN;
        break;
    case TYPE_NIL:
        return CLASS_NILCLASS;
        break;
    case TYPE_ARRAY:
        return CLASS_ARRAY;
        break;
    case TYPE_CLASS:
        return data.fixnum;
        break;
    case TYPE_OBJECT:
        return this->data.object->object->klass;
        break;
    case TYPE_UINT8:
        return CLASS_UINT8;
        break;
    case TYPE_UINT32:
        return CLASS_UINT32;
        break;
    case TYPE_UINT64:
        return CLASS_UINT64;
        break;
    case TYPE_INT32:
        return CLASS_INT32;
        break;
    case TYPE_METHOD:
        return CLASS_METHOD;
        break;
    case TYPE_INTPTR:
        return CLASS_INTPTR;
        break;
    case TYPE_BYTEBUFFER:
        return CLASS_BYTEBUFFER;
        break;
    default:
        fprintf(stderr, "Unknown data.type %d.\n", (int)data.type);
        assert(false);
        break;
    }
}

std::string DabValue::class_name() const
{
    return get_class().name;
}

DabClass &DabValue::get_class() const
{
    return $VM->get_class(class_index());
}

bool DabValue::is_a(const DabClass &klass) const
{
    return get_class().is_subclass_of(klass);
}

void DabValue::print(FILE *out, bool debug) const
{
    fprintf(out, "%s", print_value(debug).c_str());
}

std::string DabValue::print_value(bool debug) const
{
    char        buffer[32] = {0};
    std::string ret;
    bool        use_ret = false;
    switch (data.type)
    {
    case TYPE_FIXNUM:
        snprintf(buffer, sizeof(buffer), "%" PRId64, data.fixnum);
        break;
    case TYPE_UINT8:
        snprintf(buffer, sizeof(buffer), "%" PRIu8, data.num_uint8);
        break;
    case TYPE_UINT32:
        snprintf(buffer, sizeof(buffer), "%" PRIu32, data.num_uint32);
        break;
    case TYPE_UINT64:
        snprintf(buffer, sizeof(buffer), "%" PRIu64, data.num_uint64);
        break;
    case TYPE_INT32:
        snprintf(buffer, sizeof(buffer), "%" PRId32, data.num_int32);
        break;
    case TYPE_STRING:
    {
        use_ret = true;
        ret     = data.string;
        if (debug)
        {
            ret = "\"" + ret + "\"";
        }
    }
    break;
    case TYPE_SYMBOL:
        snprintf(buffer, sizeof(buffer), ":%s", data.string.c_str());
        break;
    case TYPE_BOOLEAN:
        snprintf(buffer, sizeof(buffer), "%s", data.boolean ? "true" : "false");
        break;
    case TYPE_NIL:
        snprintf(buffer, sizeof(buffer), "nil");
        break;
    case TYPE_CLASS:
        snprintf(buffer, sizeof(buffer), "%s", class_name().c_str());
        break;
    case TYPE_OBJECT:
        snprintf(buffer, sizeof(buffer), "#%s", class_name().c_str());
        break;
    case TYPE_INTPTR:
        snprintf(buffer, sizeof(buffer), "%p", data.intptr);
        break;
    case TYPE_ARRAY:
    {
        use_ret  = true;
        ret      = "[";
        size_t i = 0;
        for (auto &item : array())
        {
            if (i)
                ret += ", ";
            ret += item.print_value(debug);
            i++;
        }
        ret += "]";
    }
    break;
    default:
        snprintf(buffer, sizeof(buffer), "?");
        break;
    }
    if (!use_ret)
    {
        ret = buffer;
    }
    if (debug && data.object)
    {
        char extra[64] = {0};
        snprintf(extra, sizeof(extra), " [%d strong]", (int)data.object->count_strong);
        ret += extra;
    }
    return ret;
}

std::vector<DabValue> &DabValue::array() const
{
    assert(data.type == TYPE_ARRAY);
    auto *obj = (DabArray *)data.object->object;
    return obj->array;
}

std::vector<uint8_t> &DabValue::bytebuffer() const
{
    assert(data.type == TYPE_BYTEBUFFER);
    auto *obj = (DabByteBuffer *)data.object->object;
    return obj->bytebuffer;
}

bool DabValue::truthy() const
{
    switch (data.type)
    {
    case TYPE_FIXNUM:
        return data.fixnum;
    case TYPE_UINT8:
        return data.num_uint8;
    case TYPE_UINT32:
        return data.num_uint32;
    case TYPE_UINT64:
        return data.num_uint64;
    case TYPE_INT32:
        return data.num_int32;
    case TYPE_STRING:
        return data.string.length();
        break;
    case TYPE_BOOLEAN:
        return data.boolean;
    case TYPE_INTPTR:
        return data.intptr;
    case TYPE_NIL:
        return false;
    case TYPE_ARRAY:
        return array().size() > 0;
    default:
        return true;
    }
}

DabValue DabValue::create_instance() const
{
    assert(data.type == TYPE_CLASS);

    DabBaseObject *object = nullptr;
    auto           type   = TYPE_OBJECT;
    if (data.fixnum == CLASS_ARRAY)
    {
        object = new DabArray;
        type   = TYPE_ARRAY;
    }
    else if (data.fixnum == CLASS_BYTEBUFFER)
    {
        object = new DabByteBuffer;
        type   = TYPE_BYTEBUFFER;
    }
    else
    {
        object = new DabObject;
    }

    DabObjectProxy *proxy = new DabObjectProxy;
    proxy->object         = object;
    proxy->count_strong   = 1;
    proxy->object->klass  = this->data.fixnum;

    DabValue ret;
    ret.data.type   = type;
    ret.data.object = proxy;

    if ($VM->verbose)
    {
        fprintf(stderr, "vm: proxy %p (strong %3d): ! created : ", proxy, (int)proxy->count_strong);
        ret.dump(stderr);
        fprintf(stderr, "\n");
    }

    return ret;
}

DabValue DabValue::_get_instvar(const std::string &name)
{
    assert(this->data.type == TYPE_OBJECT);
    assert(this->data.object);

    if (!this->data.object->object)
    {
        return DabValue(nullptr);
    }

    auto  object   = (DabObject *)this->data.object->object;
    auto &instvars = object->instvars;

    if (!instvars.count(name))
    {
        return DabValue(nullptr);
    }
    return instvars[name];
}

DabValue DabValue::get_instvar(const std::string &name)
{
    auto ret = _get_instvar(name);
    if ($VM->verbose)
    {
        fprintf(stderr, "vm: proxy %p (strong %d): Get instvar <%s> -> ", this->data.object,
                (int)this->data.object->count_strong, name.c_str());
        ret.print(stderr);
        fprintf(stderr, "\n");
    }
    return ret;
}

void DabValue::set_instvar(const std::string &name, const DabValue &value)
{
    assert(this->data.type == TYPE_OBJECT);
    assert(this->data.object);

    if ($VM->verbose)
    {
        fprintf(stderr, "vm: proxy %p (strong %d): Set instvar <%s> to ", this->data.object,
                (int)this->data.object->count_strong, name.c_str());
        value.print(stderr);
        fprintf(stderr, "\n");
    }

    if (!this->data.object->object)
    {
        return;
    }

    auto  object   = (DabObject *)this->data.object->object;
    auto &instvars = object->instvars;
    instvars[name] = value;
}

void DabValue::set_data(const DabValueData &other_data)
{
    data = other_data;
    if ($VM->autorelease)
    {
        retain();
    }
}

DabValue::DabValue(const DabValue &other)
{
    set_data(other.data);
}

DabValue &DabValue::operator=(const DabValue &other)
{
    set_data(other.data);
    return *this;
}

DabValue::~DabValue()
{
    if ($VM->autorelease)
    {
        release();
    }
}

void DabValue::release()
{
    if (this->data.type == TYPE_OBJECT || data.type == TYPE_ARRAY)
    {
        this->data.object->release(this);
        this->data.object = nullptr;
    }
    this->data.type = TYPE_NIL;
}

void DabValue::retain()
{
    if (data.type == TYPE_OBJECT || data.type == TYPE_ARRAY)
    {
        data.object->retain(this);
    }
}

//

void DabObjectProxy::retain(DabValue *value)
{
    (void)value;
    if (this->destroying)
        return;
    count_strong += 1;
    if ($VM->verbose)
    {
        fprintf(stderr, "vm: proxy %p (strong %3d): + retained: ", this, (int)this->count_strong);
        value->dump(stderr);
        fprintf(stderr, "\n");
    }
}

void DabObjectProxy::release(DabValue *value)
{
    if (this->destroying)
        return;
    count_strong -= 1;
    if ($VM->verbose)
    {
        fprintf(stderr, "vm: proxy %p (strong %3d): - released: ", this, (int)this->count_strong);
        value->dump(stderr);
        fprintf(stderr, "\n");
    }
    if (count_strong == 0)
    {
        destroy(value);
    }
}

void DabObjectProxy::destroy(DabValue *value)
{
    (void)value;
    this->destroying = true;
    fprintf(stderr, "vm: proxy %p (strong %3d): X destroy\n", this, (int)this->count_strong);
    delete object;
    delete this;
}

size_t DabValue::use_count() const
{
    if (data.object)
    {
        return data.object->count_strong;
    }
    else
    {
        return 65535;
    }
}
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "modules/perception/obstacle/onboard/camera_process_subnode.h"

#include <unordered_map>

#include "modules/perception/traffic_light/util/color_space.h"

namespace apollo {
namespace perception {

using apollo::common::adapter::AdapterManager;

bool CameraProcessSubnode::InitInternal() {
  // Subnode config in DAG streaming
  std::unordered_map<std::string, std::string> fields;
  SubnodeHelper::ParseReserveField(reserve_, &fields);
  device_id_ = fields["device_id"];

  // Shared Data
  cam_obj_data_ = static_cast<CameraObjectData *>(
      shared_data_manager_->GetSharedData("CameraObjectData"));
  cam_shared_data_ = static_cast<CameraSharedData *>(
      shared_data_manager_->GetSharedData("CameraSharedData"));

  InitCalibration();

  InitModules();

  AdapterManager::AddImageShortCallback(&CameraProcessSubnode::ImgCallback,
                                        this);

  return true;
}

bool CameraProcessSubnode::InitCalibration() {
  auto ccm = Singleton<CalibrationConfigManager>::get();
  CameraCalibrationPtr calibrator = ccm->get_camera_calibration();

  // calibrator->get_image_height_width(&image_height_, &image_width_);
  camera_to_car_ = calibrator->get_camera_extrinsics();
  intrinsics_ = calibrator->get_camera_intrinsic();
  undistortion_handler_ = calibrator->get_camera_undistort_handler();
  return true;
}

bool CameraProcessSubnode::InitModules() {
  RegisterFactoryYoloCameraDetector();
  RegisterFactoryGeometryCameraConverter();
  RegisterFactoryCascadedCameraTracker();
  RegisterFactoryFlatCameraTransformer();
  RegisterFactoryObjectCameraFilter();

  detector_.reset(
      BaseCameraDetectorRegisterer::GetInstanceByName("YoloCameraDetector"));
  detector_->Init();

  converter_.reset(BaseCameraConverterRegisterer::GetInstanceByName(
      "GeometryCameraConverter"));
  converter_->Init();

  tracker_.reset(
      BaseCameraTrackerRegisterer::GetInstanceByName("CascadedCameraTracker"));
  tracker_->Init();

  transformer_.reset(BaseCameraTransformerRegisterer::GetInstanceByName(
      "FlatCameraTransformer"));
  transformer_->Init();
  // transformer_->SetExtrinsics(camera_to_car_);

  filter_.reset(
      BaseCameraFilterRegisterer::GetInstanceByName("ObjectCameraFilter"));
  filter_->Init();

  return true;
}

void CameraProcessSubnode::ImgCallback(const sensor_msgs::Image &message) {
  AdapterManager::Observe();
  sensor_msgs::Image msg = AdapterManager::GetImageShort()->GetLatestObserved();

  double timestamp = msg.header.stamp.toSec();
  AINFO << "CameraProcessSubnode ImgCallback: "
        << " frame: " << ++seq_num_ << " timestamp: ";
  AINFO << std::fixed << std::setprecision(64) << timestamp;

  cv::Mat img;
  if (!FLAGS_image_file_debug) {
    MessageToMat(msg, &img);
  } else {
    img = cv::imread(FLAGS_image_file_path, CV_LOAD_IMAGE_COLOR);
  }

  std::vector<VisualObjectPtr> objects;
  cv::Mat mask = cv::Mat::zeros(img.rows, img.cols, CV_32FC1);

  detector_->Multitask(img, CameraDetectorOptions(), &objects, &mask);
  converter_->Convert(&objects);
  tracker_->Associate(img, timestamp, &objects);
  transformer_->Transform(&objects);
  filter_->Filter(timestamp, &objects);

  std::shared_ptr<SensorObjects> out_objs(new SensorObjects);
  out_objs->timestamp = timestamp;
  VisualObjToSensorObj(objects, &out_objs);

  SharedDataPtr<CameraItem> camera_item_ptr(new CameraItem);
  camera_item_ptr->image_src_mat = img.clone();
  mask.copyTo(out_objs->camera_frame_supplement->lane_map);
  PublishDataAndEvent(timestamp, out_objs, camera_item_ptr);
}

bool CameraProcessSubnode::MessageToMat(const sensor_msgs::Image &msg,
                                        cv::Mat *img) {
  cv::Mat cv_img;
  if (msg.encoding.compare("yuyv") == 0) {
    unsigned char *yuv = (unsigned char *)&(msg.data[0]);
    cv_img = cv::Mat(msg.height, msg.width, CV_8UC3);
    traffic_light::Yuyv2rgb(yuv, cv_img.data, msg.height * msg.width);
    cv::cvtColor(cv_img, cv_img, CV_RGB2BGR);
  } else {
    cv_bridge::CvImagePtr cv_ptr = cv_bridge::toCvCopy(msg,
       sensor_msgs::image_encodings::BGR8);
    cv_img = cv_ptr->image;
  }

  if (cv_img.rows != image_height_ || cv_img.cols != image_width_) {
    cv::resize(cv_img, cv_img, cv::Size(image_width_, image_height_));
  }
  *img = cv_img.clone();
  return true;
}

void CameraProcessSubnode::VisualObjToSensorObj(
    const std::vector<VisualObjectPtr> &objects,
    SharedDataPtr<SensorObjects> *sensor_objects) {
  (*sensor_objects)->sensor_type = SensorType::CAMERA;
  (*sensor_objects)->sensor_id = device_id_;
  (*sensor_objects)->seq_num = seq_num_;
  (*sensor_objects)->sensor2world_pose = camera_to_car_;
  ((*sensor_objects)->camera_frame_supplement).reset(new CameraFrameSupplement);

  for (size_t i = 0; i < objects.size(); ++i) {
    VisualObjectPtr vobj = objects[i];
    ObjectPtr obj(new Object());

    obj->id = vobj->id;
    obj->direction = vobj->direction.cast<double>();
    obj->theta = vobj->theta;
    obj->center = vobj->center.cast<double>();
    obj->length = vobj->length;
    obj->width = vobj->width;
    obj->height = vobj->height;
    obj->type = vobj->type;
    obj->track_id = vobj->track_id;
    obj->tracking_time = vobj->track_age;
    obj->latest_tracked_time = vobj->last_track_timestamp;
    obj->velocity = vobj->velocity.cast<double>();
    obj->anchor_point = obj->center.cast<double>();
    (obj->camera_supplement).reset(new CameraSupplement());
    obj->camera_supplement->upper_left = vobj->upper_left.cast<double>();
    obj->camera_supplement->lower_right = vobj->lower_right.cast<double>();
    obj->camera_supplement->alpha = vobj->alpha;
    // obj->type_probs.assign(vobj->type_probs,
    //                        vobj->type_probs + MAX_OBJECT_TYPE);
    // obj->camera_supplement->pts8.assign(vobj->pts8,
    //                                     vobj->pts8 + 16);

    ((*sensor_objects)->objects).emplace_back(obj);
  }
}

void CameraProcessSubnode::PublishDataAndEvent(
    const double &timestamp, const SharedDataPtr<SensorObjects> &sensor_objects,
    const SharedDataPtr<CameraItem> &camera_item) {
  std::string key = "";
  SubnodeHelper::ProduceSharedDataKey(timestamp, device_id_, &key);

  cam_obj_data_->Add(key, sensor_objects);
  cam_shared_data_->Add(key, camera_item);

  for (size_t idx = 0; idx < pub_meta_events_.size(); ++idx) {
    const EventMeta &event_meta = pub_meta_events_[idx];
    Event event;
    event.event_id = event_meta.event_id;
    event.timestamp = timestamp;
    event.reserve = device_id_;
    event_manager_->Publish(event);
  }
}

}  // namespace perception
}  // namespace apollo
<commit_msg>code janitor: clean code for previous commits<commit_after>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "modules/perception/obstacle/onboard/camera_process_subnode.h"

#include <unordered_map>

#include "modules/perception/traffic_light/util/color_space.h"

namespace apollo {
namespace perception {

using apollo::common::adapter::AdapterManager;

bool CameraProcessSubnode::InitInternal() {
  // Subnode config in DAG streaming
  std::unordered_map<std::string, std::string> fields;
  SubnodeHelper::ParseReserveField(reserve_, &fields);
  device_id_ = fields["device_id"];

  // Shared Data
  cam_obj_data_ = static_cast<CameraObjectData *>(
      shared_data_manager_->GetSharedData("CameraObjectData"));
  cam_shared_data_ = static_cast<CameraSharedData *>(
      shared_data_manager_->GetSharedData("CameraSharedData"));

  InitCalibration();

  InitModules();

  AdapterManager::AddImageShortCallback(&CameraProcessSubnode::ImgCallback,
                                        this);

  return true;
}

bool CameraProcessSubnode::InitCalibration() {
  auto ccm = Singleton<CalibrationConfigManager>::get();
  CameraCalibrationPtr calibrator = ccm->get_camera_calibration();

  // calibrator->get_image_height_width(&image_height_, &image_width_);
  camera_to_car_ = calibrator->get_camera_extrinsics();
  intrinsics_ = calibrator->get_camera_intrinsic();
  undistortion_handler_ = calibrator->get_camera_undistort_handler();
  return true;
}

bool CameraProcessSubnode::InitModules() {
  RegisterFactoryYoloCameraDetector();
  RegisterFactoryGeometryCameraConverter();
  RegisterFactoryCascadedCameraTracker();
  RegisterFactoryFlatCameraTransformer();
  RegisterFactoryObjectCameraFilter();

  detector_.reset(
      BaseCameraDetectorRegisterer::GetInstanceByName("YoloCameraDetector"));
  detector_->Init();

  converter_.reset(BaseCameraConverterRegisterer::GetInstanceByName(
      "GeometryCameraConverter"));
  converter_->Init();

  tracker_.reset(
      BaseCameraTrackerRegisterer::GetInstanceByName("CascadedCameraTracker"));
  tracker_->Init();

  transformer_.reset(BaseCameraTransformerRegisterer::GetInstanceByName(
      "FlatCameraTransformer"));
  transformer_->Init();
  // transformer_->SetExtrinsics(camera_to_car_);

  filter_.reset(
      BaseCameraFilterRegisterer::GetInstanceByName("ObjectCameraFilter"));
  filter_->Init();

  return true;
}

void CameraProcessSubnode::ImgCallback(const sensor_msgs::Image &message) {
  AdapterManager::Observe();
  sensor_msgs::Image msg = AdapterManager::GetImageShort()->GetLatestObserved();

  double timestamp = msg.header.stamp.toSec();
  AINFO << "CameraProcessSubnode ImgCallback: "
        << " frame: " << ++seq_num_ << " timestamp: ";
  AINFO << std::fixed << std::setprecision(64) << timestamp;

  cv::Mat img;
  if (!FLAGS_image_file_debug) {
    MessageToMat(msg, &img);
  } else {
    img = cv::imread(FLAGS_image_file_path, CV_LOAD_IMAGE_COLOR);
  }

  std::vector<VisualObjectPtr> objects;
  cv::Mat mask = cv::Mat::zeros(img.rows, img.cols, CV_32FC1);

  detector_->Multitask(img, CameraDetectorOptions(), &objects, &mask);
  converter_->Convert(&objects);
  tracker_->Associate(img, timestamp, &objects);
  transformer_->Transform(&objects);
  filter_->Filter(timestamp, &objects);

  std::shared_ptr<SensorObjects> out_objs(new SensorObjects);
  out_objs->timestamp = timestamp;
  VisualObjToSensorObj(objects, &out_objs);

  SharedDataPtr<CameraItem> camera_item_ptr(new CameraItem);
  camera_item_ptr->image_src_mat = img.clone();
  mask.copyTo(out_objs->camera_frame_supplement->lane_map);
  PublishDataAndEvent(timestamp, out_objs, camera_item_ptr);
}

bool CameraProcessSubnode::MessageToMat(const sensor_msgs::Image &msg,
                                        cv::Mat *img) {
  cv::Mat cv_img;
  if (msg.encoding.compare("yuyv") == 0) {
    unsigned char *yuv = (unsigned char *)&(msg.data[0]);
    cv_img = cv::Mat(msg.height, msg.width, CV_8UC3);
    traffic_light::Yuyv2rgb(yuv, cv_img.data, msg.height * msg.width);
    cv::cvtColor(cv_img, cv_img, CV_RGB2BGR);
  } else {
    cv_bridge::CvImagePtr cv_ptr =
        cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
    cv_img = cv_ptr->image;
  }

  if (cv_img.rows != image_height_ || cv_img.cols != image_width_) {
    cv::resize(cv_img, cv_img, cv::Size(image_width_, image_height_));
  }
  *img = cv_img.clone();
  return true;
}

void CameraProcessSubnode::VisualObjToSensorObj(
    const std::vector<VisualObjectPtr> &objects,
    SharedDataPtr<SensorObjects> *sensor_objects) {
  (*sensor_objects)->sensor_type = SensorType::CAMERA;
  (*sensor_objects)->sensor_id = device_id_;
  (*sensor_objects)->seq_num = seq_num_;
  (*sensor_objects)->sensor2world_pose = camera_to_car_;
  ((*sensor_objects)->camera_frame_supplement).reset(new CameraFrameSupplement);

  for (size_t i = 0; i < objects.size(); ++i) {
    VisualObjectPtr vobj = objects[i];
    ObjectPtr obj(new Object());

    obj->id = vobj->id;
    obj->direction = vobj->direction.cast<double>();
    obj->theta = vobj->theta;
    obj->center = vobj->center.cast<double>();
    obj->length = vobj->length;
    obj->width = vobj->width;
    obj->height = vobj->height;
    obj->type = vobj->type;
    obj->track_id = vobj->track_id;
    obj->tracking_time = vobj->track_age;
    obj->latest_tracked_time = vobj->last_track_timestamp;
    obj->velocity = vobj->velocity.cast<double>();
    obj->anchor_point = obj->center.cast<double>();
    (obj->camera_supplement).reset(new CameraSupplement());
    obj->camera_supplement->upper_left = vobj->upper_left.cast<double>();
    obj->camera_supplement->lower_right = vobj->lower_right.cast<double>();
    obj->camera_supplement->alpha = vobj->alpha;
    // obj->type_probs.assign(vobj->type_probs,
    //                        vobj->type_probs + MAX_OBJECT_TYPE);
    // obj->camera_supplement->pts8.assign(vobj->pts8,
    //                                     vobj->pts8 + 16);

    ((*sensor_objects)->objects).emplace_back(obj);
  }
}

void CameraProcessSubnode::PublishDataAndEvent(
    const double &timestamp, const SharedDataPtr<SensorObjects> &sensor_objects,
    const SharedDataPtr<CameraItem> &camera_item) {
  std::string key = "";
  SubnodeHelper::ProduceSharedDataKey(timestamp, device_id_, &key);

  cam_obj_data_->Add(key, sensor_objects);
  cam_shared_data_->Add(key, camera_item);

  for (size_t idx = 0; idx < pub_meta_events_.size(); ++idx) {
    const EventMeta &event_meta = pub_meta_events_[idx];
    Event event;
    event.event_id = event_meta.event_id;
    event.timestamp = timestamp;
    event.reserve = device_id_;
    event_manager_->Publish(event);
  }
}

}  // namespace perception
}  // namespace apollo
<|endoftext|>


<commit_before>// Copyright (c) 2014-2015 The Dash developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "coinbase-payee.h"
#include "util.h"
#include "addrman.h"
#include "masternode.h"
#include "darksend.h"
#include "masternodeman.h"
#include <boost/filesystem.hpp>

CCoinbasePayee coinbasePayee;

//
// CCoinbasePayeeDB
//

CCoinbasePayeeDB::CCoinbasePayeeDB()
{
    pathDB = GetDataDir() / "coinbase-payee.dat";
    strMagicMessage = "CoinbasePayeeDB";
}

bool CCoinbasePayeeDB::Write(const CCoinbasePayee& objToSave)
{
    int64_t nStart = GetTimeMillis();

    // serialize, checksum data up to that point, then append checksum
    CDataStream ssObj(SER_DISK, CLIENT_VERSION);
    ssObj << strMagicMessage; // coinbase payee cache file specific magic message
    ssObj << FLATDATA(Params().MessageStart()); // network specific magic number
    ssObj << objToSave;
    uint256 hash = Hash(ssObj.begin(), ssObj.end());
    ssObj << hash;

    // open output file, and associate with CAutoFile
    FILE *file = fopen(pathDB.string().c_str(), "wb");
    CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
    if (fileout.IsNull())
        return error("%s : Failed to open file %s", __func__, pathDB.string());

    // Write and commit header, data
    try {
        fileout << ssObj;
    }
    catch (std::exception &e) {
        return error("%s : Serialize or I/O error - %s", __func__, e.what());
    }
    fileout.fclose();

    LogPrintf("Written info to coinbase-payee.dat  %dms\n", GetTimeMillis() - nStart);

    return true;
}

CCoinbasePayeeDB::ReadResult CCoinbasePayeeDB::Read(CCoinbasePayee& objToLoad)
{

    int64_t nStart = GetTimeMillis();
    // open input file, and associate with CAutoFile
    FILE *file = fopen(pathDB.string().c_str(), "rb");
    CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
    if (filein.IsNull())
    {
        error("%s : Failed to open file %s", __func__, pathDB.string());
        return FileError;
    }

    // use file size to size memory buffer
    int fileSize = boost::filesystem::file_size(pathDB);
    int dataSize = fileSize - sizeof(uint256);
    // Don't try to resize to a negative number if file is small
    if (dataSize < 0)
        dataSize = 0;
    vector<unsigned char> vchData;
    vchData.resize(dataSize);
    uint256 hashIn;

    // read data and checksum from file
    try {
        filein.read((char *)&vchData[0], dataSize);
        filein >> hashIn;
    }
    catch (std::exception &e) {
        error("%s : Deserialize or I/O error - %s", __func__, e.what());
        return HashReadError;
    }
    filein.fclose();

    CDataStream ssObj(vchData, SER_DISK, CLIENT_VERSION);

    // verify stored checksum matches input data
    uint256 hashTmp = Hash(ssObj.begin(), ssObj.end());
    if (hashIn != hashTmp)
    {
        error("%s : Checksum mismatch, data corrupted", __func__);
        return IncorrectHash;
    }

    unsigned char pchMsgTmp[4];
    std::string strMagicMessageTmp;
    try {
        // de-serialize file header (coinbase payee cache file specific magic message) and ..
        ssObj >> strMagicMessageTmp;

        // ... verify the message matches predefined one
        if (strMagicMessage != strMagicMessageTmp)
        {
            error("%s : Invalid coinbase payee cache magic message", __func__);
            return IncorrectMagicMessage;
        }

        // de-serialize file header (network specific magic number) and ..
        ssObj >> FLATDATA(pchMsgTmp);

        // ... verify the network matches ours
        if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
        {
            error("%s : Invalid network magic number", __func__);
            return IncorrectMagicNumber;
        }

        // de-serialize data into CCoinbasePayee object
        ssObj >> objToLoad;
    }
    catch (std::exception &e) {
        objToLoad.Clear();
        error("%s : Deserialize or I/O error - %s", __func__, e.what());
        return IncorrectFormat;
    }

    objToLoad.CleanUp(); // clean out expired
    LogPrintf("Loaded info from coinbase-payee.dat  %dms\n", GetTimeMillis() - nStart);
    LogPrintf("  %s\n", objToLoad.ToString());

    return Ok;
}

void DumpCoinbasePayees()
{
    int64_t nStart = GetTimeMillis();

    CCoinbasePayeeDB mndb;
    CCoinbasePayee temp;

    LogPrintf("Verifying coinbase-payee.dat format...\n");
    CCoinbasePayeeDB::ReadResult readResult = mndb.Read(temp);
    // there was an error and it was not an error on file openning => do not proceed
    if (readResult == CCoinbasePayeeDB::FileError)
        LogPrintf("Missing payees cache file - coinbase-payee.dat, will try to recreate\n");
    else if (readResult != CCoinbasePayeeDB::Ok)
    {
        LogPrintf("Error reading coinbase-payee.dat: ");
        if(readResult == CCoinbasePayeeDB::IncorrectFormat)
            LogPrintf("magic is ok but data has invalid format, will try to recreate\n");
        else
        {
            LogPrintf("file format is unknown or invalid, please fix it manually\n");
            return;
        }
    }
    LogPrintf("Writting info to coinbase-payee.dat...\n");
    mndb.Write(coinbasePayee);

    LogPrintf("Coinbase payee dump finished  %dms\n", GetTimeMillis() - nStart);
}

void CCoinbasePayee::BuildIndex(bool bForced)
{
    if(mapPaidTime.size() > 0 && !bForced) {
        LogPrintf("CCoinbasePayee::BuildIndex - coinbase cache exists, skipping BuildIndex\n");
        return;
    } else if(bForced) {
        if(fDebug) LogPrintf("CCoinbasePayee::BuildIndex - Rebuilding coinbase cache\n");
        mapPaidTime.clear();
    }

    //scan last 30 days worth of blocks, run processBlockCoinbaseTX for each

    CBlockIndex* pindexPrev = chainActive.Tip();
    int count = 0;

    for (unsigned int i = 1; pindexPrev && pindexPrev->nHeight > 0; i++) {
        count++;
        if(count > 18000) return;

        CBlock block;
        if (ReadBlockFromDisk(block, pindexPrev)) {
            ProcessBlockCoinbaseTX(block.vtx[0], block.nTime);
        }

        if (pindexPrev->pprev == NULL) { assert(pindexPrev); break; }
        pindexPrev = pindexPrev->pprev;
    }

    return;
}

void CCoinbasePayee::ProcessBlockCoinbaseTX(CTransaction& txCoinbase, int64_t nTime)
{
    if (!txCoinbase.IsCoinBase()){
        LogPrintf("ERROR: CCoinbasePayee::ProcessBlockCoinbaseTX - tx is not coinbase\n");
        return;
    }

    BOOST_FOREACH(CTxOut out, txCoinbase.vout){
        uint256 h = GetScriptHash(out.scriptPubKey);
        LogPrintf("CCoinbasePayee::ProcessBlockCoinbaseTX - %s - %d\n", h.ToString(), nTime);
        if(mapPaidTime.count(h)){
            if(mapPaidTime[h] < nTime) {
                mapPaidTime[h] = nTime;
            }
        } else {
            mapPaidTime[h] = nTime;
        }
    }
}

int64_t CCoinbasePayee::GetLastPaid(CScript& pubkey)
{
    uint256 h = GetScriptHash(pubkey);

    if(mapPaidTime.count(h)){
        return mapPaidTime[h];
    }

    return 0;
}

void CCoinbasePayee::CleanUp()
{
    std::map<uint256, int64_t>::iterator it = mapPaidTime.begin();
    while(it != mapPaidTime.end())
    {
        //keep 30 days of history
        if((*it).second < GetAdjustedTime() - (60*60*24*30)) {
            mapPaidTime.erase(it++);
        } else {
            ++it;
        }
    }
}
<commit_msg>Disabled coinpayee cleanup<commit_after>// Copyright (c) 2014-2015 The Dash developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "coinbase-payee.h"
#include "util.h"
#include "addrman.h"
#include "masternode.h"
#include "darksend.h"
#include "masternodeman.h"
#include <boost/filesystem.hpp>

CCoinbasePayee coinbasePayee;

//
// CCoinbasePayeeDB
//

CCoinbasePayeeDB::CCoinbasePayeeDB()
{
    pathDB = GetDataDir() / "coinbase-payee.dat";
    strMagicMessage = "CoinbasePayeeDB";
}

bool CCoinbasePayeeDB::Write(const CCoinbasePayee& objToSave)
{
    int64_t nStart = GetTimeMillis();

    // serialize, checksum data up to that point, then append checksum
    CDataStream ssObj(SER_DISK, CLIENT_VERSION);
    ssObj << strMagicMessage; // coinbase payee cache file specific magic message
    ssObj << FLATDATA(Params().MessageStart()); // network specific magic number
    ssObj << objToSave;
    uint256 hash = Hash(ssObj.begin(), ssObj.end());
    ssObj << hash;

    // open output file, and associate with CAutoFile
    FILE *file = fopen(pathDB.string().c_str(), "wb");
    CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
    if (fileout.IsNull())
        return error("%s : Failed to open file %s", __func__, pathDB.string());

    // Write and commit header, data
    try {
        fileout << ssObj;
    }
    catch (std::exception &e) {
        return error("%s : Serialize or I/O error - %s", __func__, e.what());
    }
    fileout.fclose();

    LogPrintf("Written info to coinbase-payee.dat  %dms\n", GetTimeMillis() - nStart);

    return true;
}

CCoinbasePayeeDB::ReadResult CCoinbasePayeeDB::Read(CCoinbasePayee& objToLoad)
{

    int64_t nStart = GetTimeMillis();
    // open input file, and associate with CAutoFile
    FILE *file = fopen(pathDB.string().c_str(), "rb");
    CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
    if (filein.IsNull())
    {
        error("%s : Failed to open file %s", __func__, pathDB.string());
        return FileError;
    }

    // use file size to size memory buffer
    int fileSize = boost::filesystem::file_size(pathDB);
    int dataSize = fileSize - sizeof(uint256);
    // Don't try to resize to a negative number if file is small
    if (dataSize < 0)
        dataSize = 0;
    vector<unsigned char> vchData;
    vchData.resize(dataSize);
    uint256 hashIn;

    // read data and checksum from file
    try {
        filein.read((char *)&vchData[0], dataSize);
        filein >> hashIn;
    }
    catch (std::exception &e) {
        error("%s : Deserialize or I/O error - %s", __func__, e.what());
        return HashReadError;
    }
    filein.fclose();

    CDataStream ssObj(vchData, SER_DISK, CLIENT_VERSION);

    // verify stored checksum matches input data
    uint256 hashTmp = Hash(ssObj.begin(), ssObj.end());
    if (hashIn != hashTmp)
    {
        error("%s : Checksum mismatch, data corrupted", __func__);
        return IncorrectHash;
    }

    unsigned char pchMsgTmp[4];
    std::string strMagicMessageTmp;
    try {
        // de-serialize file header (coinbase payee cache file specific magic message) and ..
        ssObj >> strMagicMessageTmp;

        // ... verify the message matches predefined one
        if (strMagicMessage != strMagicMessageTmp)
        {
            error("%s : Invalid coinbase payee cache magic message", __func__);
            return IncorrectMagicMessage;
        }

        // de-serialize file header (network specific magic number) and ..
        ssObj >> FLATDATA(pchMsgTmp);

        // ... verify the network matches ours
        if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
        {
            error("%s : Invalid network magic number", __func__);
            return IncorrectMagicNumber;
        }

        // de-serialize data into CCoinbasePayee object
        ssObj >> objToLoad;
    }
    catch (std::exception &e) {
        objToLoad.Clear();
        error("%s : Deserialize or I/O error - %s", __func__, e.what());
        return IncorrectFormat;
    }

    objToLoad.CleanUp(); // clean out expired
    LogPrintf("Loaded info from coinbase-payee.dat  %dms\n", GetTimeMillis() - nStart);
    LogPrintf("  %s\n", objToLoad.ToString());

    return Ok;
}

void DumpCoinbasePayees()
{
    int64_t nStart = GetTimeMillis();

    CCoinbasePayeeDB mndb;
    CCoinbasePayee temp;

    LogPrintf("Verifying coinbase-payee.dat format...\n");
    CCoinbasePayeeDB::ReadResult readResult = mndb.Read(temp);
    // there was an error and it was not an error on file openning => do not proceed
    if (readResult == CCoinbasePayeeDB::FileError)
        LogPrintf("Missing payees cache file - coinbase-payee.dat, will try to recreate\n");
    else if (readResult != CCoinbasePayeeDB::Ok)
    {
        LogPrintf("Error reading coinbase-payee.dat: ");
        if(readResult == CCoinbasePayeeDB::IncorrectFormat)
            LogPrintf("magic is ok but data has invalid format, will try to recreate\n");
        else
        {
            LogPrintf("file format is unknown or invalid, please fix it manually\n");
            return;
        }
    }
    LogPrintf("Writting info to coinbase-payee.dat...\n");
    mndb.Write(coinbasePayee);

    LogPrintf("Coinbase payee dump finished  %dms\n", GetTimeMillis() - nStart);
}

void CCoinbasePayee::BuildIndex(bool bForced)
{
    if(mapPaidTime.size() > 0 && !bForced) {
        LogPrintf("CCoinbasePayee::BuildIndex - coinbase cache exists, skipping BuildIndex\n");
        return;
    } else if(bForced) {
        if(fDebug) LogPrintf("CCoinbasePayee::BuildIndex - Rebuilding coinbase cache\n");
        mapPaidTime.clear();
    }

    //scan last 30 days worth of blocks, run processBlockCoinbaseTX for each

    CBlockIndex* pindexPrev = chainActive.Tip();
    int count = 0;

    for (unsigned int i = 1; pindexPrev && pindexPrev->nHeight > 0; i++) {
        count++;
        if(count > 18000) return;

        CBlock block;
        if (ReadBlockFromDisk(block, pindexPrev)) {
            ProcessBlockCoinbaseTX(block.vtx[0], block.nTime);
        }

        if (pindexPrev->pprev == NULL) { assert(pindexPrev); break; }
        pindexPrev = pindexPrev->pprev;
    }

    return;
}

void CCoinbasePayee::ProcessBlockCoinbaseTX(CTransaction& txCoinbase, int64_t nTime)
{
    if (!txCoinbase.IsCoinBase()){
        LogPrintf("ERROR: CCoinbasePayee::ProcessBlockCoinbaseTX - tx is not coinbase\n");
        return;
    }

    BOOST_FOREACH(CTxOut out, txCoinbase.vout){
        uint256 h = GetScriptHash(out.scriptPubKey);
        LogPrintf("CCoinbasePayee::ProcessBlockCoinbaseTX - %s - %d\n", h.ToString(), nTime);
        if(mapPaidTime.count(h)){
            if(mapPaidTime[h] < nTime) {
                mapPaidTime[h] = nTime;
            } else {
                LogPrintf("CCoinbasePayee::ProcessBlockCoinbaseTX - not updated -- %s - %d\n", h.ToString(), nTime);
            }
        } else {
            mapPaidTime[h] = nTime;
        }
    }
}

int64_t CCoinbasePayee::GetLastPaid(CScript& pubkey)
{
    uint256 h = GetScriptHash(pubkey);

    if(mapPaidTime.count(h)){
        return mapPaidTime[h];
    }

    return 0;
}

void CCoinbasePayee::CleanUp()
{
    // std::map<uint256, int64_t>::iterator it = mapPaidTime.begin();
    // while(it != mapPaidTime.end())
    // {
    //     //keep 30 days of history
    //     if((*it).second < GetAdjustedTime() - (60*60*24*30)) {
    //         mapPaidTime.erase(it++);
    //     } else {
    //         ++it;
    //     }
    // }
}
<|endoftext|>


<commit_before>// Based on:
// Fast Anti-Aliasing Polygon Scan Conversion by Jack Morrison from "Graphics
// Gems", Academic Press, 1990.

// This code renders a polygon, computing subpixel coverage at
// 8 times Y and 16 times X display resolution for anti-aliasing.

#include "df_polygon_aa.h"

#include "df_bitmap.h"
#include "df_common.h"

#include <limits.h>
#include <math.h>

static const int SUBXRES = 16;      // subpixel X resolution per pixel
static const int SUBYRES = 8;       // subpixel Y resolution per scanline

#define MOD_Y_RES(y)   ((y) & 7)    // subpixel Y modulo

struct SubpixelRowExtents {
    int left, right;
};

// Array to store the start and end X values for each row of subpixels in the
// current scanline.
static SubpixelRowExtents subpixelRowExtents[SUBYRES];

// Min and max X values of subpixels in the current pixel. Can be found by
// searching subpixelRowExtents. Only stored as an optimization.
static int leftMin, rightMax;

// Compute number of subpixels covered by polygon at current pixel.
// x is left subpixel of pixel.
static int ComputePixelCoverage(int x)
{
    static const int MAX_AREA = SUBXRES * SUBYRES;
    int area = 0;
    x *= SUBXRES;
    int xr = x + SUBXRES - 1;   // Right-most subpixel of pixel.

    for (int y = 0; y < SUBYRES; y++) {
        // Calc covered area for current subpixel y
        int partialArea = IntMin(subpixelRowExtents[y].right, xr) -
            IntMax(subpixelRowExtents[y].left, x) + 1;
        if (partialArea > 0) {
            area += partialArea;
        }
    }

    return 255 * area / MAX_AREA;
}

static void RenderScanline(DfBitmap *bmp, int y, DfColour col)
{
    DfColour tmp = col;
    int x;
    for (x = leftMin / SUBXRES; x <= (rightMax / SUBXRES); x++) {
        int coverage = ComputePixelCoverage(x);
        if (coverage == 255) {
            break;
        }
        tmp.a = (col.a * coverage) >> 8;
        PutPix(bmp, x, y, tmp);
    }
    int x2;
    for (x2 = (rightMax / SUBXRES); x2 > x; x2--) {
        int coverage = ComputePixelCoverage(x2);
        if (coverage == 255) {
            break;
        }
        tmp.a = (col.a * coverage) >> 8;
        PutPix(bmp, x2, y, tmp);
    }

    if (x2 >= x) {
        HLine(bmp, x, y, x2 - x + 1, col);
    }
}

static bool IsConvexAndAnticlockwise(DfVertex *verts, int numVerts) {
    for (int a = 0; a < numVerts; a++) {
        int b = (a + 1) % numVerts;
        int c = (a + 2) % numVerts;

        int abx = verts[b].x - verts[a].x;
        int aby = verts[b].y - verts[a].y;
        int bcx = verts[c].x - verts[b].x;
        int bcy = verts[c].y - verts[b].y;

        int crossProduct = abx * bcy - bcx * aby;
        if (crossProduct > 0)
            return false;
    }

    return true;
}

void FillPolygonAa(DfBitmap *bmp, DfVertex *verts, int numVerts, DfColour col)
{
    if (!IsConvexAndAnticlockwise(verts, numVerts))
        return;

    // Convert the verts passed in into the format we use internally,
    // find the max vertex y value and the vertex with minimum y.
    DfVertex *vertLeft = verts;
    int maxY = -1;
    for (int i = 0; i < numVerts; i++) {
        verts[i].y /= SUBXRES / SUBYRES;
        if (verts[i].y < vertLeft->y) {
            vertLeft = &verts[i];
        }
        maxY = IntMax(maxY, verts[i].y);
    }
    DfVertex *endVert = &verts[numVerts - 1];

    // Initialize scanning edges.
    DfVertex *nextVertLeft, *vertRight, *nextVertRight;
    vertRight = nextVertRight = nextVertLeft = vertLeft;

#define NEXT_LEFT_EDGE() \
    vertLeft = nextVertLeft; \
    nextVertLeft++; \
    if (nextVertLeft > endVert) nextVertLeft = verts; // Wrap.

#define NEXT_RIGHT_EDGE() \
    vertRight = nextVertRight; \
    nextVertRight--; \
    if (nextVertRight < verts) nextVertRight = endVert; // Wrap.

    // Skip any initial horizontal edges because they would cause a divide by
    // zero in the slope calculation. We know once we've got over the initial
    // horizontal edges that there cannot be anymore in a convex poly, other
    // than those that would form the bottom of the poly. We'll never
    // encounter those either because the main loop will terminate just before
    // we get to those (because y will have become equal to maxY).
    while (vertLeft->y == nextVertLeft->y) {
        NEXT_LEFT_EDGE();
    }
    while (vertRight->y == nextVertRight->y) {
        NEXT_RIGHT_EDGE();
    }

    // Initialize the extents for each row of subpixels.
    for (int i = 0; i < SUBYRES; i++) {
        subpixelRowExtents[i].left = -1;
        subpixelRowExtents[i].right = -1;
    }

    leftMin = INT_MAX;
    rightMax = -1;
    int leftSlope = ((nextVertLeft->x - vertLeft->x) << 16) / (nextVertLeft->y - vertLeft->y);
    int rightSlope = ((nextVertRight->x - vertRight->x) << 16) / (nextVertRight->y - vertRight->y);

    // Consider each row of subpixels from top to bottom.
    for (int y = vertLeft->y; y < maxY; y++) {
        // Have we reached the end of the left hand edge we are following?
        if (y == nextVertLeft->y) {
            NEXT_LEFT_EDGE();
            leftSlope = ((nextVertLeft->x - vertLeft->x) << 16) / (nextVertLeft->y - vertLeft->y);
        }

        // Have we reached the end of the right hand edge we are following?
        if (y == nextVertRight->y) {
            NEXT_RIGHT_EDGE();
            rightSlope = ((nextVertRight->x - vertRight->x) << 16) / (nextVertRight->y - vertRight->y);
        }

        // Interpolate sub-pixel x endpoints at this y and update extremes.

        SubpixelRowExtents *sre = &subpixelRowExtents[MOD_Y_RES(y)];
        sre->left = vertLeft->x + (((y - vertLeft->y) * leftSlope) >> 16);
        leftMin = IntMin(leftMin, sre->left);

        sre->right = vertRight->x + (((y - vertRight->y) * rightSlope) >> 16);
        rightMax = IntMax(rightMax, sre->right);

        // Is this the last row of subpixels for this scanline?
        if (MOD_Y_RES(y) == SUBYRES - 1) {
            RenderScanline(bmp, y / SUBYRES, col);
            leftMin = INT_MAX;
            rightMax = -1;
        }
    }

    // Mark remaining subpixel rows as empty.
    for (int yy = MOD_Y_RES(maxY); MOD_Y_RES(yy); yy++) {
        subpixelRowExtents[yy].left = subpixelRowExtents[yy].right = -1;
    }
    RenderScanline(bmp, maxY / SUBYRES, col);

    // Convert the verts back into the format the caller uses.
    for (int i = 0; i < numVerts; i++) {
        verts[i].y *= SUBXRES / SUBYRES;
    }
}
<commit_msg>When generating polygons for a fat line, I sometimes was generating degenerate polys where all the vertices had the same y value. This is neither convex nor concave! Turns out the code went wrong with such a poly. A small tweak makes it safely reject them. You could argue that they should be rendered as a horizontal line. However, rejecting them was fine for my current purposes. I might need to reconsider this in the future.<commit_after>// Based on:
// Fast Anti-Aliasing Polygon Scan Conversion by Jack Morrison from "Graphics
// Gems", Academic Press, 1990.

// This code renders a polygon, computing subpixel coverage at
// 8 times Y and 16 times X display resolution for anti-aliasing.

#include "df_polygon_aa.h"

#include "df_bitmap.h"
#include "df_common.h"

#include <limits.h>
#include <math.h>

static const int SUBXRES = 16;      // subpixel X resolution per pixel
static const int SUBYRES = 8;       // subpixel Y resolution per scanline

#define MOD_Y_RES(y)   ((y) & 7)    // subpixel Y modulo

struct SubpixelRowExtents {
    int left, right;
};

// Array to store the start and end X values for each row of subpixels in the
// current scanline.
static SubpixelRowExtents subpixelRowExtents[SUBYRES];

// Min and max X values of subpixels in the current pixel. Can be found by
// searching subpixelRowExtents. Only stored as an optimization.
static int leftMin, rightMax;

// Compute number of subpixels covered by polygon at current pixel.
// x is left subpixel of pixel.
static int ComputePixelCoverage(int x)
{
    static const int MAX_AREA = SUBXRES * SUBYRES;
    int area = 0;
    x *= SUBXRES;
    int xr = x + SUBXRES - 1;   // Right-most subpixel of pixel.

    for (int y = 0; y < SUBYRES; y++) {
        // Calc covered area for current subpixel y
        int partialArea = IntMin(subpixelRowExtents[y].right, xr) -
            IntMax(subpixelRowExtents[y].left, x) + 1;
        if (partialArea > 0) {
            area += partialArea;
        }
    }

    return 255 * area / MAX_AREA;
}

static void RenderScanline(DfBitmap *bmp, int y, DfColour col)
{
    DfColour tmp = col;
    int x;
    for (x = leftMin / SUBXRES; x <= (rightMax / SUBXRES); x++) {
        int coverage = ComputePixelCoverage(x);
        if (coverage == 255) {
            break;
        }
        tmp.a = (col.a * coverage) >> 8;
        PutPix(bmp, x, y, tmp);
    }
    int x2;
    for (x2 = (rightMax / SUBXRES); x2 > x; x2--) {
        int coverage = ComputePixelCoverage(x2);
        if (coverage == 255) {
            break;
        }
        tmp.a = (col.a * coverage) >> 8;
        PutPix(bmp, x2, y, tmp);
    }

    if (x2 >= x) {
        HLine(bmp, x, y, x2 - x + 1, col);
    }
}

static bool IsConvexAndAnticlockwise(DfVertex *verts, int numVerts) {
    for (int a = 0; a < numVerts; a++) {
        int b = (a + 1) % numVerts;
        int c = (a + 2) % numVerts;

        int abx = verts[b].x - verts[a].x;
        int aby = verts[b].y - verts[a].y;
        int bcx = verts[c].x - verts[b].x;
        int bcy = verts[c].y - verts[b].y;

        int crossProduct = abx * bcy - bcx * aby;
        if (crossProduct > 0)
            return false;
    }

    return true;
}

void FillPolygonAa(DfBitmap *bmp, DfVertex *verts, int numVerts, DfColour col)
{
    if (!IsConvexAndAnticlockwise(verts, numVerts))
        return;

    // Convert the verts passed in into the format we use internally,
    // find the max vertex y value and the vertex with minimum y.
    DfVertex *vertLeft = verts;
    int maxY = -1;
    for (int i = 0; i < numVerts; i++) {
        verts[i].y /= SUBXRES / SUBYRES;
        if (verts[i].y < vertLeft->y) {
            vertLeft = &verts[i];
        }
        maxY = IntMax(maxY, verts[i].y);
    }
    DfVertex *endVert = &verts[numVerts - 1];

    // Initialize scanning edges.
    DfVertex *nextVertLeft, *vertRight, *nextVertRight;
    vertRight = nextVertRight = nextVertLeft = vertLeft;

#define NEXT_LEFT_EDGE() \
    vertLeft = nextVertLeft; \
    nextVertLeft++; \
    if (nextVertLeft > endVert) nextVertLeft = verts; // Wrap.

#define NEXT_RIGHT_EDGE() \
    vertRight = nextVertRight; \
    nextVertRight--; \
    if (nextVertRight < verts) nextVertRight = endVert; // Wrap.

    // Skip any initial horizontal edges because they would cause a divide by
    // zero in the slope calculation. We know once we've got over the initial
    // horizontal edges that there cannot be anymore in a convex poly, other
    // than those that would form the bottom of the poly. We'll never
    // encounter those either because the main loop will terminate just before
    // we get to those (because y will have become equal to maxY).
    for (int i = 0; i < numVerts; i++) {
        if (vertLeft->y != nextVertLeft->y)
            break;
        NEXT_LEFT_EDGE();
    }

    if (vertLeft->y == nextVertLeft->y)
        return; // All verts have the same y value. This is fatal.

    while (vertRight->y == nextVertRight->y) {
        NEXT_RIGHT_EDGE();
    }

    // Initialize the extents for each row of subpixels.
    for (int i = 0; i < SUBYRES; i++) {
        subpixelRowExtents[i].left = -1;
        subpixelRowExtents[i].right = -1;
    }

    leftMin = INT_MAX;
    rightMax = -1;
    int leftSlope = ((nextVertLeft->x - vertLeft->x) << 16) / (nextVertLeft->y - vertLeft->y);
    int rightSlope = ((nextVertRight->x - vertRight->x) << 16) / (nextVertRight->y - vertRight->y);

    // Consider each row of subpixels from top to bottom.
    for (int y = vertLeft->y; y < maxY; y++) {
        // Have we reached the end of the left hand edge we are following?
        if (y == nextVertLeft->y) {
            NEXT_LEFT_EDGE();
            leftSlope = ((nextVertLeft->x - vertLeft->x) << 16) / (nextVertLeft->y - vertLeft->y);
        }

        // Have we reached the end of the right hand edge we are following?
        if (y == nextVertRight->y) {
            NEXT_RIGHT_EDGE();
            rightSlope = ((nextVertRight->x - vertRight->x) << 16) / (nextVertRight->y - vertRight->y);
        }

        // Interpolate sub-pixel x endpoints at this y and update extremes.

        SubpixelRowExtents *sre = &subpixelRowExtents[MOD_Y_RES(y)];
        sre->left = vertLeft->x + (((y - vertLeft->y) * leftSlope) >> 16);
        leftMin = IntMin(leftMin, sre->left);

        sre->right = vertRight->x + (((y - vertRight->y) * rightSlope) >> 16);
        rightMax = IntMax(rightMax, sre->right);

        // Is this the last row of subpixels for this scanline?
        if (MOD_Y_RES(y) == SUBYRES - 1) {
            RenderScanline(bmp, y / SUBYRES, col);
            leftMin = INT_MAX;
            rightMax = -1;
        }
    }

    // Mark remaining subpixel rows as empty.
    for (int yy = MOD_Y_RES(maxY); MOD_Y_RES(yy); yy++) {
        subpixelRowExtents[yy].left = subpixelRowExtents[yy].right = -1;
    }
    RenderScanline(bmp, maxY / SUBYRES, col);

    // Convert the verts back into the format the caller uses.
    for (int i = 0; i < numVerts; i++) {
        verts[i].y *= SUBXRES / SUBYRES;
    }
}
<|endoftext|>


<commit_before>/*
** Copyright 1993 by Miron Livny, and Mike Litzkow
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted,
** provided that the above copyright notice appear in all copies and that
** both that copyright notice and this permission notice appear in
** supporting documentation, and that the names of the University of
** Wisconsin and the copyright holders not be used in advertising or
** publicity pertaining to distribution of the software without specific,
** written prior permission.  The University of Wisconsin and the
** copyright holders make no representations about the suitability of this
** software for any purpose.  It is provided "as is" without express
** or implied warranty.
**
** THE UNIVERSITY OF WISCONSIN AND THE COPYRIGHT HOLDERS DISCLAIM ALL
** WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE UNIVERSITY OF
** WISCONSIN OR THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT
** OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
** OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
** OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
** OR PERFORMANCE OF THIS SOFTWARE.
**
** Author:  Mike Litzkow
**
*/

#if defined(Solaris) && !defined(Solaris251)
#include "condor_fix_timeval.h"
#include </usr/ucbinclude/sys/rusage.h>
#endif

#define _POSIX_SOURCE

#include "condor_common.h"
#include "condor_constants.h"
#include "condor_debug.h"
#include "condor_config.h"
#include "condor_attributes.h"
#include "filter.h"
#include "alloc.h"

static char *_FileName_ = __FILE__;		/* Used by EXCEPT (see except.h)     */

#include "condor_qmgr.h"

char	*param();
char	*MyName;

int		PrioAdjustment;
int		NewPriority;
int		PrioritySet;
int		AdjustmentSet;
int		InvokingUid;		// user id of person ivoking this program
char	*InvokingUserName;	// user name of person ivoking this program

const int MIN_PRIO = -20;
const int MAX_PRIO = 20;

	// Prototypes of local interest only
void usage();
int compute_adj( char * );
void ProcArg( const char * );
int calc_prio( int old_prio );
void init_user_credentials();

char	hostname[512];

	// Tell folks how to use this program
void
usage()
{
	fprintf( stderr, "Usage: %s [{+|-}priority ] [-p priority] ", MyName );
	fprintf( stderr, "[ -a ] [-r host] [user | cluster | cluster.proc] ...\n");
	exit( 1 );
}

int
main( int argc, char *argv[] )
{
	char	*arg;
	int		prio_adj;
	char			*args[argc - 1];
	int				nArgs = 0;
	int				i;
	Qmgr_connection	*q;

	MyName = argv[0];

	config( 0 );

	if( argc < 2 ) {
		usage();
	}

	PrioritySet = 0;
	AdjustmentSet = 0;

	hostname[0] = '\0';
	for( argv++; arg = *argv; argv++ ) {
		if( (arg[0] == '-' || arg[0] == '+') && isdigit(arg[1]) ) {
			PrioAdjustment = compute_adj(arg);
			AdjustmentSet = TRUE;
		} else if( arg[0] == '-' && arg[1] == 'p' ) {
			argv++;
			NewPriority = atoi(*argv);
			PrioritySet = TRUE;
		} else if( arg[0] == '-' && arg[1] == 'r' ) {
			// use the given name as the host name to connect to
			argv++;
			strcpy (hostname, *argv);
		} else {
			args[nArgs] = arg;
			nArgs++;
		}
	}

	if( PrioritySet == FALSE && AdjustmentSet == FALSE ) {
		fprintf( stderr,
			"You must specify a new priority or priority adjustment.\n");
		usage();
		exit(1);
	}

	if( PrioritySet && (NewPriority < MIN_PRIO || NewPriority > MAX_PRIO) ) {
		fprintf( stderr,
			"Invalid priority specified.  Must be between %d and %d.\n",
			MIN_PRIO, MAX_PRIO );
		exit(1);
	}

		/* Open job queue */
	if (hostname[0] == '\0')
	{
		// hostname was not set at command line; obtain from system
		if(gethostname(hostname, 200) < 0)
		{
			EXCEPT("gethostname failed, errno = %d", errno);
		}
	}
	if((q = ConnectQ(hostname)) == 0)
	{
		EXCEPT("Failed to connect to qmgr on host %s", hostname);
	}
	for(i = 0; i < nArgs; i++)
	{
		ProcArg(args[i]);
	}
	DisconnectQ(q);

#if defined(ALLOC_DEBUG)
	print_alloc_stats();
#endif

	return 0;
}

/*
  Given the old priority of a given process, calculate the new
  one based on information gotten from the command line arguments.
*/
int
calc_prio( int old_prio )
{
	int		answer;

	if( AdjustmentSet == TRUE && PrioritySet == FALSE ) {
		answer = old_prio + PrioAdjustment;
		if( answer > MAX_PRIO )
			answer = MAX_PRIO;
		else if( answer < MIN_PRIO )
			answer = MIN_PRIO;
	} else {
		answer = NewPriority;
	}
	return answer;
}

/*
  Given a command line argument specifing a relative adjustment
  of priority of the form "+adj" or "-adj", return the correct
  value as a positive or negative integer.
*/
int
compute_adj( char *arg )
{
	char *ptr;
	int val;

	ptr = arg+1;

	val = atoi(ptr);

	if( *arg == '-' ) {
		return( -val );
	} else {
		return( val );
	}
}

extern "C" int SetSyscalls( int foo ) { return foo; }

void UpdateJobAd(int cluster, int proc)
{
	int old_prio, new_prio;
	if (GetAttributeInt(cluster, proc, ATTR_JOB_PRIO, &old_prio) < 0)
	{
		fprintf(stderr, "Couldn't retrieve current prio for %d.%d.\n",
				cluster, proc);
		return;
	}
	new_prio = calc_prio( old_prio );
	SetAttributeInt(cluster, proc, ATTR_JOB_PRIO, new_prio);
}

void ProcArg(const char* arg)
{
	int		cluster, proc;
	char	*tmp;

	if(isdigit(*arg))
	// set prio by cluster/proc #
	{
		cluster = strtol(arg, &tmp, 10);
		if(cluster <= 0)
		{
			fprintf(stderr, "Invalid cluster # from %s\n", arg);
			return;
		}
		if(*tmp == '\0')
		// update prio for all jobs in the cluster
		{
			ClassAd	*ad = new ClassAd;
			char constraint[100];
			sprintf(constraint, "%s == %d", ATTR_CLUSTER_ID, cluster);
			int firstTime = 1;
			while(GetNextJobByConstraint(constraint, ad, firstTime) >= 0) {
				ad->LookupInteger(ATTR_PROC_ID, proc);
				delete ad;
				ad = new ClassAd;
				UpdateJobAd(cluster, proc);
				firstTime = 0;
			}
			delete ad;
			return;
		}
		if(*tmp == '.')
		{
			proc = strtol(tmp + 1, &tmp, 10);
			if(proc < 0)
			{
				fprintf(stderr, "Invalid proc # from %s\n", arg);
				return;
			}
			if(*tmp == '\0')
			// update prio for proc
			{
				UpdateJobAd(cluster, proc);
				return;
			}
			fprintf(stderr, "Warning: unrecognized \"%s\" skipped\n", arg);
			return;
		}
		fprintf(stderr, "Warning: unrecognized \"%s\" skipped\n", arg);
	}
	else if(arg[0] == '-' && arg[1] == 'a')
	{
		ClassAd *ad = new ClassAd;
		int firstTime = 1;
		while(GetNextJob(ad, firstTime) >= 0) {
			ad->LookupInteger(ATTR_CLUSTER_ID, cluster);
			ad->LookupInteger(ATTR_PROC_ID, proc);
			delete ad;
			ad = new ClassAd;
			UpdateJobAd(cluster, proc);
			firstTime = 0;
		}
		delete ad;
	}
	else if(isalpha(*arg))
	// update prio by user name
	{
		char	constraint[100];
		ClassAd	*ad = new ClassAd;
		int firstTime = 1;

		sprintf(constraint, "%s == \"%s\"", ATTR_OWNER, arg);

		while (GetNextJobByConstraint(constraint, ad, firstTime) >= 0) {
			ad->LookupInteger(ATTR_CLUSTER_ID, cluster);
			ad->LookupInteger(ATTR_PROC_ID, proc);
			delete ad;
			ad = new ClassAd;
			UpdateJobAd(cluster, proc);
			firstTime = 0;
		}
		delete ad;
	}
	else
	{
		fprintf(stderr, "Warning: unrecognized \"%s\" skipped\n", arg);
	}
}
<commit_msg>use malloc to allocate args array since array sizes must be constant in VC++<commit_after>/*
** Copyright 1993 by Miron Livny, and Mike Litzkow
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted,
** provided that the above copyright notice appear in all copies and that
** both that copyright notice and this permission notice appear in
** supporting documentation, and that the names of the University of
** Wisconsin and the copyright holders not be used in advertising or
** publicity pertaining to distribution of the software without specific,
** written prior permission.  The University of Wisconsin and the
** copyright holders make no representations about the suitability of this
** software for any purpose.  It is provided "as is" without express
** or implied warranty.
**
** THE UNIVERSITY OF WISCONSIN AND THE COPYRIGHT HOLDERS DISCLAIM ALL
** WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE UNIVERSITY OF
** WISCONSIN OR THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT
** OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
** OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
** OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
** OR PERFORMANCE OF THIS SOFTWARE.
**
** Author:  Mike Litzkow
**
*/

#if defined(Solaris) && !defined(Solaris251)
#include "condor_fix_timeval.h"
#include </usr/ucbinclude/sys/rusage.h>
#endif

#define _POSIX_SOURCE

#include "condor_common.h"
#include "condor_constants.h"
#include "condor_debug.h"
#include "condor_config.h"
#include "condor_attributes.h"
#include "alloc.h"

static char *_FileName_ = __FILE__;		/* Used by EXCEPT (see except.h)     */

#include "condor_qmgr.h"

char	*param();
char	*MyName;

int		PrioAdjustment;
int		NewPriority;
int		PrioritySet;
int		AdjustmentSet;
int		InvokingUid;		// user id of person ivoking this program
char	*InvokingUserName;	// user name of person ivoking this program

const int MIN_PRIO = -20;
const int MAX_PRIO = 20;

	// Prototypes of local interest only
void usage();
int compute_adj( char * );
void ProcArg( const char * );
int calc_prio( int old_prio );
void init_user_credentials();

char	hostname[512];

	// Tell folks how to use this program
void
usage()
{
	fprintf( stderr, "Usage: %s [{+|-}priority ] [-p priority] ", MyName );
	fprintf( stderr, "[ -a ] [-r host] [user | cluster | cluster.proc] ...\n");
	exit( 1 );
}

int
main( int argc, char *argv[] )
{
	char	*arg;
	char	**args = (char **)malloc(sizeof(char *)*(argc - 1));
	int				nArgs = 0;
	int				i;
	Qmgr_connection	*q;

	MyName = argv[0];

	config( 0 );

	if( argc < 2 ) {
		usage();
	}

	PrioritySet = 0;
	AdjustmentSet = 0;

	hostname[0] = '\0';
	for( argv++; arg = *argv; argv++ ) {
		if( (arg[0] == '-' || arg[0] == '+') && isdigit(arg[1]) ) {
			PrioAdjustment = compute_adj(arg);
			AdjustmentSet = TRUE;
		} else if( arg[0] == '-' && arg[1] == 'p' ) {
			argv++;
			NewPriority = atoi(*argv);
			PrioritySet = TRUE;
		} else if( arg[0] == '-' && arg[1] == 'r' ) {
			// use the given name as the host name to connect to
			argv++;
			strcpy (hostname, *argv);
		} else {
			args[nArgs] = arg;
			nArgs++;
		}
	}

	if( PrioritySet == FALSE && AdjustmentSet == FALSE ) {
		fprintf( stderr,
			"You must specify a new priority or priority adjustment.\n");
		usage();
		exit(1);
	}

	if( PrioritySet && (NewPriority < MIN_PRIO || NewPriority > MAX_PRIO) ) {
		fprintf( stderr,
			"Invalid priority specified.  Must be between %d and %d.\n",
			MIN_PRIO, MAX_PRIO );
		exit(1);
	}

		/* Open job queue */
	if (hostname[0] == '\0')
	{
		// hostname was not set at command line; obtain from system
		if(gethostname(hostname, 200) < 0)
		{
			EXCEPT("gethostname failed, errno = %d", errno);
		}
	}
	if((q = ConnectQ(hostname)) == 0)
	{
		EXCEPT("Failed to connect to qmgr on host %s", hostname);
	}
	for(i = 0; i < nArgs; i++)
	{
		ProcArg(args[i]);
	}
	DisconnectQ(q);

#if defined(ALLOC_DEBUG)
	print_alloc_stats();
#endif

	return 0;
}

/*
  Given the old priority of a given process, calculate the new
  one based on information gotten from the command line arguments.
*/
int
calc_prio( int old_prio )
{
	int		answer;

	if( AdjustmentSet == TRUE && PrioritySet == FALSE ) {
		answer = old_prio + PrioAdjustment;
		if( answer > MAX_PRIO )
			answer = MAX_PRIO;
		else if( answer < MIN_PRIO )
			answer = MIN_PRIO;
	} else {
		answer = NewPriority;
	}
	return answer;
}

/*
  Given a command line argument specifing a relative adjustment
  of priority of the form "+adj" or "-adj", return the correct
  value as a positive or negative integer.
*/
int
compute_adj( char *arg )
{
	char *ptr;
	int val;

	ptr = arg+1;

	val = atoi(ptr);

	if( *arg == '-' ) {
		return( -val );
	} else {
		return( val );
	}
}

extern "C" int SetSyscalls( int foo ) { return foo; }

void UpdateJobAd(int cluster, int proc)
{
	int old_prio, new_prio;
	if (GetAttributeInt(cluster, proc, ATTR_JOB_PRIO, &old_prio) < 0)
	{
		fprintf(stderr, "Couldn't retrieve current prio for %d.%d.\n",
				cluster, proc);
		return;
	}
	new_prio = calc_prio( old_prio );
	SetAttributeInt(cluster, proc, ATTR_JOB_PRIO, new_prio);
}

void ProcArg(const char* arg)
{
	int		cluster, proc;
	char	*tmp;

	if(isdigit(*arg))
	// set prio by cluster/proc #
	{
		cluster = strtol(arg, &tmp, 10);
		if(cluster <= 0)
		{
			fprintf(stderr, "Invalid cluster # from %s\n", arg);
			return;
		}
		if(*tmp == '\0')
		// update prio for all jobs in the cluster
		{
			ClassAd	*ad = new ClassAd;
			char constraint[100];
			sprintf(constraint, "%s == %d", ATTR_CLUSTER_ID, cluster);
			int firstTime = 1;
			while(GetNextJobByConstraint(constraint, ad, firstTime) >= 0) {
				ad->LookupInteger(ATTR_PROC_ID, proc);
				delete ad;
				ad = new ClassAd;
				UpdateJobAd(cluster, proc);
				firstTime = 0;
			}
			delete ad;
			return;
		}
		if(*tmp == '.')
		{
			proc = strtol(tmp + 1, &tmp, 10);
			if(proc < 0)
			{
				fprintf(stderr, "Invalid proc # from %s\n", arg);
				return;
			}
			if(*tmp == '\0')
			// update prio for proc
			{
				UpdateJobAd(cluster, proc);
				return;
			}
			fprintf(stderr, "Warning: unrecognized \"%s\" skipped\n", arg);
			return;
		}
		fprintf(stderr, "Warning: unrecognized \"%s\" skipped\n", arg);
	}
	else if(arg[0] == '-' && arg[1] == 'a')
	{
		ClassAd *ad = new ClassAd;
		int firstTime = 1;
		while(GetNextJob(ad, firstTime) >= 0) {
			ad->LookupInteger(ATTR_CLUSTER_ID, cluster);
			ad->LookupInteger(ATTR_PROC_ID, proc);
			delete ad;
			ad = new ClassAd;
			UpdateJobAd(cluster, proc);
			firstTime = 0;
		}
		delete ad;
	}
	else if(isalpha(*arg))
	// update prio by user name
	{
		char	constraint[100];
		ClassAd	*ad = new ClassAd;
		int firstTime = 1;

		sprintf(constraint, "%s == \"%s\"", ATTR_OWNER, arg);

		while (GetNextJobByConstraint(constraint, ad, firstTime) >= 0) {
			ad->LookupInteger(ATTR_CLUSTER_ID, cluster);
			ad->LookupInteger(ATTR_PROC_ID, proc);
			delete ad;
			ad = new ClassAd;
			UpdateJobAd(cluster, proc);
			firstTime = 0;
		}
		delete ad;
	}
	else
	{
		fprintf(stderr, "Warning: unrecognized \"%s\" skipped\n", arg);
	}
}
<|endoftext|>


<commit_before>/** @file
    @brief Implementation of Kalman-specific code in beacon-based pose
   estimator, to reduce incremental build times.

    @date 2015

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>
*/

// Copyright 2015 Sensics, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//        http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <iostream>
#include <osvr/Util/EigenCoreGeometry.h>
#if 0
template <typename T>
inline void dumpKalmanDebugOuput(const char name[], const char expr[],
                                 T const &value) {
    std::cout << "\n(Kalman Debug Output) " << name << " [" << expr << "]:\n"
              << value << std::endl;
}
#endif

// Internal Includes
#include "BeaconBasedPoseEstimator.h"
#include "VideoJacobian.h"
#include "ImagePointMeasurement.h"
#include "cvToEigen.h"

// Library/third-party includes
#include <osvr/Kalman/FlexibleKalmanFilter.h>
#include <osvr/Kalman/AugmentedProcessModel.h>
#include <osvr/Kalman/AugmentedState.h>
#include <osvr/Kalman/ConstantProcess.h>

#include <osvr/Util/EigenInterop.h>

#include <opencv2/core/eigen.hpp>

// Standard includes
// - none

namespace osvr {
namespace vbtracker {
    /// This is the constant maximum distance in image space (pixels) permitted
    /// between a projected beacon location and its detected location.
    static const auto MAX_RESIDUAL = 75.0;
    static const auto MAX_SQUARED_RESIDUAL = MAX_RESIDUAL * MAX_RESIDUAL;

    static const auto DEFAULT_MEASUREMENT_VARIANCE = 2.0;
    static const auto LOW_BEACON_MEASUREMENT_VARIANCE = 1.0;
    static const auto LOW_BEACON_CUTOFF = 5;

    static const auto DIM_BEACON_CUTOFF_TO_SKIP_BRIGHTS = 4;
    bool
    BeaconBasedPoseEstimator::m_kalmanAutocalibEstimator(const LedGroup &leds,
                                                         double dt) {
        auto const beaconsSize = m_beacons.size();
        // Default measurement variance per axis.
        auto variance = DEFAULT_MEASUREMENT_VARIANCE;
        // Default to using all the measurements we can
        auto skipBright = false;
        {
            auto totalLeds = leds.size();
            auto identified = std::size_t{0};
            auto inBoundsID = std::size_t{0};
            auto inBoundsBright = std::size_t{0};
            for (auto const &led : leds) {
                if (!led.identified()) {
                    continue;
                }
                identified++;
                auto id = led.getID();
                if (id >= beaconsSize) {
                    continue;
                }
                inBoundsID++;
                if (led.isBright()) {
                    inBoundsBright++;
                }
            }

            // Now we decide if we want to cut the variance artificially to
            // reduce latency in low-beacon situations
            if (inBoundsID < LOW_BEACON_CUTOFF) {
                variance = LOW_BEACON_MEASUREMENT_VARIANCE;
            }
            if (inBoundsID - inBoundsBright >
                DIM_BEACON_CUTOFF_TO_SKIP_BRIGHTS) {
                skipBright = true;
            }
        }

        CameraModel cam;
        cam.focalLength = m_focalLength;
        cam.principalPoint = m_principalPoint;
        ImagePointMeasurement meas{cam};
        meas.setVariance(variance);
        kalman::ConstantProcess<kalman::PureVectorState<>> beaconProcess;
        Eigen::Vector2d pt;

        kalman::predict(m_state, m_model, dt);
        auto numBad = std::size_t{0};
        auto numGood = std::size_t{0};
        for (auto const &led : leds) {
            if (!led.identified()) {
                continue;
            }
            auto id = led.getID();
            if (id >= beaconsSize) {
                continue;
            }
            if (skipBright && led.isBright()) {
                continue;
            }
            meas.setMeasurement(
                Eigen::Vector2d(led.getLocation().x, led.getLocation().y));

            auto state = kalman::makeAugmentedState(m_state, *(m_beacons[id]));
            meas.updateFromState(state);
            auto model =
                kalman::makeAugmentedProcessModel(m_model, beaconProcess);

            if (meas.getResidual(state).squaredNorm() > MAX_SQUARED_RESIDUAL) {
                // probably bad
                std::cout << "skipping a measurement with a high residual: id "
                          << id << std::endl;
                numBad++;
                continue;
            }
            numGood++;

            kalman::correct(state, model, meas);
        }

        bool incrementProbation = false;
        if (0 == m_framesInProbation) {
            // Let's try to keep a 3:2 ratio of good to bad when not "in
            // probation"
            incrementProbation = (numBad * 3 > numGood * 2);

        } else {
            // Already in trouble, add a bit of hysteresis and raising the bar
            // so we don't hop out easily.
            incrementProbation = numBad * 2 > numGood;
            if (!incrementProbation) {
                // OK, we're good again
                std::cout << "Re-attained our tracking goal." << std::endl;
                m_framesInProbation = 0;
            }
        }
        if (incrementProbation) {
            std::cout << "Fell below our target for tracking residuals: "
                      << numBad << " bad, " << numGood << " good." << std::endl;
            m_framesInProbation++;
        }
        /// Output to the OpenCV state types so we can see the reprojection
        /// debug view.
        m_rvec = eiQuatToRotVec(m_state.getQuaternion());
        cv::eigen2cv(m_state.getPosition().eval(), m_tvec);
        return true;
    }

    OSVR_PoseState
    BeaconBasedPoseEstimator::GetPredictedState(double dt) const {
        auto state = m_state;
        auto model = m_model;
        kalman::predict(state, model, dt);
        state.postCorrect();
        OSVR_PoseState ret;
        util::eigen_interop::map(ret).rotation() = state.getQuaternion();
        util::eigen_interop::map(ret).translation() =
            m_convertInternalPositionRepToExternal(state.getPosition());
        return ret;
    }

} // namespace vbtracker
} // namespace osvr
<commit_msg>Bump up the max residual again.<commit_after>/** @file
    @brief Implementation of Kalman-specific code in beacon-based pose
   estimator, to reduce incremental build times.

    @date 2015

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>
*/

// Copyright 2015 Sensics, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//        http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <iostream>
#include <osvr/Util/EigenCoreGeometry.h>
#if 0
template <typename T>
inline void dumpKalmanDebugOuput(const char name[], const char expr[],
                                 T const &value) {
    std::cout << "\n(Kalman Debug Output) " << name << " [" << expr << "]:\n"
              << value << std::endl;
}
#endif

// Internal Includes
#include "BeaconBasedPoseEstimator.h"
#include "VideoJacobian.h"
#include "ImagePointMeasurement.h"
#include "cvToEigen.h"

// Library/third-party includes
#include <osvr/Kalman/FlexibleKalmanFilter.h>
#include <osvr/Kalman/AugmentedProcessModel.h>
#include <osvr/Kalman/AugmentedState.h>
#include <osvr/Kalman/ConstantProcess.h>

#include <osvr/Util/EigenInterop.h>

#include <opencv2/core/eigen.hpp>

// Standard includes
// - none

namespace osvr {
namespace vbtracker {
    /// This is the constant maximum distance in image space (pixels) permitted
    /// between a projected beacon location and its detected location.
    static const auto MAX_RESIDUAL = 100.0;
    static const auto MAX_SQUARED_RESIDUAL = MAX_RESIDUAL * MAX_RESIDUAL;

    static const auto DEFAULT_MEASUREMENT_VARIANCE = 2.0;
    static const auto LOW_BEACON_MEASUREMENT_VARIANCE = 1.0;
    static const auto LOW_BEACON_CUTOFF = 5;

    static const auto DIM_BEACON_CUTOFF_TO_SKIP_BRIGHTS = 4;
    bool
    BeaconBasedPoseEstimator::m_kalmanAutocalibEstimator(const LedGroup &leds,
                                                         double dt) {
        auto const beaconsSize = m_beacons.size();
        // Default measurement variance per axis.
        auto variance = DEFAULT_MEASUREMENT_VARIANCE;
        // Default to using all the measurements we can
        auto skipBright = false;
        {
            auto totalLeds = leds.size();
            auto identified = std::size_t{0};
            auto inBoundsID = std::size_t{0};
            auto inBoundsBright = std::size_t{0};
            for (auto const &led : leds) {
                if (!led.identified()) {
                    continue;
                }
                identified++;
                auto id = led.getID();
                if (id >= beaconsSize) {
                    continue;
                }
                inBoundsID++;
                if (led.isBright()) {
                    inBoundsBright++;
                }
            }

            // Now we decide if we want to cut the variance artificially to
            // reduce latency in low-beacon situations
            if (inBoundsID < LOW_BEACON_CUTOFF) {
                variance = LOW_BEACON_MEASUREMENT_VARIANCE;
            }
            if (inBoundsID - inBoundsBright >
                DIM_BEACON_CUTOFF_TO_SKIP_BRIGHTS) {
                skipBright = true;
            }
        }

        CameraModel cam;
        cam.focalLength = m_focalLength;
        cam.principalPoint = m_principalPoint;
        ImagePointMeasurement meas{cam};
        meas.setVariance(variance);
        kalman::ConstantProcess<kalman::PureVectorState<>> beaconProcess;
        Eigen::Vector2d pt;

        kalman::predict(m_state, m_model, dt);
        auto numBad = std::size_t{0};
        auto numGood = std::size_t{0};
        for (auto const &led : leds) {
            if (!led.identified()) {
                continue;
            }
            auto id = led.getID();
            if (id >= beaconsSize) {
                continue;
            }
            if (skipBright && led.isBright()) {
                continue;
            }
            meas.setMeasurement(
                Eigen::Vector2d(led.getLocation().x, led.getLocation().y));

            auto state = kalman::makeAugmentedState(m_state, *(m_beacons[id]));
            meas.updateFromState(state);
            auto model =
                kalman::makeAugmentedProcessModel(m_model, beaconProcess);

            if (meas.getResidual(state).squaredNorm() > MAX_SQUARED_RESIDUAL) {
                // probably bad
                std::cout << "skipping a measurement with a high residual: id "
                          << id << std::endl;
                numBad++;
                continue;
            }
            numGood++;

            kalman::correct(state, model, meas);
        }

        bool incrementProbation = false;
        if (0 == m_framesInProbation) {
            // Let's try to keep a 3:2 ratio of good to bad when not "in
            // probation"
            incrementProbation = (numBad * 3 > numGood * 2);

        } else {
            // Already in trouble, add a bit of hysteresis and raising the bar
            // so we don't hop out easily.
            incrementProbation = numBad * 2 > numGood;
            if (!incrementProbation) {
                // OK, we're good again
                std::cout << "Re-attained our tracking goal." << std::endl;
                m_framesInProbation = 0;
            }
        }
        if (incrementProbation) {
            std::cout << "Fell below our target for tracking residuals: "
                      << numBad << " bad, " << numGood << " good." << std::endl;
            m_framesInProbation++;
        }
        /// Output to the OpenCV state types so we can see the reprojection
        /// debug view.
        m_rvec = eiQuatToRotVec(m_state.getQuaternion());
        cv::eigen2cv(m_state.getPosition().eval(), m_tvec);
        return true;
    }

    OSVR_PoseState
    BeaconBasedPoseEstimator::GetPredictedState(double dt) const {
        auto state = m_state;
        auto model = m_model;
        kalman::predict(state, model, dt);
        state.postCorrect();
        OSVR_PoseState ret;
        util::eigen_interop::map(ret).rotation() = state.getQuaternion();
        util::eigen_interop::map(ret).translation() =
            m_convertInternalPositionRepToExternal(state.getPosition());
        return ret;
    }

} // namespace vbtracker
} // namespace osvr
<|endoftext|>


<commit_before>/*
Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al.
All Rights Reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in the
  documentation and/or other materials provided with the distribution.
* Neither the name of Sony Pictures Imageworks nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <OpenColorIO/OpenColorIO.h>

#include "FileTransform.h"
#include "OpBuilders.h"
#include "Processor.h"

#include <sstream>

OCIO_NAMESPACE_ENTER
{
    Transform::~Transform()
    { }

    void BuildOps(OpRcPtrVec & ops,
                  const Config & config,
                  const ConstTransformRcPtr & transform,
                  TransformDirection dir)
    {
        if(ConstCDLTransformRcPtr cdlTransform = \
            DynamicPtrCast<const CDLTransform>(transform))
        {
            BuildCDLOps(ops, config, *cdlTransform, dir);
        }
        else if(ConstColorSpaceTransformRcPtr colorSpaceTransform = \
            DynamicPtrCast<const ColorSpaceTransform>(transform))
        {
            BuildColorSpaceOps(ops, config, *colorSpaceTransform, dir);
        }
        else if(ConstDisplayTransformRcPtr displayTransform = \
            DynamicPtrCast<const DisplayTransform>(transform))
        {
            BuildDisplayOps(ops, config, *displayTransform, dir);
        }
        else if(ConstFileTransformRcPtr fileTransform = \
            DynamicPtrCast<const FileTransform>(transform))
        {
            BuildFileOps(ops, config, *fileTransform, dir);
        }
        else if(ConstGroupTransformRcPtr groupTransform = \
            DynamicPtrCast<const GroupTransform>(transform))
        {
            BuildGroupOps(ops, config, *groupTransform, dir);
        }
        else
        {
            std::ostringstream os;
            os << "Unknown transform type for Op Creation.";
            throw Exception(os.str().c_str());
        }
    }

    std::ostream& operator<< (std::ostream & os, const Transform & transform)
    {
        const Transform* t = &transform;

        if(const CDLTransform * cdlTransform = \
            dynamic_cast<const CDLTransform*>(t))
        {
            os << *cdlTransform;
        }
        else if(const ColorSpaceTransform * colorSpaceTransform = \
            dynamic_cast<const ColorSpaceTransform*>(t))
        {
            os << *colorSpaceTransform;
        }
        else if(const DisplayTransform * displayTransform = \
            dynamic_cast<const DisplayTransform*>(t))
        {
            os << *displayTransform;
        }
        else if(const FileTransform * fileTransform = \
            dynamic_cast<const FileTransform*>(t))
        {
            os << *fileTransform;
        }
        else if(const GroupTransform * groupTransform = \
            dynamic_cast<const GroupTransform*>(t))
        {
            os << *groupTransform;
        }
        else
        {
            std::ostringstream error;
            os << "Unknown transform type for serialization.";
            throw Exception(error.str().c_str());
        }

        return os;
    }
}
OCIO_NAMESPACE_EXIT
<commit_msg>Fixed code registration bug in MatrixTransform<commit_after>/*
Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al.
All Rights Reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in the
  documentation and/or other materials provided with the distribution.
* Neither the name of Sony Pictures Imageworks nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <OpenColorIO/OpenColorIO.h>

#include "FileTransform.h"
#include "OpBuilders.h"
#include "Processor.h"

#include <sstream>

OCIO_NAMESPACE_ENTER
{
    Transform::~Transform()
    { }

    void BuildOps(OpRcPtrVec & ops,
                  const Config & config,
                  const ConstTransformRcPtr & transform,
                  TransformDirection dir)
    {
        if(ConstCDLTransformRcPtr cdlTransform = \
            DynamicPtrCast<const CDLTransform>(transform))
        {
            BuildCDLOps(ops, config, *cdlTransform, dir);
        }
        else if(ConstColorSpaceTransformRcPtr colorSpaceTransform = \
            DynamicPtrCast<const ColorSpaceTransform>(transform))
        {
            BuildColorSpaceOps(ops, config, *colorSpaceTransform, dir);
        }
        else if(ConstDisplayTransformRcPtr displayTransform = \
            DynamicPtrCast<const DisplayTransform>(transform))
        {
            BuildDisplayOps(ops, config, *displayTransform, dir);
        }
        else if(ConstFileTransformRcPtr fileTransform = \
            DynamicPtrCast<const FileTransform>(transform))
        {
            BuildFileOps(ops, config, *fileTransform, dir);
        }
        else if(ConstGroupTransformRcPtr groupTransform = \
            DynamicPtrCast<const GroupTransform>(transform))
        {
            BuildGroupOps(ops, config, *groupTransform, dir);
        }
        else if(ConstMatrixTransformRcPtr matrixTransform = \
            DynamicPtrCast<const MatrixTransform>(transform))
        {
            BuildMatrixOps(ops, config, *matrixTransform, dir);
        }
        else
        {
            std::ostringstream os;
            os << "Unknown transform type for Op Creation.";
            throw Exception(os.str().c_str());
        }
    }

    std::ostream& operator<< (std::ostream & os, const Transform & transform)
    {
        const Transform* t = &transform;

        if(const CDLTransform * cdlTransform = \
            dynamic_cast<const CDLTransform*>(t))
        {
            os << *cdlTransform;
        }
        else if(const ColorSpaceTransform * colorSpaceTransform = \
            dynamic_cast<const ColorSpaceTransform*>(t))
        {
            os << *colorSpaceTransform;
        }
        else if(const DisplayTransform * displayTransform = \
            dynamic_cast<const DisplayTransform*>(t))
        {
            os << *displayTransform;
        }
        else if(const FileTransform * fileTransform = \
            dynamic_cast<const FileTransform*>(t))
        {
            os << *fileTransform;
        }
        else if(const GroupTransform * groupTransform = \
            dynamic_cast<const GroupTransform*>(t))
        {
            os << *groupTransform;
        }
        else if(const MatrixTransform * matrixTransform = \
            dynamic_cast<const MatrixTransform*>(t))
        {
            os << *matrixTransform;
        }
        else
        {
            std::ostringstream error;
            os << "Unknown transform type for serialization.";
            throw Exception(error.str().c_str());
        }

        return os;
    }
}
OCIO_NAMESPACE_EXIT
<|endoftext|>