<commit_before>#include "rclcpp/Node.h"
#include "rclcpp/Publisher.h"
#include "rclcpp/executor/SingleThreadExecutor.h"
#include "simple_msgs/Int32.h"

int main(int argc, char** argv)
{
  rclcpp::Node *node = rclcpp::create_node();
  node->create_subscriber<simple_msgs::Int32>("topic_name");

  rclcpp::executor::SingleThreadExecutor *executor = new rclcpp::executor::SingleThreadExecutor();

  executor->register_node(node);
  executor->exec();

  return 0;
}
<commit_msg>use callback in subscriber<commit_after>#include "rclcpp/Node.h"
#include "rclcpp/Publisher.h"
#include "rclcpp/executor/SingleThreadExecutor.h"
#include "simple_msgs/Int32.h"

void callback(const simple_msgs::Int32 *msg)
{
    std::cout << "Got message: " << msg->data << std::endl;
}

int main(int argc, char** argv)
{
  rclcpp::Node *node = rclcpp::create_node();
  node->create_subscriber<simple_msgs::Int32>("topic_name", callback);

  rclcpp::executor::SingleThreadExecutor *executor = new rclcpp::executor::SingleThreadExecutor();

  executor->register_node(node);
  executor->exec();

  return 0;
}
<|endoftext|>


