/* ------------------------------------------------------------------
 * Copyright (C) 1998-2009 PacketVideo
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 * -------------------------------------------------------------------
 */
/** Class CCRGB24toRGB16. convert RGB24 to RGB16 by truncating the least significant bits. */
#include "colorconv_config.h"
#include "ccrgb24torgb16.h"


OSCL_EXPORT_REF ColorConvertBase* CCRGB24toRGB16::NewL(void)
{
    CCRGB24toRGB16* self = OSCL_NEW(CCRGB24toRGB16, ());
    return OSCL_STATIC_CAST(ColorConvertBase*, self);
}


CCRGB24toRGB16::CCRGB24toRGB16()
{
}


OSCL_EXPORT_REF CCRGB24toRGB16::~CCRGB24toRGB16()
{
}

int32 CCRGB24toRGB16::Init(int32 Src_width, int32 Src_height, int32 Src_pitch, int32 Dst_width, int32 Dst_height, int32 Dst_pitch, int32 nRotation)
{

    if (ColorConvertBase::Init(Src_width, Src_height, Src_pitch, Dst_width, Dst_height, Dst_pitch, nRotation) == 0)
    {
        return 0;
    }

    //default no zoom
    _mInitialized = true;

    SetMode(0); // called after init

    return 1;
}


int32 CCRGB24toRGB16::SetYuvFullRange(bool range)
{
    OSCL_UNUSED_ARG(range);
    OSCL_ASSERT(_mInitialized == true);

    return 1;  // do nothing here.
}

int32 CCRGB24toRGB16::SetMode(int32 nMode)  //nMode : 0 Off, 1 On
{
    OSCL_ASSERT(_mInitialized == true);

    if (nMode == 0)
    {
        //      mPtrConv = cc16Rotate;
        //      _mState     = 1;
        mPtrConv    =   &CCRGB24toRGB16::getframe;
        _mState     =   0;
        _mDisp.src_pitch = _mSrc_pitch  ;
        _mDisp.dst_pitch = _mSrc_width  ;
        _mDisp.src_width = _mSrc_width  ;
        _mDisp.src_height = _mSrc_height ;
        _mDisp.dst_width = _mSrc_width  ;
        _mDisp.dst_height = _mSrc_height ;
    }
    else
    {
#if CCSCALING
        if (_mIsZoom)
        {
#if CCROTATE
            if (_mRotation&0x1) /* zoom and rotate */
            {
                mPtrConv = &CCRGB24toRGB16::zoomRotate;
            }
            else /* zoom only */
#endif
            {
                mPtrConv    =   &CCRGB24toRGB16::zoom;
            }
        }
        else
#endif
        {
#if CCROTATE
            if (_mRotation&0x1) /* rotate only*/
            {
                mPtrConv = &CCRGB24toRGB16::rotate;
            }
            else /* no zoom, no rotate, SetMode(1) = SetMode(0) */
#endif
            {
                mPtrConv    =   &CCRGB24toRGB16::getframe;
            }
        }
        _mState     =   nMode;
        _mDisp.src_pitch = _mSrc_pitch  ;
        _mDisp.dst_pitch = _mDst_pitch  ;
        _mDisp.src_width = _mSrc_width  ;
        _mDisp.src_height = _mSrc_height ;
        _mDisp.dst_width = _mDst_width  ;
        _mDisp.dst_height = _mDst_height ;
    }

    return 1;
}


int32 CCRGB24toRGB16::GetOutputBufferSize(void)
{
    OSCL_ASSERT(_mInitialized == true);

    if (_mIsZoom)
    {
        // for zoom, need extra line of RGB_FORMAT buffer for processing otherwise memory will corrupt.
        return  _mState ? ((_mDst_height + 2)*_mDst_pitch*2) : (_mSrc_width*_mSrc_height*2);
    }
    else
    {
        return  _mState ? ((_mDst_height)*_mDst_pitch*2) : (_mSrc_width*_mSrc_height*2);
    }
}


int32 CCRGB24toRGB16::Convert(uint8 **srcBuf, uint8 *destBuf)
{
    OSCL_ASSERT(_mInitialized == true);
    OSCL_ASSERT(srcBuf);
    OSCL_ASSERT(srcBuf[0]);
    OSCL_ASSERT(srcBuf[1]);
    OSCL_ASSERT(srcBuf[2]);
    OSCL_ASSERT(destBuf);

    if (((uint32)destBuf)&0x3 || ((uint32)srcBuf[0])&0x3) /* address is not word align */
    {
        return 0;
    }

    return (*this.*mPtrConv)(srcBuf[0], destBuf, &_mDisp);
}


int32 CCRGB24toRGB16::Convert(uint8 *srcBuf, uint8 *destBuf)
{
    OSCL_ASSERT(_mInitialized == true);
    OSCL_ASSERT(srcBuf);
    OSCL_ASSERT(destBuf);

    if (((uint32)srcBuf)&0x3 || ((uint32)destBuf)&0x3) /* address is not word align */
    {
        return 0;
    }

    return (*this.*mPtrConv)(srcBuf, destBuf, &_mDisp);
}

int32 reverse(uint8 *src, uint8 *dst, int32 *disp);
int32 normal(uint8 *src, uint8 *dst, int32 *disp);

int32 CCRGB24toRGB16::getframe(uint8 *src, uint8 *dst, DisplayProperties *disp)
{
    int32 disp_prop[8];

    disp_prop[0] = disp->src_pitch;
    disp_prop[1] = disp->dst_pitch;
    disp_prop[2] = disp->src_width;
    disp_prop[3] = disp->src_height;
    disp_prop[4] = disp->dst_width;
    disp_prop[5] = disp->dst_height;
    disp_prop[6] = (_mRotation > 0 ? 1 : 0);
    disp_prop[7] = _mIsFlip;

    if (disp_prop[6] ^ disp_prop[7])    /* either flip or rotate 180*/
    {
#if (!CCROTATE)
        return 0;
#else
        return reverse(src, dst, disp_prop);
#endif
    }
    else
    {
        return normal(src, dst, disp_prop);
    }
}

