~ubuntu-branches/ubuntu/raring/freerdp/raring-proposed

« back to all changes in this revision

Viewing changes to libfreerdp-codec/nsc.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt, Jeremy Bicha, Jean-Louis Dupond, Martin Pitt
  • Date: 2012-01-31 10:02:14 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20120131100214-jaok3uwvni7sqxth
Tags: 1.0.0-0git1
Upload current Debian packaging git to get this rolling for precise.

[ Jeremy Bicha ]
* New upstream release. Closes: #647498.
* Updated symbols and bumped soname
* debian/control:
  - Added new build dependencies
  - Bump Standards-Version to 3.9.2
* debian/source/format: Set to 3.0 (quilt)
* debian/rules: Turn on strict symbols checking
* debian/watch: Watch github

[ Jean-Louis Dupond ]
* debian/control: Updated homepage
* debian/copyright: Reflect upstream switch to the Apache license

[ Martin Pitt ]
* debian/libfreerdp0.symbols: Fix version number, should
  be 1.0~beta5, not 1.0-beta5.
* debian/control: Add libavcodec-dev build dependency, upstream build system
  checks for that. Thanks Jean-Louis Dupond!

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * FreeRDP: A Remote Desktop Protocol client.
 
3
 * NSCodec Codec
 
4
 *
 
5
 * Copyright 2011 Samsung, Author Jiten Pathy
 
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
#include <stdint.h>
 
24
#include <freerdp/codec/nsc.h>
 
25
#include <freerdp/utils/memory.h>
 
26
 
 
27
/* we store the 9th bits at the end of stream as bitstream */
 
28
void nsc_cl_expand(STREAM* stream, uint8 shiftcount, uint32 origsz)
 
29
{
 
30
        uint8* sbitstream;
 
31
        uint8* temptr;
 
32
        uint8 sign,bitoff;
 
33
        uint32 bitno;
 
34
        sbitstream = stream->data + origsz;
 
35
 
 
36
        do
 
37
        {
 
38
                sign = (*(stream->p) << (shiftcount - 1)) & 0x80;
 
39
                bitno = stream->p - stream->data;
 
40
                *(stream->p++) <<= shiftcount;
 
41
                temptr = sbitstream + ((bitno) >> 3);
 
42
                bitoff = bitno % 0x8; 
 
43
                (*temptr) |= (sign >> bitoff);
 
44
        }
 
45
        while (((uint32)(stream->p - stream->data)) < origsz);
 
46
 
 
47
        stream->p = stream->data;
 
48
}
 
49
 
 
50
void nsc_chroma_supersample(NSC_CONTEXT* context)
 