<commit_before>/* Copyright 2021 The TensorFlow 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 "tensorflow/compiler/xla/client/lib/dynamic_shaped_ops.h"

#include <utility>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/types/span.h"
#include "tensorflow/compiler/xla/client/xla_builder.h"
#include "tensorflow/compiler/xla/shape_util.h"

namespace xla {
namespace {

// Given a list of shapes, create a shape whose dimensions are largest among all
// inputs.
//
// e.g.,
// shape_a = f32[10, 50]
// shape_b = f32[100, 10]
//
// result = f32[max(shape_a[0], shape_b[0]), max(shape_a[1], shape_b[1])]
//        = f32[100, 50]
Shape FindMaxShape(absl::Span<const Shape*> shapes) {
  CHECK(!shapes.empty());
  if (shapes[0]->IsTuple()) {
    // Recurse into sub-element.
    std::vector<Shape> results;
    results.reserve(shapes[0]->tuple_shapes_size());
    for (int i = 0; i < shapes[0]->tuple_shapes_size(); ++i) {
      std::vector<const Shape*> subshapes;
      subshapes.reserve(shapes.size());
      for (int64_t j = 0; j < shapes.size(); ++j) {
        subshapes.push_back(&shapes[j]->tuple_shapes(i));
      }
      results.push_back(FindMaxShape(absl::MakeSpan(subshapes)));
    }
    return ShapeUtil::MakeTupleShape(results);
  }
  Shape result = *shapes[0];

  for (const Shape* shape : shapes) {
    CHECK(result.rank() == shape->rank());
    for (int64_t dim = 0; dim < result.rank(); ++dim) {
      if (shape->dimensions(dim) > result.dimensions(dim)) {
        result.set_dimensions(dim, shape->dimensions(dim));
      }
    }
  }
  return result;
}

XlaOp ReconsileBranchDifference(const Shape& left_branch_shape,
                                const Shape& right_branch_shape,
                                XlaOp left_root) {
  if (left_branch_shape.IsTuple()) {
    // Invariant sanity check -- Left branch and right branch need to have
    // compatible shapes.
    CHECK(right_branch_shape.IsTuple() &&
          left_branch_shape.tuple_shapes_size() ==
              right_branch_shape.tuple_shapes_size());
    // Recurse into sub-element.
    std::vector<XlaOp> results;
    results.reserve(left_branch_shape.tuple_shapes_size());
    for (int i = 0; i < left_branch_shape.tuple_shapes_size(); ++i) {
      XlaOp sub_tuple = GetTupleElement(left_root, i);
      XlaOp elem = ReconsileBranchDifference(left_branch_shape.tuple_shapes(i),
                                             right_branch_shape.tuple_shapes(i),
                                             sub_tuple);
      results.push_back(elem);
    }
    return Tuple(left_root.builder(), results);
  }
  XlaOp result = left_root;
  // Invariant sanity check -- Left branch and right branch need to have
  // compatible shapes.
  CHECK(!right_branch_shape.IsTuple());
  CHECK_EQ(left_branch_shape.rank(), right_branch_shape.rank())
      << "left rank of (" << left_branch_shape.rank() << ") vs. right rank of ("
      << right_branch_shape.rank() << ")";
  for (int64_t dim = 0; dim < left_branch_shape.rank(); ++dim) {
    XlaOp original_dim = GetDimensionSize(result, dim);
    if (left_branch_shape.dimensions(dim) <
        right_branch_shape.dimensions(dim)) {
      int64_t diff = right_branch_shape.dimensions(dim) -
                     left_branch_shape.dimensions(dim);

      result = PadInDim(
          result, Zero(result.builder(), left_branch_shape.element_type()), dim,
          0, diff);
    }
    if (left_branch_shape.dimensions(dim) !=
        right_branch_shape.dimensions(dim)) {
      result = SetDimensionSize(result, original_dim, dim);
    }
  }
  return result;
}
}  // namespace
XlaOp DynamicConditional(XlaBuilder* builder, XlaOp predicate,
                         XlaOp true_operand,
                         const XlaComputation& true_computation,
                         XlaOp false_operand,
                         const XlaComputation& false_computation) {
  return builder->ReportErrorOrReturn([&]() -> StatusOr<XlaOp> {
    auto true_shape = true_computation.GetProgramShape().value().result();

    auto false_shape = false_computation.GetProgramShape().value().result();

    if (ShapeUtil::Compatible(true_shape, false_shape)) {
      return xla::Conditional(predicate, true_operand, true_computation,
                              false_operand, false_computation);
    }

    auto reconsile_branch = [](const Shape& root_shape,
                               const Shape& operand_shape,
                               const Shape& reference_root_shape,
                               const XlaComputation& computation) {
      xla::XlaBuilder builder("dynamic_builder");
      auto param = xla::Parameter(&builder, 0, operand_shape, "param");
      auto call = Call(&builder, computation, {param});

      ReconsileBranchDifference(root_shape, reference_root_shape, call);
      return builder.Build();
    };
    TF_ASSIGN_OR_RETURN(
        auto true_computation_rewritten,
        reconsile_branch(true_shape,
                         builder->GetShape(true_operand).ValueOrDie(),
                         false_shape, true_computation));

    TF_ASSIGN_OR_RETURN(
        auto false_computation_rewritten,
        reconsile_branch(false_shape,
                         builder->GetShape(false_operand).ValueOrDie(),
                         true_shape, false_computation));
    return xla::Conditional(predicate, true_operand, true_computation_rewritten,
                            false_operand, false_computation_rewritten);
  });
}

XlaOp DynamicConditional(
    XlaBuilder* builder, XlaOp branch_index,
    absl::Span<const XlaComputation* const> branch_computations,
    absl::Span<const XlaOp> branch_operands) {
  return builder->ReportErrorOrReturn([&]() -> StatusOr<XlaOp> {
    std::vector<Shape> root_shapes;
    root_shapes.reserve(branch_computations.size());
    for (int64_t i = 0; i < branch_computations.size(); ++i) {
      TF_ASSIGN_OR_RETURN(auto program_shape,
                          branch_computations[i]->GetProgramShape());
      root_shapes.push_back(program_shape.result());
    }
    TF_RET_CHECK(!root_shapes.empty());
    bool all_shapes_compatible =
        absl::c_all_of(root_shapes, [&](const Shape& shape) {
          return ShapeUtil::Compatible(root_shapes[0], shape);
        });
    if (all_shapes_compatible) {
      // All shapes are compatible, fall back to static case.
      return xla::Conditional(branch_index, branch_computations,
                              branch_operands);
    }

    std::vector<const Shape*> root_shapes_ptrs;
    root_shapes_ptrs.reserve(root_shapes.size());
    for (int64_t i = 0; i < root_shapes.size(); ++i) {
      root_shapes_ptrs.push_back(&root_shapes[i]);
    }

    Shape max_shape = FindMaxShape(absl::MakeSpan(root_shapes_ptrs));

    auto reconsile_branch = [](const Shape& root_shape,
                               const Shape& operand_shape,
                               const Shape& reference_root_shape,
                               const XlaComputation& computation) {
      xla::XlaBuilder builder("dynamic_builder");
      auto param = xla::Parameter(&builder, 0, operand_shape, "param");
      auto call = Call(&builder, computation, {param});

      ReconsileBranchDifference(root_shape, reference_root_shape, call);
      return builder.Build();
    };
    std::vector<XlaComputation> rewritten_computations;
    rewritten_computations.reserve(branch_computations.size());

    for (int64_t i = 0; i < branch_computations.size(); ++i) {
      TF_ASSIGN_OR_RETURN(Shape branch_operand_shape,
                          builder->GetShape(branch_operands[i]));

      TF_ASSIGN_OR_RETURN(auto rewritten,
                          reconsile_branch(root_shapes[i], branch_operand_shape,
                                           max_shape, *branch_computations[i]));
      rewritten_computations.push_back(std::move(rewritten));
    }
    std::vector<const XlaComputation*> rewritten_computation_ptrs;
    rewritten_computation_ptrs.reserve(branch_computations.size());
    for (int64_t i = 0; i < branch_computations.size(); ++i) {
      rewritten_computation_ptrs.push_back(&rewritten_computations[i]);
    }
    return xla::Conditional(branch_index, rewritten_computation_ptrs,
                            branch_operands);
  });
}

StatusOr<XlaOp> SetDimensionSizeWithRebound(ValueInference* value_inference,
                                            XlaOp operand, XlaOp dimension_size,
                                            int64_t dimension) {
  auto inferred_bound_status_or = value_inference->AnalyzeConstant(
      dimension_size, xla::ValueInferenceMode::kUpperBound);

  auto dynamism_status_or = value_inference->AnalyzeIsDynamic(dimension_size);
  TF_RETURN_IF_ERROR(inferred_bound_status_or.status());
  TF_RETURN_IF_ERROR(dynamism_status_or.status());
  if (inferred_bound_status_or->AllValid()) {
    int64_t inferred_bound = inferred_bound_status_or->Get<int32_t>({}).value();
    TF_ASSIGN_OR_RETURN(auto* shape_ptr,
                        operand.builder()->GetShapePtr(operand));
    // Found a tighter bound, do a slice.
    if (shape_ptr->dimensions(dimension) > inferred_bound) {
      operand = xla::SliceInDim(operand, 0, inferred_bound, 1, dimension);
    }
  }
  if (dynamism_status_or->Get<bool>({})) {
    // dimension size is dynamic, make output dynamic by calling set dimension
    // size.
    operand = xla::SetDimensionSize(operand, dimension_size, dimension);
  }
  return operand;
}

StatusOr<XlaOp> SetAllDimensionSizes(ValueInference* value_inference,
                                     XlaOp operand, XlaOp size_vector) {
  auto builder = value_inference->builder();
  TF_RETURN_IF_ERROR(builder->GetCurrentStatus());
  TF_ASSIGN_OR_RETURN(auto shape_ptr, builder->GetShapePtr(operand));

  for (int64_t i = 0; i < shape_ptr->rank(); ++i) {
    // If a dimension is dynamic, call set-dimension-size on the output.
    auto dim_size = xla::Slice(size_vector, {i}, {i + 1}, {1});
    dim_size = xla::Reshape(dim_size, {});
    dim_size = xla::ConvertElementType(dim_size, xla::S32);
    TF_ASSIGN_OR_RETURN(auto dynamism,
                        value_inference->AnalyzeIsDynamic(dim_size));
    if (dynamism.Get<bool>({})) {
      operand = xla::SetDimensionSize(operand, dim_size, i);
    }
  }
  return operand;
}
}  // namespace xla
<commit_msg>Propagate error message to the top rather than crashing the program when shapes do not match.<commit_after>/* Copyright 2021 The TensorFlow 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 "tensorflow/compiler/xla/client/lib/dynamic_shaped_ops.h"

#include <utility>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/types/span.h"
#include "tensorflow/compiler/xla/client/xla_builder.h"
#include "tensorflow/compiler/xla/shape_util.h"
#include "tensorflow/compiler/xla/util.h"

namespace xla {
namespace {

// Given a list of shapes, create a shape whose dimensions are largest among all
// inputs.
//
// e.g.,
// shape_a = f32[10, 50]
// shape_b = f32[100, 10]
//
// result = f32[max(shape_a[0], shape_b[0]), max(shape_a[1], shape_b[1])]
//        = f32[100, 50]
Shape FindMaxShape(absl::Span<const Shape*> shapes) {
  CHECK(!shapes.empty());
  if (shapes[0]->IsTuple()) {
    // Recurse into sub-element.
    std::vector<Shape> results;
    results.reserve(shapes[0]->tuple_shapes_size());
    for (int i = 0; i < shapes[0]->tuple_shapes_size(); ++i) {
      std::vector<const Shape*> subshapes;
      subshapes.reserve(shapes.size());
      for (int64_t j = 0; j < shapes.size(); ++j) {
        subshapes.push_back(&shapes[j]->tuple_shapes(i));
      }
      results.push_back(FindMaxShape(absl::MakeSpan(subshapes)));
    }
    return ShapeUtil::MakeTupleShape(results);
  }
  Shape result = *shapes[0];

  for (const Shape* shape : shapes) {
    CHECK(result.rank() == shape->rank());
    for (int64_t dim = 0; dim < result.rank(); ++dim) {
      if (shape->dimensions(dim) > result.dimensions(dim)) {
        result.set_dimensions(dim, shape->dimensions(dim));
      }
    }
  }
  return result;
}

StatusOr<XlaOp> ReconsileBranchDifference(const Shape& left_branch_shape,
                                          const Shape& right_branch_shape,
                                          XlaOp left_root) {
  if (left_branch_shape.IsTuple()) {
    // Invariant sanity check -- Left branch and right branch need to have
    // compatible shapes.
    CHECK(right_branch_shape.IsTuple() &&
          left_branch_shape.tuple_shapes_size() ==
              right_branch_shape.tuple_shapes_size());
    // Recurse into sub-element.
    std::vector<XlaOp> results;
    results.reserve(left_branch_shape.tuple_shapes_size());
    for (int i = 0; i < left_branch_shape.tuple_shapes_size(); ++i) {
      XlaOp sub_tuple = GetTupleElement(left_root, i);
      TF_ASSIGN_OR_RETURN(XlaOp elem,
                          ReconsileBranchDifference(
                              left_branch_shape.tuple_shapes(i),
                              right_branch_shape.tuple_shapes(i), sub_tuple));
      results.push_back(elem);
    }
    return Tuple(left_root.builder(), results);
  }
  XlaOp result = left_root;
  // Invariant sanity check -- Left branch and right branch need to have
  // compatible shapes.
  if (right_branch_shape.IsTuple()) {
    return InvalidArgument(
        "right_branch_shape should not be a tuple, received %s",
        right_branch_shape.DebugString());
  }
  if (left_branch_shape.rank() != right_branch_shape.rank()) {
    return InvalidArgument(
        "left_branch_shape.rank() != right_branch_shape.rank() (%d vs %d)",
        left_branch_shape.rank(), right_branch_shape.rank());
  }
  for (int64_t dim = 0; dim < left_branch_shape.rank(); ++dim) {
    XlaOp original_dim = GetDimensionSize(result, dim);
    if (left_branch_shape.dimensions(dim) <
        right_branch_shape.dimensions(dim)) {
      int64_t diff = right_branch_shape.dimensions(dim) -
                     left_branch_shape.dimensions(dim);

      result = PadInDim(
          result, Zero(result.builder(), left_branch_shape.element_type()), dim,
          0, diff);
    }
    if (left_branch_shape.dimensions(dim) !=
        right_branch_shape.dimensions(dim)) {
      result = SetDimensionSize(result, original_dim, dim);
    }
  }
  return result;
}
}  // namespace
XlaOp DynamicConditional(XlaBuilder* builder, XlaOp predicate,
                         XlaOp true_operand,
                         const XlaComputation& true_computation,
                         XlaOp false_operand,
                         const XlaComputation& false_computation) {
  return builder->ReportErrorOrReturn([&]() -> StatusOr<XlaOp> {
    auto true_shape = true_computation.GetProgramShape().value().result();

    auto false_shape = false_computation.GetProgramShape().value().result();

    if (ShapeUtil::Compatible(true_shape, false_shape)) {
      return xla::Conditional(predicate, true_operand, true_computation,
                              false_operand, false_computation);
    }

    auto reconsile_branch =
        [](const Shape& root_shape, const Shape& operand_shape,
           const Shape& reference_root_shape,
           const XlaComputation& computation) -> StatusOr<XlaComputation> {
      xla::XlaBuilder builder("dynamic_builder");
      auto param = xla::Parameter(&builder, 0, operand_shape, "param");
      auto call = Call(&builder, computation, {param});

      auto elem =
          ReconsileBranchDifference(root_shape, reference_root_shape, call);
      if (!elem.ok()) return elem.status();
      return builder.Build();
    };
    TF_ASSIGN_OR_RETURN(
        auto true_computation_rewritten,
        reconsile_branch(true_shape,
                         builder->GetShape(true_operand).ValueOrDie(),
                         false_shape, true_computation));

    TF_ASSIGN_OR_RETURN(
        auto false_computation_rewritten,
        reconsile_branch(false_shape,
                         builder->GetShape(false_operand).ValueOrDie(),
                         true_shape, false_computation));
    return xla::Conditional(predicate, true_operand, true_computation_rewritten,
                            false_operand, false_computation_rewritten);
  });
}

XlaOp DynamicConditional(
    XlaBuilder* builder, XlaOp branch_index,
    absl::Span<const XlaComputation* const> branch_computations,
    absl::Span<const XlaOp> branch_operands) {
  return builder->ReportErrorOrReturn([&]() -> StatusOr<XlaOp> {
    std::vector<Shape> root_shapes;
    root_shapes.reserve(branch_computations.size());
    for (int64_t i = 0; i < branch_computations.size(); ++i) {
      TF_ASSIGN_OR_RETURN(auto program_shape,
                          branch_computations[i]->GetProgramShape());
      root_shapes.push_back(program_shape.result());
    }
    TF_RET_CHECK(!root_shapes.empty());
    bool all_shapes_compatible =
        absl::c_all_of(root_shapes, [&](const Shape& shape) {
          return ShapeUtil::Compatible(root_shapes[0], shape);
        });
    if (all_shapes_compatible) {
      // All shapes are compatible, fall back to static case.
      return xla::Conditional(branch_index, branch_computations,
                              branch_operands);
    }

    std::vector<const Shape*> root_shapes_ptrs;
    root_shapes_ptrs.reserve(root_shapes.size());
    for (int64_t i = 0; i < root_shapes.size(); ++i) {
      root_shapes_ptrs.push_back(&root_shapes[i]);
    }

    Shape max_shape = FindMaxShape(absl::MakeSpan(root_shapes_ptrs));

    auto reconsile_branch =
        [](const Shape& root_shape, const Shape& operand_shape,
           const Shape& reference_root_shape,
           const XlaComputation& computation) -> StatusOr<XlaComputation> {
      xla::XlaBuilder builder("dynamic_builder");
      auto param = xla::Parameter(&builder, 0, operand_shape, "param");
      auto call = Call(&builder, computation, {param});

      auto elem =
          ReconsileBranchDifference(root_shape, reference_root_shape, call);
      if (!elem.ok()) return elem.status();
      return builder.Build();
    };
    std::vector<XlaComputation> rewritten_computations;
    rewritten_computations.reserve(branch_computations.size());

    for (int64_t i = 0; i < branch_computations.size(); ++i) {
      TF_ASSIGN_OR_RETURN(Shape branch_operand_shape,
                          builder->GetShape(branch_operands[i]));

      TF_ASSIGN_OR_RETURN(auto rewritten,
                          reconsile_branch(root_shapes[i], branch_operand_shape,
                                           max_shape, *branch_computations[i]));
      rewritten_computations.push_back(std::move(rewritten));
    }
    std::vector<const XlaComputation*> rewritten_computation_ptrs;
    rewritten_computation_ptrs.reserve(branch_computations.size());
    for (int64_t i = 0; i < branch_computations.size(); ++i) {
      rewritten_computation_ptrs.push_back(&rewritten_computations[i]);
    }
    return xla::Conditional(branch_index, rewritten_computation_ptrs,
                            branch_operands);
  });
}

StatusOr<XlaOp> SetDimensionSizeWithRebound(ValueInference* value_inference,
                                            XlaOp operand, XlaOp dimension_size,
                                            int64_t dimension) {
  auto inferred_bound_status_or = value_inference->AnalyzeConstant(
      dimension_size, xla::ValueInferenceMode::kUpperBound);

  auto dynamism_status_or = value_inference->AnalyzeIsDynamic(dimension_size);
  TF_RETURN_IF_ERROR(inferred_bound_status_or.status());
  TF_RETURN_IF_ERROR(dynamism_status_or.status());
  if (inferred_bound_status_or->AllValid()) {
    int64_t inferred_bound = inferred_bound_status_or->Get<int32_t>({}).value();
    TF_ASSIGN_OR_RETURN(auto* shape_ptr,
                        operand.builder()->GetShapePtr(operand));
    // Found a tighter bound, do a slice.
    if (shape_ptr->dimensions(dimension) > inferred_bound) {
      operand = xla::SliceInDim(operand, 0, inferred_bound, 1, dimension);
    }
  }
  if (dynamism_status_or->Get<bool>({})) {
    // dimension size is dynamic, make output dynamic by calling set dimension
    // size.
    operand = xla::SetDimensionSize(operand, dimension_size, dimension);
  }
  return operand;
}

StatusOr<XlaOp> SetAllDimensionSizes(ValueInference* value_inference,
                                     XlaOp operand, XlaOp size_vector) {
  auto builder = value_inference->builder();
  TF_RETURN_IF_ERROR(builder->GetCurrentStatus());
  TF_ASSIGN_OR_RETURN(auto shape_ptr, builder->GetShapePtr(operand));

  for (int64_t i = 0; i < shape_ptr->rank(); ++i) {
    // If a dimension is dynamic, call set-dimension-size on the output.
    auto dim_size = xla::Slice(size_vector, {i}, {i + 1}, {1});
    dim_size = xla::Reshape(dim_size, {});
    dim_size = xla::ConvertElementType(dim_size, xla::S32);
    TF_ASSIGN_OR_RETURN(auto dynamism,
                        value_inference->AnalyzeIsDynamic(dim_size));
    if (dynamism.Get<bool>({})) {
      operand = xla::SetDimensionSize(operand, dim_size, i);
    }
  }
  return operand;
}
}  // namespace xla
<|endoftext|>


<commit_before>/* Copyright 2018 The TensorFlow 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 "tensorflow/lite/kernels/internal/reference/softmax.h"

#include "tensorflow/lite/c/builtin_op_data.h"
#include "tensorflow/lite/c/common.h"
#include "tensorflow/lite/kernels/internal/common.h"
#include "tensorflow/lite/kernels/internal/quantization_util.h"
#include "tensorflow/lite/kernels/internal/tensor_ctypes.h"
#include "tensorflow/lite/kernels/kernel_util.h"
#include "tensorflow/lite/kernels/op_macros.h"

namespace tflite {
namespace ops {
namespace micro {
namespace activations {
namespace {

// TODO(b/141176180): This code is currently a strict subset of the portable
// implementation (softmax.cc one directory up). When TFLM implements
// registrations for selective types (e.g. compile without float support), this
// can be removed. Otherwise, any HiFi specific optimizations should land here.

// This size will work for both the hotword (1) and ambient music (0):
static SoftmaxParams kStaticOpData;

TfLiteStatus CalculateSoftmaxOpData(TfLiteContext* context,
                                    const TfLiteTensor* input,
                                    TfLiteTensor* output,
                                    const TfLiteSoftmaxParams* params,
                                    SoftmaxParams* op_data) {
  if (input->type == kTfLiteUInt8 || input->type == kTfLiteInt8) {
    if (input->type == kTfLiteUInt8) {
      TF_LITE_ENSURE_EQ(context, output->params.zero_point, 0);
    } else {
      if (output->type == kTfLiteInt16) {
        TF_LITE_ENSURE_EQ(context, output->params.zero_point, -32768);
        // NOTE: Current int16 softmax output does not require symmetric scaling
        // - so no need to verify scale here.
      } else {
        TF_LITE_ENSURE_EQ(context, output->params.zero_point, -128);
        TF_LITE_ENSURE(context, output->params.scale == 1.f / 256);
      }
    }

    static const int kScaledDiffIntegerBits = 5;

    int input_left_shift;
    tflite::PreprocessSoftmaxScaling(
        static_cast<double>(params->beta),
        static_cast<double>(input->params.scale), kScaledDiffIntegerBits,
        &op_data->input_multiplier, &input_left_shift);
    op_data->input_left_shift = input_left_shift;
    op_data->diff_min =
        -1.0 * tflite::CalculateInputRadius(kScaledDiffIntegerBits,
                                            op_data->input_left_shift);
  }
  return kTfLiteOk;
}

TfLiteStatus SoftmaxQuantized(TfLiteContext* context, const TfLiteTensor* input,
                              TfLiteTensor* output,
                              const SoftmaxParams& op_params) {
  switch (output->type) {
    case kTfLiteInt16:
      tflite::reference_ops::Softmax(
          op_params, GetTensorShape(input), GetTensorData<int8_t>(input),
          GetTensorShape(output), GetTensorData<int16_t>(output));
      return kTfLiteOk;
    case kTfLiteInt8:
      tflite::reference_ops::Softmax(
          op_params, GetTensorShape(input), GetTensorData<int8_t>(input),
          GetTensorShape(output), GetTensorData<int8_t>(output));
      return kTfLiteOk;
    default:
      TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.",
                         TfLiteTypeGetName(output->type), output->type);
      return kTfLiteError;
  }
}

}  // namespace

TfLiteStatus SoftmaxPrepare(TfLiteContext* context, TfLiteNode* node) {
  auto* params = static_cast<TfLiteSoftmaxParams*>(node->builtin_data);

  TF_LITE_ENSURE_EQ(context, NumInputs(node), 1);
  TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1);
  const TfLiteTensor* input = GetInput(context, node, 0);
  TfLiteTensor* output = GetOutput(context, node, 0);
  TF_LITE_ENSURE(context, NumDimensions(input) >= 1);

  // TODO(b/132070898): Use statically slotted SoftmaxParams structures until a
  // scratch memory API is ready.
  SoftmaxParams* op_params = &kStaticOpData;
  node->user_data = op_params;

  TF_LITE_ENSURE_STATUS(
      CalculateSoftmaxOpData(context, input, output, params, op_params));

  return kTfLiteOk;
}

TfLiteStatus SoftmaxEval(TfLiteContext* context, TfLiteNode* node) {
  auto* op_params = static_cast<SoftmaxParams*>(node->user_data);

  const TfLiteTensor* input = GetInput(context, node, 0);
  TfLiteTensor* output = GetOutput(context, node, 0);

  switch (input->type) {
    case kTfLiteInt8:
      return SoftmaxQuantized(context, input, output, *op_params);
    default:
      TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.",
                         TfLiteTypeGetName(input->type), input->type);
      return kTfLiteError;
  }
}
}  // namespace activations

TfLiteRegistration* Register_SOFTMAX() {
  static TfLiteRegistration r = {/*init=*/nullptr,
                                 /*free=*/nullptr,
                                 /*prepare=*/activations::SoftmaxPrepare,
                                 /*invoke=*/activations::SoftmaxEval,
                                 /*profiling_string=*/nullptr,
                                 /*builtin_code=*/0,
                                 /*custom_name=*/nullptr,
                                 /*version=*/0};
  return &r;
}

}  // namespace micro
}  // namespace ops
}  // namespace tflite
<commit_msg>Refactor Softmax and use new memory API.<commit_after>/* Copyright 2018 The TensorFlow 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 "tensorflow/lite/kernels/internal/reference/softmax.h"

#include "tensorflow/lite/c/builtin_op_data.h"
#include "tensorflow/lite/c/common.h"
#include "tensorflow/lite/kernels/internal/common.h"
#include "tensorflow/lite/kernels/internal/quantization_util.h"
#include "tensorflow/lite/kernels/internal/tensor_ctypes.h"
#include "tensorflow/lite/kernels/kernel_util.h"
#include "tensorflow/lite/kernels/op_macros.h"

namespace tflite {
namespace ops {
namespace micro {
namespace activations {
namespace {

// TODO(b/141176180): This code is currently a strict subset of the portable
// implementation (softmax.cc one directory up). When TFLM implements
// registrations for selective types (e.g. compile without float support), this
// can be removed. Otherwise, any HiFi specific optimizations should land here.

TfLiteStatus CalculateSoftmaxOpData(TfLiteContext* context,
                                    const TfLiteTensor* input,
                                    TfLiteTensor* output,
                                    const TfLiteSoftmaxParams* params,
                                    SoftmaxParams* op_data) {
  if (input->type == kTfLiteUInt8 || input->type == kTfLiteInt8) {
    if (input->type == kTfLiteUInt8) {
      TF_LITE_ENSURE_EQ(context, output->params.zero_point, 0);
    } else {
      if (output->type == kTfLiteInt16) {
        TF_LITE_ENSURE_EQ(context, output->params.zero_point,
                          std::numeric_limits<int16_t>::min());
        // NOTE: Current int16 softmax output does not require symmetric scaling
        // - so no need to verify scale here.
      } else {
        TF_LITE_ENSURE_EQ(context, output->params.zero_point,
                          std::numeric_limits<int8_t>::min());
        TF_LITE_ENSURE(context, output->params.scale == 1.f / 256);
      }
    }

    static const int kScaledDiffIntegerBits = 5;

    int input_left_shift;
    tflite::PreprocessSoftmaxScaling(
        static_cast<double>(params->beta),
        static_cast<double>(input->params.scale), kScaledDiffIntegerBits,
        &op_data->input_multiplier, &input_left_shift);
    op_data->input_left_shift = input_left_shift;
    op_data->diff_min =
        -1.0 * tflite::CalculateInputRadius(kScaledDiffIntegerBits,
                                            op_data->input_left_shift);
  }
  return kTfLiteOk;
}

}  // namespace

void* SoftmaxInit(TfLiteContext* context, const char* buffer, size_t length) {
  TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr);
  void* data = nullptr;
  if (context->AllocatePersistentBuffer(context, sizeof(SoftmaxParams),
                                        &data) == kTfLiteError) {
    return nullptr;
  }
  return data;
}

TfLiteStatus SoftmaxPrepare(TfLiteContext* context, TfLiteNode* node) {
  auto* params = static_cast<TfLiteSoftmaxParams*>(node->builtin_data);

  TF_LITE_ENSURE_EQ(context, NumInputs(node), 1);
  TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1);
  const TfLiteTensor* input = GetInput(context, node, 0);
  TfLiteTensor* output = GetOutput(context, node, 0);
  TF_LITE_ENSURE(context, NumDimensions(input) >= 1);

  TFLITE_DCHECK(node->user_data != nullptr);
  SoftmaxParams* op_params = static_cast<SoftmaxParams*>(node->user_data);

  TF_LITE_ENSURE_STATUS(
      CalculateSoftmaxOpData(context, input, output, params, op_params));

  return kTfLiteOk;
}

TfLiteStatus SoftmaxEval(TfLiteContext* context, TfLiteNode* node) {
  auto* op_params = static_cast<SoftmaxParams*>(node->user_data);

  const TfLiteTensor* input = GetInput(context, node, 0);
  TfLiteTensor* output = GetOutput(context, node, 0);

  if (input->type == kTfLiteInt8 && output->type == kTfLiteInt16) {
    // TODO(b/155656675): Const ref params can be slow on xtensa.
    tflite::reference_ops::Softmax(
        *op_params, GetTensorShape(input), GetTensorData<int8_t>(input),
        GetTensorShape(output), GetTensorData<int16_t>(output));
    return kTfLiteOk;
  } else {
    TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.",
                       TfLiteTypeGetName(input->type), input->type);
    return kTfLiteError;
  }
}
}  // namespace activations

TfLiteRegistration* Register_SOFTMAX() {
  static TfLiteRegistration r = {/*init=*/activations::SoftmaxInit,
                                 /*free=*/nullptr,
                                 /*prepare=*/activations::SoftmaxPrepare,
                                 /*invoke=*/activations::SoftmaxEval,
                                 /*profiling_string=*/nullptr,
                                 /*builtin_code=*/0,
                                 /*custom_name=*/nullptr,
                                 /*version=*/0};
  return &r;
}

}  // namespace micro
}  // namespace ops
}  // namespace tflite
<|endoftext|>


<commit_before>// KMail startup and initialize code
// Author: Stefan Taferner <taferner@alpin.or.at>

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

#include <kuniqueapplication.h>
#include <klocale.h>
#include <kglobal.h>
#include <dcopclient.h>
#include <kcrash.h>

#include "kmkernel.h" //control center

#undef Status // stupid X headers
#include "kmailIface_stub.h" // to call control center of master kmail

#include <kaboutdata.h>

#include "kmversion.h"

// OLD about text.  This is horrbly outdated.
/*const char* aboutText =
    "KMail [" KMAIL_VERSION "] by\n\n"
    "Stefan Taferner <taferner@kde.org>,\n"
    "Markus Wbben <markus.wuebben@kde.org>\n\n"
    "based on the work of:\n"
    "Lynx <lynx@topaz.hknet.com>,\n"
    "Stephan Meyer <Stephan.Meyer@pobox.com>,\n"
    "and the above authors.\n\n"
    "This program is covered by the GPL.\n\n"
    "Please send bugreports to taferner@kde.org";
*/

static KCmdLineOptions kmoptions[] =
{
  { "s", 0 , 0 },
  { "subject <subject>",	I18N_NOOP("Set subject of msg."), 0 },
  { "c", 0 , 0 },
  { "cc <address>",		I18N_NOOP("Send CC: to 'address'."), 0 },
  { "b", 0 , 0 },
  { "bcc <address>",		I18N_NOOP("Send BCC: to 'addres'."), 0 },
  { "h", 0 , 0 },
  { "header <header>",		I18N_NOOP("Add 'header' to msg."), 0 },
  { "msg <file>",		I18N_NOOP("Read msg-body from 'file'."), 0 },
  { "body <text>",              I18N_NOOP("Set body of msg."), 0 },
  { "attach <url>",             I18N_NOOP("Add an attachment to the mail, this can be repeated"), 0 },
  { "check",			I18N_NOOP("Check for new mail only."), 0 },
  { "composer",			I18N_NOOP("Open only composer window."), 0 },
  { "+[address]",		I18N_NOOP("Send msg to 'address'."), 0 },
//  { "+[file]",                  I18N_NOOP("Show message from file 'file'."), 0 },
  { 0, 0, 0}
};

