1e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen/*
2e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * Copyright (C) 2011 The Android Open Source Project
3e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *
4e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * Licensed under the Apache License, Version 2.0 (the "License");
5e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * you may not use this file except in compliance with the License.
6e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * You may obtain a copy of the License at
7e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *
8e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *      http://www.apache.org/licenses/LICENSE-2.0
9e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *
10e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * Unless required by applicable law or agreed to in writing, software
11e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * distributed under the License is distributed on an "AS IS" BASIS,
12e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * See the License for the specific language governing permissions and
14e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * limitations under the License.
15e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen */
16e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
17e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen/*
18e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#sourcefile  vpmotion/vp_motionmodel.c
19e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#category    motion-model
20e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen*
21e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen* Copyright 1998 Sarnoff Corporation
22e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen* All Rights Reserved
23e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen*
24e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen* Modification History
25e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen*      Date: 02/14/98
26e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen*      Author: supuns
27e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen*      Shop Order: 17xxx
28e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen*              @(#) $Id: vp_motionmodel.c,v 1.4 2011/06/17 14:04:33 mbansal Exp $
29e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen*/
30e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
31e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen/*
32e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen* ===================================================================
33e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen* Include Files
34e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen*/
35e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
36e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#include <string.h> /* memmove */
37e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#include <math.h>
38e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#include "vp_motionmodel.h"
39e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
40e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen/* Static Functions */
41e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenstatic
42e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chendouble Det3(double m[3][3])
43e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{
44e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  double result;
45e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
46e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  result =
47e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][0]*m[1][1]*m[2][2] + m[0][1]*m[1][2]*m[2][0] +
48e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][2]*m[1][0]*m[2][1] - m[0][2]*m[1][1]*m[2][0] -
49e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][0]*m[1][2]*m[2][1] - m[0][1]*m[1][0]*m[2][2];
50e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
51e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  return(result);
52e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen}
53e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
54e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chentypedef double MATRIX[4][4];
55e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
56e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenstatic
57e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chendouble Det4(MATRIX m)
58e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{
59e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    /* ==> This is a poor implementation of determinant.
60e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       Writing the formula out in closed form is unnecessarily complicated
61e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       and mistakes are easy to make. */
62e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  double result;
63e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
64e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  result=
65e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][3] *m[1][2] *m[2][1] *m[3][0] - m[0][2] *m[1][3] *m[2][1] *m[3][0] - m[0][3] *m[1][1] *m[2][2] *m[3][0] +
66e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][1] *m[1][3] *m[2][2] *m[3][0] + m[0][2] *m[1][1] *m[2][3] *m[3][0] - m[0][1] *m[1][2] *m[2][3] *m[3][0] - m[0][3] *m[1][2] *m[2][0] *m[3][1] +
67e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][2] *m[1][3] *m[2][0] *m[3][1] + m[0][3] *m[1][0] *m[2][2] *m[3][1] - m[0][0] *m[1][3] *m[2][2] *m[3][1] - m[0][2] *m[1][0] *m[2][3] *m[3][1] +
68e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][0] *m[1][2] *m[2][3] *m[3][1] + m[0][3] *m[1][1] *m[2][0] *m[3][2] - m[0][1] *m[1][3] *m[2][0] *m[3][2] - m[0][3] *m[1][0] *m[2][1] *m[3][2] +
69e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][0] *m[1][3] *m[2][1] *m[3][2] + m[0][1] *m[1][0] *m[2][3] *m[3][2] - m[0][0] *m[1][1] *m[2][3] *m[3][2] - m[0][2] *m[1][1] *m[2][0] *m[3][3] +
70e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][1] *m[1][2] *m[2][0] *m[3][3] + m[0][2] *m[1][0] *m[2][1] *m[3][3] - m[0][0] *m[1][2] *m[2][1] *m[3][3] - m[0][1] *m[1][0] *m[2][2] *m[3][3] +
71e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][0] *m[1][1] *m[2][2] *m[3][3];
72e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  /*
73e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][0]*m[1][1]*m[2][2]*m[3][3]-m[0][1]*m[1][0]*m[2][2]*m[3][3]+
74e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][1]*m[1][2]*m[2][0]*m[3][3]-m[0][2]*m[1][1]*m[2][0]*m[3][3]+
75e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][2]*m[1][0]*m[2][1]*m[3][3]-m[0][0]*m[1][2]*m[2][1]*m[3][3]+
76e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][0]*m[1][2]*m[2][3]*m[3][1]-m[0][2]*m[1][0]*m[2][3]*m[3][1]+
77e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][2]*m[1][3]*m[2][0]*m[3][1]-m[0][3]*m[1][2]*m[2][0]*m[3][1]+
78e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][3]*m[1][0]*m[2][2]*m[3][1]-m[0][0]*m[1][3]*m[2][2]*m[3][1]+
79e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][0]*m[1][3]*m[2][1]*m[3][2]-m[0][3]*m[1][0]*m[2][3]*m[3][2]+
80e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][1]*m[1][0]*m[2][3]*m[3][2]-m[0][0]*m[1][1]*m[2][0]*m[3][2]+
81e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][3]*m[1][1]*m[2][0]*m[3][2]-m[0][1]*m[1][3]*m[2][1]*m[3][2]+
82e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][1]*m[1][3]*m[2][2]*m[3][0]-m[0][3]*m[1][1]*m[2][2]*m[3][0]+
83e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][2]*m[1][1]*m[2][3]*m[3][0]-m[0][1]*m[1][2]*m[2][3]*m[3][0]+
84e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m[0][3]*m[1][2]*m[2][1]*m[3][0]-m[0][2]*m[1][3]*m[2][1]*m[3][0];
85e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    */
86e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  return(result);
87e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen}
88e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
89e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenstatic
90e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenint inv4Mat(const VP_MOTION* in, VP_MOTION* out)
91e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{
92e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    /* ==> This is a poor implementation of inversion.  The determinant
93e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       method is O(N^4), i.e. unnecessarily slow, and not numerically accurate.
94e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       The real complexity of inversion is O(N^3), and is best done using
95e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       LU decomposition. */
96e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
97e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  MATRIX inmat,outmat;
98e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  int i, j, k, l, m, n,ntemp;
99e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  double mat[3][3], indet, temp;
100e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
101e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  /* check for non-empty structures structure */
102e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  if (((VP_MOTION *) NULL == in) || ((VP_MOTION *) NULL == out)) {
103e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    return 1;
104e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  }
105e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
106e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  for(k=0,i=0;i<4;i++)
107e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    for(j=0;j<4;j++,k++)
108e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      inmat[i][j]=(double)in->par[k];
109e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
110e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  indet = Det4(inmat);
111e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  if (indet==0) return(-1);
112e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
113e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  for (i=0;i<4;i++) {
114e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    for (j=0;j<4;j++) {
115e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      m = 0;
116e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      for (k=0;k<4;k++) {
117e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    if (i != k) {
118e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      n = 0;
119e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      for (l=0;l<4;l++)
120e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        if (j != l) {
121e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen          mat[m][n] = inmat[k][l];
122e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen          n++;
123e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        }
124e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      m++;
125e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    }
126e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      }
127e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
128e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      temp = -1.;
129e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      ntemp = (i +j ) %2;
130e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if( ntemp == 0)  temp = 1.;
131e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
132e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      outmat[j][i] = temp * Det3(mat)/indet;
133e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    }
134e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  }
135e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
136e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  for(k=0,i=0;i<4;i++)
137e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    for(j=0;j<4;j++,k++)
138e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      out->par[k]=(VP_PAR)outmat[i][j]; /*lint !e771*/
139e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
140e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  return(0);
141e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen}
142e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
143e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen/*
144e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen* ===================================================================
145e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen* Public Functions
146e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#htmlstart
147e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen*/
148e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
149e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen/*
150e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * ===================================================================
151e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#fn vp_invert_motion
152e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#ft invert a motion
153e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#fd DEFINITION
154e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       Bool
155e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       vp_invert_motion(const VP_MOTION* in,VP_MOTION* out)
156e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#fd PURPOSE
157e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       This inverts the motion given in 'in'.
158e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       All motion models upto VP_MOTION_SEMI_PROJ_3D are supported.
159e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       It is assumed that the all 16 parameters are properly
160e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       initialized although you may not be using them. You could
161e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       use the VP_KEEP_ macro's defined in vp_motionmodel.h to set
162e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       the un-initialized parameters. This uses a 4x4 matrix invertion
163e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       function internally.
164e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       It is SAFE to pass the same pointer as both the 'in' and 'out'
165e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       parameters.
166e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#fd INPUTS
167e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       in  - input motion
168e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#fd OUTPUTS
169e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       out - output inverted motion. If singular matrix uninitialized.
170e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen             if MWW(in) is non-zero it is also normalized.
171e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#fd RETURNS
172e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       FALSE - matrix is singular or motion model not supported
173e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       TRUE  - otherwise
174e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#fd SIDE EFFECTS
175e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       None
176e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#endfn
177e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen*/
178e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
179e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenint vp_invert_motion(const VP_MOTION* in,VP_MOTION* out)
180e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{
181e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  int refid;
182e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
183e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  /* check for non-empty structures structure */
184e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  if (((VP_MOTION *) NULL == in) || ((VP_MOTION *) NULL == out)) {
185e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    return FALSE;
186e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  }
187e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
188e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  if (in->type>VP_MOTION_SEMI_PROJ_3D) {
189e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    return FALSE;
190e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  }
191e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
192e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  if (inv4Mat(in,out)<0)
193e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    return FALSE;
194e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
195e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  /*VP_NORMALIZE(*out);*/
196e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  out->type = in->type;
197e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  refid=in->refid;
198e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  out->refid=in->insid;
199e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  out->insid=refid;
200e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  return TRUE;
201e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen}
202e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
203e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen/*
204e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen* ===================================================================
205e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#fn vp_cascade_motion
206e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#ft Cascade two motion transforms
207e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#fd DEFINITION
208e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      Bool
209e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      vp_cascade_motion(const VP_MOTION* InAB,const VP_MOTION* InBC,VP_MOTION* OutAC)
210e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#fd PURPOSE
211e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      Given Motion Transforms A->B and B->C, this function will
212e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      generate a New Motion that describes the transformation
213e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      from A->C.
214e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      More specifically, OutAC = InBC * InAC.
215e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      This function works ok if InAB,InBC and OutAC are the same pointer.
216e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#fd INPUTS
217e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      InAB - First Motion Transform
218e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      InBC - Second Motion Tranform
219e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#fd OUTPUTS
220e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      OutAC - Cascaded Motion
221e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#fd RETURNS
222e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      FALSE - motion model not supported
223e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      TRUE  - otherwise
224e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#fd SIDE EFFECTS
225e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      None
226e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#endfn
227e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen*/
228e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
229e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenint vp_cascade_motion(const VP_MOTION* InA, const VP_MOTION* InB,VP_MOTION* Out)
230e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{
231e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    /* ==> This is a poor implementation of matrix multiplication.
232e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       Writing the formula out in closed form is unnecessarily complicated
233e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen       and mistakes are easy to make. */
234e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  VP_PAR mxx,mxy,mxz,mxw;
235e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  VP_PAR myx,myy,myz,myw;
236e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  VP_PAR mzx,mzy,mzz,mzw;
237e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  VP_PAR mwx,mwy,mwz,mww;
238e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
239e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  /* check for non-empty structures structure */
240e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  if (((VP_MOTION *) NULL == InA) || ((VP_MOTION *) NULL == InB) ||
241e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      ((VP_MOTION *) NULL == Out)) {
242e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    return FALSE;
243e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  }
244e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
245e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  if (InA->type>VP_MOTION_PROJ_3D) {
246e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    return FALSE;
247e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  }
248e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
249e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  if (InB->type>VP_MOTION_PROJ_3D) {
250e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    return FALSE;
251e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  }
252e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
253e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  mxx = MXX(*InB)*MXX(*InA)+MXY(*InB)*MYX(*InA)+MXZ(*InB)*MZX(*InA)+MXW(*InB)*MWX(*InA);
254e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  mxy = MXX(*InB)*MXY(*InA)+MXY(*InB)*MYY(*InA)+MXZ(*InB)*MZY(*InA)+MXW(*InB)*MWY(*InA);
255e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  mxz = MXX(*InB)*MXZ(*InA)+MXY(*InB)*MYZ(*InA)+MXZ(*InB)*MZZ(*InA)+MXW(*InB)*MWZ(*InA);
256e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  mxw = MXX(*InB)*MXW(*InA)+MXY(*InB)*MYW(*InA)+MXZ(*InB)*MZW(*InA)+MXW(*InB)*MWW(*InA);
257e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  myx = MYX(*InB)*MXX(*InA)+MYY(*InB)*MYX(*InA)+MYZ(*InB)*MZX(*InA)+MYW(*InB)*MWX(*InA);
258e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  myy = MYX(*InB)*MXY(*InA)+MYY(*InB)*MYY(*InA)+MYZ(*InB)*MZY(*InA)+MYW(*InB)*MWY(*InA);
259e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  myz = MYX(*InB)*MXZ(*InA)+MYY(*InB)*MYZ(*InA)+MYZ(*InB)*MZZ(*InA)+MYW(*InB)*MWZ(*InA);
260e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  myw = MYX(*InB)*MXW(*InA)+MYY(*InB)*MYW(*InA)+MYZ(*InB)*MZW(*InA)+MYW(*InB)*MWW(*InA);
261e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  mzx = MZX(*InB)*MXX(*InA)+MZY(*InB)*MYX(*InA)+MZZ(*InB)*MZX(*InA)+MZW(*InB)*MWX(*InA);
262e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  mzy = MZX(*InB)*MXY(*InA)+MZY(*InB)*MYY(*InA)+MZZ(*InB)*MZY(*InA)+MZW(*InB)*MWY(*InA);
263e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  mzz = MZX(*InB)*MXZ(*InA)+MZY(*InB)*MYZ(*InA)+MZZ(*InB)*MZZ(*InA)+MZW(*InB)*MWZ(*InA);
264e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  mzw = MZX(*InB)*MXW(*InA)+MZY(*InB)*MYW(*InA)+MZZ(*InB)*MZW(*InA)+MZW(*InB)*MWW(*InA);
265e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  mwx = MWX(*InB)*MXX(*InA)+MWY(*InB)*MYX(*InA)+MWZ(*InB)*MZX(*InA)+MWW(*InB)*MWX(*InA);
266e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  mwy = MWX(*InB)*MXY(*InA)+MWY(*InB)*MYY(*InA)+MWZ(*InB)*MZY(*InA)+MWW(*InB)*MWY(*InA);
267e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  mwz = MWX(*InB)*MXZ(*InA)+MWY(*InB)*MYZ(*InA)+MWZ(*InB)*MZZ(*InA)+MWW(*InB)*MWZ(*InA);
268e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  mww = MWX(*InB)*MXW(*InA)+MWY(*InB)*MYW(*InA)+MWZ(*InB)*MZW(*InA)+MWW(*InB)*MWW(*InA);
269e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
270e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  MXX(*Out)=mxx; MXY(*Out)=mxy; MXZ(*Out)=mxz; MXW(*Out)=mxw;
271e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  MYX(*Out)=myx; MYY(*Out)=myy; MYZ(*Out)=myz; MYW(*Out)=myw;
272e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  MZX(*Out)=mzx; MZY(*Out)=mzy; MZZ(*Out)=mzz; MZW(*Out)=mzw;
273e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  MWX(*Out)=mwx; MWY(*Out)=mwy; MWZ(*Out)=mwz; MWW(*Out)=mww;
274e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  /* VP_NORMALIZE(*Out); */
275e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  Out->type= (InA->type > InB->type) ? InA->type : InB->type;
276e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  Out->refid=InA->refid;
277e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  Out->insid=InB->insid;
278e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
279e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  return TRUE;
280e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen}
281e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
282e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen/*
283e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen* ===================================================================
284e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#fn vp_copy_motion
285e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#ft Copies the source motion to the destination motion.
286e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#fd DEFINITION
287e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    void
288e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    vp_copy_motion  (const VP_MOTION *src, VP_MOTION *dst)
289e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#fd PURPOSE
290e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    Copies the source motion to the destination motion.
291e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        It is OK if src == dst.
292e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    NOTE THAT THE SOURCE IS THE FIRST ARGUMENT.
293e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    This is different from some of the other VP
294e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    copy functions.
295e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#fd INPUTS
296e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    src is the source motion
297e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    dst is the destination motion
298e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#fd RETURNS
299e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    void
300e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#endfn
301e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen*/
302e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenvoid vp_copy_motion  (const VP_MOTION *src, VP_MOTION *dst)
303e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{
304e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  /* Use memmove rather than memcpy because it handles overlapping memory
305e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen     OK. */
306e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  memmove(dst, src, sizeof(VP_MOTION));
307e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  return;
308e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen} /* vp_copy_motion() */
309e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
310e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#define VP_SQR(x)   ( (x)*(x) )
311e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chendouble vp_motion_cornerdiff(const VP_MOTION *mot_a, const VP_MOTION *mot_b,
312e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen                     int xo, int yo, int w, int h)
313e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{
314e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  double ax1, ay1, ax2, ay2, ax3, ay3, ax4, ay4;
315e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  double bx1, by1, bx2, by2, bx3, by3, bx4, by4;
316e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  double err;
317e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
318e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  /*lint -e639 -e632 -e633 */
319e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  VP_WARP_POINT_2D(xo, yo,         *mot_a, ax1, ay1);
320e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  VP_WARP_POINT_2D(xo+w-1, yo,     *mot_a, ax2, ay2);
321e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  VP_WARP_POINT_2D(xo+w-1, yo+h-1, *mot_a, ax3, ay3);
322e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  VP_WARP_POINT_2D(xo, yo+h-1,     *mot_a, ax4, ay4);
323e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  VP_WARP_POINT_2D(xo, yo,         *mot_b, bx1, by1);
324e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  VP_WARP_POINT_2D(xo+w-1, yo,     *mot_b, bx2, by2);
325e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  VP_WARP_POINT_2D(xo+w-1, yo+h-1, *mot_b, bx3, by3);
326e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  VP_WARP_POINT_2D(xo, yo+h-1,     *mot_b, bx4, by4);
327e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  /*lint +e639 +e632 +e633 */
328e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
329e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  err = 0;
330e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  err += (VP_SQR(ax1 - bx1) + VP_SQR(ay1 - by1));
331e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  err += (VP_SQR(ax2 - bx2) + VP_SQR(ay2 - by2));
332e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  err += (VP_SQR(ax3 - bx3) + VP_SQR(ay3 - by3));
333e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  err += (VP_SQR(ax4 - bx4) + VP_SQR(ay4 - by4));
334e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
335e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  return(sqrt(err));
336e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen}
337e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
338e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenint vp_zoom_motion2d(VP_MOTION* in, VP_MOTION* out,
339e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen                 int n, int w, int h, double zoom)
340e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{
341e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  int ii;
342e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  VP_PAR inv_zoom;
343e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  VP_PAR cx, cy;
344e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  VP_MOTION R2r,R2f;
345e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  VP_MOTION *res;
346e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
347e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  /* check for non-empty structures structure */
348e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  if (((VP_MOTION *) NULL == in)||(zoom <= 0.0)||(w <= 0)||(h <= 0)) {
349e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    return FALSE;
350e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  }
351e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
352e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  /* ==> Not sure why the special case of out=NULL is necessary.  Why couldn't
353e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen     the caller just pass the same pointer for both in and out? */
354e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  res = ((VP_MOTION *) NULL == out)?in:out;
355e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
356e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  cx = (VP_PAR) (w/2.0);
357e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  cy = (VP_PAR) (h/2.0);
358e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
359e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  VP_MOTION_ID(R2r);
360e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  inv_zoom = (VP_PAR)(1.0/zoom);
361e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  MXX(R2r) = inv_zoom;
362e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  MYY(R2r) = inv_zoom;
363e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  MXW(R2r)=cx*(((VP_PAR)1.0) - inv_zoom);
364e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  MYW(R2r)=cy*(((VP_PAR)1.0) - inv_zoom);
365e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
366e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  VP_KEEP_AFFINE_2D(R2r);
367e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
368e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  for(ii=0;ii<n;ii++) {
369e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    (void) vp_cascade_motion(&R2r,in+ii,&R2f);
370e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    res[ii]=R2f;
371e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  }
372e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
373e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  return TRUE;
374e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen} /* vp_zoom_motion2d() */
375e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
376e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen/* =================================================================== */
377e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen/* end vp_motionmodel.c */
378