Initial commit - from Precise source
[freerdp-ubuntu-pcb-backport.git] / libfreerdp-codec / rfx_quantization.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol client.
3  * RemoteFX Codec Library - Quantization
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 "rfx_quantization.h"
21
22 static void rfx_quantization_decode_block(sint16* buffer, int buffer_size, uint32 factor)
23 {
24         sint16* dst;
25
26         if (factor == 0)
27                 return;
28
29         for (dst = buffer; buffer_size > 0; dst++, buffer_size--)
30         {
31                 *dst <<= factor;
32         }
33 }
34
35 void rfx_quantization_decode(sint16* buffer, const uint32* quantization_values)
36 {
37         /* Scale the values so that they are represented as 11.5 fixed-point number */
38         rfx_quantization_decode_block(buffer, 4096, 5);
39
40         rfx_quantization_decode_block(buffer, 1024, quantization_values[8] - 6); /* HL1 */
41         rfx_quantization_decode_block(buffer + 1024, 1024, quantization_values[7] - 6); /* LH1 */
42         rfx_quantization_decode_block(buffer + 2048, 1024, quantization_values[9] - 6); /* HH1 */
43         rfx_quantization_decode_block(buffer + 3072, 256, quantization_values[5] - 6); /* HL2 */
44         rfx_quantization_decode_block(buffer + 3328, 256, quantization_values[4] - 6); /* LH2 */
45         rfx_quantization_decode_block(buffer + 3584, 256, quantization_values[6] - 6); /* HH2 */
46         rfx_quantization_decode_block(buffer + 3840, 64, quantization_values[2] - 6); /* HL3 */
47         rfx_quantization_decode_block(buffer + 3904, 64, quantization_values[1] - 6); /* LH3 */
48         rfx_quantization_decode_block(buffer + 3968, 64, quantization_values[3] - 6); /* HH3 */
49         rfx_quantization_decode_block(buffer + 4032, 64, quantization_values[0] - 6); /* LL3 */
50 }
51
52 static void rfx_quantization_encode_block(sint16* buffer, int buffer_size, uint32 factor)
53 {
54         sint16* dst;
55         sint16 half;
56
57         if (factor == 0)
58                 return;
59
60         half = (1 << (factor - 1));
61         for (dst = buffer; buffer_size > 0; dst++, buffer_size--)
62         {
63                 *dst = (*dst + half) >> factor;
64         }
65 }
66
67 void rfx_quantization_encode(sint16* buffer, const uint32* quantization_values)
68 {
69         rfx_quantization_encode_block(buffer, 1024, quantization_values[8] - 6); /* HL1 */
70         rfx_quantization_encode_block(buffer + 1024, 1024, quantization_values[7] - 6); /* LH1 */
71         rfx_quantization_encode_block(buffer + 2048, 1024, quantization_values[9] - 6); /* HH1 */
72         rfx_quantization_encode_block(buffer + 3072, 256, quantization_values[5] - 6); /* HL2 */
73         rfx_quantization_encode_block(buffer + 3328, 256, quantization_values[4] - 6); /* LH2 */
74         rfx_quantization_encode_block(buffer + 3584, 256, quantization_values[6] - 6); /* HH2 */
75         rfx_quantization_encode_block(buffer + 3840, 64, quantization_values[2] - 6); /* HL3 */
76         rfx_quantization_encode_block(buffer + 3904, 64, quantization_values[1] - 6); /* LH3 */
77         rfx_quantization_encode_block(buffer + 3968, 64, quantization_values[3] - 6); /* HH3 */
78         rfx_quantization_encode_block(buffer + 4032, 64, quantization_values[0] - 6); /* LL3 */
79
80         /* The coefficients are scaled by << 5 at RGB->YCbCr phase, so we round it back here */
81         rfx_quantization_encode_block(buffer, 4096, 5);
82 }