blob: 86e7cca5c93ffa1609ab39caa0f47b04e1c1fea8 [file] [log] [blame]
/* ------------------------------------------------------------------
* 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;
}