int32 normal(uint8 *src, uint8 *dst, int32 *disp)
{
    uint8   *pSrc;
    uint16  *pDst;
    int32       src_pitch, dst_pitch, src_width, src_height;
    int32       half1, half2;
    int32       deltaSrc, deltaDst;
    int32       row, col;
    uint32      rgb, tmp0;

    src_pitch   =   disp[0];
    dst_pitch   =   disp[1];
    src_width   =   disp[2];
    src_height  =   disp[3];

    if (disp[6]) /* rotate 180 and flip */
    {   /* move the starting point to the bottom-left corner of the picture */
        deltaSrc = src_pitch * (src_height - 1) * 3;
        pSrc = (uint8*)(src + deltaSrc);
        deltaSrc = -(src_width + src_pitch) * 3;
    }
    else
    {
        deltaSrc    = (src_pitch - src_width) * 3;
        pSrc =  src;
    }

    deltaDst    = (dst_pitch - src_width);
    pDst = (uint16 *)dst;

    for (row = src_height; row > 0; row--)
    {

        for (col = src_width - 1; col >= 0; col -= 2)
        {


            half1 = *((uint16*)(pSrc));  /* read 2 bytes, G0 R0 or G0 B0 */
            half2 = *((uint16*)(pSrc += 2)); /* read 2 bytes, R1 B0 or B1 R0 */

#if RGB_FORMAT
            rgb = half1 & 0xF8;  /* get 5 bits of R0 */
            half1 = (half1 >> 5) & 0x7E0;  /* get 6 bits of G0 */
            rgb = (rgb << 8) | half1;               /*  R0, G0 */
            half1 = (half2 >> 3) & 0x1F;        /* get 5 bits of B0 */
            rgb |= half1;           /*  R0,G0,B0 */

            half1 = *((uint16*)(pSrc += 2)); /* read 2 bytes, B1 G1 */

            half2 &= 0xF800;            /* get 5 bits of R1 */
            tmp0 = half1 & 0xFC;            /* get 6 bits of G1 */
            tmp0 = (tmp0 << 3) | half2;  /* R1 G1 */
            tmp0 |= (half1 >> 11);      /* R1 G1 B1 */
#else //BGR
            rgb = half2 & 0xF8;  /* get 5 bits of R0 */
            tmp0 = (half1 >> 5) & 0x7E0;  /* get 6 bits of G0 */
            rgb = (rgb << 8) | tmp0;                /*  R0, G0 */
            half1 = (half1 >> 3) & 0x1F;        /* get 5 bits of B0 */
            rgb |= half1;           /*  R0,G0,B0 */

            half1 = *((uint16*)(pSrc += 2)); /* read 2 bytes, R1 G1 */

            tmp0 = half1 & 0xF800;      /* get 5 bits of R1 */
            half1 = (half1 << 3) & 0x7C0;  /* get G1 in the middle */
            tmp0 |= half1;             /* R1 G1 */
            tmp0 |= (half2 >> 11);     /* R1 G1 B1 */
#endif
            rgb = rgb | (tmp0 << 16);

            *((uint32*)pDst) = rgb;
            pDst += 2;
            pSrc += 2;

        }

        pSrc += deltaSrc;
        pDst += deltaDst;
    }

    return 1;
}

#if CCROTATE
int32 reverse(uint8 *src, uint8 *dst, int32 *disp)
{
    uint8   *pSrc;
    uint16  *pDst;
    int32       src_pitch, dst_pitch, src_width, src_height;
    int32       half1, half2;
    int32       deltaSrc, deltaDst;
    int32       row, col;
    uint32      rgb, tmp0;
    int nextrow, mIsFlip;

    src_pitch   =   disp[0];
    dst_pitch   =   disp[1];
    src_width   =   disp[2];
    src_height  =   disp[3];
    mIsFlip     =   disp[7];

    deltaDst    = (dst_pitch - src_width);
    pDst = (uint16 *)dst;

    if (disp[6]) /* rotation, only */
    {  /* move the starting point to the bottom-right corner of the picture */
        nextrow = src_pitch * src_height * 3;
        pSrc = (src + nextrow - 6);
        deltaSrc    = (src_width - src_pitch) * 3;
    }
    else    /* flip only */
    {   /* move the starting point to the top-right corner of the picture */
        pSrc = (src + src_width * 3 - 6);
        deltaSrc = (src_width + src_pitch) * 3;
    }

    for (row = src_height; row > 0; row--)
    {

        for (col = src_width - 1; col >= 0; col -= 2)
        {


            half1 = *((uint16*)(pSrc));  /* read 2 bytes, G0 R0 or G0 B0 */
            half2 = *((uint16*)(pSrc += 2)); /* read 2 bytes, R1 B0 or B1 R0 */

#if RGB_FORMAT
            rgb = half1 & 0xF8;  /* get 5 bits of R0 */
            half1 = (half1 >> 5) & 0x7E0;  /* get 6 bits of G0 */
            rgb = (rgb << 8) | half1;               /*  R0, G0 */
            half1 = (half2 >> 3) & 0x1F;        /* get 5 bits of B0 */
            rgb |= half1;           /*  R0,G0,B0 */

            half1 = *((uint16*)(pSrc += 2)); /* read 2 bytes, B1 G1 */

            half2 &= 0xF800;            /* get 5 bits of R1 */
            tmp0 = half1 & 0xFC;            /* get 6 bits of G1 */
            tmp0 = (tmp0 << 3) | half2;  /* R1 G1 */
            tmp0 |= (half1 >> 11);      /* R1 G1 B1 */
#else //BGR
            rgb = half2 & 0xF8;  /* get 5 bits of R0 */
            tmp0 = (half1 >> 5) & 0x7E0;  /* get 6 bits of G0 */
            rgb = (rgb << 8) | tmp0;                /*  R0, G0 */
            half1 = (half1 >> 3) & 0x1F;        /* get 5 bits of B0 */
            rgb |= half1;           /*  R0,G0,B0 */

            half1 = *((uint16*)(pSrc += 2)); /* read 2 bytes, R1 G1 */

            tmp0 = half1 & 0xF800;      /* get 5 bits of R1 */
            half1 = (half1 << 3) & 0x7C0;  /* get G1 in the middle */
            tmp0 |= half1;             /* R1 G1 */
            tmp0 |= (half2 >> 11);     /* R1 G1 B1 */
#endif
            rgb = tmp0 | (rgb << 16);

            *((uint32*)pDst) = rgb;
            pDst += 2;
            pSrc -= 10;

        }

        pSrc += deltaSrc;
        pDst += deltaDst;
    }

    return 1;
}