//-----------------------------------------------------------------------------

extern "C" {

static void setSignalHandler(void (*handler)(int));

// Crash recovery signal handler
static void signalHandler(int sigId)
{
  setSignalHandler(SIG_DFL);
  fprintf(stderr, "*** KMail got signal %d (Exiting)\n", sigId);
  // try to cleanup all windows
  kernel->dumpDeadLetters();
  ::exit(-1); //
}

// Crash recovery signal handler
static void crashHandler(int sigId)
{
  setSignalHandler(SIG_DFL);
  fprintf(stderr, "*** KMail got signal %d (Crashing)\n", sigId);
  // try to cleanup all windows
  kernel->dumpDeadLetters();
  // Return to DrKonqi.
}
//-----------------------------------------------------------------------------

static void setSignalHandler(void (*handler)(int))
{
  signal(SIGKILL, handler);
  signal(SIGTERM, handler);
  signal(SIGHUP,  handler);
  KCrash::setEmergencySaveFunction(crashHandler);
}

}
//-----------------------------------------------------------------------------

class KMailApplication : public KUniqueApplication
{
public:
  KMailApplication() : KUniqueApplication() { };

  virtual int newInstance();

  void commitData(QSessionManager& sm) {
    kernel->notClosedByUser();
    KApplication::commitData( sm );
  }
};

int KMailApplication::newInstance()
{
  QString to, cc, bcc, subj, body;
  KURL messageFile = QString::null;
  KURL::List attachURLs;
  bool mailto = false;
  bool checkMail = false;
  //bool viewOnly = false;

  // process args:
  KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
  if (args->getOption("subject"))
  {
     mailto = true;
     subj = QString::fromLocal8Bit(args->getOption("subject"));
  }

  if (args->getOption("cc"))
  {
     mailto = true;
     cc = QString::fromLocal8Bit(args->getOption("cc"));
  }

  if (args->getOption("bcc"))
  {
     mailto = true;
     bcc = QString::fromLocal8Bit(args->getOption("bcc"));
  }

  if (args->getOption("msg"))
  {
     mailto = true;
     messageFile = QString::fromLocal8Bit(args->getOption("msg"));
  }

  if (args->getOption("body"))
  {
     mailto = true;
     body = QString::fromLocal8Bit(args->getOption("body"));
  }

  QCStringList attachList = args->getOptionList("attach");
  if (!attachList.isEmpty())
  {
     mailto = true;
     for ( QCStringList::Iterator it = attachList.begin() ; it != attachList.end() ; ++it )
         attachURLs += KURL( QString::fromLocal8Bit( *it ) );
  }

  if (args->isSet("composer"))
    mailto = true;

  if (args->isSet("check"))
    checkMail = true;

  for(int i= 0; i < args->count(); i++)
  {
    if (!to.isEmpty())
      to += ", ";
     if (strncasecmp(args->arg(i),"mailto:",7)==0)
       to += args->arg(i);
     else
       to += args->arg(i);
     mailto = true;
  }

  args->clear();

  kernel->action (mailto, checkMail, to, cc, bcc, subj, body, messageFile, attachURLs);
  return 0;
}

int main(int argc, char *argv[])
{
  // WABA: KMail is a KUniqueApplication. Unfortunately this makes debugging
  // a bit harder: You should pass --nofork as commandline argument when using
  // a debugger. In gdb you can do this by typing "set args --nofork" before
  // typing "run".

  KAboutData about("kmail", I18N_NOOP("KMail"),
                   KMAIL_VERSION,
		   I18N_NOOP("The KDE E-Mail client."),
		   KAboutData::License_GPL,
                   I18N_NOOP("(c) 1997-2001, The KMail developers"),
		   0,
		   "http://kmail.kde.org");
  about.addAuthor( "Michael Haeckel", I18N_NOOP("Current maintainer"), "michael@haeckel.net" );
  about.addAuthor( "Don Sanders", I18N_NOOP("Current maintainer"), "sanders@kde.org" );
  about.addAuthor( "Stefan Taferner ", 0, "taferner@kde.org" );
  about.addAuthor( "Daniel Naber", I18N_NOOP("Documentation"), "daniel.naber@t-online.de" );
  about.addAuthor( "Andreas Gungl", I18N_NOOP("Encryption"), "a.gungl@gmx.de" );
  about.addAuthor( "Toyohiro Asukai", 0, "toyohiro@ksmplus.com" );
  about.addAuthor( "Waldo Bastian", 0, "bastian@kde.org" );
  about.addAuthor( "Steven Brown", 0, "swbrown@ucsd.edu" );
  about.addAuthor( "Cristi Dumitrescu", 0, "cristid@chip.ro" );
  about.addAuthor( "Philippe Fremy", 0, "pfremy@chez.com" );
  about.addAuthor( "Kurt Granroth", 0, "granroth@kde.org" );
  about.addAuthor( "Igor Janssen", 0, "rm@linux.ru.net" );
  about.addAuthor( "Matt Johnston", 0, "matt@caifex.org" );
  about.addAuthor( "Christer Kaivo-oja", 0, "whizkid@telia.com" );
  about.addAuthor( "Ingo Kloecker", 0, "ingo.kloecker@epost.de" );
  about.addAuthor( "Lars Knoll", 0, "knoll@kde.org" );
  about.addAuthor( "J. Nick Koston", 0, "bdraco@darkorb.net" );
  about.addAuthor( "Stephan Kulow", 0, "coolo@kde.org" );
  about.addAuthor( "Guillaume Laurent", 0, "glaurent@telegraph-road.org" );
  about.addAuthor( "Sam Magnuson", 0, "sam@trolltech.com" );
  about.addAuthor( "Laurent Montel", 0, "lmontel@mandrakesoft.com" );
  about.addAuthor( "Marc Mutz", 0, "mutz@kde.org" );
  about.addAuthor( "Matt Newell", 0, "newellm@proaxis.com" );
  about.addAuthor( "Denis Perchine", 0, "dyp@perchine.com" );
  about.addAuthor( "Carsten Pfeiffer", 0, "pfeiffer@kde.org" );
  about.addAuthor( "Sven Radej", 0, "radej@kde.org" );
  about.addAuthor( "Mark Roberts", 0, "mark@taurine.demon.co.uk" );
  about.addAuthor( "Wolfgang Rohdewald", 0, "WRohdewald@dplanet.ch" );
  about.addAuthor( "Espen Sand", 0, "espen@kde.org" );
  about.addAuthor( "George Staikos", 0, "staikos@kde.org" );
  about.addAuthor( "Jason Stephenson", 0, "panda@mis.net" );
  about.addAuthor( "Jacek Stolarczyk", 0, "jacek@mer.chemia.polsl.gliwice.pl" );
  about.addAuthor( "Roberto S. Teixeira", 0, "maragato@kde.org" );
  about.addAuthor( "Mario Weilguni", 0, "mweilguni@sime.com" );
  about.addAuthor( "Wynn Wilkes", 0, "wynnw@calderasystems.com" );
  about.addAuthor( "Robert D. Williams", 0, "rwilliams@kde.org" );
  about.addAuthor( "Markus Wuebben", 0, "markus.wuebben@kde.org" );
  about.addAuthor( "Karl-Heinz Zimmer", 0, "khz@kde.org" );

  KCmdLineArgs::init(argc, argv, &about);
  KCmdLineArgs::addCmdLineOptions( kmoptions ); // Add kmail options

  if (!KMailApplication::start())
     return 0;

  KMailApplication app;
  KGlobal::locale()->insertCatalogue("libkdenetwork");

  kapp->dcopClient()->suspend(); // Don't handle DCOP requests yet

  //local, do the init
  KMKernel kmailKernel;
  kmailKernel.init();
  kapp->dcopClient()->setDefaultObject( kmailKernel.objId() );

  // and session management
  kmailKernel.doSessionManagement();

  // any dead letters?
  kmailKernel.recoverDeadLetters();

  setSignalHandler(signalHandler);

  kapp->dcopClient()->resume(); // Ok. We are ready for DCOP requests.
  // Go!
  int ret = kapp->exec();

  // clean up
  kmailKernel.cleanup();
  return ret;
}

<commit_msg>In Help->About KMail->Authors, give back their umlauts to poor Michel and Ingo...<commit_after>// KMail startup and initialize code
// Author: Stefan Taferner <taferner@alpin.or.at>

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

#include <kuniqueapplication.h>
#include <klocale.h>
#include <kglobal.h>
#include <dcopclient.h>
#include <kcrash.h>

#include "kmkernel.h" //control center

#undef Status // stupid X headers
#include "kmailIface_stub.h" // to call control center of master kmail

#include <kaboutdata.h>

#include "kmversion.h"

// OLD about text.  This is horrbly outdated.
/*const char* aboutText =
    "KMail [" KMAIL_VERSION "] by\n\n"
    "Stefan Taferner <taferner@kde.org>,\n"
    "Markus Wbben <markus.wuebben@kde.org>\n\n"
    "based on the work of:\n"
    "Lynx <lynx@topaz.hknet.com>,\n"
    "Stephan Meyer <Stephan.Meyer@pobox.com>,\n"
    "and the above authors.\n\n"
    "This program is covered by the GPL.\n\n"
    "Please send bugreports to taferner@kde.org";
*/

static KCmdLineOptions kmoptions[] =
{
  { "s", 0 , 0 },
  { "subject <subject>",	I18N_NOOP("Set subject of msg."), 0 },
  { "c", 0 , 0 },
  { "cc <address>",		I18N_NOOP("Send CC: to 'address'."), 0 },
  { "b", 0 , 0 },
  { "bcc <address>",		I18N_NOOP("Send BCC: to 'addres'."), 0 },
  { "h", 0 , 0 },
  { "header <header>",		I18N_NOOP("Add 'header' to msg."), 0 },
  { "msg <file>",		I18N_NOOP("Read msg-body from 'file'."), 0 },
  { "body <text>",              I18N_NOOP("Set body of msg."), 0 },
  { "attach <url>",             I18N_NOOP("Add an attachment to the mail, this can be repeated"), 0 },
  { "check",			I18N_NOOP("Check for new mail only."), 0 },
  { "composer",			I18N_NOOP("Open only composer window."), 0 },
  { "+[address]",		I18N_NOOP("Send msg to 'address'."), 0 },
//  { "+[file]",                  I18N_NOOP("Show message from file 'file'."), 0 },
  { 0, 0, 0}
};

//-----------------------------------------------------------------------------

extern "C" {

static void setSignalHandler(void (*handler)(int));

// Crash recovery signal handler
static void signalHandler(int sigId)
{
  setSignalHandler(SIG_DFL);
  fprintf(stderr, "*** KMail got signal %d (Exiting)\n", sigId);
  // try to cleanup all windows
  kernel->dumpDeadLetters();
  ::exit(-1); //
}

// Crash recovery signal handler
static void crashHandler(int sigId)
{
  setSignalHandler(SIG_DFL);
  fprintf(stderr, "*** KMail got signal %d (Crashing)\n", sigId);
  // try to cleanup all windows
  kernel->dumpDeadLetters();
  // Return to DrKonqi.
}
//-----------------------------------------------------------------------------

static void setSignalHandler(void (*handler)(int))
{
  signal(SIGKILL, handler);
  signal(SIGTERM, handler);
  signal(SIGHUP,  handler);
  KCrash::setEmergencySaveFunction(crashHandler);
}

}
//-----------------------------------------------------------------------------

class KMailApplication : public KUniqueApplication
{
public:
  KMailApplication() : KUniqueApplication() { };

  virtual int newInstance();

  void commitData(QSessionManager& sm) {
    kernel->notClosedByUser();
    KApplication::commitData( sm );
  }
};

