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 "windowsmediaphoto.h"
30 #include "strcodec.h"
31 #include "decode.h"
32 
33 EXTERN_C Void freePredInfo(CWMImageStrCodec *);
34 
35 EXTERN_C Int ReadWMIHeader(CWMImageInfo *, CWMIStrCodecParam *, CCoreParameters *);
36 EXTERN_C Int StrIODecInit(CWMImageStrCodec *);
37 EXTERN_C Int StrDecInit(CWMImageStrCodec *);
38 EXTERN_C Int readPackets(CWMImageStrCodec *);
39 EXTERN_C Int DecodeMacroblockDC(CWMImageStrCodec *, CCodingContext *, Int, Int);
40 EXTERN_C Int DecodeMacroblockLowpass(CWMImageStrCodec *, CCodingContext *, Int, Int);
41 EXTERN_C Int DecodeMacroblockHighpass(CWMImageStrCodec *, CCodingContext *, Int, Int);
42 EXTERN_C Void predDCACDec(CWMImageStrCodec *);
43 EXTERN_C Void predACDec(CWMImageStrCodec *);
44 EXTERN_C Void StrIODecTerm(CWMImageStrCodec *);
45 EXTERN_C Void FreeCodingContextDec(CWMImageStrCodec *);
46 
47 EXTERN_C Int StrEncInit(CWMImageStrCodec *);
48 EXTERN_C Void StrIOEncTerm(CWMImageStrCodec *);
49 EXTERN_C Void FreeCodingContextEnc(CWMImageStrCodec *);
50 EXTERN_C Void encodeMB(CWMImageStrCodec *, Int, Int);
51 EXTERN_C Int  writeIndexTableNull(CWMImageStrCodec *);
52 EXTERN_C Void writePacketHeader(BitIOInfo *, U8, U8);
53 
54 EXTERN_C Int WriteWMIHeader(CWMImageStrCodec *);
55 EXTERN_C Int ReadImagePlaneHeader(CWMImageInfo *, CWMIStrCodecParam *, CCoreParameters *, SimpleBitIO *);
56 EXTERN_C Int WriteImagePlaneHeader(CWMImageStrCodec *);
57 EXTERN_C Int writeIndexTable(CWMImageStrCodec *);
58 EXTERN_C Int copyTo(struct WMPStream *, struct WMPStream *, size_t);
59 
60 const static Bool bFlipV[O_MAX] = {FALSE, TRUE , FALSE, TRUE, TRUE , TRUE, FALSE, FALSE};
61 const static Bool bFlipH[O_MAX] = {FALSE, FALSE, TRUE , TRUE, FALSE, TRUE, FALSE, TRUE};
62 
63 typedef struct CTileQPInfo
64 {
65     U8 dcMode;
66     U8 dcIndex[MAX_CHANNELS];
67 
68     Bool bUseDC;
69     U8 lpNum;
70     Bool bUseDCAlpha;
71     U8 lpNumAlpha;
72     U8 lpMode[16];
73     U8 lpIndex[16][MAX_CHANNELS];
74 
75     Bool bUseLP;
76     U8 hpNum;
77     Bool bUseLPAlpha;
78     U8 hpNumAlpha;
79     U8 hpMode[16];
80     U8 hpIndex[16][MAX_CHANNELS];
81 } CTileQPInfo;
82 
transcodeQuantizer(BitIOInfo * pIO,U8 cIndex[MAX_CHANNELS],U8 cChMode,size_t cChannel)83 Void transcodeQuantizer(BitIOInfo * pIO, U8 cIndex[MAX_CHANNELS], U8 cChMode, size_t cChannel)
84 {
85     if(cChMode > 2)
86         cChMode = 2;
87 
88     if(cChannel > 1)
89         putBit16(pIO, cChMode, 2); // Channel mode
90     else
91         cChMode = 0;
92 
93     putBit16(pIO, cIndex[0], 8); // Y
94 
95     if(cChMode == 1)  // MIXED
96         putBit16(pIO, cIndex[1], 8); // UV
97     else if(cChMode > 0){ // INDEPENDENT
98         size_t i;
99 
100         for(i = 1; i < cChannel; i ++)
101             putBit16(pIO, cIndex[i], 8); // UV
102     }
103 }
104 
transcodeQuantizers(BitIOInfo * pIO,U8 cIndex[16][MAX_CHANNELS],U8 cChMode[16],U32 cNum,size_t cChannel,Bool bCopy)105 Void transcodeQuantizers(BitIOInfo * pIO, U8 cIndex[16][MAX_CHANNELS], U8 cChMode[16], U32 cNum, size_t cChannel, Bool bCopy)
106 {
107     putBit16(pIO, bCopy == TRUE ? 1 : 0, 1);
108     if(bCopy == FALSE){
109         U32 i;
110 
111         putBit16(pIO, cNum - 1, 4);
112 
113         for(i = 0; i < cNum; i ++)
114             transcodeQuantizer(pIO, cIndex[i], cChMode[i], cChannel);
115     }
116 }
117 
transcodeQuantizersAlpha(BitIOInfo * pIO,U8 cIndex[16][MAX_CHANNELS],U32 cNum,size_t iChannel,Bool bCopy)118 Void transcodeQuantizersAlpha(BitIOInfo * pIO, U8 cIndex[16][MAX_CHANNELS], U32 cNum, size_t iChannel, Bool bCopy)
119 {
120     putBit16(pIO, bCopy == TRUE ? 1 : 0, 1);
121     if(bCopy == FALSE){
122         U32 i;
123 
124         putBit16(pIO, cNum - 1, 4);
125 
126         for(i = 0; i < cNum; i ++)
127             putBit16(pIO, cIndex[i][iChannel], 8);
128     }
129 }
130 
transcodeTileHeader(CWMImageStrCodec * pSC,CTileQPInfo * pTileQPInfo)131 Void transcodeTileHeader(CWMImageStrCodec * pSC, CTileQPInfo * pTileQPInfo)
132 {
133     if(pSC->m_bCtxLeft && pSC->m_bCtxTop && pSC->m_bSecondary == FALSE){ // write packet headers
134         CCodingContext * pContext = &pSC->m_pCodingContext[pSC->cTileColumn];
135         CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
136         U8 pID = (U8)((pSC->cTileRow * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + pSC->cTileColumn) & 0x1F);
137         CWMImageStrCodec * pSCAlpha = (pSC->m_param.bAlphaChannel ? pSC->m_pNextSC : NULL);
138         const size_t iAlphaPos = pSC->m_param.cNumChannels;
139 
140         writePacketHeader(pContext->m_pIODC, pSC->WMISCP.bfBitstreamFormat == SPATIAL ? 0 : 1, pID);
141         if (pSC->m_param.bTrimFlexbitsFlag && pSC->WMISCP.bfBitstreamFormat == SPATIAL)
142             putBit16(pContext->m_pIODC, pContext->m_iTrimFlexBits, 4);
143 
144         if((pSC->m_param.uQPMode & 1) != 0) // not DC uniform
145             transcodeQuantizer(pContext->m_pIODC, pTileQPInfo->dcIndex, pTileQPInfo->dcMode, pSC->WMISCP.cChannel);
146         if(pSCAlpha != NULL && (pSCAlpha->m_param.uQPMode & 1) != 0) // not DC uniform
147             putBit16(pContext->m_pIODC, pTileQPInfo->dcIndex[iAlphaPos], 8);
148 
149         if(pSC->WMISCP.bfBitstreamFormat == SPATIAL) {
150             if(pSC->WMISCP.sbSubband != SB_DC_ONLY){
151                 if((pSC->m_param.uQPMode & 2) != 0) // not LP uniform
152                     transcodeQuantizers(pContext->m_pIODC, pTileQPInfo->lpIndex, pTileQPInfo->lpMode, pTileQPInfo->lpNum, pSC->WMISCP.cChannel, pTileQPInfo->bUseDC);
153                 if(pSCAlpha != NULL && (pSCAlpha->m_param.uQPMode & 2) != 0) // not LP uniform
154                     transcodeQuantizersAlpha(pContext->m_pIODC, pTileQPInfo->lpIndex, pTileQPInfo->lpNumAlpha, iAlphaPos, pTileQPInfo->bUseDCAlpha);
155                 if(pSC->WMISCP.sbSubband != SB_NO_HIGHPASS){
156                     if((pSC->m_param.uQPMode & 4) != 0) // not HP uniform
157                         transcodeQuantizers(pContext->m_pIODC, pTileQPInfo->hpIndex, pTileQPInfo->hpMode, pTileQPInfo->hpNum, pSC->WMISCP.cChannel, pTileQPInfo->bUseLP);
158                     if(pSCAlpha != NULL && (pSCAlpha->m_param.uQPMode & 4) != 0) // not HP uniform
159                         transcodeQuantizersAlpha(pContext->m_pIODC, pTileQPInfo->hpIndex, pTileQPInfo->hpNumAlpha, iAlphaPos, pTileQPInfo->bUseLPAlpha);
160                 }
161             }
162         }
163         else{
164             if(pSC->WMISCP.sbSubband != SB_DC_ONLY){
165                 writePacketHeader(pContext->m_pIOLP, 2, pID);
166                 if((pSC->m_param.uQPMode & 2) != 0) // not LP uniform
167                     transcodeQuantizers(pContext->m_pIOLP, pTileQPInfo->lpIndex, pTileQPInfo->lpMode, pTileQPInfo->lpNum, pSC->WMISCP.cChannel, pTileQPInfo->bUseDC);
168                 if(pSCAlpha != NULL && (pSCAlpha->m_param.uQPMode & 2) != 0) // not LP uniform
169                     transcodeQuantizersAlpha(pContext->m_pIOLP, pTileQPInfo->lpIndex, pTileQPInfo->lpNumAlpha, iAlphaPos, pTileQPInfo->bUseDCAlpha);
170 
171                 if(pSC->WMISCP.sbSubband != SB_NO_HIGHPASS){
172                     writePacketHeader(pContext->m_pIOAC, 3, pID);
173                     if((pSC->m_param.uQPMode & 4) != 0) // not HP uniform
174                         transcodeQuantizers(pContext->m_pIOAC, pTileQPInfo->hpIndex, pTileQPInfo->hpMode, pTileQPInfo->hpNum, pSC->WMISCP.cChannel, pTileQPInfo->bUseLP);
175                     if(pSCAlpha != NULL && (pSCAlpha->m_param.uQPMode & 4) != 0) // not HP uniform
176                         transcodeQuantizersAlpha(pContext->m_pIOAC, pTileQPInfo->hpIndex, pTileQPInfo->hpNumAlpha, iAlphaPos, pTileQPInfo->bUseLPAlpha);
177 
178                     if(pSC->WMISCP.sbSubband != SB_NO_FLEXBITS){
179                         writePacketHeader(pContext->m_pIOFL, 4, pID);
180                         if (pSC->m_param.bTrimFlexbitsFlag)
181                             putBit16(pContext->m_pIOFL, pContext->m_iTrimFlexBits, 4);
182                     }
183                 }
184             }
185         }
186         pTile->cBitsLP = (pTileQPInfo->bUseDC ? 0 : dquantBits(pTileQPInfo->lpNum));
187         pTile->cBitsHP = (pTileQPInfo->bUseLP ? 0 : dquantBits(pTileQPInfo->hpNum));
188         if(pSCAlpha != NULL){
189             pTile = pSCAlpha->pTile + pSC->cTileColumn;
190             pTile->cBitsLP = (pTileQPInfo->bUseDCAlpha ? 0 : dquantBits(pTileQPInfo->lpNumAlpha));
191             pTile->cBitsHP = (pTileQPInfo->bUseLPAlpha ? 0 : dquantBits(pTileQPInfo->hpNumAlpha));
192         }
193     }
194 }
195 
transformDCBlock(PixelI * pOrg,PixelI * pDst,ORIENTATION oOrientation)196 Void transformDCBlock(PixelI * pOrg, PixelI * pDst, ORIENTATION oOrientation)
197 {
198     size_t i;
199 
200     if(bFlipV[oOrientation])
201         for(i = 0; i < 16; i += 4)
202             pOrg[i + 1] = -pOrg[i + 1], pOrg[i + 3] = -pOrg[i + 3];
203 
204     if(bFlipH[oOrientation])
205         for(i = 0; i < 4; i ++)
206             pOrg[i + 4] = -pOrg[i + 4], pOrg[i + 12] = -pOrg[i + 12];
207 
208     if(oOrientation < O_RCW)
209         memcpy(pDst, pOrg, 16 * sizeof(PixelI));
210     else
211         for(i = 0; i < 16; i ++)
212             pDst[i] = pOrg[(i >> 2) + ((i & 3) << 2)];
213 }
214 
transformDCBlock422(PixelI * pOrg,PixelI * pDst,ORIENTATION oOrientation)215 Void transformDCBlock422(PixelI * pOrg, PixelI * pDst, ORIENTATION oOrientation)
216 {
217     assert(oOrientation < O_RCW);
218 
219     if(bFlipV[oOrientation])
220         pOrg[1] = -pOrg[1], pOrg[3] = -pOrg[3], pOrg[4] = -pOrg[4], pOrg[5] = -pOrg[5], pOrg[7] = -pOrg[7];
221 
222     if(bFlipH[oOrientation])
223         pOrg[2] = -pOrg[2], pOrg[3] = -pOrg[3], pOrg[6] = -pOrg[6], pOrg[7] = -pOrg[7];
224 
225     if(bFlipV[oOrientation])
226         pDst[0] = pOrg[0], pDst[1] = pOrg[5], pDst[2] = pOrg[6], pDst[3] = pOrg[7], pDst[4] = pOrg[4], pDst[5] = pOrg[1], pDst[6] = pOrg[2], pDst[7] = pOrg[3];
227     else
228         memcpy(pDst, pOrg, 8 * sizeof(PixelI));
229 }
230 
transformDCBlock420(PixelI * pOrg,PixelI * pDst,ORIENTATION oOrientation)231 Void transformDCBlock420(PixelI * pOrg, PixelI * pDst, ORIENTATION oOrientation)
232 {
233     if(bFlipV[oOrientation])
234         pOrg[1] = -pOrg[1], pOrg[3] = -pOrg[3];
235 
236     if(bFlipH[oOrientation])
237         pOrg[2] = -pOrg[2], pOrg[3] = -pOrg[3];
238 
239     pDst[0] = pOrg[0], pDst[3] = pOrg[3];
240     if(oOrientation < O_RCW)
241         pDst[1] = pOrg[1], pDst[2] = pOrg[2];
242     else
243         pDst[1] = pOrg[2], pDst[2] = pOrg[1];
244 }
245 
transformACBlocks(PixelI * pOrg,PixelI * pDst,ORIENTATION oOrientation)246 Void transformACBlocks(PixelI * pOrg, PixelI * pDst, ORIENTATION oOrientation)
247 {
248     PixelI * pO, * pD;
249     const Int * pT = dctIndex[0];
250     size_t i, j, k;
251 
252     for(j = 0, pO = pOrg; j < 16; j ++, pO += 16){
253         if(bFlipV[oOrientation])
254             for(i = 0; i < 16; i += 4)
255                 pO[pT[i + 1]] = -pO[pT[i + 1]], pO[pT[i + 3]] = -pO[pT[i + 3]];
256 
257         if(bFlipH[oOrientation])
258             for(i = 0; i < 4; i ++)
259                 pO[pT[i + 4]] = -pO[pT[i + 4]], pO[pT[i + 12]] = -pO[pT[i + 12]];
260     }
261 
262     for(j = 0; j < 4; j ++)
263         for(i = 0; i < 4; i ++){
264             size_t ii = (bFlipV[oOrientation] ? 3 - i : i);
265             size_t jj = (bFlipH[oOrientation] ? 3 - j : j);
266 
267             if(oOrientation < O_RCW)
268                 memcpy(pDst + (jj * 4 + ii) * 16, pOrg + (j * 4 + i) * 16, 16 * sizeof(PixelI));
269             else{
270                 pO = pOrg + (j * 4 + i) * 16;
271                 pD = pDst + (ii * 4 + jj) * 16;
272                 for(k = 1; k < 16; k ++)
273                     pD[pT[k]] = pO[pT[(k >> 2) + ((k & 3) << 2)]];
274             }
275         }
276 }
277 
transformACBlocks422(PixelI * pOrg,PixelI * pDst,ORIENTATION oOrientation)278 Void transformACBlocks422(PixelI * pOrg, PixelI * pDst, ORIENTATION oOrientation)
279 {
280     PixelI * pO;
281     const Int * pT = dctIndex[0];
282     size_t i, j;
283 
284     assert(oOrientation < O_RCW);
285 
286     for(j = 0, pO = pOrg; j < 8; j ++, pO += 16){
287         if(bFlipV[oOrientation])
288             for(i = 0; i < 16; i += 4)
289                 pO[pT[i + 1]] = -pO[pT[i + 1]], pO[pT[i + 3]] = -pO[pT[i + 3]];
290 
291         if(bFlipH[oOrientation])
292             for(i = 0; i < 4; i ++)
293                 pO[pT[i + 4]] = -pO[pT[i + 4]], pO[pT[i + 12]] = -pO[pT[i + 12]];
294     }
295 
296     for(j = 0; j < 2; j ++)
297         for(i = 0; i < 4; i ++){
298             size_t ii = (bFlipV[oOrientation] ? 3 - i : i);
299             size_t jj = (bFlipH[oOrientation] ? 1 - j : j);
300 
301             memcpy(pDst + (jj * 4 + ii) * 16, pOrg + (j * 4 + i) * 16, 16 * sizeof(PixelI));
302         }
303 }
304 
transformACBlocks420(PixelI * pOrg,PixelI * pDst,ORIENTATION oOrientation)305 Void transformACBlocks420(PixelI * pOrg, PixelI * pDst, ORIENTATION oOrientation)
306 {
307     PixelI * pO, * pD;
308     const Int * pT = dctIndex[0];
309     size_t i, j, k;
310 
311     for(j = 0, pO = pOrg; j < 4; j ++, pO += 16){
312         if(bFlipV[oOrientation])
313             for(i = 0; i < 16; i += 4)
314                 pO[pT[i + 1]] = -pO[pT[i + 1]], pO[pT[i + 3]] = -pO[pT[i + 3]];
315 
316         if(bFlipH[oOrientation])
317             for(i = 0; i < 4; i ++)
318                 pO[pT[i + 4]] = -pO[pT[i + 4]], pO[pT[i + 12]] = -pO[pT[i + 12]];
319     }
320 
321     for(j = 0; j < 2; j ++)
322         for(i = 0; i < 2; i ++){
323             size_t ii = (bFlipV[oOrientation] ? 1 - i : i);
324             size_t jj = (bFlipH[oOrientation] ? 1 - j : j);
325 
326             if(oOrientation < O_RCW)
327                 memcpy(pDst + (jj * 2 + ii) * 16, pOrg + (j * 2 + i) * 16, 16 * sizeof(PixelI));
328             else{
329                 pO = pOrg + (j * 2 + i) * 16;
330                 pD = pDst + (ii * 2 + jj) * 16;
331                 for(k = 1; k < 16; k ++)
332                     pD[pT[k]] = pO[pT[(k >> 2) + ((k & 3) << 2)]];
333             }
334         }
335 }
336 
getROI(CWMImageInfo * pII,CCoreParameters * pCore,CWMIStrCodecParam * pSCP,CWMTranscodingParam * pParam)337 Int getROI(CWMImageInfo * pII, CCoreParameters * pCore, CWMIStrCodecParam * pSCP, CWMTranscodingParam * pParam)
338 {
339     const ORIENTATION oO = pParam->oOrientation;
340     size_t iLeft, iTop, cWidth, cHeight, i, j;
341     size_t mbLeft, mbRight, mbTop, mbBottom;
342     size_t * iTile = (size_t *)malloc(MAX_TILES * sizeof(size_t));
343 
344     if(iTile == NULL)
345         return ICERR_ERROR;
346 
347     if(pParam->cLeftX + pParam->cWidth > pII->cWidth || pParam->cTopY + pParam->cHeight > pII->cHeight) // invalid region
348         return ICERR_ERROR;
349 
350     cWidth = pParam->cWidth, cHeight = pParam->cHeight;
351     iLeft = pParam->cLeftX + pCore->cExtraPixelsLeft, iTop = pParam->cTopY + pCore->cExtraPixelsTop;
352     if(pSCP->olOverlap != OL_NONE && pParam->bIgnoreOverlap == FALSE){ // include pixels borrowed
353         size_t cBlurred = (pSCP->olOverlap == OL_TWO ? 10 : 2);
354 
355         if(iLeft > cBlurred)
356             iLeft -= cBlurred, cWidth += cBlurred;
357         else
358             cWidth += iLeft, iLeft = 0;
359         if(iTop > cBlurred)
360             iTop -= cBlurred, cHeight += cBlurred;
361         else
362             cHeight += iTop, iTop = 0;
363         cWidth += cBlurred, cHeight += cBlurred;
364         if(iLeft + cWidth > pII->cWidth + pCore->cExtraPixelsLeft + pCore->cExtraPixelsRight)
365             cWidth = pII->cWidth  + pCore->cExtraPixelsLeft + pCore->cExtraPixelsRight - iLeft;
366         if(iTop + cHeight > pII->cHeight + pCore->cExtraPixelsTop + pCore->cExtraPixelsBottom)
367             cHeight = pII->cHeight + pCore->cExtraPixelsTop + pCore->cExtraPixelsBottom - iTop;
368     }
369 
370     mbTop = (iTop >> 4), mbLeft = (iLeft >> 4);
371     mbBottom = (iTop + cHeight + 15) >> 4, mbRight = (iLeft + cWidth + 15) >> 4;
372     pCore->cExtraPixelsLeft += pParam->cLeftX - (mbLeft << 4);
373     pCore->cExtraPixelsRight = ((mbRight - mbLeft) << 4) - pParam->cWidth - pCore->cExtraPixelsLeft;
374     pCore->cExtraPixelsTop += pParam->cTopY - (mbTop << 4);
375     pCore->cExtraPixelsBottom = ((mbBottom - mbTop) << 4) - pParam->cHeight - pCore->cExtraPixelsTop;
376 
377     pII->cWidth = ((mbRight - mbLeft) << 4) - pCore->cExtraPixelsLeft - pCore->cExtraPixelsRight;
378     pII->cHeight = ((mbBottom - mbTop) << 4) - pCore->cExtraPixelsTop - pCore->cExtraPixelsBottom;
379     pParam->cLeftX = iLeft, pParam->cTopY = iTop;
380     pParam->cWidth = cWidth, pParam->cHeight = cHeight;
381 
382     // extra pixels in transformed space
383 #define SWAP(a, b) i = a, a = b, b = i
384     if(oO == O_FLIPH || oO == O_FLIPVH || oO == O_RCW_FLIPV || oO == O_RCW_FLIPVH)
385         SWAP(pCore->cExtraPixelsLeft, pCore->cExtraPixelsRight);
386     if(oO == O_FLIPV || oO == O_FLIPVH || oO == O_RCW || oO == O_RCW_FLIPV)
387         SWAP(pCore->cExtraPixelsTop, pCore->cExtraPixelsBottom);
388     if(oO >= O_RCW){
389         SWAP(pCore->cExtraPixelsLeft, pCore->cExtraPixelsTop);
390         SWAP(pCore->cExtraPixelsRight, pCore->cExtraPixelsBottom);
391     }
392 
393     // adjust tiling
394     for(i = 0, j = 0, iTile[0] = 0; i <= (size_t)pSCP->cNumOfSliceMinus1V; i ++)
395         if((size_t)pSCP->uiTileX[i] >= mbLeft && (size_t)pSCP->uiTileX[i] < mbRight){
396             if(j >= MAX_TILES)
397                 j = MAX_TILES - 1;
398             iTile[j] = (size_t)pSCP->uiTileX[i] - mbLeft, j ++;
399         }
400     if(iTile[0] == 0)
401         for(i = 0, pSCP->cNumOfSliceMinus1V = (j == 0 ? 0 : (U32)(j - 1)); i < j; i ++)
402             pSCP->uiTileX[i] = (U32)iTile[i];
403     else
404         for(i = 1, pSCP->uiTileX[0] = 0, pSCP->cNumOfSliceMinus1V = (U32)j; i <= j; i ++)
405             pSCP->uiTileX[i] = (U32)iTile[i - 1];
406     if(oO == O_FLIPH || oO == O_FLIPVH || oO == O_RCW_FLIPV || oO == O_RCW_FLIPVH){ // reverse order
407         for(i = 0; i <= (size_t)pSCP->cNumOfSliceMinus1V; i ++)
408             iTile[i] = mbRight - mbLeft - (size_t)pSCP->uiTileX[i];
409         for(i = 1, pSCP->uiTileX[0] = 0; i <= (size_t)pSCP->cNumOfSliceMinus1V; i ++)
410             pSCP->uiTileX[i] = (U32)(iTile[(size_t)pSCP->cNumOfSliceMinus1V - i + 1]);
411     }
412     for(i = 0, j = 0, iTile[0] = 0; i <= (size_t)pSCP->cNumOfSliceMinus1H; i ++)
413         if(pSCP->uiTileY[i] >= mbTop && pSCP->uiTileY[i] < mbBottom){
414             if(j >= MAX_TILES)
415                 j = MAX_TILES - 1;
416             iTile[j] = (size_t)pSCP->uiTileY[i] - mbTop, j ++;
417         }
418     if(iTile[0] == 0)
419         for(i = 0, pSCP->cNumOfSliceMinus1H = (j == 0 ? 0 : (U32)(j - 1)); i < j; i ++)
420             pSCP->uiTileY[i] = (U32)iTile[i];
421     else
422         for(i = 1, pSCP->uiTileY[0] = 0, pSCP->cNumOfSliceMinus1H = (U32)j; i <= j; i ++)
423             pSCP->uiTileY[i] = (U32)iTile[i - 1];
424     if(oO == O_FLIPV || oO == O_FLIPVH || oO == O_RCW || oO == O_RCW_FLIPV){ // reverse order
425         for(i = 0; i <= (size_t)pSCP->cNumOfSliceMinus1H; i ++)
426             iTile[i] = mbBottom - mbTop - (size_t)pSCP->uiTileY[i];
427         for(i = 1, pSCP->uiTileY[0] = 0; i <= (size_t)pSCP->cNumOfSliceMinus1H; i ++)
428             pSCP->uiTileY[i] = (U32)(iTile[(size_t)pSCP->cNumOfSliceMinus1H - i + 1]);
429     }
430     if(oO >= O_RCW){ // switch X & Y
431         for(i = 0; i <= (size_t)pSCP->cNumOfSliceMinus1V; i ++)
432             iTile[i] = (size_t)pSCP->uiTileX[i];
433         for(i = 0; i <= (size_t)pSCP->cNumOfSliceMinus1H; i ++)
434             pSCP->uiTileX[i] = pSCP->uiTileY[i];
435         for(i = 0; i <= (size_t)pSCP->cNumOfSliceMinus1V; i ++)
436             pSCP->uiTileY[i] = (U32)iTile[i];
437         i = (size_t)pSCP->cNumOfSliceMinus1H, pSCP->cNumOfSliceMinus1H = pSCP->cNumOfSliceMinus1V, pSCP->cNumOfSliceMinus1V = (U32)i;
438     }
439 
440     free(iTile);
441 
442     return ICERR_OK;
443 }
444 
isTileBoundary(U32 * pTilePos,U32 cTiles,U32 cMBs,U32 iPos)445 Bool isTileBoundary(U32 * pTilePos, U32 cTiles, U32 cMBs, U32 iPos)
446 {
447     U32 i;
448 
449     for(i = 0; i < cTiles; i ++)
450         if(iPos == pTilePos[i] * 16)
451             break;
452 
453     return ((i < cTiles || (iPos + 15) / 16 >= cMBs) ? TRUE : FALSE);
454 }
455 
isTileExtraction(CWMImageStrCodec * pSC,CWMTranscodingParam * pParam)456 Bool isTileExtraction(CWMImageStrCodec * pSC, CWMTranscodingParam * pParam)
457 {
458     if(pParam->bIgnoreOverlap == FALSE && pSC->WMISCP.olOverlap == OL_NONE)
459         pParam->bIgnoreOverlap = TRUE;
460 
461     if(pParam->bIgnoreOverlap == TRUE && pParam->oOrientation == O_NONE && pParam->bfBitstreamFormat == pSC->WMISCP.bfBitstreamFormat){
462         if(pParam->bfBitstreamFormat == SPATIAL && pParam->sbSubband != pSC->WMISCP.sbSubband)
463             return FALSE;
464 
465         return (isTileBoundary(pSC->WMISCP.uiTileX, pSC->WMISCP.cNumOfSliceMinus1V + 1, (U32)pSC->cmbWidth, (U32)(pParam->cLeftX + pSC->m_param.cExtraPixelsLeft)) &&
466             isTileBoundary(pSC->WMISCP.uiTileY, pSC->WMISCP.cNumOfSliceMinus1H + 1, (U32)pSC->cmbHeight, (U32)(pParam->cTopY + pSC->m_param.cExtraPixelsTop)) &&
467             isTileBoundary(pSC->WMISCP.uiTileX, pSC->WMISCP.cNumOfSliceMinus1V + 1, (U32)pSC->cmbWidth, (U32)(pParam->cLeftX + pParam->cWidth + pSC->m_param.cExtraPixelsLeft)) &&
468             isTileBoundary(pSC->WMISCP.uiTileY, pSC->WMISCP.cNumOfSliceMinus1H + 1, (U32)pSC->cmbHeight, (U32)(pParam->cTopY + pParam->cHeight + pSC->m_param.cExtraPixelsTop)));
469     }
470 
471     return FALSE;
472 }
473 
WMPhotoTranscode(struct WMPStream * pStreamIn,struct WMPStream * pStreamOut,CWMTranscodingParam * pParam)474 Int WMPhotoTranscode(struct WMPStream * pStreamIn, struct WMPStream * pStreamOut, CWMTranscodingParam * pParam)
475 {
476     PixelI * pMBBuf, MBBufAlpha[256]; // shared buffer, decoder <=> encoder bridge
477     PixelI * pFrameBuf = NULL, * pFrameBufAlpha = NULL;
478     CWMIMBInfo * pMBInfo = NULL, * pMBInfoAlpha = NULL;
479     CWMImageStrCodec * pSCDec, * pSCEnc, * pSC;
480     CWMDecoderParameters aDecoderParam = {0};
481     U8 * pIOHeaderDec, * pIOHeaderEnc;
482     CCodingContext * pContext;
483     CTileQPInfo * pTileQPInfo = NULL;
484     ORIENTATION oO = pParam->oOrientation;
485     size_t iAlphaPos = 0;
486     size_t cUnit;
487     size_t i, j, mbLeft, mbRight, mbTop, mbBottom, mbWidth, mbHeight;
488 
489     if(pStreamIn == NULL || pStreamOut == NULL || pParam == NULL)
490         return ICERR_ERROR;
491 
492     // initialize decoder
493     if((pSCDec = (CWMImageStrCodec *)malloc(sizeof(CWMImageStrCodec))) == NULL)
494         return ICERR_ERROR;
495     memset(pSCDec, 0, sizeof(CWMImageStrCodec));
496 
497     pSCDec->WMISCP.pWStream = pStreamIn;
498     if(ReadWMIHeader(&pSCDec->WMII, &pSCDec->WMISCP, &pSCDec->m_param) != ICERR_OK)
499         return ICERR_ERROR;
500 
501     if(pSCDec->WMISCP.cfColorFormat == YUV_422 && oO >= O_RCW)
502         pParam->oOrientation = oO = O_NONE; // Can not rotate 422 in compressed domain!
503 
504     pSCDec->cmbWidth = (pSCDec->WMII.cWidth + pSCDec->m_param.cExtraPixelsLeft + pSCDec->m_param.cExtraPixelsRight + 15) / 16;
505     pSCDec->cmbHeight = (pSCDec->WMII.cHeight + pSCDec->m_param.cExtraPixelsTop + pSCDec->m_param.cExtraPixelsBottom + 15) / 16;
506     pSCDec->m_param.cNumChannels = pSCDec->WMISCP.cChannel;
507     pSCDec->m_Dparam = &aDecoderParam;
508     pSCDec->m_Dparam->bSkipFlexbits = (pSCDec->WMISCP.sbSubband == SB_NO_FLEXBITS);
509     pSCDec->m_param.bTranscode = TRUE;
510 
511     pParam->bIgnoreOverlap = isTileExtraction(pSCDec, pParam);
512 
513     cUnit = (pSCDec->m_param.cfColorFormat == YUV_420 ? 384 : (pSCDec->m_param.cfColorFormat == YUV_422 ? 512 : 256 * pSCDec->m_param.cNumChannels));
514     if(cUnit > 256 * MAX_CHANNELS)
515         return ICERR_ERROR;
516     pSCDec->p1MBbuffer[0] = pMBBuf = (PixelI *)malloc(cUnit * sizeof(PixelI));
517     if(pMBBuf == NULL)
518         return ICERR_ERROR;
519     pSCDec->p1MBbuffer[1] = pSCDec->p1MBbuffer[0] + 256;
520     for(i = 2; i < pSCDec->m_param.cNumChannels; i ++)
521         pSCDec->p1MBbuffer[i] = pSCDec->p1MBbuffer[i - 1] + (pSCDec->m_param.cfColorFormat == YUV_420 ? 64 : (pSCDec->m_param.cfColorFormat == YUV_422 ? 128 : 256));
522 
523     if(pSCDec->m_param.bAlphaChannel){ // alpha channel
524         SimpleBitIO SB = {0};
525 
526         iAlphaPos = pSCDec->m_param.cNumChannels;
527         if((pSCDec->m_pNextSC = (CWMImageStrCodec *)malloc(sizeof(CWMImageStrCodec))) == NULL)
528             return ICERR_ERROR;
529         *pSCDec->m_pNextSC = *pSCDec;
530         pSCDec->m_pNextSC->p1MBbuffer[0] = MBBufAlpha;
531         pSCDec->m_pNextSC->WMISCP.cfColorFormat = pSCDec->m_pNextSC->WMII.cfColorFormat = pSCDec->m_pNextSC->m_param.cfColorFormat = Y_ONLY;
532         pSCDec->m_pNextSC->WMISCP.cChannel  = pSCDec->m_pNextSC->m_param.cNumChannels = 1;
533         pSCDec->m_pNextSC->m_bSecondary = TRUE;
534         pSCDec->m_pNextSC->m_pNextSC = pSCDec;
535 
536         // read plane header of second image plane
537         if(attach_SB(&SB, pSCDec->WMISCP.pWStream) != ICERR_OK)
538             return ICERR_ERROR;
539         ReadImagePlaneHeader(&pSCDec->m_pNextSC->WMII, &pSCDec->m_pNextSC->WMISCP, &pSCDec->m_pNextSC->m_param, &SB);
540         detach_SB(&SB);
541 
542         if(StrDecInit(pSCDec->m_pNextSC) != ICERR_OK)
543             return ICERR_ERROR;
544     }
545     else
546         pParam->uAlphaMode = 0;
547 
548     pIOHeaderDec = (U8 *)malloc((PACKETLENGTH * 4 - 1) + PACKETLENGTH * 4 + sizeof(BitIOInfo));
549     if(pIOHeaderDec == NULL)
550         return ICERR_ERROR;
551     memset(pIOHeaderDec, 0, (PACKETLENGTH * 4 - 1) + PACKETLENGTH * 4 + sizeof(BitIOInfo));
552     pSCDec->pIOHeader = (BitIOInfo *)((U8 *)ALIGNUP(pIOHeaderDec, PACKETLENGTH * 4) + PACKETLENGTH * 2);
553 
554     if(StrIODecInit(pSCDec) != ICERR_OK)
555         return ICERR_ERROR;
556 
557     if(StrDecInit(pSCDec) != ICERR_OK)
558         return ICERR_ERROR;
559 
560     if(pSCDec->m_param.bAlphaChannel){ // alpha channel
561         if(StrDecInit(pSCDec->m_pNextSC) != ICERR_OK)
562             return ICERR_ERROR;
563     }
564 
565     // initialize encoder
566     if((pSCEnc = (CWMImageStrCodec *)malloc(sizeof(CWMImageStrCodec))) == NULL)
567         return ICERR_ERROR;
568     memset(pSCEnc, 0, sizeof(CWMImageStrCodec));
569 
570     pSCEnc->WMII = pSCDec->WMII;
571     pSCEnc->WMISCP = pSCDec->WMISCP;
572     pSCEnc->m_param = pSCDec->m_param;
573     pSCEnc->WMISCP.pWStream = pStreamOut;
574     pSCEnc->WMISCP.bfBitstreamFormat = pParam->bfBitstreamFormat;
575 //    pSCEnc->m_param.cfColorFormat = pSCEnc->WMISCP.cfColorFormat = pParam->cfColorFormat;
576     pSCEnc->m_param.cfColorFormat = pSCEnc->WMISCP.cfColorFormat;
577     pSCEnc->m_param.cNumChannels = (pSCEnc->WMISCP.cfColorFormat == Y_ONLY ? 1 : (pSCEnc->WMISCP.cfColorFormat == YUV_444 ? 3 : pSCEnc->WMISCP.cChannel));
578     pSCEnc->m_param.bAlphaChannel = (pParam->uAlphaMode > 0);
579     pSCEnc->m_param.bTranscode = TRUE;
580     if(pParam->sbSubband >= SB_MAX)
581         pParam->sbSubband = SB_ALL;
582     if(pParam->sbSubband > pSCEnc->WMISCP.sbSubband)
583         pSCEnc->WMISCP.sbSubband = pParam->sbSubband;
584     pSCEnc->m_bSecondary = FALSE;
585 
586     pIOHeaderEnc = (U8 *)malloc((PACKETLENGTH * 4 - 1) + PACKETLENGTH * 4 + sizeof(BitIOInfo));
587     if(pIOHeaderEnc == NULL)
588         return ICERR_ERROR;
589     memset(pIOHeaderEnc, 0, (PACKETLENGTH * 4 - 1) + PACKETLENGTH * 4 + sizeof(BitIOInfo));
590     pSCEnc->pIOHeader = (BitIOInfo *)((U8 *)ALIGNUP(pIOHeaderEnc, PACKETLENGTH * 4) + PACKETLENGTH * 2);
591 
592     for(i = 0; i < pSCEnc->m_param.cNumChannels; i ++)
593         pSCEnc->pPlane[i] = pSCDec->p1MBbuffer[i];
594 
595     for(i = 1; i < pSCDec->cNumBitIO * (pSCDec->WMISCP.cNumOfSliceMinus1H + 1); i ++){
596         if(pSCDec->pIndexTable[i] == 0 && i + 1 != pSCDec->cNumBitIO * (pSCDec->WMISCP.cNumOfSliceMinus1H + 1)) // empty packet
597             pSCDec->pIndexTable[i] = pSCDec->pIndexTable[i + 1];
598         if(pSCDec->pIndexTable[i] != 0 && pSCDec->pIndexTable[i] < pSCDec->pIndexTable[i - 1]) // out of order bitstream, can not do fast tile extraction!
599             pParam->bIgnoreOverlap = FALSE;
600     }
601 
602     if(getROI(&pSCEnc->WMII, &pSCEnc->m_param, &pSCEnc->WMISCP, pParam) != ICERR_OK)
603         return ICERR_ERROR;
604 
605     mbLeft = (pParam->cLeftX >> 4);
606     mbRight = ((pParam->cLeftX + pParam->cWidth + 15) >> 4);
607     mbTop = (pParam->cTopY >> 4);
608     mbBottom = ((pParam->cTopY + pParam->cHeight + 15) >> 4);
609 
610     if(pSCDec->WMISCP.uiTileX[pSCDec->WMISCP.cNumOfSliceMinus1V] >= mbLeft && pSCDec->WMISCP.uiTileX[pSCDec->WMISCP.cNumOfSliceMinus1V] <= mbRight &&
611         pSCDec->WMISCP.uiTileY[pSCDec->WMISCP.cNumOfSliceMinus1H] >= mbTop && pSCDec->WMISCP.uiTileY[pSCDec->WMISCP.cNumOfSliceMinus1H] <= mbBottom)
612         pParam->bIgnoreOverlap = FALSE;
613 
614     pSCEnc->bTileExtraction = pParam->bIgnoreOverlap;
615 
616     mbWidth = pSCEnc->cmbWidth = mbRight - mbLeft;
617     mbHeight = pSCEnc->cmbHeight = mbBottom - mbTop;
618     if(oO >= O_RCW){
619         SWAP(pSCEnc->WMII.cWidth, pSCEnc->WMII.cHeight);
620         SWAP(pSCEnc->cmbWidth, pSCEnc->cmbHeight);
621     }
622 
623     if(oO != O_NONE){
624         pFrameBuf = (PixelI *)malloc(pSCEnc->cmbWidth * pSCEnc->cmbHeight * cUnit * sizeof(PixelI));
625         if(pFrameBuf == NULL || (pSCEnc->cmbWidth * pSCEnc->cmbHeight * cUnit * sizeof(PixelI) < pSCEnc->cmbWidth * pSCEnc->cmbHeight * cUnit))
626             return ICERR_ERROR;
627         pMBInfo = (CWMIMBInfo *)malloc(pSCEnc->cmbWidth * pSCEnc->cmbHeight * sizeof(CWMIMBInfo));
628         if(pMBInfo == NULL || (pSCEnc->cmbWidth * pSCEnc->cmbHeight * sizeof(CWMIMBInfo) < pSCEnc->cmbWidth * pSCEnc->cmbHeight))
629             return ICERR_ERROR;
630         if(pParam->uAlphaMode > 0){ // alpha channel
631             pFrameBufAlpha = (PixelI *)malloc(pSCEnc->cmbWidth * pSCEnc->cmbHeight * 256 * sizeof(PixelI));
632             if(pFrameBufAlpha == NULL || (pSCEnc->cmbWidth * pSCEnc->cmbHeight * 256 * sizeof(PixelI) < pSCEnc->cmbWidth * pSCEnc->cmbHeight * 256))
633                 return ICERR_ERROR;
634             pMBInfoAlpha = (CWMIMBInfo *)malloc(pSCEnc->cmbWidth * pSCEnc->cmbHeight * sizeof(CWMIMBInfo));
635             if(pMBInfoAlpha == NULL || (pSCEnc->cmbWidth * pSCEnc->cmbHeight * sizeof(CWMIMBInfo) < pSCEnc->cmbWidth * pSCEnc->cmbHeight))
636                 return ICERR_ERROR;
637         }
638     }
639 
640     if(oO < O_RCW && pSCEnc->WMII.oOrientation < O_RCW)
641         pSCEnc->WMII.oOrientation ^= oO;
642     else if(oO >= O_RCW && pSCEnc->WMII.oOrientation >= O_RCW){
643         pSCEnc->WMII.oOrientation ^= oO;
644         pSCEnc->WMII.oOrientation = (pSCEnc->WMII.oOrientation & 1) * 2 + (pSCEnc->WMII.oOrientation >> 1);
645     }
646     else if(oO >= O_RCW && pSCEnc->WMII.oOrientation < O_RCW)
647         pSCEnc->WMII.oOrientation = oO ^ ((pSCEnc->WMII.oOrientation & 1) * 2 + (pSCEnc->WMII.oOrientation >> 1));
648     else
649         pSCEnc->WMII.oOrientation ^= ((oO & 1) * 2 + (oO >> 1));
650 
651 //    pSCEnc->WMISCP.nExpBias += 128;
652 
653     if(pParam->bIgnoreOverlap == TRUE){
654         attachISWrite(pSCEnc->pIOHeader, pSCEnc->WMISCP.pWStream);
655         pSCEnc->pTile = pSCDec->pTile;
656         if(pSCEnc->WMISCP.cNumOfSliceMinus1H + pSCEnc->WMISCP.cNumOfSliceMinus1V == 0 && pSCEnc->WMISCP.bfBitstreamFormat == SPATIAL)
657             pSCEnc->m_param.bIndexTable = FALSE;
658         WriteWMIHeader(pSCEnc);
659     }
660     else{
661         pTileQPInfo = (CTileQPInfo *)malloc((oO == O_NONE ? 1 : (pSCEnc->WMISCP.cNumOfSliceMinus1H + 1) * (pSCEnc->WMISCP.cNumOfSliceMinus1V + 1)) * sizeof( CTileQPInfo));
662         if(pTileQPInfo == NULL || ((oO == O_NONE ? 1 : (pSCEnc->WMISCP.cNumOfSliceMinus1H + 1) * (pSCEnc->WMISCP.cNumOfSliceMinus1V + 1)) * sizeof( CTileQPInfo) < (oO == O_NONE ? 1 : (pSCEnc->WMISCP.cNumOfSliceMinus1H + 1) * (pSCEnc->WMISCP.cNumOfSliceMinus1V + 1))))
663             return ICERR_ERROR;
664 
665         if(StrEncInit(pSCEnc) != ICERR_OK)
666             return ICERR_ERROR;
667     }
668 
669     if(pParam->uAlphaMode > 0){ // alpha channel
670 //        pSCEnc->WMISCP.nExpBias -= 128;
671         if((pSCEnc->m_pNextSC = (CWMImageStrCodec *)malloc(sizeof(CWMImageStrCodec))) == NULL)
672             return ICERR_ERROR;
673         *pSCEnc->m_pNextSC = *pSCEnc;
674         pSCEnc->m_pNextSC->pPlane[0] = pSCDec->m_pNextSC->p1MBbuffer[0];
675         pSCEnc->m_pNextSC->WMISCP.cfColorFormat = pSCEnc->m_pNextSC->WMII.cfColorFormat = pSCEnc->m_pNextSC->m_param.cfColorFormat = Y_ONLY;
676         pSCEnc->m_pNextSC->WMISCP.cChannel  = pSCEnc->m_pNextSC->m_param.cNumChannels = 1;
677         pSCEnc->m_pNextSC->m_bSecondary = TRUE;
678         pSCEnc->m_pNextSC->m_pNextSC = pSCEnc;
679         pSCEnc->m_pNextSC->m_param = pSCDec->m_pNextSC->m_param;
680         pSCEnc->m_param.bAlphaChannel = TRUE;
681 
682         if(pParam->bIgnoreOverlap == TRUE)
683             pSCEnc->m_pNextSC->pTile = pSCDec->m_pNextSC->pTile;
684         else if(StrEncInit(pSCEnc->m_pNextSC) != ICERR_OK)
685                 return ICERR_ERROR;
686 
687         WriteImagePlaneHeader(pSCEnc->m_pNextSC);
688     }
689 
690     if(pParam->bIgnoreOverlap == TRUE){
691         SUBBAND sbEnc = pSCEnc->WMISCP.sbSubband, sbDec = pSCDec->WMISCP.sbSubband;
692         size_t cfEnc = ((pSCEnc->WMISCP.bfBitstreamFormat == SPATIAL || sbEnc == SB_DC_ONLY) ? 1 : (sbEnc == SB_NO_HIGHPASS ? 2 : (sbEnc == SB_NO_FLEXBITS ? 3 : 4)));
693         size_t cfDec = ((pSCDec->WMISCP.bfBitstreamFormat == SPATIAL || sbDec == SB_DC_ONLY) ? 1 : (sbDec == SB_NO_HIGHPASS ? 2 : (sbDec == SB_NO_FLEXBITS ? 3 : 4)));
694         size_t k, l = 0;
695 
696         pSCEnc->pIndexTable = (size_t *)malloc(sizeof(size_t) * (pSCEnc->WMISCP.cNumOfSliceMinus1H + 1) * (pSCEnc->WMISCP.cNumOfSliceMinus1V + 1) * cfEnc);
697 
698         if(pSCEnc->pIndexTable == NULL || cfEnc > cfDec)
699             return ICERR_ERROR;
700 
701         pSCEnc->cNumBitIO = cfEnc * (pSCEnc->WMISCP.cNumOfSliceMinus1V + 1);
702 
703         for(j = 0; j <= pSCDec->WMISCP.cNumOfSliceMinus1H; j ++){
704             for(i = 0; i <= pSCDec->WMISCP.cNumOfSliceMinus1V; i ++)
705                 if(pSCDec->WMISCP.uiTileX[i] >= mbLeft && pSCDec->WMISCP.uiTileX[i] < mbRight &&
706                     pSCDec->WMISCP.uiTileY[j] >= mbTop && pSCDec->WMISCP.uiTileY[j] < mbBottom){
707                         for(k = 0; k < cfEnc; k ++, l ++)
708                             pSCEnc->pIndexTable[l] = pSCDec->pIndexTable[(j * (pSCDec->WMISCP.cNumOfSliceMinus1V + 1) + i) * cfDec + k + 1] - pSCDec->pIndexTable[(j * (pSCDec->WMISCP.cNumOfSliceMinus1V + 1) + i) * cfDec + k];
709                 }
710         }
711 
712         if(pSCEnc->WMISCP.cNumOfSliceMinus1H + pSCEnc->WMISCP.cNumOfSliceMinus1V == 0 && pSCEnc->WMISCP.bfBitstreamFormat == SPATIAL){
713             pSCEnc->m_param.bIndexTable = FALSE;
714             pSCEnc->cNumBitIO = 0;
715             writeIndexTableNull(pSCEnc);
716         }
717         else
718             writeIndexTable(pSCEnc);
719 
720         detachISWrite(pSCEnc, pSCEnc->pIOHeader);
721 
722         for(j = l = 0; j <= pSCDec->WMISCP.cNumOfSliceMinus1H; j ++){
723             for(i = 0; i <= pSCDec->WMISCP.cNumOfSliceMinus1V; i ++)
724                 if(pSCDec->WMISCP.uiTileX[i] >= mbLeft && pSCDec->WMISCP.uiTileX[i] < mbRight &&
725                     pSCDec->WMISCP.uiTileY[j] >= mbTop && pSCDec->WMISCP.uiTileY[j] < mbBottom){
726                         for(k = 0; k < cfEnc; k ++){
727                             pSCDec->WMISCP.pWStream->SetPos(pSCDec->WMISCP.pWStream, pSCDec->pIndexTable[(j * (pSCDec->WMISCP.cNumOfSliceMinus1V + 1) + i) * cfDec + k] + pSCDec->cHeaderSize);
728                             copyTo(pSCDec->WMISCP.pWStream, pSCEnc->WMISCP.pWStream, pSCEnc->pIndexTable[l++]);
729                         }
730                 }
731         }
732 
733         free(pSCEnc->pIndexTable);
734     }
735     else
736         writeIndexTableNull(pSCEnc);
737 
738     for(pSCDec->cRow = 0; pSCDec->cRow < mbBottom && pParam->bIgnoreOverlap == FALSE; pSCDec->cRow ++){
739         for(pSCDec->cColumn = 0; pSCDec->cColumn < pSCDec->cmbWidth; pSCDec->cColumn ++){
740             Int cRow = (Int)pSCDec->cRow, cColumn = (Int)pSCDec->cColumn;
741             CWMITile * pTile;
742 
743             memset(pMBBuf, 0, sizeof(PixelI) * cUnit);
744             if(pSCDec->m_param.bAlphaChannel){ // alpha channel
745                 memset(pSCDec->m_pNextSC->p1MBbuffer[0], 0, sizeof(PixelI) * 256);
746                 pSCDec->m_pNextSC->cRow = pSCDec->cRow;
747                 pSCDec->m_pNextSC->cColumn = pSCDec->cColumn;
748             }
749 
750             // decode
751             pSC = pSCDec;
752             for(i = (pSCDec->m_param.bAlphaChannel ? 2 : 1); i > 0; i --){
753                 getTilePos(pSCDec, cColumn, cRow);
754                 if(i == 2){
755                     pSCDec->m_pNextSC->cTileColumn = pSCDec->cTileColumn;
756                     pSCDec->m_pNextSC->cTileRow = pSCDec->cTileRow;
757                 }
758 
759                 if(readPackets(pSCDec) != ICERR_OK)
760                     return ICERR_ERROR;
761 
762                 pContext = &pSCDec->m_pCodingContext[pSCDec->cTileColumn];
763 
764                 if(DecodeMacroblockDC(pSCDec, pContext, cColumn, cRow) != ICERR_OK)
765                     return ICERR_ERROR;
766 
767                 if(pSCDec->cSB > 1)
768                     if(DecodeMacroblockLowpass(pSCDec, pContext, cColumn, cRow) != ICERR_OK)
769                         return ICERR_ERROR;
770 
771                 predDCACDec(pSCDec);
772 
773                 if(pSCDec->cSB > 2)
774                     if(DecodeMacroblockHighpass(pSCDec, pContext, cColumn, cRow) != ICERR_OK)
775                         return ICERR_ERROR;
776 
777                 predACDec(pSCDec);
778 
779                 updatePredInfo(pSCDec, &pSCDec->MBInfo, cColumn, pSCDec->WMISCP.cfColorFormat);
780 
781                 pSCDec = pSCDec->m_pNextSC;
782             }
783             pSCDec = pSC;
784 
785             if(pSCDec->cRow >= mbTop && pSCDec->cColumn >= mbLeft && pSCDec->cColumn < mbRight){
786                 cRow = (Int)(pSCDec->cRow - mbTop);
787                 if(bFlipV[oO])
788                     cRow = (Int)mbHeight - cRow - 1;
789                 cColumn = (Int)(pSCDec->cColumn - mbLeft);
790                 if(bFlipH[oO])
791                     cColumn = (Int)mbWidth - cColumn - 1;
792 
793                 pSCEnc->m_bCtxLeft = pSCEnc->m_bCtxTop = FALSE;
794                 for(i = 0; i <= pSCEnc->WMISCP.cNumOfSliceMinus1H; i ++)
795                     if(pSCEnc->WMISCP.uiTileY[i] == (U32)(oO < O_RCW ? cRow : cColumn)){
796                         pSCEnc->cTileRow = i;
797                         pSCEnc->m_bCtxTop = TRUE;
798                         break;
799                     }
800                 for(i = 0; i <= pSCEnc->WMISCP.cNumOfSliceMinus1V; i ++)
801                     if(pSCEnc->WMISCP.uiTileX[i] == (U32)(oO < O_RCW ? cColumn : cRow)){
802                         pSCEnc->cTileColumn = i;
803                         pSCEnc->m_bCtxLeft = TRUE;
804                         break;
805                     }
806 
807                 if(pSCEnc->m_bCtxLeft && pSCEnc->m_bCtxTop){ // a new tile, buffer tile DQuant info
808                     CTileQPInfo * pTmp = pTileQPInfo;
809 
810                     pTile = pSCDec->pTile + pSCDec->cTileColumn;
811 
812                     if(oO != O_NONE)
813                         pTmp += pSCEnc->cTileRow * (pSCEnc->WMISCP.cNumOfSliceMinus1V + 1) + pSCEnc->cTileColumn;
814 
815                     pTmp->dcMode = pTile->cChModeDC;
816                     for(i = 0; i < pSCEnc->WMISCP.cChannel; i ++)
817                         pTmp->dcIndex[i] = pTile->pQuantizerDC[i][0].iIndex;
818 
819                     if(pSCEnc->WMISCP.sbSubband != SB_DC_ONLY){
820                         pTmp->bUseDC = pTile->bUseDC;
821                         pTmp->lpNum = pTile->cNumQPLP;
822                         if(pTmp->bUseDC == FALSE)
823                             for(j = 0; j < pTmp->lpNum; j ++){
824                                 pTmp->lpMode[j] = pTile->cChModeLP[j];
825                                 for(i = 0; i < pSCEnc->WMISCP.cChannel; i ++)
826                                     pTmp->lpIndex[j][i] = pTile->pQuantizerLP[i][j].iIndex;
827                             }
828 
829                             if(pSCEnc->WMISCP.sbSubband != SB_NO_HIGHPASS){
830                                 pTmp->bUseLP = pTile->bUseLP;
831                                 pTmp->hpNum = pTile->cNumQPHP;
832                                 if(pTmp->bUseLP == FALSE)
833                                     for(j = 0; j < pTmp->hpNum; j ++){
834                                         pTmp->hpMode[j] = pTile->cChModeHP[j];
835                                         for(i = 0; i < pSCEnc->WMISCP.cChannel; i ++)
836                                             pTmp->hpIndex[j][i] = pTile->pQuantizerHP[i][j].iIndex;
837                                     }
838                             }
839                     }
840 
841                     if(pParam->uAlphaMode > 0){
842                         pTile = pSCDec->m_pNextSC->pTile + pSCDec->cTileColumn;
843 
844                         pTmp->dcIndex[iAlphaPos] = pTile->pQuantizerDC[0][0].iIndex;
845 
846                         if(pSCEnc->WMISCP.sbSubband != SB_DC_ONLY){
847                             pTmp->bUseDCAlpha = pTile->bUseDC;
848                             pTmp->lpNumAlpha = pTile->cNumQPLP;
849                             if(pTmp->bUseDCAlpha == FALSE)
850                                 for(j = 0; j < pTmp->lpNumAlpha; j ++)
851                                     pTmp->lpIndex[j][iAlphaPos] = pTile->pQuantizerLP[0][j].iIndex;
852                             if(pSCEnc->WMISCP.sbSubband != SB_NO_HIGHPASS){
853                                 pTmp->bUseLPAlpha = pTile->bUseLP;
854                                 pTmp->hpNumAlpha = pTile->cNumQPHP;
855                                 if(pTmp->bUseLPAlpha == FALSE)
856                                     for(j = 0; j < pTmp->hpNumAlpha; j ++)
857                                         pTmp->hpIndex[j][iAlphaPos] = pTile->pQuantizerHP[0][j].iIndex;
858                             }
859                         }
860                     }
861                 }
862 
863                 if(oO == O_NONE){
864                     // encode
865                     pSCEnc->cColumn = pSCDec->cColumn - mbLeft + 1;
866                     pSCEnc->cRow = pSCDec->cRow + 1 - mbTop;
867                     pSCEnc->MBInfo = pSCDec->MBInfo;
868 
869                     getTilePos(pSCEnc, cColumn, cRow);
870 
871                     if(pSCEnc->m_bCtxLeft && pSCEnc->m_bCtxTop)
872                         transcodeTileHeader(pSCEnc, pTileQPInfo);
873 
874                     encodeMB(pSCEnc, cColumn, cRow);
875                     if(pParam->uAlphaMode > 0){
876                         pSCEnc->m_pNextSC->cColumn = pSCDec->cColumn - mbLeft + 1;
877                         pSCEnc->m_pNextSC->cRow = pSCDec->cRow + 1 - mbTop;
878                         getTilePos(pSCEnc->m_pNextSC, cColumn, cRow);
879                         pSCEnc->m_pNextSC->MBInfo = pSCDec->m_pNextSC->MBInfo;
880                         encodeMB(pSCEnc->m_pNextSC, cColumn, cRow);
881                     }
882                 }
883                 else{
884                     size_t cOff = (oO < O_RCW ? (size_t)cRow * mbWidth + (size_t)cColumn : (size_t)cRow + mbHeight * (size_t)cColumn);
885 
886                     pMBInfo[cOff] = pSCDec->MBInfo;
887 
888                     memcpy(&pFrameBuf[cOff * cUnit], pMBBuf, cUnit * sizeof(PixelI));
889 
890                     if(pParam->uAlphaMode > 0){
891                         pMBInfoAlpha[cOff] = pSCDec->m_pNextSC->MBInfo;
892 
893                         memcpy(&pFrameBufAlpha[cOff * 256], MBBufAlpha, 256 * sizeof(PixelI));
894                     }
895                 }
896             }
897         }
898 
899         advanceOneMBRow(pSCDec);
900 
901         if(oO == O_NONE)
902             advanceOneMBRow(pSCEnc);
903     }
904 
905     if(oO != O_NONE){
906         for(pSCEnc->cRow = 1; pSCEnc->cRow <= pSCEnc->cmbHeight; pSCEnc->cRow ++){
907             for(pSCEnc->cColumn = 1; pSCEnc->cColumn <= pSCEnc->cmbWidth; pSCEnc->cColumn ++){
908                 Int cRow, cColumn;
909                 size_t cOff = (pSCEnc->cRow - 1) * pSCEnc->cmbWidth + pSCEnc->cColumn - 1;
910 
911                 for(i = 0; i < ((pSCEnc->m_param.cfColorFormat == YUV_420 || pSCEnc->m_param.cfColorFormat == YUV_422) ? 1 : pSCEnc->m_param.cNumChannels); i ++){
912                     transformDCBlock(pMBInfo[cOff].iBlockDC[i], pSCEnc->MBInfo.iBlockDC[i], oO);
913                     transformACBlocks(pFrameBuf + cOff * cUnit + i * 256, pMBBuf + 256 * i, oO);
914                 }
915                 if(pSCEnc->WMISCP.cfColorFormat == YUV_420)
916                     for(i = 0; i < 2; i ++){
917                         transformDCBlock420(pMBInfo[cOff].iBlockDC[i + 1], pSCEnc->MBInfo.iBlockDC[i + 1], oO);
918                         transformACBlocks420(pFrameBuf + cOff * cUnit + 256 + i * 64, pMBBuf + 256 + i * 64, oO);
919                     }
920                 else if(pSCEnc->WMISCP.cfColorFormat == YUV_422)
921                     for(i = 0; i < 2; i ++){
922                         transformDCBlock422(pMBInfo[cOff].iBlockDC[i + 1], pSCEnc->MBInfo.iBlockDC[i + 1], oO);
923                         transformACBlocks422(pFrameBuf + cOff * cUnit + 256 + i * 128, pMBBuf + 256 + i * 128, oO);
924                     }
925 
926                     pSCEnc->MBInfo.iQIndexLP = pMBInfo[cOff].iQIndexLP;
927                     pSCEnc->MBInfo.iQIndexHP = pMBInfo[cOff].iQIndexHP;
928 
929                 cRow = (Int)pSCEnc->cRow - 1;
930                 cColumn = (Int)pSCEnc->cColumn - 1;
931                 getTilePos(pSCEnc, cColumn, cRow);
932 
933                 if(pSCEnc->m_bCtxLeft && pSCEnc->m_bCtxTop)
934                     transcodeTileHeader(pSCEnc, pTileQPInfo + pSCEnc->cTileRow * (pSCEnc->WMISCP.cNumOfSliceMinus1V + 1) + pSCEnc->cTileColumn);
935                 encodeMB(pSCEnc, cColumn, cRow);
936 
937                 if(pParam->uAlphaMode > 0){
938                     pSCEnc->m_pNextSC->cColumn = pSCEnc->cColumn;
939                     pSCEnc->m_pNextSC->cRow = pSCEnc->cRow;
940                     getTilePos(pSCEnc->m_pNextSC, cColumn, cRow);
941                     pSCEnc->m_pNextSC->MBInfo = pSCDec->m_pNextSC->MBInfo;
942 
943                     transformDCBlock(pMBInfoAlpha[cOff].iBlockDC[0], pSCEnc->m_pNextSC->MBInfo.iBlockDC[0], oO);
944                     transformACBlocks(pFrameBufAlpha + cOff * 256, MBBufAlpha, oO);
945 
946                     pSCEnc->m_pNextSC->MBInfo.iQIndexLP = pMBInfoAlpha[cOff].iQIndexLP;
947                     pSCEnc->m_pNextSC->MBInfo.iQIndexHP = pMBInfoAlpha[cOff].iQIndexHP;
948 
949                     encodeMB(pSCEnc->m_pNextSC, cColumn, cRow);
950                 }
951             }
952 
953             advanceOneMBRow(pSCEnc);
954         }
955     }
956 
957     free(pMBBuf);
958     if(oO != O_NONE){
959         free(pFrameBuf);
960         free(pMBInfo);
961         if(pParam->uAlphaMode > 0){ // alpha channel
962             free(pFrameBufAlpha);
963             free(pMBInfoAlpha);
964         }
965     }
966 
967     freePredInfo(pSCDec);
968     freeTileInfo(pSCDec);
969     StrIODecTerm(pSCDec);
970     FreeCodingContextDec(pSCDec);
971     if(pSCDec->m_param.bAlphaChannel)
972         free(pSCDec->m_pNextSC);
973     free(pSCDec);
974     free(pIOHeaderDec);
975 
976     if(pParam->bIgnoreOverlap == FALSE){
977         freePredInfo(pSCEnc);
978         freeTileInfo(pSCEnc);
979         StrIOEncTerm(pSCEnc);
980         free(pTileQPInfo);
981         FreeCodingContextEnc(pSCEnc);
982     }
983     free(pSCEnc);
984     free(pIOHeaderEnc);
985 
986     return ICERR_OK;
987 }
988