<commit_before>/*
 * Software License Agreement (Apache License)
 *
 * Copyright (c) 2014, Southwest Research Institute
 *
 * 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.
 */

#ifndef CERES_COSTS_UTILS_HPP_
#define CERES_COSTS_UTILS_HPP_

#include "ceres/ceres.h"
#include "ceres/rotation.h"
#include <industrial_extrinsic_cal/basic_types.h>

namespace industrial_extrinsic_cal
{

/* local prototypes of helper functions */

/*! \brief print a quaternion plus position as a homogeneous transform
 *  \param qx quaternion x value
 *  \param qy quaternion y value
 *  \param qz quaternion z value
 *  \param qw quaternion w value
 *  \param tx position x value
 *  \param ty position y value
 *  \param tz position z value
 */
void printQTasH(double qx, double qy, double qz, double qw, double tx, double ty, double tz);

/*! \brief print an angle axis transform as a homogeneous transform
 *  \param x angle axis x value
 *  \param y angle axis y value
 *  \param z angle axis z value
 *  \param tx position x value
 *  \param ty position y value
 *  \param tz position z value
 */
void printAATasH(double ax, double ay, double az, double tx, double ty, double tz);

/*! \brief print angle axis to homogeneous transform inverse
 *  \param ax angle axis x value
 *  \param ay angle axis y value
 *  \param az angle axis z value
 *  \param tx position x value
 *  \param ty position y value
 *  \param tz position z value
 */
void printAATasHI(double ax, double ay, double az, double tx, double ty, double tz);

/*! \brief print angle axis as euler angles
 *  \param ax angle axis x value
 *  \param ay angle axis y value
 *  \param az angle axis z value
 */
void printAAasEuler(double ax, double ay, double az);

/*! \brief print Camera Parameters
 *  \param CameraParameters include intrinsic and extrinsic
 *  \param words to provide as a header
 */
void printCameraParameters(CameraParameters C, std::string words);

/*! \brief  computes image of point in cameras image plane
 *  \param  C both intrinsic and extrinsic camera parameters
 *  \param  P the point to be projected into image
 */
Observation projectPoint(CameraParameters camera_parameters, Point3d point);

  struct TargetCameraReprjErrorNoDistortion{
    TargetCameraReprjErrorNoDistortion(double ob_x, double ob_y,
				       double fx,   double fy,
				       double cx,   double cy,
				       double pnt_x,   double pnt_y, double pnt_z)
      : ox_(ob_x),oy_(ob_y),
	fx_(fx),fy_(fy),
	cx_(cx),cy_(cy),
        pnt_x_(pnt_x), pnt_y_(pnt_y), pnt_z_(pnt_z){}

    template <typename T>
    bool operator()(const T* const c_p1,   /** extrinsic parameters */
		    const T* const c_p2,   /** 6Dof transform of target points into world frame */
		    T* resid) const {

      /** extract the variables from parameter blocks  */
      int q=0; /** extract extrinsic block of parameters */
      const T& ax    = c_p1[q++]; /**  angle_axis x for rotation of camera		 */
      const T& ay    = c_p1[q++]; /**  angle_axis y for rotation of camera */
      const T& az    = c_p1[q++]; /**  angle_axis z for rotation of camera */
      const T& tx    = c_p1[q++]; /**  translation of camera x */
      const T& ty    = c_p1[q++]; /**  translation of camera y */
      const T& tz    = c_p1[q++]; /**  translation of camera z */

      q=0; /** extract target pose block of parameters */
      const T& target_x   = c_p2[q++]; /**  target's x location */
      const T& target_y   = c_p2[q++]; /**  target's y location */
      const T& target_z   = c_p2[q++]; /**  target's z location */
      const T& target_ax  = c_p2[q++]; /**  target's ax angle axis value */
      const T& target_ay  = c_p2[q++]; /**  target's ay angle axis value */
      const T& target_az  = c_p2[q++]; /**  target's az angle axis value */

      // create a vector from the location of the point in the target's frame
      T point[3];
      point[0] = T(pnt_x_);
      point[1] = T(pnt_y_);
      point[2] = T(pnt_z_);

      /** rotate and translate points into world frame */
      T target_aa[3];/** angle axis  */
      T world_point_loc[3]; /** point rotated */
      target_aa[0] = target_ax;
      target_aa[1] = target_ay;
      target_aa[2] = target_az;
      //takes rotation as a Rodriques’ axis-angle vector, and point, returns world_point_loc as rotated point
      ceres::AngleAxisRotatePoint(target_aa,point,world_point_loc);

      /** apply target translation */
      world_point_loc[0] = world_point_loc[0] + target_x;
      world_point_loc[1] = world_point_loc[1] + target_y;
      world_point_loc[2] = world_point_loc[2] + target_z;

      /** rotate and translate points into camera frame */
      /*  Note that camera transform is from world into camera frame, not vise versa */
      T aa[3];/** angle axis  */
      T camera_point_loc[3]; /** point rotated */
      aa[0] = ax;
      aa[1] = ay;
      aa[2] = az;
      ceres::AngleAxisRotatePoint(aa,point,camera_point_loc);

      /** apply camera translation */
      T xp1 = camera_point_loc[0] + tx; /** point rotated and translated */
      T yp1 = camera_point_loc[1] + ty;
      T zp1 = camera_point_loc[2] + tz;

      /** scale into the image plane by distance away from camera */
      T xp = xp1/zp1;
      T yp = yp1/zp1;

      /** perform projection using focal length and camera center into image plane */
      resid[0] = T(fx_)*xp + T(cx_) - T(ox_);
      resid[1] = T(fy_)*yp + T(cy_) - T(oy_);

      return true;
    } /** end of operator() */

    /** Factory to hide the construction of the CostFunction object from */
    /** the client code. */
    static ceres::CostFunction* Create(const double o_x, const double o_y,
				       const double fx,  const double fy,
				       const double cx,  const double cy,
				       const double pnt_x, const double pnt_y,
                                       const double pnt_z)
  {
    return (new ceres::AutoDiffCostFunction<TargetCameraReprjErrorNoDistortion, 2, 6, 6>(
        new TargetCameraReprjErrorNoDistortion(o_x, o_y, fx, fy, cx, cy, pnt_x, pnt_y, pnt_z)));
    }
    double ox_; /** observed x location of object in image */
    double oy_; /** observed y location of object in image */
    double fx_; /*!< known focal length of camera in x */
    double fy_; /*!< known focal length of camera in y */
    double cx_; /*!< known optical center of camera in x */
    double cy_; /*!< known optical center of camera in y */
    double pnt_x_;/*!< known location of point in target's reference frame x */
    double pnt_y_;/*!< known location of point in target's reference frame y */
    double pnt_z_;/*!< known location of point in target's reference frame z */
  };

} // end of namespace
#endif
<commit_msg>Added cost function definitions. These may eventually move to ceres_costs_utils.cpp.<commit_after>/*
 * Software License Agreement (Apache License)
 *
 * Copyright (c) 2014, Southwest Research Institute
 *
 * 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.
 */

#ifndef CERES_COSTS_UTILS_HPP_
#define CERES_COSTS_UTILS_HPP_

#include "ceres/ceres.h"
#include "ceres/rotation.h"
#include <industrial_extrinsic_cal/basic_types.h>

namespace industrial_extrinsic_cal
{

/* local prototypes of helper functions */

/*! \brief print a quaternion plus position as a homogeneous transform
 *  \param qx quaternion x value
 *  \param qy quaternion y value
 *  \param qz quaternion z value
 *  \param qw quaternion w value
 *  \param tx position x value
 *  \param ty position y value
 *  \param tz position z value
 */
void printQTasH(double qx, double qy, double qz, double qw, double tx, double ty, double tz);

/*! \brief print an angle axis transform as a homogeneous transform
 *  \param x angle axis x value
 *  \param y angle axis y value
 *  \param z angle axis z value
 *  \param tx position x value
 *  \param ty position y value
 *  \param tz position z value
 */
void printAATasH(double ax, double ay, double az, double tx, double ty, double tz);

/*! \brief print angle axis to homogeneous transform inverse
 *  \param ax angle axis x value
 *  \param ay angle axis y value
 *  \param az angle axis z value
 *  \param tx position x value
 *  \param ty position y value
 *  \param tz position z value
 */
void printAATasHI(double ax, double ay, double az, double tx, double ty, double tz);

/*! \brief print angle axis as euler angles
 *  \param ax angle axis x value
 *  \param ay angle axis y value
 *  \param az angle axis z value
 */
void printAAasEuler(double ax, double ay, double az);

/*! \brief print Camera Parameters
 *  \param CameraParameters include intrinsic and extrinsic
 *  \param words to provide as a header
 */
void printCameraParameters(CameraParameters C, std::string words);

/*! \brief  computes image of point in cameras image plane
 *  \param  C both intrinsic and extrinsic camera parameters
 *  \param  P the point to be projected into image
 */
Observation projectPointWithDistortion(CameraParameters camera_parameters, Point3d point);
Observation projectPointNoDistortion(CameraParameters camera_params, Point3d point_to_project);

Observation projectPointWithDistortion(CameraParameters C, Point3d P)
{
  double p[3];
  double pt[3];
  pt[0] = P.x;
  pt[1] = P.y;
  pt[2] = P.z;

  /* transform point into camera frame */
  /* note, camera transform takes points from camera frame into world frame */
  double aa[3];
  aa[0]=C.pb_extrinsics[0];
  aa[1]=C.pb_extrinsics[1];
  aa[2]=C.pb_extrinsics[2];
  ceres::AngleAxisRotatePoint(aa, pt, p);

  // apply camera translation
  double xp1 = p[0] + C.pb_extrinsics[3];
  double yp1 = p[1] + C.pb_extrinsics[4];
  double zp1 = p[2] + C.pb_extrinsics[5];
  //p[0] +=C.pb_extrinsics[3];
  //p[1] +=C.pb_extrinsics[4];
  //p[2] +=C.pb_extrinsics[5];

  double xp = xp1 / zp1;
  double yp = yp1 / zp1;

  // calculate terms for polynomial distortion
  double r2 = xp * xp + yp * yp;
  double r4 = r2 * r2;
  double r6 = r2 * r4;

  double xp2 = xp * xp; /* temporary variables square of others */
  double yp2 = yp * yp;

  /* apply the distortion coefficients to refine pixel location */
  double xpp = xp + C.distortion_k1 * r2 * xp + C.distortion_k2 * r4 * xp +
      C.distortion_k3 * r6 * xp + C.distortion_p2 * (r2 + 2 * xp2) + 2 * C.distortion_p1 * xp * yp;
  double ypp = yp + C.distortion_k1 * r2 * yp + C.distortion_k2 * r4 * yp +
      C.distortion_k3 * r6 * yp + C.distortion_p1 * (r2 + 2 * yp2) + 2 * C.distortion_p2 * xp * yp;

  /* perform projection using focal length and camera center into image plane */
  Observation O;
  O.point_id = 0;
  O.image_loc_x = C.focal_length_x * xpp + C.center_x;
  O.image_loc_y = C.focal_length_y * ypp + C.center_y;
  return (O);
}

Observation projectPointNoDistortion(CameraParameters C, Point3d P)
{
  double p[3];                  // rotated into camera frame
  double point[3];              // world location of point
  double aa[3];                 // angle axis representation of camera transform
  double tx = C.position[0];    // location of origin in camera frame x
  double ty = C.position[1];    // location of origin in camera frame y
  double tz = C.position[2];    // location of origin in camera frame z
  double fx = C.focal_length_x; // focal length x
  double fy = C.focal_length_y; // focal length y
  double cx = C.center_x;       // optical center x
  double cy = C.center_y;       // optical center y

  aa[0] = C.angle_axis[0];
  aa[1] = C.angle_axis[1];
  aa[2] = C.angle_axis[2];
  point[0] = P.x;
  point[1] = P.y;
  point[2] = P.z;

  /** rotate and translate points into camera frame */
  ceres::AngleAxisRotatePoint(aa, point, p);

  // apply camera translation
  double xp1 = p[0] + tx;
  double yp1 = p[1] + ty;
  double zp1 = p[2] + tz;

  // scale into the image plane by distance away from camera
  double xp = xp1 / zp1;
  double yp = yp1 / zp1;

  // perform projection using focal length and camera center into image plane
  Observation O;
  O.image_loc_x = fx * xp + cx;
  O.image_loc_y = fy * yp + cy;
  return (O);
}