int KMailApplication::newInstance()
{
  QString to, cc, bcc, subj, body;
  KURL messageFile = QString::null;
  KURL::List attachURLs;
  bool mailto = false;
  bool checkMail = false;
  //bool viewOnly = false;

  // process args:
  KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
  if (args->getOption("subject"))
  {
     mailto = true;
     subj = QString::fromLocal8Bit(args->getOption("subject"));
  }

  if (args->getOption("cc"))
  {
     mailto = true;
     cc = QString::fromLocal8Bit(args->getOption("cc"));
  }

  if (args->getOption("bcc"))
  {
     mailto = true;
     bcc = QString::fromLocal8Bit(args->getOption("bcc"));
  }

  if (args->getOption("msg"))
  {
     mailto = true;
     messageFile = QString::fromLocal8Bit(args->getOption("msg"));
  }

  if (args->getOption("body"))
  {
     mailto = true;
     body = QString::fromLocal8Bit(args->getOption("body"));
  }

  QCStringList attachList = args->getOptionList("attach");
  if (!attachList.isEmpty())
  {
     mailto = true;
     for ( QCStringList::Iterator it = attachList.begin() ; it != attachList.end() ; ++it )
         attachURLs += KURL( QString::fromLocal8Bit( *it ) );
  }

  if (args->isSet("composer"))
    mailto = true;

  if (args->isSet("check"))
    checkMail = true;

  for(int i= 0; i < args->count(); i++)
  {
    if (!to.isEmpty())
      to += ", ";
     if (strncasecmp(args->arg(i),"mailto:",7)==0)
       to += args->arg(i);
     else
       to += args->arg(i);
     mailto = true;
  }

  args->clear();

  kernel->action (mailto, checkMail, to, cc, bcc, subj, body, messageFile, attachURLs);
  return 0;
}

int main(int argc, char *argv[])
{
  // WABA: KMail is a KUniqueApplication. Unfortunately this makes debugging
  // a bit harder: You should pass --nofork as commandline argument when using
  // a debugger. In gdb you can do this by typing "set args --nofork" before
  // typing "run".

  KAboutData about("kmail", I18N_NOOP("KMail"),
                   KMAIL_VERSION,
		   I18N_NOOP("The KDE E-Mail client."),
		   KAboutData::License_GPL,
                   I18N_NOOP("(c) 1997-2001, The KMail developers"),
		   0,
		   "http://kmail.kde.org");
  about.addAuthor( "Michael H\303\244ckel", I18N_NOOP("Current maintainer"), "michael@haeckel.net" );
  about.addAuthor( "Don Sanders", I18N_NOOP("Current maintainer"), "sanders@kde.org" );
  about.addAuthor( "Stefan Taferner ", 0, "taferner@kde.org" );
  about.addAuthor( "Daniel Naber", I18N_NOOP("Documentation"), "daniel.naber@t-online.de" );
  about.addAuthor( "Andreas Gungl", I18N_NOOP("Encryption"), "a.gungl@gmx.de" );
  about.addAuthor( "Toyohiro Asukai", 0, "toyohiro@ksmplus.com" );
  about.addAuthor( "Waldo Bastian", 0, "bastian@kde.org" );
  about.addAuthor( "Steven Brown", 0, "swbrown@ucsd.edu" );
  about.addAuthor( "Cristi Dumitrescu", 0, "cristid@chip.ro" );
  about.addAuthor( "Philippe Fremy", 0, "pfremy@chez.com" );
  about.addAuthor( "Kurt Granroth", 0, "granroth@kde.org" );
  about.addAuthor( "Igor Janssen", 0, "rm@linux.ru.net" );
  about.addAuthor( "Matt Johnston", 0, "matt@caifex.org" );
  about.addAuthor( "Christer Kaivo-oja", 0, "whizkid@telia.com" );
  about.addAuthor( "Ingo Kl\303\266cker", 0, "ingo.kloecker@epost.de" );
  about.addAuthor( "Lars Knoll", 0, "knoll@kde.org" );
  about.addAuthor( "J. Nick Koston", 0, "bdraco@darkorb.net" );
  about.addAuthor( "Stephan Kulow", 0, "coolo@kde.org" );
  about.addAuthor( "Guillaume Laurent", 0, "glaurent@telegraph-road.org" );
  about.addAuthor( "Sam Magnuson", 0, "sam@trolltech.com" );
  about.addAuthor( "Laurent Montel", 0, "lmontel@mandrakesoft.com" );
  about.addAuthor( "Marc Mutz", 0, "mutz@kde.org" );
  about.addAuthor( "Matt Newell", 0, "newellm@proaxis.com" );
  about.addAuthor( "Denis Perchine", 0, "dyp@perchine.com" );
  about.addAuthor( "Carsten Pfeiffer", 0, "pfeiffer@kde.org" );
  about.addAuthor( "Sven Radej", 0, "radej@kde.org" );
  about.addAuthor( "Mark Roberts", 0, "mark@taurine.demon.co.uk" );
  about.addAuthor( "Wolfgang Rohdewald", 0, "WRohdewald@dplanet.ch" );
  about.addAuthor( "Espen Sand", 0, "espen@kde.org" );
  about.addAuthor( "George Staikos", 0, "staikos@kde.org" );
  about.addAuthor( "Jason Stephenson", 0, "panda@mis.net" );
  about.addAuthor( "Jacek Stolarczyk", 0, "jacek@mer.chemia.polsl.gliwice.pl" );
  about.addAuthor( "Roberto S. Teixeira", 0, "maragato@kde.org" );
  about.addAuthor( "Mario Weilguni", 0, "mweilguni@sime.com" );
  about.addAuthor( "Wynn Wilkes", 0, "wynnw@calderasystems.com" );
  about.addAuthor( "Robert D. Williams", 0, "rwilliams@kde.org" );
  about.addAuthor( "Markus Wuebben", 0, "markus.wuebben@kde.org" );
  about.addAuthor( "Karl-Heinz Zimmer", 0, "khz@kde.org" );

  KCmdLineArgs::init(argc, argv, &about);
  KCmdLineArgs::addCmdLineOptions( kmoptions ); // Add kmail options

  if (!KMailApplication::start())
     return 0;

  KMailApplication app;
  KGlobal::locale()->insertCatalogue("libkdenetwork");

  kapp->dcopClient()->suspend(); // Don't handle DCOP requests yet

  //local, do the init
  KMKernel kmailKernel;
  kmailKernel.init();
  kapp->dcopClient()->setDefaultObject( kmailKernel.objId() );

  // and session management
  kmailKernel.doSessionManagement();

  // any dead letters?
  kmailKernel.recoverDeadLetters();

  setSignalHandler(signalHandler);

  kapp->dcopClient()->resume(); // Ok. We are ready for DCOP requests.
  // Go!
  int ret = kapp->exec();

  // clean up
  kmailKernel.cleanup();
  return ret;
}

<|endoftext|>


<commit_before>#include "DELTAPAK_S.H"

#include "DELTAPAK.H"
#include "DRAW.H"
#include "MATHS.H"
#include "SETUP.H"
#include "SPECIFIC.H"

void DrawCutSeqActors()//90DCC(<),
{
	struct NEW_CUTSCENE* cut;//$s3

	cut = &GLOBAL_cutme[0];
	//a0 = meshes
	//v0 = cut->numactors
	//s6 = 1

	if (1 < cut->numactors)
	{
		mPushMatrix();

		//loc_90E1C
		mPushMatrix();

		//v1 = 1 << 2
		//s7 = cutseq_meshbits[1];//$v1 shft
		//fp = cutseq_meshswapbits[1];//$v1 shft
		//v0 = 0x80000000 & cutseq_meshbits[1];

		if (0x80000000 & cutseq_meshbits[1])
		{
			//v0 = &actor_pnodes[1];//$v1 shft

			//v1 = 1 << 3
			//v1 = &cut[2];
			sizeof(struct NEW_CUTSCENE);
		}//loc_90FDC
	}//loc_91000

#if 0
addu    $v1, $s3, $v1
lh      $a1, 0x1E($v1)
lw      $a0, 0($v0)
li      $a2, 0xA60FC
jal     sub_91030
addiu   $a1, 1
sll     $v1, $s6, 3
addu    $v1, $s3, $v1
lh      $v1, 0x1C($v1)
lw      $a0, 4($s3)
lw      $a1, 8($s3)
lw      $a2, 0xC($s3)
li      $v0, 0x1F2480
sll     $v1, 6
jal     sub_76568
addu    $s4, $v1, $v0
jal     sub_91110
nop
lh      $v0, 2($s4)
lw      $v1, 4($s4)
sll     $v0, 2
addu    $s1, $s0, $v0
lw      $v0, 0x2030($gp)
sll     $v1, 2
li      $a2, 0xA60FC
lh      $a0, 0xC($a2)
lh      $a1, 0xE($a2)
lh      $a2, 0x10($a2)
jal     sub_7658C
addu    $s2, $v0, $v1
addiu   $a0, $sp, 0x48+var_38
move    $a1, $zero
li      $v0, 0xA610E
jal     sub_768BC
sw      $v0, 0x48+var_38($sp)
andi    $v0, $s7, 1
beqz    $v0, loc_90F3C
andi    $v0, $fp, 1
beqz    $v0, loc_90F1C
lw      $a0, 0($s1)
lw      $a0, 4($s1)

loc_90F1C:
addiu   $at, $s6, -1
bnez    $at, loc_90F34
nop
lw      $a1, 0x410($gp)
jal     sub_7FAD4
addiu   $ra, 8

loc_90F34:
jal     sub_7EEC4
li      $a1, 0xFFFFFFFF

loc_90F3C:
lh      $s4, 0($s4)
li      $s5, 1
addiu   $s4, -1
blez    $s4, loc_90FDC
addiu   $s1, 8

loc_90F50:
lw      $a1, 0($s2)
addiu   $s4, -1
andi    $v0, $a1, 1
beqz    $v0, loc_90F6C
andi    $a1, 2
jal     sub_76520
nop

loc_90F6C:
beqz    $a1, loc_90F7C
sll     $s5, 1
jal     sub_764D0
nop

loc_90F7C:
lw      $a0, 4($s2)
lw      $a1, 8($s2)
jal     sub_7658C
lw      $a2, 0xC($s2)
addiu   $a0, $sp, 0x48+var_38
jal     sub_768BC
move    $a1, $zero
and     $v0, $s5, $s7
beqz    $v0, loc_90FD0
and     $v0, $s5, $fp
beqz    $v0, loc_90FB0
lw      $a0, 0($s1)
lw      $a0, 4($s1)

loc_90FB0:
addiu   $at, $s6, -1
bnez    $at, loc_90FC8
nop
lw      $a1, 0x410($gp)
jal     sub_7FAD4
addiu   $ra, 8

loc_90FC8:
jal     sub_7EEC4
li      $a1, 0xFFFFFFFF

loc_90FD0:
addiu   $s2, 0x10
bnez    $s4, loc_90F50
addiu   $s1, 8

loc_90FDC:
jal     sub_76520
nop
lh      $v1, 0($s3)
addiu   $s6, 1
slt     $v1, $s6, $v1
bnez    $v1, loc_90E1C
nop
jal     sub_76520
nop

loc_91000:
lw      $ra, 0x48+var_4($sp)
lw      $fp, 0x48+var_8($sp)
lw      $s7, 0x48+var_C($sp)
lw      $s6, 0x48+var_10($sp)
lw      $s5, 0x48+var_14($sp)
lw      $s4, 0x48+var_18($sp)
lw      $s3, 0x48+var_1C($sp)
lw      $s2, 0x48+var_20($sp)
lw      $s1, 0x48+var_24($sp)
lw      $s0, 0x48+var_28($sp)
jr      $ra
addiu   $sp, 0x48
#endif
}