51
{
 
52
        int i;
 
53
        uint8* cur;
 
54
        uint8* tptr;
 
55
        uint8* nbitstream;
 
56
        uint8* sbitstream;
 
57
        uint8 val, bitoff, sign;
 
58
        uint16 w, h, pw, row;
 
59
        uint32 alloclen, orglen, bytno;
 
60
        STREAM* new_s;
 
61
        STREAM* temp;
 
62
 
 
63
        w = context->width;
 
64
        h = context->height;
 
65
        alloclen = orglen = w * h;
 
66
        pw = ROUND_UP_TO(context->width, 8);
 
67
        temp = stream_new(0);
 
68
 
 
69
        for (i = 0; i < 3; i++)
 
70
        {
 
71
                if (i != 0)
 
72
                        alloclen = orglen + ((orglen & 0x7) ? (orglen >> 3) + 0x1 : (orglen >> 3));
 
73
 
 
74
                new_s = stream_new(alloclen);
 
75
                stream_attach(temp, context->org_buf[i]->data, context->org_buf[i]->size);
 
76
 
 
77
                sbitstream = temp->data + context->OrgByteCount[i];
 
78
                nbitstream = new_s->data + orglen;
 
79
                cur  = new_s->p;
 
80
 
 
81
                if (i == 1)
 
82
                        pw >>= 1;
 
83
 
 
84
                while (((uint32)(temp->p - temp->data)) < context->OrgByteCount[i])
 
85
                {
 
86
                        bytno = temp->p - temp->data;
 
87
                        bitoff = bytno % 0x8; 
 
88
                        stream_read_uint8(temp, val);
 
89
                        *cur = val;
 
90
                        row = (temp->p - temp->data) % pw;
 
91
 
 
92
                        if (i == 0)
 
93
                        {
 
94
                                cur++;
 
95
                                if (row >= w)
 
96
                                        stream_seek(temp, pw-row);
 
97
                        }
 
98
                        else
 
99
                        {
 
100
                                tptr = sbitstream + ((bytno) >> 3);
 
101
                                sign = ((*tptr) << bitoff) & 0x80;
 
102
                                bytno = cur - new_s->data;
 
103
                                bitoff = bytno % 8;
 
104
                                *(nbitstream + (bytno >> 3)) |= (sign >> bitoff);
 
105
 
 
106
                                if ((bytno+w) < orglen)
 
107
                                {
 
108
                                        *(cur + w) = val;
 
109
                                        bitoff = (bytno + w) % 8;
 
110
                                        *(nbitstream + ((bytno + w) >> 3)) |= (sign >> bitoff);
 
111
                                }
 
112
 
 
113
                                if ((bytno+1) % w)
 
114
                                {
 
115
                                        *(cur+1) = val;
 
116
                                        bitoff = (bytno + 1) % 8;
 
117
                                        *(nbitstream + ((bytno + 1) >> 3)) |= (sign >> bitoff);
 
118
                                        if ((bytno+w) < orglen)
 
119
                                        {
 
120
                                                *(cur+w+1) = val;
 
121
                                                bitoff = (bytno + w + 1) % 8;
 
122
                                                *(nbitstream + ((bytno + w + 1) >> 3)) |= (sign >> bitoff);
 
123
                                        }
 
124
                                }
 
125
 
 
126
                                cur += 2;
 
127
                                bytno = cur - new_s->data;
 
128
 
 
129
                                if (((bytno/w) < h) && ((bytno) % w) < 2 )
 
130
                                {
 
131
                                        if (w % 2)
 
132
                                                cur += w-1;
 
133
                                        else
 
134
                                                cur += w;
 
135
                                }
 
136
 
 
137
                                if ((row*2) >= w)
 
138
                                        stream_seek(temp, pw-row);
 
139
                        }
 
140
                }
 
141
 
 
142
                xfree(temp->data);
 
143
                stream_detach(temp);
 
144
                stream_attach(context->org_buf[i], new_s->data, new_s->size);
 
145
                context->OrgByteCount[i] = orglen;
 
146
        }
 
147
}
 
148
 
 
149
void nsc_ycocg_rgb(NSC_CONTEXT* context)
 
150
{
 
151
        uint8* sbitstream[2];
 
152
        uint8 bitoff, sign[2], i, val;
 
153
        sint16 rgb[3], ycocg[3];
 
154
        uint32 bytno, size;
 
155
        size = context->OrgByteCount[0];
 
156
 
 
157
        for (i = 1; i < 3; i++)
 
158
                sbitstream[i-1] = context->org_buf[i]->data + context->OrgByteCount[i];
 
159
 
 
160
        do
 
161
        {
 
162
                for (i = 0; i < 3; i++)
 
163
                        ycocg[i] = *(context->org_buf[i]->p);
 
164
 
 
165
                for (i = 1; i < 3; i++)
 
166
                {
 
167
                        bytno = context->OrgByteCount[i] - size;
 
168
                        bitoff = bytno % 8;
 
169
                        sign[i-1] = (*(sbitstream[i-1] + (bytno >> 3)) >> (7 - bitoff)) & 0x1;
 
170
                        ycocg[i] = (((sint16)(0 - sign[i-1])) << 8) | ycocg[i];
 
171
                }
 
172
 
 
173
                rgb[0] = ycocg[0] + (ycocg[1] >> 1) - (ycocg[2] >> 1);
 
174
                rgb[1] = ycocg[0] + (ycocg[2] >> 1);
 
175
                rgb[2] = ycocg[0] - (ycocg[1] >> 1) - (ycocg[2] >> 1);
 
176
 
 
177
                for (i = 0; i < 3; i++)
 
178
                {
 
179
                        if (((rgb[i] >> 8) & 0x1) == 0x1)
 
180
                                val = ~((uint8) rgb[i]) + 0x1;
 
181
                        else
 
182
                                val = (uint8) rgb[i];
 
183
 
 
184
                        stream_write_uint8(context->org_buf[i], val);
 
185
                }
 
186
 
 
187
                size--;
 
188
        }
 
189
        while (size);
 
190
 
 
191
        for (i = 0; i < 3; i++)
 
192
                context->org_buf[i]->p = context->org_buf[i]->data;
 
193
}
 