  struct TargetCameraReprjErrorNoDistortion
  {
    TargetCameraReprjErrorNoDistortion(double ob_x, double ob_y,
				       double fx,   double fy,
				       double cx,   double cy,
				       double pnt_x,   double pnt_y, double pnt_z)
      : ox_(ob_x),oy_(ob_y),
	fx_(fx),fy_(fy),
	cx_(cx),cy_(cy),
        pnt_x_(pnt_x), pnt_y_(pnt_y), pnt_z_(pnt_z){}

    template <typename T>
    bool operator()(const T* const c_p1,   /** extrinsic parameters */
		    const T* const t_p1,   /** 6Dof transform of target points into world frame */
		    T* resid) const {

      /** extract the variables from parameter blocks  */
      int q=0; /** extract extrinsic block of parameters */
      const T& ax    = c_p1[q++]; /**  angle_axis x for rotation of camera		 */
      const T& ay    = c_p1[q++]; /**  angle_axis y for rotation of camera */
      const T& az    = c_p1[q++]; /**  angle_axis z for rotation of camera */
      const T& tx    = c_p1[q++]; /**  translation of camera x */
      const T& ty    = c_p1[q++]; /**  translation of camera y */
      const T& tz    = c_p1[q++]; /**  translation of camera z */

      q=0; /** extract target pose block of parameters */
      const T& target_x   = t_p1[q++]; /**  target's x location */
      const T& target_y   = t_p1[q++]; /**  target's y location */
      const T& target_z   = t_p1[q++]; /**  target's z location */
      const T& target_ax  = t_p1[q++]; /**  target's ax angle axis value */
      const T& target_ay  = t_p1[q++]; /**  target's ay angle axis value */
      const T& target_az  = t_p1[q++]; /**  target's az angle axis value */

      // create a vector from the location of the point in the target's frame
      T point[3];
      point[0] = T(pnt_x_);
      point[1] = T(pnt_y_);
      point[2] = T(pnt_z_);

      /** rotate and translate points into world frame */
      T target_aa[3];/** angle axis  */
      T world_point_loc[3]; /** point rotated */
      target_aa[0] = target_ax;
      target_aa[1] = target_ay;
      target_aa[2] = target_az;
      //takes rotation as a Rodriques’ axis-angle vector, and point, returns world_point_loc as rotated point
      ceres::AngleAxisRotatePoint(target_aa,point,world_point_loc);

      /** apply target translation */
      world_point_loc[0] = world_point_loc[0] + target_x;
      world_point_loc[1] = world_point_loc[1] + target_y;
      world_point_loc[2] = world_point_loc[2] + target_z;

      /** rotate and translate points into camera frame */
      /*  Note that camera transform is from world into camera frame, not vise versa */
      T aa[3];/** angle axis  */
      T camera_point_loc[3]; /** point rotated */
      aa[0] = ax;
      aa[1] = ay;
      aa[2] = az;
      ceres::AngleAxisRotatePoint(aa,point,camera_point_loc);

      /** apply camera translation */
      T xp1 = camera_point_loc[0] + tx; /** point rotated and translated */
      T yp1 = camera_point_loc[1] + ty;
      T zp1 = camera_point_loc[2] + tz;

      /** scale into the image plane by distance away from camera */
      T xp = xp1/zp1;
      T yp = yp1/zp1;

      /** perform projection using focal length and camera center into image plane */
      resid[0] = T(fx_)*xp + T(cx_) - T(ox_);
      resid[1] = T(fy_)*yp + T(cy_) - T(oy_);

      return true;
    } /** end of operator() */

    /** Factory to hide the construction of the CostFunction object from */
    /** the client code. */
    static ceres::CostFunction* Create(const double o_x, const double o_y,
				       const double fx,  const double fy,
				       const double cx,  const double cy,
				       const double pnt_x, const double pnt_y,
                                       const double pnt_z)
  {
    return (new ceres::AutoDiffCostFunction<TargetCameraReprjErrorNoDistortion, 2, 6, 6>(
        new TargetCameraReprjErrorNoDistortion(o_x, o_y, fx, fy, cx, cy, pnt_x, pnt_y, pnt_z)));
    }
    double ox_; /** observed x location of object in image */
    double oy_; /** observed y location of object in image */
    double fx_; /*!< known focal length of camera in x */
    double fy_; /*!< known focal length of camera in y */
    double cx_; /*!< known optical center of camera in x */
    double cy_; /*!< known optical center of camera in y */
    double pnt_x_;/*!< known location of point in target's reference frame x */
    double pnt_y_;/*!< known location of point in target's reference frame y */
    double pnt_z_;/*!< known location of point in target's reference frame z */
  };

  struct CameraReprjErrorNoDistortion
  {
    CameraReprjErrorNoDistortion(double ob_x, double ob_y, double fx, double fy, double cx, double cy) :
        ox_(ob_x), oy_(ob_y), fx_(fx), fy_(fy), cx_(cx), cy_(cy)
    {
    }

    template<typename T>
      bool operator()(const T* const c_p1, /** extrinsic parameters */
                      const T* c_p2, /** intrinsic parameters */
                      const T* point, /** point being projected, yes this is has 3 parameters */
                      T* resid) const
      {
        /** extract the variables from the camera parameters */
        int q = 0; /** extrinsic block of parameters */
        const T& ax = c_p1[q++]; /**  angle_axis x for rotation of camera           */
        const T& ay = c_p1[q++]; /**  angle_axis y for rotation of camera */
        const T& az = c_p1[q++]; /**  angle_axis z for rotation of camera */
        const T& tx = c_p1[q++]; /**  translation of camera x */
        const T& ty = c_p1[q++]; /**  translation of camera y */
        const T& tz = c_p1[q++]; /**  translation of camera z */

        q = 0; /** intrinsic block of parameters */
        const T& fx = c_p2[q++]; /**  focal length x */
        const T& fy = c_p2[q++]; /**  focal length x */
        const T& cx = c_p2[q++]; /**  center point x */
        const T& cy = c_p2[q++]; /**  center point y */

        /** rotate and translate points into camera frame */
        T aa[3];/** angle axis  */
        T p[3]; /** point rotated */
        T P[3]; /** point original */
        aa[0] = ax;
        aa[1] = ay;
        aa[2] = az;
        ceres::AngleAxisRotatePoint(aa, point, p);

        /** apply camera translation */
        T xp1 = p[0] + tx; /** point rotated and translated */
        T yp1 = p[1] + ty;
        T zp1 = p[2] + tz;

        /** scale into the image plane by distance away from camera */
        T xp = xp1 / zp1;
        T yp = yp1 / zp1;

        /** perform projection using focal length and camera center into image plane */
        resid[0] = T(fx_) * xp + T(cx_) - T(ox_);
        resid[1] = T(fy_) * yp + T(cy_) - T(oy_);

        return true;
      } /** end of operator() */

    /** Factory to hide the construction of the CostFunction object from */
    /** the client code. */
    static ceres::CostFunction* Create(const double o_x, const double o_y, const double f_x, const double f_y, const double c_x, const double c_y)
    {
      return (new ceres::AutoDiffCostFunction<CameraReprjErrorNoDistortion, 2, 6, 9, 3>(new CameraReprjErrorNoDistortion(o_x, o_y, f_x, f_y, c_x, c_y)));
    }
    double ox_; /** observed x location of object in image */
    double oy_; /** observed y location of object in image */
    double fx_; /*!< known focal length of camera in x */
    double fy_; /*!< known focal length of camera in y */
    double cx_; /*!< known optical center of camera in x */
    double cy_; /*!< known optical center of camera in y */
  };

  struct CameraReprjErrorWithDistortion
  {
    CameraReprjErrorWithDistortion(double ob_x, double ob_y) :
        ox_(ob_x), oy_(ob_y)
    {
    }