int32 CCRGB24toRGB16::rotate(uint8 *src, uint8 *dst, DisplayProperties *disp)
{
    OSCL_UNUSED_ARG(src);
    OSCL_UNUSED_ARG(dst);
    OSCL_UNUSED_ARG(disp);
// To be implemented
    return 1;
}

#endif // CCROTATE

int32 scaledown(uint8*src, uint8 *dst, int32 *disp_prop, uint8 *_mRowPix, uint8 *_mColPix);
int32 scaleup(uint8*src, uint8 *dst, int32 *disp_prop, uint8 *_mRowPix, uint8 *_mColPix);

int32 CCRGB24toRGB16::zoom(uint8 *src, uint8 *dst, DisplayProperties *disp)
{
#if (!CCSCALING)
    OSCL_UNUSED_ARG(src);
    OSCL_UNUSED_ARG(dst);
    OSCL_UNUSED_ARG(disp);
    return 0;
#else
    int32 disp_prop[8];
    int32 src_width, src_height, dst_width, dst_height;

    disp_prop[0] = disp->src_pitch;
    disp_prop[1] = disp->dst_pitch;
    disp_prop[2] = src_width = disp->src_width;
    disp_prop[3] = src_height = disp->src_height;
    disp_prop[4] = dst_width = disp->dst_width;
    disp_prop[5] = dst_height = disp->dst_height;
    disp_prop[6] = (_mRotation > 0 ? 1 : 0);
    disp_prop[7] = _mIsFlip;

    if (src_width > dst_width) /* scale down in width */
    {
        return scaledown(src, dst, disp_prop, _mRowPix, _mColPix);
    }
    else
    {
        return scaleup(src, dst, disp_prop, _mRowPix, _mColPix);
    }

    return 1;
#endif // CCSCALING
}

