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
EncodeSignificantAbsLevel(UInt iAbsLevel,struct CAdaptiveHuffman * pAHexpt,BitIOInfo * pOut)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
encodeQPIndex(BitIOInfo * pIO,U8 iIndex,U8 cBits)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
EncodeMacroblockDC(CWMImageStrCodec * pSC,CCodingContext * pContext,Int iMBX,Int iMBY)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
AdaptiveScanZero(const PixelI * pCoeffs,CAdaptiveScan * pScan,Int * pRLCoeffs,const Int iCount)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
AdaptiveScanTrim(const PixelI * pCoeffs,CAdaptiveScan * pScan,const Int iModelBits,Int * pRLCoeffs,const Int iCount)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
AdaptiveScan(const PixelI * pCoeffs,Int * pResidual,CAdaptiveScan * pScan,const Int iModelBits,const Int iTrimBits,Int * pRLCoeffs,const Int iCount)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 *************************************************************************/
EncodeMacroblockLowpass(CWMImageStrCodec * pSC,CCodingContext * pContext,Int iMBX,Int iMBY)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 *************************************************************************/
AdaptLowpassEnc(CCodingContext * pSC)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
AdaptHighpassEnc(CCodingContext * pSC)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
EncodeSignificantRun(Int iRun,Int iMaxRun,struct CAdaptiveHuffman * pAHexpt,BitIOInfo * pOut)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
EncodeFirstIndex(Bool bChroma,Int iLoc,Int iCont,Int iIndex,Int iSign,struct CAdaptiveHuffman ** ppAHexpt,BitIOInfo * pOut)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
EncodeIndex(Bool bChroma,Int iLoc,Int iCont,Int iIndex,Int iSign,struct CAdaptiveHuffman ** ppAHexpt,BitIOInfo * pOut)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
EncodeBlock(Bool bChroma,const Int * aLocalCoef,Int iNumNonzero,struct CAdaptiveHuffman ** pAHexpt,Int iContextOffset,BitIOInfo * pOut,UInt iLocation)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
CodeCoeffs(CWMImageStrCodec * pSC,CCodingContext * pContext,Int iMBX,Int iMBY,BitIOInfo * pIO,BitIOInfo * pIOFL)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 *************************************************************************/
CodeCBP(CWMImageStrCodec * pSC,CCodingContext * pContext,Int iMBX,Int iMBY,BitIOInfo * pIO)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 *************************************************************************/
EncodeMacroblockHighpass(CWMImageStrCodec * pSC,CCodingContext * pContext,Int iMBX,Int iMBY)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