    template<typename T>
      bool operator()(const T* const c_p1, /** extrinsic parameters */
                      const T* c_p2, /** intrinsic parameters */
                      const T* point, /** point being projected, yes this is has 3 parameters */
                      T* resid) const
      {
        /** extract the variables from the camera parameters */
        int q = 0; /** extrinsic block of parameters */
        const T& ax = c_p1[q++]; /**  angle_axis x for rotation of camera           */
        const T& ay = c_p1[q++]; /**  angle_axis y for rotation of camera */
        const T& az = c_p1[q++]; /**  angle_axis z for rotation of camera */
        const T& tx = c_p1[q++]; /**  translation of camera x */
        const T& ty = c_p1[q++]; /**  translation of camera y */
        const T& tz = c_p1[q++]; /**  translation of camera z */

        q = 0; /** intrinsic block of parameters */
        const T& fx = c_p2[q++]; /**  focal length x */
        const T& fy = c_p2[q++]; /**  focal length x */
        const T& cx = c_p2[q++]; /**  center point x */
        const T& cy = c_p2[q++]; /**  center point y */
        const T& k1 = c_p2[q++]; /**  distortion coefficient on 2nd order terms */
        const T& k2 = c_p2[q++]; /**  distortion coefficient on 4th order terms */
        const T& k3 = c_p2[q++]; /**  distortion coefficient on 6th order terms */
        const T& p1 = c_p2[q++]; /**  tangential distortion coefficient x */
        const T& p2 = c_p2[q++]; /**  tangential distortion coefficient y */

        /** rotate and translate points into camera frame */
        T aa[3];/** angle axis  */
        T p[3]; /** point rotated */
        aa[0] = ax;
        aa[1] = ay;
        aa[2] = az;
        ceres::AngleAxisRotatePoint(aa, point, p);

        /** apply camera translation */
        T xp1 = p[0] + tx; /** point rotated and translated */
        T yp1 = p[1] + ty;
        T zp1 = p[2] + tz;

        /** scale into the image plane by distance away from camera */
        T xp = xp1 / zp1;
        T yp = yp1 / zp1;

        /** calculate terms for polynomial distortion */
        T r2 = xp * xp + yp * yp;
        T r4 = r2 * r2;
        T r6 = r2 * r4;

        T xp2 = xp * xp; /** temporary variables square of others */
        T yp2 = yp * yp;
        /*apply the distortion coefficients to refine pixel location */
        T xpp = xp + k1 * r2 * xp + k2 * r4 * xp + k3 * r6 * xp + p2 * (r2 + T(2.0) * xp2) + T(2.0) * p1 * xp * yp;
        T ypp = yp + k1 * r2 * yp + k2 * r4 * yp + k3 * r6 * yp + p1 * (r2 + T(2.0) * yp2) + T(2.0) * p2 * xp * yp;
        /** perform projection using focal length and camera center into image plane */
        resid[0] = fx * xpp + cx - T(ox_);
        resid[1] = fy * ypp + cy - T(oy_);

        return true;
      } /** end of operator() */

    /** Factory to hide the construction of the CostFunction object from */
    /** the client code. */
    static ceres::CostFunction* Create(const double o_x, const double o_y)
    {
      return (new ceres::AutoDiffCostFunction<CameraReprjErrorWithDistortion, 2, 6, 9, 3>(new CameraReprjErrorWithDistortion(o_x, o_y)));
    }
    double ox_; /** observed x location of object in image */
    double oy_; /** observed y location of object in image */
  };

} // end of namespace
#endif
<|endoftext|>


<commit_before>#include "iir.h"
#include "fifo.h"
#include "blend.h"
#include "diff.h"

/////////////////////////////
//          +===============+
//          |               |
// INPUT ===+= IIR ===+==>(DIFF)
//             ^     |
//             |     |
//           FIFO <==+
/////////////////////////////

BEGIN_OGLES_GPGPU

// Convenience initializer:
class IirFilterProc::Impl
{
public:
    Impl(FilterKind kind, float alpha, float strength)
    : kind(kind)
    , iirProc(alpha)
    , fifoProc(1)
    , diffProc(strength)
    {
        iirProc.add(&fifoProc);
        fifoProc.add(&iirProc, 1);
        if(kind == kHighPass)
        {
            iirProc.add(&diffProc, 1);
            lastProc = &diffProc; // high pass output
        }
        iirProc.setWaitForSecondTexture(false);
    }
    IirFilterProc::FilterKind kind = kLowPass;
    BlendProc iirProc;
    FIFOPRoc fifoProc;
    DiffProc diffProc;
    ProcInterface *lastProc = &iirProc; // default for low pass
};

IirFilterProc::IirFilterProc(FilterKind kind, float alpha, float strength)
{
    // All procPasses filter will be initialized by superclass:
    m_impl = std::unique_ptr<Impl>(new Impl(kind, alpha, strength));
    procPasses.push_back(&m_impl->iirProc);
    procPasses.push_back(&m_impl->fifoProc);
    if(kind == kHighPass)
    {
        procPasses.push_back(&m_impl->diffProc);
    }
}

int IirFilterProc::init(int inW, int inH, unsigned int order, bool prepareForExternalInput)
{
    isFirst = true;
    return MultiPassProc::init(inW, inH, order, prepareForExternalInput);
}

int IirFilterProc::reinit(int inW, int inH, bool prepareForExternalInput)
{
    isFirst = true;
    return MultiPassProc::reinit(inW, inH, prepareForExternalInput);
}

IirFilterProc::~IirFilterProc() {}
ProcInterface* IirFilterProc::getInputFilter() const { return &m_impl->iirProc; }
ProcInterface* IirFilterProc::getOutputFilter() const { return m_impl->lastProc; }

int IirFilterProc::render(int position)
{   // Execute internal filter chain
    m_impl->iirProc.process(0);
    if(m_impl->kind == kHighPass)
    {
        // At this point useTexture() has been called and diffProc should have:
        // texture #1 : <- Input
        // texture #2 : <- IirProc
        m_impl->diffProc.process(0);
    }
    return 0;
}

void IirFilterProc::useTexture(GLuint id, GLuint useTexUnit, GLenum target, int position)
{
    auto &fifoProc = m_impl->fifoProc;
    auto &iirProc = m_impl->iirProc;

    if((m_impl->kind == kHighPass) && isFirst)
    {
        auto &diffProc = m_impl->diffProc;

        // (Optional) Diff filter for high pass filter:
        diffProc.useTexture(id, useTexUnit, target, 0);
        diffProc.useTexture2(iirProc.getOutputTexId(), iirProc.getTextureUnit(), GL_TEXTURE_2D);
    }

    // IIR filter input (same image for first frame)

    if(isFirst)
    {
        isFirst = false;
        iirProc.useTexture(id, useTexUnit, target, 0);
        iirProc.useTexture2(id, useTexUnit, GL_TEXTURE_2D);

        // FIFO input (from IIR)
        fifoProc.useTexture(iirProc.getOutputTexId(), iirProc.getTextureUnit(), GL_TEXTURE_2D, 0);
    }
    else
    {
        // Connect FIFO output to second input of IIR for frames >= 1
        iirProc.useTexture2(fifoProc.getOutputTexId(), fifoProc.getTextureUnit(), GL_TEXTURE_2D);
    }
}

END_OGLES_GPGPU
<commit_msg>fixed logic related to first frame initialization<commit_after>#include "iir.h"
#include "fifo.h"
#include "blend.h"
#include "diff.h"

/////////////////////////////
//          +===============+
//          |               |
// INPUT ===+= IIR ===+==>(DIFF)
//             ^     |
//             |     |
//           FIFO <==+
/////////////////////////////

BEGIN_OGLES_GPGPU

// Convenience initializer:
class IirFilterProc::Impl
{
public:
    Impl(FilterKind kind, float alpha, float strength)
    : kind(kind)
    , iirProc(alpha)
    , fifoProc(1)
    , diffProc(strength)
    {
        iirProc.add(&fifoProc);
        fifoProc.add(&iirProc, 1);
        if(kind == kHighPass)
        {
            iirProc.add(&diffProc, 1);
            lastProc = &diffProc; // high pass output
        }
        iirProc.setWaitForSecondTexture(false);
    }
    IirFilterProc::FilterKind kind = kLowPass;
    BlendProc iirProc;
    FIFOPRoc fifoProc;
    DiffProc diffProc;
    ProcInterface *lastProc = &iirProc; // default for low pass
};

IirFilterProc::IirFilterProc(FilterKind kind, float alpha, float strength)
{
    // All procPasses filter will be initialized by superclass:
    m_impl = std::unique_ptr<Impl>(new Impl(kind, alpha, strength));
    procPasses.push_back(&m_impl->iirProc);
    procPasses.push_back(&m_impl->fifoProc);
    if(kind == kHighPass)
    {
        procPasses.push_back(&m_impl->diffProc);
    }
}

int IirFilterProc::init(int inW, int inH, unsigned int order, bool prepareForExternalInput)
{
    isFirst = true;
    return MultiPassProc::init(inW, inH, order, prepareForExternalInput);
}

int IirFilterProc::reinit(int inW, int inH, bool prepareForExternalInput)
{
    isFirst = true;
    return MultiPassProc::reinit(inW, inH, prepareForExternalInput);
}

IirFilterProc::~IirFilterProc() {}
ProcInterface* IirFilterProc::getInputFilter() const { return &m_impl->iirProc; }
ProcInterface* IirFilterProc::getOutputFilter() const { return m_impl->lastProc; }

int IirFilterProc::render(int position)
{   // Execute internal filter chain
    m_impl->iirProc.process(0); // calls next->useTexture(); next->process();
    if(m_impl->kind == kHighPass)
    {
        // At this point useTexture() has been called and diffProc should have:
        // texture #1 : <- Input
        // texture #2 : <- IirProc
        m_impl->diffProc.process(0);
    }
    return 0;
}

void IirFilterProc::useTexture(GLuint id, GLuint useTexUnit, GLenum target, int position)
{
    auto &fifoProc = m_impl->fifoProc;
    auto &iirProc = m_impl->iirProc;

    if(m_impl->kind == kHighPass)
    {
        auto &diffProc = m_impl->diffProc;

        // (Optional) Diff filter for high pass filter:
        diffProc.useTexture(id, useTexUnit, target, 0);
        if(isFirst)
        {
            diffProc.useTexture2(id, useTexUnit, GL_TEXTURE_2D);
        }
        else
        {
            diffProc.useTexture2(iirProc.getOutputTexId(), iirProc.getTextureUnit(), GL_TEXTURE_2D);
        }
    }

    // IIR filter input (same image for first frame)

    if(isFirst)
    {
        isFirst = false;
        iirProc.useTexture(id, useTexUnit, target, 0);
        iirProc.useTexture2(id, useTexUnit, GL_TEXTURE_2D);

        // FIFO input (from IIR)
        fifoProc.useTexture(id, useTexUnit, target, 0);
    }
    else
    {
        // Connect FIFO output to second input of IIR for frames >= 1
        iirProc.useTexture(id, useTexUnit, target, 0);
        iirProc.useTexture2(fifoProc.getOutputTexId(), fifoProc.getTextureUnit(), GL_TEXTURE_2D);

        // FIFO input (from IIR)
        fifoProc.useTexture(iirProc.getOutputTexId(), iirProc.getTextureUnit(), GL_TEXTURE_2D, 0);

    }
}

END_OGLES_GPGPU
<|endoftext|>


<commit_before>#include <iostream>
#include <string>

#include "JSONAnalysis.hpp"

void run_part_one() {
    std::string json_string;
    std::cin >> json_string;
    std::cout << get_sum_of_numbers(json_string) << std::endl;
}
void run_part_two() {
}

int main(int argc, char* argv[]) {
    if (argc > 1) {
        if (std::string(argv[1]) == "--part_two") {
            run_part_two();
        } else {
            std::cout << "Usage: day12 [--part_two]" << std::endl;
            return -1;
        }
    } else {
        run_part_one();
    }
}
<commit_msg>added runtime code for day 12 part two<commit_after>#include <iostream>
#include <string>

#include "JSONAnalysis.hpp"