void updateAnimFrame(struct PACKNODE* node, int flags, short* frame)// (F)
{
	frame[7] = 3 * node->yrot_run;

	short x = 3 * node->xrot_run;
	short z = 3 * node->zrot_run;

	switch (cutrot)
	{
	case 0:
		frame[6] = x;
		frame[8] = z;
		break;
	case 1:
		frame[6] = z;
		frame[8] = -x;
		break;
	case 2:
		frame[6] = -x;
		frame[8] = -z;
		break;
	case 3:
		frame[6] = -z;
		frame[8] = x;
		break;
	}

	short* next = frame + 9;

	for (int i = 1; i < flags; i++, next += 2)
	{
		short x = node[i].yrot_run;
		short y = node[i].zrot_run;
		short z = node[i].xrot_run;

		if (cutrot && i == 1)
		{
			x = (x + ((short)cutrot << 8)) & 0x3FF;
		}

		next[0] = (y | ((x | (z << 10)) << 10)) >> 16;
		next[1] = y | ((x | (z << 10)) << 10);
	}
}

int GetTrackWord(unsigned long off, char* packed, unsigned char packmethod)
{
	int a0 = off * packmethod;
	int v0 = a0 >> 3;
	packed = &packed[v0];
	a0 &= 7;
	unsigned int at = ((unsigned char*)packed)[0] | (((unsigned char*)packed)[1] << 8) | (((unsigned char*)packed)[2] << 16) | (((unsigned char*)packed)[3] << 24);
	at = at >> a0;
	unsigned int v1 = (1 << packmethod) - 1;
	at &= v1;
	packmethod -= 1;
	v0 = (1 << packmethod);
	v0 = at & v0;

	if (v0 != 0)
	{
		v0 = v1 ^ -1;///@CHECKME nor     $v0, $zero, $v1
		at |= v0;
	}
	else
	{
		v0 = v1 ^ -1;///@CHECKME nor     $v0, $zero, $v1
	}
	//loc_90DC0
	v0 = at << 16;
	v0 >>= 16;

	return v0;
}

int DecodeTrack(char* packed, struct RTDECODE* decode)//90BD8(<), ?
{
	int t0 = 0;
	int v0 = 0;

	if (decode->decodetype == 0)
	{
		t0 = GetTrackWord(decode->off, packed, decode->packmethod);

		if (!(t0 & 0x20))
		{
			decode->decodetype = 2;

			if ((t0 & 0x10))
			{
				GetTrackWord(decode->off + 1, packed, decode->packmethod);
				decode->counter = ((t0 & 7) << 5) | (GetTrackWord(decode->off + 1, packed, decode->packmethod) & 0x1F);
				decode->data = GetTrackWord(decode->off + 2, packed, decode->packmethod);
				decode->off += 3;
				decode->length -= 3;
			}
			else
			{
				//loc_90C70
				decode->data = GetTrackWord(decode->off + 1, packed, decode->packmethod);
				decode->counter = t0 & 0x7;
				decode->off += 2;
				decode->length -= 2;
			}
		}
		else
		{
			//loc_90CA0
			if (!(t0 & 0xF))
			{
				decode->counter = 16;
			}
			else
			{
				decode->counter = (t0 & 0xF);
			}

			//loc_90CAC
			decode->decodetype = 1;
			decode->off += 1;
			decode->length -= 1;
		}
	}
	//loc_90CD0
	if (decode->decodetype == 2)
	{
		if (--decode->counter == 0)
		{
			decode->decodetype = 0;
		}

		//loc_90CFC
		return decode->data;
	}

	//loc_90D08
	v0 = GetTrackWord(decode->off, packed, decode->packmethod);

	decode->counter -= 1;
	decode->off += 1;
	decode->length -= 1;

	if (!(decode->counter & 0xFFFF))
	{
		decode->decodetype = 0;
	}
	//loc_90D48
	v0 <<= 16;
	v0 >>= 16;

	return v0;
}

void DecodeAnim(struct PACKNODE* node, int a1, int frame, short a3)//90A88(<), ?
{
	int t4 = 0;

	if (frame == 0)
	{
		t4 = 0;
		if (a1 > 0)
		{
			//loc_90AA8
			do
			{
				t4++;

				node->decode_x.off = 0;
				node->decode_x.counter = 0;
				node->decode_x.data = 0;
				node->decode_x.decodetype = 0;

				node->decode_y.off = 0;
				node->decode_y.counter = 0;
				node->decode_y.data = 0;
				node->decode_y.decodetype = 0;

				node->decode_z.off = 0;
				node->decode_z.counter = 0;
				node->decode_z.data = 0;
				node->decode_z.decodetype = 0;

				node->xrot_run = (unsigned short)node->xkey;
				node->yrot_run = (unsigned short)node->ykey;
				node->zrot_run = (unsigned short)node->zkey;

				node->decode_x.length = node->xlength;
				node->decode_y.length = node->ylength;
				node->decode_z.length = node->zlength;
				node++;
			} while (t4 < a1);
		}
		//loc_90BD0
		return;
	}
	else
	{
		//loc_90B14
		node->xrot_run += DecodeTrack(node->xpacked, &node->decode_x);
		node->yrot_run += DecodeTrack(node->ypacked, &node->decode_y);
		node->zrot_run += DecodeTrack(node->zpacked, &node->decode_z);
		t4 = 1;
		node++;
		if (t4 >= a1)
		{
			return;
		}
	}

	//loc_90B6C
	do
	{
		node->xrot_run += DecodeTrack(node->xpacked, &node->decode_x) & a3;
		node->yrot_run += DecodeTrack(node->ypacked, &node->decode_y) & a3;
		node->zrot_run += DecodeTrack(node->zpacked, &node->decode_z) & a3;
		t4++;
		node++;
	} while (t4 < a1);
}
<commit_msg>[Specific-PSXPC_N] Fix updateAnimFrame.<commit_after>#include "DELTAPAK_S.H"

#include "DELTAPAK.H"
#include "DRAW.H"
#include "MATHS.H"
#include "SETUP.H"
#include "SPECIFIC.H"

void DrawCutSeqActors()//90DCC(<),
{
	struct NEW_CUTSCENE* cut;//$s3

	cut = &GLOBAL_cutme[0];
	//a0 = meshes
	//v0 = cut->numactors
	//s6 = 1

	if (1 < cut->numactors)
	{
		mPushMatrix();

		//loc_90E1C
		mPushMatrix();

		//v1 = 1 << 2
		//s7 = cutseq_meshbits[1];//$v1 shft
		//fp = cutseq_meshswapbits[1];//$v1 shft
		//v0 = 0x80000000 & cutseq_meshbits[1];

		if (0x80000000 & cutseq_meshbits[1])
		{
			//v0 = &actor_pnodes[1];//$v1 shft

			//v1 = 1 << 3
			//v1 = &cut[2];
			sizeof(struct NEW_CUTSCENE);
		}//loc_90FDC
	}//loc_91000

#if 0
addu    $v1, $s3, $v1
lh      $a1, 0x1E($v1)
lw      $a0, 0($v0)
li      $a2, 0xA60FC
jal     sub_91030
addiu   $a1, 1
sll     $v1, $s6, 3
addu    $v1, $s3, $v1
lh      $v1, 0x1C($v1)
lw      $a0, 4($s3)
lw      $a1, 8($s3)
lw      $a2, 0xC($s3)
li      $v0, 0x1F2480
sll     $v1, 6
jal     sub_76568
addu    $s4, $v1, $v0
jal     sub_91110
nop
lh      $v0, 2($s4)
lw      $v1, 4($s4)
sll     $v0, 2
addu    $s1, $s0, $v0
lw      $v0, 0x2030($gp)
sll     $v1, 2
li      $a2, 0xA60FC
lh      $a0, 0xC($a2)
lh      $a1, 0xE($a2)
lh      $a2, 0x10($a2)
jal     sub_7658C
addu    $s2, $v0, $v1
addiu   $a0, $sp, 0x48+var_38
move    $a1, $zero
li      $v0, 0xA610E
jal     sub_768BC
sw      $v0, 0x48+var_38($sp)
andi    $v0, $s7, 1
beqz    $v0, loc_90F3C
andi    $v0, $fp, 1
beqz    $v0, loc_90F1C
lw      $a0, 0($s1)
lw      $a0, 4($s1)

loc_90F1C:
addiu   $at, $s6, -1
bnez    $at, loc_90F34
nop
lw      $a1, 0x410($gp)
jal     sub_7FAD4
addiu   $ra, 8

loc_90F34:
jal     sub_7EEC4
li      $a1, 0xFFFFFFFF

loc_90F3C:
lh      $s4, 0($s4)
li      $s5, 1
addiu   $s4, -1
blez    $s4, loc_90FDC
addiu   $s1, 8

loc_90F50:
lw      $a1, 0($s2)
addiu   $s4, -1
andi    $v0, $a1, 1
beqz    $v0, loc_90F6C
andi    $a1, 2
jal     sub_76520
nop

loc_90F6C:
beqz    $a1, loc_90F7C
sll     $s5, 1
jal     sub_764D0
nop

loc_90F7C:
lw      $a0, 4($s2)
lw      $a1, 8($s2)
jal     sub_7658C
lw      $a2, 0xC($s2)
addiu   $a0, $sp, 0x48+var_38
jal     sub_768BC
move    $a1, $zero
and     $v0, $s5, $s7
beqz    $v0, loc_90FD0
and     $v0, $s5, $fp
beqz    $v0, loc_90FB0
lw      $a0, 0($s1)
lw      $a0, 4($s1)

loc_90FB0:
addiu   $at, $s6, -1
bnez    $at, loc_90FC8
nop
lw      $a1, 0x410($gp)
jal     sub_7FAD4
addiu   $ra, 8

loc_90FC8:
jal     sub_7EEC4
li      $a1, 0xFFFFFFFF

loc_90FD0:
addiu   $s2, 0x10
bnez    $s4, loc_90F50
addiu   $s1, 8

loc_90FDC:
jal     sub_76520
nop
lh      $v1, 0($s3)
addiu   $s6, 1
slt     $v1, $s6, $v1
bnez    $v1, loc_90E1C
nop
jal     sub_76520
nop

loc_91000:
lw      $ra, 0x48+var_4($sp)
lw      $fp, 0x48+var_8($sp)
lw      $s7, 0x48+var_C($sp)
lw      $s6, 0x48+var_10($sp)
lw      $s5, 0x48+var_14($sp)
lw      $s4, 0x48+var_18($sp)
lw      $s3, 0x48+var_1C($sp)
lw      $s2, 0x48+var_20($sp)
lw      $s1, 0x48+var_24($sp)
lw      $s0, 0x48+var_28($sp)
jr      $ra
addiu   $sp, 0x48
#endif
}

void updateAnimFrame(struct PACKNODE* node, int flags, short* frame)//91030(<) (F)
{
	int at = 0;
	int v1 = 0;
	int v0 = 0;
	int a0 = 0;
	int t0 = 0;
	short* a3 = NULL;
	struct PACKNODE* a2 = NULL;

	frame[7] = (node->yrot_run << 1) + node->yrot_run;

	if (cutrot == 0)
	{
		//loc_91098
		frame[6] = (node->xrot_run << 1) + node->xrot_run;
		frame[8] = (node->zrot_run << 1) + node->zrot_run;
	}
	else if (cutrot - 1 == 0)
	{
		//loc_91088
		frame[6] = (node->zrot_run << 1) + node->zrot_run;
		frame[8] = -((node->xrot_run << 1) + node->xrot_run);
	}
	else if (cutrot - 2 == 0)
	{
		//loc_91080
		frame[6] = -((node->xrot_run << 1) + node->xrot_run);
		frame[8] = -((node->zrot_run << 1) + node->zrot_run);
	}
	else
	{
		frame[8] = (node->xrot_run << 1) + node->xrot_run;
		frame[6] = -((node->zrot_run << 1) + node->zrot_run);
	}

	//loc_910A0
	if (1 < flags)
	{
		a3 = &frames[9];
		a2 = &node[1];
		t0 = flags - 1;
		at = 1;

		//loc_910BC
		do
		{
			v1 = a2->xrot_run;
			v0 = a2->yrot_run;
			a0 = a2->zrot_run;

			a2++;
			if (at)
			{
				v0 += cutrot << 8;
				v0 &= 0x3FF;
			}//loc_910E0

			t0--;
			v1 <<= 20;
			v0 <<= 10;
			v1 |= v0;
			v1 |= a0;
			v0 = v1 >> 16;
			a3[0] = v0;
			a3[1] = v1;
			a3 += 2;
		} while (t0 != 0);
	}
	//locret_91108
}

