12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112 |
- //*@@@+++@@@@******************************************************************
- //
- // Copyright © Microsoft Corp.
- // All rights reserved.
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are met:
- //
- // • Redistributions of source code must retain the above copyright notice,
- // this list of conditions and the following disclaimer.
- // • Redistributions in binary form must reproduce the above copyright notice,
- // this list of conditions and the following disclaimer in the documentation
- // and/or other materials provided with the distribution.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- // POSSIBILITY OF SUCH DAMAGE.
- //
- //*@@@---@@@@******************************************************************
- #include "strTransform.h"
- #include "encode.h"
- /** rotation by pi/8 **/
- #define ROTATE1(a, b) (b) -= (((a) + 1) >> 1), (a) += (((b) + 1) >> 1) // this works well too
- #define ROTATE2(a, b) (b) -= (((a)*3 + 4) >> 3), (a) += (((b)*3 + 4) >> 3) // this works well too
- /** local functions **/
- static Void fwdOddOdd(PixelI *, PixelI *, PixelI *, PixelI *);
- static Void fwdOddOddPre(PixelI *, PixelI *, PixelI *, PixelI *);
- static Void fwdOdd(PixelI *, PixelI *, PixelI *, PixelI *);
- static Void strDCT2x2alt(PixelI * a, PixelI * b, PixelI * c, PixelI * d);
- static Void strHSTenc1(PixelI *, PixelI *);
- static Void strHSTenc(PixelI *, PixelI *, PixelI *, PixelI *);
- static Void strHSTenc1_edge (PixelI *pa, PixelI *pd);
- //static Void scaleDownUp0(PixelI *, PixelI *);
- //static Void scaleDownUp1(PixelI *, PixelI *);
- //static Void scaleDownUp2(PixelI *, PixelI *);
- //#define FOURBUTTERFLY_ENC_ALT(p, i00, i01, i02, i03, i10, i11, i12, i13, \
- // i20, i21, i22, i23, i30, i31, i32, i33) \
- // strHSTenc(&p[i00], &p[i01], &p[i02], &p[i03]); \
- // strHSTenc(&p[i10], &p[i11], &p[i12], &p[i13]); \
- // strHSTenc(&p[i20], &p[i21], &p[i22], &p[i23]); \
- // strHSTenc(&p[i30], &p[i31], &p[i32], &p[i33]); \
- // strHSTenc1(&p[i00], &p[i03]); \
- // strHSTenc1(&p[i10], &p[i13]); \
- // strHSTenc1(&p[i20], &p[i23]); \
- // strHSTenc1(&p[i30], &p[i33])
- /** DCT stuff **/
- /** data order before DCT **/
- /** 0 1 2 3 **/
- /** 4 5 6 7 **/
- /** 8 9 10 11 **/
- /** 12 13 14 15 **/
- /** data order after DCT **/
- /** 0 8 4 6 **/
- /** 2 10 14 12 **/
- /** 1 11 15 13 **/
- /** 9 3 7 5 **/
- /** reordering should be combined with zigzag scan **/
- Void strDCT4x4Stage1(PixelI * p)
- {
- /** butterfly **/
- //FOURBUTTERFLY(p, 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15);
- FOURBUTTERFLY_HARDCODED1(p);
- /** top left corner, butterfly => butterfly **/
- strDCT2x2up(&p[0], &p[1], &p[2], &p[3]);
- /** bottom right corner, pi/8 rotation => pi/8 rotation **/
- fwdOddOdd(&p[15], &p[14], &p[13], &p[12]);
- /** top right corner, butterfly => pi/8 rotation **/
- fwdOdd(&p[5], &p[4], &p[7], &p[6]);
- /** bottom left corner, pi/8 rotation => butterfly **/
- fwdOdd(&p[10], &p[8], &p[11], &p[9]);
- }
- Void strDCT4x4SecondStage(PixelI * p)
- {
- /** butterfly **/
- FOURBUTTERFLY(p, 0, 192, 48, 240, 64, 128, 112, 176,16, 208, 32, 224, 80, 144, 96, 160);
-
- /** top left corner, butterfly => butterfly **/
- strDCT2x2up(&p[0], &p[64], &p[16], &p[80]);
-
- /** bottom right corner, pi/8 rotation => pi/8 rotation **/
- fwdOddOdd(&p[160], &p[224], &p[176], &p[240]);
-
- /** top right corner, butterfly => pi/8 rotation **/
- fwdOdd(&p[128], &p[192], &p[144], &p[208]);
-
- /** bottom left corner, pi/8 rotation => butterfly **/
- fwdOdd(&p[32], &p[48], &p[96], &p[112]);
- }
- Void strNormalizeEnc(PixelI* p, Bool bChroma)
- {
- int i;
- if (!bChroma) {
- //for (i = 0; i < 256; i += 16) {
- // p[i] = (p[i] + 1) >> 2;
- //}
- }
- else {
- for (i = 0; i < 256; i += 16) {
- p[i] >>= 1;
- }
- }
- }
- /** 2x2 DCT with pre-scaling - for use on encoder side **/
- Void strDCT2x2dnEnc(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
- {
- PixelI a, b, c, d, C, t;
- a = (*pa + 0) >> 1;
- b = (*pb + 0) >> 1;
- C = (*pc + 0) >> 1;
- d = (*pd + 0) >> 1;
- //PixelI t1, t2;
-
- a += d;
- b -= C;
- t = ((a - b) >> 1);
- c = t - d;
- d = t - C;
- a -= d;
- b += c;
- *pa = a;
- *pb = b;
- *pc = c;
- *pd = d;
- }
- /** pre filter stuff **/
- /** 2-point pre for boundaries **/
- Void strPre2(PixelI * pa, PixelI * pb)
- {
- PixelI a, b;
- a = *pa;
- b = *pb;
- /** rotate **/
- b -= ((a + 2) >> 2);
- a -= ((b + 1) >> 1);
- a -= (b >> 5);
- a -= (b >> 9);
- a -= (b >> 13);
- b -= ((a + 2) >> 2);
- *pa = a;
- *pb = b;
- }
- Void strPre2x2(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
- {
- PixelI a, b, c, d;
- a = *pa;
- b = *pb;
- c = *pc;
- d = *pd;
- /** butterflies **/
- a += d;
- b += c;
- d -= (a + 1) >> 1;
- c -= (b + 1) >> 1;
- /** rotate **/
- b -= ((a + 2) >> 2);
- a -= ((b + 1) >> 1);
- a -= (b >> 5);
- a -= (b >> 9);
- a -= (b >> 13);
- b -= ((a + 2) >> 2);
- /** butterflies **/
- d += (a + 1) >> 1;
- c += (b + 1) >> 1;
- a -= d;
- b -= c;
- *pa = a;
- *pb = b;
- *pc = c;
- *pd = d;
- }
- /** 4-point pre for boundaries **/
- Void strPre4(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
- {
- PixelI a, b, c, d;
- a = *pa;
- b = *pb;
- c = *pc;
- d = *pd;
- a += d, b += c;
- d -= ((a + 1) >> 1), c -= ((b + 1) >> 1);
-
- ROTATE1(c, d);
-
- strHSTenc1_edge(&a, &d); strHSTenc1_edge(&b, &c);
-
- d += ((a + 1) >> 1), c += ((b + 1) >> 1);
- a -= d, b -= c;
- *pa = a;
- *pb = b;
- *pc = c;
- *pd = d;
- }
- /*****************************************************************************************
- Input data offsets:
- (15)(14)|(10+64)(11+64) p0 (15)(14)|(74)(75)
- (13)(12)|( 8+64)( 9+64) (13)(12)|(72)(73)
- --------+-------------- --------+--------
- ( 5)( 4)|( 0+64) (1+64) p1 ( 5)( 4)|(64)(65)
- ( 7)( 6)|( 2+64) (3+64) ( 7)( 6)|(66)(67)
- *****************************************************************************************/
- Void strPre4x4Stage1Split(PixelI *p0, PixelI *p1, Int iOffset)
- {
- PixelI *p2 = p0 + 72 - iOffset;
- PixelI *p3 = p1 + 64 - iOffset;
- p0 += 12;
- p1 += 4;
- /** butterfly & scaling **/
- strHSTenc(p0 + 0, p2 + 0, p1 + 0, p3 + 0);
- strHSTenc(p0 + 1, p2 + 1, p1 + 1, p3 + 1);
- strHSTenc(p0 + 2, p2 + 2, p1 + 2, p3 + 2);
- strHSTenc(p0 + 3, p2 + 3, p1 + 3, p3 + 3);
- strHSTenc1(p0 + 0, p3 + 0);
- strHSTenc1(p0 + 1, p3 + 1);
- strHSTenc1(p0 + 2, p3 + 2);
- strHSTenc1(p0 + 3, p3 + 3);
- /** anti diagonal corners: rotation by pi/8 **/
- ROTATE1(p1[2], p1[3]);
- ROTATE1(p1[0], p1[1]);
- ROTATE1(p2[1], p2[3]);
- ROTATE1(p2[0], p2[2]);
- /** bottom right corner: pi/8 rotation => pi/8 rotation **/
- fwdOddOddPre(p3 + 0, p3 + 1, p3 + 2, p3 + 3);
- /** butterfly **/
- strDCT2x2dn(p0 + 0, p2 + 0, p1 + 0, p3 + 0);
- strDCT2x2dn(p0 + 1, p2 + 1, p1 + 1, p3 + 1);
- strDCT2x2dn(p0 + 2, p2 + 2, p1 + 2, p3 + 2);
- strDCT2x2dn(p0 + 3, p2 + 3, p1 + 3, p3 + 3);
- }
- Void strPre4x4Stage1(PixelI* p, Int iOffset)
- {
- strPre4x4Stage1Split(p, p + 16, iOffset);
- }
- /*****************************************************************************************
- Input data offsets:
- (15)(14)|(10+32)(11+32) p0 (15)(14)|(42)(43)
- (13)(12)|( 8+32)( 9+32) (13)(12)|(40)(41)
- --------+-------------- --------+--------
- ( 5)( 4)|( 0+32)( 1+32) p1 ( 5)( 4)|(32)(33)
- ( 7)( 6)|( 2+32)( 3+32) ( 7)( 6)|(34)(35)
- *****************************************************************************************/
- Void strPre4x4Stage2Split(PixelI* p0, PixelI* p1)
- {
- /** butterfly **/
- strHSTenc(p0 - 96, p0 + 96, p1 - 112, p1 + 80);
- strHSTenc(p0 - 32, p0 + 32, p1 - 48, p1 + 16);
- strHSTenc(p0 - 80, p0 + 112, p1 - 128, p1 + 64);
- strHSTenc(p0 - 16, p0 + 48, p1 - 64, p1 + 0);
- strHSTenc1(p0 - 96, p1 + 80);
- strHSTenc1(p0 - 32, p1 + 16);
- strHSTenc1(p0 - 80, p1 + 64);
- strHSTenc1(p0 - 16, p1 + 0);
- /** anti diagonal corners: rotation **/
- ROTATE1(p1[-48], p1[-112]);
- ROTATE1(p1[-64], p1[-128]);
- ROTATE1(p0[112], p0[ 96]);
- ROTATE1(p0[ 48], p0[ 32]);
- /** bottom right corner: pi/8 rotation => pi/8 rotation **/
- fwdOddOddPre(p1 + 0, p1 + 64, p1 + 16, p1 + 80);
- /** butterfly **/
- strDCT2x2dn(p0 - 96, p1 - 112, p0 + 96, p1 + 80);
- strDCT2x2dn(p0 - 32, p1 - 48, p0 + 32, p1 + 16);
- strDCT2x2dn(p0 - 80, p1 - 128, p0 + 112, p1 + 64);
- strDCT2x2dn(p0 - 16, p1 - 64, p0 + 48, p1 + 0);
- }
- /**
- Hadamard+Scale transform
- for some strange reason, breaking up the function into two blocks, strHSTenc1 and strHSTenc
- seems to work faster
- **/
- static Void strHSTenc(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
- {
- /** different realization : does rescaling as well! **/
- PixelI a, b, c, d;
- a = *pa;
- b = *pb;
- d = *pc;
- c = *pd;
- a += c;
- b -= d;
- c = ((a - b) >> 1) - c;
- d += (b >> 1);
- b += c;
- a -= (d * 3 + 4) >> 3;
- *pa = a;
- *pb = b;
- *pc = c;
- *pd = d;
- }
- static Void strHSTenc1(PixelI *pa, PixelI *pd)
- {
- /** different realization : does rescaling as well! **/
- PixelI a, d;
- a = *pa;
- d = *pd;
- d -= (a >> 7);
- d += (a >> 10);
- //a -= (d * 3 + 4) >> 3;
- d -= (a * 3 + 0) >> 4;
- a -= (d * 3 + 0) >> 3;
- d = (a >> 1) - d;
- a -= d;
- *pa = a;
- *pd = d;
- }
- static Void strHSTenc1_edge (PixelI *pa, PixelI *pd)
- {
- /** different realizion as compared to scaling operator for 2D case **/
- PixelI a, d;
- a = *pa;
- d = -(*pd); // Negative sign needed here for 1D scaling case to ensure correct scaling.
- a -= d;
- d += (a >> 1);
- a -= (d * 3 + 4) >> 3;
- // End new operations
- //Scaling modification of adding 7/1024 in two steps (without multiplication by 7).
- d -= (a >> 7);
- d += (a >> 10);
- d -= (a * 3 + 0) >> 4;
- a -= (d * 3 + 0) >> 3;
- d = (a >> 1) - d;
- a -= d;
- *pa = a;
- *pd = d;
- }
- /** Kron(Rotate(pi/8), Rotate(pi/8)) **/\
- static Void fwdOddOdd(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
- {
- PixelI a, b, c, d, t1, t2;
- a = *pa;
- b = -*pb;
- c = -*pc;
- d = *pd;
- /** butterflies **/
- d += a;
- c -= b;
- a -= (t1 = d >> 1);
- b += (t2 = c >> 1);
- /** rotate pi/4 **/
- a += (b * 3 + 4) >> 3;
- b -= (a * 3 + 3) >> 2;
- a += (b * 3 + 3) >> 3;
- /** butterflies **/
- b -= t2;
- a += t1;
- c += b;
- d -= a;
- *pa = a;
- *pb = b;
- *pc = c;
- *pd = d;
- }
- /** Kron(Rotate(pi/8), Rotate(pi/8)) **/
- static Void fwdOddOddPre(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
- {
- PixelI a, b, c, d, t1, t2;
- a = *pa;
- b = *pb;
- c = *pc;
- d = *pd;
- /** butterflies **/
- d += a;
- c -= b;
- a -= (t1 = d >> 1);
- b += (t2 = c >> 1);
- /** rotate pi/4 **/
- a += (b * 3 + 4) >> 3;
- b -= (a * 3 + 2) >> 2;
- a += (b * 3 + 6) >> 3;
- /** butterflies **/
- b -= t2;
- a += t1;
- c += b;
- d -= a;
- *pa = a;
- *pb = b;
- *pc = c;
- *pd = d;
- }
- /** Kron(Rotate(pi/8), [1 1; 1 -1]/sqrt(2)) **/
- /** [a b c d] => [D C A B] **/
- Void fwdOdd(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
- {
- PixelI a, b, c, d;
- a = *pa;
- b = *pb;
- c = *pc;
- d = *pd;
- /** butterflies **/
- b -= c;
- a += d;
- c += (b + 1) >> 1;
- d = ((a + 1) >> 1) - d;
- /** rotate pi/8 **/
- ROTATE2(a, b);
- ROTATE2(c, d);
- /** butterflies **/
- d += (b) >> 1;
- c -= (a + 1) >> 1;
- b -= d;
- a += c;
- *pa = a;
- *pb = b;
- *pc = c;
- *pd = d;
- }
- /*************************************************************************
- Top-level function to tranform possible part of a macroblock
- *************************************************************************/
- Void transformMacroblock(CWMImageStrCodec * pSC)
- {
- OVERLAP olOverlap = pSC->WMISCP.olOverlap;
- COLORFORMAT cfColorFormat = pSC->m_param.cfColorFormat;
- Bool left = (pSC->cColumn == 0), right = (pSC->cColumn == pSC->cmbWidth);
- Bool top = (pSC->cRow == 0), bottom = (pSC->cRow == pSC->cmbHeight);
- Bool leftORright = (left || right), topORbottom = (top || bottom);
- Bool topORleft = (left || top);// rightORbottom = (right || bottom);
- Bool leftAdjacentColumn = (pSC->cColumn == 1), rightAdjacentColumn = (pSC->cColumn == pSC->cmbWidth - 1);
- // Bool topAdjacentRow = (pSC->cRow == 1), bottomAdjacentRow = (pSC->cRow == pSC->cmbHeight - 1);
- PixelI * p = NULL;// * pt = NULL;
- Int i, j;
- Int iNumChromaFullPlanes = (Int)((YUV_420 == cfColorFormat || YUV_422 == cfColorFormat) ?
- 1 : pSC->m_param.cNumChannels);
- #define mbX pSC->mbX
- #define mbY pSC->mbY
- #define tileX pSC->tileX
- #define tileY pSC->tileY
- #define bVertTileBoundary pSC->bVertTileBoundary
- #define bHoriTileBoundary pSC->bHoriTileBoundary
- #define bOneMBLeftVertTB pSC->bOneMBLeftVertTB
- #define bOneMBRightVertTB pSC->bOneMBRightVertTB
- #define iPredBefore pSC->iPredBefore
- #define iPredAfter pSC->iPredAfter
- if (pSC->WMISCP.bUseHardTileBoundaries) {
- //Add tile location information
- if (pSC->cColumn == 0) {
- bVertTileBoundary = FALSE;
- tileY = 0;
- }
- bOneMBLeftVertTB = bOneMBRightVertTB = FALSE;
- if(tileY > 0 && tileY <= pSC->WMISCP.cNumOfSliceMinus1H && (pSC->cColumn - 1) == pSC->WMISCP.uiTileY[tileY])
- bOneMBRightVertTB = TRUE;
- if(tileY < pSC->WMISCP.cNumOfSliceMinus1H && pSC->cColumn == pSC->WMISCP.uiTileY[tileY + 1]) {
- bVertTileBoundary = TRUE;
- tileY++;
- }
- else
- bVertTileBoundary = FALSE;
- if(tileY < pSC->WMISCP.cNumOfSliceMinus1H && (pSC->cColumn + 1) == pSC->WMISCP.uiTileY[tileY + 1])
- bOneMBLeftVertTB = TRUE;
- if (pSC->cRow == 0) {
- bHoriTileBoundary = FALSE;
- tileX = 0;
- }
- else if(mbY != pSC->cRow && tileX < pSC->WMISCP.cNumOfSliceMinus1V && pSC->cRow == pSC->WMISCP.uiTileX[tileX + 1]) {
- bHoriTileBoundary = TRUE;
- tileX++;
- }
- else if(mbY != pSC->cRow)
- bHoriTileBoundary = FALSE;
- }
- else {
- bVertTileBoundary = FALSE;
- bHoriTileBoundary = FALSE;
- bOneMBLeftVertTB = FALSE;
- bOneMBRightVertTB = FALSE;
- }
- mbX = pSC->cColumn, mbY = pSC->cRow;
- //================================================================
- // 400_Y, 444_YUV
- for(i = 0; i < iNumChromaFullPlanes; ++i)
- {
- PixelI* const p0 = pSC->p0MBbuffer[i];//(0 == i ? pSC->pY0 : (1 == i ? pSC->pU0 : pSC->pV0));
- PixelI* const p1 = pSC->p1MBbuffer[i];//(0 == i ? pSC->pY1 : (1 == i ? pSC->pU1 : pSC->pV1));
- //================================
- // first level overlap
- if(OL_NONE != olOverlap)
- {
- /* Corner operations */
- if ((top || bHoriTileBoundary) && (left || bVertTileBoundary))
- strPre4(p1 + 0, p1 + 1, p1 + 2, p1 + 3);
- if ((top || bHoriTileBoundary) && (right || bVertTileBoundary))
- strPre4(p1 - 59, p1 - 60, p1 - 57, p1 - 58);
- if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary))
- strPre4(p0 + 48 + 10, p0 + 48 + 11, p0 + 48 + 8, p0 + 48 + 9);
- if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary))
- strPre4(p0 - 1, p0 - 2, p0 - 3, p0 - 4);
- if(!right && !bottom)
- {
- if (top || bHoriTileBoundary)
- {
- for (j = ((left || bVertTileBoundary) ? 0 : -64); j < 192; j += 64)
- {
- p = p1 + j;
- strPre4(p + 5, p + 4, p + 64, p + 65);
- strPre4(p + 7, p + 6, p + 66, p + 67);
- p = NULL;
- }
- }
- else
- {
- for (j = ((left || bVertTileBoundary) ? 0 : -64); j < 192; j += 64)
- {
- strPre4x4Stage1Split(p0 + 48 + j, p1 + j, 0);
- }
- }
- if (left || bVertTileBoundary)
- {
- if (!top && !bHoriTileBoundary)
- {
- strPre4(p0 + 58, p0 + 56, p1 + 0, p1 + 2);
- strPre4(p0 + 59, p0 + 57, p1 + 1, p1 + 3);
- }
- for (j = -64; j < -16; j += 16)
- {
- p = p1 + j;
- strPre4(p + 74, p + 72, p + 80, p + 82);
- strPre4(p + 75, p + 73, p + 81, p + 83);
- p = NULL;
- }
- }
- else
- {
- for (j = -64; j < -16; j += 16)
- {
- strPre4x4Stage1(p1 + j, 0);
- }
- }
- strPre4x4Stage1(p1 + 0, 0);
- strPre4x4Stage1(p1 + 16, 0);
- strPre4x4Stage1(p1 + 32, 0);
- strPre4x4Stage1(p1 + 64, 0);
- strPre4x4Stage1(p1 + 80, 0);
- strPre4x4Stage1(p1 + 96, 0);
- strPre4x4Stage1(p1 + 128, 0);
- strPre4x4Stage1(p1 + 144, 0);
- strPre4x4Stage1(p1 + 160, 0);
- }
-
- if (bottom || bHoriTileBoundary)
- {
- for (j = ((left || bVertTileBoundary) ? 48 : -16); j < (right ? -16 : 240); j += 64)
- {
- p = p0 + j;
- strPre4(p + 15, p + 14, p + 74, p + 75);
- strPre4(p + 13, p + 12, p + 72, p + 73);
- p = NULL;
- }
- }
- if ((right || bVertTileBoundary) && !bottom)
- {
- if (!top && !bHoriTileBoundary)
- {
- strPre4(p0 - 1, p0 - 3, p1 - 59, p1 - 57);
- strPre4(p0 - 2, p0 - 4, p1 - 60, p1 - 58);
- }
- for (j = -64; j < -16; j += 16)
- {
- p = p1 + j;
- strPre4(p + 15, p + 13, p + 21, p + 23);
- strPre4(p + 14, p + 12, p + 20, p + 22);
- p = NULL;
- }
- }
- }
- //================================
- // first level transform
- if (!top)
- {
- for (j = (left ? 48 : -16); j < (right ? 48 : 240); j += 64)
- {
- strDCT4x4Stage1(p0 + j);
- }
- }
- if (!bottom)
- {
- for (j = (left ? 0 : -64); j < (right ? 0 : 192); j += 64)
- {
- strDCT4x4Stage1(p1 + j + 0);
- strDCT4x4Stage1(p1 + j + 16);
- strDCT4x4Stage1(p1 + j + 32);
- }
- }
-
- //================================
- // second level overlap
- if (OL_TWO == olOverlap)
- {
- /* Corner operations */
- if ((top || bHoriTileBoundary) && (left || bVertTileBoundary))
- strPre4(p1 + 0, p1 + 64, p1 + 0 + 16, p1 + 64 + 16);
- if ((top || bHoriTileBoundary) && (right || bVertTileBoundary))
- strPre4(p1 - 128, p1 - 64, p1 - 128 + 16, p1 - 64 + 16);
- if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary))
- strPre4(p0 + 32, p0 + 96, p0 + 32 + 16, p0 + 96 + 16);
- if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary))
- strPre4(p0 - 96, p0 - 32, p0 - 96 + 16, p0 - 32 + 16);
- if ((leftORright || bVertTileBoundary) && (!topORbottom && !bHoriTileBoundary))
- {
- if (left || bVertTileBoundary) {
- j = 0;
- strPre4(p0 + j + 32, p0 + j + 48, p1 + j + 0, p1 + j + 16);
- strPre4(p0 + j + 96, p0 + j + 112, p1 + j + 64, p1 + j + 80);
- }
- if (right || bVertTileBoundary) {
- j = -128;
- strPre4(p0 + j + 32, p0 + j + 48, p1 + j + 0, p1 + j + 16);
- strPre4(p0 + j + 96, p0 + j + 112, p1 + j + 64, p1 + j + 80);
- }
- }
- if (!leftORright && !bVertTileBoundary)
- {
- if (topORbottom || bHoriTileBoundary)
- {
- if (top || bHoriTileBoundary) {
- p = p1;
- strPre4(p - 128, p - 64, p + 0, p + 64);
- strPre4(p - 112, p - 48, p + 16, p + 80);
- p = NULL;
- }
- if (bottom || bHoriTileBoundary) {
- p = p0 + 32;
- strPre4(p - 128, p - 64, p + 0, p + 64);
- strPre4(p - 112, p - 48, p + 16, p + 80);
- p = NULL;
- }
- }
- else
- {
- strPre4x4Stage2Split(p0, p1);
- }
- }
- }
- //================================
- // second level transform
- if (!topORleft){
- if (pSC->m_param.bScaledArith) {
- strNormalizeEnc(p0 - 256, (i != 0));
- }
- strDCT4x4SecondStage(p0 - 256);
- }
- }
- //================================================================
- // 420_UV
- for(i = 0; i < (YUV_420 == cfColorFormat? 2 : 0); ++i)
- {
- PixelI* const p0 = pSC->p0MBbuffer[1 + i];//(0 == i ? pSC->pU0 : pSC->pV0);
- PixelI* const p1 = pSC->p1MBbuffer[1 + i];//(0 == i ? pSC->pU1 : pSC->pV1);
- //================================
- // first level overlap (420_UV)
- if (OL_NONE != olOverlap)
- {
- /* Corner operations */
- if ((top || bHoriTileBoundary) && (left || bVertTileBoundary))
- strPre4(p1 + 0, p1 + 1, p1 + 2, p1 + 3);
- if ((top || bHoriTileBoundary) && (right || bVertTileBoundary))
- strPre4(p1 - 27, p1 - 28, p1 - 25, p1 - 26);
- if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary))
- strPre4(p0 + 16 + 10, p0 + 16 + 11, p0 + 16 + 8, p0 + 16 + 9);
- if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary))
- strPre4(p0 - 1, p0 - 2, p0 - 3, p0 - 4);
- if(!right && !bottom)
- {
- if (top || bHoriTileBoundary)
- {
- for (j = ((left || bVertTileBoundary) ? 0 : -32); j < 32; j += 32)
- {
- p = p1 + j;
- strPre4(p + 5, p + 4, p + 32, p + 33);
- strPre4(p + 7, p + 6, p + 34, p + 35);
- p = NULL;
- }
- }
- else
- {
- for (j = ((left || bVertTileBoundary) ? 0: -32); j < 32; j += 32)
- {
- strPre4x4Stage1Split(p0 + 16 + j, p1 + j, 32);
- }
- }
- if (left || bVertTileBoundary)
- {
- if (!top && !bHoriTileBoundary)
- {
- strPre4(p0 + 26, p0 + 24, p1 + 0, p1 + 2);
- strPre4(p0 + 27, p0 + 25, p1 + 1, p1 + 3);
- }
- strPre4(p1 + 10, p1 + 8, p1 + 16, p1 + 18);
- strPre4(p1 + 11, p1 + 9, p1 + 17, p1 + 19);
- }
- else if (!bVertTileBoundary)
- {
- strPre4x4Stage1(p1 - 32, 32);
- }
- strPre4x4Stage1(p1, 32);
- }
- if (bottom || bHoriTileBoundary)
- {
- for (j = ((left || bVertTileBoundary) ? 16: -16); j < (right ? -16: 32); j += 32)
- {
- p = p0 + j;
- strPre4(p + 15, p + 14, p + 42, p + 43);
- strPre4(p + 13, p + 12, p + 40, p + 41);
- p = NULL;
- }
- }
- if ((right || bVertTileBoundary) && !bottom)
- {
- if (!top && !bHoriTileBoundary)
- {
- strPre4(p0 - 1, p0 - 3, p1 - 27, p1 - 25);
- strPre4(p0 - 2, p0 - 4, p1 - 28, p1 - 26);
- }
- strPre4(p1 - 17, p1 - 19, p1 - 11, p1 - 9);
- strPre4(p1 - 18, p1 - 20, p1 - 12, p1 - 10);
- }
- }
- //================================
- // first level transform (420_UV)
- if (!top)
- {
- for (j = (left ? 16 : -16); j < (right ? 16 : 48); j += 32)
- {
- strDCT4x4Stage1(p0 + j);
- }
- }
- if (!bottom)
- {
- for (j = (left ? 0 : -32); j < (right ? 0 : 32); j += 32)
- {
- strDCT4x4Stage1(p1 + j);
- }
- }
-
- //================================
- // second level overlap (420_UV)
- if (OL_TWO == olOverlap)
- {
- if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary))
- COMPUTE_CORNER_PRED_DIFF(p1 - 64 + 0, *(p1 - 64 + 32));
- if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary))
- iPredBefore[i][0] = *(p1 + 0);
- if ((right || bVertTileBoundary) && (top || bHoriTileBoundary))
- COMPUTE_CORNER_PRED_DIFF(p1 - 64 + 32, iPredBefore[i][0]);
- if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary))
- COMPUTE_CORNER_PRED_DIFF(p0 - 64 + 16, *(p0 - 64 + 48));
- if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary))
- iPredBefore[i][1] = *(p0 + 16);
- if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary))
- COMPUTE_CORNER_PRED_DIFF(p0 - 64 + 48, iPredBefore[i][1]);
- if ((leftORright || bVertTileBoundary) && !topORbottom && !bHoriTileBoundary)
- {
- if (left || bVertTileBoundary)
- strPre2(p0 + 0 + 16, p1 + 0);
- if (right || bVertTileBoundary)
- strPre2(p0 + -32 + 16, p1 + -32);
- }
- if (!leftORright)
- {
- if ((topORbottom || bHoriTileBoundary) && !bVertTileBoundary)
- {
- if (top || bHoriTileBoundary)
- strPre2(p1 - 32, p1);
- if (bottom || bHoriTileBoundary)
- strPre2(p0 + 16 - 32, p0 + 16);
- }
- else if (!topORbottom && !bHoriTileBoundary && !bVertTileBoundary)
- strPre2x2(p0 - 16, p0 + 16, p1 - 32, p1);
- }
- if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary))
- COMPUTE_CORNER_PRED_ADD(p1 - 64 + 0, *(p1 - 64 + 32));
- if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary))
- iPredAfter[i][0] = *(p1 + 0);
- if ((right || bVertTileBoundary) && (top || bHoriTileBoundary))
- COMPUTE_CORNER_PRED_ADD(p1 - 64 + 32, iPredAfter[i][0]);
- if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary))
- COMPUTE_CORNER_PRED_ADD(p0 - 64 + 16, *(p0 - 64 + 48));
- if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary))
- iPredAfter[i][1] = *(p0 + 16);
- if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary))
- COMPUTE_CORNER_PRED_ADD(p0 - 64 + 48, iPredAfter[i][1]);
- }
- //================================
- // second level transform (420_UV)
- if (!topORleft)
- {
- if (!pSC->m_param.bScaledArith) {
- strDCT2x2dn(p0 - 64, p0 - 32, p0 - 48, p0 - 16);
- }
- else {
- strDCT2x2dnEnc(p0 - 64, p0 - 32, p0 - 48, p0 - 16);
- }
- }
- }
- //================================================================
- // 422_UV
- for(i = 0; i < (YUV_422 == cfColorFormat? 2 : 0); ++i)
- {
- PixelI* const p0 = pSC->p0MBbuffer[1 + i];//(0 == i ? pSC->pU0 : pSC->pV0);
- PixelI* const p1 = pSC->p1MBbuffer[1 + i];//(0 == i ? pSC->pU1 : pSC->pV1);
- //================================
- // first level overlap (422_UV)
- if (OL_NONE != olOverlap)
- {
- /* Corner operations */
- if ((top || bHoriTileBoundary) && (left || bVertTileBoundary))
- strPre4(p1 + 0, p1 + 1, p1 + 2, p1 + 3);
- if ((top || bHoriTileBoundary) && (right || bVertTileBoundary))
- strPre4(p1 - 59, p1 - 60, p1 - 57, p1 - 58);
- if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary))
- strPre4(p0 + 48 + 10, p0 + 48 + 11, p0 + 48 + 8, p0 + 48 + 9);
- if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary))
- strPre4(p0 - 1, p0 - 2, p0 - 3, p0 - 4);
- if(!right && !bottom)
- {
- if (top || bHoriTileBoundary)
- {
- for (j = ((left || bVertTileBoundary) ? 0 : -64); j < 64; j += 64)
- {
- p = p1 + j;
- strPre4(p + 5, p + 4, p + 64, p + 65);
- strPre4(p + 7, p + 6, p + 66, p + 67);
- p = NULL;
- }
- }
- else
- {
- for (j = ((left || bVertTileBoundary) ? 0: -64); j < 64; j += 64)
- {
- strPre4x4Stage1Split(p0 + 48 + j, p1 + j, 0);
- }
- }
- if (left || bVertTileBoundary)
- {
- if (!top && !bHoriTileBoundary)
- {
- strPre4(p0 + 58, p0 + 56, p1 + 0, p1 + 2);
- strPre4(p0 + 59, p0 + 57, p1 + 1, p1 + 3);
- }
- for (j = 0; j < 48; j += 16)
- {
- p = p1 + j;
- strPre4(p + 10, p + 8, p + 16, p + 18);
- strPre4(p + 11, p + 9, p + 17, p + 19);
- p = NULL;
- }
- }
- else if (!bVertTileBoundary)
- {
- for (j = -64; j < -16; j += 16)
- {
- strPre4x4Stage1(p1 + j, 0);
- }
- }
- strPre4x4Stage1(p1 + 0, 0);
- strPre4x4Stage1(p1 + 16, 0);
- strPre4x4Stage1(p1 + 32, 0);
- }
- if (bottom || bHoriTileBoundary)
- {
- for (j = ((left || bVertTileBoundary) ? 48: -16); j < (right ? -16: 112); j += 64)
- {
- p = p0 + j;
- strPre4(p + 15, p + 14, p + 74, p + 75);
- strPre4(p + 13, p + 12, p + 72, p + 73);
- p = NULL;
- }
- }
- if ((right || bVertTileBoundary) && !bottom)
- {
- if (!top && !bHoriTileBoundary)
- {
- strPre4(p0 - 1, p0 - 3, p1 - 59, p1 - 57);
- strPre4(p0 - 2, p0 - 4, p1 - 60, p1 - 58);
- }
- for (j = -64; j < -16; j += 16)
- {
- p = p1 + j;
- strPre4(p + 15, p + 13, p + 21, p + 23);
- strPre4(p + 14, p + 12, p + 20, p + 22);
- p = NULL;
- }
- }
- }
- //================================
- // first level transform (422_UV)
- if (!top)
- {
- for (j = (left ? 48 : -16); j < (right ? 48 : 112); j += 64)
- {
- strDCT4x4Stage1(p0 + j);
- }
- }
- if (!bottom)
- {
- for (j = (left ? 0 : -64); j < (right ? 0 : 64); j += 64)
- {
- strDCT4x4Stage1(p1 + j + 0);
- strDCT4x4Stage1(p1 + j + 16);
- strDCT4x4Stage1(p1 + j + 32);
- }
- }
-
- //================================
- // second level overlap (422_UV)
- if (OL_TWO == olOverlap)
- {
- if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary))
- COMPUTE_CORNER_PRED_DIFF(p1 - 128 + 0, *(p1 - 128 + 64));
- if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary))
- iPredBefore[i][0] = *(p1 + 0);
- if ((right || bVertTileBoundary) && (top || bHoriTileBoundary))
- COMPUTE_CORNER_PRED_DIFF(p1 - 128 + 64, iPredBefore[i][0]);
- if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary))
- COMPUTE_CORNER_PRED_DIFF(p0 - 128 + 48, *(p0 - 128 + 112));
- if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary))
- iPredBefore[i][1] = *(p0 + 48);
- if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary))
- COMPUTE_CORNER_PRED_DIFF(p0 - 128 + 112, iPredBefore[i][1]);
- if (!bottom)
- {
- if (leftORright || bVertTileBoundary)
- {
- if (!top && !bHoriTileBoundary)
- {
- if (left || bVertTileBoundary)
- strPre2(p0 + 48 + 0, p1 + 0);
- if (right || bVertTileBoundary)
- strPre2(p0 + 48 + -64, p1 + -64);
- }
- if (left || bVertTileBoundary)
- strPre2(p1 + 16, p1 + 16 + 16);
- if (right || bVertTileBoundary)
- strPre2(p1 + -48, p1 + -48 + 16);
- }
- if (!leftORright && !bVertTileBoundary)
- {
- if (top || bHoriTileBoundary)
- strPre2(p1 - 64, p1);
- else
- strPre2x2(p0 - 16, p0 + 48, p1 - 64, p1);
- strPre2x2(p1 - 48, p1 + 16, p1 - 32, p1 + 32);
- }
- }
- if ((bottom || bHoriTileBoundary) && (!leftORright && !bVertTileBoundary))
- strPre2(p0 - 16, p0 + 48);
- if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary))
- COMPUTE_CORNER_PRED_ADD(p1 - 128 + 0, *(p1 - 128 + 64));
- if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary))
- iPredAfter[i][0] = *(p1 + 0);
- if ((right || bVertTileBoundary) && (top || bHoriTileBoundary))
- COMPUTE_CORNER_PRED_ADD(p1 - 128 + 64, iPredAfter[i][0]);
- if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary))
- COMPUTE_CORNER_PRED_ADD(p0 - 128 + 48, *(p0 - 128 + 112));
- if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary))
- iPredAfter[i][1] = *(p0 + 48);
- if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary))
- COMPUTE_CORNER_PRED_ADD(p0 - 128 + 112, iPredAfter[i][1]);
- }
- //================================
- // second level transform (422_UV)
- if (!topORleft)
- {
- if (!pSC->m_param.bScaledArith) {
- strDCT2x2dn(p0 - 128, p0 - 64, p0 - 112, p0 - 48);
- strDCT2x2dn(p0 - 96, p0 - 32, p0 - 80, p0 - 16);
- }
- else {
- strDCT2x2dnEnc(p0 - 128, p0 - 64, p0 - 112, p0 - 48);
- strDCT2x2dnEnc(p0 - 96, p0 - 32, p0 - 80, p0 - 16);
- }
- // 1D lossless HT
- p0[- 96] -= p0[-128];
- p0[-128] += ((p0[-96] + 1) >> 1);
- }
- }
- assert(NULL == p);
- }
|