Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/jxr/image/encode/segenc.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 <stdio.h>
30
#include <stdlib.h>
31
#include "strcodec.h"
32
#include "encode.h"
33
34
#ifdef MEM_TRACE
35
#define TRACE_MALLOC 1
36
#define TRACE_NEW 0
37
#define TRACE_HEAP 0
38
#include "memtrace.h"
39
#endif
40
41
/** local function definitions **/
42
#ifdef X86OPT_INLINE
43
__forceinline
44
#endif
45
static Int EncodeBlock (Bool bChroma, const Int *aLocalCoef, Int iNumNonzero,
46
struct CAdaptiveHuffman **pAHexpt,
47
Int iContextOffset, BitIOInfo* pOut, UInt iLocation);
48
49
/*************************************************************************
50
EncodeSignificantAbsLevel
51
*************************************************************************/
52
#ifdef X86OPT_INLINE
53
//__forceinline
54
#endif
55
static Void EncodeSignificantAbsLevel (UInt iAbsLevel, struct CAdaptiveHuffman *pAHexpt, BitIOInfo* pOut)
56
{
57
Int iIndex, iFixed, aIndex[] = { 0,1,2,2, 3,3,3,3, 4,4,4,4, 5,5,5,5 };
58
Int aFixedLength[] = { 0, 0, 1, 2, 2, 2 };
59
60
assert(iAbsLevel > 0);
61
iAbsLevel--;
62
if (iAbsLevel >= 16) {
63
Int i = iAbsLevel;
64
iIndex = 6;
65
/** find leftmost bit **/
66
i >>= 5;
67
iFixed = 4;
68
while (i) { /** caution - infinite loop if not careful **/
69
iFixed++;
70
assert (iFixed < 30);
71
i >>= 1;
72
}
73
74
pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex];
75
putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1], pAHexpt->m_pTable[iIndex * 2 + 2]);
76
if (iFixed > 18) {
77
putBit16z (pOut, 15, 4);
78
if (iFixed > 21) {
79
putBit16z (pOut, 3, 2);
80
putBit16 (pOut, iFixed - 22, 3); // 22 - 29
81
}
82
else
83
putBit16z (pOut, iFixed - 19, 2); // 19 20 21
84
}
85
else {
86
putBit16z(pOut, (iFixed - 4), 4);
87
}
88
putBit32(pOut, iAbsLevel, iFixed);
89
}
90
else {
91
iIndex = aIndex[iAbsLevel];
92
iFixed = aFixedLength[iIndex];
93
94
pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex];
95
putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1], pAHexpt->m_pTable[iIndex * 2 + 2]);
96
putBit32(pOut, iAbsLevel, iFixed);
97
}
98
}
99
100
/*************************************************************************
101
EncodeMacroblockDC
102
*************************************************************************/
103
104
Void encodeQPIndex(BitIOInfo* pIO, U8 iIndex,U8 cBits)
105
{
106
if(iIndex == 0)
107
putBit16z(pIO, 0, 1);
108
else{
109
putBit16z(pIO, 1, 1);
110
putBit16z(pIO, iIndex - 1, cBits);
111
}
112
}
113
114
Int EncodeMacroblockDC (CWMImageStrCodec *pSC, CCodingContext *pContext, Int iMBX, Int iMBY)
115
{
116
CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
117
BitIOInfo* pIO = pContext->m_pIODC;
118
CWMIMBInfo *pMBInfo = &pSC->MBInfo;
119
Int iIndex, j = 0;
120
struct CAdaptiveHuffman *pAH;
121
Int aLaplacianMean[2] = { 0, 0}, *pLM = aLaplacianMean;
122
Int iModelBits = pContext->m_aModelDC.m_iFlcBits[0];
123
COLORFORMAT cf = pSC->m_param.cfColorFormat;
124
const Int iChannels = (Int) pSC->m_param.cNumChannels;
125
126
UNREFERENCED_PARAMETER( iMBX );
127
UNREFERENCED_PARAMETER( iMBY );
128
129
writeIS_L1(pSC, pIO);
130
131
if(pSC->m_param.bTranscode == FALSE){
132
pMBInfo->iQIndexLP = (U8)(pTile->cNumQPLP > 1 ? (rand() % pTile->cNumQPLP) : 0);
133
pMBInfo->iQIndexHP = (U8)(pTile->cNumQPHP > 1 ? (rand() % pTile->cNumQPHP) : 0);
134
}
135
if(pTile->cBitsHP == 0 && pTile->cNumQPHP > 1) // use LP QP
136
pMBInfo->iQIndexHP = pMBInfo->iQIndexLP;
137
138
if(pSC->WMISCP.bfBitstreamFormat == SPATIAL && pSC->WMISCP.sbSubband != SB_DC_ONLY){
139
if(pTile->cBitsLP > 0) // MB-based LP QP index
140
encodeQPIndex(pIO, pMBInfo->iQIndexLP, pTile->cBitsLP);
141
if( pSC->WMISCP.sbSubband != SB_NO_HIGHPASS && pTile->cBitsHP > 0) // MB-based HP QP index
142
encodeQPIndex(pIO, pMBInfo->iQIndexHP, pTile->cBitsHP);
143
}
144
145
if(pSC->m_param.bTranscode == FALSE)
146
pSC->Quantize(pSC);
147
148
predMacroblockEnc(pSC);
149
150
/** code path for Y_ONLY, CMYK and N_CHANNEL DC **/
151
if(cf == Y_ONLY || cf == CMYK || cf == NCOMPONENT) {
152
Int iQDC, iDC, iSign;
153
for (j = 0; j < iChannels; j++) {
154
iDC = pMBInfo->iBlockDC[j][0];
155
iSign = (iDC < 0);
156
iDC = abs(iDC);
157
iQDC = iDC >> iModelBits;
158
159
/** send luminance DC **/
160
if (iQDC) {
161
putBit16z(pIO, 1, 1);
162
EncodeSignificantAbsLevel((UInt) iQDC, pContext->m_pAHexpt[3], pIO);
163
*pLM += 1;
164
}
165
else {
166
putBit16z(pIO, 0, 1);
167
}
168
169
putBit16(pIO, iDC, iModelBits);
170
if (iDC) {
171
putBit16z(pIO, iSign, 1);
172
}
173
174
pLM = aLaplacianMean + 1;
175
iModelBits = pContext->m_aModelDC.m_iFlcBits[1];
176
}
177
}
178
else { /** code path for YUV DC **/
179
Int iDCY, iDCU, iDCV, iQDCY, iQDCU, iQDCV;
180
181
pAH = pContext->m_pAHexpt[2];
182
iQDCY = abs(iDCY = pMBInfo->iBlockDC[0][0]);
183
iQDCU = abs(iDCU = pMBInfo->iBlockDC[1][0]);
184
iQDCV = abs(iDCV = pMBInfo->iBlockDC[2][0]);
185
if (iModelBits) {
186
iQDCY >>= iModelBits;
187
}
188
189
iModelBits = pContext->m_aModelDC.m_iFlcBits[1];
190
if (iModelBits) {
191
iQDCU >>= iModelBits;
192
iQDCV >>= iModelBits;
193
}
194
iModelBits = pContext->m_aModelDC.m_iFlcBits[0];
195
196
iIndex = (iQDCY != 0) * 4 + (iQDCU != 0) * 2 + (iQDCV != 0);
197
putBit16z(pIO, pAH->m_pTable[iIndex * 2 + 1], pAH->m_pTable[iIndex * 2 + 2]);
198
199
/** send luminance DC **/
200
if (iQDCY) {
201
EncodeSignificantAbsLevel((UInt) iQDCY, pContext->m_pAHexpt[3], pIO);
202
*pLM += 1;
203
}
204
putBit16(pIO, abs(iDCY), iModelBits);
205
if (iDCY) {
206
putBit16z(pIO, (iDCY < 0), 1);
207
}
208
209
/** send chroma DC **/
210
pLM = aLaplacianMean + 1;
211
iModelBits = pContext->m_aModelDC.m_iFlcBits[1];
212
213
if (iQDCU) {
214
EncodeSignificantAbsLevel((UInt) iQDCU, pContext->m_pAHexpt[4], pIO);
215
*pLM += 1;
216
}
217
putBit16(pIO, abs(iDCU), iModelBits);
218
if (iDCU) {
219
putBit16z(pIO, (iDCU < 0), 1);
220
}
221
222
if (iQDCV) {
223
EncodeSignificantAbsLevel((UInt) iQDCV, pContext->m_pAHexpt[4], pIO);
224
*pLM += 1;
225
}
226
putBit16(pIO, abs(iDCV), iModelBits);
227
if (iDCV) {
228
putBit16z(pIO, (iDCV < 0), 1);
229
}
230
}
231
232
UpdateModelMB (cf, iChannels, aLaplacianMean, &(pContext->m_aModelDC));
233
234
if (pSC->m_bResetContext && pSC->WMISCP.sbSubband == SB_DC_ONLY) {
235
AdaptDiscriminant(pContext->m_pAHexpt[2]);
236
AdaptDiscriminant(pContext->m_pAHexpt[3]);
237
AdaptDiscriminant(pContext->m_pAHexpt[4]);
238
}
239
240
return ICERR_OK;
241
}
242
243
/*************************************************************************
244
Scan block with zero model bits
245
*************************************************************************/
246
#ifdef X86OPT_INLINE
247
__forceinline
248
#endif
249
static Int AdaptiveScanZero (const PixelI *pCoeffs, CAdaptiveScan *pScan,
250
Int *pRLCoeffs, const Int iCount)
251
{
252
Int k, iRun = 1, iLevel, iNumNonzero = 0;
253
254
iLevel = pCoeffs[pScan[1].uScan];
255
if (iLevel) {
256
pScan[1].uTotal++;
257
pRLCoeffs[iNumNonzero * 2] = 0;
258
pRLCoeffs[iNumNonzero * 2 + 1] = iLevel;
259
iNumNonzero++;
260
iRun = 0;
261
}
262
for (k = 2; k < iCount; k++) {
263
iLevel = pCoeffs[pScan[k].uScan];
264
iRun++;
265
if (iLevel) {
266
pScan[k].uTotal++;
267
if (pScan[k].uTotal > pScan[k - 1].uTotal) {
268
CAdaptiveScan cTemp = pScan[k];
269
pScan[k] = pScan[k - 1];
270
pScan[k - 1] = cTemp;
271
}
272
pRLCoeffs[iNumNonzero * 2] = iRun - 1;
273
pRLCoeffs[iNumNonzero * 2 + 1] = iLevel;
274
iNumNonzero++;
275
iRun = 0;
276
}
277
}
278
return iNumNonzero;
279
}
280
281
/*************************************************************************
282
Scan block with nonzero model bits, all trimmed
283
*************************************************************************/
284
#ifdef X86OPT_INLINE
285
__forceinline
286
#endif
287
static Int AdaptiveScanTrim (const PixelI *pCoeffs, CAdaptiveScan *pScan,
288
const Int iModelBits, Int *pRLCoeffs, const Int iCount)
289
{
290
Int k, iRun = 1, iLevel, iNumNonzero = 0;
291
Int iTemp;
292
unsigned int iThOff = (1 << iModelBits) - 1, iTh = iThOff * 2 + 1;
293
294
iLevel = pCoeffs[pScan[1].uScan];
295
296
if ((unsigned int)(iLevel + iThOff) >= iTh) {
297
iTemp = abs (iLevel) >> iModelBits;
298
pScan[1].uTotal++;
299
pRLCoeffs[iNumNonzero * 2] = 0;
300
pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp;
301
iNumNonzero++;
302
iRun = 0;
303
}
304
for (k = 2; k < iCount; k++) {
305
iRun++;
306
iLevel = pCoeffs[pScan[k].uScan];
307
if ((unsigned int)(iLevel + iThOff) >= iTh) {
308
iTemp = abs (iLevel) >> iModelBits;
309
pScan[k].uTotal++;
310
if (pScan[k].uTotal > pScan[k - 1].uTotal) {
311
CAdaptiveScan cTemp = pScan[k];
312
pScan[k] = pScan[k - 1];
313
pScan[k - 1] = cTemp;
314
}
315
pRLCoeffs[iNumNonzero * 2] = iRun - 1;
316
pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp;
317
iNumNonzero++;
318
iRun = 0;
319
}
320
}
321
return iNumNonzero;
322
}
323
324
/*************************************************************************
325
Scan block with nonzero model bits
326
*************************************************************************/
327
/** saves around 1.5% at QP=1 (no SIMD opt) **/
328
#define USE_GRES_LUT
329
#ifdef USE_GRES_LUT
330
static const Int gRes[] = {
331
65*2+1, 63*2+1, 61*2+1, 59*2+1, 57*2+1, 55*2+1, 53*2+1, 51*2+1, 49*2+1, 47*2+1, 45*2+1, 43*2+1, 41*2+1,
332
39*2+1, 37*2+1, 35*2+1, 33*2+1, 31*2+1, 29*2+1, 27*2+1, 25*2+1, 23*2+1, 21*2+1, 19*2+1, 17*2+1, 15*2+1,
333
13*2+1, 11*2+1, 9*2+1, 7*2+1, 5*2+1, 3*2+1,
334
0,
335
2*2+1, 4*2+1, 6*2+1, 8*2+1, 10*2+1, 12*2+1, 14*2+1, 16*2+1, 18*2+1, 20*2+1, 22*2+1, 24*2+1,
336
26*2+1, 28*2+1, 30*2+1, 32*2+1, 34*2+1, 36*2+1, 38*2+1, 40*2+1, 42*2+1, 44*2+1, 46*2+1, 48*2+1, 50*2+1,
337
52*2+1, 54*2+1, 56*2+1, 58*2+1, 60*2+1, 62*2+1, 64*2+1 };
338
#endif // USE_GRES_LUT
339
340
#ifdef X86OPT_INLINE
341
//__forceinline
342
#endif
343
static Int AdaptiveScan (const PixelI *pCoeffs, Int *pResidual,
344
CAdaptiveScan *pScan,
345
const Int iModelBits, const Int iTrimBits,
346
Int *pRLCoeffs, const Int iCount)
347
{
348
if (iModelBits == 0) {
349
return AdaptiveScanZero (pCoeffs, pScan, pRLCoeffs, iCount);
350
}
351
else if (iModelBits <= iTrimBits) {
352
return AdaptiveScanTrim (pCoeffs, pScan, iModelBits, pRLCoeffs, iCount);
353
}
354
else if (iTrimBits == 0
355
#ifdef USE_GRES_LUT
356
&& iModelBits < 6
357
#endif // USE_GRES_LUT
358
) {
359
Int k, iRun = 0, iLevel, iNumNonzero = 0;
360
Int iTemp, iTemp1;
361
const unsigned int iThOff = (1 << iModelBits) - 1, iTh = iThOff * 2 + 1;
362
363
iLevel = pCoeffs[pScan[1].uScan];
364
365
if ((unsigned int)(iLevel + iThOff) >= iTh) {
366
iTemp1 = abs (iLevel);
367
iTemp = iTemp1 >> iModelBits;
368
pResidual[pScan[1].uScan] = (iTemp1 & iThOff) * 2;
369
pScan[1].uTotal++;
370
pRLCoeffs[iNumNonzero * 2] = iRun;
371
pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp;
372
iNumNonzero++;
373
iRun = 0;
374
}
375
else {
376
iRun++;
377
#ifdef USE_GRES_LUT
378
pResidual[pScan[1].uScan] = gRes[(iLevel + 32)];
379
#else // USE_GRES_LUT
380
iTemp = -(iLevel < 0);
381
pResidual[pScan[1].uScan] = (iLevel ^ iTemp) * 4 + (6 & iTemp) + (iLevel != 0);
382
#endif // USE_GRES_LUT
383
}
384
for (k = 2; k < iCount; k++) {
385
const Int sk = pScan[k].uScan;
386
//pResidual++;
387
iLevel = pCoeffs[sk];
388
if ((unsigned int)(iLevel + iThOff) >= iTh) {
389
const Int iSign = -(iLevel < 0);
390
iTemp1 = (iSign ^ iLevel) - iSign;
391
iTemp = iTemp1 >> iModelBits;
392
pResidual[sk] = (iTemp1 & iThOff) * 2;
393
pScan[k].uTotal++;
394
if (pScan[k].uTotal > pScan[k - 1].uTotal) {
395
CAdaptiveScan cTemp = pScan[k];
396
pScan[k] = pScan[k - 1];
397
pScan[k - 1] = cTemp;
398
}
399
pRLCoeffs[iNumNonzero * 2] = iRun;
400
pRLCoeffs[iNumNonzero * 2 + 1] = (iTemp ^ iSign) - iSign;
401
iNumNonzero++;
402
iRun = 0;
403
}
404
else {
405
iRun++;
406
#ifdef USE_GRES_LUT
407
pResidual[sk] = gRes[(iLevel + 32)];
408
#else // USE_GRES_LUT
409
iTemp = -(iLevel < 0);
410
pResidual[sk] = (iLevel ^ iTemp) * 4 + (6 & iTemp) + (iLevel != 0);
411
#endif // USE_GRES_LUT
412
////(abs(iLevel) * 4) + ((iLevel < 0) * 2) + (iLevel != 0);
413
}
414
}
415
return iNumNonzero;
416
}
417
else {
418
Int k, iRun = 0, iLevel, iNumNonzero = 0;
419
Int iTemp, iTemp1;
420
const unsigned int iThOff = (1 << iModelBits) - 1, iTh = iThOff * 2 + 1;
421
422
iLevel = pCoeffs[pScan[1].uScan];
423
//pResidual++;
424
if ((unsigned int)(iLevel + iThOff) >= iTh) {
425
iTemp1 = abs (iLevel);
426
iTemp = iTemp1 >> iModelBits;
427
pResidual[pScan[1].uScan] = ((iTemp1 & iThOff) >> iTrimBits) * 2;
428
pScan[1].uTotal++;
429
pRLCoeffs[iNumNonzero * 2] = iRun;
430
pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp;
431
iNumNonzero++;
432
iRun = 0;
433
}
434
else {
435
iRun++;
436
iTemp = -(iLevel < 0);
437
iLevel = ((iLevel + iTemp) >> iTrimBits) - iTemp; // round towards zero
438
iTemp = -(iLevel < 0);
439
pResidual[pScan[1].uScan] = (iLevel ^ iTemp) * 4 + (6 & iTemp) + (iLevel != 0);
440
}
441
for (k = 2; k < iCount; k++) {
442
const Int sk = pScan[k].uScan;
443
//pResidual++;
444
iLevel = pCoeffs[sk];
445
if ((unsigned int)(iLevel + iThOff) >= iTh) {
446
iTemp1 = abs (iLevel);
447
iTemp = iTemp1 >> iModelBits;
448
pResidual[sk] = ((iTemp1 & iThOff) >> iTrimBits) * 2;
449
pScan[k].uTotal++;
450
if (pScan[k].uTotal > pScan[k - 1].uTotal) {
451
CAdaptiveScan cTemp = pScan[k];
452
pScan[k] = pScan[k - 1];
453
pScan[k - 1] = cTemp;
454
}
455
pRLCoeffs[iNumNonzero * 2] = iRun;
456
pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp;
457
iNumNonzero++;
458
iRun = 0;
459
}
460
else {
461
iRun++;
462
iTemp = -(iLevel < 0);
463
iLevel = ((iLevel + iTemp) >> iTrimBits) - iTemp; // round towards zero
464
iTemp = -(iLevel < 0);
465
pResidual[sk] = (iLevel ^ iTemp) * 4 + (6 & iTemp) + (iLevel != 0);
466
}
467
}
468
return iNumNonzero;
469
}
470
}
471
472
/*************************************************************************
473
EncodeMacroblockLowpass
474
*************************************************************************/
475
Int EncodeMacroblockLowpass (CWMImageStrCodec *pSC, CCodingContext *pContext, Int iMBX, Int iMBY)
476
{
477
const COLORFORMAT cf = pSC->m_param.cfColorFormat;
478
const Int iChannels = (Int) pSC->m_param.cNumChannels;
479
Int iFullChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : iChannels;
480
CWMIMBInfo *pMBInfo = &pSC->MBInfo;
481
BitIOInfo* pIO = pContext->m_pIOLP;
482
483
CAdaptiveScan *pScan = pContext->m_aScanLowpass;
484
Int k, /*iPrevRun = -1,*/ iRun = 0;// iLastIndex = 0;
485
Int iModelBits = pContext->m_aModelLP.m_iFlcBits[0];
486
PixelI aBuf[2][8];
487
Int aLaplacianMean[2] = {0, 0}, *pLM = aLaplacianMean;
488
Int iChannel, iVal;
489
Int aRLCoeffs[MAX_CHANNELS][32], iNumCoeffs[MAX_CHANNELS];
490
const I32 *aDC[MAX_CHANNELS];
491
Int aResidual[MAX_CHANNELS][16];
492
Void (*putBits)(BitIOInfo* pIO, U32 uiBits, U32 cBits) = putBit16;
493
494
UNREFERENCED_PARAMETER( iMBX );
495
UNREFERENCED_PARAMETER( iMBY );
496
497
if (iChannels > MAX_CHANNELS)
498
return ICERR_ERROR;
499
500
if((pSC->WMISCP.bfBitstreamFormat != SPATIAL) && (pSC->pTile[pSC->cTileColumn].cBitsLP > 0)) // MB-based LP QP index
501
encodeQPIndex(pIO, pMBInfo->iQIndexLP, pSC->pTile[pSC->cTileColumn].cBitsLP);
502
503
// set arrays
504
for (k = 0; k < iChannels; k++) {
505
aDC[k] = pMBInfo->iBlockDC[k];
506
}
507
508
/** reset adaptive scan totals **/
509
if (pSC->m_bResetRGITotals) {
510
int iScale = 2;
511
int iWeight = iScale * 16;
512
pScan[0].uTotal = MAXTOTAL;
513
for (k = 1; k < 16; k++) {
514
pScan[k].uTotal = iWeight;
515
iWeight -= iScale;
516
}
517
}
518
519
/** scan 4x4 transform **/
520
for (iChannel = 0; iChannel < iFullChannels; iChannel++) {
521
iNumCoeffs[iChannel] = AdaptiveScan (aDC[iChannel], aResidual[iChannel],
522
pScan, iModelBits, 0, aRLCoeffs[iChannel], 16);
523
524
iModelBits = pContext->m_aModelLP.m_iFlcBits[1];
525
}
526
527
if (cf == YUV_420 || cf == YUV_422) { /** interleave U and V **/
528
static const Int aRemap[] = { 4, 1,2,3, 5,6,7 };
529
const Int *pRemap = aRemap + (cf == YUV_420);
530
const Int iCount = (cf == YUV_420) ? 6 : 14;
531
Int iCoef = 0;
532
533
iRun = 0;
534
iModelBits = pContext->m_aModelLP.m_iFlcBits[1];
535
536
for (k = 0; k < iCount; k++) {
537
Int iIndex = pRemap[k >> 1];
538
Int iDC = aDC[(k & 1) + 1][iIndex];
539
aBuf[k & 1][iIndex] = iVal = abs (iDC) >> iModelBits;
540
541
if (iVal) {
542
aRLCoeffs[1][iCoef * 2] = iRun;
543
aRLCoeffs[1][iCoef * 2 + 1] = (iDC < 0) ? -iVal : iVal;
544
iCoef++;
545
iRun = 0;
546
}
547
else {
548
iRun++;
549
}
550
}
551
iNumCoeffs[1] = iCoef;
552
}
553
554
/** in raw mode, this can take 6% of the bits in the extreme low rate case!!! **/
555
if (cf == YUV_420 || cf == YUV_422)
556
iFullChannels = 2;
557
558
if (cf == YUV_420 || cf == YUV_422 || cf == YUV_444) {
559
int iCBP, iMax = iFullChannels * 4 - 5; /* actually (1 << iNChannels) - 1 **/
560
int iCountM = pContext->m_iCBPCountMax, iCountZ = pContext->m_iCBPCountZero;
561
iCBP = (iNumCoeffs[0] > 0) + (iNumCoeffs[1] > 0) * 2;
562
if (iFullChannels == 3)
563
iCBP += (iNumCoeffs[2] > 0) * 4;
564
565
if (iCountZ <= 0 || iCountM < 0) {
566
iVal = iCBP;
567
if (iCountM < iCountZ) {
568
iVal = iMax - iCBP;
569
}
570
if (iVal == 0)
571
putBit16z(pIO, 0, 1);
572
else if (iVal == 1)
573
putBit16z(pIO, (iFullChannels + 1) & 0x6, iFullChannels); // 2 or 4
574
else
575
putBit16z(pIO, iVal + iMax + 1, iFullChannels + 1); // cbp + 4 or cbp + 8
576
}
577
else {
578
putBit16z(pIO, iCBP, iFullChannels);
579
}
580
581
iCountM += 1 - 4 * (iCBP == iMax);//(b + c - 2*a);
582
iCountZ += 1 - 4 * (iCBP == 0);//(a + b - 2*c);
583
if (iCountM < -8)
584
iCountM = -8;
585
else if (iCountM > 7)
586
iCountM = 7;
587
pContext->m_iCBPCountMax = iCountM;
588
589
if (iCountZ < -8)
590
iCountZ = -8;
591
else if (iCountZ > 7)
592
iCountZ = 7;
593
pContext->m_iCBPCountZero = iCountZ;
594
}
595
else { /** 1 or N channel **/
596
for (iChannel = 0; iChannel < iChannels; iChannel++) {
597
putBit16z(pIO, (iNumCoeffs[iChannel] > 0), 1);
598
}
599
}
600
601
// set appropriate function pointer
602
if (pContext->m_aModelLP.m_iFlcBits[0] > 14 || pContext->m_aModelLP.m_iFlcBits[1] > 14) {
603
putBits = putBit32;
604
}
605
606
iModelBits = pContext->m_aModelLP.m_iFlcBits[0];
607
608
for (iChannel = 0; iChannel < iFullChannels; iChannel++) {
609
const Int *pRL = aRLCoeffs[iChannel];
610
Int iCoef = iNumCoeffs[iChannel];
611
612
if (iCoef) {
613
(*pLM) += iCoef;
614
if(EncodeBlock (iChannel > 0, pRL, iCoef, pContext->m_pAHexpt, CTDC,
615
pIO, 1 + 9 * ((cf == YUV_420) && (iChannel == 1)) + ((cf == YUV_422) && (iChannel == 1))) != ICERR_OK)
616
return ICERR_ERROR;
617
}
618
619
if (iModelBits) {
620
if ((cf == YUV_420 || cf == YUV_422) && iChannel) { // 420/422 chroma
621
for (k = 1; k < ((cf == YUV_420) ? 4 : 8); k++) {
622
putBits(pIO, abs(aDC[1][k]), iModelBits);
623
if (aBuf[0][k] == 0 && aDC[1][k]) {
624
putBit16z(pIO, (aDC[1][k] < 0), 1);
625
}
626
putBits(pIO, abs(aDC[2][k]), iModelBits);
627
if (aBuf[1][k] == 0 && aDC[2][k]) {
628
putBit16z(pIO, (aDC[2][k] < 0), 1);
629
}
630
}
631
}
632
else { // normal case
633
for (k = 1; k < 16; k++) {
634
putBit16z(pIO, aResidual[iChannel][k] >> 1, iModelBits + (aResidual[iChannel][k] & 1));
635
}
636
}
637
}
638
639
pLM = aLaplacianMean + 1;
640
iModelBits = pContext->m_aModelLP.m_iFlcBits[1];
641
}
642
643
writeIS_L1(pSC, pIO);
644
645
UpdateModelMB (cf, iChannels, aLaplacianMean, &pContext->m_aModelLP);
646
647
if (pSC->m_bResetContext) {
648
AdaptLowpassEnc(pContext);
649
}
650
651
return ICERR_OK;
652
}
653
654
/*************************************************************************
655
Adapt
656
*************************************************************************/
657
Void AdaptLowpassEnc(CCodingContext *pSC)
658
{
659
Int kk;
660
for (kk = 0; kk < CONTEXTX + CTDC; kk++) { /** adapt fixed code (index 0 and 1) as well **/
661
AdaptDiscriminant (pSC->m_pAHexpt[kk]);
662
}
663
}
664
665
Void AdaptHighpassEnc(CCodingContext *pSC)
666
{
667
Int kk;
668
//Adapt (pSC->m_pAdaptHuffCBPCY, FALSE);
669
AdaptDiscriminant (pSC->m_pAdaptHuffCBPCY);
670
AdaptDiscriminant (pSC->m_pAdaptHuffCBPCY1);
671
for (kk = 0; kk < CONTEXTX; kk++) { /** adapt fixed code **/
672
AdaptDiscriminant (pSC->m_pAHexpt[kk + CONTEXTX + CTDC]);
673
}
674
}
675
676
/*************************************************************************
677
Experimental code -- encodeBlock
678
SR = <0 1 2> == <last, nonsignificant, significant run>
679
alphabet 12:
680
pAHexpt[0] == <SR', SL, SR | first symbol>
681
alphabet 6:
682
pAHexpt[1] == <SR', SL | continuous>
683
pAHexpt[2] == <SR', SL | continuous>
684
alphabet 4:
685
pAHexpt[3] == <SR', SL | 1 free slot> (SR may be last or insignificant only)
686
alphabet f(run) (this can be extended to 6 contexts - SL and SR')
687
pAHexpt[4] == <run | continuous>
688
alphabet f(lev) (this can be extended to 9 contexts)
689
pAHexpt[5-6] == <lev | continuous> first symbol
690
pAHexpt[7-8] == <lev | continuous> condition on SRn no use
691
*************************************************************************/
692
#ifdef X86OPT_INLINE
693
__forceinline
694
#endif
695
static Void EncodeSignificantRun (Int iRun, Int iMaxRun, struct CAdaptiveHuffman *pAHexpt, BitIOInfo* pOut)
696
{
697
Int iIndex, iFLC, iBin;
698
static const Int aIndex[] = {
699
0,1,2,2,3,3,4,4,4,4,4,4,4,4,
700
0,1,2,2,3,3,4,4,4,4,0,0,0,0,
701
0,1,2,3,4,4
702
};
703
704
if (iMaxRun < 5) {
705
//if (iMaxRun == 4) {
706
//static const Int gCode[] = { 0, 1, 1, 1 };
707
static const Int gLen[] = { 3, 3, 2, 1 };
708
if (iMaxRun > 1)
709
putBit16z(pOut, (iMaxRun != iRun), gLen[iMaxRun - iRun] - (4 - iMaxRun));
710
//}
711
//else if (iMaxRun == 3) {
712
// if (iRun == 1) {
713
// putBit16z(pOut, 1, 1);
714
// }
715
// else {
716
// putBit16z(pOut, 3 ^ iRun, 2);
717
// }
718
//}
719
//else if (iMaxRun == 2) {
720
// putBit16z(pOut, 2 - iRun, 1);
721
//}
722
return;
723
}
724
725
iBin = gSignificantRunBin[iMaxRun];
726
iIndex = aIndex[iRun + iBin * 14 - 1];
727
iFLC = gSignificantRunFixedLength[iIndex + iBin * 5];
728
putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1], pAHexpt->m_pTable[iIndex * 2 + 2]);
729
//this always uses table 0
730
//pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex];
731
putBit16(pOut, iRun + 1, iFLC);
732
}
733
734
#ifdef X86OPT_INLINE
735
__forceinline
736
#endif
737
static Void EncodeFirstIndex (Bool bChroma, Int iLoc, Int iCont, Int iIndex, Int iSign,
738
struct CAdaptiveHuffman **ppAHexpt, BitIOInfo* pOut)
739
{
740
// Int iContext = iCont + 1 + bChroma * 3;
741
struct CAdaptiveHuffman *pAHexpt = ppAHexpt[bChroma * 3];
742
UNREFERENCED_PARAMETER( iLoc );
743
UNREFERENCED_PARAMETER( iCont );
744
pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex];
745
pAHexpt->m_iDiscriminant1 += pAHexpt->m_pDelta1[iIndex];
746
putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1] * 2 + iSign, pAHexpt->m_pTable[iIndex * 2 + 2] + 1);
747
return;
748
}
749
750
#ifdef X86OPT_INLINE
751
__forceinline
752
#endif
753
static Void EncodeIndex (Bool bChroma, Int iLoc, Int iCont, Int iIndex, Int iSign,
754
struct CAdaptiveHuffman **ppAHexpt, BitIOInfo* pOut)
755
{
756
Int iContext = iCont + 1 + bChroma * 3;
757
758
if (iLoc < 15) {
759
struct CAdaptiveHuffman *pAHexpt = ppAHexpt[iContext];
760
pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex];
761
pAHexpt->m_iDiscriminant1 += pAHexpt->m_pDelta1[iIndex];
762
putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1] * 2 + iSign, pAHexpt->m_pTable[iIndex * 2 + 2] + 1);
763
}
764
else if (iLoc == 15) {
765
static const U32 gCode[] = { 0, 6, 2, 7 };
766
static const U32 gLen[] = { 1, 3, 2, 3 };
767
putBit16z(pOut, gCode[iIndex] * 2 + iSign, gLen[iIndex] + 1);
768
return;
769
}
770
else {//if (iLoc == 16) {
771
putBit16z(pOut, iIndex * 2 + iSign, 1 + 1);
772
return;
773
}
774
}
775
776
#ifdef X86OPT_INLINE
777
__forceinline
778
#endif
779
static Int EncodeBlock (Bool bChroma, const Int *aLocalCoef, Int iNumNonzero,
780
struct CAdaptiveHuffman **pAHexpt, Int iContextOffset,
781
BitIOInfo* pOut, UInt iLocation)
782
{
783
Int iSR, iSL, iSRn, iIndex, k, iCont, iLev;
784
785
/** first symbol **/
786
iLev = aLocalCoef[1];
787
iSR = (aLocalCoef[0] == 0);
788
iSL = ((unsigned int) (iLev + 1) > 2U);
789
iSRn = 1;
790
if (iNumNonzero == 1) {
791
iSRn = 0;
792
}
793
else if (aLocalCoef[2] > 0) {
794
iSRn = 2;
795
}
796
iIndex = iSRn * 4 + iSL * 2 + iSR;
797
EncodeFirstIndex (bChroma, iLocation, 0, iIndex, (iLev < 0), pAHexpt + iContextOffset, pOut);
798
iCont = iSR & iSRn;
799
if (iSL) {
800
EncodeSignificantAbsLevel ((UInt)(abs(iLev) - 1), pAHexpt[6 + iContextOffset + iCont], pOut);
801
}
802
if (iSR == 0) {
803
EncodeSignificantRun (aLocalCoef[0], 15 - iLocation, pAHexpt[0], pOut);
804
}
805
iLocation += aLocalCoef[0] + 1;
806
807
for (k = 1; k < iNumNonzero; k++) {
808
if (iSRn == 2) {
809
EncodeSignificantRun (aLocalCoef[k * 2], 15 - iLocation, pAHexpt[0], pOut);
810
}
811
iLocation += aLocalCoef[k * 2] + 1;
812
iSRn = 1;
813
if (k == iNumNonzero - 1) {
814
iSRn = 0;
815
}
816
else if (aLocalCoef[k * 2 + 2] > 0) {
817
iSRn = 2;
818
}
819
//iSL = (abs(aLocalCoef[k * 2 + 1]) > 1);
820
iLev = aLocalCoef[k * 2 + 1];
821
iSL = ((unsigned int) (iLev + 1) > 2U);
822
iIndex = iSRn * 2 + iSL;
823
EncodeIndex (bChroma, iLocation, iCont, iIndex, (iLev < 0), pAHexpt + iContextOffset, pOut);
824
825
iCont &= iSRn; /** big difference! **/
826
if (iSL) {
827
EncodeSignificantAbsLevel ((UInt)(abs(iLev) - 1), pAHexpt[6 + iContextOffset + iCont], pOut);
828
}
829
//else {
830
// putBit16z(pOut, (iLev < 0), 1);
831
//}
832
}
833
834
return ICERR_OK;
835
}
836
837
/*************************************************************************
838
CodeCoeffs
839
*************************************************************************/
840
#ifdef X86OPT_INLINE
841
__forceinline
842
#endif
843
static Int CodeCoeffs (CWMImageStrCodec * pSC, CCodingContext *pContext,
844
Int iMBX, Int iMBY, BitIOInfo* pIO, BitIOInfo* pIOFL)
845
{
846
const COLORFORMAT cf = pSC->m_param.cfColorFormat;
847
const Int iChannels = (Int) pSC->m_param.cNumChannels;
848
const Int iPlanes = (cf == YUV_420 || cf == YUV_422) ? 1 : iChannels;
849
CWMIMBInfo * pMBInfo = &pSC->MBInfo;
850
CAdaptiveScan *pScan;
851
Int iBlock, iNBlocks = 4;
852
Int iSubblock, iIndex = 0;
853
Int i, k;
854
const Int iNumCoeffs = 16;
855
Int iModelBits = pContext->m_aModelAC.m_iFlcBits[0], iFlex = 0, iTrim = 0, iMask = 0;
856
Int aLaplacianMean[2] = { 0, 0}, *pLM = aLaplacianMean;
857
Bool bChroma = FALSE;
858
859
UNREFERENCED_PARAMETER( iMBX );
860
UNREFERENCED_PARAMETER( iMBY );
861
862
assert (iModelBits < 16);
863
if (pContext->m_iTrimFlexBits <= iModelBits && pSC->WMISCP.sbSubband != SB_NO_FLEXBITS) {
864
iTrim = pContext->m_iTrimFlexBits;
865
iFlex = iModelBits - pContext->m_iTrimFlexBits;
866
iMask = (1 << iFlex) - 1;
867
}
868
869
if(pSC->WMISCP.sbSubband != SB_NO_FLEXBITS)
870
writeIS_L1(pSC, pIOFL);
871
872
/** set scan arrays **/
873
if (pMBInfo->iOrientation == 1) {
874
pScan = pContext->m_aScanVert;
875
}
876
else {
877
pScan = pContext->m_aScanHoriz;
878
}
879
880
/** write out coefficients **/
881
for (i = 0; i < iPlanes; i++) {
882
Int iPattern = pMBInfo->iCBP[i];
883
884
if (cf == YUV_420) {
885
iNBlocks = 6;
886
iPattern += (pMBInfo->iCBP[1] << 16) + (pMBInfo->iCBP[2] << 20);
887
}
888
else if (cf == YUV_422) {
889
iNBlocks = 8;
890
iPattern += (pMBInfo->iCBP[1] << 16) + (pMBInfo->iCBP[2] << 24);
891
}
892
893
for (iBlock = iIndex = 0; iBlock < iNBlocks; iBlock++) {
894
writeIS_L2(pSC, pIO);
895
if (pIO != pIOFL)
896
writeIS_L2(pSC, pIOFL);
897
898
for (iSubblock = 0; iSubblock < 4; iSubblock++, iPattern >>= 1, iIndex ++) {
899
const PixelI *pCoeffs = NULL;
900
901
if(iBlock < 4){
902
pCoeffs = pSC->pPlane[i] + blkOffset[iIndex];
903
}
904
else if(cf == YUV_420){
905
pCoeffs = pSC->pPlane[iBlock - 3] + blkOffsetUV[iSubblock];
906
}
907
else if(cf == YUV_422){
908
pCoeffs = pSC->pPlane[1 + ((iBlock - 4) >> 1)] + blkOffsetUV_422[(iBlock & 1) * 4 + iSubblock];
909
}
910
911
/** put AC bits **/
912
913
if ((iPattern & 1) == 0) {
914
if (iFlex) {
915
/** FLC only, all else is skipped **/
916
for (k = 1; k < iNumCoeffs; k++) {
917
Int data = pCoeffs[dctIndex[0][k]];
918
Int atdata = (abs(data) >> iTrim);
919
Int word = atdata & iMask, len = iFlex;
920
if (atdata) {
921
word += word + (data < 0);
922
len++;
923
}
924
putBit16z(pIOFL, word, len);
925
}
926
}
927
}
928
else {
929
// WARNING!!! interaction between lowpass coefficients and highpass scan ordering - may lead to break in decoding when model bits is nonzero!
930
// Fix is to use same scan order in model bits transmission, and defer update of scan order to end of block
931
/** collect coefficients **/
932
Int aLocalCoef[32], iNumNonzero = 0;
933
Int aResidual[16];
934
935
iNumNonzero = AdaptiveScan (pCoeffs, aResidual,
936
pScan, iModelBits, iTrim, aLocalCoef, 16);
937
(*pLM) += iNumNonzero;
938
EncodeBlock (bChroma, aLocalCoef, iNumNonzero, pContext->m_pAHexpt, CTDC + CONTEXTX, pIO, 1);
939
940
if (iFlex) {
941
for (k = 1; k < iNumCoeffs; k++) {
942
putBit16z(pIOFL, aResidual[dctIndex[0][k]] >> 1, iFlex + (aResidual[dctIndex[0][k]] & 1));
943
}
944
}
945
}
946
}
947
if (iBlock == 3) {
948
iModelBits = pContext->m_aModelAC.m_iFlcBits[1];
949
assert (iModelBits < 16);
950
pLM = aLaplacianMean + 1;
951
bChroma = TRUE;
952
iTrim = iFlex = iMask = 0;
953
if (pContext->m_iTrimFlexBits <= iModelBits && pSC->WMISCP.sbSubband != SB_NO_FLEXBITS) {
954
iTrim = pContext->m_iTrimFlexBits;
955
iFlex = iModelBits - iTrim;
956
iMask = (1 << iFlex) - 1;
957
}
958
}
959
}
960
}
961
962
/** update model at end of MB **/
963
UpdateModelMB (cf, iChannels, aLaplacianMean, &pContext->m_aModelAC);
964
965
return ICERR_OK;
966
}
967
968
969
/*************************************************************************
970
CodeCBP
971
*************************************************************************/
972
static Void CodeCBP (CWMImageStrCodec * pSC, CCodingContext *pContext,
973
Int iMBX, Int iMBY, BitIOInfo *pIO)
974
{
975
const COLORFORMAT cf = pSC->m_param.cfColorFormat;
976
const Int iChannel = (cf == NCOMPONENT || cf == CMYK) ? (Int) pSC->m_param.cNumChannels : 1;
977
Int iDiffCBPCY, iDiffCBPCU = 0, iDiffCBPCV = 0, iDY;
978
Int iBlock, i, k;
979
static const Int aNumOnes[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
980
static const Int aTabLen[] = { 0, 2, 2, 2, 2, 2, 3, 2, 2, 3, 3, 2, 3, 2, 2, 0 };
981
static const Int aTabCode[] = { 0, 0, 1, 0, 2, 1, 4, 3, 3, 5, 6, 2, 7, 1, 0, 0 };
982
CAdaptiveHuffman *pAH;
983
Int iCount, iPattern, iCode, iCodeU = 0, iCodeV = 0;
984
985
UNREFERENCED_PARAMETER( iMBX );
986
UNREFERENCED_PARAMETER( iMBY );
987
988
predCBPEnc(pSC, pContext);
989
writeIS_L1(pSC, pIO);
990
991
iDiffCBPCU = pSC->MBInfo.iDiffCBP[1];
992
iDiffCBPCV = pSC->MBInfo.iDiffCBP[2];
993
994
for (i = 0; i < iChannel; i++) {
995
iDiffCBPCY = pSC->MBInfo.iDiffCBP[i];
996
997
if(cf == YUV_420){ // PackCBP420
998
iDiffCBPCY = (iDiffCBPCY & 0xf) + ((iDiffCBPCU & 1) << 4) + ((iDiffCBPCV & 1) << 5) +
999
((iDiffCBPCY & 0x00f0) << 2) + ((iDiffCBPCU & 2) << 9) + ((iDiffCBPCV & 2) << 10) +
1000
((iDiffCBPCY & 0x0f00) << 4) + ((iDiffCBPCU & 4) << 14) + ((iDiffCBPCV & 4) << 15) +
1001
((iDiffCBPCY & 0xf000) << 6) + ((iDiffCBPCU & 8) << 19) + ((iDiffCBPCV & 8) << 20);
1002
}
1003
else if(cf == YUV_422){// PackCBP422
1004
iDiffCBPCY = (iDiffCBPCY & 0xf) + ((iDiffCBPCU & 1) << 4) + ((iDiffCBPCU & 4) << 3) +
1005
((iDiffCBPCV & 1) << 6) + ((iDiffCBPCV & 4) << 5) +
1006
((iDiffCBPCY & 0x00f0) << 4) + ((iDiffCBPCU & 2) << 11) + ((iDiffCBPCU & 8) << 10) +
1007
((iDiffCBPCV & 2) << 13) + ((iDiffCBPCV & 8) << 12) +
1008
((iDiffCBPCY & 0x0f00) << 8) + ((iDiffCBPCU & 16) << 16) + ((iDiffCBPCU & 64) << 15) +
1009
((iDiffCBPCV & 16) << 18) + ((iDiffCBPCV & 64) << 17) +
1010
((iDiffCBPCY & 0xf000) << 12) + ((iDiffCBPCU & 32) << 23) + ((iDiffCBPCU & 128) << 22) +
1011
((iDiffCBPCV & 32) << 25) + ((iDiffCBPCV & 128) << 24);
1012
}
1013
1014
/** send CBPCY **/
1015
iPattern = 0;
1016
iDY = iDiffCBPCY;
1017
if (cf == YUV_444) {
1018
iDY |= (iDiffCBPCU | iDiffCBPCV);
1019
}
1020
1021
for (iBlock = 0; iBlock < 4; iBlock++) {
1022
if(cf == YUV_422) {
1023
iPattern |= ((iDY & 0xff) != 0) * 0x10;
1024
iDY >>= 8;
1025
}
1026
else if (cf == YUV_420) {
1027
iPattern |= ((iDY & 0x3f) != 0) * 0x10;
1028
iDY >>= 6;
1029
}
1030
else {
1031
iPattern |= ((iDY & 0xf) != 0) * 0x10;
1032
iDY >>= 4;
1033
}
1034
iPattern >>= 1;
1035
}
1036
1037
pAH = pContext->m_pAdaptHuffCBPCY1;
1038
iCount = aNumOnes[iPattern];
1039
putBit16z(pIO, pAH->m_pTable[iCount * 2 + 1], pAH->m_pTable[iCount * 2 + 2]);
1040
pAH->m_iDiscriminant += pAH->m_pDelta[iCount];
1041
if (aTabLen[iPattern]) {
1042
putBit16z(pIO, aTabCode[iPattern], aTabLen[iPattern]);
1043
}
1044
1045
for (iBlock = 0; iBlock < 4; iBlock++) {
1046
switch (cf) {
1047
case YUV_444:
1048
iCode = iDiffCBPCY & 0xf;
1049
iCodeU = iDiffCBPCU & 0xf;
1050
iCodeV = iDiffCBPCV & 0xf;
1051
iCode |= ((iCodeU != 0) << 4);
1052
iCode |= ((iCodeV != 0) << 5);
1053
iDiffCBPCY >>= 4;
1054
iDiffCBPCU >>= 4;
1055
iDiffCBPCV >>= 4;
1056
break;
1057
1058
case YUV_422:
1059
iCode = iDiffCBPCY & 0xff;
1060
iDiffCBPCY >>= 8;
1061
break;
1062
1063
case YUV_420:
1064
iCode = iDiffCBPCY & 0x3f;
1065
iDiffCBPCY >>= 6;
1066
break;
1067
1068
default:
1069
iCode = iDiffCBPCY & 0xf;
1070
iDiffCBPCY >>= 4;
1071
}
1072
1073
if (iCode) {
1074
static const Int gTab0[16] = { 0,1,1,2, 1,3,3,4, 1,3,3,4, 2,4,4,5 };
1075
static const Int gFL0[16] = { 0,2,2,1, 2,2,2,2, 2,2,2,2, 1,2,2,0 };
1076
static const Int gCode0[16] = { 0,0,1,0, 2,0,1,0, 3,2,3,1, 1,2,3,0 };
1077
int val, iChroma = (iCode >> 4);
1078
iCode &= 0xf;
1079
1080
if(cf == YUV_422) {
1081
iCodeU = (iChroma & 3);
1082
iCodeV = ((iChroma >> 2) & 3);
1083
iChroma = (iCodeU == 0 ? 0 : 1);
1084
if(iCodeV != 0) {
1085
iChroma += 2;
1086
}
1087
}
1088
1089
if (iChroma) {
1090
if (gTab0[iCode] > 2) {
1091
val = 8;
1092
}
1093
else {
1094
val = gTab0[iCode] + 6 - 1;
1095
}
1096
}
1097
else {
1098
val = gTab0[iCode] - 1;
1099
}
1100
pAH = pContext->m_pAdaptHuffCBPCY;
1101
putBit16z(pIO, pAH->m_pTable[val * 2 + 1], pAH->m_pTable[val * 2 + 2]);
1102
pAH->m_iDiscriminant += pAH->m_pDelta[val];
1103
1104
if (iChroma) {
1105
if (iChroma == 1)
1106
putBit16z(pIO, 1, 1);
1107
else
1108
putBit16z(pIO, 3 - iChroma, 2);
1109
}
1110
if (val == 8) {
1111
if (gTab0[iCode] == 3) {
1112
putBit16z(pIO, 1, 1);
1113
}
1114
else {
1115
putBit16z(pIO, 5 - gTab0[iCode], 2);
1116
}
1117
}
1118
if (gFL0[iCode]) {
1119
putBit16z(pIO, gCode0[iCode], gFL0[iCode]);
1120
}
1121
1122
if (cf == YUV_444) {
1123
pAH = pContext->m_pAHexpt[1];
1124
iPattern = iCodeU;
1125
for (k = 0; k < 2; k++) {
1126
if (iPattern) {
1127
iCount = aNumOnes[iPattern];
1128
iCount--;
1129
putBit16z(pIO, pAH->m_pTable[iCount * 2 + 1], pAH->m_pTable[iCount * 2 + 2]);
1130
if (aTabLen[iPattern]) {
1131
putBit16z(pIO, aTabCode[iPattern], aTabLen[iPattern]);
1132
}
1133
}
1134
iPattern = iCodeV;
1135
}
1136
}
1137
else if (cf == YUV_422){
1138
iPattern = iCodeU;
1139
for(k = 0; k < 2; k ++) {
1140
if(iPattern) {
1141
if (iPattern == 1)
1142
putBit16z(pIO, 1, 1);
1143
else {
1144
putBit16z(pIO, 3 - iPattern, 2);
1145
}
1146
}
1147
iPattern = iCodeV;
1148
}
1149
}
1150
}
1151
}
1152
}
1153
}
1154
1155
/*************************************************************************
1156
macroblock encode function using 4x4 transforms
1157
*************************************************************************/
1158
Int EncodeMacroblockHighpass(CWMImageStrCodec * pSC, CCodingContext *pContext, Int iMBX, Int iMBY)
1159
{
1160
BitIOInfo* pIO = pContext->m_pIOAC;
1161
BitIOInfo* pIOFL = pContext->m_pIOFL;
1162
1163
if((pSC->WMISCP.bfBitstreamFormat != SPATIAL) && (pSC->pTile[pSC->cTileColumn].cBitsHP > 0)) // MB-based HP QP index
1164
encodeQPIndex(pIO, pSC->MBInfo.iQIndexHP, pSC->pTile[pSC->cTileColumn].cBitsHP);
1165
1166
/** reset adaptive scan totals **/
1167
if (pSC->m_bResetRGITotals) {
1168
Int iScale = 2;
1169
Int iWeight = iScale * 16;
1170
Int k;
1171
pContext->m_aScanHoriz[0].uTotal = pContext->m_aScanVert[0].uTotal = MAXTOTAL;
1172
for (k = 1; k < 16; k++) {
1173
pContext->m_aScanHoriz[k].uTotal = pContext->m_aScanVert[k].uTotal = iWeight;
1174
iWeight -= iScale;
1175
}
1176
}
1177
CodeCBP(pSC, pContext, iMBX, iMBY, pIO);
1178
if(CodeCoeffs(pSC, pContext, iMBX, iMBY, pIO, pIOFL) != ICERR_OK)
1179
return ICERR_ERROR;
1180
1181
if (pSC->m_bResetContext) {
1182
AdaptHighpassEnc(pContext);
1183
}
1184
1185
return ICERR_OK;
1186
}
1187
1188