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