int GetTrackWord(unsigned long off, char* packed, unsigned char packmethod)
{
	int a0 = off * packmethod;
	int v0 = a0 >> 3;
	packed = &packed[v0];
	a0 &= 7;
	unsigned int at = ((unsigned char*)packed)[0] | (((unsigned char*)packed)[1] << 8) | (((unsigned char*)packed)[2] << 16) | (((unsigned char*)packed)[3] << 24);
	at = at >> a0;
	unsigned int v1 = (1 << packmethod) - 1;
	at &= v1;
	packmethod -= 1;
	v0 = (1 << packmethod);
	v0 = at & v0;

	if (v0 != 0)
	{
		v0 = v1 ^ -1;///@CHECKME nor     $v0, $zero, $v1
		at |= v0;
	}
	else
	{
		v0 = v1 ^ -1;///@CHECKME nor     $v0, $zero, $v1
	}
	//loc_90DC0
	v0 = at << 16;
	v0 >>= 16;

	return v0;
}

int DecodeTrack(char* packed, struct RTDECODE* decode)//90BD8(<), ?
{
	int t0 = 0;
	int v0 = 0;

	if (decode->decodetype == 0)
	{
		t0 = GetTrackWord(decode->off, packed, decode->packmethod);

		if (!(t0 & 0x20))
		{
			decode->decodetype = 2;

			if ((t0 & 0x10))
			{
				GetTrackWord(decode->off + 1, packed, decode->packmethod);
				decode->counter = ((t0 & 7) << 5) | (GetTrackWord(decode->off + 1, packed, decode->packmethod) & 0x1F);
				decode->data = GetTrackWord(decode->off + 2, packed, decode->packmethod);
				decode->off += 3;
				decode->length -= 3;
			}
			else
			{
				//loc_90C70
				decode->data = GetTrackWord(decode->off + 1, packed, decode->packmethod);
				decode->counter = t0 & 0x7;
				decode->off += 2;
				decode->length -= 2;
			}
		}
		else
		{
			//loc_90CA0
			if (!(t0 & 0xF))
			{
				decode->counter = 16;
			}
			else
			{
				decode->counter = (t0 & 0xF);
			}

			//loc_90CAC
			decode->decodetype = 1;
			decode->off += 1;
			decode->length -= 1;
		}
	}
	//loc_90CD0
	if (decode->decodetype == 2)
	{
		if (--decode->counter == 0)
		{
			decode->decodetype = 0;
		}

		//loc_90CFC
		return decode->data;
	}

	//loc_90D08
	v0 = GetTrackWord(decode->off, packed, decode->packmethod);

	decode->counter -= 1;
	decode->off += 1;
	decode->length -= 1;

	if (!(decode->counter & 0xFFFF))
	{
		decode->decodetype = 0;
	}
	//loc_90D48
	v0 <<= 16;
	v0 >>= 16;

	return v0;
}

void DecodeAnim(struct PACKNODE* node, int a1, int frame, short a3)//90A88(<), ?
{
	int t4 = 0;

	if (frame == 0)
	{
		t4 = 0;
		if (a1 > 0)
		{
			//loc_90AA8
			do
			{
				t4++;

				node->decode_x.off = 0;
				node->decode_x.counter = 0;
				node->decode_x.data = 0;
				node->decode_x.decodetype = 0;

				node->decode_y.off = 0;
				node->decode_y.counter = 0;
				node->decode_y.data = 0;
				node->decode_y.decodetype = 0;

				node->decode_z.off = 0;
				node->decode_z.counter = 0;
				node->decode_z.data = 0;
				node->decode_z.decodetype = 0;

				node->xrot_run = (unsigned short)node->xkey;
				node->yrot_run = (unsigned short)node->ykey;
				node->zrot_run = (unsigned short)node->zkey;

				node->decode_x.length = node->xlength;
				node->decode_y.length = node->ylength;
				node->decode_z.length = node->zlength;
				node++;
			} while (t4 < a1);
		}
		//loc_90BD0
		return;
	}
	else
	{
		//loc_90B14
		node->xrot_run += DecodeTrack(node->xpacked, &node->decode_x);
		node->yrot_run += DecodeTrack(node->ypacked, &node->decode_y);
		node->zrot_run += DecodeTrack(node->zpacked, &node->decode_z);
		t4 = 1;
		node++;
		if (t4 >= a1)
		{
			return;
		}
	}

	//loc_90B6C
	do
	{
		node->xrot_run += DecodeTrack(node->xpacked, &node->decode_x) & a3;
		node->yrot_run += DecodeTrack(node->ypacked, &node->decode_y) & a3;
		node->zrot_run += DecodeTrack(node->zpacked, &node->decode_z) & a3;
		t4++;
		node++;
	} while (t4 < a1);
}
<|endoftext|>


<commit_before>/*******************************************************************************
* ALMA - Atacama Large Millimiter Array
* (c) European Southern Observatory, 2011
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*
* "@(#) $Id: bulkDataNTSenderFlow.cpp,v 1.5 2011/07/27 13:28:31 bjeram Exp $"
*
* who       when      what
* --------  --------  ----------------------------------------------
* bjeram  2011-04-19  created
*/

#include "bulkDataNTSenderFlow.h"
#include <iostream>

#include <AV/FlowSpec_Entry.h>  // we need it for TAO_Tokenizer ??
#include <ACSBulkDataError.h>   // error definition  ??

static char *rcsId="@(#) $Id: bulkDataNTSenderFlow.cpp,v 1.5 2011/07/27 13:28:31 bjeram Exp $";
static void *use_rcsId = ((void)&use_rcsId,(void *) &rcsId);

using namespace AcsBulkdata;
using namespace std;

BulkDataNTSenderFlow::BulkDataNTSenderFlow(BulkDataNTSenderStream *senderStream, const char* flowName/*, cb*/) :
		senderStream_m(senderStream)
{
	AUTO_TRACE(__PRETTY_FUNCTION__);

	std::string topicName;

	flowName_m = flowName;

	// should be reactor to have just one object for comunication !! DDSDataWriter or similar
	ddsPublisher_m = new BulkDataNTDDSPublisher(senderStream_m->getDDSParticipant());

	topicName = senderStream_m->getName() + "#" + flowName_m;
	ddsTopic_m = ddsPublisher_m->createDDSTopic(topicName.c_str());

	ddsDataWriter_m= ddsPublisher_m->createDDSWriter(ddsTopic_m);

}

BulkDataNTSenderFlow::~BulkDataNTSenderFlow()
{
	AUTO_TRACE(__PRETTY_FUNCTION__);
	senderStream_m->removeFlowFromMap(flowName_m.c_str());

	// this part can go to BulkDataNTDDSPublisher, anyway we need to refactor
	DDS::DomainParticipant *participant = senderStream_m->getDDSParticipant();
	if (participant!=0)
	{
		participant->delete_datawriter(ddsDataWriter_m);
		participant->delete_topic(ddsTopic_m);
	}
	else
	{
		//TBD: error handling
	}
	delete ddsPublisher_m;
}//~BulkDataNTSenderFlow

void BulkDataNTSenderFlow::startSend(ACE_Message_Block *param)
{
 startSend((unsigned char*)(param->rd_ptr()), param->length());
}

void BulkDataNTSenderFlow::startSend(const unsigned char *param, size_t len)
{
	writeFrame(ACSBulkData::BD_PARAM, param, len);
}//startSend

void BulkDataNTSenderFlow::sendData(ACE_Message_Block *buffer)
{
	 sendData((unsigned char*)(buffer->rd_ptr()), buffer->length());
}//sendData

void BulkDataNTSenderFlow::sendData(const unsigned char *buffer, size_t len)
{
	DDS::ReturnCode_t ret;
// RTI	DDS_ReliableWriterCacheChangedStatus status;
	DDS::InstanceHandle_t handle = DDS::HANDLE_NIL;

	//ACSBulkData::BulkDataNTFrame *frame;
	unsigned int sizeOfFrame = ACSBulkData::FRAME_MAX_LEN;  //TBD: tmp should be configurable

	unsigned int numOfFrames = len / sizeOfFrame; // how many frames of size sizeOfDataChunk do we have to send
	unsigned int restFrameSize = len % sizeOfFrame; // what rests ?

	// should we wait for all ACKs? timeout should be configurable
	DDS::Duration_t ack_timeout_delay = {1, 0};//1s

	//TBD  RTI do we have to create the frame each time or  just once in the constructor ... ?
	 frame =  ACSBulkData::BulkDataNTFrameTypeSupport::create_data();
	if (frame == NULL) {
		printf("BD_DDS::BDdataMessageTypeSupport::create_data error - frame null\n");
		// delete
	//TBD:: error handling
	}

	frame->dataType = ACSBulkData::BD_DATA;  //we are going to send data
	frame->data.length(sizeOfFrame); // frame.data.resize(sizeOfFrame);; // do we actually need resize ?

	std::cout <<  " Going to send: " << len << " Bytes";
	std::cout << " = (" << numOfFrames << " times chunks of size: " << sizeOfFrame << " bytes => ";
	std::cout << numOfFrames*sizeOfFrame << "Bytes ) + " <<  restFrameSize << " Bytes"<< std::endl;

//	start_time = ACE_OS::gettimeofday();

	unsigned int numOfIter = (restFrameSize>0) ? numOfFrames+1 : numOfFrames;

	for(unsigned int i=0; i<numOfIter; i++)
	{
		if (i==(numOfIter-1) && restFrameSize>0)
		{
			// last frame
			frame->data.length(sizeOfFrame); //frame.data.resize(restFrameSize);
			frame->data.from_array((buffer+(i*sizeOfFrame)), restFrameSize);
			//std::copy ((buffer+(i*sizeOfFrame)), (buffer+(i*sizeOfFrame)+restFrameSize), frame.data.begin() );
		}else
		{
			frame->data.from_array((buffer+(i*sizeOfFrame)), sizeOfFrame);
			//std::copy ((buffer+(i*sizeOfFrame)), (buffer+(i*sizeOfFrame)+sizeOfFrame), frame.data.begin() );
		}

		frame->restDataLength = numOfIter-1-i;

		ret = ddsDataWriter_m->write(*frame, handle);
		if( ret != DDS::RETCODE_OK) {

// RTI			senderFlows_m[flownumber].dataWriter->get_reliable_writer_cache_changed_status(status);

			if (ret==DDS::RETCODE_TIMEOUT)
			{
				std::cerr << "Timeout while sending " <<  i << " data" << std::endl;
			}else
			{
				std::cerr << "Failed to send " <<  i << " data return code: " << ret << std::endl;
			}

/* RTI			cout << "\t\t Int unacknowledged_sample_count: " << status.unacknowledged_sample_count;
			cout << "\t\t Int unacknowledged_sample_count_peak: " << status.unacknowledged_sample_count_peak << endl;
*/
			ret = ddsDataWriter_m->wait_for_acknowledgments(ack_timeout_delay);
							if( ret != DDS::RETCODE_OK) {
								std::cerr << " !Failed while waiting for acknowledgment of "
										<< "data being received by subscriptions, some data "
										<< "may not have been delivered." << std::endl;
							}//if

/* RTI			cout << "\t\t Int1 unacknowledged_sample_count: " << status.unacknowledged_sample_count;
			cout << "\t\t Int1 unacknowledged_sample_count_peak: " << status.unacknowledged_sample_count_peak << endl;
			*/
		}//if
	}//for

// do we need to wait for ACK after each frame is sent or at the edn or not at all, configurable ?
	ret = ddsDataWriter_m->wait_for_acknowledgments(ack_timeout_delay);
	if( ret != DDS::RETCODE_OK) {
		std::cerr << " !Failed while waiting for acknowledgment of "
				<< "data being received by subscriptions, some data "
				<< "may not have been delivered." << std::endl;
	}//if

}//sendData

