FreeRDP
prim_shift.c
1 /* FreeRDP: A Remote Desktop Protocol Client
2  * Shift operations.
3  * vi:ts=4 sw=4:
4  *
5  * (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
6  * Licensed under the Apache License, Version 2.0 (the "License"); you may
7  * not use this file except in compliance with the License. You may obtain
8  * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12  * or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 #include <freerdp/config.h>
17 #include <winpr/assert.h>
18 #include <winpr/cast.h>
19 
20 #include <freerdp/types.h>
21 #include <freerdp/primitives.h>
22 
23 #include "prim_internal.h"
24 #include "prim_shift.h"
25 
26 /* ------------------------------------------------------------------------- */
27 static INLINE INT16 shift(INT16 val, UINT32 sh)
28 {
29  const INT16 rc = (int16_t)(((UINT32)val << sh) & 0xFFFF);
30  return WINPR_ASSERTING_INT_CAST(INT16, rc);
31 }
32 
33 static INLINE pstatus_t general_lShiftC_16s_inplace(INT16* WINPR_RESTRICT pSrcDst, UINT32 val,
34  UINT32 len)
35 {
36  if (val == 0)
37  return PRIMITIVES_SUCCESS;
38  if (val >= 16)
39  return -1;
40 
41  for (UINT32 x = 0; x < len; x++)
42  pSrcDst[x] = shift(pSrcDst[x], val);
43 
44  return PRIMITIVES_SUCCESS;
45 }
46 
47 static INLINE pstatus_t general_lShiftC_16s(const INT16* pSrc, UINT32 val, INT16* pDst, UINT32 len)
48 {
49  if (val == 0)
50  return PRIMITIVES_SUCCESS;
51  if (val >= 16)
52  return -1;
53 
54  for (UINT32 x = 0; x < len; x++)
55  pDst[x] = shift(pSrc[x], val);
56 
57  return PRIMITIVES_SUCCESS;
58 }
59 
60 /* ------------------------------------------------------------------------- */
61 static INLINE pstatus_t general_rShiftC_16s(const INT16* pSrc, UINT32 val, INT16* pDst, UINT32 len)
62 {
63  if (val == 0)
64  return PRIMITIVES_SUCCESS;
65  if (val >= 16)
66  return -1;
67 
68  for (UINT32 x = 0; x < len; x++)
69  pDst[x] = WINPR_ASSERTING_INT_CAST(int16_t, pSrc[x] >> val);
70 
71  return PRIMITIVES_SUCCESS;
72 }
73 
74 /* ------------------------------------------------------------------------- */
75 static INLINE pstatus_t general_lShiftC_16u(const UINT16* pSrc, UINT32 val, UINT16* pDst,
76  UINT32 len)
77 {
78  if (val == 0)
79  return PRIMITIVES_SUCCESS;
80  if (val >= 16)
81  return -1;
82 
83  for (UINT32 x = 0; x < len; x++)
84  pDst[x] = WINPR_ASSERTING_INT_CAST(UINT16, ((pSrc[x] << val) & 0xFFFF));
85 
86  return PRIMITIVES_SUCCESS;
87 }
88 
89 /* ------------------------------------------------------------------------- */
90 static INLINE pstatus_t general_rShiftC_16u(const UINT16* pSrc, UINT32 val, UINT16* pDst,
91  UINT32 len)
92 {
93  if (val == 0)
94  return PRIMITIVES_SUCCESS;
95  if (val >= 16)
96  return -1;
97 
98  for (UINT32 x = 0; x < len; x++)
99  pDst[x] = pSrc[x] >> val;
100 
101  return PRIMITIVES_SUCCESS;
102 }
103 
104 /* ------------------------------------------------------------------------- */
105 static INLINE pstatus_t general_shiftC_16s(const INT16* pSrc, INT32 val, INT16* pDst, UINT32 len)
106 {
107  if (val == 0)
108  return PRIMITIVES_SUCCESS;
109 
110  if (val < 0)
111  return general_rShiftC_16s(pSrc, WINPR_ASSERTING_INT_CAST(UINT32, -val), pDst, len);
112  else
113  return general_lShiftC_16s(pSrc, WINPR_ASSERTING_INT_CAST(UINT32, val), pDst, len);
114 }
115 
116 /* ------------------------------------------------------------------------- */
117 static INLINE pstatus_t general_shiftC_16u(const UINT16* pSrc, INT32 val, UINT16* pDst, UINT32 len)
118 {
119  if (val == 0)
120  return PRIMITIVES_SUCCESS;
121 
122  if (val < 0)
123  return general_rShiftC_16u(pSrc, WINPR_ASSERTING_INT_CAST(UINT32, -val), pDst, len);
124  else
125  return general_lShiftC_16u(pSrc, WINPR_ASSERTING_INT_CAST(UINT32, val), pDst, len);
126 }
127 
128 /* ------------------------------------------------------------------------- */
129 void primitives_init_shift(primitives_t* WINPR_RESTRICT prims)
130 {
131  /* Start with the default. */
132  prims->lShiftC_16s_inplace = general_lShiftC_16s_inplace;
133  prims->lShiftC_16s = general_lShiftC_16s;
134  prims->rShiftC_16s = general_rShiftC_16s;
135  prims->lShiftC_16u = general_lShiftC_16u;
136  prims->rShiftC_16u = general_rShiftC_16u;
137  /* Wrappers */
138  prims->shiftC_16s = general_shiftC_16s;
139  prims->shiftC_16u = general_shiftC_16u;
140 }
141 
142 void primitives_init_shift_opt(primitives_t* WINPR_RESTRICT prims)
143 {
144  primitives_init_shift_sse3(prims);
145 }