194
 
 
195
void nsc_colorloss_recover(NSC_CONTEXT* context)
 
196
{
 
197
        int i;
 
198
        uint8 cllvl;
 
199
        cllvl = context->nsc_stream->colorLossLevel;
 
200
 
 
201
        for (i = 1; i < 3; i++)
 
202
                nsc_cl_expand(context->org_buf[i], cllvl, context->OrgByteCount[i]);
 
203
}
 
204
 
 
205
void nsc_rle_decode(STREAM* in, STREAM* out, uint32 origsz)
 
206
{
 
207
        uint32 i;
 
208
        uint8 value;
 
209
        i = origsz;
 
210
 
 
211
        while (i > 4)
 
212
        {
 
213
                stream_read_uint8(in, value);
 
214
 
 
215
                if (i == 5)
 
216
                {
 
217
                        stream_write_uint8(out,value);
 
218
                        i-=1;
 
219
                }
 
220
                else if (value == *(in->p))
 
221
                {
 
222
                        stream_seek(in, 1);
 
223
 
 
224
                        if (*(in->p) < 0xFF)
 
225
                        {
 
226
                                uint8 len;
 
227
                                stream_read_uint8(in, len);
 
228
                                stream_set_byte(out, value, len+2);
 
229
                                i -= (len+2);
 
230
                        }
 
231
                        else
 
232
                        {
 
233
                                uint32 len;
 
234
                                stream_seek(in, 1);
 
235
                                stream_read_uint32(in, len);
 
236
                                stream_set_byte(out, value, len);
 
237
                                i -= len;
 
238
                        }
 
239
                }
 
240
                else
 
241
                {
 
242
                        stream_write_uint8(out, value);
 
243
                        i -= 1;
 
244
                }
 
245
        }
 
246
 
 
247
        stream_copy(out, in, 4);
 
248
}
 
249
 
 
250
void nsc_rle_decompress_data(NSC_CONTEXT* context)
 
251
{
 
252
        STREAM* rles;
 
253
        uint16 i;
 
254
        uint32 origsize;
 
255
        rles = stream_new(0);
 
256
        rles->p = rles->data = context->nsc_stream->pdata->p;
 
257
        rles->size = context->nsc_stream->pdata->size;
 
258
 
 
259
        for (i = 0; i < 4; i++)
 
260
        {
 
261
                origsize = context->OrgByteCount[i];
 
262
 
 
263
                if (i == 3 && context->nsc_stream->PlaneByteCount[i] == 0)
 
264
                        stream_set_byte(context->org_buf[i], 0xff, origsize);
 
265
                else if (context->nsc_stream->PlaneByteCount[i] < origsize)
 
266
                        nsc_rle_decode(rles, context->org_buf[i], origsize);
 
267
                else
 
268
                        stream_copy(context->org_buf[i], rles, origsize);
 
269
 
 
270
                context->org_buf[i]->p = context->org_buf[i]->data;
 
271
        }
 
272
}
 
273
 
 
274
void nsc_combine_argb(NSC_CONTEXT* context)
 
275
{
 
276
        int i;
 
277
        uint8* bmp;
 
278
        bmp = context->bmpdata;
 
279
 
 
280
        for (i = 0; i < (context->width * context->height); i++)
 
281
        {
 
282
                stream_read_uint8(context->org_buf[2], *bmp++);
 
283
                stream_read_uint8(context->org_buf[1], *bmp++);
 
284
                stream_read_uint8(context->org_buf[0], *bmp++);
 
285
                stream_read_uint8(context->org_buf[3], *bmp++);
 
286
        }
 
287
}
 
