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