void run_part_one() {
    std::string json_string;
    std::cin >> json_string;
    std::cout << get_sum_of_numbers(json_string) << std::endl;
}
void run_part_two() {
    std::string json_string;
    std::cin >> json_string;
    std::cout << get_sum_of_numbers_without_red(json_string) << std::endl;
}

int main(int argc, char* argv[]) {
    if (argc > 1) {
        if (std::string(argv[1]) == "--part_two") {
            run_part_two();
        } else {
            std::cout << "Usage: day12 [--part_two]" << std::endl;
            return -1;
        }
    } else {
        run_part_one();
    }
}
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <time.h>

// OpenCV headers
#include <cv.h>
#include <highgui.h>

#include <opencv2/contrib/contrib.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <opencv_workbench/utils/Stream.h>
#include <opencv_workbench/syllo/syllo.h>

#include <opencv_workbench/utils/AnnotationParser.h>
#include <opencv_workbench/plot/Plot.h>

#include <opencv_workbench/detector/Detector.h>
#include <opencv_workbench/plugin_manager/PluginManager.h>

using std::cout;
using std::endl;

PluginManager<Detector, Detector_maker_t> plugin_manager_;

int main(int argc, char *argv[])
{
     //int aflag = 0;
     //int bflag = 0;
     //char *cvalue = NULL;
     //int index;
     int hide_window_flag = 0;
     int step_flag = 0;
     int c;
     //std::string video_filename = "/home/syllogismrxs/Documents/Thesis/data/sonar-avi/2014-01-24-ME-sonar-only-diver/2014_01_24_15_24_06.avi";
     std::string video_filename = "/home/syllogismrxs/Documents/Thesis/data/NEEMO/neemo-sonar/2015_07_29-Walking-Habitat/2015_07_29_13_28_17-hab-diver-fish.son";
     std::string plugin_name = "relative_detector";
     std::string xml_output_dir = "";
     int xml_output_dir_flag = 0;

     while ((c = getopt (argc, argv, "abc:f:hp:o:s")) != -1) {
          switch (c) {
          //case 'a':
          //     aflag = 1;
          //     break;
          //case 'b':
          //     bflag = 1;
          //     break;
          case 'o':
               xml_output_dir_flag = 1;
               xml_output_dir = std::string(optarg);
               break;
          case 'h':
               hide_window_flag = 1;
               break;
          case 'p':
               plugin_name = std::string(optarg);
               break;
          case 'f':
               video_filename = std::string(optarg);
               break;
          case 's':
               step_flag = 1;
               break;
          case '?':
               if (optopt == 'c') {
                    fprintf (stderr, "Option -%c requires an argument.\n", optopt);
               } else if (optopt == 'f') {
                    fprintf (stderr, "Option -%c requires a video filename as an argument.\n", optopt);
               } else if (optopt == 'o') {
                    fprintf (stderr, "Option -%c requires an output directory as an argument.\n", optopt);
               } else if (optopt == 'p') {
                    fprintf (stderr, "Option -%c requires a plugin name as an argument.\n", optopt);
               } else if (isprint (optopt)) {
                    fprintf (stderr, "Unknown option `-%c'.\n", optopt);
               } else {
                    fprintf (stderr,
                             "Unknown option character `\\x%x'.\n",
                             optopt);
               }
               return 1;
          default:
               abort ();
          }
     }

     syllo::fill_line("=");
     cout << "Running Detector" << endl;
     syllo::fill_line("=");

     syllo::Stream stream;
     syllo::Status status = stream.open(video_filename);
     //stream.set_sonar_data_mode(syllo::image);
     //stream.set_sonar_data_mode(syllo::range);

     if (status != syllo::Success) {
          cout << "Failed to open: " << video_filename << endl;
          return -1;
     }

     // Setup Hand Annotated Parser (Truth)
     bool hand_ann_found = true;
     AnnotationParser parser_truth;
     int retcode = parser_truth.CheckForFile(video_filename, AnnotationParser::hand);
     if (retcode != 0) {
          cout << "Error parsing hand annotated file." << endl;
          hand_ann_found = false;
     }

     // Setup Annotation Parser_Tracks
     AnnotationParser parser_tracks;
     parser_tracks.CheckForFile(video_filename, AnnotationParser::track);
     parser_tracks.clear();
     parser_tracks.set_width(stream.width());
     parser_tracks.set_height(stream.height());
     parser_tracks.set_depth(3);
     parser_tracks.set_type("video");
     parser_tracks.set_number_of_frames(stream.get_frame_count());
     parser_tracks.set_plugin_name(plugin_name);

     if (xml_output_dir_flag == 1) {
          parser_tracks.set_xml_output_dir(xml_output_dir);
     }

     // Load the Bridge shared library (based on yml file)
     retcode = plugin_manager_.search_for_plugins("OPENCV_WORKBENCH_PLUGIN_PATH");
     if (retcode != 0) {
          cout << "Failed to find plugins." << endl;
          return -1;
     }

     retcode = plugin_manager_.open_library(plugin_name);
     if (retcode != 0) {
          cout << "Unable to open library: " << plugin_name << endl;

          return -1;
     } else {
          cout << "Using Bridge Library: " << plugin_name << endl;
     }

     Detector * detector_;
     detector_ = plugin_manager_.object();
     detector_->set_stream(&stream);
     detector_->print();

     if (hide_window_flag) {
          detector_->hide_windows(true);
     } else {
          detector_->hide_windows(false);
     }

     cv::Mat original;
     int frame_number = 0;
     while (stream.read(original)) {

          // Pass the frame to the detector plugin
          detector_->set_frame(frame_number, original);

          // Get track list from detector
          std::vector<wb::Entity> tracks = detector_->tracks();

          // Put all track data in parser for saving and
          // Draw estimated diver locations on original image
          Frame frame;
          frame.set_frame_number(frame_number);
          std::vector<wb::Entity>::iterator it = tracks.begin();
          for (; it != tracks.end(); it++) {
               cv::Point point = it->centroid();
               //cv::Point point = it->estimated_centroid();

               frame.objects[it->name()] = *it;

               if (it->type() == wb::Entity::Diver) {
                    // If this is a diver type, mark it on the original image
                    int radius = 3;
                    cv::circle(original, cv::Point(point.x,point.y),
                               radius, cv::Scalar(0,0,0), 2, 8, 0);
               }
          }
          // Save frame to parser
          parser_tracks.frames[frame_number] = frame;

          if (!hide_window_flag) {
               cv::imshow("Detection", original);

               if (step_flag) {
                    int key = cv::waitKey(0);
                    if (key == 'q' || key == 1048689) { // 'q' key
                         cout << "Ending early." << endl;
                         break;
                    } else if (key == 'p' || key == 1048688) {
                         step_flag = 0;
                    }
               } else {
                    int key = cv::waitKey(1);
                    if (key == 'q' || key == 1048689) {
                         cout << "Ending early." << endl;
                         break;
                    } else if (key == 'p' || key == 1048688) {
                         step_flag = 1;
                    }
               }

          }
          frame_number++;
     }

     // Which track exhibited the most displacement?
     // Which track is the oldest?

     // We can only compare the detector to truth data if we have a hand
     // annotated file.
     if (hand_ann_found) {
          cout << "Scoring detector..." << endl;
          std::vector<std::string> names;
          names.push_back("diver");
          parser_tracks.score_detector(parser_truth, names);
     } else {
          cout << "WARNING: Can't score detector because hand annotated "
               << "file is missing" << endl;
     }

     cout << "Saving tracks to xml file" << endl;
     parser_tracks.write_annotation();

     plugin_manager_.close_libraries();

     cout << "Done Processing." << endl;
     return 0;
}
<commit_msg>fixed diver name<commit_after>#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <time.h>

// OpenCV headers
#include <cv.h>
#include <highgui.h>

#include <opencv2/contrib/contrib.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <opencv_workbench/utils/Stream.h>
#include <opencv_workbench/syllo/syllo.h>

#include <opencv_workbench/utils/AnnotationParser.h>
#include <opencv_workbench/plot/Plot.h>

#include <opencv_workbench/detector/Detector.h>
#include <opencv_workbench/plugin_manager/PluginManager.h>

using std::cout;
using std::endl;

PluginManager<Detector, Detector_maker_t> plugin_manager_;