288
 
 
289
void nsc_stream_initialize(NSC_CONTEXT* context, STREAM* s)
 
290
{
 
291
        int i;
 
292
 
 
293
        for (i = 0; i < 4; i++)
 
294
                stream_read_uint32(s, context->nsc_stream->PlaneByteCount[i]);
 
295
 
 
296
        stream_read_uint8(s, context->nsc_stream->colorLossLevel);
 
297
        stream_read_uint8(s, context->nsc_stream->ChromaSubSamplingLevel);
 
298
        stream_seek(s, 2);
 
299
 
 
300
        context->nsc_stream->pdata = stream_new(0);
 
301
        stream_attach(context->nsc_stream->pdata, s->p, BYTESUM(context->nsc_stream->PlaneByteCount));
 
302
}
 
303
 
 
304
void nsc_context_initialize(NSC_CONTEXT* context, STREAM* s)
 
305
{
 
306
        int i;
 
307
        uint32 tempsz;
 
308
        nsc_stream_initialize(context, s);
 
309
        context->bmpdata = xzalloc(context->width * context->height * 4);
 
310
 
 
311
        for (i = 0; i < 4; i++)
 
312
                context->OrgByteCount[i]=context->width * context->height;
 
313
 
 
314
        if (context->nsc_stream->ChromaSubSamplingLevel > 0)    /* [MS-RDPNSC] 2.2 */
 
315
        {
 
316
                uint32 tempWidth,tempHeight;
 
317
                tempWidth = ROUND_UP_TO(context->width, 8);
 
318
                context->OrgByteCount[0] = tempWidth * context->height;
 
319
                tempWidth = tempWidth >> 1 ;
 
320
                tempHeight = ROUND_UP_TO(context->height, 2);
 
321
                tempHeight = tempHeight >> 1;
 
322
                context->OrgByteCount[1] = tempWidth * tempHeight;
 
323
                context->OrgByteCount[2] = tempWidth * tempHeight;
 
324
        }
 
325
        for (i = 0; i < 4; i++)
 
326
        {
 
327
                tempsz = context->OrgByteCount[i];
 
328
 
 
329
                if (i == 1 || i == 2)
 
330
                        tempsz += (tempsz & 0x7) ? (tempsz >> 3) + 0x1 : (tempsz >> 3); /* extra bytes/8 bytes for bitstream to store the 9th bit after colorloss recover */
 
331
 
 
332
                context->org_buf[i] = stream_new(tempsz);
 
333
        }
 
334
}
 
335
 
 
336
void nsc_context_destroy(NSC_CONTEXT* context)
 
337
{
 
338
        int i;
 
339
 
 
340
        for (i = 0;i < 4; i++)
 
341
                stream_free(context->org_buf[i]);
 
342
 
 
343
        stream_detach(context->nsc_stream->pdata);
 
344
        xfree(context->bmpdata);
 
345
}
 
346
 
 
347
NSC_CONTEXT* nsc_context_new(void)
 
348
{
 
349
        NSC_CONTEXT* nsc_context;
 
350
        nsc_context = xnew(NSC_CONTEXT);
 
351
        nsc_context->nsc_stream = xnew(NSC_STREAM);
 
352
        return nsc_context;
 
353
}
 
354
 
 
355
void nsc_process_message(NSC_CONTEXT* context, uint8* data, uint32 length)
 
356
{
 
357
        STREAM* s;
 
358
        s = stream_new(0);
 
359
        stream_attach(s, data, length);
 
360
        nsc_context_initialize(context, s);
 
361
 
 
362
        /* RLE decode */
 
363
        nsc_rle_decompress_data(context);
 
364
 
 
365
        /* colorloss recover */
 
366
        nsc_colorloss_recover(context);
 
367
 
 
368
        /* Chroma supersample */
 
369
        if (context->nsc_stream->ChromaSubSamplingLevel > 0)
 
370
                nsc_chroma_supersample(context);
 
371
        
 
372
        /* YCoCg to RGB Convert */
 
373
        nsc_ycocg_rgb(context);
 
374
 
 
375
        /* Combine ARGB planes */
 
376
        nsc_combine_argb(context);
 
377
}