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 // #include "xplatform_image.h"
31 
32 #ifdef MEM_TRACE
33 #define TRACE_MALLOC    1
34 #define TRACE_NEW       0
35 #define TRACE_HEAP      0
36 #include "memtrace.h"
37 #endif
38 
39 #include <stdlib.h>
40 #include <string.h>
41 
42 #if !(defined(__ANSI__))
43 // Desktop
44 #include <windows.h>
45 #else
46 // ANSI
47 #include <time.h>
48 #endif
49 
50 Int grgiZigzagInv4x4_lowpass [] = {
51     0, 1, 4, 5, 2, 8, 6, 9,
52     3, 12, 10, 7, 13, 11, 14, 15
53 };
54 
55 Int grgiZigzagInv4x4H [] = {
56     0, 1, 4, 5, 2, 8, 6, 9,
57     3, 12, 10, 7, 13, 11, 14, 15
58 };
59 Int grgiZigzagInv4x4V [] = {
60     0, 4, 8, 5,  1, 12, 9, 6,  2, 13, 3, 15,  7, 10, 14, 11
61 };
62 
63 const Int gSignificantRunBin[] = {
64     -1,-1,-1,-1,
65     2,2,2,
66     1,1,1,1,
67     0,0,0,0
68 };
69 
70 const Int gSignificantRunFixedLength[] = {
71     0,0,1,1,3,
72     0,0,1,1,2,
73     0,0,0,0,1,
74 };
75 
76 /*************************************************************************
77     UpdateModelMB : update adaptive model at end of macroblock
78     (for lowest resolution only)
79 *************************************************************************/
80 #define MODELWEIGHT 70//90
81 
UpdateModelMB(COLORFORMAT cf,Int iChannels,Int iLaplacianMean[],CAdaptiveModel * pModel)82 Void UpdateModelMB (COLORFORMAT cf, Int iChannels, Int iLaplacianMean[], CAdaptiveModel *pModel)
83 {
84     Int j;
85     static const Int aWeight0[3] = { 240/*DC*/, 12/*LP*/, 1 };
86     static const Int aWeight1[3][MAX_CHANNELS] = {
87         { 0,240,120,80, 60,48,40,34, 30,27,24,22, 20,18,17,16 },
88         { 0,12,6,4,     3,2,2,2,     2,1,1,1,     1,1,1,1 },
89         { 0,16,8,5,     4,3,3,2,     2,2,2,1,     1,1,1,1 }
90     };
91     static const Int aWeight2[6] = { 120,37,2,/*420*/ 120,18,1/*422*/ };
92 
93     iLaplacianMean[0] *= aWeight0[pModel->m_band - BAND_DC];
94     if (cf == YUV_420) {
95         iLaplacianMean[1] *= aWeight2[pModel->m_band - BAND_DC];
96     }
97     else if (cf == YUV_422) {
98         iLaplacianMean[1] *= aWeight2[3 + (pModel->m_band) - BAND_DC];
99     }
100     else {
101         iLaplacianMean[1] *= aWeight1[pModel->m_band - BAND_DC][iChannels - 1];
102         if (pModel->m_band == BAND_AC)
103             iLaplacianMean[1] >>= 4;
104     }
105 
106     for (j = 0; j < 2; j++) {
107         Int iLM = iLaplacianMean[j];
108         Int iMS = pModel->m_iFlcState[j];
109         Int iDelta = (iLM - MODELWEIGHT) >> 2;
110 
111         if (iDelta <= -8) {
112             iDelta += 4;
113             if (iDelta < -16)
114                 iDelta = -16;
115             iMS += iDelta;
116             if (iMS < -8) {
117                 if (pModel->m_iFlcBits[j] == 0)
118                     iMS = -8;
119                 else {
120                     iMS = 0;
121                     pModel->m_iFlcBits[j]--;
122                 }
123             }
124         }
125         else if (iDelta >= 8) {
126             iDelta -= 4;
127             if (iDelta > 15)
128                 iDelta = 15;
129             iMS += iDelta;
130             if (iMS > 8) {
131                 if (pModel->m_iFlcBits[j] >= 15) {
132                     pModel->m_iFlcBits[j] = 15;
133                     iMS = 8;
134                 }
135                 else {
136                     iMS = 0;
137                     pModel->m_iFlcBits[j]++;
138                 }
139             }
140         }
141         pModel->m_iFlcState[j] = iMS;
142         if (cf == Y_ONLY)
143             break;
144     }
145 }
146 
147 
ResetCodingContext(CCodingContext * pContext)148 Void ResetCodingContext(CCodingContext *pContext)
149 {
150     // reset bit reduction models
151     memset (&(pContext->m_aModelAC), 0, sizeof(CAdaptiveModel));
152     pContext->m_aModelAC.m_band = BAND_AC;
153 
154     memset (&(pContext->m_aModelLP), 0, sizeof(CAdaptiveModel));
155     pContext->m_aModelLP.m_band = BAND_LP;
156     pContext->m_aModelLP.m_iFlcBits[0] = pContext->m_aModelLP.m_iFlcBits[1] = 4;
157 
158     memset (&(pContext->m_aModelDC), 0, sizeof(CAdaptiveModel));
159     pContext->m_aModelDC.m_band = BAND_DC;
160     pContext->m_aModelDC.m_iFlcBits[0] = pContext->m_aModelDC.m_iFlcBits[1] = 8;
161 
162     // reset CBP models
163     pContext->m_iCBPCountMax = pContext->m_iCBPCountZero = 1;
164 
165     pContext->m_aCBPModel.m_iCount0[0] = pContext->m_aCBPModel.m_iCount0[1] = -4;
166     pContext->m_aCBPModel.m_iCount1[0] = pContext->m_aCBPModel.m_iCount1[1] = 4;
167     pContext->m_aCBPModel.m_iState[0] = pContext->m_aCBPModel.m_iState[1] = 0;
168 }
169 
170 /*************************************************************************
171     Initialize zigzag scan parameters
172 *************************************************************************/
InitZigzagScan(CCodingContext * pContext)173 Void InitZigzagScan(CCodingContext * pContext)
174 {
175     if (NULL != pContext) {
176         Int i;
177         for (i=0; i<16; i++) {
178             pContext->m_aScanLowpass[i].uScan = grgiZigzagInv4x4_lowpass[i];
179             pContext->m_aScanHoriz[i].uScan = dctIndex[0][grgiZigzagInv4x4H[i]];
180             pContext->m_aScanVert[i].uScan  = dctIndex[0][grgiZigzagInv4x4V[i]];
181         }
182     }
183 }
184