#if CCSCALING
int32 scaledown(uint8*src, uint8 *dst, int32 *disp, uint8 *_mRowPix, uint8 *_mColPix)
{
    uint8   *pSrc;
    uint16  *pDst;
    int32   src_pitch, dst_pitch, src_width, src_height, dst_width;
    int32   half1, half2;
    int32   deltaSrc;
    int32   row, col;
    uint32  rgb, R0, G0, B0, R1, G1, B1, R2, G2, B2;
    int     temp, denom, row_interp;
    int      mIsFlip;
    uint8 *rowpix, *colpix;

    src_pitch   =   disp[0];
    dst_pitch   =   disp[1];
    src_width   =   disp[2];
    src_height  =   disp[3];
    dst_width   =   disp[4];
    mIsFlip     =   disp[7];

    if ((disp[6] ^ mIsFlip) == 1) /* rotate 180 and  no flip || rotate 0 and  with flip */
    {
        if (disp[6] == 1) /*rotate 180 and  no flip */
        {
            temp = src_pitch * src_height * 3;
            pSrc = (src + temp - 6);
            deltaSrc = (src_width - src_pitch) * 3;
        }
        else /* rotate 0 and  with flip */
        {
            pSrc = (src + src_width * 3 - 6);
            deltaSrc = (src_width + src_pitch) * 3;
        }
        pDst = (uint16 *)dst;
        colpix = _mColPix + src_height - 1;
        row_interp = 0;

        for (row = src_height; row > 0; row--)
        {/* decrement index, _mColPix[.] is
            symmetric to increment index */

            /*  if(*colpix--==0)
                {
                    pSrc+=src_width*3;
                    pSrc+=deltaSrc;
                    continue;
                }*/

            rowpix = _mRowPix + src_width - 1;
            denom = 1;
            R2 = G2 = B2 = 0;

            for (col = src_width; col > 0; col -= 2)
            { /* decrement index, _mRowPix[.] is
                symmetric to increment index */

                half1 = *((uint16*)(pSrc));  /* read 2 bytes, G0 R0 or G0 B0 */
                half2 = *((uint16*)(pSrc += 2)); /* read 2 bytes, R1 B0 or B1 R0 */

#if RGB_FORMAT
                R1 = (half1 >> 3) & 0x1F;
                G1 = (half1 >> 10);
                B1 = (half2 >> 3) & 0x1F;
                half1 = *((uint16*)(pSrc += 2)); /* read 2 bytes, B1 G1 */
                R0 = half2 >> 11;
                G0 = (half1 >> 2) & 0x3F;
                B0 = half1 >> 11;
#else
                B1 = (half1 >> 3) & 0x1F;
                G1 = (half1 >> 10);
                R1 = (half2 >> 3) & 0x1F;
                half1 = *((uint16*)(pSrc += 2)); /* read 2 bytes, R1 G1 */
                B0 = half2 >> 11;
                G0 = (half1 >> 2) & 0x3F;
                R0 = half1 >> 11;
#endif
                pSrc -= 10;

                temp = *rowpix--;

                R2 += R0;
                G2 += G0;
                B2 += B0;
                if (temp)
                {
                    R2 = (R2 + (denom / 2)) / denom;
                    G2 = (G2 + (denom / 2)) / denom;
                    B2 = (B2 + (denom / 2)) / denom;
                    // re-use R0,G0,B0,half1, do row interpolation
                    if (row_interp)
                    {
                        half1 = *pDst;
                        R0 = half1 >> 11;
                        G0 = (half1 >> 5) & 0x3F;
                        B0 = half1 & 0x1F;
                        R2 = (R2 + R0 + 1) >> 1;
                        G2 = (G2 + G0 + 1) >> 1;
                        B2 = (B2 + B0 + 1) >> 1;
                    }
                    rgb = (R2 << 6) | G2;
                    rgb = (rgb << 5) | B2;
                    R2 = G2 = B2 = 0;
                    denom = 1;
                    *pDst++ = rgb;
                }
                else
                {
                    denom++;
                }

                temp = *rowpix--;
                R2 += R1;
                G2 += G1;
                B2 += B1;
                if (temp)
                {
                    R2 = (R2 + (denom / 2)) / denom;
                    G2 = (G2 + (denom / 2)) / denom;
                    B2 = (B2 + (denom / 2)) / denom;
                    // re-use R0,G0,B0,half1, do row interpolation
                    if (row_interp)
                    {
                        half1 = *pDst;
                        R0 = half1 >> 11;
                        G0 = (half1 >> 5) & 0x3F;
                        B0 = half1 & 0x1F;
                        R2 = (R2 + R0 + 1) >> 1;
                        G2 = (G2 + G0 + 1) >> 1;
                        B2 = (B2 + B0 + 1) >> 1;
                    }
                    rgb = (R2 << 6) | G2;
                    rgb = (rgb << 5) | B2;
                    R2 = G2 = B2 = 0;
                    denom = 1;
                    *pDst++ = rgb;
                }
                else
                {
                    denom++;
                }
            }
            if (*colpix-- == 1)
            {
                pDst += (dst_pitch - dst_width);
                row_interp = 0;
            }
            else
            {
                pDst -= dst_width;
                row_interp = 1;
            }
            pSrc += deltaSrc;
        }
    }
    else
    {
        if (disp[6] == 1) /* rotate 180 and  with flip */
        {
            /* move the starting point to the bottom-left corner of the picture */
            deltaSrc = src_pitch * (src_height - 1);
            pSrc = src + deltaSrc * 3;
            deltaSrc = -(src_pitch + src_width) * 3;
        }
        else
        {   // only scale down, no rotation ,no flip
            deltaSrc    = (src_pitch - src_width) * 3;
            pSrc = src;
        }

        pDst = (uint16 *)dst;
        colpix = _mColPix + src_height - 1;
        row_interp = 0;

        for (row = src_height; row > 0; row--)
        {/* decrement index, _mColPix[.] is
            symmetric to increment index */

            /*  if(*colpix--==0)
                {
                    pSrc+=src_width*3;
                    pSrc+=deltaSrc;
                    continue;
                }*/

            rowpix = _mRowPix + src_width - 1;
            denom = 1;
            R2 = G2 = B2 = 0;

            for (col = src_width; col > 0; col -= 2)
            { /* decrement index, _mRowPix[.] is
                symmetric to increment index */

                half1 = *((uint16*)(pSrc));  /* read 2 bytes, G0 R0 or G0 B0 */
                half2 = *((uint16*)(pSrc += 2)); /* read 2 bytes, R1 B0 or B1 R0 */

#if RGB_FORMAT
                R0 = (half1 >> 3) & 0x1F;
                G0 = (half1 >> 10);
                B0 = (half2 >> 3) & 0x1F;
                half1 = *((uint16*)(pSrc += 2)); /* read 2 bytes, B1 G1 */
                R1 = half2 >> 11;
                G1 = (half1 >> 2) & 0x3F;
                B1 = half1 >> 11;
#else
                B0 = (half1 >> 3) & 0x1F;
                G0 = (half1 >> 10);
                R0 = (half2 >> 3) & 0x1F;
                half1 = *((uint16*)(pSrc += 2)); /* read 2 bytes, R1 G1 */
                B1 = half2 >> 11;
                G1 = (half1 >> 2) & 0x3F;
                R1 = half1 >> 11;
#endif
                pSrc += 2;

                temp = *rowpix--;

                R2 += R0;
                G2 += G0;
                B2 += B0;
                if (temp)
                {
                    R2 = (R2 + (denom / 2)) / denom;
                    G2 = (G2 + (denom / 2)) / denom;
                    B2 = (B2 + (denom / 2)) / denom;
                    // re-use R0,G0,B0,half1, do row interpolation
                    if (row_interp)
                    {
                        half1 = *pDst;
                        R0 = half1 >> 11;
                        G0 = (half1 >> 5) & 0x3F;
                        B0 = half1 & 0x1F;
                        R2 = (R2 + R0 + 1) >> 1;
                        G2 = (G2 + G0 + 1) >> 1;
                        B2 = (B2 + B0 + 1) >> 1;
                    }
                    rgb = (R2 << 6) | G2;
                    rgb = (rgb << 5) | B2;
                    R2 = G2 = B2 = 0;
                    denom = 1;
                    *pDst++ = rgb;
                }
                else
                {
                    denom++;
                }

                temp = *rowpix--;
                R2 += R1;
                G2 += G1;
                B2 += B1;
                if (temp)
                {
                    R2 = (R2 + (denom / 2)) / denom;
                    G2 = (G2 + (denom / 2)) / denom;
                    B2 = (B2 + (denom / 2)) / denom;
                    // re-use R0,G0,B0,half1, do row interpolation
                    if (row_interp)
                    {
                        half1 = *pDst;
                        R0 = half1 >> 11;
                        G0 = (half1 >> 5) & 0x3F;
                        B0 = half1 & 0x1F;
                        R2 = (R2 + R0 + 1) >> 1;
                        G2 = (G2 + G0 + 1) >> 1;
                        B2 = (B2 + B0 + 1) >> 1;
                    }
                    rgb = (R2 << 6) | G2;
                    rgb = (rgb << 5) | B2;
                    R2 = G2 = B2 = 0;
                    denom = 1;
                    *pDst++ = rgb;
                }
                else
                {
                    denom++;
                }
            }
            if (*colpix-- == 1)
            {
                pDst += (dst_pitch - dst_width);
                row_interp = 0;
            }
            else
            {
                pDst -= dst_width;
                row_interp = 1;
            }
            pSrc += deltaSrc;
        }
    }

    return 1;
}

