1 //*@@@+++@@@@******************************************************************
2 //
3 // Copyright � Microsoft Corp.
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 //
9 // � Redistributions of source code must retain the above copyright notice,
10 //   this list of conditions and the following disclaimer.
11 // � Redistributions in binary form must reproduce the above copyright notice,
12 //   this list of conditions and the following disclaimer in the documentation
13 //   and/or other materials provided with the distribution.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 // POSSIBILITY OF SUCH DAMAGE.
26 //
27 //*@@@---@@@@******************************************************************
28 
29 #include "strcodec.h"
30 
31 #define DEQUANT(iRaw, iQP) ((iRaw) * (iQP))
32 
dequantizeBlock4x4(PixelI * pRec,Int * pOrg,const Int * pIndex,Int iQPLP)33 Void dequantizeBlock4x4(PixelI * pRec, Int * pOrg, const Int * pIndex, Int iQPLP)
34 {
35     Int i;
36 
37     for(i = 1; i < 16; i ++)
38         pRec[pIndex[i]] = DEQUANT(pOrg[i], iQPLP);
39 }
40 
dequantizeBlock2x2(PixelI * pRec,Int * pOrg,Int iQPLP)41 Void dequantizeBlock2x2(PixelI * pRec, Int * pOrg, Int iQPLP)
42 {
43     pRec[32] = DEQUANT(pOrg[1], iQPLP);
44     pRec[16] = DEQUANT(pOrg[2], iQPLP);
45     pRec[48] = DEQUANT(pOrg[3], iQPLP);
46 }
47 
dequantizeBlock4x2(PixelI * pRec,Int * pOrg,Int iQPLP)48 Void dequantizeBlock4x2(PixelI * pRec, Int * pOrg, Int iQPLP)
49 {
50     pRec[ 64] = DEQUANT(pOrg[1], iQPLP);
51     pRec[ 16] = DEQUANT(pOrg[2], iQPLP);
52     pRec[ 80] = DEQUANT(pOrg[3], iQPLP);
53     pRec[ 32] = DEQUANT(pOrg[4], iQPLP);
54     pRec[ 96] = DEQUANT(pOrg[5], iQPLP);
55     pRec[ 48] = DEQUANT(pOrg[6], iQPLP);
56     pRec[112] = DEQUANT(pOrg[7], iQPLP);
57 }
58 
59 
dequantizeMacroblock(CWMImageStrCodec * pSC)60 Int dequantizeMacroblock(CWMImageStrCodec * pSC)
61 {
62     const COLORFORMAT cf = pSC->m_param.cfColorFormat;
63     CWMIMBInfo *pMBInfo = &pSC->MBInfo;
64     CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
65     const size_t iChannels = pSC->m_param.cNumChannels;
66     size_t i;
67 
68     for(i = 0; i < iChannels; i ++){
69         //dequantize DC
70         pSC->p1MBbuffer[i][0] = DEQUANT(pMBInfo->iBlockDC[i][0], pTile->pQuantizerDC[i]->iQP);
71 
72         // dequantize LP
73         if(pSC->WMISCP.sbSubband != SB_DC_ONLY)
74             if(i == 0 || (cf != YUV_422 && cf != YUV_420))
75                 dequantizeBlock4x4(pSC->p1MBbuffer[i] , pMBInfo->iBlockDC[i], dctIndex[2], pTile->pQuantizerLP[i][pMBInfo->iQIndexLP].iQP);
76             else if(cf == YUV_422)
77                 dequantizeBlock4x2(pSC->p1MBbuffer[i], pMBInfo->iBlockDC[i], pTile->pQuantizerLP[i][pMBInfo->iQIndexLP].iQP);
78             else // 420
79                 dequantizeBlock2x2(pSC->p1MBbuffer[i], pMBInfo->iBlockDC[i], pTile->pQuantizerLP[i][pMBInfo->iQIndexLP].iQP);
80     }
81 
82     return ICERR_OK;
83 }
84 
85 /* frequency domain inverse DCAC prediction */
predDCACDec(CWMImageStrCodec * pSC)86 Void predDCACDec(CWMImageStrCodec * pSC)
87 {
88     const COLORFORMAT cf = pSC->m_param.cfColorFormat;
89     const Int iChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : (Int) pSC->m_param.cNumChannels;
90     CWMIMBInfo *pMBInfo = &(pSC->MBInfo);
91     size_t mbX = pSC->cColumn;// mbY = pSC->cRow;
92     Int iDCACPredMode = getDCACPredMode(pSC, mbX);
93     Int iDCPredMode = (iDCACPredMode & 0x3);
94     Int iADPredMode = (iDCACPredMode & 0xC);
95     PixelI * pOrg, * pRef;
96     Int ii;
97 
98     for(ii = 0; ii < iChannels; ii ++){
99         pOrg = pMBInfo->iBlockDC[ii];//[dcBlkIdx + (i >> 4)]; // current DC block
100 
101         /* DC prediction */
102         if(iDCPredMode == 1){ // predict DC from top
103             pOrg[0] += pSC->PredInfoPrevRow[ii][mbX].iDC;
104         }
105         else if(iDCPredMode == 0){ // predict DC from left
106             pOrg[0] += (pSC->PredInfo[ii] + mbX - 1)->iDC;
107         }
108         else if(iDCPredMode == 2){// predict DC from top&left
109             pOrg[0] += ((pSC->PredInfo[ii] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[ii] + mbX)->iDC) >> 1;
110         }
111 
112         /* AD prediction */
113         if(iADPredMode == 4){// predict AD from top
114             pRef = (pSC->PredInfoPrevRow[ii] + mbX)->piAD;
115             pOrg[4] += pRef[3], pOrg[8] += pRef[4], pOrg[12] += pRef[5];
116         }
117         else if(iADPredMode == 0){// predict AD from left
118             pRef = (pSC->PredInfo[ii] + mbX - 1)->piAD;
119             pOrg[1] += pRef[0], pOrg[2] += pRef[1], pOrg[3] += pRef[2];
120         }
121     }
122 
123     if(cf == YUV_420){
124         for(ii = 1; ii < 3; ii ++){
125             pOrg = pMBInfo->iBlockDC[ii];//dcBlkIdx + ii]; // current DC block
126 
127             /* DC prediction */
128             if(iDCPredMode == 1){ // predict DC from top
129                 pOrg[0] += (pSC->PredInfoPrevRow[ii] + mbX)->iDC;
130             }
131             else if(iDCPredMode == 0){ // predict DC from left
132                 pOrg[0] += (pSC->PredInfo[ii] + mbX - 1)->iDC;
133             }
134             else if(iDCPredMode == 2){ // predict DC from top&left
135                 pOrg[0] += (((pSC->PredInfo[ii] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[ii] + mbX)->iDC + 1) >> 1);
136             }
137 
138             /* AD prediciton */
139             if(iADPredMode == 4){// predict AD from top
140                 pOrg[2] += (pSC->PredInfoPrevRow[ii] + mbX)->piAD[1];
141             }
142             else if(iADPredMode == 0){// predict AD from left
143                 pOrg[1] += (pSC->PredInfo[ii] + mbX - 1)->piAD[0];
144             }
145         }
146     }
147     else if(cf == YUV_422){
148         for(ii = 1; ii < 3; ii ++){
149             pOrg = pMBInfo->iBlockDC[ii];//[dcBlkIdx + ii]; // current DC block
150 
151             /* DC prediciton */
152             if(iDCPredMode == 1){ // predict DC from top
153                 pOrg[0] += (pSC->PredInfoPrevRow[ii] + mbX)->iDC;
154             }
155             else if(iDCPredMode == 0){ // predict DC from left
156                 pOrg[0] += (pSC->PredInfo[ii] + mbX - 1)->iDC;
157             }
158             else if(iDCPredMode == 2){ // predict DC from top&left
159                 pOrg[0] += (((pSC->PredInfo[ii] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[ii] + mbX)->iDC + 1) >> 1);
160             }
161 
162             /* AD prediction */
163             if(iADPredMode == 4){// predict AD from top
164                 pOrg[4] += (pSC->PredInfoPrevRow[ii] + mbX)->piAD[4]; // AC of HT !!!
165                 pOrg[2] += (pSC->PredInfoPrevRow[ii] + mbX)->piAD[3];
166                 pOrg[6] += pOrg[2];
167             }
168             else if(iADPredMode == 0){// predict AD from left
169                 pOrg[4] += (pSC->PredInfo[ii] + mbX - 1)->piAD[4];  // AC of HT !!!
170                 pOrg[1] += (pSC->PredInfo[ii] + mbX - 1)->piAD[0];
171                 pOrg[5] += (pSC->PredInfo[ii] + mbX - 1)->piAD[2];
172             }
173             else if(iDCPredMode == 1){
174                 pOrg[6] += pOrg[2];
175             }
176         }
177     }
178 
179     pMBInfo->iOrientation = 2 - getACPredMode(pMBInfo, cf);
180 }
181 
182 /*************************************************************************
183     Frequency domain inverse AC prediction
184 *************************************************************************/
predACDec(CWMImageStrCodec * pSC)185 Void predACDec(CWMImageStrCodec * pSC)
186 {
187     const COLORFORMAT cf = pSC->m_param.cfColorFormat;
188     const Int iChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : (Int) pSC->m_param.cNumChannels;
189     // size_t mbX = pSC->cColumn, mbY = pSC->cRow;
190     CWMIMBInfo *pMBInfo = &pSC->MBInfo;
191     Int iACPredMode = 2 - pMBInfo->iOrientation;
192     PixelI * pOrg, * pRef;
193     Int i, j;
194 
195     /* AC prediction */
196     for(i = 0; i < iChannels; i++){
197         // prediction only happens inside MB
198         PixelI* pSrc = pSC->p1MBbuffer[i];//0 == i ? pSC->pY1 : (1 == i ? pSC->pU1 : pSC->pV1);
199 
200         switch (iACPredMode)
201         {
202             case 1:
203             {
204                 // predict from top
205                 static U8 blkIdx[] = {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15};
206 
207                 for (j = 0; j < sizeof(blkIdx) / sizeof(*blkIdx); ++j)
208                 {
209                     pOrg = pSrc + 16 * blkIdx[j];
210                     pRef = pOrg - 16;
211 
212                     pOrg[ 2] += pRef[ 2];
213                     pOrg[10] += pRef[10];
214                     pOrg[ 9] += pRef[ 9];
215                 }
216                 break;
217             }
218 
219             case 0:
220                 // predict from left
221                 for (j = 64; j < 256; j += 16)
222                 {
223                     pOrg = pSrc + j;
224                     pRef = pOrg - 64;
225 
226                     pOrg[1] += pRef[1];
227                     pOrg[5] += pRef[5];
228                     pOrg[6] += pRef[6];
229                 }
230                 break;
231 
232             default:
233                 // no prediction
234                 break;
235         }
236     }
237 
238     if(cf == YUV_420){
239         for(i = 16; i <= 20; i += 4){
240             PixelI* pSrc = pSC->p1MBbuffer[(i >> 2) - 3];//16 == i ? pSC->pU1 : pSC->pV1;
241 
242             switch (iACPredMode)
243             {
244                 case 1:
245                 {
246                     // predict from top
247                     for (j = 1; j <= 3; j += 2)
248                     {
249                         pOrg = pSrc + 16 * j;
250                         pRef = pOrg - 16;
251 
252                         pOrg[ 2] += pRef[ 2];
253                         pOrg[10] += pRef[10];
254                         pOrg[ 9] += pRef[ 9];
255                     }
256                     break;
257                 }
258 
259                 case 0:
260                     // predict from left
261                     for (j = 2; j <= 3; ++j)
262                     {
263                         pOrg = pSrc + 16 * j;
264                         pRef = pOrg - 32;
265 
266                         pOrg[1] += pRef[1];
267                         pOrg[5] += pRef[5];
268                         pOrg[6] += pRef[6];
269                     }
270                     break;
271 
272                 default:
273                     // no prediction
274                     break;
275             }
276         }
277     }
278     else if(cf == YUV_422){
279         for(i = 16; i < 32; i += 8){
280             PixelI* pSrc = pSC->p1MBbuffer[(i >> 3) - 1];//16 == i ? pSC->pU1 : pSC->pV1;
281 
282             switch (iACPredMode)
283             {
284                 case 1:
285                 {
286                     // predict from top
287                     for (j = 2; j < 8; j ++)
288                     {
289                         pOrg = pSrc + blkOffsetUV_422[j];
290                         pRef = pOrg - 16;
291 
292                         pOrg[10] += pRef[10];
293                         pOrg[ 2] += pRef[ 2];
294                         pOrg[ 9] += pRef[ 9];
295                     }
296                     break;
297                 }
298 
299                 case 0:
300                     // predict from left
301                     for (j = 1; j < 8; j += 2)
302                     {
303                         pOrg = pSrc + blkOffsetUV_422[j];
304                         pRef = pOrg - 64;
305 
306                         pOrg[1] += pRef[1];
307                         pOrg[5] += pRef[5];
308                         pOrg[6] += pRef[6];
309                     }
310                     break;
311 
312                 default:
313                     // no prediction
314                     break;
315             }
316         }
317     }
318 }
319 
320 /*************************************************************************
321     CBP
322 *************************************************************************/
NumOnes(int i)323 static int NumOnes(int i)
324 {
325     int retval = 0;
326     static const int g_Count[] = { 0,1,1,2, 1,2,2,3, 1,2,2,3, 2,3,3,4 };
327     i = i & 0xffff;
328     while (i) {
329         retval += g_Count[i & 0xf];
330         i >>= 4;
331     }
332     return retval;
333 }
334 
335 #define SATURATE32(x) if((unsigned int)(x + 16) >= 32) { if (x < 0) x = -16; else x = 15; }
336 
337 /* CBP prediction for 16 x 16 MB */
338 /* block index */
339 /*  0  1  4  5 */
340 /*  2  3  6  7 */
341 /*  8  9 12 13 */
342 /* 10 11 14 15 */
predCBPCDec(CWMImageStrCodec * pSC,Int iCBP,size_t mbX,size_t mbY,size_t c,CCBPModel * pModel)343 static Int predCBPCDec(CWMImageStrCodec * pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)
344 {
345     Int iNOrig;
346     const int iNDiff = AVG_NDIFF;
347     size_t c1 = c ? 1 : 0;
348 
349     UNREFERENCED_PARAMETER( mbY );
350 
351     if (pModel->m_iState[c1] == 0) {
352         if(pSC->m_bCtxLeft) {
353             if (pSC->m_bCtxTop) {
354                 iCBP ^= 1;
355             }
356             else {
357                 Int iTopCBP  = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;
358                 iCBP ^= (iTopCBP >> 10) & 1; // left: top(10) => 0
359             }
360         }
361         else {
362             Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;
363             iCBP ^= ((iLeftCBP >> 5) & 1); // left(5) => 0
364         }
365 
366         iCBP ^= (0x02 & (iCBP << 1)); // 0 => 1
367         iCBP ^= (0x10 & (iCBP << 3)); // 1 => 4
368         iCBP ^= (0x20 & (iCBP << 1)); // 4 => 5
369 
370         iCBP ^= ((iCBP & 0x33) << 2);
371         iCBP ^= ((iCBP & 0xcc) << 6);
372         iCBP ^= ((iCBP & 0x3300) << 2);
373 
374     }
375     else if (pModel->m_iState[c1] == 2) {
376         iCBP ^= 0xffff;
377     }
378 
379     iNOrig = NumOnes(iCBP);
380 
381     pModel->m_iCount0[c1] += iNOrig - iNDiff;
382     SATURATE32(pModel->m_iCount0[c1]);
383 
384     pModel->m_iCount1[c1] += 16 - iNOrig - iNDiff;
385     SATURATE32(pModel->m_iCount1[c1]);
386 
387     if (pModel->m_iCount0[c1] < 0) {
388         if (pModel->m_iCount0[c1] < pModel->m_iCount1[c1]) {
389             pModel->m_iState[c1] = 1;
390         }
391         else {
392             pModel->m_iState[c1] = 2;
393         }
394     }
395     else if (pModel->m_iCount1[c1] < 0) {
396         pModel->m_iState[c1] = 2;
397     }
398     else {
399         pModel->m_iState[c1] = 0;
400     }
401     return iCBP;
402 }
403 
predCBPC420Dec(CWMImageStrCodec * pSC,Int iCBP,size_t mbX,size_t mbY,size_t c,CCBPModel * pModel)404 static Int predCBPC420Dec(CWMImageStrCodec * pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)
405 {
406     Int iNOrig;
407     const int iNDiff = AVG_NDIFF;
408 
409     UNREFERENCED_PARAMETER( mbY );
410 
411     if (pModel->m_iState[1] == 0) {
412         if(pSC->m_bCtxLeft) {
413             if (pSC->m_bCtxTop) {
414                 iCBP ^= 1;
415             }
416             else {
417                 Int iTopCBP  = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;
418                 iCBP ^= (iTopCBP >> 2) & 1; // left: top(2) => 0
419             }
420         }
421         else {
422             Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;
423             iCBP ^= ((iLeftCBP >> 1) & 1); // left(1) => 0
424         }
425 
426         iCBP ^= (0x02 & (iCBP << 1)); // 0 => 1
427         iCBP ^= ((iCBP & 0x3) << 2); // [0 1] -> [2 3]
428     }
429     else if (pModel->m_iState[1] == 2) {
430         iCBP ^= 0xf;
431     }
432 
433     iNOrig = NumOnes(iCBP) * 4;
434 
435     pModel->m_iCount0[1] += iNOrig - iNDiff;
436     SATURATE32(pModel->m_iCount0[1]);
437 
438     pModel->m_iCount1[1] += 16 - iNOrig - iNDiff;
439     SATURATE32(pModel->m_iCount1[1]);
440 
441     if (pModel->m_iCount0[1] < 0) {
442         if (pModel->m_iCount0[1] < pModel->m_iCount1[1]) {
443             pModel->m_iState[1] = 1;
444         }
445         else {
446             pModel->m_iState[1] = 2;
447         }
448     }
449     else if (pModel->m_iCount1[1] < 0) {
450         pModel->m_iState[1] = 2;
451     }
452     else {
453         pModel->m_iState[1] = 0;
454     }
455 
456     return iCBP;
457 }
458 
predCBPC422Dec(CWMImageStrCodec * pSC,Int iCBP,size_t mbX,size_t mbY,size_t c,CCBPModel * pModel)459 static Int predCBPC422Dec(CWMImageStrCodec * pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)
460 {
461     Int iNOrig;
462     const int iNDiff = AVG_NDIFF;
463 
464     UNREFERENCED_PARAMETER( mbY );
465 
466     if (pModel->m_iState[1] == 0) {
467         if(pSC->m_bCtxLeft) {
468             if (pSC->m_bCtxTop) {
469                 iCBP ^= 1;
470             }
471             else {
472                 Int iTopCBP  = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;
473                 iCBP ^= (iTopCBP >> 6) & 1; // left: top(6) => 0
474             }
475         }
476         else {
477             Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;
478             iCBP ^= ((iLeftCBP >> 1) & 1); // left(1) => 0
479         }
480 
481         iCBP ^= (iCBP & 0x1) << 1; // [0]->[1]
482         iCBP ^= (iCBP & 0x3) << 2; // [0 1]->[2 3]
483         iCBP ^= (iCBP & 0xc) << 2; // [2 3]->[4 5]
484         iCBP ^= (iCBP & 0x30) << 2; // [4 5]->[6 7]
485     }
486     else if (pModel->m_iState[1] == 2) {
487         iCBP ^= 0xff;
488     }
489 
490     iNOrig = NumOnes(iCBP) * 2;
491 
492     pModel->m_iCount0[1] += iNOrig - iNDiff;
493     SATURATE32(pModel->m_iCount0[1]);
494 
495     pModel->m_iCount1[1] += 16 - iNOrig - iNDiff;
496     SATURATE32(pModel->m_iCount1[1]);
497 
498     if (pModel->m_iCount0[1] < 0) {
499         if (pModel->m_iCount0[1] < pModel->m_iCount1[1]) {
500             pModel->m_iState[1] = 1;
501         }
502         else {
503             pModel->m_iState[1] = 2;
504         }
505     }
506     else if (pModel->m_iCount1[1] < 0) {
507         pModel->m_iState[1] = 2;
508     }
509     else {
510         pModel->m_iState[1] = 0;
511     }
512 
513     return iCBP;
514 }
515 
516 
517 /* Coded Block Pattern (CBP) prediction */
predCBPDec(CWMImageStrCodec * pSC,CCodingContext * pContext)518 Void predCBPDec(CWMImageStrCodec *pSC, CCodingContext *pContext)
519 {
520     const COLORFORMAT cf = pSC->m_param.cfColorFormat;
521     const size_t iChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : pSC->m_param.cNumChannels;
522     size_t i, mbX = pSC->cColumn, mbY = pSC->cRow;
523     CWMIMBInfo *pMBInfo = &(pSC->MBInfo);
524 
525     for (i = 0; i < iChannels; i++) {
526         (pSC->PredInfo[i] + mbX)->iCBP = pMBInfo->iCBP[i] = predCBPCDec(pSC, pMBInfo->iDiffCBP[i], mbX, mbY, i, &pContext->m_aCBPModel); // Y Channel
527     }
528 
529     if (cf == YUV_422){
530         (pSC->PredInfo[1] + mbX)->iCBP = pMBInfo->iCBP[1] = predCBPC422Dec(pSC, pMBInfo->iDiffCBP[1], mbX, mbY, 1, &pContext->m_aCBPModel);
531         (pSC->PredInfo[2] + mbX)->iCBP = pMBInfo->iCBP[2] = predCBPC422Dec(pSC, pMBInfo->iDiffCBP[2], mbX, mbY, 2, &pContext->m_aCBPModel);
532     }
533     else if (cf == YUV_420) {
534         (pSC->PredInfo[1] + mbX)->iCBP = pMBInfo->iCBP[1] = predCBPC420Dec(pSC, pMBInfo->iDiffCBP[1], mbX, mbY, 1, &pContext->m_aCBPModel);
535         (pSC->PredInfo[2] + mbX)->iCBP = pMBInfo->iCBP[2] = predCBPC420Dec(pSC, pMBInfo->iDiffCBP[2], mbX, mbY, 2, &pContext->m_aCBPModel);
536     }
537     //}
538 }
539 
540