📄 imageconversion.cpp
字号:
/*
* ImageConversion.cpp
*
* Copyright 2005 - 2007, Antony Pranata
* http://www.antonypranata.com
*
* Project: Screenshot for Symbian OS.
*
* This program 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 program 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 program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <ImageConversion.h>
#include "ScreenShot.h" // used for MIME type
// CONSTANTS
#define KDisplayMode EColor16M
// --------------------------------------------------------------------------
// CImageDecoder
// --------------------------------------------------------------------------
CImageDecoder* CImageDecoder::FileNewL(RFs& /*aFs*/, const TDesC& aFileName)
{
CImageDecoder* self = new (ELeave) CImageDecoder();
CleanupStack::PushL(self);
self->ConstructL(aFileName);
CleanupStack::Pop();
return self;
}
CImageDecoder::~CImageDecoder()
{
delete iUtility;
delete iFileName;
delete iActiveScheduler;
}
void CImageDecoder::OpenOnly(TInt aFrameNumber)
{
iRequestStatus = 0;
iDestBitmap = 0;
iDestMaskBitmap = 0;
iFrameNumber = aFrameNumber;
iDecodeStatus = EFileOpening;
iUtility->OpenL(*iFileName);
// This will create a netsted loop. Needed because we want to have
// synchronous call here. So this function should return after the image
// has been opened.
//
// CAUTION: Use it very carefully!!! Do not create another nested loop
// when calling this function. It might lead to uncertain condition
// because there are two nested loops and we cannot guarantee that
// Start() and Stop() are called symetrically.
iActiveScheduler = new (ELeave) CActiveSchedulerWait();
iActiveScheduler->Start();
}
void CImageDecoder::Convert(TRequestStatus* aRequestStatus, CFbsBitmap& aDestination,
TInt aFrameNumber)
{
iRequestStatus = aRequestStatus;
iDestBitmap = &aDestination;
iDestMaskBitmap = 0;
iFrameNumber = aFrameNumber;
*iRequestStatus = KRequestPending;
iDecodeStatus = EFileOpening;
iUtility->OpenL(*iFileName);
}
void CImageDecoder::Convert(TRequestStatus* aRequestStatus, CFbsBitmap& aDestination,
CFbsBitmap& aDestinationMask, TInt aFrameNumber)
{
iRequestStatus = aRequestStatus;
iDestBitmap = &aDestination;
iDestMaskBitmap = &aDestinationMask;
iFrameNumber = aFrameNumber;
*iRequestStatus = KRequestPending;
iDecodeStatus = EFileOpening;
iUtility->OpenL(*iFileName);
}
void CImageDecoder::Cancel()
{
iUtility->Cancel();
}
TFrameInfo CImageDecoder::FrameInfo(TInt aFrameNumber) const
{
__ASSERT_DEBUG(iUtility, User::Invariant());
TFrameInfo frameInfo;
iUtility->FrameInfo(aFrameNumber, frameInfo);
return frameInfo;
}
void CImageDecoder::MiuoCreateComplete(TInt /*aError*/)
{
}
void CImageDecoder::MiuoOpenComplete(TInt aError)
{
// If further frames to display, loop round to display them
if (KErrNone == aError)
{
TFrameInfo frameInfo;
TInt err = KErrNone;
// Opens the bitmap.
if (EFileOpening == iDecodeStatus)
{
// If iDestBitmap is not 0, then we have to convert it.
// Otherwise we don't need to do anything (the users just
// want to open an image and get frame info).
if (iDestBitmap)
{
iUtility->FrameInfo(iFrameNumber, frameInfo);
err = iDestBitmap->Create(
frameInfo.iOverallSizeInPixels, KDisplayMode);
if (KErrNone == err)
{
iUtility->ConvertL(*iDestBitmap, iFrameNumber);
}
iDecodeStatus = EBitmapConverting;
}
else if (iActiveScheduler)
{
iActiveScheduler->AsyncStop();
delete iActiveScheduler;
iActiveScheduler = 0;
}
}
// Opens the bitmap mask.
else if (EBitmapConverting == iDecodeStatus)
{
iUtility->FrameInfo(iFrameNumber + 1, frameInfo);
err = iDestMaskBitmap->Create(
frameInfo.iOverallSizeInPixels, KDisplayMode);
if (KErrNone == err)
{
iUtility->ConvertL(*iDestMaskBitmap, iFrameNumber + 1);
}
iDecodeStatus = EBitmapMaskConverting;
}
if (KErrNone != err)
{
User::RequestComplete(iRequestStatus, aError);
}
}
else
{
User::RequestComplete(iRequestStatus, aError);
}
}
void CImageDecoder::MiuoConvertComplete(TInt aError)
{
// If there is mask bitmap, then open it too.
if ((iDestMaskBitmap) && (EBitmapConverting == iDecodeStatus)
&& (iUtility->FrameCount() > iFrameNumber + 1))
{
MiuoOpenComplete(aError);
}
else
{
User::RequestComplete(iRequestStatus, aError);
}
}
CImageDecoder::CImageDecoder()
{
}
void CImageDecoder::ConstructL(const TDesC& aFileName)
{
iUtility = CMdaImageFileToBitmapUtility::NewL(*this, 0);
iFileName = aFileName.AllocL();
}
// --------------------------------------------------------------------------
// CImageEncoder
// --------------------------------------------------------------------------
// The aFrameData is actually a dummy one. We don't use it here.
// It is there just to make is compatible with S60.
CImageEncoder* CImageEncoder::FileNewL(RFs& /*aFs*/, const TDesC& aFileName,
const TDesC8& aMimeType)
{
CImageEncoder* self = new (ELeave) CImageEncoder();
CleanupStack::PushL(self);
self->ConstructL(aFileName, aMimeType);
CleanupStack::Pop();
return self;
}
CImageEncoder::~CImageEncoder()
{
delete iUtility;
delete iFileName;
delete iMimeType;
}
void CImageEncoder::Convert(TRequestStatus* aRequestStatus, CFbsBitmap& aDestination,
CFrameImageData* aFrameImageData)
{
iRequestStatus = aRequestStatus;
iDestBitmap = &aDestination;
*iRequestStatus = KRequestPending;
// Reads the image file based on its MIME type.
if (iMimeType->Compare(KMimeTypeJpg) == 0)
{
if (aFrameImageData)
{
iJpgClipFormat.iSettings.iQualityFactor =
aFrameImageData->iQualityFactor;
}
iUtility->CreateL(*iFileName, &iJpgClipFormat, &iJpgCodec,
&iJpgCodec);
}
else if (iMimeType->Compare(KMimeTypeBmp) == 0)
{
if (aFrameImageData)
{
if (aFrameImageData->iBitsPerPixel == 8)
{
iUtility->CreateL(*iFileName, &iBmpClipFormat, &iBmp8bppCodec,
&iBmp8bppCodec);
}
else
{
iUtility->CreateL(*iFileName, &iBmpClipFormat, &iBmpCodec,
&iBmpCodec);
}
}
else
{
iUtility->CreateL(*iFileName, &iBmpClipFormat, &iBmpCodec,
&iBmpCodec);
}
}
else if (iMimeType->Compare(KMimeTypeMbm) == 0)
{
if (aFrameImageData->iBitsPerPixel == 8)
{
iMbmClipFormat.iDisplayMode = EColor256;
}
else
{
iMbmClipFormat.iDisplayMode = EColor16M;
}
iUtility->CreateL(*iFileName, &iMbmClipFormat, 0, 0);
}
else
{
User::Invariant(); // panic if image format is not known
}
}
void CImageEncoder::Cancel()
{
iUtility->Cancel();
}
void CImageEncoder::MiuoCreateComplete(TInt aError)
{
if (KErrNone == aError)
{
//Now the bitmap file has been created, write the bitmap to it
TRAPD(err, iUtility->ConvertL(*iDestBitmap));
if (err != KErrNone)
{
User::RequestComplete(iRequestStatus, aError);
}
}
else
{
User::RequestComplete(iRequestStatus, aError);
}
}
void CImageEncoder::MiuoOpenComplete(TInt /*aError*/)
{
}
void CImageEncoder::MiuoConvertComplete(TInt aError)
{
User::RequestComplete(iRequestStatus, aError);
}
CImageEncoder::CImageEncoder()
{
}
void CImageEncoder::ConstructL(const TDesC& aFileName,
const TDesC8& aMimeType)
{
iUtility = CMdaImageBitmapToFileUtility::NewL(*this, 0);
iFileName = aFileName.AllocL();
iMimeType = aMimeType.AllocL();
}
// End of File
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -