~ubuntu-branches/ubuntu/saucy/kopete/saucy-proposed

« back to all changes in this revision

Viewing changes to libkopete/avdevice/sonix_compress.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-06-21 02:22:39 UTC
  • Revision ID: package-import@ubuntu.com-20130621022239-63l3zc8p0nf26pt6
Tags: upstream-4.10.80
ImportĀ upstreamĀ versionĀ 4.10.80

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "sonix_compress.h"
 
2
 
 
3
#define CLAMP(x)        ((x)<0?0:((x)>255)?255:(x))
 
4
 
 
5
typedef struct {
 
6
        int is_abs;
 
7
        int len;
 
8
        int val;
 
9
        int unk;
 
10
} code_table_t;
 
11
 
 
12
 
 
13
/* local storage */
 
14
static code_table_t table[256];
 
15
static int init_done = 0;
 
16
 
 
17
/* global variable */
 
18
int sonix_unknown = 0;
 
19
 
 
20
/*
 
21
        sonix_decompress_init
 
22
        =====================
 
23
                pre-calculates a locally stored table for efficient huffman-decoding.
 
24
 
 
25
        Each entry at index x in the table represents the codeword
 
26
        present at the MSB of byte x.
 
27
 
 
28
*/
 
29
void sonix_decompress_init(void)
 
30
{
 
31
        int i;
 
32
        int is_abs, val, len, unk;
 
33
 
 
34
        for (i = 0; i < 256; i++) {
 
35
                is_abs = 0;
 
36
                val = 0;
 
37
                len = 0;
 
38
                unk = 0;
 
39
                if ((i & 0x80) == 0) {
 
40
                        /* code 0 */
 
41
                        val = 0;
 
42
                        len = 1;
 
43
                }
 
44
                else if ((i & 0xE0) == 0x80) {
 
45
                        /* code 100 */
 
46
                        val = +4;
 
47
                        len = 3;
 
48
                }
 
49
                else if ((i & 0xE0) == 0xA0) {
 
50
                        /* code 101 */
 
51
                        val = -4;
 
52
                        len = 3;
 
53
                }
 
54
                else if ((i & 0xF0) == 0xD0) {
 
55
                        /* code 1101 */
 
56
                        val = +11;
 
57
                        len = 4;
 
58
                }
 
59
                else if ((i & 0xF0) == 0xF0) {
 
60
                        /* code 1111 */
 
61
                        val = -11;
 
62
                        len = 4;
 
63
                }
 
64
                else if ((i & 0xF8) == 0xC8) {
 
65
                        /* code 11001 */
 
66
                        val = +20;
 
67
                        len = 5;
 
68
                }
 
69
                else if ((i & 0xFC) == 0xC0) {
 
70
                        /* code 110000 */
 
71
                        val = -20;
 
72
                        len = 6;
 
73
                }
 
74
                else if ((i & 0xFC) == 0xC4) {
 
75
                        /* code 110001xx: unknown */
 
76
                        val = 0;
 
77
                        len = 8;
 
78
                        unk = 1;
 
79
                }
 
80
                else if ((i & 0xF0) == 0xE0) {
 
81
                        /* code 1110xxxx */
 
82
                        is_abs = 1;
 
83
                        val = (i & 0x0F) << 4;
 
84
                        len = 8;
 
85
                }
 
86
                table[i].is_abs = is_abs;
 
87
                table[i].val = val;
 
88
                table[i].len = len;
 
89
                table[i].unk = unk;
 
90
        }
 
91
 
 
92
        sonix_unknown = 0;
 
93
        init_done = 1;
 
94
}
 
95
 
 
96
 
 
97
/*
 
98
        sonix_decompress
 
99
        ================
 
100
                decompresses an image encoded by a SN9C101 camera controller chip.
 
101
 
 
102
        IN      width
 
103
                height
 
104
                inp             pointer to compressed frame (with header already stripped)
 
105
        OUT     outp    pointer to decompressed frame
 
106
 
 
107
        Returns 0 if the operation was successful.
 
108
        Returns <0 if operation failed.
 
109
 
 
110
*/
 
111
int sonix_decompress(int width, int height, unsigned char *inp, unsigned char *outp)
 
112
{
 
113
        int row, col;
 
114
        int val;
 
115
        int bitpos;
 
116
        unsigned char code;
 
117
        unsigned char *addr;
 
118
 
 
119
        if (!init_done) {
 
120
                /* do sonix_decompress_init first! */
 
121
                return -1;
 
122
        }
 
123
 
 
124
        bitpos = 0;
 
125
        for (row = 0; row < height; row++) {
 
126
 
 
127
                col = 0;
 
128
 
 
129
                /* first two pixels in first two rows are stored as raw 8-bit */
 
130
                if (row < 2) {
 
131
                        addr = inp + (bitpos >> 3);
 
132
                        code = (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7)));
 
133
                        bitpos += 8;
 
134
                        *outp++ = code;
 
135
 
 
136
                        addr = inp + (bitpos >> 3);
 
137
                        code = (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7)));
 
138
                        bitpos += 8;
 
139
                        *outp++ = code;
 
140
 
 
141
                        col += 2;
 
142
                }
 
143
 
 
144
                while (col < width) {
 
145
                        /* get bitcode from bitstream */
 
146
                        addr = inp + (bitpos >> 3);
 
147
                        code = (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7)));
 
148
 
 
149
                        /* update bit position */
 
150
                        bitpos += table[code].len;
 
151
 
 
152
                        /* update code statistics */
 
153
                        sonix_unknown += table[code].unk;
 
154
 
 
155
                        /* calculate pixel value */
 
156
                        val = table[code].val;
 
157
                        if (!table[code].is_abs) {
 
158
                                /* value is relative to top and left pixel */
 
159
                                if (col < 2) {
 
160
                                        /* left column: relative to top pixel */
 
161
                                        val += outp[-2*width];
 
162
                                }
 
163
                                else if (row < 2) {
 
164
                                        /* top row: relative to left pixel */
 
165
                                        val += outp[-2];
 
166
                                }
 
167
                                else {
 
168
                                        /* main area: average of left pixel and top pixel */
 
169
                                        val += (outp[-2] + outp[-2*width]) / 2;
 
170
                                }
 
171
                        }
 
172
 
 
173
                        /* store pixel */
 
174
                        *outp++ = CLAMP(val);
 
175
                        col++;
 
176
                }
 
177
        }
 
178
 
 
179
        return 0;
 
180
}