📄 pixelbuffer.cpp
字号:
/* Copyright (C) 2006 Lucas Gomez All Rights Reserved.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
// INCLUDE FILES
#include "PixelBuffer.h"
#include "VncViewer.pan"
#include "LogWriter.h"
//LITERALS
// ============================ MEMBER FUNCTIONS ===============================
// -----------------------------------------------------------------------------
// CConn::ConstructL()
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CPixelBuffer::ConstructL()
{
SetPF(new CPixelFormat());
}
// -----------------------------------------------------------------------------
// CPixelBuffer::CPixelBuffer()
// C++ default constructor can NOT contain any code, that might leave.
// -----------------------------------------------------------------------------
//
CPixelBuffer::CPixelBuffer()
{
}
// ---------------------------------------------------------------------------
// CPixelBuffer::~CPixelBuffer()
// Destructor.
// ---------------------------------------------------------------------------
//
CPixelBuffer::~CPixelBuffer()
{
/*if(iFormat)
{
delete iFormat;
iFormat=NULL;
}*/
iData.Close();
}
void CPixelBuffer::SetPF(CPixelFormat* aPF)
{
if(aPF->GetBpp()!=8)
User::Leave(EVncViewerBppMustBe8);
if(iFormat!=aPF)
{
if(iFormat)
delete iFormat;
iFormat=aPF;
}
}
CPixelFormat* CPixelBuffer::GetPF()
{
return iFormat;
}
TInt CPixelBuffer::GetWidth()
{
return iWidth;
}
TInt CPixelBuffer::GetHeight()
{
return iHeight;
}
TInt CPixelBuffer::GetArea()
{
return iWidth*iHeight;
}
TInt CPixelBuffer::GetStride()
{
return iWidth;
}
void CPixelBuffer::FillRect(TInt aX,TInt aY,TInt aW,TInt aH,TInt aPix)
{
TInt bytesPerPixel=GetPF()->GetBpp()/8;
TInt bytesPerRow=bytesPerPixel*GetStride();
for(TInt ry=aY;ry<aY+aH;ry++)
{
for(TInt rx=aX;rx<aX+aW;rx++)
iData[ry*bytesPerRow+rx]=static_cast<TUint8>(aPix);
}
}
void CPixelBuffer::ImageRect(TInt aX,TInt aY,TInt aW,TInt aH,TDes8& aPix,TInt aOffset)
{
TInt bytesPerPixel=GetPF()->GetBpp()/8;
TInt bytesPerDestRow=bytesPerPixel*GetStride();
for(TInt j=0;j<aH;j++)
iData.MidTPtr((aY+j)*bytesPerDestRow+aX).Copy(aPix.Mid(aOffset+j*aW,aW));
}
void CPixelBuffer::CopyRect(TInt aX,TInt aY,TInt aW,TInt aH,TInt aSrcX,TInt aSrcY)
{
TInt dest=aX+aY*GetStride();
TInt src=aSrcX+aSrcY*GetStride();
TInt inc=GetStride();
if(aY>aSrcY)
{
src+=(aH-1)*inc;
dest+=(aH-1)*inc;
inc=-inc;
}
TInt destEnd=dest+aH*inc;
while(dest!=destEnd)
{
iData.MidTPtr(dest).Copy(iData.Mid(src,aW));
src+=inc;
dest+=inc;
}
}
void CPixelBuffer::MaskRect(TInt aX, TInt aY,TInt aW,TInt aH,TDes8& aPix,TDes8& aMask)
{
TInt maskBytesPerRow=(aW+7)/8;
TInt stride=GetStride();
for(TInt j=0;j<aH;j++)
{
TInt cy=aY+j;
if(cy>=0 && cy<iHeight)
{
for(TInt i=0;i<aW;i++)
{
TInt cx=aX+i;
if(cx>=0 && cx<iWidth)
{
TInt byte=j*maskBytesPerRow+i/8;
TInt bit=7-i%8;
if((aMask[byte]&(1<<bit))!=0)
{
iData[cy*stride+cx]=aPix[j*aW+i];
}
}
}
}
}
}
/**
* NewL.
* Two-phased constructor.
* Construct a CConn for the AVKON application aApp
* using two phase construction, and return a pointer
* to the created object.
* @return A pointer to the created instance of CConn.
*/
CManagedPixelBuffer* CManagedPixelBuffer::NewL()
{
CManagedPixelBuffer* self = CManagedPixelBuffer::NewLC();
CleanupStack::Pop(self);
return self;
}
/**
* NewLC.
* Two-phased constructor.
* Construct a CConn for the AVKON application aApp
* using two phase construction, and return a pointer
* to the created object.
* @return A pointer to the created instance of CConn.
*/
CManagedPixelBuffer* CManagedPixelBuffer::NewLC()
{
CManagedPixelBuffer* self = new (ELeave) CManagedPixelBuffer();
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
/**
* ~CPixelBuffer
* Virtual Destructor.
*/
CManagedPixelBuffer::~CManagedPixelBuffer()
{
}
/**
* CManagedPixelBuffer::.
* C++ default constructor.
*/
CManagedPixelBuffer::CManagedPixelBuffer() : CPixelBuffer()
{
}
/**
* ConstructL
* 2nd phase constructor.
*/
void CManagedPixelBuffer::ConstructL()
{
CPixelBuffer::ConstructL();
}
void CManagedPixelBuffer::SetSize(TInt aW,TInt aH)
{
iWidth=aW;
iHeight=aH;
CheckDataSize();
}
void CManagedPixelBuffer::SetPF(CPixelFormat* aPF)
{
CPixelBuffer::SetPF(aPF);
CheckDataSize();
}
TInt CManagedPixelBuffer::DataLen()
{
return GetArea()*(GetPF()->GetBpp()/8);
}
void CManagedPixelBuffer::CheckDataSize()
{
if(iData.Length()==0 || iData.Length()<DataLen())
iData.CreateMaxL(DataLen());
}
/**
* NewL.
* Two-phased constructor.
* Construct a CConn for the AVKON application aApp
* using two phase construction, and return a pointer
* to the created object.
* @return A pointer to the created instance of CConn.
*/
CPixelBufferImage* CPixelBufferImage::NewL(TInt aW,TInt aH)
{
CPixelBufferImage* self = CPixelBufferImage::NewLC(aW,aH);
CleanupStack::Pop(self);
return self;
}
/**
* NewLC.
* Two-phased constructor.
* Construct a CConn for the AVKON application aApp
* using two phase construction, and return a pointer
* to the created object.
* @return A pointer to the created instance of CConn.
*/
CPixelBufferImage* CPixelBufferImage::NewLC(TInt aW,TInt aH)
{
CPixelBufferImage* self = new (ELeave) CPixelBufferImage();
CleanupStack::PushL(self);
self->ConstructL(aW,aH);
return self;
}
/**
* ~CPixelBuffer
* Virtual Destructor.
*/
CPixelBufferImage::~CPixelBufferImage()
{
iRgb.Close();
if(iCM)
{
delete iCM;
iCM=NULL;
}
if(iImage)
{
delete iImage;
iImage=NULL;
}
/*if(iFormat)
{
delete iFormat;
iFormat=NULL;
}*/
}
/**
* CManagedPixelBuffer::.
* C++ default constructor.
*/
CPixelBufferImage::CPixelBufferImage() : CPixelBuffer()
{
}
/**
* ConstructL
* 2nd phase constructor.
*/
void CPixelBufferImage::ConstructL(TInt aW,TInt aH)
{
//CPixelBuffer::ConstructL();
SetPF(new CPixelFormat(8,8,EFalse,EFalse,0,0,0,0,0,0));
Resize(aW,aH);
// Fill the colour map with bgr233. This is only so that if the server
// doesn't set the colour map properly, at least we're likely to see
// something instead of a completely black screen.
iCM=CPalette::NewL(256);
for(TInt i=0;i<256;i++)
{
iRgb.AppendL(TRgb(((i&7)*255+3)/7,(((i>>3)&7)*255+3)/7,(((i>>6)&3)*255+1)/3));
iCM->SetEntry(i,iRgb[i]);
}
}
void CPixelBufferImage::Resize(TInt aW,TInt aH)
{
if(aW==GetWidth() && aH==GetHeight()) return;
TInt oldStrideBytes=GetStride()*(iFormat->GetBpp()/8);
TInt rowsToCopy=aH<GetHeight() ? aH : GetHeight();
TInt bytesPerRow=(aW<GetWidth() ? aW : GetWidth())*(iFormat->GetBpp()/8);
RBuf8 oldData;
oldData.CreateL(iData);
iWidth=aW;
iHeight=aH;
if(iImage)
delete iImage;
iImage=new (ELeave) CFbsBitmap();
User::LeaveIfError(iImage->Create(TSize(iWidth,iHeight),EColor256));
iData.Close();
iData.CreateMaxL(GetWidth()*GetHeight()*(iFormat->GetBpp()/8));
TInt newStrideBytes=GetStride()*(iFormat->GetBpp()/8);
for(TInt i=0;i<rowsToCopy;i++)
{
iData.MidTPtr(newStrideBytes*i).Copy(oldData.Mid(oldStrideBytes*i,bytesPerRow));
}
oldData.Close();
}
void CPixelBufferImage::Put(TInt aX,TInt aY,TInt aW,TInt aH,CWindowGc* aGraphics)
{
TBitmapUtil bitmapUtil(iImage);
bitmapUtil.Begin(TPoint(aX,aY));
for(TInt j=0;j<aH;j++)
{
for(TInt i=0;i<aW;i++)
{
bitmapUtil.SetPos(TPoint(aX+i,aY+j));
bitmapUtil.SetPixel(iCM->GetEntry(iData[GetWidth()*(aY+j)+aX+i]).Color256());
}
}
bitmapUtil.End();
}
void CPixelBufferImage::CopyRect(TInt aX,TInt aY,TInt aW,TInt aH,TInt aSrcX,TInt aSrcY)
{
CPixelBuffer::CopyRect(aX,aY,aW,aH,aSrcX,aSrcY);
TBitmapUtil bitmapUtil(iImage);
bitmapUtil.Begin(TPoint(aX,aY));
for(TInt j=0;j<aH;j++)
{
for(TInt i=0;i<aW;i++)
{
bitmapUtil.SetPos(TPoint(aX+i,aY+j));
bitmapUtil.SetPixel(iCM->GetEntry(iData[GetWidth()*(aY+j)+aX+i]).Color256());
}
}
bitmapUtil.End();
}
void CPixelBufferImage::SetColourMapEntries(TInt aFirstColour,TInt aNColours,RArray<TInt>& aRgbs)
{
for(TInt i=0;i<aNColours;i++)
{
iRgb[aFirstColour+i].SetRed(static_cast<TUint8>(aRgbs[i*3] >> 8));
iRgb[aFirstColour+i].SetGreen(static_cast<TUint8>(aRgbs[i*3+1] >> 8));
iRgb[aFirstColour+i].SetBlue(static_cast<TUint8>(aRgbs[i*3+2] >> 8));
}
}
void CPixelBufferImage::UpdateColourMap()
{
for(TInt i=0;i<iRgb.Count();i++)
{
iCM->SetEntry(i,iRgb[i]);
}
}
/**
* NewL.
* Two-phased constructor.
* Construct a CConn for the AVKON application aApp
* using two phase construction, and return a pointer
* to the created object.
* @return A pointer to the created instance of CConn.
*/
CCursor* CCursor::NewL()
{
CCursor* self = CCursor::NewLC();
CleanupStack::Pop(self);
return self;
}
/**
* NewLC.
* Two-phased constructor.
* Construct a CConn for the AVKON application aApp
* using two phase construction, and return a pointer
* to the created object.
* @return A pointer to the created instance of CConn.
*/
CCursor* CCursor::NewLC()
{
CCursor* self = new (ELeave) CCursor();
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
/**
* ~CPixelBuffer
* Virtual Destructor.
*/
CCursor::~CCursor()
{
iMask.Close();
}
/**
* CManagedPixelBuffer::.
* C++ default constructor.
*/
CCursor::CCursor() : CManagedPixelBuffer()
{
}
/**
* ConstructL
* 2nd phase constructor.
*/
void CCursor::ConstructL()
{
CManagedPixelBuffer::ConstructL();
}
void CCursor::SetSize(TInt aW,TInt aH)
{
CManagedPixelBuffer::SetSize(aW,aH);
if(iMask.Length()==0 || iMask.Length()<MaskLen())
iMask.CreateMaxL(MaskLen());
}
TInt CCursor::MaskLen()
{
return (GetWidth()+7)/8*GetHeight();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -