Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/jxr/image/sys/adapthuff.c
4393 views
1
//*@@@+++@@@@******************************************************************
2
//
3
// Copyright © Microsoft Corp.
4
// All rights reserved.
5
//
6
// Redistribution and use in source and binary forms, with or without
7
// modification, are permitted provided that the following conditions are met:
8
//
9
// • Redistributions of source code must retain the above copyright notice,
10
// this list of conditions and the following disclaimer.
11
// • Redistributions in binary form must reproduce the above copyright notice,
12
// this list of conditions and the following disclaimer in the documentation
13
// and/or other materials provided with the distribution.
14
//
15
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25
// POSSIBILITY OF SUCH DAMAGE.
26
//
27
//*@@@---@@@@******************************************************************
28
29
#include "strcodec.h"
30
31
#ifdef MEM_TRACE
32
#define TRACE_MALLOC 1
33
#define TRACE_NEW 0
34
#define TRACE_HEAP 0
35
#include "memtrace.h"
36
#endif
37
38
// Huffman lookup tables
39
static const short g4HuffLookupTable[40] = {
40
19,19,19,19,27,27,27,27,10,10,10,10,10,10,10,10,
41
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
42
0,0,0,0,0,0,0,0 };
43
44
static const short g5HuffLookupTable[2][42] = {{
45
28,28,36,36,19,19,19,19,10,10,10,10,10,10,10,10,
46
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
47
0,0,0,0,0,0,0,0,0,0 },
48
{
49
11,11,11,11,19,19,19,19,27,27,27,27,35,35,35,35,
50
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
51
0,0,0,0,0,0,0,0,0,0 }};
52
53
static const short g6HuffLookupTable[4][44] = {{
54
13,29,44,44,19,19,19,19,34,34,34,34,34,34,34,34,
55
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
56
0,0,0,0,0,0,0,0,0,0,0,0 },
57
{
58
12,12,28,28,43,43,43,43,2,2,2,2,2,2,2,2,
59
18,18,18,18,18,18,18,18,34,34,34,34,34,34,34,34,
60
0,0,0,0,0,0,0,0,0,0,0,0 },
61
{
62
4,4,12,12,43,43,43,43,18,18,18,18,18,18,18,18,
63
26,26,26,26,26,26,26,26,34,34,34,34,34,34,34,34,
64
0,0,0,0,0,0,0,0,0,0,0,0 },
65
{
66
5,13,36,36,43,43,43,43,18,18,18,18,18,18,18,18,
67
25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
68
0,0,0,0,0,0,0,0,0,0,0,0 }};
69
70
static const short g7HuffLookupTable[2][46] = {{
71
45,53,36,36,27,27,27,27,2,2,2,2,2,2,2,2,
72
10,10,10,10,10,10,10,10,18,18,18,18,18,18,18,18,
73
0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
74
{
75
-32736,37,28,28,19,19,19,19,10,10,10,10,10,10,10,10,
76
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
77
5,6,0,0,0,0,0,0,0,0,0,0,0,0 }};
78
79
static const short g8HuffLookupTable[2][48] = {{
80
53,21,28,28,11,11,11,11,43,43,43,43,59,59,59,59,
81
2,2,2,2,2,2,2,2,34,34,34,34,34,34,34,34,
82
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
83
{
84
52,52,20,20,3,3,3,3,11,11,11,11,27,27,27,27,
85
35,35,35,35,43,43,43,43,58,58,58,58,58,58,58,58,
86
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }};
87
88
static const short g9HuffLookupTable[2][50] = {{
89
13,29,37,61,20,20,68,68,3,3,3,3,51,51,51,51,
90
41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
91
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
92
0,0 },
93
{
94
-32736,53,28,28,11,11,11,11,19,19,19,19,43,43,43,43,
95
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
96
-32734,4,7,8,0,0,0,0,0,0,0,0,0,0,0,0,
97
0,0 }};
98
99
static const short g12HuffLookupTable[5][56] = {{
100
-32736,5,76,76,37,53,69,85,43,43,43,43,91,91,91,91,
101
57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
102
-32734,1,2,3,0,0,0,0,0,0,0,0,0,0,0,0,
103
0,0,0,0,0,0,0,0 },
104
{
105
-32736,85,13,53,4,4,36,36,43,43,43,43,67,67,67,67,
106
75,75,75,75,91,91,91,91,58,58,58,58,58,58,58,58,
107
2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
108
0,0,0,0,0,0,0,0 },
109
{
110
-32736,37,92,92,11,11,11,11,43,43,43,43,59,59,59,59,
111
67,67,67,67,75,75,75,75,2,2,2,2,2,2,2,2,
112
-32734,-32732,2,3,6,10,0,0,0,0,0,0,0,0,0,0,
113
0,0,0,0,0,0,0,0 },
114
{
115
-32736,29,37,69,3,3,3,3,43,43,43,43,59,59,59,59,
116
75,75,75,75,91,91,91,91,10,10,10,10,10,10,10,10,
117
-32734,10,2,6,0,0,0,0,0,0,0,0,0,0,0,0,
118
0,0,0,0,0,0,0,0 },
119
{
120
-32736,93,28,28,60,60,76,76,3,3,3,3,43,43,43,43,
121
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
122
-32734,-32732,-32730,2,4,8,6,10,0,0,0,0,0,0,0,0,
123
0,0,0,0,0,0,0,0 }};
124
125
/**********************************************************************
126
Allocation and dellocation
127
**********************************************************************/
128
Void Clean (CAdaptiveHuffman *pAdHuff)
129
{
130
if (pAdHuff == NULL)
131
return;
132
free (pAdHuff);
133
}
134
135
CAdaptiveHuffman *Allocate (Int iNSymbols, CODINGMODE cm)
136
{
137
CAdaptiveHuffman *pAdHuff = (CAdaptiveHuffman *) malloc (sizeof (CAdaptiveHuffman));
138
139
UNREFERENCED_PARAMETER(cm);
140
141
if (pAdHuff == NULL)
142
return NULL;
143
if (iNSymbols > 255 || iNSymbols <= 0)
144
goto ErrorExit;
145
146
memset (pAdHuff, 0, sizeof (CAdaptiveHuffman));
147
pAdHuff->m_iNSymbols = iNSymbols;
148
149
pAdHuff->m_pDelta = NULL;
150
pAdHuff->m_iDiscriminant = pAdHuff->m_iUpperBound = pAdHuff->m_iLowerBound = 0;
151
152
return pAdHuff;
153
154
ErrorExit:
155
Clean (pAdHuff);
156
return NULL;
157
}
158
159
/**********************************************************************
160
Adapt Huffman table
161
**********************************************************************/
162
// Alphabet size = 4
163
static const Int g_Index4Table[] = {
164
1,2,3,3
165
};
166
static const Int g4CodeTable[] = {
167
4,
168
1, 1,
169
1, 2,
170
0, 3,
171
1, 3
172
};
173
174
// Alphabet size = 5
175
static const Int g_Index5Table[] = {
176
1,2,3,4,4,
177
1,3,3,3,3
178
};
179
static const Int g5CodeTable[] = {
180
5,
181
1, 1,
182
1, 2,
183
1, 3,
184
0, 4,
185
1, 4,
186
187
5,
188
1, 1,
189
0, 3,
190
1, 3,
191
2, 3,
192
3, 3,
193
};
194
static const Int g5DeltaTable[] = { 0,-1,0,1,1 };
195
196
// Alphabet size = 6
197
static const Int g_Index6Table[] = {
198
1,5,3,5,2,4,
199
2,4,2,4,2,3,
200
4,4,2,2,2,3,
201
5,5,2,1,4,3,
202
};
203
static const Int g6CodeTable[] = {
204
6,
205
1, 1,
206
0, 5,
207
1, 3,
208
1, 5,
209
1, 2,
210
1, 4,
211
212
6,
213
1, 2,
214
0, 4,
215
2, 2,
216
1, 4,
217
3, 2,
218
1, 3,
219
220
6,
221
0, 4,
222
1, 4,
223
1, 2,
224
2, 2,
225
3, 2,
226
1, 3,
227
228
6,
229
0, 5,
230
1, 5,
231
1, 2,
232
1, 1,
233
1, 4,
234
1, 3
235
};
236
static const Int g6DeltaTable[] = {
237
-1, 1, 1, 1, 0, 1,
238
-2, 0, 0, 2, 0, 0,
239
-1,-1, 0, 1,-2, 0
240
};
241
242
// Alphabet size = 7
243
static const Int g_Index7Table[] = { 2,2,2,3,4,5,5,
244
1,2,3,4,5,6,6 };
245
static const Int g7CodeTable[] = {
246
7,
247
1, 2,
248
2, 2,
249
3, 2,
250
1, 3,
251
1, 4,
252
0, 5,
253
1, 5,
254
255
7,
256
1, 1,
257
1, 2,
258
1, 3,
259
1, 4,
260
1, 5,
261
0, 6,
262
1, 6
263
};
264
static const Int g7DeltaTable[] = { 1,0,-1,-1,-1,-1,-1 };
265
266
// Alphabet size = 8
267
static const Int g_Index8Table[] = { 2,3,5,4,2,3,5,3,
268
3,3,4,3,3,3,4,2};
269
static const Int g8CodeTable[] = {
270
8,
271
2, 2,
272
1, 3,
273
1, 5,
274
1, 4,
275
3, 2,
276
2, 3,
277
0, 5,
278
3, 3,
279
280
8,
281
1, 3,
282
2, 3,
283
1, 4,
284
3, 3,
285
4, 3,
286
5, 3,
287
0, 4,
288
3, 2
289
};
290
static const Int g8DeltaTable[] = { -1,0,1,1,-1,0,1,1 };
291
292
static const Int g_Index9Table[] = {
293
3,5,4,5,5,1,3,5,4,
294
1,3,3,4,6,3,5,7,7,
295
};
296
static const Int g9CodeTable[] = {
297
9,
298
2, 3,
299
0, 5,
300
2, 4,
301
1, 5,
302
2, 5,
303
1, 1,
304
3, 3,
305
3, 5,
306
3, 4,
307
308
9,
309
1, 1,
310
1, 3,
311
2, 3,
312
1, 4,
313
1, 6,
314
3, 3,
315
1, 5,
316
0, 7,
317
1, 7,
318
};
319
static const Int g9DeltaTable[] = { 2,2,1,1,-1,-2,-2,-2,-3 };
320
321
// Alphabet size = 12
322
static const Int g_Index12Table[] = { // index12 is the most critical symbol
323
5,6,7,7,5,3,5,1,5,4,5,3,
324
4,5,6,6,4,3,5,2,3,3,5,3,
325
2,3,7,7,5,3,7,3,3,3,7,4,
326
3,2,7,5,5,3,7,3,5,3,6,3,
327
3,1,7,4,7,3,8,4,7,4,8,5,
328
};
329
static const Int g12CodeTable[] = {
330
12,
331
1, 5,
332
1, 6,
333
0, 7,
334
1, 7,
335
4, 5,
336
2, 3,
337
5, 5,
338
1, 1,
339
6, 5,
340
1, 4,
341
7, 5,
342
3, 3,
343
344
12,
345
2, 4,
346
2, 5,
347
0, 6,
348
1, 6,
349
3, 4,
350
2, 3,
351
3, 5,
352
3, 2,
353
3, 3,
354
4, 3,
355
1, 5,
356
5, 3,
357
358
12,
359
3, 2,
360
1, 3,
361
0, 7,
362
1, 7,
363
1, 5,
364
2, 3,
365
2, 7,
366
3, 3,
367
4, 3,
368
5, 3,
369
3, 7,
370
1, 4,
371
372
12,
373
1, 3,
374
3, 2,
375
0, 7,
376
1, 5,
377
2, 5,
378
2, 3,
379
1, 7,
380
3, 3,
381
3, 5,
382
4, 3,
383
1, 6,
384
5, 3,
385
386
12,
387
2, 3,
388
1, 1,
389
1, 7,
390
1, 4,
391
2, 7,
392
3, 3,
393
0, 8,
394
2, 4,
395
3, 7,
396
3, 4,
397
1, 8,
398
1, 5
399
};
400
static const Int g12DeltaTable[] = {
401
1, 1, 1, 1, 1, 0, 0,-1, 2, 1, 0, 0,
402
2, 2,-1,-1,-1, 0,-2,-1, 0, 0,-2,-1,
403
-1, 1, 0, 2, 0, 0, 0, 0,-2, 0, 1, 1,
404
0, 1, 0, 1,-2, 0,-1,-1,-2,-1,-2,-2
405
};
406
407
/**********************************************************************
408
Adapt fixed length codes based on discriminant
409
**********************************************************************/
410
static const Int THRESHOLD = 8;
411
static const Int MEMORY = 8;
412
413
Void AdaptDiscriminant (CAdaptiveHuffman *pAdHuff)
414
{
415
Int iSym = pAdHuff->m_iNSymbols, t, dL, dH;
416
const Int *pCodes, *pDelta = NULL;
417
Bool bChange = FALSE;
418
static const Int gMaxTables[] = { 0,0,0,0, 1,2, 4,2, 2,2, 0,0,5 };
419
static const Int gSecondDisc[]= { 0,0,0,0, 0,0, 1,0, 0,0, 0,0,1 };
420
421
if (!pAdHuff->m_bInitialize) {
422
pAdHuff->m_bInitialize = 1;
423
pAdHuff->m_iDiscriminant = pAdHuff->m_iDiscriminant1 = 0;
424
pAdHuff->m_iTableIndex = gSecondDisc[iSym];//(gMaxTables[iSym] - 1) >> 1;
425
}
426
427
dL = dH = pAdHuff->m_iDiscriminant;
428
if (gSecondDisc[iSym]) {
429
dH = pAdHuff->m_iDiscriminant1;
430
}
431
432
if (dL < pAdHuff->m_iLowerBound) {
433
pAdHuff->m_iTableIndex--;
434
bChange = TRUE;
435
}
436
else if (dH > pAdHuff->m_iUpperBound) {
437
pAdHuff->m_iTableIndex++;
438
bChange = TRUE;
439
}
440
if (bChange) {
441
/** if initialization is fixed, we can exit on !bChange **/
442
pAdHuff->m_iDiscriminant = 0;
443
pAdHuff->m_iDiscriminant1 = 0;
444
}
445
{
446
if (pAdHuff->m_iDiscriminant < -THRESHOLD * MEMORY)
447
pAdHuff->m_iDiscriminant = -THRESHOLD * MEMORY;
448
else if (pAdHuff->m_iDiscriminant > THRESHOLD * MEMORY)
449
pAdHuff->m_iDiscriminant = THRESHOLD * MEMORY;
450
451
if (pAdHuff->m_iDiscriminant1 < -THRESHOLD * MEMORY)
452
pAdHuff->m_iDiscriminant1 = -THRESHOLD * MEMORY;
453
else if (pAdHuff->m_iDiscriminant1 > THRESHOLD * MEMORY)
454
pAdHuff->m_iDiscriminant1 = THRESHOLD * MEMORY;
455
}
456
457
t = pAdHuff->m_iTableIndex;
458
assert (t >= 0);
459
assert (t < gMaxTables[iSym]);
460
461
//pAdHuff->m_iDiscriminant >>= 1;
462
pAdHuff->m_iLowerBound = (t == 0) ? (1u << 31) : -THRESHOLD;
463
pAdHuff->m_iUpperBound = (t == gMaxTables[iSym] - 1) ? (1 << 30) : THRESHOLD;
464
465
switch (iSym) {
466
case 4:
467
pCodes = g4CodeTable;
468
pAdHuff->m_hufDecTable = (short *) g4HuffLookupTable;
469
break;
470
case 5:
471
pCodes = g5CodeTable + (iSym * 2 + 1) * t;
472
pDelta = g5DeltaTable;
473
pAdHuff->m_hufDecTable = g5HuffLookupTable[t];
474
break;
475
case 6:
476
pCodes = g6CodeTable + (iSym * 2 + 1) * t;
477
pAdHuff->m_pDelta1 = g6DeltaTable + iSym * (t - (t + 1 == gMaxTables[iSym]));
478
pDelta = g6DeltaTable + (t - 1 + (t == 0)) * iSym;
479
pAdHuff->m_hufDecTable = g6HuffLookupTable[t];
480
break;
481
case 7:
482
pCodes = g7CodeTable + (iSym * 2 + 1) * t;
483
pDelta = g7DeltaTable;
484
pAdHuff->m_hufDecTable = g7HuffLookupTable[t];
485
break;
486
case 8:
487
//printf ("%d ", t);
488
pCodes = g8CodeTable;// + (iSym * 2 + 1) * t;
489
//pDelta = g8DeltaTable;
490
pAdHuff->m_hufDecTable = g8HuffLookupTable[0];
491
break;
492
case 9:
493
pCodes = g9CodeTable + (iSym * 2 + 1) * t;
494
pDelta = g9DeltaTable;
495
pAdHuff->m_hufDecTable = g9HuffLookupTable[t];
496
break;
497
case 12:
498
pCodes = g12CodeTable + (iSym * 2 + 1) * t;
499
pAdHuff->m_pDelta1 = g12DeltaTable + iSym * (t - (t + 1 == gMaxTables[iSym]));
500
pDelta = g12DeltaTable + (t - 1 + (t == 0)) * iSym;
501
pAdHuff->m_hufDecTable = g12HuffLookupTable[t];
502
break;
503
default:
504
assert (0); // undefined fixed length table
505
return;
506
}
507
508
pAdHuff->m_pTable = pCodes;
509
pAdHuff->m_pDelta = pDelta;
510
}
511
512