int main(int argc, char *argv[])
{
     //int aflag = 0;
     //int bflag = 0;
     //char *cvalue = NULL;
     //int index;
     int hide_window_flag = 0;
     int step_flag = 0;
     int c;
     //std::string video_filename = "/home/syllogismrxs/Documents/Thesis/data/sonar-avi/2014-01-24-ME-sonar-only-diver/2014_01_24_15_24_06.avi";
     std::string video_filename = "/home/syllogismrxs/Documents/Thesis/data/NEEMO/neemo-sonar/2015_07_29-Walking-Habitat/2015_07_29_13_28_17-hab-diver-fish.son";
     std::string plugin_name = "relative_detector";
     std::string xml_output_dir = "";
     int xml_output_dir_flag = 0;

     while ((c = getopt (argc, argv, "abc:f:hp:o:s")) != -1) {
          switch (c) {
          //case 'a':
          //     aflag = 1;
          //     break;
          //case 'b':
          //     bflag = 1;
          //     break;
          case 'o':
               xml_output_dir_flag = 1;
               xml_output_dir = std::string(optarg);
               break;
          case 'h':
               hide_window_flag = 1;
               break;
          case 'p':
               plugin_name = std::string(optarg);
               break;
          case 'f':
               video_filename = std::string(optarg);
               break;
          case 's':
               step_flag = 1;
               break;
          case '?':
               if (optopt == 'c') {
                    fprintf (stderr, "Option -%c requires an argument.\n", optopt);
               } else if (optopt == 'f') {
                    fprintf (stderr, "Option -%c requires a video filename as an argument.\n", optopt);
               } else if (optopt == 'o') {
                    fprintf (stderr, "Option -%c requires an output directory as an argument.\n", optopt);
               } else if (optopt == 'p') {
                    fprintf (stderr, "Option -%c requires a plugin name as an argument.\n", optopt);
               } else if (isprint (optopt)) {
                    fprintf (stderr, "Unknown option `-%c'.\n", optopt);
               } else {
                    fprintf (stderr,
                             "Unknown option character `\\x%x'.\n",
                             optopt);
               }
               return 1;
          default:
               abort ();
          }
     }

     syllo::fill_line("=");
     cout << "Running Detector" << endl;
     syllo::fill_line("=");

     syllo::Stream stream;
     syllo::Status status = stream.open(video_filename);
     //stream.set_sonar_data_mode(syllo::image);
     //stream.set_sonar_data_mode(syllo::range);

     if (status != syllo::Success) {
          cout << "Failed to open: " << video_filename << endl;
          return -1;
     }

     // Setup Hand Annotated Parser (Truth)
     bool hand_ann_found = true;
     AnnotationParser parser_truth;
     int retcode = parser_truth.CheckForFile(video_filename, AnnotationParser::hand);
     if (retcode != 0) {
          cout << "Error parsing hand annotated file." << endl;
          hand_ann_found = false;
     }

     // Setup Annotation Parser_Tracks
     AnnotationParser parser_tracks;
     parser_tracks.CheckForFile(video_filename, AnnotationParser::track);
     parser_tracks.clear();
     parser_tracks.set_width(stream.width());
     parser_tracks.set_height(stream.height());
     parser_tracks.set_depth(3);
     parser_tracks.set_type("video");
     parser_tracks.set_number_of_frames(stream.get_frame_count());
     parser_tracks.set_plugin_name(plugin_name);

     if (xml_output_dir_flag == 1) {
          parser_tracks.set_xml_output_dir(xml_output_dir);
     }

     // Load the Bridge shared library (based on yml file)
     retcode = plugin_manager_.search_for_plugins("OPENCV_WORKBENCH_PLUGIN_PATH");
     if (retcode != 0) {
          cout << "Failed to find plugins." << endl;
          return -1;
     }

     retcode = plugin_manager_.open_library(plugin_name);
     if (retcode != 0) {
          cout << "Unable to open library: " << plugin_name << endl;

          return -1;
     } else {
          cout << "Using Bridge Library: " << plugin_name << endl;
     }

     Detector * detector_;
     detector_ = plugin_manager_.object();
     detector_->set_stream(&stream);
     detector_->print();

     if (hide_window_flag) {
          detector_->hide_windows(true);
     } else {
          detector_->hide_windows(false);
     }

     cv::Mat original;
     int frame_number = 0;
     while (stream.read(original)) {

          // Pass the frame to the detector plugin
          detector_->set_frame(frame_number, original);

          // Get track list from detector
          std::vector<wb::Entity> tracks = detector_->tracks();

          // Put all track data in parser for saving and
          // Draw estimated diver locations on original image
          Frame frame;
          frame.set_frame_number(frame_number);
          std::vector<wb::Entity>::iterator it = tracks.begin();
          for (; it != tracks.end(); it++) {
               cv::Point point = it->centroid();
               //cv::Point point = it->estimated_centroid();

               frame.objects[it->name()] = *it;

               if (it->type() == wb::Entity::Diver) {
                    // If this is a diver type, mark it on the original image
                    int radius = 3;
                    cv::circle(original, cv::Point(point.x,point.y),
                               radius, cv::Scalar(0,0,0), 2, 8, 0);
               }
          }
          // Save frame to parser
          parser_tracks.frames[frame_number] = frame;

          if (!hide_window_flag) {
               cv::imshow("Detection", original);

               if (step_flag) {
                    int key = cv::waitKey(0);
                    if (key == 'q' || key == 1048689) { // 'q' key
                         cout << "Ending early." << endl;
                         break;
                    } else if (key == 'p' || key == 1048688) {
                         step_flag = 0;
                    }
               } else {
                    int key = cv::waitKey(1);
                    if (key == 'q' || key == 1048689) {
                         cout << "Ending early." << endl;
                         break;
                    } else if (key == 'p' || key == 1048688) {
                         step_flag = 1;
                    }
               }

          }
          frame_number++;
     }

     // Which track exhibited the most displacement?
     // Which track is the oldest?

     // We can only compare the detector to truth data if we have a hand
     // annotated file.
     if (hand_ann_found) {
          cout << "Scoring detector..." << endl;
          std::vector<std::string> names;
          names.push_back("diver:1");
          parser_tracks.score_detector(parser_truth, names);
     } else {
          cout << "WARNING: Can't score detector because hand annotated "
               << "file is missing" << endl;
     }

     cout << "Saving tracks to xml file" << endl;
     parser_tracks.write_annotation();

     plugin_manager_.close_libraries();

     cout << "Done Processing." << endl;
     return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: shape.hxx,v $
 * $Revision: 1.7 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef OOX_DRAWINGML_SHAPE_HXX
#define OOX_DRAWINGML_SHAPE_HXX

#include "oox/helper/propertymap.hxx"
#include "oox/drawingml/drawingmltypes.hxx"
#include "oox/drawingml/lineproperties.hxx"
#include "oox/drawingml/fillproperties.hxx"
#include "oox/drawingml/customshapeproperties.hxx"
#include "oox/drawingml/table/tableproperties.hxx"
#include "oox/drawingml/textliststyle.hxx"

#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/drawing/XDrawPage.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <vector>
#include <map>

namespace oox { namespace drawingml {

typedef ::std::map< ::rtl::OUString, ShapePtr > ShapeIdMap;

enum ShapeStyle
{
    SHAPESTYLE_ln,
    SHAPESTYLE_fill,
    SHAPESTYLE_effect,
    SHAPESTYLE_font
};
typedef std::map< ShapeStyle, ColorPtr > ShapeStylesColorMap;
typedef std::map< ShapeStyle, rtl::OUString > ShapeStylesIndexMap;

// ============================================================================

/** A callback that will be called after the ::com::sun::drawing::XShape has been
    created from the imported shape and it has been inserted into the draw page.

    An instance of a derived class of this callback can be set at every
    ::oox::drawingml::Shape instance to implement anything that needs a created
    and inserted XShape.
 */
class CreateShapeCallback
{
public:
    virtual             ~CreateShapeCallback();
    virtual void        onCreateXShape(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape ) = 0;
};
typedef ::boost::shared_ptr< CreateShapeCallback > CreateShapeCallbackRef;

// ============================================================================

class Shape
    : public boost::enable_shared_from_this< Shape >
{
public:

    Shape( const sal_Char* pServiceType = NULL );
    virtual ~Shape();

    rtl::OUString&                  getServiceName(){ return msServiceName; };
    void                            setServiceName( const sal_Char* pServiceName );
    PropertyMap&                    getShapeProperties(){ return maShapeProperties; };
    LinePropertiesPtr               getLineProperties(){ return mpLinePropertiesPtr; };
    FillPropertiesPtr               getFillProperties(){ return mpFillPropertiesPtr; };
    FillPropertiesPtr               getGraphicProperties() { return mpGraphicPropertiesPtr; };
    CustomShapePropertiesPtr        getCustomShapeProperties(){ return mpCustomShapePropertiesPtr; };
    table::TablePropertiesPtr       getTableProperties(){ if ( !mpTablePropertiesPtr.get() )
                                                            mpTablePropertiesPtr.reset( new table::TableProperties() );
                                                        return mpTablePropertiesPtr; };

    void                            setPosition( com::sun::star::awt::Point nPosition ){ maPosition = nPosition; };
    void                            setSize( com::sun::star::awt::Size aSize ){ maSize = aSize; };
    void                            setRotation( sal_Int32 nRotation ) { mnRotation = nRotation; };
    void                            setFlip( sal_Bool bFlipH, sal_Bool bFlipV ) { mbFlipH = bFlipH; mbFlipV = bFlipV; };
    void                            addChild( const ShapePtr pChildPtr ) { maChilds.push_back( pChildPtr ); };
    std::vector< ShapePtr >&        getChilds() { return maChilds; };

    void                            setName( const rtl::OUString& rName ) { msName = rName; };
    ::rtl::OUString                 getName( ) { return msName; }
    void                            setId( const rtl::OUString& rId ) { msId = rId; };
    void                            setSubType( sal_uInt32 nSubType ) { mnSubType = nSubType; };
    sal_Int32                       getSubType() const { return mnSubType; };
    void                            setIndex( sal_uInt32 nIndex ) { mnIndex = nIndex; };

    // setDefaults has to be called if styles are imported (OfficeXML is not storing properties having the default value)
    void                            setDefaults();

    void                setTextBody(const TextBodyPtr & pTextBody);
    TextBodyPtr         getTextBody();
    void                setMasterTextListStyle( const TextListStylePtr& pMasterTextListStyle );
    TextListStylePtr    getMasterTextListStyle() const { return mpMasterTextListStyle; };

    ShapeStylesColorMap&    getShapeStylesColor(){ return maShapeStylesColorMap; }
    ShapeStylesIndexMap&    getShapeStylesIndex(){ return maShapeStylesIndexMap; }

    inline void         setCreateShapeCallback( CreateShapeCallbackRef xCallback ) { mxCreateCallback = xCallback; }

    // addShape is creating and inserting the corresponding XShape.
    void                addShape(
                            const oox::core::XmlFilterBase& rFilterBase,
                            const ThemePtr& rxTheme,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
                            const ::com::sun::star::awt::Rectangle* pShapeRect = 0,
                            ShapeIdMap* pShapeMap = 0 );

    void                setXShape( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rXShape )
                            { mxShape = rXShape; };
    const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > &
                        getXShape() const { return mxShape; }

    virtual void        applyShapeReference( const Shape& rReferencedShape );

protected:

    ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
                        createAndInsert(
                            const ::oox::core::XmlFilterBase& rFilterBase,
                            const ::rtl::OUString& rServiceName,
                            const ThemePtr& rxTheme,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
                            const ::com::sun::star::awt::Rectangle* pShapeRect );

    void                addChilds(
                            const ::oox::core::XmlFilterBase& rFilterBase,
                            Shape& rMaster,
                            const ThemePtr& rxTheme,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
                            const ::com::sun::star::awt::Rectangle& rClientRect,
                            ShapeIdMap* pShapeMap );

    std::vector< ShapePtr >     maChilds;               // only used for group shapes
    TextBodyPtr                 mpTextBody;
    LinePropertiesPtr           mpLinePropertiesPtr;
    FillPropertiesPtr           mpFillPropertiesPtr;
    FillPropertiesPtr           mpGraphicPropertiesPtr;
    CustomShapePropertiesPtr    mpCustomShapePropertiesPtr;
    table::TablePropertiesPtr   mpTablePropertiesPtr;
    PropertyMap                 maShapeProperties;
    TextListStylePtr            mpMasterTextListStyle;
    ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > mxShape;

    rtl::OUString   msServiceName;
    rtl::OUString   msName;
    rtl::OUString   msId;
    sal_uInt32      mnSubType;      // if this type is not zero, then the shape is a placeholder
    sal_uInt32      mnIndex;

    ShapeStylesColorMap maShapeStylesColorMap;
    ShapeStylesIndexMap maShapeStylesIndexMap;

    com::sun::star::awt::Size       maSize;
    com::sun::star::awt::Point      maPosition;

private:

    void setShapeStyles( const ThemePtr& rxTheme, LineProperties& rLineProperties, FillProperties& rFillProperties );
    void setShapeStyleColors( const ::oox::core::XmlFilterBase& rFilterBase,
            LineProperties& rLineProperties, FillProperties& rFillProperties, PropertyMap& rShapeProperties );

    CreateShapeCallbackRef          mxCreateCallback;
    sal_Int32                       mnRotation;
    sal_Bool                        mbFlipH;
    sal_Bool                        mbFlipV;
};

::rtl::OUString GetShapeType( sal_Int32 nType );

} }

#endif  //  OOX_DRAWINGML_SHAPE_HXX
<commit_msg>INTEGRATION: CWS xmlfilter06 (1.5.6); FILE MERGED 2008/06/30 14:50:17 dr 1.5.6.8: #i10000# resync additions 2008/06/30 09:56:42 dr 1.5.6.7: RESYNC: (1.5-1.6); FILE MERGED 2008/06/23 12:55:43 dr 1.5.6.6: final chart font formatting 2008/06/12 15:01:20 dr 1.5.6.5: chart formatting, some more changes 2008/06/10 10:50:23 dr 1.5.6.4: chart area formatting, first steps 2008/06/09 15:16:11 dr 1.5.6.3: more chart line formatting, add line dashs to chart dash container 2008/06/06 16:27:51 dr 1.5.6.2: chart formatting: builtin line/fill/effect styles, manual line formatting 2008/05/27 10:40:27 dr 1.5.6.1: joined changes from CWS xmlfilter05<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: shape.hxx,v $
 * $Revision: 1.8 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef OOX_DRAWINGML_SHAPE_HXX
#define OOX_DRAWINGML_SHAPE_HXX

#include "oox/helper/propertymap.hxx"
#include "oox/drawingml/drawingmltypes.hxx"
#include "oox/drawingml/customshapeproperties.hxx"
#include "oox/drawingml/textliststyle.hxx"

#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/drawing/XDrawPage.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <vector>
#include <map>

namespace oox { namespace drawingml {

typedef ::std::map< ::rtl::OUString, ShapePtr > ShapeIdMap;

struct ShapeStyleRef
{
    Color               maPhClr;
    sal_Int32           mnThemedIdx;
};

typedef ::std::map< sal_Int32, ShapeStyleRef > ShapeStyleRefMap;

// ============================================================================

/** A callback that will be called after the ::com::sun::drawing::XShape has been
    created from the imported shape and it has been inserted into the draw page.

    An instance of a derived class of this callback can be set at every
    ::oox::drawingml::Shape instance to implement anything that needs a created
    and inserted XShape.
 */
class CreateShapeCallback
{
public:
    virtual             ~CreateShapeCallback();
    virtual void        onCreateXShape(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape ) = 0;
};
typedef ::boost::shared_ptr< CreateShapeCallback > CreateShapeCallbackRef;

// ============================================================================

class Shape
    : public boost::enable_shared_from_this< Shape >
{
public:

    Shape( const sal_Char* pServiceType = NULL );
    virtual ~Shape();

    rtl::OUString&                  getServiceName(){ return msServiceName; }
    void                            setServiceName( const sal_Char* pServiceName );

    PropertyMap&                    getShapeProperties(){ return maShapeProperties; }

    inline LineProperties&          getLineProperties() { return *mpLinePropertiesPtr; }
    inline const LineProperties&    getLineProperties() const { return *mpLinePropertiesPtr; }

    inline FillProperties&          getFillProperties() { return *mpFillPropertiesPtr; }
    inline const FillProperties&    getFillProperties() const { return *mpFillPropertiesPtr; }

    FillPropertiesPtr               getGraphicProperties() { return mpGraphicPropertiesPtr; }
    CustomShapePropertiesPtr        getCustomShapeProperties(){ return mpCustomShapePropertiesPtr; }

    table::TablePropertiesPtr       getTableProperties();

    void                            setPosition( com::sun::star::awt::Point nPosition ){ maPosition = nPosition; }
    void                            setSize( com::sun::star::awt::Size aSize ){ maSize = aSize; }
    void                            setRotation( sal_Int32 nRotation ) { mnRotation = nRotation; }
    void                            setFlip( sal_Bool bFlipH, sal_Bool bFlipV ) { mbFlipH = bFlipH; mbFlipV = bFlipV; }
    void                            addChild( const ShapePtr pChildPtr ) { maChildren.push_back( pChildPtr ); }
    std::vector< ShapePtr >&        getChildren() { return maChildren; }

    void                            setName( const rtl::OUString& rName ) { msName = rName; }
    ::rtl::OUString                 getName( ) { return msName; }
    void                            setId( const rtl::OUString& rId ) { msId = rId; }
    void                            setSubType( sal_uInt32 nSubType ) { mnSubType = nSubType; }
    sal_Int32                       getSubType() const { return mnSubType; }
    void                            setIndex( sal_uInt32 nIndex ) { mnIndex = nIndex; }

    // setDefaults has to be called if styles are imported (OfficeXML is not storing properties having the default value)
    void                            setDefaults();

    void                setTextBody(const TextBodyPtr & pTextBody);
    TextBodyPtr         getTextBody();
    void                setMasterTextListStyle( const TextListStylePtr& pMasterTextListStyle );
    TextListStylePtr    getMasterTextListStyle() const { return mpMasterTextListStyle; }

    inline ShapeStyleRefMap&        getShapeStyleRefs() { return maShapeStyleRefs; }
    inline const ShapeStyleRefMap&  getShapeStyleRefs() const { return maShapeStyleRefs; }
    const ShapeStyleRef*            getShapeStyleRef( sal_Int32 nRefType ) const;

    inline void         setCreateShapeCallback( CreateShapeCallbackRef xCallback ) { mxCreateCallback = xCallback; }

    // addShape is creating and inserting the corresponding XShape.
    void                addShape(
                            const oox::core::XmlFilterBase& rFilterBase,
                            const ThemePtr& rxTheme,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
                            const ::com::sun::star::awt::Rectangle* pShapeRect = 0,
                            ShapeIdMap* pShapeMap = 0 );

    void                setXShape( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rXShape )
                            { mxShape = rXShape; };
    const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > &
                        getXShape() const { return mxShape; }

    virtual void        applyShapeReference( const Shape& rReferencedShape );

protected:

    ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
                        createAndInsert(
                            const ::oox::core::XmlFilterBase& rFilterBase,
                            const ::rtl::OUString& rServiceName,
                            const ThemePtr& rxTheme,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
                            const ::com::sun::star::awt::Rectangle* pShapeRect );

    void                addChildren(
                            const ::oox::core::XmlFilterBase& rFilterBase,
                            Shape& rMaster,
                            const ThemePtr& rxTheme,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
                            const ::com::sun::star::awt::Rectangle& rClientRect,
                            ShapeIdMap* pShapeMap );

    std::vector< ShapePtr >     maChildren;               // only used for group shapes
    TextBodyPtr                 mpTextBody;
    LinePropertiesPtr           mpLinePropertiesPtr;
    FillPropertiesPtr           mpFillPropertiesPtr;
    FillPropertiesPtr           mpGraphicPropertiesPtr;
    CustomShapePropertiesPtr    mpCustomShapePropertiesPtr;
    table::TablePropertiesPtr   mpTablePropertiesPtr;
    PropertyMap                 maShapeProperties;
    TextListStylePtr            mpMasterTextListStyle;
    ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > mxShape;

    rtl::OUString   msServiceName;
    rtl::OUString    msName;
    rtl::OUString    msId;
    sal_uInt32      mnSubType;      // if this type is not zero, then the shape is a placeholder
    sal_uInt32      mnIndex;

    ShapeStyleRefMap   maShapeStyleRefs;

    com::sun::star::awt::Size       maSize;
    com::sun::star::awt::Point      maPosition;

private:
    CreateShapeCallbackRef          mxCreateCallback;
    sal_Int32                       mnRotation;
    sal_Bool                        mbFlipH;
    sal_Bool                        mbFlipV;
};

::rtl::OUString GetShapeType( sal_Int32 nType );

} }

#endif  //  OOX_DRAWINGML_SHAPE_HXX
<|endoftext|>


<commit_before>#include <string>
#include <map>
#include <vector>
#include <iostream>
#include <fstream>

#include <cereal/archives/binary.hpp>
#include <cereal/archives/portable_binary.hpp>
#include <cereal/types/vector.hpp>
#include <cereal/types/string.hpp>

#include "base64.h"
#include "deltagen.h"
#include "deltacommon.h"
#include "bscommon.h"

delta_info make_delta_info(recursive_directory_iterator &i)
{
	delta_info di;

	di.type = i->status().type();
	di.size = 0;
	if (is_regular_file(i->status()))
		di.size = file_size(i->path());
	di.hash = hash_entry(i);
	di.deleted = false;

	return di;
}

bool operator==(const delta_info &l, const delta_info &r) {
	return l.type == r.type && l.size == r.size && l.hash == r.hash;
}

bool has_option(char **begin, char **end, const std::string &option)
{
	return std::find(begin, end, option) != end;
}

#define HAS_OPTION(x) has_option(argv, argv + argc, x)
#define OPTION(x) (x < argc ? argv[x] : NULL)

int create(char *before_tree, char *after_tree, char *patch_file);
int apply(char *tree, char *patch_file);

int show_help(int result, std::string &bn) {
	if (result == 1) {
		printf("usage: %s <command> <args>\n\n", bn.c_str());
		printf("    create <before_tree> <after_tree> <patch_file>\n");
		printf("    apply <tree> <patch_file>\n");
	}
	return result;
}

int main(int argc, char **argv)
{

	std::string bn = basename(path(argv[0]));

	if (HAS_OPTION("-h") || HAS_OPTION("--help")) {
		return show_help(1, bn);
	}

	int result = 0;

	bool is_create = HAS_OPTION("create");
	bool is_apply = HAS_OPTION("apply");
	if (is_create ^ is_apply) {
		if (is_create)
			result = create(OPTION(2), OPTION(3), OPTION(4));
		else
			result = apply(OPTION(2), OPTION(3));
	}
	else {
		fprintf(stderr, "error: create or apply command must be specified\n");
		result = 1;
	}

	return show_help(result, bn);
}

std::string get_tree_hash(std::map<std::string, delta_info> tree) {
	unsigned char hash[crypto_generichash_BYTES];
	crypto_generichash_state state;
	crypto_generichash_init(&state, NULL, 0, sizeof(hash));
	for (auto &i : tree) {
		hash_delta_info(i.first, i.second, state);
	}
	crypto_generichash_final(&state, hash, sizeof(hash));
	return base64_encode((const unsigned char *) &hash[0], sizeof(hash));
}

int create(char *before_tree, char *after_tree, char *patch_file)
{
	if (!before_tree) {
		fprintf(stderr, "error: <before_tree> missing\n");
		return 1;
	}

	if (!after_tree) {
		fprintf(stderr, "error: <after_tree> missing\n");
		return 1;
	}

	if (!patch_file) {
		fprintf(stderr, "error: <patch_file> missing\n");
		return 1;
	}

	path before_path(before_tree);
	path after_path(after_tree);
	path patch_path(patch_file);

	if (!is_directory(before_path)) {
		fprintf(stderr, "error: <before_tree> '%s' is not a directory\n", before_path.generic_string().c_str());
		return 1;
	}

	if (!is_directory(after_path)) {
		fprintf(stderr, "error: <after_tree> option '%s' is not a directory\n", after_path.generic_string().c_str());
		return 1;
	}

	if (exists(patch_path)) {
		fprintf(stderr, "error: <patch_file> '%s' already exists\n", patch_path.generic_string().c_str());
		return 2;
	}

	std::map<std::string, delta_info> before_tree_state;
	std::map<std::string, delta_info> after_tree_state_unmod;
	std::map<std::string, delta_info> after_tree_state;

	delta_info deleted;
	deleted.deleted = true;

	printf("processing %s...\n", before_path.generic_string().c_str());
	process_tree(before_path, [&](path &path, recursive_directory_iterator &i) {
		auto before_info = make_delta_info(i);
		auto key(path.generic_string());
		before_tree_state[key] = before_info;
		after_tree_state[key] = deleted;
	});

	printf("processing %s...\n", after_path.generic_string().c_str());
	process_tree(after_path, [&](path &path, recursive_directory_iterator &i) {
		auto after_info = make_delta_info(i);
		auto key(path.generic_string());
		after_tree_state_unmod[key] = after_info;

		auto res = before_tree_state.find(key);
		if (res != end(before_tree_state)) {
			if (res->second == after_info) {
				after_tree_state.erase(key);
				return;
			}
		}

		after_tree_state[key] = after_info;
	});

	delta_op_toc toc;
	toc.before_hash = get_tree_hash(before_tree_state);
	toc.after_hash = get_tree_hash(after_tree_state_unmod);

	printf("before tree: '%s'\n", before_path.generic_string().c_str());
	printf("    hash: '%s'\n", toc.before_hash.c_str());
	std::cout << "    file count: " << before_tree_state.size() << std::endl;
	printf("after tree: '%s'\n", after_path.generic_string().c_str());
	printf("    hash: '%s'\n", toc.after_hash.c_str());
	std::cout << "    mod cnt: " << after_tree_state.size() << std::endl;

	printf("generating delta operations...\n");

	int a_op_cnt = 0;
	int b_op_cnt = 0;
	int d_op_cnt = 0;

	for (auto &i : after_tree_state) {
		auto &after_info = i.second;

		if (after_info.deleted) {
			d_op_cnt++;
			toc.ops.push_back(delta_op(delta_op_type::DELETE, i.first));
			continue;
		}

		auto res = before_tree_state.find(i.first);
		if (res == end(before_tree_state)) {
			a_op_cnt++;
			toc.ops.push_back(delta_op(delta_op_type::ADD, i.first));
			continue;
		}

		auto &before_info = res->second;
		if (before_info.type != after_info.type) {
			d_op_cnt++; a_op_cnt++;
			toc.ops.push_back(delta_op(delta_op_type::DELETE, i.first));
			toc.ops.push_back(delta_op(delta_op_type::ADD, i.first));
		}
		else {
			b_op_cnt++;
			toc.ops.push_back(delta_op(delta_op_type::PATCH, i.first));
		}
	}

	printf("  %4d deletions\n  %4d additions\n  %4d bpatches\n", d_op_cnt, a_op_cnt, b_op_cnt);

	std::ofstream ofs(patch_path.native().c_str(), std::ios::binary);
	cereal::PortableBinaryOutputArchive archive(ofs);
	archive(toc);
	ofs.close();

	return 0;
}

int apply(char *tree, char *patch_file)
{
	return 0;
}
<commit_msg>Make get_tree_hash argument const<commit_after>#include <string>
#include <map>
#include <vector>
#include <iostream>
#include <fstream>

#include <cereal/archives/binary.hpp>
#include <cereal/archives/portable_binary.hpp>
#include <cereal/types/vector.hpp>
#include <cereal/types/string.hpp>

#include "base64.h"
#include "deltagen.h"
#include "deltacommon.h"
#include "bscommon.h"

delta_info make_delta_info(recursive_directory_iterator &i)
{
	delta_info di;

	di.type = i->status().type();
	di.size = 0;
	if (is_regular_file(i->status()))
		di.size = file_size(i->path());
	di.hash = hash_entry(i);
	di.deleted = false;

	return di;
}

bool operator==(const delta_info &l, const delta_info &r) {
	return l.type == r.type && l.size == r.size && l.hash == r.hash;
}

bool has_option(char **begin, char **end, const std::string &option)
{
	return std::find(begin, end, option) != end;
}

#define HAS_OPTION(x) has_option(argv, argv + argc, x)
#define OPTION(x) (x < argc ? argv[x] : NULL)

int create(char *before_tree, char *after_tree, char *patch_file);
int apply(char *tree, char *patch_file);

int show_help(int result, std::string &bn) {
	if (result == 1) {
		printf("usage: %s <command> <args>\n\n", bn.c_str());
		printf("    create <before_tree> <after_tree> <patch_file>\n");
		printf("    apply <tree> <patch_file>\n");
	}
	return result;
}

int main(int argc, char **argv)
{

	std::string bn = basename(path(argv[0]));

	if (HAS_OPTION("-h") || HAS_OPTION("--help")) {
		return show_help(1, bn);
	}

	int result = 0;

	bool is_create = HAS_OPTION("create");
	bool is_apply = HAS_OPTION("apply");
	if (is_create ^ is_apply) {
		if (is_create)
			result = create(OPTION(2), OPTION(3), OPTION(4));
		else
			result = apply(OPTION(2), OPTION(3));
	}
	else {
		fprintf(stderr, "error: create or apply command must be specified\n");
		result = 1;
	}

	return show_help(result, bn);
}

std::string get_tree_hash(const std::map<std::string, delta_info> &tree) {
	unsigned char hash[crypto_generichash_BYTES];
	crypto_generichash_state state;
	crypto_generichash_init(&state, NULL, 0, sizeof(hash));
	for (auto &i : tree) {
		hash_delta_info(i.first, i.second, state);
	}
	crypto_generichash_final(&state, hash, sizeof(hash));
	return base64_encode((const unsigned char *) &hash[0], sizeof(hash));
}

int create(char *before_tree, char *after_tree, char *patch_file)
{
	if (!before_tree) {
		fprintf(stderr, "error: <before_tree> missing\n");
		return 1;
	}

	if (!after_tree) {
		fprintf(stderr, "error: <after_tree> missing\n");
		return 1;
	}

	if (!patch_file) {
		fprintf(stderr, "error: <patch_file> missing\n");
		return 1;
	}

	path before_path(before_tree);
	path after_path(after_tree);
	path patch_path(patch_file);

	if (!is_directory(before_path)) {
		fprintf(stderr, "error: <before_tree> '%s' is not a directory\n", before_path.generic_string().c_str());
		return 1;
	}

	if (!is_directory(after_path)) {
		fprintf(stderr, "error: <after_tree> option '%s' is not a directory\n", after_path.generic_string().c_str());
		return 1;
	}

	if (exists(patch_path)) {
		fprintf(stderr, "error: <patch_file> '%s' already exists\n", patch_path.generic_string().c_str());
		return 2;
	}

	std::map<std::string, delta_info> before_tree_state;
	std::map<std::string, delta_info> after_tree_state_unmod;
	std::map<std::string, delta_info> after_tree_state;

	delta_info deleted;
	deleted.deleted = true;

	printf("processing %s...\n", before_path.generic_string().c_str());
	process_tree(before_path, [&](path &path, recursive_directory_iterator &i) {
		auto before_info = make_delta_info(i);
		auto key(path.generic_string());
		before_tree_state[key] = before_info;
		after_tree_state[key] = deleted;
	});

	printf("processing %s...\n", after_path.generic_string().c_str());
	process_tree(after_path, [&](path &path, recursive_directory_iterator &i) {
		auto after_info = make_delta_info(i);
		auto key(path.generic_string());
		after_tree_state_unmod[key] = after_info;

		auto res = before_tree_state.find(key);
		if (res != end(before_tree_state)) {
			if (res->second == after_info) {
				after_tree_state.erase(key);
				return;
			}
		}

		after_tree_state[key] = after_info;
	});

	delta_op_toc toc;
	toc.before_hash = get_tree_hash(before_tree_state);
	toc.after_hash = get_tree_hash(after_tree_state_unmod);

	printf("before tree: '%s'\n", before_path.generic_string().c_str());
	printf("    hash: '%s'\n", toc.before_hash.c_str());
	std::cout << "    file count: " << before_tree_state.size() << std::endl;
	printf("after tree: '%s'\n", after_path.generic_string().c_str());
	printf("    hash: '%s'\n", toc.after_hash.c_str());
	std::cout << "    mod cnt: " << after_tree_state.size() << std::endl;

	printf("generating delta operations...\n");

	int a_op_cnt = 0;
	int b_op_cnt = 0;
	int d_op_cnt = 0;

	for (auto &i : after_tree_state) {
		auto &after_info = i.second;

		if (after_info.deleted) {
			d_op_cnt++;
			toc.ops.push_back(delta_op(delta_op_type::DELETE, i.first));
			continue;
		}

		auto res = before_tree_state.find(i.first);
		if (res == end(before_tree_state)) {
			a_op_cnt++;
			toc.ops.push_back(delta_op(delta_op_type::ADD, i.first));
			continue;
		}

		auto &before_info = res->second;
		if (before_info.type != after_info.type) {
			d_op_cnt++; a_op_cnt++;
			toc.ops.push_back(delta_op(delta_op_type::DELETE, i.first));
			toc.ops.push_back(delta_op(delta_op_type::ADD, i.first));
		}
		else {
			b_op_cnt++;
			toc.ops.push_back(delta_op(delta_op_type::PATCH, i.first));
		}
	}

	printf("  %4d deletions\n  %4d additions\n  %4d bpatches\n", d_op_cnt, a_op_cnt, b_op_cnt);

	std::ofstream ofs(patch_path.native().c_str(), std::ios::binary);
	cereal::PortableBinaryOutputArchive archive(ofs);
	archive(toc);
	ofs.close();

	return 0;
}

int apply(char *tree, char *patch_file)
{
	return 0;
}
<|endoftext|>


<commit_before>#define BOOST_TEST_STATIC_LINK

#include <boost/test/unit_test.hpp>
#include "./../../fixed_point_lib/src/fixed_point.hpp"

#include <iomanip>
#include <sstream>

namespace core { namespace unit_tests {
    namespace {
        using core::S_fixed_point;
        using core::U_fixed_point;

        double r(double low, double high)
        {
            return low + std::rand() / (double(RAND_MAX) / (high - low));
        }
    }

    BOOST_AUTO_TEST_SUITE(Precision)

#define ITERATIONS size_t(1E+6)
#define FMIN(type) double(std::numeric_limits<type>::min())
#define FMAX(type) double(std::numeric_limits<type>::max())

#define U(n, f, name) typedef UOU_fixed_point<n, f>::type name
#define S(n, f, name) typedef SOU_fixed_point<n, f>::type name

    BOOST_AUTO_TEST_CASE(sum)
    {
#define PRECISION_TEST(t1, t2, error) \
    BOOST_FOREACH(size_t it, boost::irange<size_t>(0, ITERATIONS, 1)) { \
    /* shortening range not to take care about rounding errors at the bounds */ \
        double u1 = r(FMIN(t1) + 1u, FMAX(t1) - 1u); \
        double u2 = r(std::max(FMIN(t1) + 1u - u1, FMIN(t2) + 1u), \
            std::min(FMAX(t1) - 1u - u1, FMAX(t2) - 1u)); \
        \
        t1 const a(u1); t2 const b(u2); \
        if (std::fabs(double(a + b) - (u1 + u2)) > error) { \
            std::stringstream message_stream; \
            message_stream \
                << std::setprecision(5) \
                << u1 \
                << " + " \
                << u2 \
                << ": summation was made with unexpected rounding error"; \
            \
            BOOST_CHECK_MESSAGE(false, message_stream.str()); \
        } \
    }
        U(28,13,t1); U(37,15,t2); PRECISION_TEST(t1,t2, 1E-3); // floor(log(10,2^13-1))-1=2
        S(56,34,t3); S(56,47,t4); PRECISION_TEST(t3,t4, 1E-9); // floor(log(10,2^34-1))-1=9
        S(61,52,t5); S(61,52,t6); PRECISION_TEST(t5,t6, 1E-14); // floor(log(10,2^52-1))-1=14
        U(53,23,t7); S(23,22,t8); PRECISION_TEST(t7,t8, 1E-5); // floor(log(10, 2^22-1))-1=5

#undef PRECISION_TEST
    }

#define PRECISION_TEST(fp, low, high, f, error) \
    BOOST_FOREACH(size_t i, boost::irange<size_t>(0, ITERATIONS, 1)) \
    { \
        double const u(r(low, high)); \
        fp::##f##_type const x = std::##f##(fp(u)); \
        \
        if (std::fabs(double(x) - std::##f##(u)) > error) { \
            std::stringstream message_stream; \
            message_stream \
                << std::setprecision(9) \
                << "unexpected accuracy: " \
                << #f \
                << "(" \
                << u \
                << ") = " \
                << std::##f(u) \
                << " was computed as " \
                << double(x); \
            \
            BOOST_CHECK_MESSAGE(false, message_stream.str()); \
        } \
    }

    BOOST_AUTO_TEST_SUITE_END()
}}
<commit_msg>precision.cpp: tests for +,-,*,/<commit_after>#define BOOST_TEST_STATIC_LINK

#include <boost/test/unit_test.hpp>
#include "./../../fixed_point_lib/src/fixed_point.hpp"

#include <iomanip>
#include <sstream>

#include <exception>

namespace core { namespace unit_tests {
    namespace {
        using core::S_fixed_point;
        using core::U_fixed_point;

        double r(double low, double high)
        {
            if (low > high) {
                throw std::exception("illegal range");
            }
            return low + std::rand() / (double(RAND_MAX) / (high - low));
        }
    }

    BOOST_AUTO_TEST_SUITE(Precision)

#define ITERATIONS size_t(1E+6)
#define FMIN(type) double(std::numeric_limits<type>::min())
#define FMAX(type) double(std::numeric_limits<type>::max())

#define U(n, f, name) typedef UOU_fixed_point<n, f>::type name
#define S(n, f, name) typedef SOU_fixed_point<n, f>::type name

    BOOST_AUTO_TEST_CASE(sum)
    {
#define PRECISION_TEST(t, error) \
    BOOST_FOREACH(size_t it, boost::irange<size_t>(0, ITERATIONS, 1)) { \
    /* shortening range not to take care about rounding errors at the bounds */ \
        double u1 = r(FMIN(t) + 1u, FMAX(t) - 1u); \
        double u2 = r(FMIN(t) + 1u, FMAX(t) - 1u); \
        \
        t const a(u1); t const b(u2); \
        try { \
            if (std::fabs(double(a + b) - (u1 + u2)) > 2 * error) { \
                std::stringstream message_stream; \
                message_stream \
                    << std::setprecision(5) \
                    << u1 \
                    << " + " \
                    << u2 \
                    << ": sum was made with unexpected rounding error"; \
                \
                BOOST_CHECK_MESSAGE(false, message_stream.str()); \
            } \
        } \
        catch(std::exception){ \
            std::stringstream message_stream; \
            message_stream \
                << u1 << " " << u2; \
            BOOST_CHECK_MESSAGE(false, message_stream.str()); \
        } \
    }

        U(28,13,t1); PRECISION_TEST(t1, 1E-2); // floor(log(10,2^13-1))-1=2
        S(56,34,t2); PRECISION_TEST(t2, 1E-9); // floor(log(10,2^34-1))-1=9
        S(61,52,t3); PRECISION_TEST(t3, 1E-14); // floor(log(10,2^52-1))-1=14
        U(53,23,t4); PRECISION_TEST(t4, 1E-5); // floor(log(10, 2^22-1))-1=5

#undef PRECISION_TEST
    }

    BOOST_AUTO_TEST_CASE(subtraction)
    {
#define PRECISION_TEST(t, error) \
    BOOST_FOREACH(size_t it, boost::irange<size_t>(0, ITERATIONS, 1)) { \
    /* shortening range not to take care about rounding errors at the bounds */ \
        double u1 = r(FMIN(t) + 1u, FMAX(t) - 1u); \
        double u2 = r(FMIN(t) + 1u, FMAX(t) - 1u); \
        \
        t const a(u1); t const b(u2); \
        try { \
            if (std::fabs(double(a - b) - (u1 - u2)) > 2 * error) { \
                std::stringstream message_stream; \
                message_stream \
                    << std::setprecision(5) \
                    << u1 \
                    << " - " \
                    << u2 \
                    << ": subtraction was made with unexpected rounding error"; \
                \
                BOOST_CHECK_MESSAGE(false, message_stream.str()); \
            } \
        } \
        catch(std::exception){ \
            std::stringstream message_stream; \
            message_stream \
                << u1 << " " << u2; \
            BOOST_CHECK_MESSAGE(false, message_stream.str()); \
        } \
    }
        S(28,13,t1); PRECISION_TEST(t1, 1E-2); // floor(log(10,2^13-1))-1=2
        S(56,34,t2); PRECISION_TEST(t2, 1E-9); // floor(log(10,2^34-1))-1=9
        S(61,52,t3); PRECISION_TEST(t3, 1E-14); // floor(log(10,2^52-1))-1=14
        S(53,23,t4); PRECISION_TEST(t4, 1E-5); // floor(log(10, 2^22-1))-1=5

#undef PRECISION_TEST
    }

    BOOST_AUTO_TEST_CASE(multiplication)
    {
#define PRECISION_TEST(t1, t2, error) \
    BOOST_FOREACH(size_t it, boost::irange<size_t>(0, ITERATIONS, 1)) { \
        double u1 = r(FMIN(t1), FMAX(t1)); \
        double u2 = r(FMIN(t2), FMAX(t2)); \
        \
        try { \
            t1 const a(u1); t2 const b(u2); \
            if (std::fabs(double(a * b) - (u1 * u2)) > error * (std::fabs(u1) + std::fabs(u2))) { \
                std::stringstream message_stream; \
                message_stream \
                    << std::setprecision(5) \
                    << u1 \
                    << " * " \
                    << u2 \
                    << ": multiplication was made with unexpected rounding error"; \
                \
                BOOST_CHECK_MESSAGE(false, message_stream.str()); \
            } \
        } \
        catch(std::exception){ \
            std::stringstream message_stream; \
            message_stream \
                << u1 << " " << u2; \
            BOOST_CHECK_MESSAGE(false, message_stream.str()); \
        } \
    }

        U(18,13,t1); U(20,15,t2); PRECISION_TEST(t1,t2, 1E-3); // floor(log(10,2^13-1))-1=2
        S(24,23,t3); S(30,22,t4); PRECISION_TEST(t3,t4, 1E-5); // floor(log(10,2^22-1))-1=5
        S(30,29,t5); S(33,33,t6); PRECISION_TEST(t5,t6, 1E-7); // floor(log(10,2^22-1))-1=7

#undef PRECISION_TEST
    }

    BOOST_AUTO_TEST_CASE(division)
    {
#define PRECISION_TEST(t1, t2, error) \
    BOOST_FOREACH(size_t it, boost::irange<size_t>(0, ITERATIONS, 1)) { \
        double u1 = r(FMIN(t1), FMAX(t1)); \
        double u2 = r(FMIN(t2), FMAX(t2)); \
        if (u2 == 0) { \
            continue; \
        } \
        \
        try { \
            t1 const a(u1); t2 const b(u2); \
            if (std::fabs(double(a / b) - (u1 / u2)) > error * (u1 + u2) / (u2 * (u2 - error))) { \
                std::stringstream message_stream; \
                message_stream \
                    << std::setprecision(5) \
                    << u1 \
                    << " / " \
                    << u2 \
                    << ": division was made with unexpected rounding error"; \
                \
                BOOST_CHECK_MESSAGE(false, message_stream.str()); \
            } \
        } \
        catch(std::exception){ \
            std::stringstream message_stream; \
            message_stream \
                << u1 << " " << u2; \
            BOOST_CHECK_MESSAGE(false, message_stream.str()); \
        } \
    }

        U(18,13,t1); U(20,15,t2); PRECISION_TEST(t1,t2, 1E-2); // floor(log(10,2^13-1))-1=2
        S(24,23,t3); S(30,22,t4); PRECISION_TEST(t3,t4, 1E-5); // floor(log(10,2^22-1))-1=5
        S(30,29,t5); S(33,33,t6); PRECISION_TEST(t5,t6, 1E-7); // floor(log(10,2^22-1))-1=7

#undef PRECISION_TEST
    }

#define PRECISION_TEST(fp, low, high, f, error) \
    BOOST_FOREACH(size_t i, boost::irange<size_t>(0, ITERATIONS, 1)) \
    { \
        double const u(r(low, high)); \
        fp::##f##_type const x = std::##f##(fp(u)); \
        \
        if (std::fabs(double(x) - std::##f##(u)) > error) { \
            std::stringstream message_stream; \
            message_stream \
                << std::setprecision(9) \
                << "unexpected accuracy: " \
                << #f \
                << "(" \
                << u \
                << ") = " \
                << std::##f(u) \
                << " was computed as " \
                << double(x); \
            \
            BOOST_CHECK_MESSAGE(false, message_stream.str()); \
        } \
    }

    BOOST_AUTO_TEST_SUITE_END()
}}
<|endoftext|>