void BulkDataNTSenderFlow::stopSend()
{
	writeFrame(ACSBulkData::BD_STOP);
}//stopSend

void BulkDataNTSenderFlow::writeFrame(ACSBulkData::DataType dataType,  const unsigned char *param, size_t len)
{

	DDS::ReturnCode_t ret;
	DDS::InstanceHandle_t handle = DDS::HANDLE_NIL;
	//ACSBulkData::BulkDataNTFrame *frame;

	if (len>ACSBulkData::FRAME_MAX_LEN){
		printf("parameter too long !!\n");
		// delete
		//TBD:: error handling
	}

	//RTI do we have to create the frame each time or ... ?
	frame = ACSBulkData::BulkDataNTFrameTypeSupport::create_data();
	if (frame == NULL) {
		printf("BD_DDS::BDdataMessageTypeSupport::create_data error - frame null\n");
		// delete
		//TBD:: error handling
	}

	//frame
	frame->dataType = dataType;
	frame->data./*resize*/length(len);
	if (param!=0 && len!=0)
		frame->data.from_array(param, len); //frame.data.assign(len, *param);   //1st parameter  is of type const unsigned char !!

	ret = ddsDataWriter_m->write(*frame, handle);
	if( ret != DDS::RETCODE_OK)
	{
		//TBD EH  special for timeout
		std::cerr << "Failed to send parameter. Return code: " << ret << std::endl;
	}//if

	// should we wait for all ACKs? timeout should be configurable
	DDS::Duration_t ack_timeout_delay = {1, 0};//1s
	ret = ddsDataWriter_m->wait_for_acknowledgments(ack_timeout_delay);
	if( ret != DDS::RETCODE_OK) {
		std::cerr << " !Failed while waiting for acknowledgment of "
				<< "data being received by subscriptions, some data "
				<< "may not have been delivered." << std::endl;
		//TBD error handling
	}//if

}//writeFrame

/*___oOo___*/
<commit_msg>replaces stdout with ACS log<commit_after>/*******************************************************************************
* ALMA - Atacama Large Millimiter Array
* (c) European Southern Observatory, 2011
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*
* "@(#) $Id: bulkDataNTSenderFlow.cpp,v 1.6 2011/07/27 14:42:28 bjeram Exp $"
*
* who       when      what
* --------  --------  ----------------------------------------------
* bjeram  2011-04-19  created
*/

#include "bulkDataNTSenderFlow.h"
#include <iostream>

#include <AV/FlowSpec_Entry.h>  // we need it for TAO_Tokenizer ??
#include <ACSBulkDataError.h>   // error definition  ??

static char *rcsId="@(#) $Id: bulkDataNTSenderFlow.cpp,v 1.6 2011/07/27 14:42:28 bjeram Exp $";
static void *use_rcsId = ((void)&use_rcsId,(void *) &rcsId);

using namespace AcsBulkdata;
using namespace std;

BulkDataNTSenderFlow::BulkDataNTSenderFlow(BulkDataNTSenderStream *senderStream, const char* flowName/*, cb*/) :
		senderStream_m(senderStream)
{
	AUTO_TRACE(__PRETTY_FUNCTION__);

	std::string topicName;

	flowName_m = flowName;

	// should be reactor to have just one object for comunication !! DDSDataWriter or similar
	ddsPublisher_m = new BulkDataNTDDSPublisher(senderStream_m->getDDSParticipant());

	topicName = senderStream_m->getName() + "#" + flowName_m;
	ddsTopic_m = ddsPublisher_m->createDDSTopic(topicName.c_str());

	ddsDataWriter_m= ddsPublisher_m->createDDSWriter(ddsTopic_m);
}

BulkDataNTSenderFlow::~BulkDataNTSenderFlow()
{
	AUTO_TRACE(__PRETTY_FUNCTION__);

	senderStream_m->removeFlowFromMap(flowName_m.c_str());

	// this part can go to BulkDataNTDDSPublisher, anyway we need to refactor
	DDS::DomainParticipant *participant = senderStream_m->getDDSParticipant();
	if (participant!=0)
	{
		participant->delete_datawriter(ddsDataWriter_m);
		participant->delete_topic(ddsTopic_m);
	}
	else
	{
		//TBD: error handling
	}
	delete ddsPublisher_m;
}//~BulkDataNTSenderFlow

void BulkDataNTSenderFlow::startSend(ACE_Message_Block *param)
{
 startSend((unsigned char*)(param->rd_ptr()), param->length());
}

void BulkDataNTSenderFlow::startSend(const unsigned char *param, size_t len)
{
	writeFrame(ACSBulkData::BD_PARAM, param, len);
}//startSend

void BulkDataNTSenderFlow::sendData(ACE_Message_Block *buffer)
{
	 sendData((unsigned char*)(buffer->rd_ptr()), buffer->length());
}//sendData

void BulkDataNTSenderFlow::sendData(const unsigned char *buffer, size_t len)
{
	DDS::ReturnCode_t ret;
// RTI	DDS_ReliableWriterCacheChangedStatus status;
	DDS::InstanceHandle_t handle = DDS::HANDLE_NIL;

	//ACSBulkData::BulkDataNTFrame *frame;
	unsigned int sizeOfFrame = ACSBulkData::FRAME_MAX_LEN;  //TBD: tmp should be configurable

	unsigned int numOfFrames = len / sizeOfFrame; // how many frames of size sizeOfDataChunk do we have to send
	unsigned int restFrameSize = len % sizeOfFrame; // what rests ?

	// should we wait for all ACKs? timeout should be configurable
	DDS::Duration_t ack_timeout_delay = {1, 0};//1s

	//TBD  RTI do we have to create the frame each time or  just once in the constructor ... ?
	 frame =  ACSBulkData::BulkDataNTFrameTypeSupport::create_data();
	if (frame == NULL) {
		printf("BD_DDS::BDdataMessageTypeSupport::create_data error - frame null\n");
		// delete
	//TBD:: error handling
	}

	frame->dataType = ACSBulkData::BD_DATA;  //we are going to send data
	frame->data.length(sizeOfFrame); // frame.data.resize(sizeOfFrame);; // do we actually need resize ?

	ACS_SHORT_LOG((LM_DEBUG, "Going to send: %d Bytes = %d*%d(=%d) + %d",
			len, numOfFrames, sizeOfFrame, numOfFrames*sizeOfFrame, restFrameSize));

//	start_time = ACE_OS::gettimeofday();

	unsigned int numOfIter = (restFrameSize>0) ? numOfFrames+1 : numOfFrames;

	for(unsigned int i=0; i<numOfIter; i++)
	{
		if (i==(numOfIter-1) && restFrameSize>0)
		{
			// last frame
			frame->data.length(sizeOfFrame); //frame.data.resize(restFrameSize);
			frame->data.from_array((buffer+(i*sizeOfFrame)), restFrameSize);
			//std::copy ((buffer+(i*sizeOfFrame)), (buffer+(i*sizeOfFrame)+restFrameSize), frame.data.begin() );
		}else
		{
			frame->data.from_array((buffer+(i*sizeOfFrame)), sizeOfFrame);
			//std::copy ((buffer+(i*sizeOfFrame)), (buffer+(i*sizeOfFrame)+sizeOfFrame), frame.data.begin() );
		}

		frame->restDataLength = numOfIter-1-i;

		ret = ddsDataWriter_m->write(*frame, handle);
		if( ret != DDS::RETCODE_OK) {

// RTI			senderFlows_m[flownumber].dataWriter->get_reliable_writer_cache_changed_status(status);

			if (ret==DDS::RETCODE_TIMEOUT)
			{
				std::cerr << "Timeout while sending " <<  i << " data" << std::endl;
			}else
			{
				std::cerr << "Failed to send " <<  i << " data return code: " << ret << std::endl;
			}

/* RTI			cout << "\t\t Int unacknowledged_sample_count: " << status.unacknowledged_sample_count;
			cout << "\t\t Int unacknowledged_sample_count_peak: " << status.unacknowledged_sample_count_peak << endl;
*/
			ret = ddsDataWriter_m->wait_for_acknowledgments(ack_timeout_delay);
							if( ret != DDS::RETCODE_OK) {
								std::cerr << " !Failed while waiting for acknowledgment of "
										<< "data being received by subscriptions, some data "
										<< "may not have been delivered." << std::endl;
							}//if

/* RTI			cout << "\t\t Int1 unacknowledged_sample_count: " << status.unacknowledged_sample_count;
			cout << "\t\t Int1 unacknowledged_sample_count_peak: " << status.unacknowledged_sample_count_peak << endl;
			*/
		}//if
	}//for

// do we need to wait for ACK after each frame is sent or at the edn or not at all, configurable ?
	ret = ddsDataWriter_m->wait_for_acknowledgments(ack_timeout_delay);
	if( ret != DDS::RETCODE_OK) {
		std::cerr << " !Failed while waiting for acknowledgment of "
				<< "data being received by subscriptions, some data "
				<< "may not have been delivered." << std::endl;
	}//if

}//sendData

void BulkDataNTSenderFlow::stopSend()
{
	writeFrame(ACSBulkData::BD_STOP);
}//stopSend

void BulkDataNTSenderFlow::writeFrame(ACSBulkData::DataType dataType,  const unsigned char *param, size_t len)
{

	DDS::ReturnCode_t ret;
	DDS::InstanceHandle_t handle = DDS::HANDLE_NIL;
	//ACSBulkData::BulkDataNTFrame *frame;

	if (len>ACSBulkData::FRAME_MAX_LEN){
		printf("parameter too long !!\n");
		// delete
		//TBD:: error handling
	}

	//RTI do we have to create the frame each time or ... ?
	frame = ACSBulkData::BulkDataNTFrameTypeSupport::create_data();
	if (frame == NULL) {
		printf("BD_DDS::BDdataMessageTypeSupport::create_data error - frame null\n");
		// delete
		//TBD:: error handling
	}

	//frame
	frame->dataType = dataType;
	frame->data./*resize*/length(len);
	if (param!=0 && len!=0)
		frame->data.from_array(param, len); //frame.data.assign(len, *param);   //1st parameter  is of type const unsigned char !!

	ret = ddsDataWriter_m->write(*frame, handle);
	if( ret != DDS::RETCODE_OK)
	{
		//TBD EH  special for timeout
		std::cerr << "Failed to send parameter. Return code: " << ret << std::endl;
	}//if

	// should we wait for all ACKs? timeout should be configurable
	DDS::Duration_t ack_timeout_delay = {1, 0};//1s
	ret = ddsDataWriter_m->wait_for_acknowledgments(ack_timeout_delay);
	if( ret != DDS::RETCODE_OK) {
		std::cerr << " !Failed while waiting for acknowledgment of "
				<< "data being received by subscriptions, some data "
				<< "may not have been delivered." << std::endl;
		//TBD error handling
	}//if

}//writeFrame

/*___oOo___*/
<|endoftext|>