int32 scaleup(uint8*src, uint8 *dst, int32 *disp, uint8 *_mRowPix, uint8 *_mColPix)
{
    uint8   *pSrc = NULL;
    uint16  *pDst = NULL, *pTop = NULL, *pLine = NULL;
    int32   src_pitch, dst_pitch, src_width, src_height, dst_width;
    int32   half1, half2;
    int32   deltaSrc;
    int32   row, col;
    uint32  rgb, tmp, R0, G0, B0, R1, G1, B1, R2, G2, B2;
    int     temp;
    int nextrow, mIsFlip;
    uint8 *rowpix, *colpix;

    src_pitch   =   disp[0];
    dst_pitch   =   disp[1];
    src_width   =   disp[2];
    src_height  =   disp[3];
    dst_width   =   disp[4];
    mIsFlip     =   disp[7];

    if (((disp[6] == 0) && (mIsFlip == 1)) || ((disp[6] == 1) && (mIsFlip == 0))) /* rotate 180 and  no flip || rotate 0 and  with flip */
    {
        if (disp[6] == 1) /*rotate 0 and  with flip */
        {
            nextrow = src_pitch * src_height * 3;
            pSrc = (src + nextrow - 6);
            deltaSrc = (src_width - src_pitch) * 3;
        }
        else /* rotate 180 and  no flip */
        {
            pSrc = (src + src_width * 3 - 6);
            deltaSrc = (src_width + src_pitch) * 3;
        }

        pDst = (uint16 *)dst;
        colpix = _mColPix + disp[3] - 1;

        for (row = src_height; row > 0; row--)
        {/* decrement index, _mColPix[.] is
            symmetric to increment index */
            rowpix = _mRowPix + src_width - 1;

            for (col = src_width; col > 0; col -= 2)
            { /* decrement index, _mRowPix[.] is
                symmetric to increment index */

                half1 = *((uint16*)(pSrc));  /* read 2 bytes, G0 R0 or G0 B0 */
                half2 = *((uint16*)(pSrc += 2)); /* read 2 bytes, R1 B0 or B1 R0 */

#if RGB_FORMAT
                R1 = (half1 >> 3) & 0x1F;
                G1 = (half1 >> 10);
                B1 = (half2 >> 3) & 0x1F;
                half1 = *((uint16*)(pSrc += 2)); /* read 2 bytes, B1 G1 */
                R0 = half2 >> 11;
                G0 = (half1 >> 2) & 0x3F;
                B0 = half1 >> 11;
#else
                B1 = (half1 >> 3) & 0x1F;
                G1 = (half1 >> 10);
                R1 = (half2 >> 3) & 0x1F;
                half1 = *((uint16*)(pSrc += 2)); /* read 2 bytes, R1 G1 */
                B0 = half2 >> 11;
                G0 = (half1 >> 2) & 0x3F;
                R0 = half1 >> 11;
#endif
                pSrc -= 10;

                temp = rowpix[0] + rowpix[-1];
                rowpix -= 2;
                rgb = (R0 << 6) | G0;
                rgb = (rgb << 5) | B0;
                tmp = (R1 << 6) | G1;
                tmp = (tmp << 5) | B1;

                *pDst++ = rgb;
                if (temp == 3)
                {
                    R0 = (R0 + R1 + 1) >> 1;
                    G0 = (G0 + G1 + 1) >> 1;
                    B0 = (B0 + B1 + 1) >> 1;
                    rgb = (R0 << 6) | G0;
                    rgb = (rgb << 5) | B0;
                    *pDst++ = rgb;
                }
                else if (temp == 4)
                {
                    R2 = (2 * R0 + R1 + 1) / 3;
                    R1 = (2 * R1 + R0 + 1) / 3;
                    G2 = (2 * G0 + G1 + 1) / 3;
                    G1 = (2 * G1 + G0 + 1) / 3;
                    rgb = (R2 << 6) | G2;
                    B2 = (2 * B0 + B1 + 1) / 3;
                    B1 = (2 * B1 + B0 + 1) / 3;
                    rgb = (rgb << 5) | B2;
                    *pDst++ = rgb;
                    rgb = (R1 << 6) | G1;
                    rgb = (rgb << 5) | B1;
                    *pDst++ = rgb;
                }
                else if (temp == 5)
                {
                    R2 = (3 * R0 + R1 + 2) / 4;
                    G2 = (3 * G0 + G1 + 2) / 4;
                    B2 = (3 * B0 + B1 + 2) / 4;
                    rgb = (R2 << 6) | G2;
                    rgb = (rgb << 5) | B2;
                    *pDst++ = rgb;
                    R2 = (R0 + R1 + 1) / 2;
                    G2 = (G0 + G1 + 1) / 2;
                    B2 = (B0 + B1 + 1) / 2;
                    rgb = (R2 << 6) | G2;
                    rgb = (rgb << 5) | B2;
                    *pDst++ = rgb;
                    R2 = (R0 + 3 * R1 + 2) / 4;
                    G2 = (G0 + 3 * G1 + 2) / 4;
                    B2 = (B0 + 3 * B1 + 2) / 4;
                    rgb = (R2 << 6) | G2;
                    rgb = (rgb << 5) | B2;
                    *pDst++ = rgb;
                }
                else if (temp == 6)
                {
                    R2 = (4 * R0 + R1 + 2) / 5;
                    G2 = (4 * G0 + G1 + 2) / 5;
                    B2 = (4 * B0 + B1 + 2) / 5;
                    rgb = (R2 << 6) | G2;
                    rgb = (rgb << 5) | B2;
                    *pDst++ = rgb;
                    R2 = (3 * R0 + 2 * R1 + 2) / 5;
                    G2 = (3 * G0 + 2 * G1 + 2) / 5;
                    B2 = (3 * B0 + 2 * B1 + 2) / 5;
                    rgb = (R2 << 6) | G2;
                    rgb = (rgb << 5) | B2;
                    *pDst++ = rgb;
                    R2 = (2 * R0 + 3 * R1 + 2) / 5;
                    G2 = (2 * G0 + 3 * G1 + 2) / 5;
                    B2 = (2 * B0 + 3 * B1 + 2) / 5;
                    rgb = (R2 << 6) | G2;
                    rgb = (rgb << 5) | B2;
                    *pDst++ = rgb;
                    R2 = (R0 + 4 * R1 + 2) / 5;
                    G2 = (G0 + 4 * G1 + 2) / 5;
                    B2 = (B0 + 4 * B1 + 2) / 5;
                    rgb = (R2 << 6) | G2;
                    rgb = (rgb << 5) | B2;
                    *pDst++ = rgb;
                }

                *pDst++ = tmp;
            }

            if (!(row&1)) /* even row */
            {
                // have to leave some space for row interpolation
                pDst -= dst_width;
                pTop = pDst;
                pDst += dst_pitch * (colpix[0] + colpix[-1] - 1);
                colpix--;
            }
            else /* odd row */ // do the row interpolation
            {
                temp = colpix[0] + colpix[1];
                pDst -= dst_width; // back to the beginning of bottom line

                if (temp != 2) // need to interpolate
                {
                    pLine = pDst - dst_pitch;
                    for (col = dst_width; col > 0; col--)
                    {
                        rgb = *pTop++;
                        tmp = *pDst++;
                        // now averager rgb and tmp
                        R0 = rgb >> 11;
                        R1 = tmp >> 11;
                        G0 = (rgb >> 5) & 0x3F;
                        G1 = (tmp >> 5) & 0x3F;
                        B0 = rgb & 0x1F;
                        B1 = tmp & 0x1F;
                        if (temp == 3)
                        {
                            R2 = (R0 + R1 + 1) >> 1;
                            G2 = (G0 + G1 + 1) >> 1;
                            B2 = (B0 + B1 + 1) >> 1;
                            rgb = (R2 << 6) | G2;
                            rgb = (rgb << 5) | B2;
                            *pLine++ = rgb;
                        }
                        else if (temp == 4)
                        {
                            R2 = (2 * R0 + R1 + 1) / 3;
                            R1 = (2 * R1 + R0 + 1) / 3;
                            G2 = (2 * G0 + G1 + 1) / 3;
                            G1 = (2 * G1 + G0 + 1) / 3;
                            rgb = (R2 << 6) | G2;
                            B2 = (2 * B0 + B1 + 1) / 3;
                            B1 = (2 * B1 + B0 + 1) / 3;
                            rgb = (rgb << 5) | B2;
                            pLine[-dst_pitch] = rgb; // line above
                            rgb = (R1 << 6) | G1;
                            rgb = (rgb << 5) | B1;
                            *pLine++ = rgb;
                        }
                        else if (temp == 5)
                        {
                            R2 = (3 * R0 + R1 + 2) / 4;
                            G2 = (3 * G0 + G1 + 2) / 4;
                            B2 = (3 * B0 + B1 + 2) / 4;
                            rgb = (R2 << 6) | G2;
                            rgb = (rgb << 5) | B2;
                            pLine[-(dst_pitch<<1)] = rgb;
                            R2 = (R0 + R1 + 1) / 2;
                            G2 = (G0 + G1 + 1) / 2;
                            B2 = (B0 + B1 + 1) / 2;
                            rgb = (R2 << 6) | G2;
                            rgb = (rgb << 5) | B2;
                            pLine[-dst_pitch] = rgb;
                            R2 = (R0 + 3 * R1 + 2) / 4;
                            G2 = (G0 + 3 * G1 + 2) / 4;
                            B2 = (B0 + 3 * B1 + 2) / 4;
                            rgb = (R2 << 6) | G2;
                            rgb = (rgb << 5) | B2;
                            *pLine++ = rgb;
                        }
                        else if (temp == 6)
                        {
                            R2 = (4 * R0 + R1 + 2) / 5;
                            G2 = (4 * G0 + G1 + 2) / 5;
                            B2 = (4 * B0 + B1 + 2) / 5;
                            rgb = (R2 << 6) | G2;
                            rgb = (rgb << 5) | B2;
                            pLine[-dst_pitch*3] = rgb;
                            R2 = (3 * R0 + 2 * R1 + 2) / 5;
                            G2 = (3 * G0 + 2 * G1 + 2) / 5;
                            B2 = (3 * B0 + 2 * B1 + 2) / 5;
                            rgb = (R2 << 6) | G2;
                            rgb = (rgb << 5) | B2;
                            pLine[-(dst_pitch<<1)] = rgb;
                            R2 = (2 * R0 + 3 * R1 + 2) / 5;
                            G2 = (2 * G0 + 3 * G1 + 2) / 5;
                            B2 = (2 * B0 + 3 * B1 + 2) / 5;
                            rgb = (R2 << 6) | G2;
                            rgb = (rgb << 5) | B2;
                            pLine[-dst_pitch] = rgb;
                            R2 = (R0 + 4 * R1 + 2) / 5;
                            G2 = (G0 + 4 * G1 + 2) / 5;
                            B2 = (B0 + 4 * B1 + 2) / 5;
                            rgb = (R2 << 6) | G2;
                            rgb = (rgb << 5) | B2;
                            *pLine++ = rgb;
                        }
                    }
                    pDst -= dst_width;
                }
                pDst += dst_pitch;
                colpix--;
            }

            pSrc += deltaSrc;
        }
    }
    else  /* rotate 180 and  with flip || no rotation ,no flip */
    {
        if (disp[6] == 1) /* rotate 180 and  with flip */
        {
            /* move the starting point to the bottom-left corner of the picture */
            deltaSrc = src_pitch * (src_height - 1);
            pSrc = src + deltaSrc * 3;
            deltaSrc = -(src_pitch + src_width) * 3;
        }
        else
        {   // only scale up, no rotation ,no flip
            deltaSrc    = (src_pitch - src_width) * 3;
            pSrc = src;
        }

        pDst = (uint16 *)dst;
        colpix = _mColPix + src_height - 1;

        for (row = src_height; row > 0; row--)
        {/* decrement index, _mColPix[.] is
            symmetric to increment index */
            rowpix = _mRowPix + src_width - 1;

            for (col = src_width; col > 0; col -= 2)
            { /* decrement index, _mRowPix[.] is
                symmetric to increment index */

                half1 = *((uint16*)(pSrc));  /* read 2 bytes, G0 R0 or G0 B0 */
                half2 = *((uint16*)(pSrc += 2)); /* read 2 bytes, R1 B0 or B1 R0 */

#if RGB_FORMAT
                R0 = (half1 >> 3) & 0x1F;
                G0 = (half1 >> 10);
                B0 = (half2 >> 3) & 0x1F;
                half1 = *((uint16*)(pSrc += 2)); /* read 2 bytes, B1 G1 */
                R1 = half2 >> 11;
                G1 = (half1 >> 2) & 0x3F;
                B1 = half1 >> 11;
#else
                B0 = (half1 >> 3) & 0x1F;
                G0 = (half1 >> 10);
                R0 = (half2 >> 3) & 0x1F;
                half1 = *((uint16*)(pSrc += 2)); /* read 2 bytes, R1 G1 */
                B1 = half2 >> 11;
                G1 = (half1 >> 2) & 0x3F;
                R1 = half1 >> 11;
#endif
                pSrc += 2;

                temp = rowpix[0] + rowpix[-1];
                rowpix -= 2;
                rgb = (R0 << 6) | G0;
                rgb = (rgb << 5) | B0;
                tmp = (R1 << 6) | G1;
                tmp = (tmp << 5) | B1;

                *pDst++ = rgb;
                if (temp == 3)
                {
                    R0 = (R0 + R1 + 1) >> 1;
                    G0 = (G0 + G1 + 1) >> 1;
                    B0 = (B0 + B1 + 1) >> 1;
                    rgb = (R0 << 6) | G0;
                    rgb = (rgb << 5) | B0;
                    *pDst++ = rgb;
                }
                else if (temp == 4)
                {
                    R2 = (2 * R0 + R1 + 1) / 3;
                    R1 = (2 * R1 + R0 + 1) / 3;
                    G2 = (2 * G0 + G1 + 1) / 3;
                    G1 = (2 * G1 + G0 + 1) / 3;
                    rgb = (R2 << 6) | G2;
                    B2 = (2 * B0 + B1 + 1) / 3;
                    B1 = (2 * B1 + B0 + 1) / 3;
                    rgb = (rgb << 5) | B2;
                    *pDst++ = rgb;
                    rgb = (R1 << 6) | G1;
                    rgb = (rgb << 5) | B1;
                    *pDst++ = rgb;
                }
                else if (temp == 5)
                {
                    R2 = (3 * R0 + R1 + 2) / 4;
                    G2 = (3 * G0 + G1 + 2) / 4;
                    B2 = (3 * B0 + B1 + 2) / 4;
                    rgb = (R2 << 6) | G2;
                    rgb = (rgb << 5) | B2;
                    *pDst++ = rgb;
                    R2 = (R0 + R1 + 1) / 2;
                    G2 = (G0 + G1 + 1) / 2;
                    B2 = (B0 + B1 + 1) / 2;
                    rgb = (R2 << 6) | G2;
                    rgb = (rgb << 5) | B2;
                    *pDst++ = rgb;
                    R2 = (R0 + 3 * R1 + 2) / 4;
                    G2 = (G0 + 3 * G1 + 2) / 4;
                    B2 = (B0 + 3 * B1 + 2) / 4;
                    rgb = (R2 << 6) | G2;
                    rgb = (rgb << 5) | B2;
                    *pDst++ = rgb;
                }
                else if (temp == 6)
                {
                    R2 = (4 * R0 + R1 + 2) / 5;
                    G2 = (4 * G0 + G1 + 2) / 5;
                    B2 = (4 * B0 + B1 + 2) / 5;
                    rgb = (R2 << 6) | G2;
                    rgb = (rgb << 5) | B2;
                    *pDst++ = rgb;
                    R2 = (3 * R0 + 2 * R1 + 2) / 5;
                    G2 = (3 * G0 + 2 * G1 + 2) / 5;
                    B2 = (3 * B0 + 2 * B1 + 2) / 5;
                    rgb = (R2 << 6) | G2;
                    rgb = (rgb << 5) | B2;
                    *pDst++ = rgb;
                    R2 = (2 * R0 + 3 * R1 + 2) / 5;
                    G2 = (2 * G0 + 3 * G1 + 2) / 5;
                    B2 = (2 * B0 + 3 * B1 + 2) / 5;
                    rgb = (R2 << 6) | G2;
                    rgb = (rgb << 5) | B2;
                    *pDst++ = rgb;
                    R2 = (R0 + 4 * R1 + 2) / 5;
                    G2 = (G0 + 4 * G1 + 2) / 5;
                    B2 = (B0 + 4 * B1 + 2) / 5;
                    rgb = (R2 << 6) | G2;
                    rgb = (rgb << 5) | B2;
                    *pDst++ = rgb;
                }

                *pDst++ = tmp;
            }

            if (!(row&1)) /* even row */
            {
                // have to leave some space for row interpolation
                pDst -= dst_width;
                pTop = pDst;
                pDst += dst_pitch * (colpix[0] + colpix[-1] - 1);
                colpix--;
            }
            else /* odd row */ // do the row interpolation
            {
                temp = colpix[0] + colpix[1];
                pDst -= dst_width; // back to the beginning of bottom line

                if (temp != 2) // need to interpolate
                {
                    pLine = pDst - dst_pitch;
                    for (col = dst_width; col > 0; col--)
                    {
                        rgb = *pTop++;
                        tmp = *pDst++;
                        // now averager rgb and tmp
                        R0 = rgb >> 11;
                        R1 = tmp >> 11;
                        G0 = (rgb >> 5) & 0x3F;
                        G1 = (tmp >> 5) & 0x3F;
                        B0 = rgb & 0x1F;
                        B1 = tmp & 0x1F;
                        if (temp == 3)
                        {
                            R2 = (R0 + R1 + 1) >> 1;
                            G2 = (G0 + G1 + 1) >> 1;
                            B2 = (B0 + B1 + 1) >> 1;
                            rgb = (R2 << 6) | G2;
                            rgb = (rgb << 5) | B2;
                            *pLine++ = rgb;
                        }
                        else if (temp == 4)
                        {
                            R2 = (2 * R0 + R1 + 1) / 3;
                            R1 = (2 * R1 + R0 + 1) / 3;
                            G2 = (2 * G0 + G1 + 1) / 3;
                            G1 = (2 * G1 + G0 + 1) / 3;
                            rgb = (R2 << 6) | G2;
                            B2 = (2 * B0 + B1 + 1) / 3;
                            B1 = (2 * B1 + B0 + 1) / 3;
                            rgb = (rgb << 5) | B2;
                            pLine[-dst_pitch] = rgb; // line above
                            rgb = (R1 << 6) | G1;
                            rgb = (rgb << 5) | B1;
                            *pLine++ = rgb;
                        }
                        else if (temp == 5)
                        {
                            R2 = (3 * R0 + R1 + 2) / 4;
                            G2 = (3 * G0 + G1 + 2) / 4;
                            B2 = (3 * B0 + B1 + 2) / 4;
                            rgb = (R2 << 6) | G2;
                            rgb = (rgb << 5) | B2;
                            pLine[-(dst_pitch<<1)] = rgb;
                            R2 = (R0 + R1 + 1) / 2;
                            G2 = (G0 + G1 + 1) / 2;
                            B2 = (B0 + B1 + 1) / 2;
                            rgb = (R2 << 6) | G2;
                            rgb = (rgb << 5) | B2;
                            pLine[-dst_pitch] = rgb;
                            R2 = (R0 + 3 * R1 + 2) / 4;
                            G2 = (G0 + 3 * G1 + 2) / 4;
                            B2 = (B0 + 3 * B1 + 2) / 4;
                            rgb = (R2 << 6) | G2;
                            rgb = (rgb << 5) | B2;
                            *pLine++ = rgb;
                        }
                        else if (temp == 6)
                        {
                            R2 = (4 * R0 + R1 + 2) / 5;
                            G2 = (4 * G0 + G1 + 2) / 5;
                            B2 = (4 * B0 + B1 + 2) / 5;
                            rgb = (R2 << 6) | G2;
                            rgb = (rgb << 5) | B2;
                            pLine[-dst_pitch*3] = rgb;
                            R2 = (3 * R0 + 2 * R1 + 2) / 5;
                            G2 = (3 * G0 + 2 * G1 + 2) / 5;
                            B2 = (3 * B0 + 2 * B1 + 2) / 5;
                            rgb = (R2 << 6) | G2;
                            rgb = (rgb << 5) | B2;
                            pLine[-(dst_pitch<<1)] = rgb;
                            R2 = (2 * R0 + 3 * R1 + 2) / 5;
                            G2 = (2 * G0 + 3 * G1 + 2) / 5;
                            B2 = (2 * B0 + 3 * B1 + 2) / 5;
                            rgb = (R2 << 6) | G2;
                            rgb = (rgb << 5) | B2;
                            pLine[-dst_pitch] = rgb;
                            R2 = (R0 + 4 * R1 + 2) / 5;
                            G2 = (G0 + 4 * G1 + 2) / 5;
                            B2 = (B0 + 4 * B1 + 2) / 5;
                            rgb = (R2 << 6) | G2;
                            rgb = (rgb << 5) | B2;
                            *pLine++ = rgb;
                        }
                    }
                    pDst -= dst_width;
                }
                pDst += dst_pitch;
                colpix--;
            }

            pSrc += deltaSrc;
        }
    }
    return 1;
}
#endif //CCSCALING

int32 CCRGB24toRGB16::zoomRotate(uint8 *src, uint8 *dst, DisplayProperties *disp)
{
    // To be implemented
    OSCL_UNUSED_ARG(src);
    OSCL_UNUSED_ARG(dst);
    OSCL_UNUSED_ARG(disp);
    return 1;
}



