Change debian changelog, add -c0 into rules file to prevent symbol whinges, fix point...
[freerdp-ubuntu-pcb-backport.git] / libfreerdp-codec / rfx_dwt.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol client.
3  * RemoteFX Codec Library - DWT
4  *
5  * Copyright 2011 Vic Lee
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include "rfx_dwt.h"
25
26 static void rfx_dwt_2d_decode_block(sint16* buffer, sint16* idwt, int subband_width)
27 {
28         sint16 *dst, *l, *h;
29         sint16 *l_dst, *h_dst;
30         sint16 *hl, *lh, *hh, *ll;
31         int total_width;
32         int x, y;
33         int n;
34
35         total_width = subband_width << 1;
36
37         /* Inverse DWT in horizontal direction, results in 2 sub-bands in L, H order in tmp buffer idwt. */
38         /* The 4 sub-bands are stored in HL(0), LH(1), HH(2), LL(3) order. */
39         /* The lower part L uses LL(3) and HL(0). */
40         /* The higher part H uses LH(1) and HH(2). */
41
42         ll = buffer + subband_width * subband_width * 3;
43         hl = buffer;
44         l_dst = idwt;
45
46         lh = buffer + subband_width * subband_width;
47         hh = buffer + subband_width * subband_width * 2;
48         h_dst = idwt + subband_width * subband_width * 2;
49
50         for (y = 0; y < subband_width; y++)
51         {
52                 /* Even coefficients */
53                 l_dst[0] = ll[0] - ((hl[0] + hl[0] + 1) >> 1);
54                 h_dst[0] = lh[0] - ((hh[0] + hh[0] + 1) >> 1);
55                 for (n = 1; n < subband_width; n++)
56                 {
57                         x = n << 1;
58                         l_dst[x] = ll[n] - ((hl[n-1] + hl[n] + 1) >> 1);
59                         h_dst[x] = lh[n] - ((hh[n-1] + hh[n] + 1) >> 1);
60                 }
61
62                 /* Odd coefficients */
63                 for (n = 0; n < subband_width-1; n++)
64                 {
65                         x = n << 1;
66                         l_dst[x + 1] = (hl[n] << 1) + ((l_dst[x] + l_dst[x + 2]) >> 1);
67                         h_dst[x + 1] = (hh[n] << 1) + ((h_dst[x] + h_dst[x + 2]) >> 1);
68                 }
69                 x = n << 1;
70                 l_dst[x + 1] = (hl[n] << 1) + (l_dst[x]);
71                 h_dst[x + 1] = (hh[n] << 1) + (h_dst[x]);               
72
73                 ll += subband_width;
74                 hl += subband_width;
75                 l_dst += total_width;
76
77                 lh += subband_width;
78                 hh += subband_width;
79                 h_dst += total_width;
80         }
81
82         /* Inverse DWT in vertical direction, results are stored in original buffer. */
83         for (x = 0; x < total_width; x++)
84         {
85                 /* Even coefficients */
86                 for (n = 0; n < subband_width; n++)
87                 {
88                         y = n << 1;
89                         dst = buffer + y * total_width + x;
90                         l = idwt + n * total_width + x;
91                         h = l + subband_width * total_width;
92                         dst[0] = *l - (((n > 0 ? *(h - total_width) : *h) + (*h) + 1) >> 1);
93                 }
94
95                 /* Odd coefficients */
96                 for (n = 0; n < subband_width; n++)
97                 {
98                         y = n << 1;
99                         dst = buffer + y * total_width + x;
100                         l = idwt + n * total_width + x;
101                         h = l + subband_width * total_width;
102                         dst[total_width] = (*h << 1) + ((dst[0] + dst[n < subband_width - 1 ? 2 * total_width : 0]) >> 1);
103                 }
104         }
105 }
106
107 void rfx_dwt_2d_decode(sint16* buffer, sint16* dwt_buffer)
108 {
109         rfx_dwt_2d_decode_block(buffer + 3840, dwt_buffer, 8);
110         rfx_dwt_2d_decode_block(buffer + 3072, dwt_buffer, 16);
111         rfx_dwt_2d_decode_block(buffer, dwt_buffer, 32);
112 }
113
114 static void rfx_dwt_2d_encode_block(sint16* buffer, sint16* dwt, int subband_width)
115 {
116         sint16 *src, *l, *h;
117         sint16 *l_src, *h_src;
118         sint16 *hl, *lh, *hh, *ll;
119         int total_width;
120         int x, y;
121         int n;
122
123         total_width = subband_width << 1;
124
125         /* DWT in vertical direction, results in 2 sub-bands in L, H order in tmp buffer dwt. */
126         for (x = 0; x < total_width; x++)
127         {
128                 for (n = 0; n < subband_width; n++)
129                 {
130                         y = n << 1;
131                         l = dwt + n * total_width + x;
132                         h = l + subband_width * total_width;
133                         src = buffer + y * total_width + x;
134
135                         /* H */
136                         *h = (src[total_width] - ((src[0] + src[n < subband_width - 1 ? 2 * total_width : 0]) >> 1)) >> 1;
137
138                         /* L */
139                         *l = src[0] + (n == 0 ? *h : (*(h - total_width) + *h) >> 1);
140                 }
141         }
142
143         /* DWT in horizontal direction, results in 4 sub-bands in HL(0), LH(1), HH(2), LL(3) order, stored in original buffer. */
144         /* The lower part L generates LL(3) and HL(0). */
145         /* The higher part H generates LH(1) and HH(2). */
146
147         ll = buffer + subband_width * subband_width * 3;
148         hl = buffer;
149         l_src = dwt;
150
151         lh = buffer + subband_width * subband_width;
152         hh = buffer + subband_width * subband_width * 2;
153         h_src = dwt + subband_width * subband_width * 2;
154
155         for (y = 0; y < subband_width; y++)
156         {
157                 /* L */
158                 for (n = 0; n < subband_width; n++)
159                 {
160                         x = n << 1;
161
162                         /* HL */
163                         hl[n] = (l_src[x + 1] - ((l_src[x] + l_src[n < subband_width - 1 ? x + 2 : x]) >> 1)) >> 1;
164                         /* LL */
165                         ll[n] = l_src[x] + (n == 0 ? hl[n] : (hl[n - 1] + hl[n]) >> 1);
166                 }
167
168                 /* H */
169                 for (n = 0; n < subband_width; n++)
170                 {
171                         x = n << 1;
172
173                         /* HH */
174                         hh[n] = (h_src[x + 1] - ((h_src[x] + h_src[n < subband_width - 1 ? x + 2 : x]) >> 1)) >> 1;
175                         /* LH */
176                         lh[n] = h_src[x] + (n == 0 ? hh[n] : (hh[n - 1] + hh[n]) >> 1);
177                 }
178
179                 ll += subband_width;
180                 hl += subband_width;
181                 l_src += total_width;
182
183                 lh += subband_width;
184                 hh += subband_width;
185                 h_src += total_width;
186         }
187 }
188
189 void rfx_dwt_2d_encode(sint16* buffer, sint16* dwt_buffer)
190 {
191         rfx_dwt_2d_encode_block(buffer, dwt_buffer, 32);
192         rfx_dwt_2d_encode_block(buffer + 3072, dwt_buffer, 16);
193         rfx_dwt_2d_encode_block(buffer + 3840, dwt_buffer, 8);
194 }