diff -r 000000000000 -r 3da2a79470a7 testtoolsconn/stat/desktop/source/lib/src/cstatdataformatconverter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testtoolsconn/stat/desktop/source/lib/src/cstatdataformatconverter.cpp Mon Mar 08 15:04:18 2010 +0800 @@ -0,0 +1,673 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + + +#include "stdafx.h" +#include "afxpriv.h" +#include "CSTATDataFormatConverter.h" + +//------------------------------------------------------------------------------- +//standard functions for new variant class +CSTATDataFormatConverter::CSTATDataFormatConverter(CSTATLogFile *pLog) +: bWriteToFile(true) +{ + vt = VT_BLOB; + + BLOB* pBody = new BLOB; + byref = pBody; + pBody->pBlobData = m_index = new BYTE [16]; //16 is the default buffer size + pBody->cbSize = m_bufsize = 16; + + // set up logging + pLogFile = pLog; + + // reset bitmap structures + memset(&iPbmHeader, 0xff, sizeof(iPbmHeader)); + memset(&fileheader, 0xff, sizeof(fileheader)); + memset(&bmpHeader, 0xff, sizeof(bmpHeader)); + pPbmBits = NULL; + bmpBits = NULL; + lDataSize = 0; +} + +//------------------------------------------------------------------------------- + +//Destructor +CSTATDataFormatConverter::~CSTATDataFormatConverter() +{ + BLOB* pBody = (BLOB*)byref; + if (pBody) + { + if (pBody->pBlobData) + delete [] pBody->pBlobData; + + delete pBody; + } + + if (pPbmBits) + { + delete [] pPbmBits; + pPbmBits = NULL; + } + + if (bmpBits) + { + delete [] bmpBits; + bmpBits = NULL; + } +} + +//---------------------------------------------------------------------------- + +bool CSTATDataFormatConverter::ConvertStringToUnicode(CString& data) +{ + // clear the existing buffer + ((BLOB*)byref)->cbSize = 0; + + // length IN BYTES of the UNICODE result (not the TCHAR input) + UINT len = (data.GetLength() + 1) * 2; + + // check that the buffer can hold the contents -- otherwise enlarge + EnsureBufSize( len ); + + // convert the input string to unicode + USES_CONVERSION; + LPWSTR wstr = T2W(data.GetBuffer(0)); + + // copy data into the buffer and set the size + memcpy( m_index, wstr, len); + ((BLOB*)byref)->cbSize = len; + + // done + return true; +} + +//---------------------------------------------------------------------------- + +void CSTATDataFormatConverter::EnsureBufSize(int size) +{ + if (size > m_bufsize) + { + BLOB* pBody = (BLOB*)byref; + BYTE* newbuf = new BYTE [size]; + delete[] pBody->pBlobData; + m_index = pBody->pBlobData = newbuf; + m_bufsize = size; + } +} + +//---------------------------------------------------------------------------- +//Converts from .mbm to .bmp +int +CSTATDataFormatConverter::ConvertScreenShot(CString &mbmdirectory, CString &destdir) +{ + CFileFind imagefinder; + CString searchpattern = mbmdirectory; + if (searchpattern.Right(1) != _T('\\')) + searchpattern += _T("\\"); + searchpattern += "*.mbm"; + + // there will only ever be one file to be converted at a time + if (imagefinder.FindFile(searchpattern, 0)) + { + imagefinder.FindNextFile(); + + // get the source filename (in quotes) + CString imagefilename = _T("\""); + imagefilename += imagefinder.GetFilePath(); + imagefilename += _T("\""); + + // get the destination folder (in quotes) + CString newimagefilename = _T("\""); + newimagefilename += destdir; + + // add a backslash if we need one + if (newimagefilename.Right(1) != _T("\\")) + newimagefilename += _T("\\"); + + // add the filename + newimagefilename += imagefinder.GetFileName(); + newimagefilename.Replace(_T(".mbm"), _T(".bmp")); + newimagefilename += _T("\""); + imagefinder.Close(); + + // remove dest file if it already exists + if(imagefinder.FindFile(newimagefilename, 0)) + { + imagefinder.Close(); + DeleteFile(newimagefilename); + } + + imagefilename.Remove('\"'); + newimagefilename.Remove('\"'); + + if (bWriteToFile) + { + pLogFile->Set(CONVERTINGIMAGE, imagefilename.GetBuffer(0)); + pLogFile->Set(TO, newimagefilename.GetBuffer(0)); + } + else + pLogFile->Set(READINGIMAGE, imagefilename.GetBuffer(0)); + + // convert the bitmap + int errorcode = LoadBitmap(imagefilename); + if (errorcode != ITS_OK) + return pLogFile->Set(E_BITMAPLOADFAILED, pLogFile->Text(errorcode)); + + if ((errorcode = SaveBitmap(newimagefilename)) != ITS_OK) + return pLogFile->Set(E_BITMAPSAVEFAILED, pLogFile->Text(errorcode)); + + DeleteFile(imagefilename); //delete original .mbm image + + // success + mbmdirectory = newimagefilename; + + // log a message that desktop STAT can use to display bitmap + pLogFile->Set(SCREENSHOT_CONVERSION_OK, mbmdirectory, false, true); + + return ITS_OK; + } + + return pLogFile->Set(E_NOIMAGESTOCONVERT, searchpattern); +} + +//---------------------------------------------------------------------------- +int CSTATDataFormatConverter::LoadBitmap(CString &file) +{ + // reset structures + memset(&iPbmHeader, 0xff, sizeof(iPbmHeader)); + if (pPbmBits) + { + delete [] pPbmBits; + pPbmBits = NULL; + } + + // open file + HANDLE infile; + if (INVALID_HANDLE_VALUE != (infile = CreateFile(file, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + 0))) + { + long int iBuffer; + DWORD dwBytesRead = 0; + + // read the header to ensure it is a valid file + if (!ReadFile(infile, (LPVOID *)&iBuffer, 4, &dwBytesRead, NULL) || + dwBytesRead != 4 || iBuffer != KWriteOnceFileStoreUid) + { + CloseHandle(infile); + return E_BADFORMAT; + } + + if (!ReadFile(infile, (LPVOID *)&iBuffer, 4, &dwBytesRead, NULL) || + dwBytesRead != 4 || iBuffer != KMultiBitmapFileImageUid) + { + CloseHandle(infile); + return E_BADFORMAT; + } + + if (!ReadFile(infile, (LPVOID *)&iBuffer, 4, &dwBytesRead, NULL) || + dwBytesRead != 4 || iBuffer != 0) + { + CloseHandle(infile); + return E_BADFORMAT; + } + + if (!ReadFile(infile, (LPVOID *)&iBuffer, 4, &dwBytesRead, NULL) || + dwBytesRead != 4 || iBuffer != KMultiBitmapFileImageChecksum) + { + CloseHandle(infile); + return E_BADFORMAT; + } + + if (!ReadFile(infile, (LPVOID *)&iBuffer, 4, &dwBytesRead, NULL) || + dwBytesRead != 4) + { + CloseHandle(infile); + return E_BADFORMAT; + } + + // go back to offset from the beginning + if (SetFilePointer(infile, iBuffer, NULL, FILE_BEGIN) == 0xFFFFFFFF) + { + CloseHandle(infile); + return E_BADFORMAT; + } + + // read the number of sources (in our case it will always be one) + if (!ReadFile(infile, (LPVOID *)&iBuffer, 4, &dwBytesRead, NULL) || + dwBytesRead != 4) + { + CloseHandle(infile); + return E_BADFORMAT; + } + + // read offset from the beginning of this bitmap + if (!ReadFile(infile, (LPVOID *)&iBuffer, 4, &dwBytesRead, NULL) || + dwBytesRead != 4) + { + CloseHandle(infile); + return E_BADFORMAT; + } + + // go back to offset from the beginning + if (SetFilePointer(infile, iBuffer, NULL, FILE_BEGIN) == 0xFFFFFFFF) + { + CloseHandle(infile); + return E_BADFORMAT; + } + + // read in the header + DWORD dwSize = sizeof(SEpocBitmapHeader); + if (!ReadFile(infile, (LPVOID *)&iPbmHeader, dwSize, &dwBytesRead, NULL) || dwBytesRead != dwSize) + { + CloseHandle(infile); + return E_BADFORMAT; + } + + dwSize = iPbmHeader.iBitmapSize - iPbmHeader.iStructSize; + + // now read in the bitmap matrix + pPbmBits = new char[dwSize]; + if (pPbmBits) + { + memset(pPbmBits, 0xff, dwSize); + if (!ReadFile(infile, (LPVOID *)pPbmBits, dwSize, &dwBytesRead, NULL) || dwBytesRead != dwSize) + { + CloseHandle(infile); + return E_BADFORMAT; + } + + if (iPbmHeader.iCompression != ENoBitmapCompression) + { + int byteWidth = ByteWidth(iPbmHeader.iWidthInPixels, iPbmHeader.iBitsPerPixel); + int expandedsize = byteWidth * iPbmHeader.iHeightInPixels; + char* newbits = new char[expandedsize]; + if (newbits) + { + memset(newbits,0xff,expandedsize); + int ret = ITS_OK; + + switch (iPbmHeader.iCompression) + { + case EByteRLECompression: + ret = ExpandByteRLEData(newbits,expandedsize,pPbmBits, dwSize); + break; + case ETwelveBitRLECompression: + ret = ExpandTwelveBitRLEData(newbits,expandedsize,pPbmBits, dwSize); + break; + case ESixteenBitRLECompression: + ret = ExpandSixteenBitRLEData(newbits,expandedsize,pPbmBits, dwSize); + break; + case ETwentyFourBitRLECompression: + ret = ExpandTwentyFourBitRLEData(newbits,expandedsize,pPbmBits, dwSize); + break; + default: + delete [] pPbmBits; + return E_BADCOMPRESSION; + break; + } + + delete [] pPbmBits; + pPbmBits = newbits; + iPbmHeader.iCompression = ENoBitmapCompression; + iPbmHeader.iBitmapSize += expandedsize - dwSize; + } + else + { + CloseHandle(infile); + return E_OUTOFMEM; + } + } + + CloseHandle(infile); + } + else + { + CloseHandle(infile); + return E_OUTOFMEM; + } + } + else + return E_FILE_OPEN_READ_FAILED; + + return ITS_OK; +} + +bool +CSTATDataFormatConverter::ExpandByteRLEData(char* aDest,int aDestSize,char* aSrce,int aSrceSize) +{ + char* srcelimit=aSrce+aSrceSize; + char* destlimit=aDest+aDestSize; + while(aSrce=0) + { + *aDest++=value; + count--; + } + } + } + if (aSrce!=srcelimit || aDest!=destlimit) + return false; + + return true; +} + +bool +CSTATDataFormatConverter::ExpandTwelveBitRLEData(char* aDest,int aDestSizeInBytes,char* aSrce,int aSrceSizeInBytes) +{ + unsigned short* srcePtr = (unsigned short*)aSrce; + unsigned short* destPtr = (unsigned short*)aDest; + unsigned short* srcePtrLimit = srcePtr + (aSrceSizeInBytes / 2); + unsigned short* destPtrLimit = destPtr + (aDestSizeInBytes / 2); + + while (srcePtr < srcePtrLimit && destPtr < destPtrLimit) + { + unsigned short value = *srcePtr++; + int runLength = (value >> 12) + 1; + value &= 0x0fff; + + for (;runLength > 0;runLength--) + *destPtr++ = value; + } + + if (srcePtr != srcePtrLimit || destPtr != destPtrLimit) + return false; + + return true; +} + +bool +CSTATDataFormatConverter::ExpandSixteenBitRLEData(char* aDest,int aDestSizeInBytes,char* aSrce,int aSrceSizeInBytes) +{ + char* srcePtrLimit = aSrce + aSrceSizeInBytes; + unsigned short* destPtr = (unsigned short*)aDest; + unsigned short* destPtrLimit = destPtr + (aDestSizeInBytes / 2); + + while (aSrce < srcePtrLimit && destPtr < destPtrLimit) + { + int runLength = *aSrce++; + + if (runLength >= 0) + { + unsigned short value = *((unsigned short*)(aSrce)); + aSrce += 2; + for (runLength++; runLength > 0; runLength--) + *destPtr++ = value; + } + else + { + runLength = -runLength; + int byteLength = runLength * 2; + memcpy(destPtr,aSrce,byteLength); + aSrce += byteLength; + destPtr += runLength; + } + } + + if (aSrce != srcePtrLimit || destPtr != destPtrLimit) + return false; + + return true; +} + +bool +CSTATDataFormatConverter::ExpandTwentyFourBitRLEData(char* aDest,int aDestSizeInBytes,char* aSrce,int aSrceSizeInBytes) +{ + char* srcePtrLimit = aSrce + aSrceSizeInBytes; + char* destPtrLimit = aDest + aDestSizeInBytes; + + while (aSrce < srcePtrLimit && aDest < destPtrLimit) + { + int runLength = *aSrce++; + + if (runLength >= 0) + { + char component1 = *aSrce++; + char component2 = *aSrce++; + char component3 = *aSrce++; + for (runLength++; runLength > 0; runLength--) + { + *aDest++ = component1; + *aDest++ = component2; + *aDest++ = component3; + } + } + else + { + runLength = -runLength; + int byteLength = runLength * 3; + memcpy(aDest,aSrce,byteLength); + aSrce += byteLength; + aDest += byteLength; + } + } + + if (aSrce != srcePtrLimit || aDest != destPtrLimit) + return false; + + return true; +} + +int +CSTATDataFormatConverter::SaveBitmap(CString &newfilename) +{ + // reset structures + memset(&fileheader, 0xff, sizeof(fileheader)); + memset(&bmpHeader, 0xff, sizeof(bmpHeader)); + if (bmpBits) + { + delete [] bmpBits; + bmpBits = NULL; + } + lDataSize = 0; + + // copy header info into BMP structures + bmpHeader.biSize = sizeof(TBitmapInfoHeader); + bmpHeader.biWidth = iPbmHeader.iWidthInPixels; + bmpHeader.biHeight = iPbmHeader.iHeightInPixels; + bmpHeader.biPlanes = 1; + bmpHeader.biBitCount = 24; + bmpHeader.biCompression = 0; + bmpHeader.biSizeImage = 0; + bmpHeader.biXPelsPerMeter = 0; + bmpHeader.biYPelsPerMeter = 0; + bmpHeader.biClrUsed = 0; + bmpHeader.biClrImportant = 0; + + long byteWidth = ((bmpHeader.biWidth * 3) + 3) & ~3; + lDataSize = bmpHeader.biHeight * byteWidth; + + fileheader.bfType = 'B'+('M'<<8); + fileheader.bfSize = sizeof(TBitmapFileHeader)+sizeof(TBitmapInfoHeader) + lDataSize; + fileheader.bfReserved1 = 0; + fileheader.bfReserved2 = 0; + fileheader.bfOffBits = sizeof(TBitmapFileHeader)+sizeof(TBitmapInfoHeader); + + // copy BMP data + bmpBits = new char[lDataSize]; + if (!bmpBits) + return E_OUTOFMEM; + + memset(bmpBits,0xff,lDataSize); + + for(long y=0;y>= (aXCoord&7); + return TRgb::Gray2(col & 1); + case 2: + col = pPbmBits[yOffset + (aXCoord / 4)]; + col = (unsigned char)(col>>(2*(aXCoord%4))); + return TRgb::Gray4(col & 3); + case 4: + col = pPbmBits[yOffset + (aXCoord / 2)]; + if (aXCoord & 1) + col >>= 4; + col &= 0xf; + if (iPbmHeader.iColor==EColorBitmap) + return TRgb::Color16(col); + else + return TRgb::Gray16(col); + case 8: + col=pPbmBits[yOffset + aXCoord]; + if (iPbmHeader.iColor==EColorBitmap) + return TRgb::Color256(col); + else + return TRgb::Gray256(col); + case 12: + case 16: + { + unsigned short* shortPtr = (unsigned short*)&pPbmBits[yOffset + (aXCoord * 2)]; + if (iPbmHeader.iBitsPerPixel == 12) + return TRgb::Color4K(*shortPtr); + else + return TRgb::Color64K(*shortPtr); + } + case 24: + { + char* pixelPtr = pPbmBits + yOffset + (aXCoord * 3); + TRgb pixelColor; + pixelColor.iBlue = *pixelPtr++; + pixelColor.iGreen = *pixelPtr++; + pixelColor.iRed = *pixelPtr; + return pixelColor; + } + default: + return TRgb(0); + } +} + +int +CSTATDataFormatConverter::ByteWidth(int aPixelWidth,int aBitsPerPixel) +{ + int wordWidth = 0; + + switch (aBitsPerPixel) + { + case 1: + wordWidth = (aPixelWidth + 31) / 32; + break; + case 2: + wordWidth = (aPixelWidth + 15) / 16; + break; + case 4: + wordWidth = (aPixelWidth + 7) / 8; + break; + case 8: + wordWidth = (aPixelWidth + 3) / 4; + break; + case 12: + case 16: + wordWidth = (aPixelWidth + 1) / 2; + break; + case 24: + wordWidth = (((aPixelWidth * 3) + 11) / 12) * 3; + break; + default: + break; + }; + + return wordWidth * 4; +} +