--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/group/bld.inf Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,28 @@
+/*
+* Copyright (c) 2006 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: Project specification for Imaging Extensions projects.
+*
+*/
+
+#include <platform_paths.hrh>
+
+#include "../imagingext_plat/group/bld.inf"
+#include "../imagingext_pub/group/bld.inf"
+
+#include "../imageadaptationextensions/group/bld.inf"
+#include "../imagingmodules/group/bld.inf"
+
+PRJ_EXPORTS
+
+// End of File
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imageadaptationextensions/data/ImageAdaptationExtensions_stub.pkg Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,32 @@
+;
+; Copyright (c) 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:
+;
+; Languages
+&EN
+
+; Header
+#{"Image Adaptation Extensions"}, (0x10204BF0), 1, 0, 0, TYPE=SA
+
+; Localised Vendor name
+%{"Nokia"}
+
+; Unique Vendor name
+:"Nokia"
+
+; Files
+; -----
+
+""-"z:\sys\bin\IclExtJpegApi.dll"
+
Binary file imageadaptationextensions/data/ImageAdaptationExtensions_stub.sis has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imageadaptationextensions/group/bld.inf Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,31 @@
+/*
+* Copyright (c) 2006 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:
+*
+*/
+
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_EXPORTS
+../data/ImageAdaptationExtensions_stub.sis /epoc32/data/z/system/install/ImageAdaptationExtensions_stub.sis
+
+PRJ_MMPFILES
+#include "../iclextjpegapi/group/bld.inf"
+
+
+
+// End of File
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imageadaptationextensions/iclextjpegapi/BWINS/IclExtJpegApiU.DEF Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,68 @@
+EXPORTS
+ ??1CExtJpegDecoder@@UAE@XZ @ 1 NONAME ; CExtJpegDecoder::~CExtJpegDecoder(void)
+ ??1CExtJpegEncoder@@UAE@XZ @ 2 NONAME ; CExtJpegEncoder::~CExtJpegEncoder(void)
+ ??1CVisualFrame@@UAE@XZ @ 3 NONAME ; CVisualFrame::~CVisualFrame(void)
+ ?CapabilitiesL@CExtJpegDecoder@@QAEHXZ @ 4 NONAME ; int CExtJpegDecoder::CapabilitiesL(void)
+ ?CapabilitiesL@CExtJpegEncoder@@QAEHXZ @ 5 NONAME ; int CExtJpegEncoder::CapabilitiesL(void)
+ ?ContinueConvertL@CExtJpegDecoder@@QAEXPAVTRequestStatus@@PBVCVisualFrame@@AAHH@Z @ 6 NONAME ; void CExtJpegDecoder::ContinueConvertL(class TRequestStatus *, class CVisualFrame const *, int &, int)
+ ?ContinueConvertL@CExtJpegEncoder@@QAEXPAVTRequestStatus@@PBVCVisualFrame@@AAH@Z @ 7 NONAME ; void CExtJpegEncoder::ContinueConvertL(class TRequestStatus *, class CVisualFrame const *, int &)
+ ?ConvertL@CExtJpegDecoder@@QAEXPAVTRequestStatus@@PBVCVisualFrame@@AAHH@Z @ 8 NONAME ; void CExtJpegDecoder::ConvertL(class TRequestStatus *, class CVisualFrame const *, int &, int)
+ ?ConvertL@CExtJpegEncoder@@QAEXPAVTRequestStatus@@PBVCVisualFrame@@AAHPBVCFrameImageData@@@Z @ 9 NONAME ; void CExtJpegEncoder::ConvertL(class TRequestStatus *, class CVisualFrame const *, int &, class CFrameImageData const *)
+ ?DataChunkL@CVisualFrame@@QBEABVRChunk@@XZ @ 10 NONAME ; class RChunk const & CVisualFrame::DataChunkL(void) const
+ ?DataContainer@CVisualFrame@@QBE?AW4TDataContainer@1@XZ @ 11 NONAME ; enum CVisualFrame::TDataContainer CVisualFrame::DataContainer(void) const
+ ?DataNewL@CExtJpegDecoder@@SAPAV1@AAVRFs@@ABVTDesC8@@1W4TOptions@CImageDecoder@@@Z @ 12 NONAME ; class CExtJpegDecoder * CExtJpegDecoder::DataNewL(class RFs &, class TDesC8 const &, class TDesC8 const &, enum CImageDecoder::TOptions)
+ ?DataNewL@CExtJpegDecoder@@SAPAV1@AAVRFs@@ABVTDesC8@@W4TOptions@CImageDecoder@@VTUid@@33@Z @ 13 NONAME ; class CExtJpegDecoder * CExtJpegDecoder::DataNewL(class RFs &, class TDesC8 const &, enum CImageDecoder::TOptions, class TUid, class TUid, class TUid)
+ ?DataNewL@CExtJpegDecoder@@SAPAV1@AAVRFs@@PBVCVisualFrame@@ABVTDesC8@@W4TOptions@CImageDecoder@@@Z @ 14 NONAME ; class CExtJpegDecoder * CExtJpegDecoder::DataNewL(class RFs &, class CVisualFrame const *, class TDesC8 const &, enum CImageDecoder::TOptions)
+ ?DataNewL@CExtJpegDecoder@@SAPAV1@AAVRFs@@PBVCVisualFrame@@W4TOptions@CImageDecoder@@VTUid@@33@Z @ 15 NONAME ; class CExtJpegDecoder * CExtJpegDecoder::DataNewL(class RFs &, class CVisualFrame const *, enum CImageDecoder::TOptions, class TUid, class TUid, class TUid)
+ ?DataNewL@CExtJpegDecoder@@SAPAV1@W4TDecoderType@1@AAVRFs@@ABVTDesC8@@W4TOptions@CImageDecoder@@@Z @ 16 NONAME ; class CExtJpegDecoder * CExtJpegDecoder::DataNewL(enum CExtJpegDecoder::TDecoderType, class RFs &, class TDesC8 const &, enum CImageDecoder::TOptions)
+ ?DataNewL@CExtJpegDecoder@@SAPAV1@W4TDecoderType@1@AAVRFs@@PBVCVisualFrame@@W4TOptions@CImageDecoder@@@Z @ 17 NONAME ; class CExtJpegDecoder * CExtJpegDecoder::DataNewL(enum CExtJpegDecoder::TDecoderType, class RFs &, class CVisualFrame const *, enum CImageDecoder::TOptions)
+ ?DataNewL@CExtJpegEncoder@@SAPAV1@AAPAVHBufC8@@ABVTDesC8@@W4TOptions@CImageEncoder@@@Z @ 18 NONAME ; class CExtJpegEncoder * CExtJpegEncoder::DataNewL(class HBufC8 * &, class TDesC8 const &, enum CImageEncoder::TOptions)
+ ?DataNewL@CExtJpegEncoder@@SAPAV1@AAPAVHBufC8@@W4TOptions@CImageEncoder@@VTUid@@22@Z @ 19 NONAME ; class CExtJpegEncoder * CExtJpegEncoder::DataNewL(class HBufC8 * &, enum CImageEncoder::TOptions, class TUid, class TUid, class TUid)
+ ?DataNewL@CExtJpegEncoder@@SAPAV1@PBVCVisualFrame@@ABVTDesC8@@W4TOptions@CImageEncoder@@@Z @ 20 NONAME ; class CExtJpegEncoder * CExtJpegEncoder::DataNewL(class CVisualFrame const *, class TDesC8 const &, enum CImageEncoder::TOptions)
+ ?DataNewL@CExtJpegEncoder@@SAPAV1@PBVCVisualFrame@@W4TOptions@CImageEncoder@@VTUid@@22@Z @ 21 NONAME ; class CExtJpegEncoder * CExtJpegEncoder::DataNewL(class CVisualFrame const *, enum CImageEncoder::TOptions, class TUid, class TUid, class TUid)
+ ?DataNewL@CExtJpegEncoder@@SAPAV1@W4TEncoderType@1@AAPAVHBufC8@@W4TOptions@CImageEncoder@@@Z @ 22 NONAME ; class CExtJpegEncoder * CExtJpegEncoder::DataNewL(enum CExtJpegEncoder::TEncoderType, class HBufC8 * &, enum CImageEncoder::TOptions)
+ ?DataNewL@CExtJpegEncoder@@SAPAV1@W4TEncoderType@1@PBVCVisualFrame@@W4TOptions@CImageEncoder@@@Z @ 23 NONAME ; class CExtJpegEncoder * CExtJpegEncoder::DataNewL(enum CExtJpegEncoder::TEncoderType, class CVisualFrame const *, enum CImageEncoder::TOptions)
+ ?DataOffset@CVisualFrame@@QBEHXZ @ 24 NONAME ; int CVisualFrame::DataOffset(void) const
+ ?DataPtrL@CVisualFrame@@QBE?AVTPtr8@@XZ @ 25 NONAME ; class TPtr8 CVisualFrame::DataPtrL(void) const
+ ?Dimension@CVisualFrame@@QBE?AVTSize@@XZ @ 26 NONAME ; class TSize CVisualFrame::Dimension(void) const
+ ?FileNewL@CExtJpegDecoder@@SAPAV1@AAVRFs@@ABVTDesC16@@ABVTDesC8@@W4TOptions@CImageDecoder@@@Z @ 27 NONAME ; class CExtJpegDecoder * CExtJpegDecoder::FileNewL(class RFs &, class TDesC16 const &, class TDesC8 const &, enum CImageDecoder::TOptions)
+ ?FileNewL@CExtJpegDecoder@@SAPAV1@AAVRFs@@ABVTDesC16@@W4TOptions@CImageDecoder@@VTUid@@33@Z @ 28 NONAME ; class CExtJpegDecoder * CExtJpegDecoder::FileNewL(class RFs &, class TDesC16 const &, enum CImageDecoder::TOptions, class TUid, class TUid, class TUid)
+ ?FileNewL@CExtJpegDecoder@@SAPAV1@W4TDecoderType@1@AAVRFs@@ABVTDesC16@@W4TOptions@CImageDecoder@@@Z @ 29 NONAME ; class CExtJpegDecoder * CExtJpegDecoder::FileNewL(enum CExtJpegDecoder::TDecoderType, class RFs &, class TDesC16 const &, enum CImageDecoder::TOptions)
+ ?FileNewL@CExtJpegEncoder@@SAPAV1@AAVRFs@@ABVTDesC16@@ABVTDesC8@@W4TOptions@CImageEncoder@@@Z @ 30 NONAME ; class CExtJpegEncoder * CExtJpegEncoder::FileNewL(class RFs &, class TDesC16 const &, class TDesC8 const &, enum CImageEncoder::TOptions)
+ ?FileNewL@CExtJpegEncoder@@SAPAV1@AAVRFs@@ABVTDesC16@@W4TOptions@CImageEncoder@@VTUid@@33@Z @ 31 NONAME ; class CExtJpegEncoder * CExtJpegEncoder::FileNewL(class RFs &, class TDesC16 const &, enum CImageEncoder::TOptions, class TUid, class TUid, class TUid)
+ ?FileNewL@CExtJpegEncoder@@SAPAV1@W4TEncoderType@1@AAVRFs@@ABVTDesC16@@W4TOptions@CImageEncoder@@@Z @ 32 NONAME ; class CExtJpegEncoder * CExtJpegEncoder::FileNewL(enum CExtJpegEncoder::TEncoderType, class RFs &, class TDesC16 const &, enum CImageEncoder::TOptions)
+ ?FrameFormat@CVisualFrame@@QBEHXZ @ 33 NONAME ; int CVisualFrame::FrameFormat(void) const
+ ?FrameLayout@CVisualFrame@@QBEABVTFrameLayout@1@XZ @ 34 NONAME ; class CVisualFrame::TFrameLayout const & CVisualFrame::FrameLayout(void) const
+ ?GetDestinationDataSizeL@CExtJpegEncoder@@QAEHXZ @ 35 NONAME ; int CExtJpegEncoder::GetDestinationDataSizeL(void)
+ ?MaxSize@CVisualFrame@@QBEHXZ @ 36 NONAME ; int CVisualFrame::MaxSize(void) const
+ ?NewL@CExtJpegDecoder@@SAPAV1@XZ @ 37 NONAME ; class CExtJpegDecoder * CExtJpegDecoder::NewL(void)
+ ?NewL@CExtJpegEncoder@@SAPAV1@XZ @ 38 NONAME ; class CExtJpegEncoder * CExtJpegEncoder::NewL(void)
+ ?NewL@CVisualFrame@@SAPAV1@AAVRChunk@@HHABVTSize@@HABVTFrameLayout@1@@Z @ 39 NONAME ; class CVisualFrame * CVisualFrame::NewL(class RChunk &, int, int, class TSize const &, int, class CVisualFrame::TFrameLayout const &)
+ ?NewL@CVisualFrame@@SAPAV1@AAVRChunk@@HHHABVTSize@@H@Z @ 40 NONAME ; class CVisualFrame * CVisualFrame::NewL(class RChunk &, int, int, int, class TSize const &, int)
+ ?NewL@CVisualFrame@@SAPAV1@AAVTDes8@@ABVTSize@@H@Z @ 41 NONAME ; class CVisualFrame * CVisualFrame::NewL(class TDes8 &, class TSize const &, int)
+ ?NewL@CVisualFrame@@SAPAV1@AAVTDes8@@ABVTSize@@HABVTFrameLayout@1@@Z @ 42 NONAME ; class CVisualFrame * CVisualFrame::NewL(class TDes8 &, class TSize const &, int, class CVisualFrame::TFrameLayout const &)
+ ?ProvideNewDestDataL@CExtJpegEncoder@@QAEXPBVCVisualFrame@@@Z @ 43 NONAME ; void CExtJpegEncoder::ProvideNewDestDataL(class CVisualFrame const *)
+ ?SetBitmapOverlayL@CExtJpegEncoder@@QAEXABVCFbsBitmap@@IVTPoint@@@Z @ 44 NONAME ; void CExtJpegEncoder::SetBitmapOverlayL(class CFbsBitmap const &, unsigned int, class TPoint)
+ ?SetBitmapReplaceL@CExtJpegEncoder@@QAEXABVCFbsBitmap@@VTPoint@@@Z @ 45 NONAME ; void CExtJpegEncoder::SetBitmapReplaceL(class CFbsBitmap const &, class TPoint)
+ ?SetCroppingL@CExtJpegDecoder@@QAEXVTRect@@@Z @ 46 NONAME ; void CExtJpegDecoder::SetCroppingL(class TRect)
+ ?SetDctDecodingL@CExtJpegDecoder@@QAEXXZ @ 47 NONAME ; void CExtJpegDecoder::SetDctDecodingL(void)
+ ?SetDctEncodingL@CExtJpegEncoder@@QAEXXZ @ 48 NONAME ; void CExtJpegEncoder::SetDctEncodingL(void)
+ ?SetFlippingL@CExtJpegDecoder@@QAEXXZ @ 49 NONAME ; void CExtJpegDecoder::SetFlippingL(void)
+ ?SetImageReplaceL@CExtJpegEncoder@@QAEXPBVCVisualFrame@@VTPoint@@@Z @ 50 NONAME ; void CExtJpegEncoder::SetImageReplaceL(class CVisualFrame const *, class TPoint)
+ ?SetLosslessFlippingL@CExtJpegEncoder@@QAEXXZ @ 51 NONAME ; void CExtJpegEncoder::SetLosslessFlippingL(void)
+ ?SetLosslessMirroringL@CExtJpegEncoder@@QAEXXZ @ 52 NONAME ; void CExtJpegEncoder::SetLosslessMirroringL(void)
+ ?SetLosslessRotationL@CExtJpegEncoder@@QAEXH@Z @ 53 NONAME ; void CExtJpegEncoder::SetLosslessRotationL(int)
+ ?SetMirroringL@CExtJpegDecoder@@QAEXXZ @ 54 NONAME ; void CExtJpegDecoder::SetMirroringL(void)
+ ?SetRotationL@CExtJpegDecoder@@QAEXH@Z @ 55 NONAME ; void CExtJpegDecoder::SetRotationL(int)
+ ?SetSizeL@CVisualFrame@@QAEXH@Z @ 56 NONAME ; void CVisualFrame::SetSizeL(int)
+ ?SetStreamingL@CExtJpegDecoder@@QAEXAAVTSize@@@Z @ 57 NONAME ; void CExtJpegDecoder::SetStreamingL(class TSize &)
+ ?SetStreamingL@CExtJpegEncoder@@QAEXAAVTSize@@PBVCFrameImageData@@@Z @ 58 NONAME ; void CExtJpegEncoder::SetStreamingL(class TSize &, class CFrameImageData const *)
+ ?Size@CVisualFrame@@QBEHXZ @ 59 NONAME ; int CVisualFrame::Size(void) const
+ ?SupportedFormatsL@CExtJpegDecoder@@QAEHXZ @ 60 NONAME ; int CExtJpegDecoder::SupportedFormatsL(void)
+ ?SupportedFormatsL@CExtJpegEncoder@@QAEHXZ @ 61 NONAME ; int CExtJpegEncoder::SupportedFormatsL(void)
+ ?GetImageFrameL@CVisualFrame@@QAEPAVCImageFrame@@XZ @ 62 NONAME ; class CImageFrame * CVisualFrame::GetImageFrameL(void)
+ ?NewL@CVisualFrame@@SAPAV1@PBVCImageFrame@@@Z @ 63 NONAME ; class CVisualFrame * CVisualFrame::NewL(class CImageFrame const *)
+ ?ContinueConvert@CExtJpegDecoder@@UAEXPAVTRequestStatus@@@Z @ 64 NONAME ; void CExtJpegDecoder::ContinueConvert(class TRequestStatus *)
+ ?Convert@CExtJpegDecoder@@UAEXPAVTRequestStatus@@AAVCFbsBitmap@@1H@Z @ 65 NONAME ; void CExtJpegDecoder::Convert(class TRequestStatus *, class CFbsBitmap &, class CFbsBitmap &, int)
+ ?Convert@CExtJpegDecoder@@UAEXPAVTRequestStatus@@AAVCFbsBitmap@@H@Z @ 66 NONAME ; void CExtJpegDecoder::Convert(class TRequestStatus *, class CFbsBitmap &, int)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imageadaptationextensions/iclextjpegapi/EABI/IclExtJpegApiU.DEF Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,82 @@
+EXPORTS
+ _ZN12CVisualFrame14GetImageFrameLEv @ 1 NONAME
+ _ZN12CVisualFrame4NewLEPK11CImageFrame @ 2 NONAME
+ _ZN12CVisualFrame4NewLER5TDes8RK5TSizei @ 3 NONAME
+ _ZN12CVisualFrame4NewLER5TDes8RK5TSizeiRKNS_12TFrameLayoutE @ 4 NONAME
+ _ZN12CVisualFrame4NewLER6RChunkiiRK5TSizeiRKNS_12TFrameLayoutE @ 5 NONAME
+ _ZN12CVisualFrame4NewLER6RChunkiiiRK5TSizei @ 6 NONAME
+ _ZN12CVisualFrame8SetSizeLEi @ 7 NONAME
+ _ZN12CVisualFrameD0Ev @ 8 NONAME
+ _ZN12CVisualFrameD1Ev @ 9 NONAME
+ _ZN12CVisualFrameD2Ev @ 10 NONAME
+ _ZN15CExtJpegDecoder12SetCroppingLE5TRect @ 11 NONAME
+ _ZN15CExtJpegDecoder12SetFlippingLEv @ 12 NONAME
+ _ZN15CExtJpegDecoder12SetRotationLEi @ 13 NONAME
+ _ZN15CExtJpegDecoder13CapabilitiesLEv @ 14 NONAME
+ _ZN15CExtJpegDecoder13SetMirroringLEv @ 15 NONAME
+ _ZN15CExtJpegDecoder13SetStreamingLER5TSize @ 16 NONAME
+ _ZN15CExtJpegDecoder15SetDctDecodingLEv @ 17 NONAME
+ _ZN15CExtJpegDecoder16ContinueConvertLEP14TRequestStatusPK12CVisualFrameRii @ 18 NONAME
+ _ZN15CExtJpegDecoder17SupportedFormatsLEv @ 19 NONAME
+ _ZN15CExtJpegDecoder4NewLEv @ 20 NONAME
+ _ZN15CExtJpegDecoder8ConvertLEP14TRequestStatusPK12CVisualFrameRii @ 21 NONAME
+ _ZN15CExtJpegDecoder8DataNewLENS_12TDecoderTypeER3RFsPK12CVisualFrameN13CImageDecoder8TOptionsE @ 22 NONAME
+ _ZN15CExtJpegDecoder8DataNewLENS_12TDecoderTypeER3RFsRK6TDesC8N13CImageDecoder8TOptionsE @ 23 NONAME
+ _ZN15CExtJpegDecoder8DataNewLER3RFsPK12CVisualFrameN13CImageDecoder8TOptionsE4TUidS7_S7_ @ 24 NONAME
+ _ZN15CExtJpegDecoder8DataNewLER3RFsPK12CVisualFrameRK6TDesC8N13CImageDecoder8TOptionsE @ 25 NONAME
+ _ZN15CExtJpegDecoder8DataNewLER3RFsRK6TDesC8N13CImageDecoder8TOptionsE4TUidS7_S7_ @ 26 NONAME
+ _ZN15CExtJpegDecoder8DataNewLER3RFsRK6TDesC8S4_N13CImageDecoder8TOptionsE @ 27 NONAME
+ _ZN15CExtJpegDecoder8FileNewLENS_12TDecoderTypeER3RFsRK7TDesC16N13CImageDecoder8TOptionsE @ 28 NONAME
+ _ZN15CExtJpegDecoder8FileNewLER3RFsRK7TDesC16N13CImageDecoder8TOptionsE4TUidS7_S7_ @ 29 NONAME
+ _ZN15CExtJpegDecoder8FileNewLER3RFsRK7TDesC16RK6TDesC8N13CImageDecoder8TOptionsE @ 30 NONAME
+ _ZN15CExtJpegDecoderD0Ev @ 31 NONAME
+ _ZN15CExtJpegDecoderD1Ev @ 32 NONAME
+ _ZN15CExtJpegDecoderD2Ev @ 33 NONAME
+ _ZN15CExtJpegEncoder13CapabilitiesLEv @ 34 NONAME
+ _ZN15CExtJpegEncoder13SetStreamingLER5TSizePK15CFrameImageData @ 35 NONAME
+ _ZN15CExtJpegEncoder15SetDctEncodingLEv @ 36 NONAME
+ _ZN15CExtJpegEncoder16ContinueConvertLEP14TRequestStatusPK12CVisualFrameRi @ 37 NONAME
+ _ZN15CExtJpegEncoder16SetImageReplaceLEPK12CVisualFrame6TPoint @ 38 NONAME
+ _ZN15CExtJpegEncoder17SetBitmapOverlayLERK10CFbsBitmapj6TPoint @ 39 NONAME
+ _ZN15CExtJpegEncoder17SetBitmapReplaceLERK10CFbsBitmap6TPoint @ 40 NONAME
+ _ZN15CExtJpegEncoder17SupportedFormatsLEv @ 41 NONAME
+ _ZN15CExtJpegEncoder19ProvideNewDestDataLEPK12CVisualFrame @ 42 NONAME
+ _ZN15CExtJpegEncoder20SetLosslessFlippingLEv @ 43 NONAME
+ _ZN15CExtJpegEncoder20SetLosslessRotationLEi @ 44 NONAME
+ _ZN15CExtJpegEncoder21SetLosslessMirroringLEv @ 45 NONAME
+ _ZN15CExtJpegEncoder23GetDestinationDataSizeLEv @ 46 NONAME
+ _ZN15CExtJpegEncoder4NewLEv @ 47 NONAME
+ _ZN15CExtJpegEncoder8ConvertLEP14TRequestStatusPK12CVisualFrameRiPK15CFrameImageData @ 48 NONAME
+ _ZN15CExtJpegEncoder8DataNewLENS_12TEncoderTypeEPK12CVisualFrameN13CImageEncoder8TOptionsE @ 49 NONAME
+ _ZN15CExtJpegEncoder8DataNewLENS_12TEncoderTypeERP6HBufC8N13CImageEncoder8TOptionsE @ 50 NONAME
+ _ZN15CExtJpegEncoder8DataNewLEPK12CVisualFrameN13CImageEncoder8TOptionsE4TUidS5_S5_ @ 51 NONAME
+ _ZN15CExtJpegEncoder8DataNewLEPK12CVisualFrameRK6TDesC8N13CImageEncoder8TOptionsE @ 52 NONAME
+ _ZN15CExtJpegEncoder8DataNewLERP6HBufC8N13CImageEncoder8TOptionsE4TUidS5_S5_ @ 53 NONAME
+ _ZN15CExtJpegEncoder8DataNewLERP6HBufC8RK6TDesC8N13CImageEncoder8TOptionsE @ 54 NONAME
+ _ZN15CExtJpegEncoder8FileNewLENS_12TEncoderTypeER3RFsRK7TDesC16N13CImageEncoder8TOptionsE @ 55 NONAME
+ _ZN15CExtJpegEncoder8FileNewLER3RFsRK7TDesC16N13CImageEncoder8TOptionsE4TUidS7_S7_ @ 56 NONAME
+ _ZN15CExtJpegEncoder8FileNewLER3RFsRK7TDesC16RK6TDesC8N13CImageEncoder8TOptionsE @ 57 NONAME
+ _ZN15CExtJpegEncoderD0Ev @ 58 NONAME
+ _ZN15CExtJpegEncoderD1Ev @ 59 NONAME
+ _ZN15CExtJpegEncoderD2Ev @ 60 NONAME
+ _ZNK12CVisualFrame10DataChunkLEv @ 61 NONAME
+ _ZNK12CVisualFrame10DataOffsetEv @ 62 NONAME
+ _ZNK12CVisualFrame11FrameFormatEv @ 63 NONAME
+ _ZNK12CVisualFrame11FrameLayoutEv @ 64 NONAME
+ _ZNK12CVisualFrame13DataContainerEv @ 65 NONAME
+ _ZNK12CVisualFrame4SizeEv @ 66 NONAME
+ _ZNK12CVisualFrame7MaxSizeEv @ 67 NONAME
+ _ZNK12CVisualFrame8DataPtrLEv @ 68 NONAME
+ _ZNK12CVisualFrame9DimensionEv @ 69 NONAME
+ _ZTI12CVisualFrame @ 70 NONAME ; #<TI>#
+ _ZTI15CExtJpegDecoder @ 71 NONAME ; #<TI>#
+ _ZTI15CExtJpegEncoder @ 72 NONAME ; #<TI>#
+ _ZTI16CVisualFrameImpl @ 73 NONAME ; #<TI>#
+ _ZTV12CVisualFrame @ 74 NONAME ; #<VT>#
+ _ZTV15CExtJpegDecoder @ 75 NONAME ; #<VT>#
+ _ZTV15CExtJpegEncoder @ 76 NONAME ; #<VT>#
+ _ZTV16CVisualFrameImpl @ 77 NONAME ; #<VT>#
+ _ZN15CExtJpegDecoder15ContinueConvertEP14TRequestStatus @ 78 NONAME
+ _ZN15CExtJpegDecoder7ConvertEP14TRequestStatusR10CFbsBitmapS3_i @ 79 NONAME
+ _ZN15CExtJpegDecoder7ConvertEP14TRequestStatusR10CFbsBitmapi @ 80 NONAME
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imageadaptationextensions/iclextjpegapi/group/IclExtJpegApi.mmp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,42 @@
+/*
+* Copyright (c) 2006 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: Project specification file for IclExtJpegApi.
+*
+*/
+
+#include <icl/icl_uids.hrh>
+#include <platform_paths.hrh>
+
+TARGET IclExtJpegApi.dll
+CAPABILITY CAP_GENERAL_DLL
+targettype DLL
+
+UID 0x1000008D 0x10204BF0
+VENDORID VID_DEFAULT
+
+SOURCEPATH ../src
+SOURCE IclExtJpegApi.cpp
+SOURCE IclExtJpegApiFrameImplV2.cpp
+
+USERINCLUDE ../inc
+OS_LAYER_SYSTEMINCLUDE
+SYSTEMINCLUDE /epoc32/include/ecom
+SYSTEMINCLUDE /epoc32/include/icl
+
+LIBRARY euser.lib
+LIBRARY ImageConversion.lib
+LIBRARY ecom.lib
+LIBRARY Jpegimageframeplugin.lib
+
+// End of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imageadaptationextensions/iclextjpegapi/group/bld.inf Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,29 @@
+/*
+* Copyright (c) 2005, 2006 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: Build information file for Extended ICL API.
+*
+*/
+
+#include <platform_paths.hrh>
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_EXPORTS
+../rom/IclExtJpegApi.iby CORE_OS_LAYER_IBY_EXPORT_PATH(IclExtJpegApi.iby)
+
+PRJ_MMPFILES
+IclExtJpegApi.mmp
+
+// End of File
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imageadaptationextensions/iclextjpegapi/inc/IclExtJpegApiConst.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2006 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: Definition of constants for IclExtJpegApi
+*
+*/
+
+#ifndef _ICLEXTJPEGAPICONST_
+#define _ICLEXTJPEGAPICONST_
+
+//----------------------------------------------------------------------------
+// Common const definitions:
+//----------------------------------------------------------------------------
+_LIT8( KJpgMimeType,"image/jpeg" );
+_LIT( KJpgFileExt,".jpg" );
+
+const TInt KMinSwVersion = 64;
+const TInt KMinHwVersion = 0;
+const TInt KMaxSwVersion = 127;
+const TInt KMaxHwVersion = 63;
+
+//----------------------------------------------------------------------------
+// V2 specific variations:
+//----------------------------------------------------------------------------
+
+const TUid KUidExtIclImageFrameFormat = { 0x11111111 };
+
+//----------------------------------------------------------------------------
+// Initial version specific variations:
+//----------------------------------------------------------------------------
+
+#endif // _ICLEXTJPEGAPICONST_
+
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imageadaptationextensions/iclextjpegapi/inc/IclExtJpegApiFrameImpl.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,276 @@
+/*
+* Copyright (c) 2006 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: Definition of TFrameFormatExt and CVisualFrameImpl
+*
+*/
+
+#ifndef _ICLEXTJPEGAPIFRAMEIMPL_
+#define _ICLEXTJPEGAPIFRAMEIMPL_
+
+#include <icl/icl_propertyuids.h>
+#include "IclExtJpegApiConst.h"
+
+class CVisualFrame::TFrameLayout;
+
+#include "imageframe.h"
+
+/**
+* TFrameFormatExt
+* @lib IclExtJpegApi.lib
+* @since 3.2
+*/
+class TFrameFormatExt : public TFrameFormatBase
+ {
+ public:
+
+ /**
+ * C++ default constructor.
+ */
+ TFrameFormatExt( TInt aFormatCode ) :
+ TFrameFormatBase( KUidExtIclImageFrameFormat ),
+ iFormatCode( aFormatCode )
+ {
+ Constructor();
+ };
+
+ /**
+ * Duplicate
+ * @since 3.2
+ * @return TFrameFormatExt
+ */
+ TFrameFormatBase* DuplicateL() const
+ {
+ return new ( ELeave ) TFrameFormatExt( iFormatCode );
+ };
+
+ /**
+ * Colour space
+ * @since 3.2
+ * @return TUid
+ */
+ TUid ColourSpace() const;
+
+ /**
+ * Sampling
+ * @since 3.2
+ * @return TUid
+ */
+ TUid Sampling() const;
+
+ /**
+ * Format code
+ * @since 3.2
+ * @return TInt
+ */
+ TInt FormatCode() const;
+
+ /**
+ * Set colour space
+ * @since 3.2
+ * @param aColourSpace
+ * @return void
+ */
+ void SetColourSpace( TUid aColourSpace );
+
+
+ protected:
+
+ /**
+ * constructor.
+ */
+ void Constructor();
+
+ protected: // Data
+
+ // The image frame colour space
+ TUid iColourSpace;
+ // The frame sampling
+ TUid iSampling;
+ // The image frame format code which uniquely identifies all other parameters.
+ TInt iFormatCode;
+
+ };
+
+
+/**
+* CVisualFrameImpl
+* @lib IclExtJpegApi.lib
+* @since 3.2
+*/
+class CVisualFrameImpl : public CImageFrame
+ {
+ public:
+
+ /**
+ * Two-phased constructor.
+ * @since 3.2
+ * @param aBuffer A descriptor reference to buffer containing the image data.
+ * @param aDimension The dimensions of the corresponding image data.
+ * @param aFrameFormat The frame format of the corresponding image data.
+ */
+ static CVisualFrameImpl* NewL(
+ TDes8& aBuffer,
+ const TSize& aDimension,
+ TInt aFrameFormat );
+
+ /**
+ * Two-phased constructor.
+ * @param aChunk An RChunk reference to buffer containing the image data.
+ * @param aSize The amount of image data in bytes.
+ * @param amaxSize The maximum size of the memory reserved in the chunk.
+ * @param aDataOffset The offset value specifying the location of the image
+ * data in the chunk.
+ * @param aDimension The dimensions of the corresponding image data.
+ * @param aFrameFormat The frame format of the corresponding image data.
+ */
+ static CVisualFrameImpl* NewL(
+ RChunk& aChunk,
+ TInt aSize,
+ TInt aMaxSize,
+ TInt aDataOffset,
+ const TSize& aDimension,
+ TInt aFrameFormat );
+ /**
+ * Two-phased constructor.
+ * @param aBuffer A descriptor reference to buffer containing the image data.
+ * @param aDimension The dimensions of the corresponding image data.
+ * @param aFrameLayout The layout of the image color components.
+ */
+ static CVisualFrameImpl* NewL(
+ TDes8& aBuffer,
+ const TSize& aDimension,
+ TInt aFrameFormat,
+ const CVisualFrame::TFrameLayout& aFrameLayout );
+
+ /**
+ * Two-phased constructor.
+ * @param aChunk An RChunk reference to buffer containing the image data.
+ * @param aSize The amount of image data in bytes.
+ * @param aMaxSize The maximum size of the memory reserved in the chunk for
+ * the image data.
+ * @param aDimension The dimensions of the corresponding image data.
+ * @param aFrameFormat The frame format of the corresponding image data.
+ * @param aFrameLayout The layout of the image color components. TFrameLayout
+ * contains the scan line lengths and offsets for each component
+ * in planar YUV case
+ */
+ static CVisualFrameImpl* NewL(
+ RChunk& aChunk,
+ TInt aSize,
+ TInt aMaxSize,
+ const TSize& aDimension,
+ TInt aFrameFormat,
+ const CVisualFrame::TFrameLayout& aFrameLayout );
+
+ static CVisualFrameImpl* NewL( const CImageFrame* aImageFrame );
+
+ /**
+ * Get image frame
+ * @since 3.2
+ * @return CImageFrame
+ */
+ CImageFrame* GetImageFrameL();
+
+ /**
+ * Returns a constant reference to the chunk containing
+ * the image data, if exists.
+ * @since 3.2
+ * @return RChunk
+ */
+ const RChunk& DataChunkL() const;
+
+ /**
+ * Returns a descriptor pointer to the image data location, if exists
+ * @since 3.2
+ * @return TPtr8
+ */
+ TPtr8 DataPtrL() const;
+
+ /**
+ * Returns the dimensions of the image.
+ * @since 3.2
+ * @return TSize
+ */
+ TSize Dimension() const;
+
+ /**
+ * Return the image data format.
+ * @since 3.2
+ * @return TInt
+ */
+ TInt FrameFormat2() const;
+
+ /**
+ * Returns the offset of the image data for non-planar,
+ * single-component or compressed images.
+ * @since 3.2
+ * @return TInt
+ */
+ TInt DataOffset() const;
+
+ /**
+ * Returns the amount of stored image data in bytes.
+ * @since 3.2
+ * @return TInt
+ */
+ TInt Size() const;
+
+ /**
+ * Sets the amount of image data to the given value.
+ * Should be called when the image data amount is modified explicitly.
+ * @since 3.2
+ * @param
+ * @return void
+ */
+ void SetSizeL( TInt aSize );
+
+ /**
+ * Returns the maximum size of the memory space reserved for image data
+ * @since 3.2
+ * @return TInt
+ */
+ TInt MaxSize() const;
+
+ /**
+ * Returns the storage type of the image data.
+ * @since 3.2
+ * @return TInt
+ */
+ TInt DataContainer() const;
+
+ /**
+ * Returns the layout of the image data for planar compressed images.
+ * @since 3.2
+ * @param
+ * @return CVisualFrame::TFrameLayout
+ */
+ const CVisualFrame::TFrameLayout& FrameLayout2() const;
+
+ /**
+ * Destructor.
+ */
+ virtual ~CVisualFrameImpl();
+
+ private: // Data
+
+ CVisualFrame::TFrameLayout iFrameLayout2;
+
+ TInt iSize;
+ };
+
+
+#endif // _ICLEXTJPEGAPIFRAMEIMPL_
+
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imageadaptationextensions/iclextjpegapi/rom/IclExtJpegApi.iby Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,25 @@
+/*
+* Copyright (c) 2002-2006 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: Image description file for project IclExtJpegApi
+*
+*/
+
+
+#ifndef __ICLEXTJPEGAPI_IBY
+#define __ICLEXTJPEGAPI_IBY
+
+//ExifLib
+file=ABI_DIR\BUILD_DIR\IclExtJpegApi.dll SHARED_LIB_DIR\IclExtJpegApi.dll
+
+#endif //__ICLEXTJPEGAPI_IBY
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imageadaptationextensions/iclextjpegapi/src/IclExtJpegApi.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,1296 @@
+/*
+* Copyright (c) 2006-2008 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: Implementation of CVisualFrame, CExtJpegDecoder and CExtJpegEncoder
+*
+*/
+
+// INCLUDE FILES
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <icl_uids_def.hrh>
+#endif
+#include "IclExtJpegApi.h"
+#include "IclExtJpegApiFrameImpl.h"
+
+
+/*****************************************************/
+/* Visual Frame Data Structure in Extended ICL API */
+/*****************************************************/
+
+// ---------------------------------------------------------
+// CVisualFrame* CVisualFrame::NewL
+// Two-phased constructor.
+// ---------------------------------------------------------
+//
+EXPORT_C CVisualFrame* CVisualFrame::NewL(
+ TDes8& aBuffer,
+ const TSize& aDimension,
+ TInt aFrameFormat )
+ {
+
+ CVisualFrame* self = new ( ELeave ) CVisualFrame();
+ CleanupStack::PushL( self );
+ self->iVisualFrameImpl = CVisualFrameImpl::NewL( aBuffer, aDimension, aFrameFormat );
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+// ---------------------------------------------------------
+// CVisualFrame* CVisualFrame::NewL
+// Two-phased constructor.
+// ---------------------------------------------------------
+//
+EXPORT_C CVisualFrame* CVisualFrame::NewL(
+ RChunk& aChunk,
+ TInt aSize,
+ TInt aMaxSize,
+ TInt aDataOffset,
+ const TSize& aDimension,
+ TInt aFrameFormat )
+ {
+ CVisualFrame* self = new ( ELeave ) CVisualFrame();
+ CleanupStack::PushL( self );
+ self->iVisualFrameImpl = CVisualFrameImpl::NewL( aChunk, aSize, aMaxSize,
+ aDataOffset, aDimension, aFrameFormat );
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+// ---------------------------------------------------------
+// CVisualFrame* CVisualFrame::NewL
+// Two-phased constructor.
+// ---------------------------------------------------------
+//
+EXPORT_C CVisualFrame* CVisualFrame::NewL(
+ TDes8& aBuffer,
+ const TSize& aDimension,
+ TInt aFrameFormat,
+ const TFrameLayout& aFrameLayout )
+ {
+ CVisualFrame* self = new ( ELeave ) CVisualFrame();
+ CleanupStack::PushL( self );
+ self->iVisualFrameImpl = CVisualFrameImpl::NewL( aBuffer, aDimension,
+ aFrameFormat, aFrameLayout );
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+// ---------------------------------------------------------
+// CVisualFrame* CVisualFrame::NewL
+// Two-phased constructor.
+// ---------------------------------------------------------
+//
+EXPORT_C CVisualFrame* CVisualFrame::NewL(
+ RChunk& aChunk,
+ TInt aSize,
+ TInt aMaxSize,
+ const TSize& aDimension,
+ TInt aFrameFormat,
+ const TFrameLayout& aFrameLayout )
+ {
+ CVisualFrame* self = new ( ELeave ) CVisualFrame();
+ CleanupStack::PushL( self );
+ self->iVisualFrameImpl = CVisualFrameImpl::NewL( aChunk, aSize, aMaxSize,
+ aDimension, aFrameFormat,
+ aFrameLayout );
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+// ----------------------------------------------------------
+// CVisualFrame::DataChunkL
+// ----------------------------------------------------------
+//
+EXPORT_C const RChunk& CVisualFrame::DataChunkL() const
+ {
+ return iVisualFrameImpl->DataChunkL();
+ }
+
+// ----------------------------------------------------------
+// CVisualFrame::DataPtrL
+// ----------------------------------------------------------
+//
+EXPORT_C TPtr8 CVisualFrame::DataPtrL() const
+ {
+ return iVisualFrameImpl->DataPtrL();
+ }
+
+// ----------------------------------------------------------
+// CVisualFrame::Dimension
+// ----------------------------------------------------------
+//
+EXPORT_C TSize CVisualFrame::Dimension() const
+ {
+ return iVisualFrameImpl->Dimension();
+ }
+
+// ----------------------------------------------------------
+// CVisualFrame::FrameFormat
+// ----------------------------------------------------------
+//
+EXPORT_C TInt CVisualFrame::FrameFormat() const
+ {
+ return iVisualFrameImpl->FrameFormat2();
+ }
+
+// ----------------------------------------------------------
+// CVisualFrame::DataOffset
+// ----------------------------------------------------------
+//
+EXPORT_C TInt CVisualFrame::DataOffset() const
+ {
+ return iVisualFrameImpl->DataOffset();
+ }
+
+// ----------------------------------------------------------
+// CVisualFrame::Size
+// ----------------------------------------------------------
+//
+EXPORT_C TInt CVisualFrame::Size() const
+ {
+ return iVisualFrameImpl->Size();
+ }
+
+// ----------------------------------------------------------
+// CVisualFrame::SetSizeL
+// ----------------------------------------------------------
+//
+EXPORT_C void CVisualFrame::SetSizeL( TInt aSize )
+ {
+ iVisualFrameImpl->SetSizeL( aSize );
+ }
+
+// ----------------------------------------------------------
+// CVisualFrame::MaxSize
+// ----------------------------------------------------------
+//
+EXPORT_C TInt CVisualFrame::MaxSize() const
+ {
+ return iVisualFrameImpl->MaxSize();
+ }
+
+// ----------------------------------------------------------
+// CVisualFrame::DataContainer
+// ----------------------------------------------------------
+//
+EXPORT_C CVisualFrame::TDataContainer CVisualFrame::DataContainer() const
+ {
+ return ( TDataContainer )iVisualFrameImpl->DataContainer();
+ }
+
+// ----------------------------------------------------------
+// CVisualFrame::FrameLayout
+// ----------------------------------------------------------
+//
+EXPORT_C const CVisualFrame::TFrameLayout& CVisualFrame::FrameLayout() const
+ {
+ return iVisualFrameImpl->FrameLayout2();
+ }
+
+// ----------------------------------------------------------
+// CVisualFrame::~CVisualFrame
+// Destructor
+// ----------------------------------------------------------
+//
+EXPORT_C CVisualFrame::~CVisualFrame()
+ {
+ delete iVisualFrameImpl;
+ }
+
+// ---------------------------------------------------------
+// CVisualFrame* CVisualFrame::NewL
+// Two-phased constructor.
+// ---------------------------------------------------------
+//
+EXPORT_C CVisualFrame* CVisualFrame::NewL( const CImageFrame* aImageFrame )
+ {
+ CVisualFrame* self = new ( ELeave ) CVisualFrame();
+ CleanupStack::PushL( self );
+ self->iVisualFrameImpl = CVisualFrameImpl::NewL( aImageFrame );
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+// ----------------------------------------------------------
+// CVisualFrame::GetImageFrameL
+// ----------------------------------------------------------
+//
+EXPORT_C CImageFrame* CVisualFrame::GetImageFrameL()
+ {
+ return iVisualFrameImpl->GetImageFrameL();
+ }
+
+
+/*****************************************************/
+/* Extended ICL Jpeg Decoder API */
+/*****************************************************/
+
+// ---------------------------------------------------------
+// CExtJpegDecoder* CExtJpegDecoder::NewL
+// Two-phased constructor.
+// ---------------------------------------------------------
+//
+EXPORT_C CExtJpegDecoder* CExtJpegDecoder::NewL()
+ {
+ return new (ELeave) CExtJpegDecoder();
+ }
+
+// ---------------------------------------------------------
+// CExtJpegDecoder* CExtJpegDecoder::FileNewL
+// Creates, initializes and returns a pointer to an object of
+// class CExtJpegDecoder
+// ---------------------------------------------------------
+//
+EXPORT_C CExtJpegDecoder* CExtJpegDecoder::FileNewL(
+ RFs& aFs, const TDesC& aSourceFilename,
+ const TDesC8& aMIMEType,
+ const TOptions aOptions )
+ {
+ CExtJpegDecoder* dec = reinterpret_cast<CExtJpegDecoder*>(
+ CImageDecoder::FileNewL( aFs, aSourceFilename,
+ aMIMEType, aOptions ) );
+ CleanupStack::PushL( dec );
+ if ( dec->CapabilitiesL() < ECapNone )
+ {
+ User::Leave( KErrNotFound );
+ }
+ CleanupStack::Pop();
+ return dec;
+ }
+
+// ---------------------------------------------------------
+// CExtJpegDecoder* CExtJpegDecoder::FileNewL
+// Creates, initializes and returns a pointer to an object of
+// class CExtJpegDecoder
+// ---------------------------------------------------------
+//
+EXPORT_C CExtJpegDecoder* CExtJpegDecoder::FileNewL(
+ RFs& aFs,
+ const TDesC& aSourceFilename,
+ const TOptions aOptions,
+ const TUid aImageType,
+ const TUid aImageSubType,
+ const TUid aDecoderUid )
+ {
+ CExtJpegDecoder* dec = reinterpret_cast<CExtJpegDecoder*>(
+ CImageDecoder::FileNewL( aFs, aSourceFilename, aOptions,
+ aImageType, aImageSubType, aDecoderUid ) );
+ CleanupStack::PushL( dec );
+ if ( dec->CapabilitiesL() < ECapNone )
+ {
+ User::Leave( KErrNotFound );
+ }
+ CleanupStack::Pop();
+ return dec;
+ }
+
+// ---------------------------------------------------------
+// CExtJpegDecoder* CExtJpegDecoder::DataNewL
+// Creates, initializes and returns a pointer to an object of
+// class CExtJpegDecoder
+// ---------------------------------------------------------
+//
+EXPORT_C CExtJpegDecoder* CExtJpegDecoder::DataNewL(
+ RFs& aFs,
+ const TDesC8& aSourceData,
+ const TDesC8& aMIMEType,
+ const TOptions aOptions )
+ {
+ CExtJpegDecoder* dec = reinterpret_cast<CExtJpegDecoder*>(
+ CImageDecoder::DataNewL( aFs, aSourceData,
+ aMIMEType, aOptions ) );
+ CleanupStack::PushL( dec );
+ if ( dec->CapabilitiesL() < ECapNone )
+ {
+ User::Leave( KErrNotFound );
+ }
+ CleanupStack::Pop();
+ return dec;
+ }
+
+// ---------------------------------------------------------
+// CExtJpegDecoder* CExtJpegDecoder::DataNewL
+// Creates, initializes and returns a pointer to an object of
+// class CExtJpegDecoder
+// ---------------------------------------------------------
+//
+EXPORT_C CExtJpegDecoder* CExtJpegDecoder::DataNewL(
+ RFs& aFs,
+ const TDesC8& aSourceData,
+ const TOptions aOptions,
+ const TUid aImageType,
+ const TUid aImageSubType,
+ const TUid aDecoderUid )
+ {
+ CExtJpegDecoder* dec = reinterpret_cast<CExtJpegDecoder*>(
+ CImageDecoder::DataNewL( aFs, aSourceData, aOptions,
+ aImageType, aImageSubType, aDecoderUid ) );
+ CleanupStack::PushL( dec );
+ if ( dec->CapabilitiesL() < ECapNone )
+ {
+ User::Leave( KErrNotFound );
+ }
+ CleanupStack::Pop();
+ return dec;
+ }
+
+// ---------------------------------------------------------
+// CExtJpegDecoder* CExtJpegDecoder::DataNewL
+// Creates, initializes and returns a pointer to an object of
+// class CExtJpegDecoder
+// ---------------------------------------------------------
+//
+EXPORT_C CExtJpegDecoder* CExtJpegDecoder::DataNewL(
+ RFs& aFs,
+ const CVisualFrame* aSourceData,
+ const TDesC8& aMIMEType,
+ const TOptions aOptions )
+ {
+
+ TUint8* sourcePtr = NULL;
+ CVisualFrame* sourceDataFrame = const_cast<CVisualFrame*>( aSourceData );
+ if ( sourceDataFrame->DataContainer() == CVisualFrame::EInChunk )
+ {
+ sourcePtr = sourceDataFrame->DataChunkL().Base() + sourceDataFrame->DataOffset();
+ }
+ else if ( sourceDataFrame->DataContainer() == CVisualFrame::EInDescriptor )
+ {
+ sourcePtr = const_cast<TUint8*>( sourceDataFrame->DataPtrL().Ptr() )
+ + sourceDataFrame->DataOffset();
+ }
+ else
+ {
+ User::Leave( KErrArgument );
+ }
+ TPtrC8 sourceData( sourcePtr, sourceDataFrame->Size() );
+ CExtJpegDecoder* dec = reinterpret_cast<CExtJpegDecoder*>(
+ CImageDecoder::DataNewL( aFs, sourceData,
+ aMIMEType, aOptions ) );
+ CleanupStack::PushL( dec );
+ if ( dec->CapabilitiesL() < ECapNone )
+ {
+ User::Leave( KErrNotFound );
+ }
+ CleanupStack::Pop();
+ return dec;
+ }
+
+// ---------------------------------------------------------
+// CExtJpegDecoder* CExtJpegDecoder::DataNewL
+// Creates, initializes and returns a pointer to an object of
+// class CExtJpegDecoder
+// ---------------------------------------------------------
+//
+EXPORT_C CExtJpegDecoder* CExtJpegDecoder::DataNewL(
+ RFs& aFs,
+ const CVisualFrame* aSourceData,
+ const TOptions aOptions,
+ const TUid aImageType,
+ const TUid aImageSubType,
+ const TUid aDecoderUid )
+ {
+ TUint8* sourcePtr = NULL;
+ CVisualFrame* sourceDataFrame = const_cast<CVisualFrame*>( aSourceData );
+ if ( sourceDataFrame->DataContainer() == CVisualFrame::EInChunk )
+ {
+ sourcePtr = sourceDataFrame->DataChunkL().Base() + sourceDataFrame->DataOffset();
+ }
+ else if ( aSourceData->DataContainer() == CVisualFrame::EInDescriptor )
+ {
+ sourcePtr = const_cast<TUint8*>( sourceDataFrame->DataPtrL().Ptr() )
+ + sourceDataFrame->DataOffset();
+ }
+ else
+ {
+ User::Leave( KErrArgument );
+ }
+
+ TPtrC8 sourceData( sourcePtr, sourceDataFrame->Size() );
+ CExtJpegDecoder* dec = reinterpret_cast<CExtJpegDecoder*>(
+ CImageDecoder::DataNewL( aFs, sourceData, aOptions,
+ aImageType, aImageSubType, aDecoderUid ) );
+ CleanupStack::PushL( dec );
+ if ( dec->CapabilitiesL() < ECapNone )
+ {
+ User::Leave( KErrNotFound );
+ }
+ CleanupStack::Pop();
+ return dec;
+ }
+
+// ----------------------------------------------------------
+// CExtJpegDecoder::~CExtJpegDecoder
+// Destructor
+// ----------------------------------------------------------
+//
+EXPORT_C CExtJpegDecoder::~CExtJpegDecoder()
+ {
+ }
+
+// ----------------------------------------------------------
+// CExtJpegDecoder::SetCroppingL
+// ----------------------------------------------------------
+//
+EXPORT_C void CExtJpegDecoder::SetCroppingL( TRect aCropRect )
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( ECapCropping );
+ CustomSyncL( reinterpret_cast<TInt>( &aCropRect ) );
+ CustomSyncL( EEnd );
+ }
+
+// ----------------------------------------------------------
+// CExtJpegDecoder::SetStreamingL
+// ----------------------------------------------------------
+//
+EXPORT_C void CExtJpegDecoder::SetStreamingL( TSize& aMacroBlockSize )
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( ECapStreaming );
+ CustomSyncL( reinterpret_cast<TInt>( &aMacroBlockSize ) );
+ CustomSyncL( EEnd );
+ }
+
+// ----------------------------------------------------------
+// CExtJpegDecoder::SetRotationL
+// ----------------------------------------------------------
+//
+EXPORT_C void CExtJpegDecoder::SetRotationL( TInt aDegree )
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( ECapRotation );
+ CustomSyncL( aDegree );
+ CustomSyncL( EEnd );
+ }
+
+// ----------------------------------------------------------
+// CExtJpegDecoder::SetFlippingL
+// ----------------------------------------------------------
+//
+EXPORT_C void CExtJpegDecoder::SetFlippingL()
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( ECapFlipping );
+ CustomSyncL( EEnd );
+ }
+
+// ----------------------------------------------------------
+// CExtJpegDecoder::SetMirroringL
+// ----------------------------------------------------------
+//
+EXPORT_C void CExtJpegDecoder::SetMirroringL()
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( ECapMirroring );
+ CustomSyncL( EEnd );
+ }
+
+// ----------------------------------------------------------
+// CExtJpegDecoder::SetDctDecodingL
+// ----------------------------------------------------------
+//
+EXPORT_C void CExtJpegDecoder::SetDctDecodingL()
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( ECapDctDecoding );
+ CustomSyncL( EEnd );
+ }
+
+// ----------------------------------------------------------
+// CExtJpegDecoder::ConvertL
+// ----------------------------------------------------------
+//
+EXPORT_C void CExtJpegDecoder::ConvertL(
+ TRequestStatus* aRequestStatus,
+ const CVisualFrame* aDestinationFrame,
+ TInt& aNoOfDecodedMBlocks,
+ TInt aFrameNumber )
+ {
+ iIsExtConvert = ETrue;
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( EConvert );
+ CustomSyncL( reinterpret_cast<TInt>( aDestinationFrame ) );
+ CustomSyncL( reinterpret_cast<TInt>( &aNoOfDecodedMBlocks ) );
+ CustomSyncL( aFrameNumber );
+ CustomSyncL( EReadyForAsync );
+ CustomAsync( aRequestStatus, 0 );
+ }
+
+// ----------------------------------------------------------
+// CExtJpegDecoder::ContinueConvertL
+// ----------------------------------------------------------
+//
+EXPORT_C void CExtJpegDecoder::ContinueConvertL(
+ TRequestStatus* aRequestStatus,
+ const CVisualFrame* aDestinationFrame,
+ TInt& aNoOfDecodedMBlocks,
+ TInt aFrameNumber )
+ {
+ iIsExtConvert = ETrue;
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( EContinueConvert );
+ CustomSyncL( reinterpret_cast<TInt>( aDestinationFrame ) );
+ CustomSyncL( reinterpret_cast<TInt>( &aNoOfDecodedMBlocks ) );
+ CustomSyncL( aFrameNumber );
+ CustomSyncL( EReadyForAsync );
+ CustomAsync( aRequestStatus, 0 );
+ }
+
+// ----------------------------------------------------------
+// CExtJpegDecoder::SupportedFormatsL
+// ----------------------------------------------------------
+//
+EXPORT_C TInt CExtJpegDecoder::SupportedFormatsL()
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( ESupportedFormats );
+ TInt retVal = KErrNotFound;
+ CustomSyncL( reinterpret_cast<TInt>( &retVal ) );
+ CustomSyncL( EEnd );
+ return retVal;
+ }
+
+// ----------------------------------------------------------
+// CExtJpegDecoder::CapabilitiesL
+// ----------------------------------------------------------
+//
+EXPORT_C TInt CExtJpegDecoder::CapabilitiesL()
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( ECapabilities );
+ TInt retVal = KErrNotFound;
+ CustomSyncL( reinterpret_cast<TInt>( &retVal ) );
+ CustomSyncL( EEnd );
+ return retVal;
+ }
+
+// ----------------------------------------------------------
+// CExtJpegDecoder::CExtJpegDecoder
+// ----------------------------------------------------------
+//
+CExtJpegDecoder::CExtJpegDecoder() : CJPEGImageFrameDecoder()
+ {
+ }
+
+// ----------------------------------------------------------
+// CExtJpegDecoder::Convert
+// ----------------------------------------------------------
+//
+EXPORT_C void CExtJpegDecoder::Convert( TRequestStatus* aRequestStatus,
+ CFbsBitmap& aDestination, TInt aFrameNumber )
+ {
+ iIsExtConvert = EFalse;
+ CImageDecoder::Convert( aRequestStatus, aDestination, aFrameNumber );
+ }
+
+// ----------------------------------------------------------
+// CExtJpegDecoder::Convert
+// ----------------------------------------------------------
+//
+EXPORT_C void CExtJpegDecoder::Convert( TRequestStatus* aRequestStatus,
+ CFbsBitmap& aDestination,
+ CFbsBitmap& aDestinationMask, TInt aFrameNumber )
+ {
+ iIsExtConvert = EFalse;
+ CImageDecoder::Convert( aRequestStatus, aDestination, aDestinationMask, aFrameNumber );
+ }
+
+// ----------------------------------------------------------
+// CExtJpegDecoder::ContinueConvert
+// ----------------------------------------------------------
+//
+EXPORT_C void CExtJpegDecoder::ContinueConvert( TRequestStatus* aRequestStatus )
+ {
+ if( iIsExtConvert )
+ {
+ User::RequestComplete( aRequestStatus, KErrUnknown );
+ }
+ else
+ {
+ CImageDecoder::ContinueConvert( aRequestStatus );
+ }
+ }
+
+// ----------------------------------------------------------
+// CExtJpegDecoder* CExtJpegDecoder::FileNewL
+// Creates, initializes and returns a pointer to an object of
+// class CExtJpegDecoder
+// ----------------------------------------------------------
+//
+EXPORT_C CExtJpegDecoder* CExtJpegDecoder::FileNewL(
+ const TDecoderType aDecoderType,
+ RFs& aFs,
+ const TDesC& aSourceFileName,
+ const TOptions aOptions )
+ {
+ TInt versionMin = KMinSwVersion;
+ TInt versionMax = KMaxSwVersion;
+ if ( aDecoderType == EHwImplementation )
+ {
+ versionMin = KMinHwVersion;
+ versionMax = KMaxHwVersion;
+ }
+ TUid uId = GetUidByVersionRangeL( versionMin, versionMax );
+ if ( uId == KNullUid )
+ {
+ User::Leave( KErrNotFound );
+ }
+ return CExtJpegDecoder::FileNewL( aFs, aSourceFileName, aOptions,
+ KImageTypeJPGUid, KNullUid, uId );
+ }
+
+// ----------------------------------------------------------
+// CExtJpegDecoder* CExtJpegDecoder::DataNewL
+// Creates, initializes and returns a pointer to an object of
+// class CExtJpegDecoder
+// ----------------------------------------------------------
+//
+EXPORT_C CExtJpegDecoder* CExtJpegDecoder::DataNewL(
+ const TDecoderType aDecoderType,
+ RFs& aFs,
+ const TDesC8& aSourceData,
+ const TOptions aOptions )
+ {
+ TInt versionMin = KMinSwVersion;
+ TInt versionMax = KMaxSwVersion;
+ if ( aDecoderType == EHwImplementation )
+ {
+ versionMin = KMinHwVersion;
+ versionMax = KMaxHwVersion;
+ }
+ TUid uId = GetUidByVersionRangeL( versionMin, versionMax );
+ if ( uId == KNullUid )
+ {
+ User::Leave( KErrNotFound );
+ }
+ return CExtJpegDecoder::DataNewL( aFs, aSourceData, aOptions,
+ KImageTypeJPGUid, KNullUid, uId );
+
+ }
+
+// ----------------------------------------------------------
+// CExtJpegDecoder* CExtJpegDecoder::DataNewL
+// Creates, initializes and returns a pointer to an object of
+// class CExtJpegDecoder
+// ----------------------------------------------------------
+//
+EXPORT_C CExtJpegDecoder* CExtJpegDecoder::DataNewL(
+ const TDecoderType aDecoderType,
+ RFs& aFs,
+ const CVisualFrame* aSourceData,
+ const TOptions aOptions )
+ {
+ TInt versionMin = KMinSwVersion;
+ TInt versionMax = KMaxSwVersion;
+ if ( aDecoderType == EHwImplementation )
+ {
+ versionMin = KMinHwVersion;
+ versionMax = KMaxHwVersion;
+ }
+ TUid uId = GetUidByVersionRangeL( versionMin, versionMax );
+ if ( uId == KNullUid )
+ {
+ User::Leave( KErrNotFound );
+ }
+ return CExtJpegDecoder::DataNewL( aFs, aSourceData, aOptions,
+ KImageTypeJPGUid, KNullUid, uId );
+ }
+
+
+// ----------------------------------------------------------
+// CExtJpegDecoder::GetUidByVersionRangeL
+// ----------------------------------------------------------
+//
+TUid CExtJpegDecoder::GetUidByVersionRangeL( TInt aMinVersion, TInt aMaxVersion )
+ {
+ TUid uId = KNullUid;
+ TUid propertyUid = KUidSwCodec;
+
+ RUidDataArray implArray;
+ // based on the version decide what kind of codec to fetch
+ if( ( aMinVersion == KMinSwVersion ) && ( aMaxVersion == KMaxSwVersion ) )
+ {
+ propertyUid = KUidSwCodec;
+ }
+ else if( ( aMinVersion == KMinHwVersion ) && ( aMaxVersion == KMaxHwVersion ) )
+ {
+ propertyUid = KUidHwCodec;
+ }
+
+ // property array to be verified
+ const TUid properties[] = { propertyUid, KImageTypeJPGUid };
+
+ // Request existing plugins with the desired properties
+ TRAPD( getIntErr, CImageDecoder::GetInterfaceImplementationsL(
+ properties,
+ 2,
+ implArray ) );
+ CleanupClosePushL( implArray );
+ User::LeaveIfError( getIntErr );
+
+ TInt count = implArray.Count();
+ for( --count; uId == KNullUid && count >= 0; --count )
+ {
+ // Get the Jpeg decoder UID and find out whether it is requested
+ // type of decoder by version number.
+ TUid tempUid = implArray[ count ];
+ CImplementationInformationType* implInfo = NULL;
+ TRAPD( error, implInfo =
+ CImageDecoder::GetImplementationInformationL( tempUid ) );
+
+ User::LeaveIfError( error );
+
+ // check the opaque data and version no
+ TInt version = implInfo->Version();
+ if ( ( implInfo->OpaqueData().Find( KJpgMimeType ) != KErrNotFound )
+ && ( version <= aMaxVersion ) && ( version >= aMinVersion ) )
+ {
+ uId = tempUid;
+ }
+ delete implInfo;
+ } // for - count
+ CleanupStack::PopAndDestroy(&implArray);
+ return uId;
+
+ }
+
+
+
+/*****************************************************/
+/* Extended ICL Jpeg Encoder API */
+/*****************************************************/
+
+
+// ---------------------------------------------------------
+// CExtJpegEncoder* CExtJpegEncoder::NewL
+// Two-phased constructor.
+// ---------------------------------------------------------
+//
+EXPORT_C CExtJpegEncoder* CExtJpegEncoder::NewL()
+ {
+ return new (ELeave) CExtJpegEncoder();
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder* CExtJpegEncoder::FileNewL
+// Creates, initializes and returns a pointer to an object of
+// class CExtJpegEncoder
+// ---------------------------------------------------------
+//
+EXPORT_C CExtJpegEncoder* CExtJpegEncoder::FileNewL(
+ RFs& aFs,
+ const TDesC& aDestinationFilename,
+ const TDesC8& aMIMEType,
+ const TOptions aOptions )
+ {
+ CExtJpegEncoder* enc = reinterpret_cast<CExtJpegEncoder*>(
+ CImageEncoder::FileNewL( aFs, aDestinationFilename,
+ aMIMEType, aOptions ) );
+ CleanupStack::PushL( enc );
+ if ( enc->CapabilitiesL() < ECapNone )
+ {
+ User::Leave( KErrNotFound );
+ }
+ CleanupStack::Pop();
+ return enc;
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder* CExtJpegEncoder::FileNewL
+// Creates, initializes and returns a pointer to an object of
+// class CExtJpegEncoder
+// ---------------------------------------------------------
+//
+EXPORT_C CExtJpegEncoder* CExtJpegEncoder::FileNewL(
+ RFs& aFs,
+ const TDesC& aDestinationFilename,
+ const TOptions aOptions,
+ const TUid aImageType,
+ const TUid aImageSubType,
+ const TUid aEncoderUid )
+ {
+ CExtJpegEncoder* enc = reinterpret_cast<CExtJpegEncoder*>(
+ CImageEncoder::FileNewL( aFs, aDestinationFilename,
+ aOptions, aImageType, aImageSubType, aEncoderUid ) );
+ CleanupStack::PushL( enc );
+ if ( enc->CapabilitiesL() < ECapNone )
+ {
+ User::Leave( KErrNotFound );
+ }
+ CleanupStack::Pop();
+ return enc;
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder* CExtJpegEncoder::DataNewL
+// Creates, initializes and returns a pointer to an object of
+// class CExtJpegEncoder
+// ---------------------------------------------------------
+//
+EXPORT_C CExtJpegEncoder* CExtJpegEncoder::DataNewL(
+ HBufC8*& aDestinationData,
+ const TDesC8& aMIMEType,
+ const TOptions aOptions )
+ {
+ CExtJpegEncoder* enc = reinterpret_cast<CExtJpegEncoder*>(
+ CImageEncoder::DataNewL( aDestinationData,
+ aMIMEType, aOptions ) );
+ CleanupStack::PushL( enc );
+ if ( enc->CapabilitiesL() < ECapNone )
+ {
+ User::Leave( KErrNotFound );
+ }
+ CleanupStack::Pop();
+ return enc;
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder* CExtJpegEncoder::DataNewL
+// Creates, initializes and returns a pointer to an object of
+// class CExtJpegEncoder
+// ---------------------------------------------------------
+//
+EXPORT_C CExtJpegEncoder* CExtJpegEncoder::DataNewL(
+ HBufC8*& aDestinationData,
+ const TOptions aOptions,
+ const TUid aImageType,
+ const TUid aImageSubType,
+ const TUid aEncoderUid )
+ {
+ CExtJpegEncoder* enc = reinterpret_cast<CExtJpegEncoder*>(
+ CImageEncoder::DataNewL( aDestinationData,
+ aOptions, aImageType, aImageSubType, aEncoderUid ) );
+ CleanupStack::PushL( enc );
+ if ( enc->CapabilitiesL() < ECapNone )
+ {
+ User::Leave( KErrNotFound );
+ }
+ CleanupStack::Pop();
+ return enc;
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder* CExtJpegEncoder::DataNewL
+// Creates, initializes and returns a pointer to an object of
+// class CExtJpegEncoder
+// ---------------------------------------------------------
+//
+EXPORT_C CExtJpegEncoder* CExtJpegEncoder::DataNewL(
+ const CVisualFrame* aDestinationData,
+ const TDesC8& aMIMEType,
+ const TOptions aOptions )
+ {
+ HBufC8* tmp = NULL;
+ CExtJpegEncoder* enc = reinterpret_cast<CExtJpegEncoder*>(
+ CImageEncoder::DataNewL( tmp,
+ aMIMEType, aOptions ) );
+ CleanupStack::PushL( enc );
+ if ( enc->CapabilitiesL() < ECapNone )
+ {
+ User::Leave( KErrNotFound );
+ }
+ enc->CustomSyncL( KExtensionUID );
+ enc->CustomSyncL( EDestVisualFrame );
+ enc->CustomSyncL( reinterpret_cast<TInt>( aDestinationData ) );
+ enc->CustomSyncL( EEnd );
+ CleanupStack::Pop();
+ return enc;
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder* CExtJpegEncoder::DataNewL
+// Creates, initializes and returns a pointer to an object of
+// class CExtJpegEncoder
+// ---------------------------------------------------------
+//
+EXPORT_C CExtJpegEncoder* CExtJpegEncoder::DataNewL(
+ const CVisualFrame* aDestinationData,
+ const TOptions aOptions,
+ const TUid aImageType,
+ const TUid aImageSubType,
+ const TUid aEncoderUid )
+ {
+ HBufC8* tmp = NULL;
+ CExtJpegEncoder* enc = reinterpret_cast<CExtJpegEncoder*>(
+ CImageEncoder::DataNewL( tmp, aOptions,
+ aImageType, aImageSubType, aEncoderUid ) );
+ CleanupStack::PushL( enc );
+ if ( enc->CapabilitiesL() < ECapNone )
+ {
+ User::Leave( KErrNotFound );
+ }
+ enc->CustomSyncL( KExtensionUID );
+ enc->CustomSyncL( EDestVisualFrame );
+ enc->CustomSyncL( reinterpret_cast<TInt>( aDestinationData ) );
+ enc->CustomSyncL( EEnd );
+ CleanupStack::Pop();
+ return enc;
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder::~CExtJpegEncoder
+// Destructor.
+// ---------------------------------------------------------
+//
+EXPORT_C CExtJpegEncoder::~CExtJpegEncoder()
+ {
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder::SetStreamingL
+// ---------------------------------------------------------
+//
+EXPORT_C void CExtJpegEncoder::SetStreamingL( TSize& aMacroBlockSize,
+ const CFrameImageData* aFrameImageData )
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( ECapStreaming );
+ CustomSyncL( reinterpret_cast<TInt>( &aMacroBlockSize ) );
+ CustomSyncL( reinterpret_cast<TInt>( aFrameImageData ) );
+ CustomSyncL( EEnd );
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder::SetImageReplaceL
+// ---------------------------------------------------------
+//
+EXPORT_C void CExtJpegEncoder::SetImageReplaceL( const CVisualFrame* aReplaceImage,
+ TPoint aReplacePoint )
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( ECapImageReplacing );
+ CustomSyncL( reinterpret_cast<TInt>( aReplaceImage ) );
+ CustomSyncL( reinterpret_cast<TInt>( &aReplacePoint ) );
+ CustomSyncL( EEnd );
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder::SetBitmapReplaceL
+// ---------------------------------------------------------
+//
+EXPORT_C void CExtJpegEncoder::SetBitmapReplaceL( const CFbsBitmap& aReplaceBitmap,
+ TPoint aReplacePoint )
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( ECapBitmapReplacing );
+ CustomSyncL( reinterpret_cast<TInt>( &aReplaceBitmap ) );
+ CustomSyncL( reinterpret_cast<TInt>( &aReplacePoint ) );
+ CustomSyncL( EEnd );
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder::SetBitmapOverlayL
+// ---------------------------------------------------------
+//
+EXPORT_C void CExtJpegEncoder::SetBitmapOverlayL( const CFbsBitmap& aOverlayBitmap,
+ TUint aAlphaValue, TPoint aOverlayPoint )
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( ECapBitmapOverlay );
+ CustomSyncL( reinterpret_cast<TInt>( &aOverlayBitmap ) );
+ CustomSyncL( aAlphaValue );
+ CustomSyncL( reinterpret_cast<TInt>( &aOverlayPoint ) );
+ CustomSyncL( EEnd );
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder::SetLosslessRotationL
+// ---------------------------------------------------------
+//
+EXPORT_C void CExtJpegEncoder::SetLosslessRotationL( TInt aDegree )
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( ECapLosslessRotation );
+ CustomSyncL( aDegree );
+ CustomSyncL( EEnd );
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder::SetLosslessFlippingL
+// ---------------------------------------------------------
+//
+EXPORT_C void CExtJpegEncoder::SetLosslessFlippingL()
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( ECapLosslessFlipping );
+ CustomSyncL( EEnd );
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder::SetLosslessMirroringL
+// ---------------------------------------------------------
+//
+EXPORT_C void CExtJpegEncoder::SetLosslessMirroringL()
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( ECapLosslessMirroring );
+ CustomSyncL( EEnd );
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder::SetDctEncodingL
+// ---------------------------------------------------------
+//
+EXPORT_C void CExtJpegEncoder::SetDctEncodingL()
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( ECapDctEncoding );
+ CustomSyncL( EEnd );
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder::ProvideNewDestDataL
+// ---------------------------------------------------------
+//
+EXPORT_C void CExtJpegEncoder::ProvideNewDestDataL( const CVisualFrame* aDestinationData )
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( ENewDestData );
+ CustomSyncL( reinterpret_cast<TInt>( aDestinationData ) );
+ CustomSyncL( EEnd );
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder::ConvertL
+// ---------------------------------------------------------
+//
+EXPORT_C void CExtJpegEncoder::ConvertL(
+ TRequestStatus* aRequestStatus,
+ const CVisualFrame* aSourceFrame,
+ TInt& aNoOfEncodedMBlocks,
+ const CFrameImageData* aFrameImageData )
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( EConvert );
+ CustomSyncL( reinterpret_cast<TInt>( aSourceFrame ) );
+ CustomSyncL( reinterpret_cast<TInt>( &aNoOfEncodedMBlocks ) );
+ CustomSyncL( reinterpret_cast<TInt>( aFrameImageData ) );
+ CustomSyncL( EReadyForAsync );
+ CustomAsync( aRequestStatus, 0 );
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder::ContinueConvertL
+// ---------------------------------------------------------
+//
+EXPORT_C void CExtJpegEncoder::ContinueConvertL(
+ TRequestStatus* aRequestStatus,
+ const CVisualFrame* aSourceFrame,
+ TInt& aNoOfEncodedMBlocks )
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( EContinueConvert );
+ CustomSyncL( reinterpret_cast<TInt>( aSourceFrame ) );
+ CustomSyncL( reinterpret_cast<TInt>( &aNoOfEncodedMBlocks ) );
+ CustomSyncL( EReadyForAsync );
+ CustomAsync( aRequestStatus, 0 );
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder::SupportedFormatsL
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CExtJpegEncoder::SupportedFormatsL()
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( ESupportedFormats );
+ TInt retVal = KErrNotFound;
+ CustomSyncL( reinterpret_cast<TInt>( &retVal ) );
+ CustomSyncL( EEnd );
+ return retVal;
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder::CapabilitiesL
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CExtJpegEncoder::CapabilitiesL()
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( ECapabilities );
+ TInt retVal = KErrNotFound;
+ CustomSyncL( reinterpret_cast<TInt>( &retVal ) );
+ CustomSyncL( EEnd );
+ return retVal;
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder::CExtJpegEncoder
+// ---------------------------------------------------------
+//
+CExtJpegEncoder::CExtJpegEncoder() : CJPEGImageFrameEncoder()
+ {
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder* CExtJpegEncoder::FileNewL
+// Creates, initializes and returns a pointer to an object of
+// class CExtJpegEncoder
+// ---------------------------------------------------------
+//
+EXPORT_C CExtJpegEncoder* CExtJpegEncoder::FileNewL(
+ const TEncoderType aEncoderType,
+ RFs& aFs,
+ const TDesC& aDestinationFilename,
+ const TOptions aOptions )
+ {
+ TInt versionMin = KMinSwVersion;
+ TInt versionMax = KMaxSwVersion;
+ if ( aEncoderType == EHwImplementation )
+ {
+ versionMin = KMinHwVersion;
+ versionMax = KMaxHwVersion;
+ }
+ TUid uId = GetUidByVersionRangeL( versionMin, versionMax );
+ if ( uId == KNullUid )
+ {
+ User::Leave( KErrNotFound );
+ }
+ return CExtJpegEncoder::FileNewL( aFs, aDestinationFilename, aOptions,
+ KImageTypeJPGUid, KNullUid, uId );
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder* CExtJpegEncoder::DataNewL
+// Creates, initializes and returns a pointer to an object of
+// class CExtJpegEncoder
+// ---------------------------------------------------------
+//
+EXPORT_C CExtJpegEncoder* CExtJpegEncoder::DataNewL(
+ const TEncoderType aEncoderType,
+ HBufC8*& aDestinationData,
+ const TOptions aOptions )
+ {
+ TInt versionMin = KMinSwVersion;
+ TInt versionMax = KMaxSwVersion;
+ if ( aEncoderType == EHwImplementation )
+ {
+ versionMin = KMinHwVersion;
+ versionMax = KMaxHwVersion;
+ }
+ TUid uId = GetUidByVersionRangeL( versionMin, versionMax );
+ if ( uId == KNullUid )
+ {
+ User::Leave( KErrNotFound );
+ }
+ return CExtJpegEncoder::DataNewL( aDestinationData, aOptions,
+ KImageTypeJPGUid, KNullUid, uId );
+
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder* CExtJpegEncoder::DataNewL
+// Creates, initializes and returns a pointer to an object of
+// class CExtJpegEncoder
+// ---------------------------------------------------------
+//
+EXPORT_C CExtJpegEncoder* CExtJpegEncoder::DataNewL(
+ const TEncoderType aEncoderType,
+ const CVisualFrame* aDestinationData,
+ const TOptions aOptions )
+ {
+ TInt versionMin = KMinSwVersion;
+ TInt versionMax = KMaxSwVersion;
+ if ( aEncoderType == EHwImplementation )
+ {
+ versionMin = KMinHwVersion;
+ versionMax = KMaxHwVersion;
+ }
+ TUid uId = GetUidByVersionRangeL( versionMin, versionMax );
+ if ( uId == KNullUid )
+ {
+ User::Leave( KErrNotFound );
+ }
+ return CExtJpegEncoder::DataNewL( aDestinationData, aOptions,
+ KImageTypeJPGUid, KNullUid, uId );
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder::GetDestinationDataSizeL
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CExtJpegEncoder::GetDestinationDataSizeL()
+ {
+ CustomSyncL( KExtensionUID );
+ CustomSyncL( EDestDataSize );
+ TInt retVal = KErrNotFound;
+ CustomSyncL( reinterpret_cast<TInt>( &retVal ) );
+ CustomSyncL( EEnd );
+ return retVal;
+ }
+
+// ---------------------------------------------------------
+// CExtJpegEncoder::GetUidByVersionRangeL
+// ---------------------------------------------------------
+//
+TUid CExtJpegEncoder::GetUidByVersionRangeL( TInt aMinVersion, TInt aMaxVersion )
+ {
+ TUid uId = KNullUid;
+ TUid propertyUid = KUidSwCodec;
+
+ // based on the version decide what kind of codec to fetch
+ if( ( aMinVersion == KMinSwVersion ) && ( aMaxVersion == KMaxSwVersion ) )
+ {
+ propertyUid = KUidSwCodec;
+ }
+ else if( ( aMinVersion == KMinHwVersion ) && ( aMaxVersion == KMaxHwVersion ) )
+ {
+ propertyUid = KUidHwCodec;
+ }
+
+ // property array to be verified
+ const TUid properties[] = { propertyUid, KImageTypeJPGUid };
+
+ RUidDataArray implArray;
+ // Request existing plugins with the desired properties
+ TRAPD( getIntErr, CImageEncoder::GetInterfaceImplementationsL(
+ properties,
+ 2,
+ implArray ) );
+ CleanupClosePushL( implArray );
+ User::LeaveIfError( getIntErr );
+
+ TInt count = implArray.Count();
+ for( --count; uId == KNullUid && count >= 0; --count )
+ {
+ // Check all encoders and find the one having Jpeg mime type,
+ TUid tempUid = implArray[ count ];
+
+ // Get the same encoder UID and find out more info for testing
+ TUid uId2 = { KEncoderInterfaceUidValue };
+ RImplInfoPtrArray implInfo;
+ REComSession::ListImplementationsL( uId2, implInfo );
+ TInt count2 = implInfo.Count();
+ uId2 = tempUid;
+ for ( --count2; uId == KNullUid && count2 >= 0; --count2 )
+ {
+ CImplementationInformation& implInfoCur = *implInfo[count2];
+ if ( ( implInfoCur.ImplementationUid() == uId2 ) &&
+ ( implInfoCur.OpaqueData().Find( KJpgMimeType ) != KErrNotFound ) )
+ {
+ uId = uId2;
+ }
+ }
+ implInfo.ResetAndDestroy();
+ } // for - count
+
+ CleanupStack::PopAndDestroy( &implArray );
+ return uId;
+ }
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imageadaptationextensions/iclextjpegapi/src/IclExtJpegApiFrameImplV2.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,663 @@
+/*
+* Copyright (c) 2006 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: Implementation of CVisualFrameImpl
+*
+*/
+
+#include "IclExtJpegApi.h"
+#include "IclExtJpegApiFrameImpl.h"
+
+// ---------------------------------------------------------
+// TFrameFormatExt::Constructor
+// ---------------------------------------------------------
+//
+void TFrameFormatExt::Constructor()
+ {
+ switch ( iFormatCode )
+ {
+ case CVisualFrame::EFormatMonochrome:
+ {
+ iColourSpace = KUidColourSpaceYCbCr;
+ iSampling = KUidSamplingMonochrome;
+ break;
+ }
+ case CVisualFrame::EFormat16bitRGB444:
+ case CVisualFrame::EFormat16BitRGB565:
+ case CVisualFrame::EFormat32BitRGB888:
+ case CVisualFrame::EFormatFbsBitmapColor4K:
+ case CVisualFrame::EFormatFbsBitmapColor64K:
+ case CVisualFrame::EFormatFbsBitmapColor16M:
+ {
+ iColourSpace = KUidColourSpaceRGB;
+ iSampling = KUidSamplingColor444;
+ break;
+ }
+ case CVisualFrame::EFormatYUV420SemiPlanar:
+ case CVisualFrame::EFormatYUV420Interleaved:
+ case CVisualFrame::EFormatYUV420Planar:
+ {
+ iColourSpace = KUidColourSpaceYCbCr;
+ iSampling = KUidSamplingColor420;
+ break;
+ }
+ case CVisualFrame::EFormatYUV422:
+ case CVisualFrame::EFormatYUV422Reversed:
+ case CVisualFrame::EFormatExtYUV422Interleaved:
+ case CVisualFrame::EFormatExtYUV422Planar:
+ {
+ iColourSpace = KUidColourSpaceYCbCr;
+ iSampling = KUidSamplingColor422;
+ break;
+ }
+ case CVisualFrame::EFormatExtYUV444Planar:
+ case CVisualFrame::EFormatYUV444:
+ {
+ iColourSpace = KUidColourSpaceYCbCr;
+ iSampling = KUidSamplingColor444;
+ break;
+ }
+ case CVisualFrame::EFormatJpeg:
+ case CVisualFrame::EFormatExif:
+ case CVisualFrame::EFormatUserDefined:
+ case CVisualFrame::EFormatExtDctCoeff:
+ {
+ iColourSpace = KNullUid;
+ iSampling = KNullUid;
+ break;
+ }
+ default:
+ {
+ iFormatCode = KErrNotFound;
+ iColourSpace = KNullUid;
+ iSampling = KNullUid;
+ }
+ }
+ }
+
+// ----------------------------------------------------------
+// TFrameFormatExt::ColourSpace
+// ----------------------------------------------------------
+//
+TUid TFrameFormatExt::ColourSpace() const
+ {
+ return iColourSpace;
+ }
+
+// ----------------------------------------------------------
+// TFrameFormatExt::Sampling
+// ----------------------------------------------------------
+//
+TUid TFrameFormatExt::Sampling() const
+ {
+ return iSampling;
+ }
+
+// ----------------------------------------------------------
+// TFrameFormatExt::FormatCode
+// ----------------------------------------------------------
+//
+TInt TFrameFormatExt::FormatCode() const
+ {
+ return iFormatCode;
+ }
+
+// ----------------------------------------------------------
+// TFrameFormatExt::ColourSpace
+// ----------------------------------------------------------
+//
+void TFrameFormatExt::SetColourSpace( TUid aColourSpace )
+ {
+ iColourSpace = aColourSpace;
+ }
+
+
+
+/*****************************************************/
+/* Visual Frame Data Structure in Extended ICL API */
+/*****************************************************/
+
+
+// ----------------------------------------------------------
+// TFrameFormatBase* GetFrameFormatL
+// ----------------------------------------------------------
+//
+TFrameFormatBase* GetFrameFormatL( TInt aFrameFormatCode )
+ {
+ TUid formatUid = KNullUid;
+ switch ( aFrameFormatCode )
+ {
+ case CVisualFrame::EFormatMonochrome:
+ {
+ formatUid = KUidFormatYUVMonochrome;
+ break;
+ }
+ case CVisualFrame::EFormat16bitRGB444:
+ {
+ formatUid = KUidFormat16bitRGB444Interleaved;
+ break;
+ }
+ case CVisualFrame::EFormat16BitRGB565:
+ {
+ formatUid = KUidFormat16BitRGB565Interleaved;
+ break;
+ }
+ case CVisualFrame::EFormat32BitRGB888:
+ {
+ formatUid = KUidFormat32BitRGB888Interleaved;
+ break;
+ }
+ case CVisualFrame::EFormatYUV420Interleaved:
+ {
+ formatUid = KUidFormatYUV420Interleaved;
+ break;
+ }
+ case CVisualFrame::EFormatYUV420Planar:
+ {
+ formatUid = KUidFormatYUV420Planar;
+ break;
+ }
+ case CVisualFrame::EFormatYUV422:
+ {
+ formatUid = KUidFormatYUV422Interleaved;
+ break;
+ }
+ case CVisualFrame::EFormatYUV422Reversed:
+ {
+ formatUid = KUidFormatYUV422InterleavedReversed;
+ break;
+ }
+ case CVisualFrame::EFormatYUV444:
+ {
+ formatUid = KUidFormatYUV444Interleaved;
+ break;
+ }
+ case CVisualFrame::EFormatYUV420SemiPlanar:
+ {
+ formatUid = KUidFormatYUV420SemiPlanar;
+ break;
+ }
+ case CVisualFrame::EFormatExtYUV422Interleaved:
+ {
+ formatUid = KUidFormatYYUV422Interleaved;
+ break;
+ }
+ case CVisualFrame::EFormatExtYUV422Planar:
+ {
+ formatUid = KUidFormatYUV422Planar;
+ break;
+ }
+ case CVisualFrame::EFormatExtYUV444Planar:
+ {
+ formatUid = KUidFormatYUV444Planar;
+ break;
+ }
+ case CVisualFrame::EFormatJpeg:
+ case CVisualFrame::EFormatExif:
+ case CVisualFrame::EFormatFbsBitmapColor4K:
+ case CVisualFrame::EFormatFbsBitmapColor64K:
+ case CVisualFrame::EFormatFbsBitmapColor16M:
+ case CVisualFrame::EFormatUserDefined:
+ case CVisualFrame::EFormatExtDctCoeff:
+ {
+ break;
+ }
+ default:
+ {
+ User::Leave( KErrNotSupported );
+ }
+ }
+ TFrameFormatBase* frameFormatBase = NULL;
+ if ( formatUid == KNullUid )
+ {
+ frameFormatBase = new ( ELeave ) TFrameFormatExt( aFrameFormatCode );
+ }
+ else
+ {
+ frameFormatBase = new ( ELeave ) TFrameFormat( formatUid );
+ }
+ return frameFormatBase;
+ }
+
+// ----------------------------------------------------------
+// GetFrameFormat
+// ----------------------------------------------------------
+//
+TInt GetFrameFormat( const TFrameFormatBase& aFrameFormat )
+ {
+ TInt frameFormatCode = KErrNotFound;
+ if ( aFrameFormat.Type() == KUidIclImageFrameFormat )
+ {
+ const TFrameFormat& frameFormat = reinterpret_cast<const TFrameFormat&>( aFrameFormat );
+ switch ( frameFormat.FormatCode().iUid )
+ {
+ case KFormatYUVMonochromeUidValue:
+ {
+ frameFormatCode = CVisualFrame::EFormatMonochrome;
+ break;
+ }
+ case KFormat16bitRGB444InterleavedUidValue:
+ {
+ frameFormatCode = CVisualFrame::EFormat16bitRGB444;
+ break;
+ }
+ case KFormat16BitRGB565InterleavedUidValue:
+ {
+ frameFormatCode = CVisualFrame::EFormat16BitRGB565;
+ break;
+ }
+ case KFormat32BitRGB888InterleavedUidValue:
+ {
+ frameFormatCode = CVisualFrame::EFormat32BitRGB888;
+ break;
+ }
+ case KFormatYUV420InterleavedUidValue:
+ {
+ frameFormatCode = CVisualFrame::EFormatYUV420Interleaved;
+ break;
+ }
+ case KFormatYUV420PlanarUidValue:
+ {
+ frameFormatCode = CVisualFrame::EFormatYUV420Planar;
+ break;
+ }
+ case KFormatYUV422InterleavedUidValue:
+ {
+ frameFormatCode = CVisualFrame::EFormatYUV422;
+ break;
+ }
+ case KFormatYUV422InterleavedReversedUidValue:
+ {
+ frameFormatCode = CVisualFrame::EFormatYUV422Reversed;
+ break;
+ }
+ case KFormatYUV444InterleavedUidValue:
+ {
+ frameFormatCode = CVisualFrame::EFormatYUV444;
+ break;
+ }
+ case KFormatYUV420SemiPlanarUidValue:
+ {
+ frameFormatCode = CVisualFrame::EFormatYUV420SemiPlanar;
+ break;
+ }
+ case KFormatYYUV422InterleavedUidValue:
+ {
+ frameFormatCode = CVisualFrame::EFormatExtYUV422Interleaved;
+ break;
+ }
+ case KFormatYUV422PlanarUidValue:
+ {
+ frameFormatCode = CVisualFrame::EFormatExtYUV422Planar;
+ break;
+ }
+ case KFormatYUV444PlanarUidValue:
+ {
+ frameFormatCode = CVisualFrame::EFormatExtYUV444Planar;
+ break;
+ }
+ default:
+ {
+ }
+ }
+ }
+ else if ( aFrameFormat.Type() == KUidExtIclImageFrameFormat )
+ {
+ frameFormatCode = reinterpret_cast<const TFrameFormatExt&>( aFrameFormat ).FormatCode();
+ }
+ return frameFormatCode;
+ }
+
+
+
+// ---------------------------------------------------------
+// CVisualFrameImpl* CVisualFrameImpl::NewL
+// Two-phased constructor.
+// ---------------------------------------------------------
+//
+CVisualFrameImpl* CVisualFrameImpl::NewL(
+ TDes8& aBuffer,
+ const TSize& aDimension,
+ TInt aFrameFormat )
+ {
+
+ TFrameFormatBase* frameFormat = GetFrameFormatL( aFrameFormat );
+
+ CleanupStack::PushL( frameFormat );
+
+ TFrameLayout frameLayout = TFrameLayout( 1 );
+ frameLayout.SetStart( 0, 0 );
+ frameLayout.SetScanLength( 0, aBuffer.MaxLength() );
+ frameLayout.SetLength( 0, aBuffer.MaxLength() );
+ frameLayout.SetCurrentLength( 0, aBuffer.Length() );
+
+ CVisualFrameImpl* self = new ( ELeave ) CVisualFrameImpl();
+ CleanupStack::PushL( self );
+ self->ConstructL( aBuffer, aBuffer.MaxLength(), aDimension, *frameFormat, frameLayout );
+ CleanupStack::Pop( self );
+ CleanupStack::PopAndDestroy( frameFormat );
+
+ return self;
+ }
+
+// ---------------------------------------------------------
+// CVisualFrameImpl* CVisualFrameImpl::NewL
+// Two-phased constructor.
+// ---------------------------------------------------------
+//
+CVisualFrameImpl* CVisualFrameImpl::NewL(
+ RChunk& aChunk,
+ TInt aSize,
+ TInt aMaxSize,
+ TInt aDataOffset,
+ const TSize& aDimension,
+ TInt aFrameFormat )
+ {
+
+ TFrameFormatBase* frameFormat = GetFrameFormatL( aFrameFormat );
+ CleanupStack::PushL( frameFormat );
+
+ TFrameLayout frameLayout = TFrameLayout( 1 );
+
+ frameLayout.SetStart( 0, aDataOffset );
+ frameLayout.SetScanLength( 0, aMaxSize );
+ frameLayout.SetLength( 0, aMaxSize );
+ frameLayout.SetCurrentLength( 0, aSize );
+
+ CVisualFrameImpl* self = new ( ELeave ) CVisualFrameImpl();
+ CleanupStack::PushL( self );
+ self->ConstructL( &aChunk, aMaxSize, aDataOffset, aDimension, *frameFormat, frameLayout );
+ self->iSize = aSize;
+ CleanupStack::Pop( self );
+ CleanupStack::PopAndDestroy( frameFormat );
+
+ return self;
+ }
+
+// ---------------------------------------------------------
+// CVisualFrameImpl* CVisualFrameImpl::NewL
+// Two-phased constructor.
+// ---------------------------------------------------------
+//
+CVisualFrameImpl* CVisualFrameImpl::NewL(
+ TDes8& aBuffer,
+ const TSize& aDimension,
+ TInt aFrameFormat,
+ const CVisualFrame::TFrameLayout& aFrameLayout )
+ {
+ TFrameFormatBase* frameFormat = GetFrameFormatL( aFrameFormat );
+ CleanupStack::PushL( frameFormat );
+
+ TFrameLayout frameLayout = TFrameLayout( aFrameLayout.iNumberOfPlanes );
+
+ for ( TInt i = 0; i < aFrameLayout.iNumberOfPlanes; ++i )
+ {
+ frameLayout.SetStart( i, aFrameLayout.iOffset[i] );
+ frameLayout.SetScanLength( i, aFrameLayout.iScanLineLength[i] );
+ frameLayout.SetLength( i, aFrameLayout.iMaxLength[i] );
+ frameLayout.SetCurrentLength( i, aFrameLayout.iLength[i] );
+ }
+
+ CVisualFrameImpl* self = new ( ELeave ) CVisualFrameImpl();
+ CleanupStack::PushL( self );
+ self->ConstructL( aBuffer, aBuffer.MaxLength(), aDimension, *frameFormat, frameLayout );
+ CleanupStack::Pop( self );
+ CleanupStack::PopAndDestroy( frameFormat );
+
+ return self;
+ }
+
+// ---------------------------------------------------------
+// CVisualFrameImpl* CVisualFrameImpl::NewL
+// Two-phased constructor.
+// ---------------------------------------------------------
+//
+CVisualFrameImpl* CVisualFrameImpl::NewL(
+ RChunk& aChunk,
+ TInt aSize,
+ TInt aMaxSize,
+ const TSize& aDimension,
+ TInt aFrameFormat,
+ const CVisualFrame::TFrameLayout& aFrameLayout )
+ {
+ TFrameFormatBase* frameFormat = GetFrameFormatL( aFrameFormat );
+ CleanupStack::PushL( frameFormat );
+
+ TFrameLayout frameLayout = TFrameLayout( aFrameLayout.iNumberOfPlanes );
+
+ for ( TInt i = 0; i < aFrameLayout.iNumberOfPlanes; ++i )
+ {
+ frameLayout.SetStart( i, aFrameLayout.iOffset[i] );
+ frameLayout.SetScanLength( i, aFrameLayout.iScanLineLength[i] );
+ frameLayout.SetLength( i, aFrameLayout.iMaxLength[i] );
+ frameLayout.SetCurrentLength( i, aFrameLayout.iLength[i] );
+ }
+
+ CVisualFrameImpl* self = new ( ELeave ) CVisualFrameImpl();
+ CleanupStack::PushL( self );
+ self->ConstructL( &aChunk, aMaxSize, aFrameLayout.iOffset[0], aDimension, *frameFormat, frameLayout );
+ self->iSize = aSize;
+ CleanupStack::Pop( self );
+ CleanupStack::PopAndDestroy( frameFormat );
+
+ return self;
+ }
+
+// ---------------------------------------------------------
+// CVisualFrameImpl* CVisualFrameImpl::NewL
+// Two-phased constructor.
+// ---------------------------------------------------------
+//
+CVisualFrameImpl* CVisualFrameImpl::NewL( const CImageFrame* aImageFrame )
+ {
+ if ( ( aImageFrame->FrameFormat().Type() != KUidIclImageFrameFormat ) &&
+ ( aImageFrame->FrameFormat().Type() != KUidExtIclImageFrameFormat ) )
+ {
+ User::Leave( KErrNotSupported );
+ }
+ CVisualFrameImpl* self = new ( ELeave ) CVisualFrameImpl();
+ CleanupStack::PushL( self );
+ if ( aImageFrame->IsChunk() )
+ {
+ self->ConstructL(
+ &const_cast<CImageFrame*>( aImageFrame )->DataChunk(),
+ aImageFrame->MaxBufferSize(),
+ aImageFrame->DataOffset(),
+ aImageFrame->FrameSizeInPixels(),
+ aImageFrame->FrameFormat(),
+ aImageFrame->FrameLayout() );
+ const TFrameLayout& frameLayout = reinterpret_cast<const TFrameLayout&>( aImageFrame->FrameLayout() );
+ self->iSize = frameLayout.CurrentLength( frameLayout.Planes() - 1 ) + frameLayout.Start( frameLayout.Planes() - 1 ) - frameLayout.Start( 0 );
+ }
+ else
+ {
+ self->ConstructL(
+ const_cast<CImageFrame*>( aImageFrame )->Data(),
+ aImageFrame->MaxBufferSize(),
+ aImageFrame->FrameSizeInPixels(),
+ aImageFrame->FrameFormat(),
+ aImageFrame->FrameLayout() );
+ }
+
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+// ---------------------------------------------------------
+// CVisualFrameImpl::GetImageFrameL
+// ---------------------------------------------------------
+//
+CImageFrame* CVisualFrameImpl::GetImageFrameL()
+ {
+ if ( FrameFormat().Type() != KUidIclImageFrameFormat )
+ {
+ User::Leave( KErrNotSupported );
+ }
+
+ if ( IsChunk() )
+ {
+ return CImageFrame::NewL(
+ &DataChunk(),
+ MaxBufferSize(),
+ DataOffset(),
+ FrameSizeInPixels(),
+ FrameFormat(),
+ FrameLayout() );
+ }
+ else
+ {
+ return CImageFrame::NewL(
+ Data(),
+ MaxBufferSize(),
+ FrameSizeInPixels(),
+ FrameFormat(),
+ FrameLayout() );
+ }
+ }
+
+// ---------------------------------------------------------
+// CVisualFrameImpl::DataChunkL
+// ---------------------------------------------------------
+//
+const RChunk& CVisualFrameImpl::DataChunkL() const
+ {
+ if ( !IsChunk() )
+ {
+ User::Leave( KErrNotFound );
+ }
+ return const_cast<CVisualFrameImpl*>( this )->DataChunk();
+ }
+
+// ---------------------------------------------------------
+// CVisualFrameImpl::DataPtrL
+// ---------------------------------------------------------
+//
+TPtr8 CVisualFrameImpl::DataPtrL() const
+ {
+ if ( IsChunk() )
+ {
+ User::Leave( KErrNotFound );
+ }
+ TDes8& des = const_cast<CVisualFrameImpl*>( this )->Data();
+ return TPtr8( const_cast<TUint8*>( des.Ptr() ), des.Length(), des.MaxLength() );
+ }
+
+// ---------------------------------------------------------
+// CVisualFrameImpl::Dimension
+// ---------------------------------------------------------
+//
+TSize CVisualFrameImpl::Dimension() const
+ {
+ return FrameSizeInPixels();
+ }
+
+// ---------------------------------------------------------
+// CVisualFrameImpl::FrameFormat2
+// ---------------------------------------------------------
+//
+TInt CVisualFrameImpl::FrameFormat2() const
+ {
+ return GetFrameFormat( FrameFormat() );
+ }
+
+// ---------------------------------------------------------
+// CVisualFrameImpl::DataOffset
+// ---------------------------------------------------------
+//
+TInt CVisualFrameImpl::DataOffset() const
+ {
+ return CImageFrame::DataOffset();
+ }
+
+// ---------------------------------------------------------
+// CVisualFrameImpl::Size
+// ---------------------------------------------------------
+//
+TInt CVisualFrameImpl::Size() const
+ {
+ if ( !IsChunk() )
+ {
+ return Data().Length();
+ }
+ return iSize;
+ }
+
+// ---------------------------------------------------------
+// CVisualFrameImpl::SetSizeL
+// ---------------------------------------------------------
+//
+void CVisualFrameImpl::SetSizeL( TInt aSize )
+ {
+ if ( ( aSize < 0 ) || ( aSize > MaxSize() ) )
+ {
+ User::Leave( KErrArgument );
+ }
+ if ( !IsChunk() )
+ {
+ Data().SetLength( aSize );
+ }
+ iSize = aSize;
+ }
+
+// ---------------------------------------------------------
+// CVisualFrameImpl::MaxSize
+// ---------------------------------------------------------
+//
+TInt CVisualFrameImpl::MaxSize() const
+ {
+ return MaxBufferSize();
+ }
+
+// ---------------------------------------------------------
+// CVisualFrameImpl::DataContainer
+// ---------------------------------------------------------
+//
+TInt CVisualFrameImpl::DataContainer() const
+ {
+ if ( IsChunk() )
+ {
+ return CVisualFrame::EInChunk;
+ }
+ return CVisualFrame::EInDescriptor;
+ }
+
+// ---------------------------------------------------------
+// CVisualFrameImpl::FrameLayout2
+// ---------------------------------------------------------
+//
+const CVisualFrame::TFrameLayout& CVisualFrameImpl::FrameLayout2() const
+ {
+ const TFrameLayout& frameLayout = reinterpret_cast<const TFrameLayout&>( FrameLayout() );
+ CVisualFrame::TFrameLayout& frameLayout2 = const_cast<CVisualFrameImpl*>( this )->iFrameLayout2;
+ frameLayout2.iNumberOfPlanes = frameLayout.Planes();
+ for (TInt i = 0; i < iFrameLayout2.iNumberOfPlanes; ++i )
+ {
+ frameLayout2.iOffset[i] = frameLayout.Start( i );
+ frameLayout2.iScanLineLength[i] = frameLayout.ScanLength( i );
+ frameLayout2.iLength[i] = frameLayout.CurrentLength( i );
+ frameLayout2.iMaxLength[i] = frameLayout.Length( i );
+ }
+ return iFrameLayout2;
+ }
+
+// ---------------------------------------------------------
+// CVisualFrameImpl::~CVisualFrameImpl
+// Destructor
+// ---------------------------------------------------------
+//
+CVisualFrameImpl::~CVisualFrameImpl()
+ {
+ }
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_plat/ecam_face_tracking_custom_api/ecam_face_tracking_custom_api.metaxml Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,13 @@
+<?xml version="1.0" ?>
+<api id="2a36f7ac07856e789b808483ccab0b38" dataversion="2.0">
+<name>ECam Face Tracking Custom API</name>
+<description>This ECam custom API controls the face tracking features. Face tracking algorithm is implemented by ECam and potentially other adaptation components. Any ECam client can use this custom interface to query for supported face tracking features, enable or disable tracking, and control face indicator rendering. ECam implementation is responsible for rendering face indicators around detected faces if the feature enabled.</description>
+<type>c++</type>
+<collection>imageadaptationextensions</collection>
+<libs></libs>
+<release category="platform" sinceversion="5.1"/>
+<attributes>
+<htmldocprovided>no</htmldocprovided>
+<adaptation>yes</adaptation>
+</attributes>
+</api>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_plat/ecam_face_tracking_custom_api/group/bld.inf Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,26 @@
+/*
+* Copyright (c) 2008 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: This Custom API controls the Face Tracking features.
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_EXPORTS
+
+../inc/ecamfacetrackingcustomapi.h OS_LAYER_PLATFORM_EXPORT_PATH(ecamfacetrackingcustomapi.h)
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_plat/ecam_face_tracking_custom_api/inc/ecamfacetrackingcustomapi.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,149 @@
+/*
+* Copyright (c) 2008 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: This Custom API controls the Face Tracking features.
+*
+*/
+
+
+#ifndef ECAMFACETRACKINGCUSTOMAPI_H
+#define ECAMFACETRACKINGCUSTOMAPI_H
+
+#include <e32base.h>
+
+// CONSTANTS
+
+const TUid KCameraFaceTrackingUid = { 0x2001E2AF };
+
+// CLASS DECLARATION
+
+/**
+* Custom interface for Face Tracking setting.
+*
+* @since S60 v5.1
+*/
+class MCameraFaceTracking
+ {
+
+public:
+
+ /**
+ * List of supported face tracking settings
+ */
+ enum TFaceTrackingSettings
+ {
+ EFaceTrackingSupported = 0x1, /// @see SetFaceTrackingL()
+ EFaceIndicatorsSupported = 0x2, /// @see EnableFaceIndicatorsL()
+ EFaceSelectionSupported = 0x4, /// @see SetFaceSelectionPointL()
+ EFaceRectanglesSupported = 0x8 /// @see GetFaceRectanglesL()
+ };
+
+ /**
+ * Returns a bitfield of supported face tracking settings. The bitfield
+ * is a combination of TFaceTrackingSettings enumeration values.
+ *
+ * @since S60 v5.1
+ * @return a bitfield that contains list of supported face tracking settings
+ */
+ virtual TUint32 SupportedFaceTrackingSettings() = 0;
+
+ /**
+ * Enables or disables face tracking.
+ *
+ * @since S60 v5.1
+ * @param aFaceTrackingOn face tracking switch
+ * @leave KErrNotSupported if face tracking is not supported
+ * @leave KErrInUse if camera is not reserved
+ * @leave KErrNotReady if camera power is not on
+ */
+ virtual void SetFaceTrackingL( TBool aFaceTrackingOn ) = 0;
+
+ /**
+ * Returns current face tracking status.
+ *
+ * @since S60 v5.1
+ * @return ETrue if face tracking is on
+ */
+ virtual TBool FaceTrackingOn() const = 0;
+
+ /**
+ * Sets drawing of face indicators on or off. If drawing is off or not
+ * supported, application should draw face indicators itself. In this
+ * situation application should also do face selection itself.
+ *
+ * @since S60 v5.1
+ * @param aIndicatorsOn indicators switch
+ * @leave KErrNotSupported if drawing of face indicators is not supported
+ * @leave KErrInUse if camera is not reserved
+ * @leave KErrNotReady if camera power is not on
+ */
+ virtual void EnableFaceIndicatorsL( TBool aIndicatorsOn ) = 0;
+
+ /**
+ * Returns current status of face indicators
+ *
+ * @since S60 v5.1
+ * @return ETrue if face indicators are drawn
+ */
+ virtual TBool FaceIndicatorsOn() const = 0;
+
+ /**
+ * Sets a point that is used for selecting or deselecting the primary
+ * face among all detected faces.
+ *
+ * The given point is used to select or deselect (in case the face is
+ * already selected) a primary face. In case drawing of face indicators
+ * is on, it is up to the implementation to decide which face is
+ * selected/deselected using the point coordinates provided by this method.
+ * In case drawing of face indicators is off, application should do face
+ * selection itself and use this method to pass the point where the camera
+ * adjustment should be made (e.g., focus) i.e. center of currently
+ * selected face.
+ *
+ * Reference size defines the coordinate space where the point
+ * coordinates reside. Thus the point coordinates are within the
+ * rectangle [[0,0], [aReferenceSize.iWidth,aReferenceSize.iHeight]].
+ * Usually the reference size is the same as viewfinder size.
+ *
+ * @since S60 v5.1
+ * @param aFaceSelectionPoint coordinates of the selection point
+ * @param aReferenceSize reference size for the selection point coordinates
+ * @leave KErrNotSupported if face selection is not supported
+ * @leave KErrInUse if camera is not reserved
+ * @leave KErrNotReady if camera power is not on or face tracking is not on
+ */
+ virtual void SetFaceSelectionPointL(
+ const TPoint& aFaceSelectionPoint,
+ const TSize& aReferenceSize ) = 0;
+
+ /**
+ * Returns rectangles of faces in the given array and a reference size that
+ * defines the limits for the coordinate space where the rectangle
+ * coordinates reside.
+ *
+ * This method should be called only when drawing of face indicators is off.
+ * Application can draw face indicators and do face selection using these
+ * rectangles. The array is empty if no faces were detected.
+ *
+ * @since S60 v5.1
+ * @param aRectangles array where rectangles of the faces are returned
+ * @return reference size for the face rectangles
+ * @leave KErrNotSupported if returning face rectangles is not supported
+ * @leave KErrInUse if camera is not reserved
+ * @leave KErrNotReady if camera power is not on or face tracking is not on
+ */
+ virtual TSize GetFaceRectanglesL( RArray<TRect>& aRectangles ) = 0;
+
+ };
+
+#endif //ECAMFACETRACKINGCUSTOMAPI_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_plat/ecam_orientation_custom_api/ecam_orientation_custom_api.metaxml Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,13 @@
+<?xml version="1.0" ?>
+<api id="4fb44b6b6cf3408d9b58e2099011c0ac" dataversion="2.0">
+<name>ecam orientation custom api</name>
+<description>Custom interface for Orientation setting</description>
+<type>c++</type>
+<collection>imageadaptationextensions</collection>
+<libs></libs>
+<release category="platform" sinceversion="5.0"/>
+<attributes>
+<htmldocprovided>no</htmldocprovided>
+<adaptation>no</adaptation>
+</attributes>
+</api>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_plat/ecam_orientation_custom_api/group/bld.inf Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,27 @@
+/*
+* Copyright (c) 2008 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: File that exports the files belonging to
+* ECam Orientation Custom API
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_EXPORTS
+
+../inc/ECamOrientationCustomInterface2.h OS_LAYER_PLATFORM_EXPORT_PATH(ECamOrientationCustomInterface2.h)
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_plat/ecam_orientation_custom_api/inc/ECamOrientationCustomInterface2.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,72 @@
+/*
+* Copyright (c) 2006 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: Custom interface for Orientation setting.
+*
+*/
+
+
+#ifndef ECAMORIENTATIONCUSTOMINTERFACE_H
+#define ECAMORIENTATIONCUSTOMINTERFACE_H
+
+#include <e32base.h>
+
+// CONSTANTS
+
+const TUid KCameraOrientationUid = { 0x101F87CD };
+
+// CLASS DECLARATION
+
+/**
+* Custom interface for Orientation setting.
+*/
+class MCameraOrientation
+ {
+
+ public:
+
+ /**
+ * List of Orientation settings
+ */
+ enum TOrientation
+ {
+ EOrientation0 = 0x00,
+ EOrientation90 = 0x01,
+ EOrientation180 = 0x02,
+ EOrientation270 = 0x04
+ };
+
+ /**
+ * Gives the current Orientation setting value
+ * @return TOrientation
+ */
+ virtual TOrientation Orientation() const = 0;
+
+ /**
+ * Sets Orientation
+ * @param aValue new Orientation setting
+ * @leave KErrNotSupported if aValue is not supported
+ * @leave KErrInUse if camera is not reserved
+ * @leave KErrNotReady if camera power is not on
+ */
+ virtual void SetOrientationL( TOrientation aValue ) = 0;
+
+ /**
+ * Gives the bitfield of supported Orientation settings
+ * @return the bitfield that contains supported TOrientation settings
+ */
+ virtual TUint32 SupportedOrientations() const = 0;
+
+ };
+
+#endif //ECAMORIENTATIONCUSTOMINTERFACE_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_plat/ecam_ui_orientation_override_custom_api/ecam_ui_orientation_override_custom_api.metaxml Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,13 @@
+<?xml version="1.0" ?>
+<api id="4aae1b50ae1ddeb6863dc2a155d280e0" dataversion="2.0">
+<name>ECam UI Orientation Override Custom API</name>
+<description>This Custom API is created to fix the synchronization problem between Camera Application and Camera Server about the current screen orientation. CWsScreenDevice is used as a reference and Camera Application should use its NumScreenModes() and GetScreenModeSizeAndRotation() methods to inform it by the mode index, which mode it is currently in. It is most likely the one also returned by CurrentScreenMode() but also other mode can be given. Camera server then returns an error if that mode is not supported and some alternative value should be used if it's wanted to be set.</description>
+<type>c++</type>
+<collection>imageadaptationextensions</collection>
+<libs></libs>
+<release category="platform" sinceversion="5.1"/>
+<attributes>
+<htmldocprovided>no</htmldocprovided>
+<adaptation>yes</adaptation>
+</attributes>
+</api>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_plat/ecam_ui_orientation_override_custom_api/group/bld.inf Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,27 @@
+/*
+* Copyright (c) 2008 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: File that exports the files belonging to
+* ECam UI Orientation Override Custom API
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_EXPORTS
+
+../inc/ECamUIOrientationOverrideCustomAPI.h OS_LAYER_PLATFORM_EXPORT_PATH(ECamUIOrientationOverrideCustomAPI.h)
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_plat/ecam_ui_orientation_override_custom_api/inc/ECamUIOrientationOverrideCustomAPI.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,61 @@
+/*
+* Copyright (c) 2008 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: This Custom API is created to fix the synchronization problem
+* between Camera Application and Camera Server about the current
+* screen orientation. CWsScreenDevice is used as a reference and
+* Camera Application should use its NumScreenModes() and
+* GetScreenModeSizeAndRotation() methods to inform it by the mode
+* index, which mode it is currently in. It is most likely the one
+* also returned by CurrentScreenMode() but also other mode can be
+* given. Camera server then returns an error if that mode is not
+* supported and some alternative value should be used if it's
+* wanted to be set.
+*
+*/
+
+
+#ifndef ECAMUIORIENTATIONOVERRIDECUSTOMAPI_H
+#define ECAMUIORIENTATIONOVERRIDECUSTOMAPI_H
+
+#include <e32base.h>
+
+// CONSTANTS
+
+const TUid KCameraUIOrientationOverrideUid = { 0x2001E2AE };
+
+// CLASS DECLARATION
+
+/**
+* Custom interface for Orientation setting.
+*/
+class MCameraUIOrientationOverride
+ {
+
+ public:
+
+ /**
+ * Sets Orientation mode and is based on wsini.ini that can be fetched
+ * from CWsScreenDevice. This method should be called after calling
+ * CCamera::New2L(), before CCamera::Reserve() and before
+ * CCamera::CameraInfo().
+ * @param aMode Mode that specifies the wanted orientation
+ * @leave KErrNotSupported if aMode is not supported
+ * @leave KErrGeneral if this method is not supported
+ * @leave KErrInUse if this method is not called at the right time
+ */
+ virtual void SetOrientationModeL( TInt aMode ) = 0;
+
+ };
+
+#endif //ECAMUIORIENTATIONOVERRIDECUSTOMAPI_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_plat/extended_icl_jpeg_api/extended_icl_jpeg_api.metaxml Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,19 @@
+<?xml version="1.0" ?>
+<api id="293063d490f04b693dfd8626cf320e26" dataversion="2.0">
+ <name>Extended ICL Jpeg API</name>
+ <description>Nokia specific extension to Symbian's JPEG, which provides certain memory efficient improvements(streaming) enocding/decoding and also some DCT domain based lossless(initial quality upkeeping) operations like overlaying, rotating, mirroring.
+</description>
+ <type>c++</type>
+ <collection>imageadaptationextensions</collection>
+ <libs>
+ <lib name="IclExtJpegApi.lib" />
+ </libs>
+ <release category="platform"/>
+ <attributes>
+ <!-- This indicates wether the api provedes separate html documentation -->
+ <!-- or is the additional documentation generated from headers. -->
+ <!-- If you are unsuere then the value is "no" -->
+ <htmldocprovided>no</htmldocprovided>
+ <adaptation>no</adaptation>
+ </attributes>
+</api>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_plat/extended_icl_jpeg_api/group/bld.inf Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,27 @@
+/*
+* Copyright (c) 2006 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: File that exports the files belonging to
+: Extended ICL Jpeg API
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_EXPORTS
+
+../inc/IclExtJpegApi.h OS_LAYER_PLATFORM_EXPORT_PATH(IclExtJpegApi.h)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_plat/extended_icl_jpeg_api/inc/IclExtJpegApi.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,1015 @@
+/*
+* Copyright (c) 2006 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: Definition of CVisualFrame, CExtJpegDecoder and CExtJpegEncoder
+*
+*/
+
+#ifndef _ICLEXTJPEGAPI_
+#define _ICLEXTJPEGAPI_
+
+#include "ImageConversion.h"
+#include <icl/Icl_UIDS.hrh>
+
+#include "ICLExifImageFrame.h"
+const TInt KMaxNumberOfPlanes = KMaxPlanesInFrame;
+const TUid KUidExtFormatJpeg = { 0 };
+const TUid KUidExtIclApiSupport = { 0 };
+const TInt KExtensionUID = 0x01010101;
+
+// FORWARD DECLARATIONS
+class CVisualFrameImpl;
+
+// CLASS DECLARATION
+
+/**
+* CVisualFrame
+* @lib IclExtJpegApi.lib
+* @since 3.2
+*/
+class CVisualFrame : public CBase
+ {
+ public:
+
+ // TFrameLayout contains the scan line lengths and offsets for each component in planar YUV case
+ class TFrameLayout
+ {
+ public:
+ TInt iNumberOfPlanes;
+ TInt iScanLineLength[KMaxNumberOfPlanes];
+ TInt iOffset[KMaxNumberOfPlanes];
+ TInt iLength[KMaxNumberOfPlanes];
+ TInt iMaxLength[KMaxNumberOfPlanes];
+ };
+
+ enum TDataContainer
+ {
+ EInChunk,
+ EInDescriptor
+ };
+
+ enum TDataFormat
+ {
+ /* Copied from CCamera::TFormat: */
+
+ /** 8 bit greyscale values, 0=black, 255=white. */
+ EFormatMonochrome = 0x0001,//+
+ /** Packed RGB triplets, 4 bits per pixel with red in the least significant bits
+ and the 4 most significant bits unused. */
+ EFormat16bitRGB444 = 0x0002,//+
+ /** Packed RGB triplets, 5 bits per pixel for red and blue and 6 bits for green,
+ with red in the least significant bits. */
+ EFormat16BitRGB565 = 0x0004,//+
+ /** Packed RGB triplets, 8 bits per pixel with red in the least significant bits
+ and the 8 most significant bits unused. */
+ EFormat32BitRGB888 = 0x0008,//+
+ /** JFIF JPEG. */
+ EFormatJpeg = 0x0010,
+ /** EXIF JPEG */
+ EFormatExif = 0x0020,
+ /** CFbsBitmap object with display mode EColor4K. */
+ EFormatFbsBitmapColor4K = 0x0040,
+ /** CFbsBitmap object with display mode EColor64K. */
+ EFormatFbsBitmapColor64K = 0x0080,
+ /** CFbsBitmap object with display mode EColor16M. */
+ EFormatFbsBitmapColor16M = 0x0100,
+ /** Implementation dependent. */
+ EFormatUserDefined = 0x0200,
+ /** 4:2:0 format, 8 bits per sample, Y00Y01Y10Y11UV. */
+ EFormatYUV420Interleaved = 0x0400,//+
+ /** 4:2:0 format, 8 bits per sample, Y00Y01Y02Y03...U0...V0... */
+ EFormatYUV420Planar = 0x0800,//+
+ /** 4:2:2 format, 8 bits per sample, UY0VY1. */
+ EFormatYUV422 = 0x1000,//+
+ /** 4:2:2 format, 8 bits per sample, Y1VY0U. */
+ EFormatYUV422Reversed = 0x2000,//+
+ /** 4:4:4 format, 8 bits per sample, Y00U00V00 Y01U01V01... */
+ EFormatYUV444 = 0x4000,//+
+ /** 4:2:0 format, 8 bits per sample, Y00Y01Y02Y03...U0V0... */
+ EFormatYUV420SemiPlanar = 0x8000,//+
+
+ /* Other formats: */
+
+ /** 4:2:2 format, 8 bits per sample, Y0Y1UV. */
+ EFormatExtYUV422Interleaved = 0x00100000,
+ /** 4:2:2 format, 8 bits per sample, Y0Y1Y2...U0U1...V0V1. */
+ EFormatExtYUV422Planar = 0x00200000,
+ /** 4:4:4 format, 8 bits per sample, Y0U0V0Y1U1V1. */
+ EFormatExtYUV444Planar = 0x00400000,
+ /** DCT coefficients */
+ EFormatExtDctCoeff = 0x00800000,
+
+ };
+
+ public: // New functions
+
+ /**
+ * Symbian C++ Two-phased constructor.
+ * @since 3.2
+ * @param aBuffer A descriptor reference to buffer containing the image data.
+ * @param aDimension The dimensions of the corresponding image data.
+ * @param aFrameFormat The frame format of the corresponding image data.
+ * @return CVisualFrame* A pointer to frame object.
+ */
+ IMPORT_C static CVisualFrame* NewL(
+ TDes8& aBuffer,
+ const TSize& aDimension,
+ TInt aFrameFormat );
+
+ /**
+ * Symbian C++ Two-phased constructor.
+ * @since 3.2
+ * @param aChunk An RChunk reference to buffer containing the image data.
+ * @param aSize The amount of image data in bytes.
+ * @param amaxSize The maximum size of the memory reserved in the chunk.
+ * @param aDataOffset The offset value specifying the location of the image
+ * data in the chunk.
+ * @param aDimension The dimensions of the corresponding image data.
+ * @param aFrameFormat The frame format of the corresponding image data.
+ * @return CVisualFrame* A pointer to frame object.
+ */
+ IMPORT_C static CVisualFrame* NewL(
+ RChunk& aChunk,
+ TInt aSize,
+ TInt aMaxSize,
+ TInt aDataOffset,
+ const TSize& aDimension,
+ TInt aFrameFormat );
+
+ /**
+ * Symbian C++ Two-phased constructor.
+ * @since 3.2
+ * @param aBuffer A descriptor reference to buffer containing the image data.
+ * @param aDimension The dimensions of the corresponding image data.
+ * @param aFrameLayout The layout of the image color components.
+ * @return CVisualFrame* A pointer to frame object.
+ */
+ IMPORT_C static CVisualFrame* NewL(
+ TDes8& aBuffer,
+ const TSize& aDimension,
+ TInt aFrameFormat,
+ const TFrameLayout& aFrameLayout );
+
+ /**
+ * Symbian C++ Two-phased constructor.
+ * @since 3.2
+ * @param aChunk An RChunk reference to buffer containing the image data.
+ * @param aSize The amount of image data in bytes.
+ * @param aMaxSize The maximum size of the memory reserved in the chunk for
+ * the image data.
+ * @param aDimension The dimensions of the corresponding image data.
+ * @param aFrameFormat The frame format of the corresponding image data.
+ * @param aFrameLayout The layout of the image color components. TFrameLayout
+ * contains the scan line lengths and offsets for each component
+ * in planar YUV case
+ * @return CVisualFrame* A pointer to frame object.
+ */
+ IMPORT_C static CVisualFrame* NewL(
+ RChunk& aChunk,
+ TInt aSize,
+ TInt aMaxSize,
+ const TSize& aDimension,
+ TInt aFrameFormat,
+ const TFrameLayout& aFrameLayout );
+
+
+ /**
+ * Returns a constant reference to the chunk containing
+ * the image data, if exists.
+ * @since 3.2
+ * @return RChunk
+ */
+ IMPORT_C const RChunk& DataChunkL() const;
+
+ /**
+ * Returns a descriptor pointer to the image data location, if exists
+ * @since 3.2
+ * @return TPtr8
+ */
+ IMPORT_C TPtr8 DataPtrL() const;
+
+ /**
+ * Returns the dimensions of the image.
+ * @since 3.2
+ * @return TSize
+ */
+ IMPORT_C TSize Dimension() const;
+
+ /**
+ * Return the image data format.
+ * @since 3.2
+ * @return TInt
+ */
+ IMPORT_C TInt FrameFormat() const;
+
+ /**
+ * Returns the offset of the image data for non-planar,
+ * single-component or compressed images.
+ * @since 3.2
+ * @return TInt
+ */
+ IMPORT_C TInt DataOffset() const;
+
+ /**
+ * Returns the amount of stored image data in bytes.
+ * @since 3.2
+ * @return TInt
+ */
+ IMPORT_C TInt Size() const;
+
+ /**
+ * Sets the amount of image data to the given value.
+ * Should be called when the image data amount is modified explicitly.
+ * @since 3.2
+ * @return void
+ */
+ IMPORT_C void SetSizeL( TInt aSize );
+
+ /**
+ * Returns the maximum size of the memory space reserved for image data
+ * @since 3.2
+ * @return TInt
+ */
+ IMPORT_C TInt MaxSize() const;
+
+ /**
+ * Returns the storage type of the image data.
+ * @since 3.2
+ * @return TDataContainer
+ */
+ IMPORT_C TDataContainer DataContainer() const;
+
+ /**
+ * Returns the layout of the image data for planar compressed images.
+ * @since 3.2
+ * @return TFrameLayout
+ */
+ IMPORT_C const TFrameLayout& FrameLayout() const;
+
+ /**
+ * Destructor
+ */
+ IMPORT_C virtual ~CVisualFrame();
+
+ /**
+ * Symbian C++ Two-phased constructor.
+ */
+ IMPORT_C static CVisualFrame* NewL( const CImageFrame* aImageFrame );
+
+ /**
+ * Get image frame
+ * @since 3.2
+ * @return CImageFrame
+ */
+ IMPORT_C CImageFrame* GetImageFrameL();
+
+
+ private:
+
+ CVisualFrameImpl* iVisualFrameImpl;
+
+ };
+
+
+// CLASS DECLARATION
+
+/**
+* CExtJpegDecoder
+* @lib IclExtJpegApi.lib
+* @since 3.2
+*/
+class CExtJpegDecoder : public CJPEGImageFrameDecoder
+ {
+ public:
+
+ enum TDecoderCapability
+ {
+ ECapNone = 0x0000,
+ ECapCropping = 0x0001,
+ ECapStreaming = 0x0002,
+ ECapRotation = 0x0004,
+ ECapFlipping = 0x0008,
+ ECapMirroring = 0x0010,
+ ECapDctDecoding = 0x0020,
+ ECapExifData = 0x0040
+ };
+
+ enum TDecoderOperations
+ {
+ EEnd = 0x00010000,
+ ESupportedFormats = 0x00020000,
+ ECapabilities = 0x00040000,
+ EReadyForAsync = 0x00080000,
+ EConvert = 0x00100000,
+ EContinueConvert = 0x00200000
+ };
+
+ enum TDecoderType
+ {
+ ESwImplementation = 0,
+ EHwImplementation
+ };
+
+ public:
+
+ /**
+ * Symbian C++ Two-phased constructor.
+ * @since 3.2
+ */
+ IMPORT_C static CExtJpegDecoder* NewL();
+
+
+ /**
+ * Creates and initializes CExtJpegDecoder
+ * @since 3.2
+ * @param aFs A reference to a file server session to use.
+ * @param aSourceFilename The name of the Jpeg file to decode.
+ * @param aMIMEType The Jpeg MIME type for matching the decoder plugin.
+ * @param aOptions Decoder options defined in ICL.
+ * @return CExtJpegDecoder* A pointer to decoder object.
+ */
+ IMPORT_C static CExtJpegDecoder* FileNewL(
+ RFs& aFs,
+ const TDesC& aSourceFilename,
+ const TDesC8& aMIMEType,
+ const TOptions aOptions = EOptionNone );
+
+ /**
+ * Creates and initializes CExtJpegDecoder
+ * @since 3.2
+ * @param aFs A reference to a file server session to use.
+ * @param aSourceFilename The name of the Jpeg file to decode.
+ * @param aOptions Decoder options defined in ICL.
+ * @param aImageType The Jpeg image type.
+ * @param aImageSubType The Jpeg image subtype (Null UID).
+ * @param aDecoderUid The decoder plugin UID.
+ * @return CExtJpegDecoder* A pointer to decoder object.
+ */
+ IMPORT_C static CExtJpegDecoder* FileNewL(
+ RFs& aFs,
+ const TDesC& aSourceFilename,
+ const TOptions aOptions = EOptionNone,
+ const TUid aImageType = KNullUid,
+ const TUid aImageSubType = KNullUid,
+ const TUid aDecoderUid = KNullUid );
+
+ /**
+ * Creates and initializes CExtJpegDecoder
+ * @since 3.2
+ * @param aFs A reference to a file server session to use.
+ * @param aSourceData The descriptor reference for the Jpeg image data to decode.
+ * @param aMIMEType The Jpeg MIME type for matching the decoder plugin.
+ * @param aOptions Decoder options defined in ICL.
+ * @return CExtJpegDecoder* A pointer to decoder object.
+ */
+ IMPORT_C static CExtJpegDecoder* DataNewL(
+ RFs& aFs,
+ const TDesC8& aSourceData,
+ const TDesC8& aMIMEType,
+ const TOptions aOptions = EOptionNone );
+ /**
+ * Creates and initializes CExtJpegDecoder
+ * @since 3.2
+ * @param aFs A reference to a file server session to use.
+ * @param aSourceData The descriptor reference for the Jpeg image data to decode.
+ * @param aOptions Decoder options defined in ICL.
+ * @param aImageType The Jpeg image type.
+ * @param aImageSubType The Jpeg image subtype (Null UID).
+ * @param aDecoderUid The decoder plugin UID.
+ * @return CExtJpegDecoder* A pointer to decoder object.
+ */
+ IMPORT_C static CExtJpegDecoder* DataNewL(
+ RFs& aFs,
+ const TDesC8& aSourceData,
+ const TOptions aOptions = EOptionNone,
+ const TUid aImageType = KNullUid,
+ const TUid aImageSubType = KNullUid,
+ const TUid aDecoderUid = KNullUid );
+
+ /**
+ * Creates and initializes CExtJpegDecoder
+ * @since 3.2
+ * @param aFs A reference to a file server session to use.
+ * @param aSourceData Pointer to the visual frame structure keeping
+ * the Jpeg image data to decode.
+ * @param aMIMEType The Jpeg MIME type for matching the decoder plugin.
+ * @param aOptions Decoder options defined in ICL.
+ * @return CExtJpegDecoder* A pointer to decoder object.
+ */
+ IMPORT_C static CExtJpegDecoder* DataNewL(
+ RFs& aFs,
+ const CVisualFrame* aSourceData,
+ const TDesC8& aMIMEType,
+ const TOptions aOptions = EOptionNone );
+
+ /**
+ * Creates and initializes CExtJpegDecoder
+ * @since 3.2
+ * @param aFs A reference to a file server session to use.
+ * @param aSourceData Pointer to the visual frame structure keeping
+ * the Jpeg image data to decode.
+ * @param aOptions Decoder options defined in ICL.
+ * @param aImageType The Jpeg image type.
+ * @param aImageSubType The Jpeg image subtype (Null UID).
+ * @param aDecoderUid The decoder plugin UID.
+ * @return CExtJpegDecoder* A pointer to decoder object.
+ */
+ IMPORT_C static CExtJpegDecoder* DataNewL(
+ RFs& aFs,
+ const CVisualFrame* aSourceData,
+ const TOptions aOptions = EOptionNone,
+ const TUid aImageType = KNullUid,
+ const TUid aImageSubType = KNullUid,
+ const TUid aDecoderUid = KNullUid );
+
+ /**
+ * Destructor.
+ */
+ IMPORT_C virtual ~CExtJpegDecoder();
+
+ /**
+ * Enables the use of cropping feature and specifies the cropping region.
+ * @since 3.2
+ * @param aCropRect The rectangular cropping region that will be decoded.
+ * @return void
+ */
+ IMPORT_C void SetCroppingL( TRect aCropRect );
+
+ /**
+ * Enables the use of streaming feature and retrieves the macroblock
+ * dimensions in the Jpeg data.
+ * @since 3.2
+ * @param aMacroBlockSize The macroblock dimensions in the
+ * Jpeg image that is set by the decoder
+ * @return void
+ */
+ IMPORT_C void SetStreamingL( TSize& aMacroBlockSize );
+
+ /**
+ * Enables the use of rotation feature and specifies the rotating degree.
+ * @since 3.2
+ * @param aDegree The rotation degree. Can take any values between 1 and 359.
+ * @return void
+ */
+ IMPORT_C void SetRotationL( TInt aDegree );
+
+ /**
+ * Enables the use of flipping feature.
+ * @since 3.2
+ * @return void
+ */
+ IMPORT_C void SetFlippingL();
+
+ /**
+ * Enables the use of mirroring feature.
+ * @since 3.2
+ * @return void
+ */
+ IMPORT_C void SetMirroringL();
+
+ /**
+ * SEnables the use of DCT decoding feature.
+ * @since 3.2
+ * @return void
+ */
+ IMPORT_C void SetDctDecodingL();
+
+ /**
+ * Asynchronous function for initiating the decoding
+ * @since 3.2
+ * @param aRequestStatus The pointer to the status of the operation
+ * that is set by the decoder after it is completed.
+ * After a complete successful operation, the status
+ * is KErrNone.
+ * @param aDestinationFrame Pointer to the visual frame structure that is keeping
+ * the destination image data. The client should do the
+ * proper allocation of the destination location.
+ * @param aNoOfDecodedMBlocks Reference to the number of decoded macroblocks that is
+ * set by the decoder after the decoding is completed.
+ * @param aFrameNumber The frame index in the Jpeg image.
+ * @return void
+ */
+ IMPORT_C void ConvertL(
+ TRequestStatus* aRequestStatus,
+ const CVisualFrame* aDestinationFrame,
+ TInt& aNoOfDecodedMBlocks,
+ TInt aFrameNumber = 0 );
+
+ /**
+ * Asynchronous function for initiating one of the iterations of streamed decoding.
+ * @since 3.2
+ * @param aRequestStatus The pointer to the status of the operation
+ * that is set by the decoder after it is completed.
+ * After a complete successful operation, the status
+ * is KErrNone.
+ * @param aDestinationFrame Pointer to the visual frame structure that is keeping
+ * the destination image data. The client should do the
+ * proper allocation of the destination location.
+ * @param aNoOfDecodedMBlocks Reference to the number of decoded macroblocks that is
+ * set by the decoder after the decoding is completed.
+ * @param aFrameNumber The frame index in the Jpeg image.
+ * @return void
+ */
+ IMPORT_C void ContinueConvertL(
+ TRequestStatus* aRequestStatus,
+ const CVisualFrame* aDestinationFrame,
+ TInt& aNoOfDecodedMBlocks,
+ TInt aFrameNumber = 0 );
+
+ /**
+ * Returns the destination (uncompressed) data formats that are supported by the decoder
+ * @since 3.2
+ * @return TInt The supported destination (uncompressed) data formats.
+ * The value is a combination of the flags defined in
+ * CVisualFrame::TDataFormat.
+ */
+ IMPORT_C TInt SupportedFormatsL();
+
+ /**
+ * Returns the Extended API features (capabilities) that are supported by the decoder.
+ * @since 3.2
+ * @return TInt The supported Extended API features.
+ * The value is a combination of the flags defined in TDecoderCapabilities.
+ */
+ IMPORT_C TInt CapabilitiesL();
+
+ /**
+ * Creates and initializes CExtJpegDecoder
+ * @since 3.2
+ * @param aDecoderType Decoder implementation type: HW or SW.
+ * @param aFs A reference to a file server session to use.
+ * @param aSourceFilename The name of the Jpeg file to decode.
+ * @param aOptions Decoder options defined in ICL.
+ * @return CExtJpegDecoder* A pointer to decoder object.
+ */
+ IMPORT_C static CExtJpegDecoder* FileNewL(
+ const TDecoderType aDecoderType,
+ RFs& aFs,
+ const TDesC& aSourceFilename,
+ const TOptions aOptions = EOptionNone );
+
+ /**
+ * Creates and initializes CExtJpegDecoder
+ * @since 3.2
+ * @param aDecoderType Decoder implementation type: HW or SW.
+ * @param aFs A reference to a file server session to use.
+ * @param aSourceData The descriptor reference for the Jpeg image data to decode.
+ * @param aOptions Decoder options defined in ICL.
+ * @return CExtJpegDecoder* A pointer to decoder object.
+ */
+ IMPORT_C static CExtJpegDecoder* DataNewL(
+ const TDecoderType aDecoderType,
+ RFs& aFs,
+ const TDesC8& aSourceData,
+ const TOptions aOptions = EOptionNone );
+
+ /**
+ * Creates and initializes CExtJpegDecoder
+ * @since 3.2
+ * @param aDecoderType Decoder implementation type: HW or SW.
+ * @param aFs A reference to a file server session to use.
+ * @param aSourceData Pointer to the visual frame structure keeping
+ * the Jpeg image data to decode.
+ * @param aOptions Decoder options defined in ICL.
+ * @return CExtJpegDecoder* A pointer to decoder object.
+ */
+ IMPORT_C static CExtJpegDecoder* DataNewL(
+ const TDecoderType aDecoderType,
+ RFs& aFs,
+ const CVisualFrame* aSourceData,
+ const TOptions aOptions = EOptionNone );
+
+ /**
+ * Convert
+ * @since 3.2
+ * @param aRequestStatus The pointer to the status of the operation
+ * that is set by the decoder after it is completed.
+ * After a complete successful operation, the status
+ * is KErrNone.
+ * @param aDestination
+ * @param aFrameNumber The frame index in the Jpeg image.
+ * @return void
+ */
+ IMPORT_C void Convert( TRequestStatus* aRequestStatus,
+ CFbsBitmap& aDestination, TInt aFrameNumber = 0);
+
+ /**
+ * Convert
+ * @since 3.2
+ * @param aRequestStatus The pointer to the status of the operation
+ * that is set by the decoder after it is completed.
+ * After a complete successful operation, the status
+ * is KErrNone.
+ * @param aDestination Bitmap destination
+ * @param aDestinationMask Bitmap destination mask
+ * @param aFrameNumber The frame index in the Jpeg image.
+ * @return void
+ */
+ IMPORT_C void Convert( TRequestStatus* aRequestStatus,
+ CFbsBitmap& aDestination,
+ CFbsBitmap& aDestinationMask,
+ TInt aFrameNumber = 0 );
+
+ /**
+ * Continue convert
+ * @since 3.2
+ * @param aRequestStatus The pointer to the status of the operation
+ * that is set by the decoder after it is completed.
+ * After a complete successful operation, the status
+ * is KErrNone.
+ * @return void
+ */
+ IMPORT_C void ContinueConvert( TRequestStatus* aRequestStatus );
+
+ private:
+
+ /**
+ * C++ default constructor.
+ */
+ CExtJpegDecoder();
+
+ /**
+ * Get an uid by version range
+ * @since 3.2
+ * @param aMinVersion
+ * @param aMaxVersion
+ * @return TUid
+ */
+ static TUid GetUidByVersionRangeL( TInt aMinVersion, TInt aMaxVersion );
+
+ TBool iIsExtConvert;
+
+ };
+
+
+// CLASS DECLARATION
+
+/**
+* CExtJpegEncoder
+* @lib IclExtJpegApi.lib
+* @since 3.2
+*/
+class CExtJpegEncoder : public CJPEGImageFrameEncoder
+ {
+ public:
+
+ enum TEncoderCapability
+ {
+ ECapNone = 0x0000,
+ ECapStreaming = 0x0001,
+ ECapBitmapOverlay = 0x0002,
+ ECapImageReplacing = 0x0004,
+ ECapBitmapReplacing = 0x0008,
+ ECapLosslessRotation = 0x0010,
+ ECapLosslessFlipping = 0x0020,
+ ECapLosslessMirroring = 0x0040,
+ ECapDctEncoding = 0x0080
+ };
+
+ enum TEncoderOperations
+ {
+ EEnd = 0x00010000,
+ ESupportedFormats = 0x00020000,
+ ECapabilities = 0x00040000,
+ EReadyForAsync = 0x00080000,
+ EConvert = 0x00100000,
+ EContinueConvert = 0x00200000,
+ EDestVisualFrame = 0x00400000,
+ ENewDestData = 0x00800000,
+ EDestDataSize = 0x01000000
+ };
+
+ enum TEncoderType
+ {
+ ESwImplementation = 0,
+ EHwImplementation
+ };
+
+ public:
+
+
+ /**
+ * Symbian C++ Two-phased constructor.
+ */
+ IMPORT_C static CExtJpegEncoder* NewL();
+
+ /**
+ * Creates and initializes CExtJpegEncoder
+ * @since 3.2
+ * @param aFs A reference to a file server session to use.
+ * @param aDestinationFilename The name of the destination Jpeg file.
+ * @param aMIMEType The Jpeg MIME type for matching the encoder plugin.
+ * @param aOptions Encoder options defined in ICL.
+ * @return CExtJpegEncoder* A pointer to encoder object.
+ */
+ IMPORT_C static CExtJpegEncoder* FileNewL(
+ RFs& aFs,
+ const TDesC& aDestinationFilename,
+ const TDesC8& aMIMEType,
+ const TOptions aOptions = EOptionNone );
+
+ /**
+ * Creates and initializes CExtJpegEncoder
+ * @param aFs A reference to a file server session to use.
+ * @param aDestinationFilename The name of the destination Jpeg file.
+ * @param aOptions Encoder options defined in ICL.
+ * @param aImageT The Jpeg image type.
+ * @param aImageSubType The Jpeg image subtype (Null UID).
+ * @param aEncoderUid The encoder plugin UID.
+ * @return CExtJpegEncoder* A pointer to encoder object.
+ */
+ IMPORT_C static CExtJpegEncoder* FileNewL(
+ RFs& aFs,
+ const TDesC& aDestinationFilename,
+ const TOptions aOptions = EOptionNone,
+ const TUid aImageType = KNullUid,
+ const TUid aImageSubType = KNullUid,
+ const TUid aEncoderUid = KNullUid );
+
+ /**
+ * Creates and initializes CExtJpegEncoder
+ * @param aDestinationData Pointer reference to the destination
+ * Jpeg data location that will be allocated by the encoder.
+ * @param aMIMEType The Jpeg MIME type for matching the encoder plugin.
+ * @param aOptions Encoder options defined in ICL.
+ * @return CExtJpegEncoder* A pointer to encoder object.
+ */
+ IMPORT_C static CExtJpegEncoder* DataNewL(
+ HBufC8*& aDestinationData,
+ const TDesC8& aMIMEType,
+ const TOptions aOptions = EOptionNone);
+ /**
+ * Creates and initializes CExtJpegEncoder
+ * @param aDestinationData Pointer reference to the destination
+ * Jpeg data location that will be allocated by the encoder.
+ * @param aOptions Encoder options defined in ICL.
+ * @param aImageType The Jpeg image type.
+ * @param aImageSubType The Jpeg image subtype (Null UID).
+ * @param aEncoderUid The encoder plugin UID.
+ * @return CExtJpegEncoder* A pointer to encoder object.
+ */
+ IMPORT_C static CExtJpegEncoder* DataNewL(
+ HBufC8*& aDestinationData,
+ const TOptions aOptions = EOptionNone,
+ const TUid aImageType = KNullUid,
+ const TUid aImageSubType = KNullUid,
+ const TUid aEncoderUid = KNullUid);
+ /**
+ * Creates and initializes CExtJpegEncoder
+ * @param aDestinationData Pointer to the visual frame structure keeping the destination
+ * Jpeg data allocated with maximum size by the client.
+ * @param aMIMEType The Jpeg MIME type for matching the encoder plugin.
+ * @param aOptions Encoder options defined in ICL.
+ * @return CExtJpegEncoder* A pointer to encoder object.
+ */
+ IMPORT_C static CExtJpegEncoder* DataNewL(
+ const CVisualFrame* aDestinationData,
+ const TDesC8& aMIMEType,
+ const TOptions aOptions = EOptionNone);
+ /**
+ * Creates and initializes CExtJpegEncoder
+ * @param aDestinationData Pointer to the visual frame structure keeping the destination
+ * Jpeg data allocated with maximum size by the client.
+ * @param aOptions Encoder options defined in ICL.
+ * @param aImageType The Jpeg image type.
+ * @param aImageSubType The Jpeg image subtype (Null UID).
+ * @param aEncoderUid The encoder plugin UID.
+ * @return CExtJpegEncoder* A pointer to encoder object.
+ */
+ IMPORT_C static CExtJpegEncoder* DataNewL(
+ const CVisualFrame* aDestinationData,
+ const TOptions aOptions = EOptionNone,
+ const TUid aImageType = KNullUid,
+ const TUid aImageSubType = KNullUid,
+ const TUid aEncoderUid = KNullUid);
+
+ /**
+ * Destructor.
+ */
+ IMPORT_C virtual ~CExtJpegEncoder();
+
+ /**
+ * Enables the use of streaming feature and retrieves the
+ * macroblock dimensions in the Jpeg data.
+ * @since 3.2
+ * @param aMacroBlockSize The macroblock dimensions in the Jpeg
+ * image that is set by the encoder.
+ * @param aFrameImageData The pointer to the destination Jpeg image data structure.
+ * @return void
+ */
+ IMPORT_C void SetStreamingL( TSize& aMacroBlockSize,
+ const CFrameImageData* aFrameImageData= NULL );
+
+ /**
+ * Enables the use of replacing feature, where the given image
+ * is replaced starting from the specified up-left corner point.
+ * @since 3.2
+ * @param aReplaceImage The image data that will be replaced.
+ * @param aReplacePoint The up-left corner point of the replacing region.
+ * @return void
+ */
+ IMPORT_C void SetImageReplaceL( const CVisualFrame* aReplaceImage, TPoint aReplacePoint );
+
+ /**
+ * Enables the use of replacing feature, where the given bitmap
+ * is replaced starting from the specified up-left corner point.
+ * @since 3.2
+ * @param aReplaceBitmap The bitmap that will be replaced.
+ * @param aReplacePoint The up-left corner point of the replacing region.
+ * @return void
+ */
+ IMPORT_C void SetBitmapReplaceL( const CFbsBitmap& aReplaceBitmap, TPoint aReplacePoint );
+
+ /**
+ * Enables the use of overlay feature, where the given bitmap
+ * is overlayed transparently based on the given alpha value
+ * starting from the specified up-left corner point.
+ * @since 3.2
+ * @param aOverlayBitmap The bitmap that will be overlayed.
+ * @param aAlphaValue The alpha value for the transparency of the overlayed bitmap.
+ * @param aOverlayPoint The up-left corner point of the overlay region.
+ * @return void
+ */
+ IMPORT_C void SetBitmapOverlayL( const CFbsBitmap& aOverlayBitmap,
+ TUint aAlphaValue, TPoint aOverlayPoint );
+
+ /**
+ * Enables the use of lossless rotation feature and specifies the rotating degree.
+ * @since 3.2
+ * @param aDegree The rotation degree. Can take any values between 1 and 359.
+ * @return void
+ */
+ IMPORT_C void SetLosslessRotationL( TInt aDegree );
+
+ /**
+ * Enables the use of lossless flipping feature.
+ * @since 3.2
+ * @return void
+ */
+ IMPORT_C void SetLosslessFlippingL();
+
+ /**
+ * SEnables the use of lossless mirroring feature.
+ * @since 3.2
+ * @return void
+ */
+ IMPORT_C void SetLosslessMirroringL();
+
+ /**
+ * Enables the use of DCT encoding feature.
+ * @since 3.2
+ * @return void
+ */
+ IMPORT_C void SetDctEncodingL();
+
+ /**
+ * Provides a new visual frame structure for the
+ * destination data replacing any previously delivered ones.
+ * All the operations coming after this function call should
+ * use the provided structure.
+ * @since 3.2
+ * @param aDestinationData The new visual frame structure for the destination data.
+ * @return void
+ */
+ IMPORT_C void ProvideNewDestDataL( const CVisualFrame* aDestinationData );
+
+ /**
+ * Asynchronous function for initiating the encoding.
+ * @since 3.2
+ * @param aRequestStatus The pointer to the status of the operation
+ * that is set by the encoder after it is completed.
+ * After a complete successful operation, the status
+ * is KErrNone.
+ * @param aSourceFrame Pointer to the visual frame structure that is keeping
+ * the source image data. In streaming case, contains a
+ * part of the uncompressed image data at the beginning.
+ * @param aNoOfEncodedMBlocks Reference to the number of encoded macroblocks that is
+ * set by the encoder after the encoding is completed.
+ * @param aFrameImageData Pointer to optional frame image data structure defined in ICL.
+ * @return void
+ */
+ IMPORT_C void ConvertL(
+ TRequestStatus* aRequestStatus,
+ const CVisualFrame* aSourceFrame,
+ TInt& aNoOfEncodedMBlocks,
+ const CFrameImageData* aFrameImageData = NULL );
+
+ /**
+ * Asynchronous function for initiating one of the iterations of streamed encoding.
+ * @since 3.2
+ * @param aRequestStatus The pointer to the status of the operation
+ * that is set by the encoder after it is completed.
+ * After a complete successful operation, the status
+ * is KErrNone.
+ * @param aSourceFrame Pointer to the visual frame structure that is keeping
+ * the source image data. In streaming case, contains a
+ * part of the uncompressed image data at the beginning.
+ * @param aNoOfEncodedMBlocks Reference to the number of encoded macroblocks that is
+ * set by the encoder after the encoding is completed.
+ * @return
+ */
+ IMPORT_C void ContinueConvertL(
+ TRequestStatus* aRequestStatus,
+ const CVisualFrame* aSourceFrame,
+ TInt& aNoOfEncodedMBlocks );
+
+ /**
+ * Returns the source (uncompressed) data formats that are supported by the encoder.
+ * @since 3.2
+ * @return TInt The supported source (uncompressed) data formats.
+ * The value is a combination of the flags defined
+ * in CVisualFrame::TDataFormat.
+ */
+ IMPORT_C TInt SupportedFormatsL();
+
+ /**
+ * Returns the Extended API features (capabilities) that are supported by the encoder.
+ * @since 3.2
+ * @return TInt The supported Extended API features.
+ * The value is a combination of the flags defined
+ * in TEncoderCapabilities.
+ */
+ IMPORT_C TInt CapabilitiesL();
+
+ /**
+ * Creates and initializes CExtJpegEncoder
+ * @since 3.2
+ * @param aEncoderType Encoder implementation type: HW or SW.
+ * @param aFs A reference to a file server session to use.
+ * @param aDestinationFilename The name of the destination Jpeg file.
+ * @param aOptions Encoder options defined in ICL.
+ * @return CExtJpegEncoder* A pointer to encoder object.
+ */
+ IMPORT_C static CExtJpegEncoder* FileNewL(
+ const TEncoderType aEncoderType,
+ RFs& aFs,
+ const TDesC& aDestinationFilename,
+ const TOptions aOptions = EOptionNone );
+
+ /**
+ * Creates and initializes CExtJpegEncoder
+ * @since 3.2
+ * @param aEncoderType Encoder implementation type: HW or SW.
+ * @param aDestinationData Pointer reference to the destination Jpeg
+ * data location that will be allocated by the encoder.
+ * @param aOptions Encoder options defined in ICL.
+ * @return CExtJpegEncoder* A pointer to encoder object.
+ */
+ IMPORT_C static CExtJpegEncoder* DataNewL(
+ const TEncoderType aEncoderType,
+ HBufC8*& aDestinationData,
+ const TOptions aOptions = EOptionNone );
+ /**
+ * Creates and initializes CExtJpegEncoder
+ * @since 3.2
+ * @param aEncoderType Encoder implementation type: HW or SW.
+ * @param aDestinationData Pointer to the visual frame structure keeping the
+ * destination Jpeg data allocated with maximum size by the client.
+ * @param aOptions Encoder options defined in ICL.
+ * @return CExtJpegEncoder* A pointer to encoder object.
+ */
+ IMPORT_C static CExtJpegEncoder* DataNewL(
+ const TEncoderType aEncoderType,
+ const CVisualFrame* aDestinationData,
+ const TOptions aOptions = EOptionNone );
+
+ /**
+ * Returns the actual destination buffer size
+ * @since 3.2
+ * @return TInt The actual destination buffer size required.
+ * -1 means the codec is not able to determine the required buffer size.
+ */
+ IMPORT_C TInt GetDestinationDataSizeL();
+
+
+ private:
+
+ /**
+ * C++ default constructor.
+ */
+ CExtJpegEncoder();
+
+ /**
+ * Get an uid by version range
+ * @since 3.2
+ * @param aMinVersion
+ * @param aMaxVersion
+ * @return TUid
+ */
+ static TUid GetUidByVersionRangeL( TInt aMinVersion, TInt aMaxVersion );
+
+ };
+
+#endif // _ICLEXTJPEGAPI_
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_plat/group/bld.inf Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,26 @@
+/*
+* Copyright (c) 2006-2008 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: Includes all the Domain API specific bld.inf files, which
+* export files.
+*
+*/
+
+
+
+#include "../jpeg2000_icl_plugin_api/group/bld.inf"
+#include "../extended_icl_jpeg_api/group/bld.inf"
+#include "../h324_annex_k_custom_api/group/bld.inf"
+#include "../ecam_orientation_custom_api/group/bld.inf"
+#include "../ecam_ui_orientation_override_custom_api/group/bld.inf"
+#include "../ecam_face_tracking_custom_api/group/bld.inf"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_plat/h324_annex_k_custom_api/group/bld.inf Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,27 @@
+/*
+* Copyright (c) 2007 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: File that exports the files belonging to
+* H324 Annex K Custom Interface
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_EXPORTS
+
+../inc/ch324annexkdefinedencoderconfigdataci.h OS_LAYER_PLATFORM_EXPORT_PATH(ch324annexkdefinedencoderconfigdataci.h)
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_plat/h324_annex_k_custom_api/h324_annex_k_custom_api.metaxml Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,13 @@
+<?xml version="1.0" ?>
+<api id="e8535acf0719f877107c577efbeedcdb" dataversion="2.0">
+<name>H324 Annex K Custom API</name>
+<description>User defined encoder init data custom interface</description>
+<type>c++</type>
+<collection>imagingmodules</collection>
+<libs></libs>
+<release category="platform" sinceversion="3.2"/>
+<attributes>
+<htmldocprovided>no</htmldocprovided>
+<adaptation>yes</adaptation>
+</attributes>
+</api>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_plat/h324_annex_k_custom_api/inc/ch324annexkdefinedencoderconfigdataci.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,68 @@
+/*
+* Copyright (c) 2007 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: user defined encoder init data custom interface
+*
+*/
+
+
+/**
+* @Example of the CI usage:
+* 1. Create CI.
+* MH324AnnexKDefinedEncoderConfigDataCI* userConfigCI = NULL;
+* userConfigCI = (MH324AnnexKDefinedEncoderConfigDataCI*)iDevvrInstance->CustomInterface( hwdevUid, H324AnnexKDefinedEncoderConfigDataCIUid );
+*
+* CDEVVRVideoRecord iDevvrInstance - The inctance of the DeviceVideoRecord;
+* TUid hwdevUid - Encoder HwDevice Uid;
+* H324AnnexKDefinedEncoderConfigDataCIUid - Custom Interface Uid;
+*
+*
+* 2. TInt status = userConfigCI->H324AnnexKDefinedEncoderConfigDataOn();
+*
+* if ( status != KErrNone )
+* {
+* // handle error
+* }
+*
+* 3. This CI API H324AnnexKDefinedEncoderConfigDataOn() can only be called before the initializing phase (Before Initialize() method is called by DevVideo).
+*
+*/
+
+#ifndef __CH324ANNEXKDEFINEDENCODERCONFIGDATACI_H
+#define __CH324ANNEXKDEFINEDENCODERCONFIGDATACI_H
+
+
+// CONSTANTS
+const TUid H324AnnexKDefinedEncoderConfigDataCIUid = {0x10204C0B}; // Custom Interface UId
+
+
+// CLASS DECLARATION
+/**
+* User defined encoder confguration data custom interface
+*
+*/
+class MH324AnnexKDefinedEncoderConfigDataCI
+ {
+ public:
+
+ /**
+ * Enables inserting H324 pre-defind config data (VOL / SPS PPS / etc. )
+ * @param none
+ * @return KErrNone - Success, otherwise KErrGeneral - Error, unable to process operation
+ */
+ virtual TInt H324AnnexKDefinedEncoderConfigDataOn() = 0;
+
+ };
+
+
+#endif // __CH324ANNEXKDEFINEDENCODERCONFIGDATACI_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_plat/jpeg2000_icl_plugin_api/group/bld.inf Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,28 @@
+/*
+* Copyright (c) 2006 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: File that exports the files belonging to
+: JPEG2000 ICL plugin API
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_EXPORTS
+
+../inc/JP2KUids.hrh OS_LAYER_PLATFORM_EXPORT_PATH(JP2KUids.hrh)
+../inc/JP2KImageData.h OS_LAYER_PLATFORM_EXPORT_PATH(JP2KImageData.h)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_plat/jpeg2000_icl_plugin_api/inc/JP2KImageData.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,317 @@
+/*
+* Copyright (c) 2003, 2004 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: Collection of classes derived from TImageDataBlock used
+* to store and represent the Image data.
+*
+*/
+
+
+#ifndef __JP2KIMAGEDATA_H__
+#define __JP2KIMAGEDATA_H__
+
+// INCLUDES
+#include <ICL/ImageData.h>
+
+// CONSTANTS
+
+// Identification UIDs for TImageDataBlock-derived classes
+#define KJ2KCommentUid 0x101F865F // UID for COM marker
+#define KJ2KIprBoxUid 0x101F8660 // UID for IPR box
+#define KJ2KXmlBoxUid 0x101F8661 // UID for XML box
+#define KJ2KUuidBoxUid 0x101F8662 // UID for UUID box
+#define KJ2KUuidInfoBoxUid 0x101F8663 // UID for UUIDINFO box
+
+#define KJ2KUuidIDSize 16 // ID size in UUID box
+
+// MACROS
+
+// DATA TYPES
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+class CFrameImageData;
+
+// CLASS DECLARATION
+
+/**
+ * JP2K specific image data variant which holds JP2K COM marker.
+ *
+ * @JP2KCodec.dll
+ * @since 2.6
+ */
+class TJp2kComment : public TImageDataBlock
+ {
+ public: // Constructors and destructor
+
+ /**
+ * C++ default constructor.
+ */
+ TJp2kComment();
+
+ public: // New functions
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private: // New functions
+
+ private: // Functions from base classes
+
+ /**
+ * From TImageDataBlock
+ * @since 2.6
+ * @param aFrameImageData: Image data which hold current duplication.
+ */
+ TImageDataBlock* DuplicateL( CFrameImageData& aFrameImageData ) const;
+
+ public: // Data
+
+ // The comment to set/query
+ HBufC8 *iComment;
+
+ protected: // Data
+
+ private: // Data
+
+ public: // Friend classes
+
+ protected: // Friend classes
+
+ private: // Friend classes
+ };
+
+/**
+ * JP2K specific image data variant which holds JP2K IPR box.
+ *
+ * @JP2KCodec.dll
+ * @since 2.6
+ */
+class TJp2kIprBox : public TImageDataBlock
+ {
+ public: // Constructors and destructor
+
+ /**
+ * C++ default constructor.
+ */
+ TJp2kIprBox();
+
+ public: // New functions
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private: // New functions
+
+ private: // Functions from base classes
+
+ /**
+ * From TImageDataBlock
+ * @since 2.6
+ * @param aFrameImageData: Image data which hold current duplication.
+ */
+ TImageDataBlock* DuplicateL( CFrameImageData& aFrameImageData ) const;
+
+ public: // Data
+
+ // The ipr data to set/query
+ HBufC8 *iIprData;
+
+ protected: // Data
+
+ private: // Data
+
+ public: // Friend classes
+
+ protected: // Friend classes
+
+ private: // Friend classes
+ };
+
+/**
+ * JP2K specific image data variant which holds JP2K XML box.
+ *
+ * @JP2KCodec.dll
+ * @since 2.6
+ */
+class TJp2kXmlBox : public TImageDataBlock
+ {
+ public: // Constructors and destructor
+
+ /**
+ * C++ default constructor.
+ */
+ TJp2kXmlBox();
+
+ public: // New functions
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private: // New functions
+
+ private: // Functions from base classes
+
+ /**
+ * From TImageDataBlock
+ * @since 2.6
+ * @param aFrameImageData: Image data which hold current duplication.
+ */
+ TImageDataBlock* DuplicateL( CFrameImageData& aFrameImageData ) const;
+
+ public: // Data
+
+ // The xml data to set/query
+ HBufC8 *iXmlData;
+
+ protected: // Data
+
+ private: // Data
+
+ public: // Friend classes
+
+ protected: // Friend classes
+
+ private: // Friend classes
+ };
+
+/**
+ * JP2K specific image data variant which holds JP2K UUID box.
+ *
+ * @JP2KCodec.dll
+ * @since 2.6
+ */
+class TJp2kUuidBox : public TImageDataBlock
+ {
+ public: // Constructors and destructor
+
+ /**
+ * C++ default constructor.
+ */
+ TJp2kUuidBox();
+
+ public: // New functions
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private: // New functions
+
+ private: // Functions from base classes
+
+ /**
+ * From TImageDataBlock
+ * @since 2.6
+ * @param aFrameImageData: Image data which hold current duplication.
+ */
+ TImageDataBlock* DuplicateL( CFrameImageData& aFrameImageData ) const;
+
+ public: // Data
+
+ // The id field to set/query
+ TBuf8<KJ2KUuidIDSize> iUuidId;
+
+ // The uuid data to set/query
+ HBufC8 *iUuidData;
+
+ protected: // Data
+
+ private: // Data
+
+ public: // Friend classes
+
+ protected: // Friend classes
+
+ private: // Friend classes
+ };
+
+/**
+ * JP2K specific image data variant which holds JP2K UUID Info box.
+ *
+ * @JP2KCodec.dll
+ * @since 2.6
+ */
+class TJp2kUuidInfoBox : public TImageDataBlock
+ {
+ public: // Constructors and destructor
+
+ /**
+ * C++ default constructor.
+ */
+ TJp2kUuidInfoBox();
+
+ public: // New functions
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private: // New functions
+
+ private: // Functions from base classes
+
+ /**
+ * From TImageDataBlock
+ * @since 2.6
+ * @param aFrameImageData: Image data which hold current duplication.
+ */
+ TImageDataBlock* DuplicateL( CFrameImageData& aFrameImageData ) const;
+
+ public: // Data
+
+ // The uuid info nu field to set/query
+ TInt iUuidInfoNu;
+
+ // The uuid info id data field to set/query
+ // concatenation of ( nu * 16 bytes ID field )
+ // ID(0) | ID(1) | .. | ID(n-1)
+ // where n = nu field and ID(x) = 16 bytes data
+ HBufC8 *iUuidInfoId;
+
+ // The uuid info version field to set/query
+ TInt iUuidInfoVersion;
+
+ // The uuid info flag field to set/query
+ TInt iUuidInfoFlag;
+
+ // The uuid info url data field to set/query
+ HBufC8 *iUuidInfoData;
+
+ protected: // Data
+
+ private: // Data
+
+ public: // Friend classes
+
+ protected: // Friend classes
+
+ private: // Friend classes
+ };
+
+#endif // __JP2KIMAGEDATA_H__
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_plat/jpeg2000_icl_plugin_api/inc/JP2KUids.hrh Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 2003, 2004 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: Resource header file for JPEG2000 plugin.
+*
+*/
+
+
+#ifndef JP2KUIDS_HRH
+#define JP2KUIDS_HRH
+
+#define KJ2KCodecDllUidValue 0x101F862D // DLL UID
+#define KJ2KDecoderImplementationUid 0x101F8649 // Main codec UID
+#define KJ2KDecoderImplementationUidValueFileFormat 0x101F862E // File format UID
+#define KJ2KDecoderImplementationUidValueCodeStream 0x101F862F // Codestream UID
+#define KImageTypeJ2KUid 0x101F8630 // Image type UID
+
+#endif
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_plat/jpeg2000_icl_plugin_api/jpeg2000_icl_plugin_api.metaxml Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<api id="13896b18ea1158a01eedabf66bcf26c7" dataversion="2.0">
+ <name>JPEG2000 ICL plugin API</name>
+ <description>API for storing and representing the Image data.</description>
+ <type>c++</type>
+ <collection>imagingmodules</collection>
+ <libs>
+ <lib name="JP2KCodec.lib" />
+ </libs>
+ <release category="platform"/>
+ <attributes>
+ <!-- This indicates wether the api provedes separate html documentation -->
+ <!-- or is the additional documentation generated from headers. -->
+ <!-- If you are unsuere then the value is "no" -->
+ <htmldocprovided>no</htmldocprovided>
+ <adaptation>no</adaptation>
+ </attributes>
+</api>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/exif_api.metaxml Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<api id="55c113f3c39eefa5cccc6e64e1c9d07e" dataversion="2.0">
+ <name>Exif API</name>
+ <description>Exif header information creation/read/modification support for compressed JPEG images</description>
+ <type>c++</type>
+ <collection>imagingmodules</collection>
+ <libs>
+ <lib name="ExifLib.lib" />
+ </libs>
+ <release category="public" sinceversion="3.0"/>
+ <attributes>
+ <!-- This indicates wether the api provedes separate html documentation -->
+ <!-- or is the additional documentation generated from headers. -->
+ <!-- If you are unsuere then the value is "no" -->
+ <htmldocprovided>no</htmldocprovided>
+ <adaptation>no</adaptation>
+ </attributes>
+</api>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/group/bld.inf Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,29 @@
+/*
+* Copyright (c) 2006 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: File that exports the files belonging to
+: Exif API
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_EXPORTS
+
+../inc/ExifTag.h OS_LAYER_PUBLIC_EXPORT_PATH(ExifTag.h)
+../inc/ExifRead.h OS_LAYER_PUBLIC_EXPORT_PATH(ExifRead.h)
+../inc/ExifModify.h OS_LAYER_PUBLIC_EXPORT_PATH(ExifModify.h)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/inc/ExifModify.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,557 @@
+/*
+* Copyright (c) 2003, 2004 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: Exif file format creator/modifier class
+*
+*/
+
+
+#ifndef EXIFMODIFY_H
+#define EXIFMODIFY_H
+
+// INCLUDES
+#include <e32base.h>
+#include "ExifRead.h"
+
+// CONSTANTS
+
+// MACROS
+
+// DATA TYPES
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+class TExifTagInfo;
+
+// CLASS DECLARATION
+
+/**
+* CExifModify
+* Interface class for modifying existing Exif v2.2 (or prior) file format or
+* creating Exif v2.2 file format using valid Jpeg image.
+* An instance of this class can be instantiated in one of two ways:
+* by providing valid Exif data or by providing valid Jpeg image.
+*
+* @lib ExifLib
+* @since 2.6
+*/
+NONSHARABLE_CLASS( CExifModify ): public CBase
+ {
+ public: // Enumerations
+
+ /**
+ * The operation mode enumeration specifying the create or modify modes.
+ */
+ enum TOperationMode
+ {
+ EModify = 0,
+ ECreate
+ };
+
+ public:
+ enum TExifModifyOption
+ {
+ ENoOptions = 0x0000,
+ ENoJpegParsing = 0x0001, // No jpeg validity checking is done
+ ENoTagChecking = 0x0002 // Ignore unknown EXIF tags and mandatory tag checking
+ };
+
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor.
+ */
+ IMPORT_C static CExifModify* NewL(
+ const TDesC8& aInData,
+ CExifModify::TOperationMode aOperationMode = EModify );
+
+ IMPORT_C static CExifModify* NewL(
+ const TDesC8& aInData,
+ CExifModify::TOperationMode aOperationMode,
+ TUint aExifModifyOption );
+
+
+ /**
+ * Two-phased constructor.
+ */
+ IMPORT_C static CExifModify* NewL();
+
+ /**
+ * Destructor.
+ */
+ virtual ~CExifModify();
+
+ public: // New functions
+
+ /**
+ * Returns a constant pointer to a CExifRead instance that can be used
+ * to parse the associated Exif image.
+ * @since 2.6
+ * @return Unmodifiable pointer to Exif reader instance.
+ */
+ virtual const CExifRead* Reader() const = 0;
+
+ /**
+ * Inserts/Updates the given tag in the specified IFD structure of the
+ * Exif data.
+ * @since 2.6
+ * @param aIfdType The hosting IFD type.
+ * @param aExifTagInfo The informative fields of tag that is updated.
+ * @param aExifData Data of the tag that is updated.
+ * @return void
+ */
+ virtual void SetTagL(
+ TExifIfdType aIfdType,
+ TExifTagInfo aExifTagInfo,
+ const TDesC8& aTagData ) = 0;
+
+ /**
+ * Removes the tag with the given tag ID from the specified IFD
+ * structure in the Exif data.
+ * @since 2.6
+ * @param aIfdType The hosting IFD type.
+ * @param aTagId The target tag ID.
+ * @return Error code.
+ */
+ virtual TInt DeleteTag( TExifIfdType aIfdType, TUint16 aTagId ) = 0;
+
+ /**
+ * Removes the specified IFD structure and all its tags from the Exif
+ * data.
+ * @since 2.6
+ * @param aIfdType The target IFD type.
+ * @return Error code.
+ */
+ virtual TInt DeleteIfd( TExifIfdType aIfdType ) = 0;
+
+ /**
+ * Inserts/Updates the given thumbnail Jpeg image data into the 1st IFD
+ * structure in the Exif data.
+ * @since 2.6
+ * @param aThumbnailData The Exif thumbnail image data that is updated.
+ * @return void
+ */
+ virtual void SetThumbnailL( const TDesC8& aThumbnailData ) = 0;
+
+ /**
+ * Removes the thumbnail Jpeg image data from the 1st IFD structure in
+ * the Exif data.
+ * @since 2.6
+ * @return Error code.
+ */
+ virtual TInt RemoveThumbnail() = 0;
+
+ /**
+ * Flushes the Exif data into the given data buffer, and releases the
+ * internal structures.
+ * @since 2.6
+ * @param aInData The original Exif image data, which contains identical
+ * data provided while calling the NewL function.
+ * @return Pointer to descriptor containing new Exif image data.
+ */
+ virtual HBufC8* WriteDataL( const TDesC8& aInData ) = 0;
+
+ /**
+ * Inserts/Updates given Image Description in the Exif data.
+ * @since 2.6
+ * @param aImageDescription Updated Image Description data.
+ * @return void
+ */
+ virtual void SetImageDescriptionL( const TDesC8& aImageDescription ) = 0;
+
+ /**
+ * Inserts/Updates given Make in the Exif data.
+ * @since 2.6
+ * @param aMake Updated Make data.
+ * @return void
+ */
+ virtual void SetMakeL( const TDesC8& aMake ) = 0;
+
+ /**
+ * Inserts/Updates given Model in the Exif data.
+ * @since 2.6
+ * @param aModel Updated Model data.
+ * @return void
+ */
+ virtual void SetModelL( const TDesC8& aModel ) = 0;
+
+ /**
+ * Inserts/Updates given Orientation in the Exif data.
+ * @since 2.6
+ * @param aOrientation Updated Orientation data.
+ * @return void
+ */
+ virtual void SetOrientationL( TUint16 aOrientation ) = 0;
+
+ /**
+ * Inserts/Updates given X Resolution in the Exif data.
+ * @since 2.6
+ * @param aXResolution1 Updated X Resolution numerator.
+ * @param aXResolution2 Updated X Resolution denominator.
+ * @return void
+ */
+ virtual void SetXResolutionL(
+ TUint32 aXResolution1,
+ TUint32 aXResolution2 ) = 0;
+
+ /**
+ * Inserts/Updates given Y Resolution in the Exif data.
+ * @since 2.6
+ * @param aYResolution1 Updated Y Resolution numerator.
+ * @param aYResolution2 Updated Y Resolution denominator.
+ * @return void
+ */
+ virtual void SetYResolutionL(
+ TUint32 aYResolution1,
+ TUint32 aYResolution2 ) = 0;
+
+ /**
+ * Inserts/Updates given Resolution Unit in the Exif data.
+ * @since 2.6
+ * @param aResolutionUnit Updated Resolution Unit data.
+ * @return void
+ */
+ virtual void SetResolutionUnitL( TUint16 aResolutionUnit ) = 0;
+
+ /**
+ * Inserts/Updates given Transfer Function in the Exif data.
+ * @since 2.6
+ * @param aTransferFunction Updated Transfer Function data.
+ * @return void
+ */
+ virtual void SetTransferFunctionL(
+ const TDesC8& aTransferFunction ) = 0;
+
+ /**
+ * Inserts/Updates given Date Time in the Exif data.
+ * @since 2.6
+ * @param aDateTime Updated Date Time data.
+ * @return void
+ */
+ virtual void SetDateTimeL( const TDesC8& aDateTime ) = 0;
+
+ /**
+ * Inserts/Updates given YCbCr Positioning in the Exif data.
+ * @since 2.6
+ * @param aYCbCrPositioning YCbCr Positioning data.
+ * @return void
+ */
+ virtual void SetYCbCrPositioningL( TUint16 aYCbCrPositioning) = 0;
+
+ /**
+ * Inserts/Updates given Software in the Exif data.
+ * @since 2.6
+ * @param aSoftware Updated Software data.
+ * @return void
+ */
+ virtual void SetSoftwareL( const TDesC8& aSoftware ) = 0;
+
+ /**
+ * Inserts/Updates given Copyright in the Exif data.
+ * @since 2.6
+ * @param aCopyright Updated Copyright data.
+ * @return void
+ */
+ virtual void SetCopyrightL( const TDesC8& aCopyright ) = 0;
+
+ /**
+ * Inserts/Updates given Exposure Time in the Exif data.
+ * @since 2.6
+ * @param aExposureTime1 Updated Exposure Time numerator.
+ * @param aExposureTime2 Updated Exposure Time denominator.
+ * @return void
+ */
+ virtual void SetExposureTimeL(
+ TUint32 aExposureTime1,
+ TUint32 aExposureTime2 ) = 0;
+
+ /**
+ * Inserts/Updates given Components Configuration in the Exif data.
+ * @since 2.6
+ * @param aComponentsConfiguration Updated Components Configuration data.
+ * @return void
+ */
+ virtual void SetComponentsConfigurationL(
+ TUint8 aFirstComponent, TUint8 aSecondComponent,
+ TUint8 aThirdComponent, TUint8 aFourthComponent ) = 0;
+
+ /**
+ * Inserts/Updates given Flash in the Exif data.
+ * @since 2.6
+ * @param aFlash Updated Flash data.
+ * @return void
+ */
+ virtual void SetFlashL( TUint16 aFlash ) = 0;
+
+ /**
+ * Inserts/Updates given Color Space in the Exif data.
+ * @since 2.6
+ * @param aColorSpace Updated Color Space data.
+ * @return void
+ */
+ virtual void SetColorSpaceL( TUint16 aColorSpace ) = 0;
+
+ /**
+ * Inserts/Updates given Pixel X Dimension in the Exif data.
+ * @since 2.6
+ * @param aPixelXDimension Updated Pixel X Dimension data.
+ * @return void
+ */
+ virtual void SetPixelXDimensionL( TUint32 aPixelXDimension ) = 0;
+
+ /**
+ * Inserts/Updates given Pixel Y Dimension in the Exif data.
+ * @since 2.6
+ * @param aPixelYDimension Updated Pixel Y Dimension data.
+ * @return void
+ */
+ virtual void SetPixelYDimensionL( TUint32 aPixelYDimension ) = 0;
+
+ /**
+ * Inserts/Updates given Exposure Mode in the Exif data.
+ * @since 2.6
+ * @param aExposureMode Updated Exposure Mode data.
+ * @return void
+ */
+ virtual void SetExposureModeL( TUint16 aExposureMode ) = 0;
+
+ /**
+ * Inserts/Updates given White Balance in the Exif data.
+ * @since 2.6
+ * @param aWhiteBalance Updated White Balance data.
+ * @return void
+ */
+ virtual void SetWhiteBalanceL( TUint16 aWhiteBalance ) = 0;
+
+ /**
+ * Inserts/Updates given Scene Capture Type in the Exif data.
+ * @since 2.6
+ * @param aSceneCaptureType Updated Scene Capture Type data.
+ * @return void
+ */
+ virtual void SetSceneCaptureTypeL( TUint16 aSceneCaptureType ) = 0;
+
+
+ /**
+ * Inserts/Updates given Exposure Program in the Exif data.
+ * @since 2.6
+ * @param aExposureProgram Updated Exposure Program data.
+ * @return void
+ */virtual void SetExposureProgramL( TUint16 aExposureProgram ) = 0;
+
+ /**
+ * Inserts/Updates given Iso Speed Ratings in the Exif data.
+ * @since 2.6
+ * @param aIsoSpeedRatings Updated Iso Speed Ratings data.
+ * @return void
+ */
+ virtual void SetIsoSpeedRatingsL( const TDesC8& aIsoSpeedRatings ) = 0;
+
+ /**
+ * Inserts/Updates given Date Time Original in the Exif data.
+ * @since 2.6
+ * @param aDateTimeOriginal Updated Date Time Original data.
+ * @return void
+ */
+ virtual void SetDateTimeOriginalL(
+ const TDesC8& aDateTimeOriginal ) = 0;
+
+ /**
+ * Inserts/Updates given Date Time Digitized in the Exif data.
+ * @since 2.6
+ * @param aDateTimeDigitized Updated Date Time Digitized data.
+ * @return void
+ */
+ virtual void SetDateTimeDigitizedL(
+ const TDesC8& aDateTimeDigitized ) = 0;
+
+ /**
+ * Inserts/Updates given Aperture Value in the Exif data.
+ * @since 2.6
+ * @param aApertureValue1 Updated Aperture Value numerator.
+ * @param aApertureValue2 Updated Aperture Value denominator.
+ * @return void
+ */
+ virtual void SetApertureValueL(
+ TUint32 aApertureValue1,
+ TUint32 aApertureValue2 ) = 0;
+
+ /**
+ * Inserts/Updates given Exposure Bias Value in the Exif data.
+ * @since 2.6
+ * @param aExposureBiasValue1 Updated Exposure Bias Value numerator.
+ * @param aExposureBiasValue2 Updated Exposure Bias Value denominator.
+ * @return void
+ */
+ virtual void SetExposureBiasValueL(
+ TInt32 aExposureBiasValue1,
+ TInt32 aExposureBiasValue2 ) = 0;
+
+ /**
+ * Inserts/Updates given Metering Mode in the Exif data.
+ * @since 2.6
+ * @param aMeteringMode Updated Metering Mode data.
+ * @return void
+ */
+ virtual void SetMeteringModeL( TUint16 aMeteringMode ) = 0;
+
+ /**
+ * Inserts/Updates given Light Source in the Exif data.
+ * @since 2.6
+ * @param aLightSource Updated Light Source data.
+ * @return void
+ */
+ virtual void SetLightSourceL( TUint16 aLightSource ) = 0;
+
+ /**
+ * Inserts/Updates given Maker Note in the Exif data.
+ * @since 2.6
+ * @param aMakerNote Updated Maker Note data.
+ * @return void
+ */
+ virtual void SetMakerNoteL( const TDesC8& aMakerNote ) = 0;
+
+ /**
+ * Inserts/Updates given User Comment in the Exif data.
+ * @since 2.6
+ * @param aUserComment Updated User Comment data.
+ * @return void
+ */
+ virtual void SetUserCommentL( const TDesC8& aUserComment ) = 0;
+
+ /**
+ * Inserts/Updates given Related Sound File in the Exif data.
+ * @since 2.6
+ * @param aRelatedSoundFile Updated Related Sound File data.
+ * @return void
+ */
+ virtual void SetRelatedSoundFileL(
+ const TDesC8& aRelatedSoundFile ) = 0;
+
+ /**
+ * Inserts/Updates given File Source in the Exif data.
+ * @since 2.6
+ * @param aFileSource Updated File Source data.
+ * @return void
+ */
+ virtual void SetFileSourceL( TInt8 aFileSource ) = 0;
+
+ /**
+ * Inserts/Updates given Digital Zoom Ratio in the Exif data.
+ * @since 2.6
+ * @param aDigitalZoomRatio1 Updated Digital Zoom Ratio numerator.
+ * @param aDigitalZoomRatio2 Updated Digital Zoom Ratio denominator.
+ * @return void
+ */
+ virtual void SetDigitalZoomRatioL(
+ TUint32 aDigitalZoomRatio1,
+ TUint32 aDigitalZoomRatio2 ) = 0;
+
+ /**
+ * Inserts/Updates given Contrast in the Exif data.
+ * @since 2.6
+ * @param aContrast Updated Contrast data.
+ * @return void
+ */
+ virtual void SetContrastL( TUint16 aContrast ) = 0;
+
+ /**
+ * Inserts/Updates given Saturation in the Exif data.
+ * @since 2.6
+ * @param aSaturation Updated Saturation data.
+ * @return void
+ */
+ virtual void SetSaturationL( TUint16 aSaturation ) = 0;
+
+ /**
+ * Inserts/Updates given Sharpness in the Exif data.
+ * @since 2.6
+ * @param aSharpness Updated Sharpness data.
+ * @return void
+ */
+ virtual void SetSharpnessL( TUint16 aSharpness ) = 0;
+
+ /**
+ * Inserts/Updates given thumbnail X Resolution in the Exif data.
+ * @since 2.6
+ * @param aXResolution1 Updated thumbnail X Resolution numerator.
+ * @param aXResolution2 Updated thumbnail X Resolution denominator.
+ * @return void
+ */
+ virtual void SetThumbnailXResolutionL(
+ TUint32 aXResolution1,
+ TUint32 aXResolution2 ) = 0;
+
+ /**
+ * Inserts/Updates given thumbnail Y Resolution in the Exif data.
+ * @since 2.6
+ * @param aYResolution1 Updated thumbnail Y Resolution numerator.
+ * @param aYResolution2 Updated thumbnail Y Resolution denominator.
+ * @return void
+ */
+ virtual void SetThumbnailYResolutionL(
+ TUint32 aYResolution1,
+ TUint32 aYResolution2 ) = 0;
+
+ /**
+ * Inserts/Updates given thumbnail Resolution Unit in the Exif data.
+ * @since 2.6
+ * @param aResolutionUnit Updated thumbnail Resolution Unit data.
+ * @return void
+ */
+ virtual void SetThumbnailResolutionUnitL( TUint16 aResolutionUnit ) = 0;
+
+ /**
+ * Inserts/Updates given Shutter Speed Value in the Exif data.
+ * @since 2.6
+ * @param aShutterSpeedValue1 Updated Shutter Speed Value numerator.
+ * @param aShutterSpeedValue2 Updated Shutter Speed Value denominator.
+ * @return void
+ */
+ virtual void SetShutterSpeedValueL(
+ TInt32 aShutterSpeedValue1,
+ TInt32 aShutterSpeedValue2 ) = 0;
+
+ /**
+ * Inserts/Updates given Brightness Value in the Exif data.
+ * @since 2.6
+ * @param aBrightnessValue1 Updated Brightness Value numerator.
+ * @param aBrightnessValue2 Updated Brightness Value denominator.
+ * @return void
+ */
+ virtual void SetBrightnessValueL(
+ TInt32 aBrightnessValue1,
+ TInt32 aBrightnessValue2 ) = 0;
+
+ /**
+ * Inserts/Updates given Custom Rendered in the Exif data.
+ * @since 2.6
+ * @param aCustomRendered Updated Custom Rendered data.
+ * @return void
+ */
+ virtual void SetCustomRenderedL( TUint16 aCustomRendered ) = 0;
+
+ /**
+ * Inserts/Updates given Gain Control in the Exif data.
+ * @since 2.6
+ * @param aGainControl Updated Gain Control data.
+ * @return void
+ */
+ virtual void SetGainControlL( TUint16 aGainControl ) = 0;
+
+ };
+
+#endif // EXIFMODIFY_H
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/inc/ExifRead.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,615 @@
+/*
+* Copyright (c) 2003, 2004 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: Exif file format parser ( reader ) class
+*
+*/
+
+
+#ifndef EXIFREAD_H
+#define EXIFREAD_H
+
+// INCLUDES
+#include <e32base.h>
+
+// CONSTANTS
+
+// MACROS
+
+// DATA TYPES
+enum TExifIfdType
+ {
+ EIfd0 = 0,
+ EIfdExif,
+ EIfd1,
+ EIfdGps,
+ EIfdIntOp
+ };
+
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+class CExifTag;
+
+// CLASS DECLARATION
+
+/**
+* CExifRead
+* Interface class for parsing Exif v2.2 file format. An instance of this class
+* can be instantiated providing valid Exif data.
+*
+* @lib ExifLib
+* @since 2.6
+*/
+NONSHARABLE_CLASS( CExifRead ): public CBase
+ {
+
+ public: // Enumerations
+ enum TExifReadOption
+ {
+ ENoOptions = 0x0000, // Original, safe full parsing
+ ENoJpeg = 0x0001, // No main JPEG included, no parsing for main image
+ EFastJpegParsing = 0x0002, // Fast JPEG marker parsing
+ ENoTagChecking = 0x0004 // Ignore unknown EXIF tags and mandatory tag checking
+ };
+
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor.
+ */
+ IMPORT_C static CExifRead* NewL( const TDesC8& aExifData );
+
+ IMPORT_C static CExifRead* NewL( const TDesC8& aExifData, TUint aExifReadOption );
+
+ /**
+ * Destructor.
+ */
+ virtual ~CExifRead();
+
+ public: // New functions
+
+ /**
+ * Returns the Tag instance, which has the specified ID from the
+ * requested IFD.
+ * @since 2.6
+ * @param aIfdType The hosting IFD type
+ * @param aTagId The queried tag ID.
+ * @return Unmodifiable tag instance returned.
+ */
+ virtual const CExifTag* GetTagL(
+ TExifIfdType aIfdType,
+ TUint16 aTagId ) const = 0;
+
+ /**
+ * Returns the IDs of all the tags that are stored in the Exif data.
+ * @since 2.6
+ * @param aIfdType The hosting IFD type.
+ * @param aNoTags Number of tag IDs returned.
+ * @return Pointer to the tag IDs.
+ */
+ virtual TUint16* GetTagIdsL(
+ TExifIfdType aIfdType,
+ TInt& aNoTags ) const = 0;
+
+ /**
+ * Returns the types of the IFDs stored in the Exif data.
+ * @since 2.6
+ * @param aNoIfd Number of IFD types returned.
+ * @return Pointer to the IFD types.
+ */
+ virtual TExifIfdType* GetIfdTypesL( TInt& aNoIfd ) const = 0;
+
+ /**
+ * Returns pointer to a copy of the thumbnail image data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing a copy of the
+ * Exif thumbnail image.
+ */
+ virtual HBufC8* GetThumbnailL() const = 0;
+
+ /**
+ * Returns a boolean stating if the queried IFD structure exists in the
+ * Exif data.
+ * @since 2.6
+ * @param aIfdType The queried IFD type.
+ * @return Boolean stating if the specified IFD exists or not.
+ */
+ virtual TBool IfdExists( TExifIfdType aIfdType ) const = 0;
+
+ /**
+ * Returns a boolean stating if the queried tag exists in the specified
+ * IFD structure.
+ * @since 2.6
+ * @param aTagId Queried tag ID.
+ * @param aIfdType The hosting IFD type.
+ * @return Boolean stating if the specified tag exists or not.
+ */
+ virtual TBool TagExists(
+ TUint16 aTagId,
+ TExifIfdType aIfdType ) const = 0;
+
+ /**
+ * Gets the Image Description tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Image
+ * Description data.
+ */
+ virtual HBufC8* GetImageDescriptionL() const = 0;
+
+ /**
+ * Gets the Make tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Make data.
+ */
+ virtual HBufC8* GetMakeL() const = 0;
+
+ /**
+ * Gets the Model tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Model data.
+ */
+ virtual HBufC8* GetModelL() const = 0;
+
+ /**
+ * Gets the Transfer Function tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Transfer
+ * Function data.
+ */
+ virtual HBufC8* GetTransferFunctionL() const = 0;
+
+ /**
+ * Gets the Date Time tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Date Time
+ * data.
+ */
+ virtual HBufC8* GetDateTimeL() const = 0;
+
+ /**
+ * Gets the Software tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Software
+ * data.
+ */
+ virtual HBufC8* GetSoftwareL() const = 0;
+
+ /**
+ * Gets the Copyright tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Copyright
+ * data.
+ */
+ virtual HBufC8* GetCopyrightL() const = 0;
+
+ /**
+ * Gets the Orientation tag data.
+ * @since 2.6
+ * @param aOrientation Returned Orientation data.
+ * @return Error code.
+ */
+ virtual TInt GetOrientation( TUint16& aOrientation ) const = 0;
+
+ /**
+ * Gets the X Resolution tag data.
+ * @since 2.6
+ * @param aXResolution1 Returned X Resolution numerator.
+ * @param aXResolution2 Returned X Resolution denominator.
+ * @return Error code.
+ */
+ virtual TInt GetXResolution(
+ TUint32& aXResolution1,
+ TUint32& aXResolution2 ) const = 0;
+
+ /**
+ * Gets the Y Resolution tag data.
+ * @since 2.6
+ * @param aYResolution1 Returned Y Resolution numerator.
+ * @param aYResolution2 Returned Y Resolution denominator.
+ * @return Error code.
+ */
+ virtual TInt GetYResolution(
+ TUint32& aYResolution1,
+ TUint32& aYResolution2 ) const = 0;
+
+ /**
+ * Gets the Resolution Unit tag data.
+ * @since 2.6
+ * @param aResolutionUnit Returned Resolution Unit data.
+ * @return Error code.
+ */
+ virtual TInt GetResolutionUnit( TUint16& aResolutionUnit ) const = 0;
+
+ /**
+ * Gets the YCbCr Positioning tag data.
+ * @since 2.6
+ * @param aYCbCrPositioning Returned YCbCr Positioning data.
+ * @return Error code.
+ */
+ virtual TInt GetYCbCrPositioning(
+ TUint16& aYCbCrPositioning ) const = 0;
+
+ /**
+ * Gets the Exif Ifd Pointer tag data.
+ * @since 2.6
+ * @param aExifIfdPointer Returned Exif Ifd Pointer data.
+ * @return Error code.
+ */
+ virtual TInt GetExifIfdPointer( TUint32& aExifIfdPointer ) const = 0;
+
+ /**
+ * Gets the Gps Info Ifd Pointer tag data.
+ * @since 2.6
+ * @param aGpsInfoIfdPointer Returned Gps Info Ifd Pointer data.
+ * @return Error code.
+ */
+ virtual TInt GetGpsInfoIfdPointer(
+ TUint32& aGpsInfoIfdPointer ) const = 0;
+
+ /**
+ * Gets the Iso Speed Ratings tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Iso Speed
+ * Ratings data.
+ */
+ virtual HBufC8* GetIsoSpeedRatingsL() const = 0;
+
+ /**
+ * Gets the Date Time Original tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Date Time
+ * Original data.
+ */
+ virtual HBufC8* GetDateTimeOriginalL() const = 0;
+
+ /**
+ * Gets the Date Time Digitized tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Date Time
+ * Digitized data.
+ */
+ virtual HBufC8* GetDateTimeDigitizedL() const = 0;
+
+ /**
+ * Gets the Maker Note tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Maker Note
+ * data.
+ */
+ virtual HBufC8* GetMakerNoteL() const = 0;
+
+ /**
+ * Gets the User Comment tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the User
+ * Comment data.
+ */
+ virtual HBufC8* GetUserCommentL() const = 0;
+
+ /**
+ * Gets the Related Sound File tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Related
+ * Sound File data.
+ */
+ virtual HBufC8* GetRelatedSoundFileL() const = 0;
+
+ /**
+ * Gets the Exposure Time tag data.
+ * @since 2.6
+ * @param ExposureTime Returned Exposure Time data.
+ * @return Error code.
+ */
+ virtual TInt GetExposureTime(
+ TUint32& aExposureTime1,
+ TUint32& aExposureTime2 ) const = 0;
+
+ /**
+ * Gets the Components Configuration tag data.
+ * @since 2.6
+ * @param aComponentsConfiguration Returned Components Configuration
+ * data.
+ * @return Error code.
+ */
+ virtual TInt GetComponentsConfiguration(
+ TUint8& aFirstComponent, TUint8& aSecondComponent,
+ TUint8& aThirdComponent, TUint8& aFourthComponent) const = 0;
+
+ /**
+ * Gets the Flash tag data.
+ * @since 2.6
+ * @param aFlash Returned Flash data.
+ * @return Error code.
+ */
+ virtual TInt GetFlash( TUint16& aFlash ) const = 0;
+
+ /**
+ * Gets the ColorSpace tag data.
+ * @since 2.6
+ * @param aColorSpace Returned ColorSpace data.
+ * @return Error code.
+ */
+ virtual TInt GetColorSpace( TUint16& aColorSpace ) const = 0;
+
+ /**
+ * Gets the Pixel X Dimension tag data.
+ * @since 2.6
+ * @param aPixelXDimension Returned Pixel X Dimension data.
+ * @return Error code.
+ */
+ virtual TInt GetPixelXDimension( TUint32& aPixelXDimension ) const = 0;
+
+ /**
+ * Gets the Pixel Y Dimension tag data.
+ * @since 2.6
+ * @param aPixelYDimension Returned Pixel Y Dimension data.
+ * @return Error code.
+ */
+ virtual TInt GetPixelYDimension( TUint32& aPixelYDimension ) const = 0;
+
+ /**
+ * Gets the Exposure Mode tag data.
+ * @since 2.6
+ * @param aExposureMode Returned Exposure Mode data.
+ * @return Error code.
+ */
+ virtual TInt GetExposureMode( TUint16& aExposureMode ) const = 0;
+
+ /**
+ * Gets the White Balance tag data.
+ * @since 2.6
+ * @param aWhiteBalance Returned White Balance data.
+ * @return Error code.
+ */
+ virtual TInt GetWhiteBalance( TUint16& aWhiteBalance ) const = 0;
+
+ /**
+ * Gets the Scene Capture Type tag data.
+ * @since 2.6
+ * @param aSceneCaptureType Returned Scene Capture Type data.
+ * @return Error code.
+ */
+ virtual TInt GetSceneCaptureType(
+ TUint16& aSceneCaptureType ) const = 0;
+
+ /**
+ * Gets the Exposure Program tag data.
+ * @since 2.6
+ * @param aExposureProgram Returned Exposure Program data.
+ * @return Error code.
+ */
+ virtual TInt GetExposureProgram( TUint16& aExposureProgram ) const = 0;
+
+ /**
+ * Gets the Aperture Value tag data.
+ * @since 2.6
+ * @param aApertureValue1 Returned Aperture Value numerator.
+ * @param aApertureValue2 Returned Aperture Value denominator.
+ * @return Error code.
+ */
+ virtual TInt GetApertureValue(
+ TUint32& aApertureValue1,
+ TUint32& aApertureValue2 ) const = 0;
+
+ /**
+ * Gets the Exposure Bias Value tag data.
+ * @since 2.6
+ * @param aExposureBiasValue1 Returned Exposure Bias Value numerator.
+ * @param aExposureBiasValue1 Returned Exposure Bias Value denominator.
+ * @return Error code.
+ */
+ virtual TInt GetExposureBiasValue(
+ TInt32& aExposureBiasValue1,
+ TInt32& aExposureBiasValue2 ) const = 0;
+
+ /**
+ * Gets the Metering Mode tag data.
+ * @since 2.6
+ * @param aMeteringMode Returned Metering Mode data.
+ * @return Error code.
+ */
+ virtual TInt GetMeteringMode( TUint16& aMeteringMode ) const = 0;
+
+ /**
+ * Gets the Light Source tag data.
+ * @since 2.6
+ * @param aLightSource Returned Light Source data.
+ * @return Error code.
+ */
+ virtual TInt GetLightSource( TUint16& aLightSource ) const = 0;
+
+ /**
+ * Gets the File Source tag data.
+ * @since 2.6
+ * @param aFileSource Returned File Source data.
+ * @return Error code.
+ */
+ virtual TInt GetFileSource( TInt8& aFileSource ) const = 0;
+
+ /**
+ * Gets the Digital Zoom Ratio tag data.
+ * @since 2.6
+ * @param aDigitalZoomRatio1 Returned Digital Zoom Ratio numerator.
+ * @param aDigitalZoomRatio2 Returned Digital Zoom Ratio denominator.
+ * @return Error code.
+ */
+ virtual TInt GetDigitalZoomRatio(
+ TUint32& aDigitalZoomRatio1,
+ TUint32& aDigitalZoomRatio2 ) const = 0;
+
+ /**
+ * Gets the Contrast tag data.
+ * @since 2.6
+ * @param aContrast Returned Contrast data.
+ * @return Error code.
+ */
+ virtual TInt GetContrast( TUint16& aContrast ) const = 0;
+
+ /**
+ * Gets the Saturation tag data.
+ * @since 2.6
+ * @param aSaturation Returned Saturation data.
+ * @return Error code.
+ */
+ virtual TInt GetSaturation( TUint16& aSaturation ) const = 0;
+
+ /**
+ * Gets the Sharpness tag data.
+ * @since 2.6
+ * @param aSharpness Returned Sharpness data.
+ * @return Error code.
+ */
+ virtual TInt GetSharpness( TUint16& aSharpness ) const = 0;
+
+ /**
+ * Gets the Exif Version tag data.
+ * @since 2.6
+ * @param aExifVersion Returned Exif Version data.
+ * @return Error code.
+ */
+ virtual TInt GetExifVersion( TUint32& aExifVersion ) const = 0;
+
+ /**
+ * Gets the Flash Pix Version tag data.
+ * @since 2.6
+ * @param aFlashPixVersion Returned Flash Pix Version data.
+ * @return Error code.
+ */
+ virtual TInt GetFlashPixVersion( TUint32& aFlashPixVersion ) const = 0;
+
+ /**
+ * Gets the Interoperability Ifd Pointer tag data.
+ * @since 2.6
+ * @param aInteroperabilityIfdPointer Returned Interoperability Ifd
+ * Pointer data.
+ * @return Error code.
+ */
+ virtual TInt GetInteroperabilityIfdPointer(
+ TUint32& aInteroperabilityIfdPointer ) const = 0;
+
+ /**
+ * Gets the thumbnail X Resolution tag data.
+ * @since 2.6
+ * @param aXResolution1 Returned thumbnail X Resolution numerator.
+ * @param aXResolution1 Returned thumbnail X Resolution denominator.
+ * @return Error code.
+ */
+ virtual TInt GetThumbnailXResolution(
+ TUint32& aXResolution1,
+ TUint32& aXResolution2 ) const = 0;
+
+ /**
+ * Gets the thumbnail Y Resolution tag data.
+ * @since 2.6
+ * @param aYResolution1 Returned thumbnail Y Resolution numerator.
+ * @param aYResolution1 Returned thumbnail Y Resolution denominator.
+ * @return Error code.
+ */
+ virtual TInt GetThumbnailYResolution(
+ TUint32& aYResolution1,
+ TUint32& aYResolution2 ) const = 0;
+
+ /**
+ * Gets the thumbnail Resolution Unit tag data.
+ * @since 2.6
+ * @param aResolutionUnit Returned thumbnail Resolution Unit data.
+ * @return Error code.
+ */
+ virtual TInt GetThumbnailResolutionUnit(
+ TUint16& aResolutionUnit ) const = 0;
+
+ /**
+ * Gets the thumbnail Compression tag data.
+ * @since 2.6
+ * @param aCompression Returned thumbnail Compression data.
+ * @return Error code.
+ */
+ virtual TInt GetThumbnailCompression( TUint16& aCompression ) const = 0;
+
+ /**
+ * Gets the thumbnail Jpeg Interchange Format tag data.
+ * @since 2.6
+ * @param aJpegInterchangeFormat Returned thumbnail Jpeg Interchange
+ * Format data.
+ * @return Error code.
+ */
+ virtual TInt GetJpegInterchangeFormat(
+ TUint32& aJpegInterchangeFormat ) const = 0;
+
+ /**
+ * Gets the thumbnail Jpeg Interchange Format Length tag data.
+ * @since 2.6
+ * @param aJpegInterchangeFormatLength Returned thumbnail Jpeg
+ * Interchange Format Length data.
+ * @return Error code.
+ */
+ virtual TInt GetJpegInterchangeFormatLength(
+ TUint32& aJpegInterchangeFormatLength ) const = 0;
+
+ /**
+ * Returns a copy of whole Exif APP1 segment in a descriptor.
+ * @since 2.6
+ * @return Descriptor containing the Exif APP1 segment data.
+ */
+ virtual HBufC8* GetExifAppSegmentL() const = 0;
+
+ /**
+ * Gets the Shutter Speed Value tag data.
+ * @since 2.6
+ * @param aShutterSpeedValue1 Shutter Speed Value numerator.
+ * @param aShutterSpeedValue2 Shutter Speed Value denominator.
+ * @return Error code.
+ */
+ virtual TInt GetShutterSpeedValue( TInt32& aShutterSpeedValue1,
+ TInt32& aShutterSpeedValue2 ) const = 0;
+
+ /**
+ * Gets the Brightness Value tag data.
+ * @since 2.6
+ * @param aBrightnessValue1 Brightness Value numerator.
+ * @param aBrightnessValue2 Brightness Value denominator.
+ * @return Error code.
+ */
+ virtual TInt GetBrightnessValue( TInt32& aBrightnessValue1,
+ TInt32& aBrightnessValue2 ) const = 0;
+
+ /**
+ * Gets the Custom Rendered tag data.
+ * @since 2.6
+ * @param aCustomRendered Returned Custom Rendered data.
+ * @return Error code.
+ */
+ virtual TInt GetCustomRendered( TUint16& aCustomRendered ) const = 0;
+
+ /**
+ * Gets the Gain Control tag data.
+ * @since 2.6
+ * @param aGainControl Returned Gain Control data.
+ * @return Error code.
+ */
+ virtual TInt GetGainControl( TUint16& aGainControl ) const = 0;
+
+ /**
+ * Gets the Gps Version tag data.
+ * @since 2.6
+ * @param aGpsVersion Returned Gps Version data.
+ * @return Error code.
+ */
+ virtual TInt GetGpsVersion( TUint32& aGpsVersion ) const = 0;
+ };
+
+#endif // EXIFREAD_H
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/inc/ExifTag.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,124 @@
+/*
+* Copyright (c) 2003, 2004 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: Exif tag wrapper
+*
+*/
+
+
+
+#ifndef EXIFTAG_H
+#define EXIFTAG_H
+
+// INCLUDES
+#include <e32base.h>
+
+// CONSTANTS
+
+// MACROS
+
+// DATA TYPES
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+class TExifTagInfo;
+
+// CLASS DECLARATION
+
+/**
+* Interface class for handling Exif Tags.
+* This class is used to get tag data from an Exif image.
+* @lib ExifLib
+* @since 2.6
+*/
+NONSHARABLE_CLASS( CExifTag ): public CBase
+ {
+ public: // Enumerations
+
+ /**
+ * Tag Data type enumeration.
+ */
+ enum TExifTagDataType
+ {
+ ETagByte = 1,
+ ETagAscii = 2,
+ ETagShort = 3,
+ ETagLong = 4,
+ ETagRational = 5,
+ ETagUndefined = 7,
+ ETagSlong = 9,
+ ETagSrational = 10
+ };
+
+ public:
+
+ /**
+ * Destructor.
+ */
+ virtual ~CExifTag();
+
+ public: // New functions
+
+ /**
+ * Duplicate constructor. Creates an exact copy instance of the tag.
+ * @since 2.6
+ * @param
+ * @return An instance of this class including the same contents of
+ * this instance.
+ */
+ virtual CExifTag* DuplicateL() const = 0;
+
+ /**
+ * Returns the informative fields of a tag.
+ * @since 2.6
+ * @param
+ * @return TExifTagInfo structure including informative fields of a tag
+ */
+ virtual TExifTagInfo TagInfo() const = 0;
+
+ /**
+ * Returns data contents of a tag
+ * @since 2.6
+ * @param
+ * @return Unmodifiable pointer to tag data.
+ */
+ virtual TPtrC8 Data() const = 0;
+
+ };
+
+
+class TExifTagInfo
+ {
+ public: // Constructors and destructor
+
+ IMPORT_C TExifTagInfo(
+ TUint16 aTagId,
+ CExifTag::TExifTagDataType aDataType,
+ TUint32 aDataCount );
+
+ public: // Data
+
+ // Tag ID
+ TUint16 iId;
+
+ // Tag data type
+ CExifTag::TExifTagDataType iDataType;
+
+ // Number of tag data elements (having tag data type).
+ TUint32 iDataCount;
+ };
+
+#endif // EXIFTAG_H
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/Bwinscw/ExifLibTestu.def Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,4 @@
+EXPORTS
+ ?LibEntryL@@YAPAVCTestModule@@XZ @ 1 NONAME ; class CTestModule * LibEntryL(void)
+ ?SetRequirements@@YAHAAPAVCTestModuleParam@@AAK@Z @ 2 NONAME ; int SetRequirements(class CTestModuleParam * &, unsigned long &)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/EABI/ExifLibTestU.DEF Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,24 @@
+EXPORTS
+ _Z9LibEntryLv @ 1 NONAME
+ _Z15SetRequirementsRP16CTestModuleParamRm @ 2 NONAME
+ _ZTI10CTestSuite @ 3 NONAME ; #<TI>#
+ _ZTI11CTestCallerI12CExifIopTestE @ 4 NONAME ; #<TI>#
+ _ZTI11CTestCallerI12CExifTagTestE @ 5 NONAME ; #<TI>#
+ _ZTI11CTestCallerI13CExifReadTestE @ 6 NONAME ; #<TI>#
+ _ZTI11CTestCallerI15CExifCreateTestE @ 7 NONAME ; #<TI>#
+ _ZTI11CTestCallerI15CExifModifyTestE @ 8 NONAME ; #<TI>#
+ _ZTI11CTestCallerI16CExifModifyTest2E @ 9 NONAME ; #<TI>#
+ _ZTI14CAssertFailure @ 10 NONAME ; #<TI>#
+ _ZTI15CExifLibTestInc @ 11 NONAME ; #<TI>#
+ _ZTI9CTestCase @ 12 NONAME ; #<TI>#
+ _ZTV10CTestSuite @ 13 NONAME ; #<VT>#
+ _ZTV11CTestCallerI12CExifIopTestE @ 14 NONAME ; #<VT>#
+ _ZTV11CTestCallerI12CExifTagTestE @ 15 NONAME ; #<VT>#
+ _ZTV11CTestCallerI13CExifReadTestE @ 16 NONAME ; #<VT>#
+ _ZTV11CTestCallerI15CExifCreateTestE @ 17 NONAME ; #<VT>#
+ _ZTV11CTestCallerI15CExifModifyTestE @ 18 NONAME ; #<VT>#
+ _ZTV11CTestCallerI16CExifModifyTest2E @ 19 NONAME ; #<VT>#
+ _ZTV14CAssertFailure @ 20 NONAME ; #<VT>#
+ _ZTV15CExifLibTestInc @ 21 NONAME ; #<VT>#
+ _ZTV9CTestCase @ 22 NONAME ; #<VT>#
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/group/ExifLibTest.mmp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,92 @@
+/*
+* Copyright (c) 2008 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: ExifLib tests
+*
+*/
+
+
+#if defined(__S60_)
+ #include <platform_paths.hrh>
+#endif
+
+TARGET ExifLibTest.dll
+TARGETTYPE dll
+
+CAPABILITY CAP_GENERAL_DLL
+VENDORID VID_DEFAULT
+
+// Define directories for the .def-files of WINS and WINSCW builds separately.
+// IMPORTANT NOTICE: The lines in the example that end with a backslash
+// must have one space after the backslash.
+#if defined(ARMCC)
+deffile ../EABI/
+#elif defined( WINSCW )
+deffile ../Bwinscw/
+#elif defined( WINS )
+deffile ../Bwins/
+#else
+deffile ../Bmarm/
+#endif
+
+#ifdef _USE_CPPUNIT_
+UID 0x101F5380 0x101F5380
+#else
+UID 0x1000008D 0x101FB3E7
+#endif
+
+
+SOURCEPATH ../src
+#ifdef _USE_CPPUNIT_
+SOURCE ExifLibTest.cpp
+#else
+SOURCE ExifLibTestStif.cpp
+#endif
+SOURCE ExifLibTestInc.cpp
+SOURCE ExifIopTest.cpp
+SOURCE ExifTagTest.cpp
+SOURCE ExifReadTest.cpp
+SOURCE ExifReadTest100.cpp
+SOURCE ExifReadTest200.cpp
+SOURCE ExifCreateTest.cpp
+SOURCE ExifCreateTest100.cpp
+SOURCE ExifModifyTest.cpp
+SOURCE ExifModifyTest100.cpp
+SOURCE ExifModifyTest2.cpp
+
+#ifndef _USE_CPPUNIT_
+SOURCE TestFrameWork/TestCase.cpp
+SOURCE TestFrameWork/AssertFailure.cpp
+SOURCE TestFrameWork/TestSuite.cpp
+#endif
+
+USERINCLUDE ../../../../imagingmodules/exiflib/inc
+USERINCLUDE ../../../../imagingmodules/inc
+USERINCLUDE ../../inc
+
+USERINCLUDE ../inc
+USERINCLUDE ../inc/TestFrameWork
+
+OS_LAYER_SYSTEMINCLUDE
+
+LIBRARY euser.lib
+LIBRARY efsrv.lib
+LIBRARY ExifLib.lib
+#ifdef _USE_CPPUNIT_
+LIBRARY cppunitframework.lib
+#else
+LIBRARY stiftestinterface.lib
+#endif
+
+EPOCHEAPSIZE 1 10000000
+EXPORTUNFROZEN
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/group/ExifLibTest.pkg Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,146 @@
+;
+; Copyright (c) 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: ExifLibTest
+;
+; Languages
+; =========
+&EN
+
+; Name, UID for installation, Maj.Ver., Min.Ver., Variant, FLAG TO SPECIFY UNICODE, System component
+; ==================================================================================================
+#{"EXIFLIBTEST"},(0x101FB3E7),1,0,1,TYPE=SA
+
+
+; Localised Vendor name
+%{"Nokia-EN"}
+
+; Unique Vendor name
+:"Nokia"
+
+"\epoc32\release\armv5\urel\ExifLibTest.dll" -"$:\sys\bin\ExifLibTest.dll"
+
+"..\data\mmc\ExifLibTest\CameraApi.jpg" -"F:\testing\data\ExifLibTest\CameraApi.jpg"
+"..\data\mmc\ExifLibTest\FullExif.jpg" -"F:\testing\data\ExifLibTest\FullExif.jpg"
+"..\data\mmc\ExifLibTest\FullExif3mpix.jpg" -"F:\testing\data\ExifLibTest\FullExif3mpix.jpg"
+"..\data\mmc\ExifLibTest\InvalidExif1.jpg" -"F:\testing\data\ExifLibTest\InvalidExif1.jpg"
+"..\data\mmc\ExifLibTest\InvalidExif10.jpg" -"F:\testing\data\ExifLibTest\InvalidExif10.jpg"
+"..\data\mmc\ExifLibTest\InvalidExif11.jpg" -"F:\testing\data\ExifLibTest\InvalidExif11.jpg"
+"..\data\mmc\ExifLibTest\InvalidExif12.jpg" -"F:\testing\data\ExifLibTest\InvalidExif12.jpg"
+"..\data\mmc\ExifLibTest\InvalidExif13.jpg" -"F:\testing\data\ExifLibTest\InvalidExif13.jpg"
+"..\data\mmc\ExifLibTest\InvalidExif14.jpg" -"F:\testing\data\ExifLibTest\InvalidExif14.jpg"
+"..\data\mmc\ExifLibTest\InvalidExif2.jpg" -"F:\testing\data\ExifLibTest\InvalidExif2.jpg"
+"..\data\mmc\ExifLibTest\InvalidExif3.jpg" -"F:\testing\data\ExifLibTest\InvalidExif3.jpg"
+"..\data\mmc\ExifLibTest\InvalidExif4.jpg" -"F:\testing\data\ExifLibTest\InvalidExif4.jpg"
+"..\data\mmc\ExifLibTest\InvalidExif5.jpg" -"F:\testing\data\ExifLibTest\InvalidExif5.jpg"
+"..\data\mmc\ExifLibTest\InvalidExif6.jpg" -"F:\testing\data\ExifLibTest\InvalidExif6.jpg"
+"..\data\mmc\ExifLibTest\InvalidExif7.jpg" -"F:\testing\data\ExifLibTest\InvalidExif7.jpg"
+"..\data\mmc\ExifLibTest\InvalidExif8.jpg" -"F:\testing\data\ExifLibTest\InvalidExif8.jpg"
+"..\data\mmc\ExifLibTest\InvalidExif9.jpg" -"F:\testing\data\ExifLibTest\InvalidExif9.jpg"
+"..\data\mmc\ExifLibTest\InvalidJpeg1.jpg" -"F:\testing\data\ExifLibTest\InvalidJpeg1.jpg"
+"..\data\mmc\ExifLibTest\InvalidJpeg2.jpg" -"F:\testing\data\ExifLibTest\InvalidJpeg2.jpg"
+"..\data\mmc\ExifLibTest\InvalidJpeg3.jpg" -"F:\testing\data\ExifLibTest\InvalidJpeg3.jpg"
+"..\data\mmc\ExifLibTest\NoTagChk_IMG_AN19.jpeg" -"F:\testing\data\ExifLibTest\NoTagChk_IMG_AN19.jpeg"
+"..\data\mmc\ExifLibTest\NoTagChk_Original.jpg" -"F:\testing\data\ExifLibTest\NoTagChk_Original.jpg"
+"..\data\mmc\ExifLibTest\NoThumbnail.jpg" -"F:\testing\data\ExifLibTest\NoThumbnail.jpg"
+"..\data\mmc\ExifLibTest\NotSupportedExif1.jpg" -"F:\testing\data\ExifLibTest\NotSupportedExif1.jpg"
+"..\data\mmc\ExifLibTest\NotSupportedExif2.jpg" -"F:\testing\data\ExifLibTest\NotSupportedExif2.jpg"
+"..\data\mmc\ExifLibTest\tagInWrongIfd.jpg" -"F:\testing\data\ExifLibTest\tagInWrongIfd.jpg"
+"..\data\mmc\ExifLibTest\Thumbnail.jpg" -"F:\testing\data\ExifLibTest\Thumbnail.jpg"
+"..\data\mmc\ExifLibTest\ValidExif.jpg" -"F:\testing\data\ExifLibTest\ValidExif.jpg"
+"..\data\mmc\ExifLibTest\ValidJpeg.jpg" -"F:\testing\data\ExifLibTest\ValidJpeg.jpg"
+"..\data\mmc\ExifLibTest\DSCN1011_unknown_tags.jpg" -"F:\testing\data\ExifLibTest\DSCN1011_unknown_tags.jpg"
+
+"..\data\mmc\ExifLibTest\IOP\a1.jpg" -"F:\testing\data\ExifLibTest\IOP\a1.jpg"
+"..\data\mmc\ExifLibTest\IOP\Bigendian_exif.jpg" -"F:\testing\data\ExifLibTest\IOP\Bigendian_exif.jpg"
+"..\data\mmc\ExifLibTest\IOP\ExifCanon21.jpg" -"F:\testing\data\ExifLibTest\IOP\ExifCanon21.jpg"
+"..\data\mmc\ExifLibTest\IOP\ExifFuji21_1.jpg" -"F:\testing\data\ExifLibTest\IOP\ExifFuji21_1.jpg"
+"..\data\mmc\ExifLibTest\IOP\ExifFuji21_2.jpg" -"F:\testing\data\ExifLibTest\IOP\ExifFuji21_2.jpg"
+"..\data\mmc\ExifLibTest\IOP\ExifFuji21_3.jpg" -"F:\testing\data\ExifLibTest\IOP\ExifFuji21_3.jpg"
+"..\data\mmc\ExifLibTest\IOP\ExifKodak21.jpg" -"F:\testing\data\ExifLibTest\IOP\ExifKodak21.jpg"
+"..\data\mmc\ExifLibTest\IOP\ExifNikon21.jpg" -"F:\testing\data\ExifLibTest\IOP\ExifNikon21.jpg"
+"..\data\mmc\ExifLibTest\IOP\ExifOlympus21.jpg" -"F:\testing\data\ExifLibTest\IOP\ExifOlympus21.jpg"
+"..\data\mmc\ExifLibTest\IOP\ExifRicoh21.jpg" -"F:\testing\data\ExifLibTest\IOP\ExifRicoh21.jpg"
+"..\data\mmc\ExifLibTest\IOP\ExifSanyo20.jpg" -"F:\testing\data\ExifLibTest\IOP\ExifSanyo20.jpg"
+"..\data\mmc\ExifLibTest\IOP\ExifSanyo21.jpg" -"F:\testing\data\ExifLibTest\IOP\ExifSanyo21.jpg"
+"..\data\mmc\ExifLibTest\IOP\ExifSony21.jpg" -"F:\testing\data\ExifLibTest\IOP\ExifSony21.jpg"
+"..\data\mmc\ExifLibTest\IOP\Exif_Own_cpy.jpg" -"F:\testing\data\ExifLibTest\IOP\Exif_Own_cpy.jpg"
+"..\data\mmc\ExifLibTest\IOP\Exif_Own_new.jpg" -"F:\testing\data\ExifLibTest\IOP\Exif_Own_new.jpg"
+"..\data\mmc\ExifLibTest\IOP\F1_gstripe_lab1_decoded_0.jpg" -"F:\testing\data\ExifLibTest\IOP\F1_gstripe_lab1_decoded_0.jpg"
+"..\data\mmc\ExifLibTest\IOP\F1_gstripe_lab2_decoded_0.jpg" -"F:\testing\data\ExifLibTest\IOP\F1_gstripe_lab2_decoded_0.jpg"
+"..\data\mmc\ExifLibTest\IOP\F1_jpeg_datastructure_0808_15fps_120Mhz_decoded_0.jpg" -"F:\testing\data\ExifLibTest\IOP\F1_jpeg_datastructure_0808_15fps_120Mhz_decoded_0.jpg"
+"..\data\mmc\ExifLibTest\IOP\F2_18dB_03_04_decoded_1.jpg" -"F:\testing\data\ExifLibTest\IOP\F2_18dB_03_04_decoded_1.jpg"
+"..\data\mmc\ExifLibTest\IOP\F2_20dB_04_04_04_decoded_0.jpg" -"F:\testing\data\ExifLibTest\IOP\F2_20dB_04_04_04_decoded_0.jpg"
+"..\data\mmc\ExifLibTest\IOP\F2_set2_for_silicon2_2_decoded_0.jpg" -"F:\testing\data\ExifLibTest\IOP\F2_set2_for_silicon2_2_decoded_0.jpg"
+"..\data\mmc\ExifLibTest\IOP\F3_01_01_1152x864_decoded_0.jpg" -"F:\testing\data\ExifLibTest\IOP\F3_01_01_1152x864_decoded_0.jpg"
+"..\data\mmc\ExifLibTest\IOP\F3_01_01_1280x960_decoded_0.jpg" -"F:\testing\data\ExifLibTest\IOP\F3_01_01_1280x960_decoded_0.jpg"
+"..\data\mmc\ExifLibTest\IOP\Image(001).jpg" -"F:\testing\data\ExifLibTest\IOP\Image(001).jpg"
+"..\data\mmc\ExifLibTest\IOP\Image(002).jpg" -"F:\testing\data\ExifLibTest\IOP\Image(002).jpg"
+"..\data\mmc\ExifLibTest\IOP\Image(003)1.jpg" -"F:\testing\data\ExifLibTest\IOP\Image(003)1.jpg"
+"..\data\mmc\ExifLibTest\IOP\Image(005).jpg" -"F:\testing\data\ExifLibTest\IOP\Image(005).jpg"
+"..\data\mmc\ExifLibTest\IOP\Image.jpg" -"F:\testing\data\ExifLibTest\IOP\Image.jpg"
+"..\data\mmc\ExifLibTest\IOP\img06_1.jpg" -"F:\testing\data\ExifLibTest\IOP\img06_1.jpg"
+"..\data\mmc\ExifLibTest\IOP\img07_1.jpg" -"F:\testing\data\ExifLibTest\IOP\img07_1.jpg"
+"..\data\mmc\ExifLibTest\IOP\img08_1.jpg" -"F:\testing\data\ExifLibTest\IOP\img08_1.jpg"
+"..\data\mmc\ExifLibTest\IOP\img09_1.jpg" -"F:\testing\data\ExifLibTest\IOP\img09_1.jpg"
+"..\data\mmc\ExifLibTest\IOP\img11_1.jpg" -"F:\testing\data\ExifLibTest\IOP\img11_1.jpg"
+"..\data\mmc\ExifLibTest\IOP\img12_1.jpg" -"F:\testing\data\ExifLibTest\IOP\img12_1.jpg"
+"..\data\mmc\ExifLibTest\IOP\img13_1.jpg" -"F:\testing\data\ExifLibTest\IOP\img13_1.jpg"
+"..\data\mmc\ExifLibTest\IOP\img14_1.jpg" -"F:\testing\data\ExifLibTest\IOP\img14_1.jpg"
+"..\data\mmc\ExifLibTest\IOP\irfan2.jpg" -"F:\testing\data\ExifLibTest\IOP\irfan2.jpg"
+"..\data\mmc\ExifLibTest\IOP\MirageX.jpg" -"F:\testing\data\ExifLibTest\IOP\MirageX.jpg"
+"..\data\mmc\ExifLibTest\IOP\moneycornr.jpg" -"F:\testing\data\ExifLibTest\IOP\moneycornr.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_121500peep.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_121500peep.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_1918.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_1918.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_2003_0316_150318AA.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_2003_0316_150318AA.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_armour.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_armour.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_blacksea.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_blacksea.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_blmosque.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_blmosque.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_davetime.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_davetime.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_F18.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_F18.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_gorgon.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_gorgon.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_gw2.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_gw2.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_gw3.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_gw3.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_gw8.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_gw8.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_irfan3.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_irfan3.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_mapSC98_595x197.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_mapSC98_595x197.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_mapSC98_793x262.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_mapSC98_793x262.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_mosaic.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_mosaic.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_nastassia.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_nastassia.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_newyki2.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_newyki2.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_new_walls.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_new_walls.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_NYKIbig.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_NYKIbig.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_obelisk.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_obelisk.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_old_walls.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_old_walls.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_Otaniemi2.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_Otaniemi2.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_ovlyki2.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_ovlyki2.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_rnjana06.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_rnjana06.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_smcexperiment.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_smcexperiment.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_stsophia.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_stsophia.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_stsophia_ex.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_stsophia_ex.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_tomb.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_tomb.jpg"
+"..\data\mmc\ExifLibTest\IOP\Odd_wake.jpg" -"F:\testing\data\ExifLibTest\IOP\Odd_wake.jpg"
+"..\data\mmc\ExifLibTest\IOP\Pshop1_176_144.jpg" -"F:\testing\data\ExifLibTest\IOP\Pshop1_176_144.jpg"
+"..\data\mmc\ExifLibTest\IOP\Pshop2_400_300.jpg" -"F:\testing\data\ExifLibTest\IOP\Pshop2_400_300.jpg"
+"..\data\mmc\ExifLibTest\IOP\Pshop3_800_600.jpg" -"F:\testing\data\ExifLibTest\IOP\Pshop3_800_600.jpg"
+"..\data\mmc\ExifLibTest\IOP\red_panda.jpg" -"F:\testing\data\ExifLibTest\IOP\red_panda.jpg"
+"..\data\mmc\ExifLibTest\IOP\sf_haukivuori.jpg" -"F:\testing\data\ExifLibTest\IOP\sf_haukivuori.jpg"
+"..\data\mmc\ExifLibTest\IOP\sf_haukki.jpg" -"F:\testing\data\ExifLibTest\IOP\sf_haukki.jpg"
+"..\data\mmc\ExifLibTest\IOP\v12_j3_jpg3_10_decoded.jpg" -"F:\testing\data\ExifLibTest\IOP\v12_j3_jpg3_10_decoded.jpg"
+"..\data\mmc\ExifLibTest\IOP\v12_j3_jpg4_08_decoded.jpg" -"F:\testing\data\ExifLibTest\IOP\v12_j3_jpg4_08_decoded.jpg"
+
+"..\data\mmc\ExifLibTest\out\Distribution.Policy.S60" -"F:\testing\data\ExifLibTest\out\Distribution.Policy.S60"
+"..\data\mmc\ExifLibTest\IOP\out\Distribution.Policy.S60" -"F:\testing\data\ExifLibTest\IOP\out\Distribution.Policy.S60"
+
+; eof
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/group/bld.inf Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,31 @@
+/*
+* Copyright (c) 2008 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: ExifLib tests
+*
+*/
+
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_TESTEXPORTS
+
+PRJ_EXPORTS
+
+PRJ_TESTMMPFILES
+ExifLibTest.mmp
+
+PRJ_MMPFILES
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/inc/ExifLibTest.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2003, 2004 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: Exif Library Test DLL
+*
+*/
+
+
+#ifndef __EXIFLIBTEST_H
+#define __EXIFLIBTEST_H
+
+
+// INCLUDES
+
+#include <e32base.h>
+
+#include <CppUnit/Test.h>
+#include <CppUnit/TestCase.h>
+#include <CppUnit/TestCaller.h>
+#include <CppUnit/TestSuite.h>
+
+#include "ExifLibTestInc.h"
+// CLASS DECLARATION
+
+
+class CExifLibTest : public CTestSuite
+ {
+ public:
+
+ CExifLibTest(); //lint !e1526 is OK.
+ ~CExifLibTest();
+
+
+ // A function to collect and return a suite of tests
+ static MTest* suiteL ();
+ protected:
+ private:
+ };
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/inc/ExifLibTestInc.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,749 @@
+/*
+* Copyright (c) 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: ExifLibTest
+*
+*/
+#include "ExifRead.h"
+#include "ExifModify.h"
+#include "ExifTag.h"
+#include "ExifValueTable.h"
+#include <fbs.h>
+#include "ExifCommon.h"
+
+
+#ifdef _USE_CPPUNIT_
+#include <CppUnit/Test.h>
+#include <CppUnit/TestCase.h>
+#include <CppUnit/TestCaller.h>
+#include <CppUnit/TestSuite.h>
+#else
+#include "TestFrameWork/test.h"
+#include "TestFrameWork/testCase.h"
+#include "TestFrameWork/testCaller.h"
+#include "TestFrameWork/testSuite.h"
+#endif
+_LIT( KRootC, "C:\\ExifLibTest\\" );
+_LIT( KRootE, "F:\\testing\\data\\ExifLibTest\\" );
+_LIT( KRootData, "C:\\data\\ExifLibTest\\" );
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+_LIT(KIopDir, "C:\\ExifLibTest\\IOP\\");
+_LIT( KRootOut, "C:\\ExifLibTest\\" );
+#else
+_LIT(KIopDir, "F:\\testing\\data\\ExifLibTest\\IOP\\");
+_LIT( KRootOut, "F:\\testing\\data\\ExifLibTest\\" );
+#endif
+
+_LIT(KValidExif, "ValidExif.jpg");
+_LIT(KInvalidExif1, "InvalidExif1.jpg");
+_LIT(KInvalidExif2, "InvalidExif2.jpg");
+_LIT(KInvalidExif3, "InvalidExif3.jpg");
+_LIT(KInvalidExif4, "InvalidExif4.jpg");
+_LIT(KInvalidExif5, "InvalidExif5.jpg");
+_LIT(KInvalidExif6, "InvalidExif6.jpg");
+_LIT(KInvalidExif7, "InvalidExif7.jpg");
+_LIT(KInvalidExif8, "InvalidExif8.jpg");
+_LIT(KInvalidExif9, "InvalidExif9.jpg");
+_LIT(KInvalidExif10, "InvalidExif10.jpg");
+_LIT(KInvalidExif11, "InvalidExif11.jpg");
+_LIT(KInvalidExif12, "InvalidExif12.jpg");
+_LIT(KInvalidExif13, "InvalidExif13.jpg");
+_LIT(KInvalidExif14, "InvalidExif14.jpg");
+_LIT(KNotSupportedExif1, "NotSupportedExif1.jpg");
+_LIT(KNotSupportedExif2, "NotSupportedExif2.jpg");
+_LIT(KFullExif, "FullExif.jpg");
+_LIT(KFullExif3mpix, "FullExif3mpix.jpg");
+_LIT(KValidJpeg, "ValidJpeg.jpg");
+_LIT(KInvalidJpeg1, "InvalidJpeg1.jpg");
+_LIT(KInvalidJpeg2, "InvalidJpeg2.jpg");
+_LIT(KInvalidJpeg3, "InvalidJpeg3.jpg");
+_LIT(KValidThumbnail, "Thumbnail.jpg");
+_LIT(KNoThumbnail, "NoThumbnail.jpg");
+_LIT(KCameraAPIJpeg, "CameraApi.jpg");
+_LIT(KNoTagChk_IMG_AN19, "NoTagChk_IMG_AN19.jpeg");
+_LIT(KNoTagChk_IMG_AN19_out, "NoTagChk_IMG_AN19_out.jpeg");
+_LIT(KNoTagChk_Original, "NoTagChk_Original.jpg");
+_LIT(KtagInWrongIfd, "tagInWrongIfd.jpg");
+_LIT(KtagInWrongIfd_out, "tagInWrongIfd_out.jpg");
+_LIT(KUnknown_tags, "DSCN1011_unknown_tags.jpg");
+_LIT(KUnknown_tags_out, "DSCN1011_unknown_tags_out.jpg");
+
+
+class CExifLibTestInc;
+
+class TUtils
+ {
+ public:
+
+ static HBufC8* ReadFileL(RFs aFs, const TDesC& aFileName)
+ {
+ HBufC* fileName = HBufC::NewL( 128 );
+ CleanupStack::PushL( fileName );
+ fileName->Des().Append( KRootC );
+ fileName->Des().Append( aFileName );
+ RFile file;
+ LOGTEXT2( _L( "ExifLib: TUtils::ReadFileL %s" ), fileName->Ptr());
+ TInt error = file.Open(aFs,fileName->Des(),EFileShareExclusive|EFileRead);
+ if ( error != KErrNone )
+ {
+ fileName->Des().Copy( KRootE );
+ fileName->Des().Append( aFileName );
+ error = file.Open(aFs,fileName->Des(),EFileShareExclusive|EFileRead);
+ if ( error != KErrNone )
+ {
+ fileName->Des().Copy( KRootData );
+ fileName->Des().Append( aFileName );
+ error = file.Open(aFs,fileName->Des(),EFileShareExclusive|EFileRead);
+ if ( error != KErrNone )
+ {
+ User::LeaveIfError( file.Open(aFs,aFileName,EFileShareExclusive|EFileRead) );
+ }
+ }
+ }
+ CleanupClosePushL(file);
+ TInt size = 0;
+ file.Size(size);
+
+ HBufC8* buffer = HBufC8::NewL(size);
+ CleanupStack::PushL(buffer);
+ TPtr8 bufferDes(buffer->Des());
+ User::LeaveIfError(file.Read(bufferDes));
+ CleanupStack::Pop(buffer);
+ CleanupStack::PopAndDestroy();
+ CleanupStack::PopAndDestroy();
+ return buffer;
+ };
+
+ static HBufC8* ReadFileL(RFs aFs, const TDesC& aFileName, TUint32 aMaxRead)
+ {
+ HBufC* fileName = HBufC::NewL( 128 );
+ CleanupStack::PushL( fileName );
+ fileName->Des().Append( KRootC );
+ fileName->Des().Append( aFileName );
+ RFile file;
+ LOGTEXT2( _L( "ExifLib: TUtils::ReadFileL %s" ), fileName->Ptr());
+ TInt error = file.Open(aFs,fileName->Des(),EFileShareExclusive|EFileRead);
+ if ( error != KErrNone )
+ {
+ fileName->Des().Copy( KRootE );
+ fileName->Des().Append( aFileName );
+ error = file.Open(aFs,fileName->Des(),EFileShareExclusive|EFileRead);
+ if ( error != KErrNone )
+ {
+ fileName->Des().Copy( KRootData );
+ fileName->Des().Append( aFileName );
+ error = file.Open(aFs,fileName->Des(),EFileShareExclusive|EFileRead);
+ if ( error != KErrNone )
+ {
+ User::LeaveIfError( file.Open(aFs,aFileName,EFileShareExclusive|EFileRead) );
+ }
+ }
+ }
+ CleanupClosePushL(file);
+ TInt size = 0;
+ file.Size(size);
+ // read up to max size parameter
+ if ( size > aMaxRead )
+ size = aMaxRead;
+
+ HBufC8* buffer = HBufC8::NewL(size);
+ CleanupStack::PushL(buffer);
+ TPtr8 bufferDes(buffer->Des());
+ User::LeaveIfError(file.Read(bufferDes, size));
+ CleanupStack::Pop(buffer);
+ CleanupStack::PopAndDestroy();
+ CleanupStack::PopAndDestroy();
+ return buffer;
+ };
+
+ static HBufC8* CreateDummyBufL(TInt aSize)
+ {
+ HBufC8* buf = HBufC8::NewL(aSize);
+ CleanupStack::PushL(buf);
+ TUint8* tmp = new(ELeave) TUint8[aSize];
+ CleanupStack::PushL(tmp);
+ TInt i = 0;
+ for(i = 0; i < aSize - (aSize % 5); i+=5)
+ {
+ tmp[i] = 'D';
+ tmp[i+1] = 'U';
+ tmp[i+2] = 'M';
+ tmp[i+3] = 'M';
+ tmp[i+4] = 'Y';
+ }
+ for(TInt j = 0; j < aSize % 5; j++)
+ tmp[i + j] = 'D';
+ buf->Des().Copy(tmp, aSize);
+ buf->Des().SetLength(aSize);
+ CleanupStack::PopAndDestroy(tmp);
+ CleanupStack::Pop(buf);
+ return buf;
+ };
+
+ static void GetAllTagsTestL(CExifRead* read, const TDesC& aFileName)
+ {
+ TInt error = 0;
+ RDebug::Print(_L("GetAllTagsTestL starts for %s"), aFileName.Ptr());
+ if ( !read )
+ {
+ return;
+ }
+ HBufC8* thumbnail = NULL;
+ TRAP( error, thumbnail = read->GetThumbnailL());
+ CleanupStack::PushL(thumbnail);
+ if(!error && thumbnail)
+ RDebug::Print(_L("thumbnail ok, size %d ..."), thumbnail->Des().Size());
+ else
+ RDebug::Print(_L("no thumbnail %d..."), error);
+ CleanupStack::PopAndDestroy(thumbnail);
+
+ HBufC8* datetime = NULL;
+ TRAP( error, datetime = read->GetDateTimeL());
+ CleanupStack::PushL(datetime);
+ if( !error && datetime)
+ RDebug::Print(_L("datetime ok, size %d ..."), datetime->Des().Size());
+ else
+ RDebug::Print(_L("no datetime %d..."), error);
+ CleanupStack::PopAndDestroy(datetime);
+
+ HBufC8* imagedescription = NULL;
+ TRAP( error, imagedescription = read->GetImageDescriptionL() );
+ CleanupStack::PushL(imagedescription);
+ if(!error && imagedescription)
+ RDebug::Print(_L("imagedescription ok, size %d ..."), imagedescription->Des().Size());
+ else
+ RDebug::Print(_L("no imagedescription %d..."), error);
+ CleanupStack::PopAndDestroy(imagedescription);
+
+ HBufC8* make = NULL;
+ TRAP( error, make = read->GetMakeL() );
+ CleanupStack::PushL(make);
+ if(!error && make)
+ RDebug::Print(_L("make ok, size %d ..."), make->Des().Size());
+ else
+ RDebug::Print(_L("no make %d..."), error);
+ CleanupStack::PopAndDestroy(make);
+
+ HBufC8* model = NULL;
+ TRAP( error, model = read->GetModelL() );
+ CleanupStack::PushL(model);
+ if(!error && model)
+ RDebug::Print(_L("model ok, size %d ..."), model->Des().Size());
+ else
+ RDebug::Print(_L("no model %d..."), error);
+ CleanupStack::PopAndDestroy(model);
+
+ HBufC8* software = NULL;
+ TRAP( error, software = read->GetSoftwareL() );
+ CleanupStack::PushL(software);
+ if(!error && software)
+ RDebug::Print(_L("software ok, size %d ..."), software->Des().Size());
+ else
+ RDebug::Print(_L("no software %d..."), error);
+ CleanupStack::PopAndDestroy(software);
+
+ HBufC8* copyright = NULL;
+ TRAP( error, copyright = read->GetCopyrightL() );
+ CleanupStack::PushL(copyright);
+ if(!error && copyright)
+ RDebug::Print(_L("copyright ok, size %d ..."), copyright->Des().Size());
+ else
+ RDebug::Print(_L("no copyright %d..."), error);
+ CleanupStack::PopAndDestroy(copyright);
+
+ TUint16 orientation = 0;
+ TInt err = read->GetOrientation( orientation);
+ if(!err)
+ RDebug::Print(_L("orientation ok %d ..."), orientation);
+ else
+ RDebug::Print(_L("no orientation %d..."), err);
+
+ TUint32 gpsversion = 0;
+ err = read->GetGpsVersion( gpsversion );
+ if(!err)
+ RDebug::Print(_L("gpsversion ok 0x%x ..."), gpsversion);
+ else
+ RDebug::Print(_L("no gpsversion %d..."), err);
+
+ TUint32 exifversion = 0;
+ err = read->GetExifVersion( exifversion );
+ if(!err)
+ RDebug::Print(_L("exifversion ok 0x%x ..."), exifversion);
+ else
+ RDebug::Print(_L("no exifversion %d..."), err);
+
+ TUint32 flashpixversion = 0;
+ err = read->GetFlashPixVersion( flashpixversion );
+ if(!err)
+ RDebug::Print(_L("flashpixversion ok 0x%x ..."), flashpixversion);
+ else
+ RDebug::Print(_L("no flashpixversion %d..."), err);
+
+ HBufC8* datetimeoriginal = NULL;
+ TRAP( error, datetimeoriginal = read->GetDateTimeOriginalL() );
+ CleanupStack::PushL(datetimeoriginal);
+ if(!error && datetimeoriginal)
+ RDebug::Print(_L("datetimeoriginal ok, size %d ..."), datetimeoriginal->Des().Size());
+ else
+ RDebug::Print(_L("no datetimeoriginal %d..."), error);
+ CleanupStack::PopAndDestroy(datetimeoriginal);
+
+ HBufC8* datetimedigitized = NULL;
+ TRAP( error, datetimedigitized = read->GetDateTimeDigitizedL() );
+ CleanupStack::PushL(datetimedigitized);
+ if(!error && datetimedigitized)
+ RDebug::Print(_L("datetimedigitized ok, size %d ..."), datetimedigitized->Des().Size());
+ else
+ RDebug::Print(_L("no datetimedigitized %d..."), error);
+ CleanupStack::PopAndDestroy(datetimedigitized);
+
+ HBufC8* usercomment = NULL;
+ TRAP( error, usercomment = read->GetUserCommentL() );
+ CleanupStack::PushL(usercomment);
+ if(!error && usercomment)
+ RDebug::Print(_L("usercomment ok, size %d ..."), usercomment->Des().Size());
+ else
+ RDebug::Print(_L("no usercomment %d..."), error);
+ CleanupStack::PopAndDestroy(usercomment);
+
+ HBufC8* relatedsoundfile = NULL;
+ TRAP( error, relatedsoundfile = read->GetRelatedSoundFileL() );
+ CleanupStack::PushL(relatedsoundfile);
+ if(!error && relatedsoundfile)
+ RDebug::Print(_L("relatedsoundfile ok, size %d ..."), relatedsoundfile->Des().Size());
+ else
+ RDebug::Print(_L("no relatedsoundfile %d..."), error);
+ CleanupStack::PopAndDestroy(relatedsoundfile);
+
+
+/*-------------- missing test cases---------
+
+ TInt GetXResolution(
+ TUint32& aXResolution1,
+ TUint32& aXResolution2 ) const;
+
+ TInt GetYResolution(
+ TUint32& aYResolution1,
+ TUint32& aYResolution2 ) const;
+
+ TInt GetResolutionUnit( TUint16& aResolutionUnit ) const;
+
+ TInt GetYCbCrPositioning( TUint16& aYCbCrPositioning ) const;
+
+ TInt GetExifIfdPointer( TUint32& aExifIfdPointer ) const;
+
+ TInt GetGpsInfoIfdPointer( TUint32& aGpsInfoIfdPointer ) const;
+
+ HBufC8* GetIsoSpeedRatingsL() const;
+
+ HBufC8* GetMakerNoteL() const;
+
+
+ TInt GetExposureTime(
+ TUint32& aExposureTime1,
+ TUint32& aExposureTime2 ) const;
+
+ TInt GetComponentsConfiguration(
+ TUint8& aFirstComponent, TUint8& aSecondComponent,
+ TUint8& aThirdComponent, TUint8& aFourthComponent) const;
+
+ TInt GetFlash( TUint16& aFlash ) const;
+
+ TInt GetColorSpace( TUint16& aColorSpace ) const;
+
+ TInt GetPixelXDimension( TUint32& aPixelXDimension ) const;
+
+ TInt GetPixelYDimension( TUint32& aPixelYDimension ) const;
+
+ TInt GetExposureMode( TUint16& aExposureMode ) const;
+
+ TInt GetWhiteBalance( TUint16& aWhiteBalance ) const;
+
+ TInt GetSceneCaptureType( TUint16& aSceneCaptureType ) const;
+
+ TInt GetExposureProgram( TUint16& aExposureProgram ) const;
+
+ TInt GetApertureValue(
+ TUint32& aApertureValue1,
+ TUint32& aApertureValue2 ) const;
+
+ TInt GetExposureBiasValue(
+ TInt32& aExposureBiasValue1,
+ TInt32& aExposureBiasValue2 ) const;
+
+ TInt GetMeteringMode( TUint16& aMeteringMode ) const;
+
+ TInt GetLightSource( TUint16& aLightSource ) const;
+
+ TInt GetFileSource( TInt8& aFileSource ) const;
+
+ TInt GetDigitalZoomRatio(
+ TUint32& aDigitalZoomRatio1,
+ TUint32& aDigitalZoomRatio2 ) const;
+
+ TInt GetContrast( TUint16& aContrast ) const;
+
+ TInt GetSaturation( TUint16& aSaturation ) const;
+
+ TInt GetSharpness( TUint16& aSharpness ) const;
+
+
+
+ TInt GetInteroperabilityIfdPointer(
+ TUint32& aInteroperabilityIfdPointer ) const;
+
+ TInt GetThumbnailXResolution(
+ TUint32& aXResolution1,
+ TUint32& aXResolution2 ) const;
+
+ TInt GetThumbnailYResolution(
+ TUint32& aYResolution1,
+ TUint32& aYResolution2 ) const;
+
+ TInt GetThumbnailResolutionUnit( TUint16& aResolutionUnit ) const;
+
+ TInt GetThumbnailCompression( TUint16& aCompression ) const;
+
+ TInt GetJpegInterchangeFormat( TUint32& aJpegInterchangeFormat ) const;
+
+ TInt GetJpegInterchangeFormatLength(
+ TUint32& aJpegInterchangeFormatLength ) const;
+
+ HBufC8* GetExifAppSegmentL() const;
+
+ TInt GetShutterSpeedValue( TInt32& aShutterSpeedValue1,
+ TInt32& aShutterSpeedValue2 ) const;
+
+ TInt GetBrightnessValue( TInt32& aBrightnessValue1,
+ TInt32& aBrightnessValue2 ) const;
+
+ TInt GetCustomRendered( TUint16& aCustomRendered ) const;
+
+ TInt GetGainControl( TUint16& aGainControl ) const;
+
+
+
+--------------*/
+ return;
+ };
+ };
+
+class CExifTagTest : public CTestCase
+ {
+ friend class CExifLibTestInc;
+
+ RFs iFs;
+ public:
+ CExifTagTest(){};
+ ~CExifTagTest(){};
+ void ExifTag001L();
+ void ExifTag002L();
+ // Allocate the resources for one test function
+ void setUpL ()
+ {
+ User::LeaveIfError(iFs.Connect());
+ };
+
+ // Free the resources reserved in setUpL()
+ void tearDown ()
+ {
+ iFs.Close();
+ };
+ };
+
+class CExifReadTest : public CTestCase
+ {
+ friend class CExifLibTestInc;
+ RFs iFs;
+
+ public:
+ CExifReadTest(){};
+ ~CExifReadTest(){};
+ void ExifRead001L();
+ void ExifRead002L();
+ void ExifRead003L();
+ void ExifRead004L();
+ void ExifRead005L();
+ void ExifRead006L();
+ void ExifRead007L();
+ void ExifRead008L();
+ void ExifRead009L();
+ void ExifRead010L();
+ void ExifRead011L();
+ void ExifRead012L();
+ void ExifRead013L();
+ void ExifRead014L();
+ void ExifRead015L();
+ void ExifRead016L();
+ void ExifRead017L();
+ void ExifRead018L();
+ // For fast reader
+ void ExifRead101L();
+ void ExifRead102L();
+ void ExifRead103L();
+ void ExifRead104L();
+ void ExifRead105L();
+ void ExifRead106L();
+ void ExifRead107L();
+ void ExifRead108L();
+ void ExifRead109L();
+ void ExifRead110L();
+ void ExifRead111L();
+ void ExifRead112L();
+ void ExifRead113L();
+ void ExifRead114L();
+ void ExifRead115L();
+ void ExifRead116L();
+ // For no tag validity checking
+ void ExifRead201L();
+ void ExifRead202L();
+ void ExifRead203L();
+ void ExifRead204L();
+ void ExifRead205L();
+ void ExifRead206L();
+ void ExifRead207L();
+ void ExifRead208L();
+ void ExifRead209L();
+ void ExifRead210L();
+ void ExifRead211L();
+ void ExifRead212L();
+ void ExifRead213L();
+ void ExifRead214L();
+ void ExifRead215L();
+ void ExifRead216L();
+
+ // Allocate the resources for one test function
+ void setUpL ()
+ {
+ User::LeaveIfError(iFs.Connect());
+ };
+
+
+ // Free the resources reserved in setUpL()
+ void tearDown ()
+ {
+ iFs.Close();
+ };
+ };
+
+class CExifCreateTest : public CTestCase
+ {
+ friend class CExifLibTestInc;
+ RFs iFs;
+
+ public:
+ CExifCreateTest(){};
+ ~CExifCreateTest(){};
+ void ExifCreate001L();
+ void ExifCreate002L();
+ void ExifCreate003L();
+ void ExifCreate004L();
+ void ExifCreate005L();
+ void ExifCreate006L();
+ void ExifCreate007L();
+ void ExifCreate008L();
+ void ExifCreate009L();
+ void ExifCreate010L();
+ void ExifCreate011L();
+ void ExifCreate012L();
+ void ExifCreate013L();
+ //For fast test
+ void ExifCreate101L();
+ void ExifCreate102L();
+ void ExifCreate103L();
+ void ExifCreate104L();
+ void ExifCreate105L();
+ void ExifCreate106L();
+ void ExifCreate107L();
+ void ExifCreate108L();
+ void ExifCreate109L();
+ void ExifCreate110L();
+ void ExifCreate111L();
+ void ExifCreate112L();
+ void ExifCreate113L();
+
+ // Allocate the resources for one test function
+ void setUpL ()
+ {
+ User::LeaveIfError(iFs.Connect());
+ };
+
+ // Free the resources reserved in setUpL()
+ void tearDown ()
+ {
+ iFs.Close();
+ };
+ };
+
+class CExifModifyTest : public CTestCase
+ {
+ friend class CExifLibTestInc;
+ RFs iFs;
+
+ public:
+ CExifModifyTest(){};
+ ~CExifModifyTest(){};
+ void ExifModify001L();
+ void ExifModify002L();
+ void ExifModify003L();
+ void ExifModify004L();
+ void ExifModify005L();
+ void ExifModify006L();
+ void ExifModify007L();
+ void ExifModify008L();
+ void ExifModify009L();
+ void ExifModify010L();
+ void ExifModify011L();
+ void ExifModify012L();
+ void ExifModify013L();
+ void ExifModify014L();
+ void ExifModify015L();
+ void ExifModify016L();
+ void ExifModify017L();
+ void ExifModify018L();
+ void ExifModify019L();
+ void ExifModify020L();
+ void ExifModify021L();
+ void ExifModify022L();
+ void ExifModify023L();
+ // For fast modifier
+ void ExifModify101L();
+ void ExifModify102L();
+ void ExifModify103L();
+ void ExifModify104L();
+ void ExifModify105L();
+ void ExifModify106L();
+ void ExifModify107L();
+ void ExifModify108L();
+ void ExifModify109L();
+ void ExifModify110L();
+ void ExifModify111L();
+ void ExifModify112L();
+ void ExifModify113L();
+ void ExifModify114L();
+ void ExifModify115L();
+ void ExifModify116L();
+ void ExifModify117L();
+ void ExifModify118L();
+ void ExifModify119L();
+
+
+ // Allocate the resources for one test function
+ void setUpL ()
+ {
+ User::LeaveIfError(iFs.Connect());
+ };
+
+ // Free the resources reserved in setUpL()
+ void tearDown ()
+ {
+ iFs.Close();
+ };
+ };
+
+class CExifModifyTest2 : public CTestCase
+ {
+ friend class CExifLibTestInc;
+ RFs iFs;
+
+ public:
+ CExifModifyTest2(){};
+ ~CExifModifyTest2(){};
+ void ExifModify001L();
+ void ExifModify002L();
+ void ExifModify003L();
+ void ExifModify004L();
+ void ExifModify005L();
+ void ExifModify006L();
+ void ExifModify007L();
+ void ExifModify008L();
+ void ExifModify009L();
+ void ExifModify010L();
+ void ExifModify011L();
+ void ExifModify012L();
+ void ExifModify013L();
+ void ExifModify014L();
+ void ExifModify015L();
+ void ExifModify016L();
+ void ExifModify017L();
+ void ExifModify018L();
+ void ExifModify019L();
+
+ // Allocate the resources for one test function
+ void setUpL ()
+ {
+ User::LeaveIfError(iFs.Connect());
+ };
+
+ // Free the resources reserved in setUpL()
+ void tearDown ()
+ {
+ iFs.Close();
+ };
+ };
+
+class CExifIopTest : public CTestCase
+ {
+ friend class CExifLibTestInc;
+ RFs iFs;
+
+ public:
+ CExifIopTest(){};
+ ~CExifIopTest(){};
+ void ExifIop001L();
+ void ExifIop002L();
+ void ExifIop003L();
+ void ExifIop004L();
+ void ExifIop005L();
+ // Allocate the resources for one test function
+ void setUpL ()
+ {
+ User::LeaveIfError(iFs.Connect());
+ iWrite = ETrue;
+ };
+
+ // Free the resources reserved in setUpL()
+ void tearDown ()
+ {
+ iFs.Close();
+ };
+ private:
+ void ExifIop1L(const TDesC& aFileName);
+ void ExifIop2L(const TDesC& aFileName);
+ void ExifIop3L(CExifRead* aExifRead, const TDesC& aFileName);
+ HBufC8* CreateDummyBufL(TInt aSize);
+ void InsertGpsTagsL(CExifModify* aModify);
+
+ TBool iWrite;
+ };
+
+class CExifLibTestInc : public CTestCase
+ {
+ friend class CExifTagTest;
+ friend class CExifReadTest;
+ friend class CExifCreateTest;
+ public:
+
+ CExifLibTestInc();
+ ~CExifLibTestInc();
+
+ // Allocate the resources for one test function
+ void setUpL ();
+
+ // Free the resources reserved in setUpL()
+ void tearDown ();
+
+ // A function to collect and return a suite of tests
+ static MTest* suiteL ();
+ };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/inc/ExifLibTestStif.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,118 @@
+/*
+* Copyright (c) 2003, 2004 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: Exif Library Test DLL
+*
+*/
+
+
+#ifndef __EXIFLIBTEST_H
+#define __EXIFLIBTEST_H
+
+
+// INCLUDES
+
+#include <e32base.h>
+
+#include "ExifLibTestInc.h"
+// CLASS DECLARATION
+class CTestModule;
+class TCaseInfo;
+
+// Demo testmodule class definition.
+NONSHARABLE_CLASS( CTestModule )
+ :public CTestModuleBase
+ {
+ public: // Enumerations
+ // None
+
+ private: // Enumerations
+ // None
+
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor.
+ */
+ static CTestModule* NewL();
+
+ /**
+ * Destructor.
+ */
+ ~CTestModule();
+
+ public: // New functions
+ // None
+
+ public: // Functions from base classes
+
+ /**
+ * Test cases are inquired from the Test Module by calling GetTestCases.
+ * Test cases are appended to RPointerArray<TTestCaseInfo>& aTestCases
+ * that is a list consisting of several TTestCaseInfo objects.
+ */
+ TInt GetTestCasesL( const TFileName& aConfigFile,
+ RPointerArray<TTestCaseInfo>& aTestCases );
+ /**
+ * RunTestCase is used to run an individual test case.
+ */
+ TInt RunTestCaseL( const TInt aCaseNumber,
+ const TFileName& aConfig,
+ TTestResult& aResult );
+
+ protected: // New functions
+ // None
+
+ protected: // Functions from base classes
+ // None
+
+ private:
+
+ /**
+ * C++ default constructor.
+ */
+ CTestModule();
+
+ /**
+ * Symbian OS constructor.
+ */
+ void ConstructL();
+
+ /**
+ * Function returning test case name and pointer to test case function
+ */
+ const TCaseInfo Case ( const TInt aCaseNumber ) const;
+
+
+ public: //Data
+ // None
+
+ protected: // Data
+ // None
+
+ private: // Data
+
+ CTestSuite *iTestSuite ;
+ CActiveScheduler* iScheduler;
+
+ public: // Friend classes
+ // None
+
+ protected: // Friend classes
+ // None
+
+ private: // Friend classes
+ // None
+
+ };
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/inc/TestFrameWork/AssertFailure.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,68 @@
+/*
+* Copyright (c) 2002 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: ExifLibTest
+*
+*/
+
+
+
+#ifndef __CPPUNIT_ASSERT_FAILURE_H
+#define __CPPUNIT_ASSERT_FAILURE_H
+
+#include <e32base.h>
+
+_LIT8(KCppUnitUnknownFilename, "-unknown-");
+const TInt KCppUnitUnknownLineNumber=(-1);
+
+
+class CAssertFailure : public CBase
+ {
+public:
+
+ static CAssertFailure* NewL (const TDesC8& aMessage,
+ TInt aLineNumber=KCppUnitUnknownLineNumber,
+ const TDesC8& aFileName=KCppUnitUnknownFilename);
+
+ static CAssertFailure* NewLC (const TDesC8& aMessage,
+ TInt aLineNumber=KCppUnitUnknownLineNumber,
+ const TDesC8& aFileName=KCppUnitUnknownFilename);
+
+ static CAssertFailure* NewL (CAssertFailure& aAssertFailure);
+
+ static CAssertFailure* NewLC (CAssertFailure& aAssertFailure);
+
+ ~CAssertFailure ();
+
+ const TDesC8& What() const;
+ TInt LineNumber() const;
+ const TDesC8& FileName() const;
+
+ void SetMyHeapCellCount (TInt aHeapCellCount);
+ TInt MyHeapCellCount ();
+
+private:
+
+ CAssertFailure ();
+ CAssertFailure (TInt aLineNumber);
+ void ConstructL (const TDesC8& aMessage, const TDesC8& aFileName);
+ void ConstructL (CAssertFailure& aAssertFailure);
+
+ HBufC8* iMessage;
+ TInt iLineNumber;
+ HBufC8* iFileName;
+ TInt iMyHeapCellCount;
+ };
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/inc/TestFrameWork/TestResult.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,72 @@
+/*
+* Copyright (c) 2002 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: ExifLibTest
+*
+*/
+
+
+
+#ifndef __CPPUNIT_TESTRESULT_H
+#define __CPPUNIT_TESTRESULT_H
+
+#include <e32base.h>
+
+class MTest;
+class CAssertFailure;
+class CTestFailure;
+
+
+/*
+ * A CTestResult collects the results of executing a test case. It is an
+ * instance of the Collecting Parameter pattern.
+ *
+ * The test framework distinguishes between failures and errors.
+ * A failure is anticipated and checked for with assertions. Errors are
+ * unanticipated problems that are caused by "leaves" that are not generated
+ * by the framework.
+ *
+ * see MTest
+ */
+
+class CTestResult : public CBase
+ {
+public:
+
+ IMPORT_C static CTestResult* NewLC();
+ IMPORT_C static CTestResult* NewL();
+
+ IMPORT_C ~CTestResult ();
+
+ IMPORT_C TInt TestCount ();
+ IMPORT_C RPointerArray<CTestFailure>& Errors ();
+ IMPORT_C RPointerArray<CTestFailure>& Failures ();
+ IMPORT_C TBool WasSuccessful ();
+
+ void IncrementTestCount ();
+ void AddErrorL (MTest& aTest, TInt aError);
+ void AddFailureL (MTest& aTest, CAssertFailure* aAssertFailure);
+
+private:
+
+ void ConstructL ();
+ CTestResult ();
+
+ RPointerArray<CTestFailure> iErrors;
+ RPointerArray<CTestFailure> iFailures;
+ TInt iTestCount;
+ };
+
+#endif
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/inc/TestFrameWork/test.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,55 @@
+/*
+* Copyright (c) 2002 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: ExifLibTest
+*
+*/
+
+
+
+#ifndef __CPPUNIT_MTEST_H
+#define __CPPUNIT_MTEST_H
+
+#include <e32base.h>
+#include <StifTestModule.h>
+class CCppUnitLog;
+
+
+// A MTest can be run and collect its results. See CTestResult.
+//
+class MTest
+ {
+public:
+
+ virtual ~MTest() { }
+
+ virtual void ExecuteL (TTestResult& aResult) = 0;
+
+ virtual TInt CountTestCases () = 0;
+
+ virtual const TDesC8& Name () = 0;
+
+ // Same functions with an Index.
+ virtual void ExecuteTestL(TTestResult& aResult,
+ TInt aIndex) = 0;
+
+ virtual const TDesC8& TestCaseName (TInt aIndex) = 0;
+ };
+
+// All the polymorphic DLLs containing tests should use the following UID:
+//
+const TInt KCppUnitTestDllUidValue=0x101F5380;
+const TUid KCppUnitTestDllUid={KCppUnitTestDllUidValue};
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/inc/TestFrameWork/testCaller.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,120 @@
+/*
+* Copyright (c) 2002 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: ExifLibTest
+*
+*/
+
+
+
+#ifndef CPPUNIT_TESTCALLER_H
+#define CPPUNIT_TESTCALLER_H
+
+#include "TestFrameWork/testCase.h"
+
+
+/*
+ * A test caller provides access to a test case method
+ * on a test case class. Test callers are useful when
+ * you want to run an individual test or add it to a suite.
+ *
+ * Here is an example:
+ *
+ * class CMathTest : public CTestCase
+ * {
+ * public:
+ * void setUpL ();
+ * void tearDown ();
+ *
+ * protected:
+ * void testAddL ();
+ * void testSubtractL ();
+ * };
+ *
+ * CTest* CMathTest::suiteL ()
+ * {
+ * CTestSuite *suite = CTestSuite::NewL();
+ * suite->addTestL(CTestCaller<MathTest>::NewL(_L("testAddL") testAddL));
+ * suite->addTestL(CTestCaller<MathTest>::NewL(_L("testSubtractL") testSubtractL));
+ * return suite;
+ * }
+ *
+ * You can use a CTestCaller to bind any test method on a CTestCase
+ * class, as long as it does not have parameters and returns void.
+ *
+ * See CTestCase
+ */
+
+
+template <class Fixture> class CTestCaller : public CTestCase
+ {
+public:
+
+ typedef void (Fixture::*TestMethod)();
+
+ static CTestCaller* NewLC (const TDesC8& aName, TestMethod aTest);
+ static CTestCaller* NewL (const TDesC8& aName, TestMethod aTest);
+ ~CTestCaller();
+
+protected:
+
+ // From CTestCase:
+ void setUpL () { iFixture->setUpL (); }
+ void executeTestL () { (iFixture->*iTest)(); }
+ void tearDown () { iFixture->tearDown (); }
+
+private:
+
+ CTestCaller (TestMethod aTest) : iTest(aTest) { }
+ void ConstructL (const TDesC8& aName);
+
+ TestMethod iTest;
+ Fixture *iFixture;
+ };
+
+
+template <class Fixture>
+CTestCaller<Fixture>* CTestCaller<Fixture>::NewLC (const TDesC8& aName,
+ TestMethod aTest)
+ {
+ CTestCaller* self = new(ELeave) CTestCaller(aTest);
+ CleanupStack::PushL(self);
+ self->ConstructL(aName);
+ return self;
+ }
+
+template <class Fixture>
+CTestCaller<Fixture>* CTestCaller<Fixture>::NewL (const TDesC8& aName,
+ TestMethod aTest)
+ {
+ CTestCaller* self = NewLC(aName, aTest);
+ CleanupStack::Pop();
+ return self;
+ }
+
+
+template <class Fixture>
+void CTestCaller<Fixture>::ConstructL (const TDesC8& aName)
+ {
+ CTestCase::ConstructL(aName);
+ iFixture = new(ELeave)Fixture;
+ }
+
+
+template <class Fixture>
+CTestCaller<Fixture>::~CTestCaller ()
+ {
+ delete iFixture;
+ }
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/inc/TestFrameWork/testCase.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,200 @@
+/*
+* Copyright (c) 2002 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: ExifLibTest
+*
+*/
+
+
+
+#ifndef __CPPUNIT_CTESTCASE_H
+#define __CPPUNIT_CTESTCASE_H
+
+#include <e32base.h>
+#include "TestFrameWork/test.h"
+#include <StifTestModule.h>
+class CAssertFailure;
+class CTestResult;
+class CppUnitLog;
+
+/*
+ * A test case defines the fixture to run multiple tests. To define a test case
+ * 1) implement a subclass of CTestCase
+ * 2) define instance variables that store the state of the fixture
+ * 3) initialize the fixture state by overriding setUp
+ * 4) clean-up after a test by overriding tearDown.
+ *
+ * Each test runs in its own fixture so there can be no side effects
+ * among test runs. Here is an example:
+ *
+ * class CMathTest : public CTestCase
+ * {
+ * public:
+ *
+ * void setUpL ()
+ * {
+ * iValue1 = 2;
+ * iValue2 = 3;
+ * }
+ *
+ * private:
+ *
+ * TInt iValue1, iValue2;
+ * }
+ *
+ * For each test implement a method which interacts with the fixture.
+ * Verify the expected results with assertions specified
+ * by calling assert on the expression you want to test:
+ *
+ * protected:
+ * void testAddL ()
+ * {
+ * TInt result = value1 + value2;
+ * assertL (result == 5);
+ * }
+ *
+ * The tests to be run can be collected into a CTestSuite:
+ *
+ * public:
+ * static CMathTest::suiteL ()
+ * {
+ * CTestSuite *suiteOfTests = CTestSuite::NewL(_L8("aSuite"));
+ * suiteOfTests->addTestL(CTestCaller<MathTest>::NewL(_L8("testAddL"), testAddL));
+ * return suiteOfTests;
+ * }
+ *
+ * see CTestSuite and CTestCaller
+ *
+ */
+
+
+class CTestCase : public MTest, public CBase
+ {
+public:
+
+ ~CTestCase ();
+
+ // From MTest:
+ void ExecuteL (TTestResult& aResult);
+
+ // From MTest:
+ TInt CountTestCases ();
+
+ // From MTest:
+ const TDesC8& Name ();
+
+ // From MTest:
+ void ExecuteTestL(TTestResult& aResult,
+ TInt aIndex);
+
+ // From MTest:
+ const TDesC8& TestCaseName (TInt aIndex);
+
+protected:
+
+ virtual void ConstructL (const TDesC8& aName);
+
+ void AssertL (TBool aCondition,
+ const TDesC8& aConditionExpression,
+ TInt aLineNumber,
+ const TDesC8& aFileName);
+
+ void AssertEqualsL (TInt aExpected,
+ TInt aActual,
+ TInt aLineNumber,
+ const TDesC8& aFileName);
+
+ void AssertEqualsL (TReal aExpected,
+ TReal aActual,
+ TReal aDelta,
+ TInt aLineNumber,
+ const TDesC8& aFileName);
+
+ void AssertEqualsL (const TDesC8& aExpected,
+ const TDesC8& aActual,
+ TInt aLineNumber,
+ const TDesC8& aFileName);
+
+ void AssertEqualsL (const TDesC16& aExpected,
+ const TDesC16& aActual,
+ TInt aLineNumber,
+ const TDesC8& aFileName);
+
+ void AllocFailureSimulation (TBool aSwitchedOn);
+
+ virtual void setUpL () = 0;
+ virtual void executeTestL () { }
+ virtual void tearDown () = 0;
+
+ CTestCase ();
+
+private:
+
+ TInt ExecuteImplL ();
+
+ HBufC8* NotEqualsMessageLC (const TDesC8& aExpected,
+ const TDesC8& aActual);
+
+ HBufC8* NotEqualsMessageLC (const TDesC16& aExpected,
+ const TDesC16& aActual);
+
+ void AssertFailureToTlsL (const TDesC8& aMessage,
+ TInt aLineNumber,
+ const TDesC8& aFileName);
+
+ CAssertFailure* AssertFailureFromTlsL ();
+
+ TInt HeapCellsReservedByAssertFailure ();
+
+ // data
+ HBufC8* iName;
+ RHeap::TAllocFail iAllocFailureType;
+ TUint iAllocFailureRate;
+ };
+
+
+// A set of macros which allow us to get the line number
+// and file name at the point of an assertion failure:
+
+#undef assertL
+#define assertL(condition)\
+ (this->AssertL ((condition), TPtrC8((TText8*)(#condition)),\
+ __LINE__, TPtrC8((TText8*)__FILE__)))
+
+// Macros for primitive value comparisons
+#define assertTIntsEqualL(expected,actual)\
+ (this->AssertEqualsL ((expected), (actual),\
+ __LINE__, TPtrC8((TText8*)__FILE__)))
+
+#define assertTRealsEqualL(expected,actual,delta)\
+ (this->AssertEqualsL ((expected), (actual), (delta),\
+ __LINE__,TPtrC8((TText8*)__FILE__)))
+
+
+// Macros for descriptor comparisons
+#define assertTDesC8sEqualL(expected,actual)\
+ (this->AssertEqualsL ((expected), (actual),\
+ __LINE__, TPtrC8((TText8*)__FILE__)))
+
+#define assertTDesC16sEqualL(expected,actual)\
+ (this->AssertEqualsL ((expected), (actual),\
+ __LINE__, TPtrC8((TText8*)__FILE__)))
+
+#if defined(_UNICODE)
+#define assertTDesCsEqualL(expected,actual) assertTDesC16sEqualL(expected,actual)
+#else
+#define assertTDesCsEqualL(expected,actual) assertTDesC8sEqualL(expected,actual)
+#endif
+
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/inc/TestFrameWork/testSuite.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,73 @@
+/*
+* Copyright (c) 2002 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: ExifLibTest
+*
+*/
+
+
+
+#ifndef __CPPUNIT_CTESTSUITE_H
+#define __CPPUNIT_CTESTSUITE_H
+
+#include <e32base.h>
+#include "TestFrameWork/test.h"
+
+class TestResult;
+class CppUnitLog;
+
+/*
+* A CTestSuite is a Composite of MTests.
+* It runs a collection of test cases.
+*
+* see MTest and CTestCaller
+*/
+
+
+class CTestSuite : public MTest, public CBase
+ {
+ public:
+
+ static CTestSuite* NewLC(const TDesC8& aName);
+ static CTestSuite* NewL(const TDesC8& aName);
+ ~CTestSuite ();
+
+ void addTestL (MTest *aTest);
+
+ // From MTest:
+ void ExecuteL (TTestResult& aResult);
+
+ // From MTest:
+ TInt CountTestCases ();
+
+ // From MTest:
+ const TDesC8& Name ();
+
+
+ // From MTest:
+ void ExecuteTestL(TTestResult& aResult,
+ TInt aIndex);
+
+ // From MTest:
+ const TDesC8& TestCaseName (TInt aIndex);
+
+ private:
+
+ void ConstructL (const TDesC8& aName);
+ CTestSuite () { }
+
+ RPointerArray<MTest> iTests;
+ HBufC8 *iName;
+ };
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/src/ExifCreateTest.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,1338 @@
+/*
+* Copyright (c) 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: ExifLibTest
+*
+*/
+#include "ExifLibTestInc.h"
+
+
+// Exif.Create.001
+// Instantiate an Exif modifier with valid Jpeg image
+// Created Exif modifier instance in ECreate mode is returned.
+void CExifCreateTest::ExifCreate001L()
+ {
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = CExifModify::NewL(*jpeg, CExifModify::ECreate);
+ if(!modify)
+ User::Leave(KErrGeneral);
+ delete modify;
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+// Exif.Create.002
+// Try to instantiate an Exif modifier with invalid/ corrupted Jpeg image
+// Leaves with proper error code.
+void CExifCreateTest::ExifCreate002L()
+ {
+ // Various invalid/ corrupted Jpeg images
+
+ // Not baseline Jpeg
+ HBufC8* jpeg = TUtils::ReadFileL( iFs, KInvalidJpeg1 );
+ CleanupStack::PushL( jpeg );
+ CExifModify* modify = 0;
+ TRAPD( error, modify = CExifModify::NewL(*jpeg, CExifModify::ECreate) );
+ if ( ( error != KErrNotSupported ) || ( modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( jpeg );
+
+ // No SOI
+ jpeg = TUtils::ReadFileL( iFs, KInvalidJpeg2 );
+ CleanupStack::PushL( jpeg );
+ TRAP( error, modify = CExifModify::NewL(*jpeg, CExifModify::ECreate) );
+ if ( ( error != KErrCorrupt ) || ( modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( jpeg );
+
+ // No EOI
+ jpeg = TUtils::ReadFileL( iFs, KInvalidJpeg3 );
+ CleanupStack::PushL( jpeg );
+ TRAP( error, modify = CExifModify::NewL(*jpeg, CExifModify::ECreate) );
+ if ( ( error != KErrCorrupt ) || ( modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( jpeg );
+
+ jpeg = TUtils::CreateDummyBufL( 120000 );
+ CleanupStack::PushL( jpeg );
+ HBufC8* jpeg2 = TUtils::ReadFileL( iFs, KValidJpeg );
+ jpeg->Des().Copy( jpeg2->Ptr(), jpeg->Length() / 1000 );
+ jpeg->Des().SetLength(120000);
+ delete jpeg2;
+ jpeg2 = 0;
+ TRAP( error, modify = CExifModify::NewL(*jpeg, CExifModify::ECreate) );
+ if ( ( error != KErrCorrupt ) || ( modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( jpeg );
+ }
+
+// Exif.Create.003
+// Retrieve reader instance for the related Exif data.
+// Returns unmodifiable reader instance.
+void CExifCreateTest::ExifCreate003L()
+ {
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = CExifModify::NewL(*jpeg, CExifModify::ECreate);
+ CleanupStack::PushL(modify);
+
+ const CExifRead* reader = modify->Reader();
+ if(!reader)
+ User::Leave(KErrGeneral);
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+// Exif.Create.004
+// Insert/ Update a valid tag into the specified IFD in Exif data.
+// The given tag instance is inserted or updated.
+void CExifCreateTest::ExifCreate004L()
+ {
+//For each IFD.
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = CExifModify::NewL(*jpeg, CExifModify::ECreate);
+ CleanupStack::PushL(modify);
+
+
+ HBufC8* buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ TExifTagInfo tag(KIdImageDescription, CExifTag::ETagAscii, 16);
+ modify->SetTagL(EIfd0, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(20);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdUserComment;
+ tag.iDataType = CExifTag::ETagUndefined;
+ tag.iDataCount = 20;
+ modify->SetTagL(EIfdExif, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 0;
+ tag.iId = KIdExposureProgram;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 1;
+ modify->SetTagL(EIfdExif, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(1);
+ CleanupStack::PushL(buf);
+ tag.iId = 3;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 1;
+ modify->SetTagL(EIfdGps, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(3);
+ CleanupStack::PushL(buf);
+ tag.iId = 1;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 3;
+ modify->SetTagL(EIfdIntOp, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 2;
+ tag.iId = KIdResolutionUnit;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 1;
+ modify->SetTagL(EIfd1, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+// Exif.Create.005
+// Try to insert/ update an invalid tag into the specified IFD in Exif data.
+// Leaves with proper error code.
+void CExifCreateTest::ExifCreate005L()
+ {
+//* Tag is not allowed to be inserted into the specified IFD,
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = CExifModify::NewL(*jpeg, CExifModify::ECreate);
+ CleanupStack::PushL(modify);
+
+
+ HBufC8* buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ TExifTagInfo tag(KIdImageDescription, CExifTag::ETagAscii, 16);
+ TRAPD(error, modify->SetTagL(EIfdExif, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(20);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdUserComment;
+ tag.iDataType = CExifTag::ETagUndefined;
+ tag.iDataCount = 20;
+ TRAP(error, modify->SetTagL(EIfd1, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 0;
+ tag.iId = KIdExposureProgram;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 1;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ tag.iId = 3;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 2;
+ TRAP(error, modify->SetTagL(EIfdIntOp, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(3);
+ CleanupStack::PushL(buf);
+ tag.iId = 1;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 3;
+ TRAP(error, modify->SetTagL(EIfdExif, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 2;
+ tag.iId = KIdResolutionUnit;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 1;
+ TRAP(error, modify->SetTagL(EIfdGps, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ //* The Exif data size exceeds 64K"
+
+ buf = TUtils::CreateDummyBufL(66000);
+ CleanupStack::PushL(buf);
+ tag.iId = 8;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 66000;
+ TRAP(error, modify->SetTagL(EIfdGps, tag, buf->Des()));
+ if(error != KErrOverflow)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ // Tag ID is invalid,
+ buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ tag.iId = 200;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 19;
+ TRAP(error, modify->SetTagL(EIfdGps, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ //Tag ID doesn't match with the data type, (Full validity)
+ //* Not supported yet!!!
+ buf = TUtils::CreateDummyBufL(20);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdImageDescription;
+ tag.iDataType = CExifTag::ETagByte;
+ tag.iDataCount = 20;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ //*/
+
+ //Data count doesn't match with the given tag data size
+ buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdImageDescription;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 24;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrArgument)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ //Tag data value is not valid (Full validity)
+ // !!! DROPPED !!!
+ /* Not supported yet!!!
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdImageDescription;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 2;
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 200;
+ TRAP(error, modify->SetTagL(EIfdExif, tag, buf->Des()));
+ if(error != KErrArgument)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ */
+
+ // Data length = 0
+ buf = TUtils::CreateDummyBufL(2);
+ buf->Des().SetLength(0);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdImageDescription;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 2;
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 200;
+ TRAP(error, modify->SetTagL(EIfdExif, tag, buf->Des()));
+ if(error != KErrArgument)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+// Exif.Create.06
+// Insert/ Update compressed Exif thumbnail image into the the Exif data.
+// Inserts/ Updates the Exif thumbnail image
+void CExifCreateTest::ExifCreate006L()
+ {
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = CExifModify::NewL(*jpeg, CExifModify::ECreate);
+ CleanupStack::PushL(modify);
+
+ HBufC8* thumbnail = TUtils::ReadFileL(iFs, KValidThumbnail);
+ CleanupStack::PushL(thumbnail);
+ modify->SetThumbnailL(thumbnail->Des());
+ CleanupStack::PopAndDestroy(thumbnail);
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+// Exif.Create.007
+// Try to Insert/ Update compressed Exif thumbnail image with in invalid cases.
+// Leaves with proper error code.
+void CExifCreateTest::ExifCreate007L()
+ {
+ TInt error = 0;
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = 0;
+ //"* Given thumbnail data is not valid compressed Exif thumbnail image, !! Not supported yet !!
+ modify = CExifModify::NewL(*jpeg, CExifModify::ECreate);
+ CleanupStack::PushL(modify);
+
+ HBufC8* buf = TUtils::CreateDummyBufL(8000);
+ CleanupStack::PushL(buf);
+ TRAP( error, modify->SetThumbnailL(buf->Des()) );
+ if ( error != KErrCorrupt )
+ {
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( buf );
+
+
+//* The Exif data size exceeds 64K"
+ TExifTagInfo tag(KIdImageDescription, CExifTag::ETagAscii, 60000);
+ buf = TUtils::CreateDummyBufL(60000);
+ CleanupStack::PushL(buf);
+ modify->SetTagL(EIfd0, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ HBufC8* thumbnail = TUtils::ReadFileL(iFs, KValidThumbnail);
+ CleanupStack::PushL(thumbnail);
+ TRAP( error, modify->SetThumbnailL(thumbnail->Des()) );
+ if ( error != KErrOverflow )
+ {
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(thumbnail);
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+// Exif.Create.008
+// Write the final Exif image to a buffer.
+// Writes the whole Exif image in a buffer, and returns the buffer.
+void CExifCreateTest::ExifCreate008L()
+ {
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = CExifModify::NewL(*jpeg, CExifModify::ECreate);
+ CleanupStack::PushL(modify);
+
+ // Insert Tags
+ HBufC8* buf = 0;
+ TUint16 tmp1 = 0;
+ TUint32 tmp3 = 0;
+ TUint32 tmp4 = 0;
+
+ tmp3 = 72;
+ tmp4 = 1;
+ modify->SetXResolutionL(tmp3, tmp4);
+ modify->SetYResolutionL(tmp3, tmp4);
+ tmp1 = 2;
+ modify->SetResolutionUnitL(tmp1);
+ tmp1 = 1;
+ modify->SetYCbCrPositioningL(tmp1);
+
+ tmp3 = 0x1230;
+ modify->SetComponentsConfigurationL(1, 2, 3, 0);
+ tmp1 = 1;
+ modify->SetColorSpaceL(tmp1);
+ tmp3 = 1024;
+ modify->SetPixelXDimensionL(tmp3);
+ tmp3 = 768;
+ modify->SetPixelYDimensionL(tmp3);
+
+
+ buf = TUtils::CreateDummyBufL(5);
+ CleanupStack::PushL(buf);
+ modify->SetImageDescriptionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+
+ buf = TUtils::CreateDummyBufL(768*2);
+ CleanupStack::PushL(buf);
+ modify->SetTransferFunctionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ modify->SetExposureModeL(0);
+ modify->SetWhiteBalanceL(0);
+ modify->SetSceneCaptureTypeL(0);
+ modify->SetExposureProgramL(0);
+
+ modify->SetLightSourceL(0);
+
+ buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ modify->SetMakerNoteL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ HBufC8* buffer = modify->WriteDataL(jpeg->Des());
+ if(!buffer)
+ User::Leave(KErrGeneral);
+ delete buffer;
+ buffer = 0;
+
+ TPtrC8 tmpDes;
+ buffer = modify->WriteDataL( tmpDes );
+ if(!buffer)
+ User::Leave(KErrGeneral);
+ delete buffer;
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+
+// Exif.Create.009
+// Try to write the final Exif image to a buffer for invalid cases or incorrect original data buffer
+// Leaves with proper error code.
+void CExifCreateTest::ExifCreate009L()
+ {
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = CExifModify::NewL(*jpeg, CExifModify::ECreate);
+ CleanupStack::PushL(modify);
+
+//"* Given buffer content is not the same with the original buffer content
+ TInt error = 0;
+ HBufC8* buf = 0;
+ HBufC8* buffer = 0;
+
+ buf = TUtils::CreateDummyBufL( jpeg->Length() );
+ CleanupStack::PushL( buf );
+ TRAP( error, buffer = modify->WriteDataL( *buf ) );
+
+ if ( ( error != KErrArgument ) || ( buffer ) )
+ {
+ if ( buffer )
+ delete buffer;
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( buf );
+
+//* The Exif data doesn't contain all mandatory tags"
+
+ // Insert Tags
+ TUint16 tmp1 = 0;
+ TUint32 tmp3 = 0;
+ TUint32 tmp4 = 0;
+
+ tmp3 = 72;
+ tmp4 = 1;
+ modify->SetXResolutionL(tmp3, tmp4);
+ tmp1 = 2;
+ modify->SetResolutionUnitL(tmp1);
+
+ tmp3 = 0x1230;
+ modify->SetComponentsConfigurationL(1, 2, 3, 0);
+ tmp1 = 1;
+ modify->SetColorSpaceL(tmp1);
+ tmp3 = 768;
+ modify->SetPixelYDimensionL(tmp3);
+
+
+ buf = TUtils::CreateDummyBufL(5);
+ CleanupStack::PushL(buf);
+ modify->SetImageDescriptionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+
+ buf = TUtils::CreateDummyBufL(768*2);
+ CleanupStack::PushL(buf);
+ modify->SetTransferFunctionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ modify->SetExposureModeL(0);
+ modify->SetWhiteBalanceL(0);
+ modify->SetSceneCaptureTypeL(0);
+ modify->SetExposureProgramL(0);
+
+ modify->SetLightSourceL(0);
+
+ buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ modify->SetMakerNoteL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buffer = 0;
+ TRAP(error, buffer = modify->WriteDataL(jpeg->Des()));
+ if(buffer)
+ {
+ delete buffer;
+ User::Leave(KErrGeneral);
+ }
+ if(error != KErrNotReady)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+// Exif.Create.010
+// Insert/Update specific data using Set functions.
+// Inserts/ Updates the tag data
+void CExifCreateTest::ExifCreate010L()
+ {
+//For each Set function.
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = CExifModify::NewL(*jpeg, CExifModify::ECreate);
+ CleanupStack::PushL(modify);
+
+ // For some Set functions.
+ // Insert Tags
+ HBufC8* buf = 0;
+ TUint16 tmp1 = 0;
+ TUint32 tmp3 = 0;
+ TUint32 tmp4 = 0;
+ TInt32 tmp5 = 0;
+ TInt32 tmp6 = 0;
+
+ buf = TUtils::CreateDummyBufL(10);
+ CleanupStack::PushL(buf);
+ modify->SetUserCommentL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ modify->SetModelL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ tmp1 = 0;
+ modify->SetMeteringModeL(tmp1);
+
+ tmp5 = 1;
+ tmp6 = 1;
+ modify->SetExposureBiasValueL(tmp5, tmp6);
+
+ buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ buf->Des().Copy(_L("2004:01:19 11:00:00"));
+ modify->SetDateTimeOriginalL(buf->Des());
+ modify->SetDateTimeDigitizedL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ tmp5 = 1;
+ tmp6 = 1;
+ modify->SetApertureValueL(tmp5, tmp6);
+
+ buf = TUtils::CreateDummyBufL(12);
+ CleanupStack::PushL(buf);
+ modify->SetImageDescriptionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(12);
+ CleanupStack::PushL(buf);
+ modify->SetMakeL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ modify->SetOrientationL(1);
+ modify->SetExposureModeL(0);
+ modify->SetWhiteBalanceL(0);
+ modify->SetSceneCaptureTypeL(0);
+ modify->SetExposureProgramL(0);
+
+ tmp3 = 72;
+ tmp4 = 1;
+ modify->SetXResolutionL(tmp3, tmp4);
+ modify->SetThumbnailYResolutionL(tmp3, tmp4);
+ modify->SetFileSourceL(1);
+ modify->SetSharpnessL(0);
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+// Exif.Create.011
+// Try to Insert/Update specific data using Set functions in invalid cases.
+// Leaves with or returns proper error code.
+void CExifCreateTest::ExifCreate011L()
+ {
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = CExifModify::NewL(*jpeg, CExifModify::ECreate);
+ CleanupStack::PushL(modify);
+//"* Data size is invalid
+ HBufC8* buf = 0;
+ buf = TUtils::CreateDummyBufL(700);
+ CleanupStack::PushL(buf);
+ TRAPD(error, modify->SetTransferFunctionL(buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+//* Data value is invalid" (Full validity)
+ // !!! DROPPED !!!
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+// Exif.Create.012
+// Test the behavior of the previous test cases after the Exif image is written into a buffer (WriteDataL) called.
+// Leaves with or returns proper error code.
+// CHANGED:
+// This feature is changed. Multiple usage is allowed any more. Test using the modifier after WriteDataL function.
+void CExifCreateTest::ExifCreate012L()
+ {
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = CExifModify::NewL(*jpeg, CExifModify::ECreate);
+ CleanupStack::PushL(modify);
+
+ // Insert Tags
+ TUint16 tmp1 = 0;
+ TUint32 tmp3 = 0;
+ TUint32 tmp4 = 0;
+
+ modify->SetYCbCrPositioningL(2);
+ modify->SetComponentsConfigurationL(1, 2, 3, 0);
+ tmp1 = 1;
+ modify->SetColorSpaceL(tmp1);
+ tmp3 = 480;
+ modify->SetPixelYDimensionL(tmp3);
+
+ tmp3 = 72;
+ tmp4 = 1;
+ modify->SetXResolutionL(tmp3, tmp4);
+ modify->SetYResolutionL(tmp3, tmp4);
+ tmp1 = 2;
+ modify->SetResolutionUnitL(tmp1);
+
+ HBufC8* buffer = NULL;
+ TRAPD( error, buffer = modify->WriteDataL( jpeg->Des() ) );
+ if( (error != KErrNotReady) || (buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ TPtrC8 tmpDes;
+ TRAP( error, buffer = modify->WriteDataL( tmpDes ) );
+ if( (error != KErrNotReady) || (buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ modify->SetPixelXDimensionL(640);
+
+ TRAP( error, buffer = modify->WriteDataL( tmpDes ) );
+ if( (error != KErrNone) || (!buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+ delete buffer;
+ buffer = 0;
+
+ TRAP( error, buffer = modify->WriteDataL( jpeg->Des() ) );
+ if( (error != KErrNone) || (!buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ CleanupStack::PushL(buffer);
+ RFile file;
+ TBuf<255> fileName;
+ fileName.Copy(KRootOut);
+ fileName.Append(_L("out\\"));
+
+ // Create out folder, ignore errors
+ iFs.MkDir(fileName);
+
+ fileName.Append(_L("Create12_01.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootC);
+ fileName.Append(_L("out\\"));
+ // Create out folder, ignore errors
+ iFs.MkDir(fileName);
+ fileName.Append(_L("Create12_01.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootData);
+ fileName.Append(_L("out\\"));
+ // Create out folder, ignore errors
+ iFs.MkDir(fileName);
+ fileName.Append(_L("Create12_01.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+ }
+ }
+ }
+ }
+ }
+
+ file.Write(buffer->Des());
+ file.Close();
+ CleanupStack::PopAndDestroy(buffer);
+ buffer = 0;
+
+ TRAP( error, buffer = modify->WriteDataL( tmpDes ) );
+ if( (error != KErrNone) || (!buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+ delete buffer;
+ buffer = 0;
+
+
+ TRAP( error, buffer = modify->WriteDataL( jpeg->Des() ) );
+ if( (error != KErrNone) || (!buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ CleanupStack::PushL(buffer);
+ fileName.Copy(KRootOut);
+ fileName.Append(_L("out\\"));
+ // Create out folder, ignore errors
+ iFs.MkDir(fileName);
+ fileName.Append(_L("Create12_02.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootC);
+ fileName.Append(_L("out\\"));
+ // Create out folder, ignore errors
+ iFs.MkDir(fileName);
+ fileName.Append(_L("Create12_02.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootData);
+ fileName.Append(_L("out\\"));
+ // Create out folder, ignore errors
+ iFs.MkDir(fileName);
+ fileName.Append(_L("Create12_02.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+ }
+ }
+ }
+ }
+ }
+
+ file.Write(buffer->Des());
+ file.Close();
+ CleanupStack::PopAndDestroy(buffer);
+ buffer = 0;
+
+ modify->DeleteTag(EIfdExif, KIdPixelXDimension);
+
+ TRAP( error, buffer = modify->WriteDataL( jpeg->Des() ) );
+ if( (error != KErrNotReady) || (buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ TRAP( error, buffer = modify->WriteDataL( tmpDes ) );
+ if( (error != KErrNotReady) || (buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+// Exif.Create.MEM.013
+// Test the behavior of the previous test cases in OOM situations.
+// Successfully operates or leaves with OOM error, without any memory leaks.
+void CExifCreateTest::ExifCreate013L()
+ {
+//OOM in EXIF.CREATE.001- EXIF.CREATE.012
+ TInt error = KErrGeneral;
+ TInt i = 0;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate001L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate002L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate003L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate004L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate005L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate006L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate007L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate008L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate009L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate010L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate011L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate012L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/src/ExifCreateTest100.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,1344 @@
+/*
+* Copyright (c) 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: ExifLibTest
+*
+*/
+#include "ExifLibTestInc.h"
+
+
+// Exif.Create.101
+// Instantiate an Exif modifier with valid Jpeg image
+// Created Exif modifier instance in ECreate mode is returned.
+void CExifCreateTest::ExifCreate101L()
+ {
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = CExifModify::NewL(*jpeg, CExifModify::ECreate, CExifModify::ENoJpegParsing);
+ if(!modify)
+ User::Leave(KErrGeneral);
+ delete modify;
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+// Exif.Create.102
+// Try to instantiate an Exif modifier with invalid/ corrupted Jpeg image
+// Leaves with proper error code.
+void CExifCreateTest::ExifCreate102L()
+ {
+ // Various invalid/ corrupted Jpeg images
+
+ // Not baseline Jpeg
+ HBufC8* jpeg = TUtils::ReadFileL( iFs, KInvalidJpeg1 );
+ CleanupStack::PushL( jpeg );
+ CExifModify* modify = 0;
+ TRAPD( error, modify = CExifModify::NewL(*jpeg, CExifModify::ECreate, CExifModify::ENoJpegParsing) );
+ if ( error ) // error detected
+ {
+ if ( ( error != KErrNotSupported ) || ( modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ }
+ delete modify;
+ modify = 0;
+ CleanupStack::PopAndDestroy( jpeg );
+
+ // No SOI
+ jpeg = TUtils::ReadFileL( iFs, KInvalidJpeg2 );
+ CleanupStack::PushL( jpeg );
+ TRAP( error, modify = CExifModify::NewL(*jpeg, CExifModify::ECreate, CExifModify::ENoJpegParsing) );
+ if ( error ) // error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ }
+ delete modify;
+ modify = 0;
+ CleanupStack::PopAndDestroy( jpeg );
+
+ // No EOI
+ jpeg = TUtils::ReadFileL( iFs, KInvalidJpeg3 );
+ CleanupStack::PushL( jpeg );
+ TRAP( error, modify = CExifModify::NewL(*jpeg, CExifModify::ECreate, CExifModify::ENoJpegParsing) );
+ if ( error ) // error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ }
+ delete modify;
+ modify = 0;
+ CleanupStack::PopAndDestroy( jpeg );
+
+ jpeg = TUtils::CreateDummyBufL( 120000 );
+ CleanupStack::PushL( jpeg );
+ HBufC8* jpeg2 = TUtils::ReadFileL( iFs, KValidJpeg );
+ jpeg->Des().Copy( jpeg2->Ptr(), jpeg->Length() / 1000 );
+ jpeg->Des().SetLength(120000);
+ delete jpeg2;
+ jpeg2 = 0;
+ TRAP( error, modify = CExifModify::NewL(*jpeg, CExifModify::ECreate, CExifModify::ENoJpegParsing) );
+ if ( error ) // error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ }
+ delete modify;
+ modify = 0;
+ CleanupStack::PopAndDestroy( jpeg );
+ }
+
+// Exif.Create.103
+// Retrieve reader instance for the related Exif data.
+// Returns unmodifiable reader instance.
+void CExifCreateTest::ExifCreate103L()
+ {
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = CExifModify::NewL(*jpeg, CExifModify::ECreate, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+
+ const CExifRead* reader = modify->Reader();
+ if(!reader)
+ User::Leave(KErrGeneral);
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+// Exif.Create.104
+// Insert/ Update a valid tag into the specified IFD in Exif data.
+// The given tag instance is inserted or updated.
+void CExifCreateTest::ExifCreate104L()
+ {
+//For each IFD.
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = CExifModify::NewL(*jpeg, CExifModify::ECreate, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+
+
+ HBufC8* buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ TExifTagInfo tag(KIdImageDescription, CExifTag::ETagAscii, 16);
+ modify->SetTagL(EIfd0, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(20);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdUserComment;
+ tag.iDataType = CExifTag::ETagUndefined;
+ tag.iDataCount = 20;
+ modify->SetTagL(EIfdExif, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 0;
+ tag.iId = KIdExposureProgram;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 1;
+ modify->SetTagL(EIfdExif, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(1);
+ CleanupStack::PushL(buf);
+ tag.iId = 3;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 1;
+ modify->SetTagL(EIfdGps, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(3);
+ CleanupStack::PushL(buf);
+ tag.iId = 1;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 3;
+ modify->SetTagL(EIfdIntOp, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 2;
+ tag.iId = KIdResolutionUnit;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 1;
+ modify->SetTagL(EIfd1, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+// Exif.Create.105
+// Try to insert/ update an invalid tag into the specified IFD in Exif data.
+// Leaves with proper error code.
+void CExifCreateTest::ExifCreate105L()
+ {
+//* Tag is not allowed to be inserted into the specified IFD,
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = CExifModify::NewL(*jpeg, CExifModify::ECreate, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+
+
+ HBufC8* buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ TExifTagInfo tag(KIdImageDescription, CExifTag::ETagAscii, 16);
+ TRAPD(error, modify->SetTagL(EIfdExif, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(20);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdUserComment;
+ tag.iDataType = CExifTag::ETagUndefined;
+ tag.iDataCount = 20;
+ TRAP(error, modify->SetTagL(EIfd1, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 0;
+ tag.iId = KIdExposureProgram;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 1;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ tag.iId = 3;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 2;
+ TRAP(error, modify->SetTagL(EIfdIntOp, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(3);
+ CleanupStack::PushL(buf);
+ tag.iId = 1;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 3;
+ TRAP(error, modify->SetTagL(EIfdExif, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 2;
+ tag.iId = KIdResolutionUnit;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 1;
+ TRAP(error, modify->SetTagL(EIfdGps, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ //* The Exif data size exceeds 64K"
+
+ buf = TUtils::CreateDummyBufL(66000);
+ CleanupStack::PushL(buf);
+ tag.iId = 8;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 66000;
+ TRAP(error, modify->SetTagL(EIfdGps, tag, buf->Des()));
+ if(error != KErrOverflow)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ // Tag ID is invalid,
+ buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ tag.iId = 200;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 19;
+ TRAP(error, modify->SetTagL(EIfdGps, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ //Tag ID doesn't match with the data type, (Full validity)
+ //* Not supported yet!!!
+ buf = TUtils::CreateDummyBufL(20);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdImageDescription;
+ tag.iDataType = CExifTag::ETagByte;
+ tag.iDataCount = 20;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ //*/
+
+ //Data count doesn't match with the given tag data size
+ buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdImageDescription;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 24;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrArgument)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ //Tag data value is not valid (Full validity)
+ // !!! DROPPED !!!
+ /* Not supported yet!!!
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdImageDescription;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 2;
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 200;
+ TRAP(error, modify->SetTagL(EIfdExif, tag, buf->Des()));
+ if(error != KErrArgument)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ */
+
+ // Data length = 0
+ buf = TUtils::CreateDummyBufL(2);
+ buf->Des().SetLength(0);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdImageDescription;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 2;
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 200;
+ TRAP(error, modify->SetTagL(EIfdExif, tag, buf->Des()));
+ if(error != KErrArgument)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+// Exif.Create.106
+// Insert/ Update compressed Exif thumbnail image into the the Exif data.
+// Inserts/ Updates the Exif thumbnail image
+void CExifCreateTest::ExifCreate106L()
+ {
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = CExifModify::NewL(*jpeg, CExifModify::ECreate, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+
+ HBufC8* thumbnail = TUtils::ReadFileL(iFs, KValidThumbnail);
+ CleanupStack::PushL(thumbnail);
+ modify->SetThumbnailL(thumbnail->Des());
+ CleanupStack::PopAndDestroy(thumbnail);
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+// Exif.Create.107
+// Try to Insert/ Update compressed Exif thumbnail image with in invalid cases.
+// Leaves with proper error code.
+void CExifCreateTest::ExifCreate107L()
+ {
+ TInt error = 0;
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = 0;
+ //"* Given thumbnail data is not valid compressed Exif thumbnail image, !! Not supported yet !!
+ modify = CExifModify::NewL(*jpeg, CExifModify::ECreate, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+
+ HBufC8* buf = TUtils::CreateDummyBufL(8000);
+ CleanupStack::PushL(buf);
+ TRAP( error, modify->SetThumbnailL(buf->Des()) );
+ if ( error != KErrCorrupt )
+ {
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( buf );
+
+
+//* The Exif data size exceeds 64K"
+ TExifTagInfo tag(KIdImageDescription, CExifTag::ETagAscii, 60000);
+ buf = TUtils::CreateDummyBufL(60000);
+ CleanupStack::PushL(buf);
+ modify->SetTagL(EIfd0, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ HBufC8* thumbnail = TUtils::ReadFileL(iFs, KValidThumbnail);
+ CleanupStack::PushL(thumbnail);
+ TRAP( error, modify->SetThumbnailL(thumbnail->Des()) );
+ if ( error != KErrOverflow )
+ {
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(thumbnail);
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+// Exif.Create.108
+// Write the final Exif image to a buffer.
+// Writes the whole Exif image in a buffer, and returns the buffer.
+void CExifCreateTest::ExifCreate108L()
+ {
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = CExifModify::NewL(*jpeg, CExifModify::ECreate, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+
+ // Insert Tags
+ HBufC8* buf = 0;
+ TUint16 tmp1 = 0;
+ TUint32 tmp3 = 0;
+ TUint32 tmp4 = 0;
+
+ tmp3 = 72;
+ tmp4 = 1;
+ modify->SetXResolutionL(tmp3, tmp4);
+ modify->SetYResolutionL(tmp3, tmp4);
+ tmp1 = 2;
+ modify->SetResolutionUnitL(tmp1);
+ tmp1 = 1;
+ modify->SetYCbCrPositioningL(tmp1);
+
+ tmp3 = 0x1230;
+ modify->SetComponentsConfigurationL(1, 2, 3, 0);
+ tmp1 = 1;
+ modify->SetColorSpaceL(tmp1);
+ tmp3 = 1024;
+ modify->SetPixelXDimensionL(tmp3);
+ tmp3 = 768;
+ modify->SetPixelYDimensionL(tmp3);
+
+
+ buf = TUtils::CreateDummyBufL(5);
+ CleanupStack::PushL(buf);
+ modify->SetImageDescriptionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+
+ buf = TUtils::CreateDummyBufL(768*2);
+ CleanupStack::PushL(buf);
+ modify->SetTransferFunctionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ modify->SetExposureModeL(0);
+ modify->SetWhiteBalanceL(0);
+ modify->SetSceneCaptureTypeL(0);
+ modify->SetExposureProgramL(0);
+
+ modify->SetLightSourceL(0);
+
+ buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ modify->SetMakerNoteL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ HBufC8* buffer = modify->WriteDataL(jpeg->Des());
+ if(!buffer)
+ User::Leave(KErrGeneral);
+ delete buffer;
+ buffer = 0;
+
+ TPtrC8 tmpDes;
+ buffer = modify->WriteDataL( tmpDes );
+ if(!buffer)
+ User::Leave(KErrGeneral);
+ delete buffer;
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+
+// Exif.Create.109
+// Try to write the final Exif image to a buffer for invalid cases or incorrect original data buffer
+// Leaves with proper error code.
+void CExifCreateTest::ExifCreate109L()
+ {
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = CExifModify::NewL(*jpeg, CExifModify::ECreate, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+
+//"* Given buffer content is not the same with the original buffer content
+ TInt error = 0;
+ HBufC8* buf = 0;
+ HBufC8* buffer = 0;
+
+ buf = TUtils::CreateDummyBufL( jpeg->Length() );
+ CleanupStack::PushL( buf );
+ TRAP( error, buffer = modify->WriteDataL( *buf ) );
+
+ if ( ( error != KErrArgument ) || ( buffer ) )
+ {
+ if ( buffer )
+ delete buffer;
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( buf );
+
+//* The Exif data doesn't contain all mandatory tags"
+
+ // Insert Tags
+ TUint16 tmp1 = 0;
+ TUint32 tmp3 = 0;
+ TUint32 tmp4 = 0;
+
+ tmp3 = 72;
+ tmp4 = 1;
+ modify->SetXResolutionL(tmp3, tmp4);
+ tmp1 = 2;
+ modify->SetResolutionUnitL(tmp1);
+
+ tmp3 = 0x1230;
+ modify->SetComponentsConfigurationL(1, 2, 3, 0);
+ tmp1 = 1;
+ modify->SetColorSpaceL(tmp1);
+ tmp3 = 768;
+ modify->SetPixelYDimensionL(tmp3);
+
+
+ buf = TUtils::CreateDummyBufL(5);
+ CleanupStack::PushL(buf);
+ modify->SetImageDescriptionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+
+ buf = TUtils::CreateDummyBufL(768*2);
+ CleanupStack::PushL(buf);
+ modify->SetTransferFunctionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ modify->SetExposureModeL(0);
+ modify->SetWhiteBalanceL(0);
+ modify->SetSceneCaptureTypeL(0);
+ modify->SetExposureProgramL(0);
+
+ modify->SetLightSourceL(0);
+
+ buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ modify->SetMakerNoteL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buffer = 0;
+ TRAP(error, buffer = modify->WriteDataL(jpeg->Des()));
+ if(buffer)
+ {
+ delete buffer;
+ User::Leave(KErrGeneral);
+ }
+ if(error != KErrNotReady)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+// Exif.Create.110
+// Insert/Update specific data using Set functions.
+// Inserts/ Updates the tag data
+void CExifCreateTest::ExifCreate110L()
+ {
+//For each Set function.
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = CExifModify::NewL(*jpeg, CExifModify::ECreate, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+
+ // For some Set functions.
+ // Insert Tags
+ HBufC8* buf = 0;
+ TUint16 tmp1 = 0;
+ TUint32 tmp3 = 0;
+ TUint32 tmp4 = 0;
+ TInt32 tmp5 = 0;
+ TInt32 tmp6 = 0;
+
+ buf = TUtils::CreateDummyBufL(10);
+ CleanupStack::PushL(buf);
+ modify->SetUserCommentL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ modify->SetModelL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ tmp1 = 0;
+ modify->SetMeteringModeL(tmp1);
+
+ tmp5 = 1;
+ tmp6 = 1;
+ modify->SetExposureBiasValueL(tmp5, tmp6);
+
+ buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ buf->Des().Copy(_L("2004:01:19 11:00:00"));
+ modify->SetDateTimeOriginalL(buf->Des());
+ modify->SetDateTimeDigitizedL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ tmp5 = 1;
+ tmp6 = 1;
+ modify->SetApertureValueL(tmp5, tmp6);
+
+ buf = TUtils::CreateDummyBufL(12);
+ CleanupStack::PushL(buf);
+ modify->SetImageDescriptionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(12);
+ CleanupStack::PushL(buf);
+ modify->SetMakeL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ modify->SetOrientationL(1);
+ modify->SetExposureModeL(0);
+ modify->SetWhiteBalanceL(0);
+ modify->SetSceneCaptureTypeL(0);
+ modify->SetExposureProgramL(0);
+
+ tmp3 = 72;
+ tmp4 = 1;
+ modify->SetXResolutionL(tmp3, tmp4);
+ modify->SetThumbnailYResolutionL(tmp3, tmp4);
+ modify->SetFileSourceL(1);
+ modify->SetSharpnessL(0);
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+// Exif.Create.111
+// Try to Insert/Update specific data using Set functions in invalid cases.
+// Leaves with or returns proper error code.
+void CExifCreateTest::ExifCreate111L()
+ {
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = CExifModify::NewL(*jpeg, CExifModify::ECreate, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+//"* Data size is invalid
+ HBufC8* buf = 0;
+ buf = TUtils::CreateDummyBufL(700);
+ CleanupStack::PushL(buf);
+ TRAPD(error, modify->SetTransferFunctionL(buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+//* Data value is invalid" (Full validity)
+ // !!! DROPPED !!!
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+// Exif.Create.112
+// Test the behavior of the previous test cases after the Exif image is written into a buffer (WriteDataL) called.
+// Leaves with or returns proper error code.
+// CHANGED:
+// This feature is changed. Multiple usage is allowed any more. Test using the modifier after WriteDataL function.
+void CExifCreateTest::ExifCreate112L()
+ {
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+ CExifModify* modify = CExifModify::NewL(*jpeg, CExifModify::ECreate, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+
+ // Insert Tags
+ TUint16 tmp1 = 0;
+ TUint32 tmp3 = 0;
+ TUint32 tmp4 = 0;
+
+ modify->SetYCbCrPositioningL(2);
+ modify->SetComponentsConfigurationL(1, 2, 3, 0);
+ tmp1 = 1;
+ modify->SetColorSpaceL(tmp1);
+ tmp3 = 480;
+ modify->SetPixelYDimensionL(tmp3);
+
+ tmp3 = 72;
+ tmp4 = 1;
+ modify->SetXResolutionL(tmp3, tmp4);
+ modify->SetYResolutionL(tmp3, tmp4);
+ tmp1 = 2;
+ modify->SetResolutionUnitL(tmp1);
+
+ HBufC8* buffer = NULL;
+ TRAPD( error, buffer = modify->WriteDataL( jpeg->Des() ) );
+ if( (error != KErrNotReady) || (buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ TPtrC8 tmpDes;
+ TRAP( error, buffer = modify->WriteDataL( tmpDes ) );
+ if( (error != KErrNotReady) || (buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ modify->SetPixelXDimensionL(640);
+
+ TRAP( error, buffer = modify->WriteDataL( tmpDes ) );
+ if( (error != KErrNone) || (!buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+ delete buffer;
+ buffer = 0;
+
+ TRAP( error, buffer = modify->WriteDataL( jpeg->Des() ) );
+ if( (error != KErrNone) || (!buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ CleanupStack::PushL(buffer);
+ RFile file;
+ TBuf<255> fileName;
+ fileName.Copy(KRootOut);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Create112_01.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootC);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Create112_01.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootData);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Create112_01.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+ }
+ }
+ }
+ }
+ }
+
+ file.Write(buffer->Des());
+ file.Close();
+ CleanupStack::PopAndDestroy(buffer);
+ buffer = 0;
+
+ TRAP( error, buffer = modify->WriteDataL( tmpDes ) );
+ if( (error != KErrNone) || (!buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+ delete buffer;
+ buffer = 0;
+
+
+ TRAP( error, buffer = modify->WriteDataL( jpeg->Des() ) );
+ if( (error != KErrNone) || (!buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ CleanupStack::PushL(buffer);
+ fileName.Copy(KRootOut);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Create112_02.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootC);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Create112_02.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootData);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Create112_02.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+ }
+ }
+ }
+ }
+ }
+
+ file.Write(buffer->Des());
+ file.Close();
+ CleanupStack::PopAndDestroy(buffer);
+ buffer = 0;
+
+ modify->DeleteTag(EIfdExif, KIdPixelXDimension);
+
+ TRAP( error, buffer = modify->WriteDataL( jpeg->Des() ) );
+ if( (error != KErrNotReady) || (buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ TRAP( error, buffer = modify->WriteDataL( tmpDes ) );
+ if( (error != KErrNotReady) || (buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+// Exif.Create.MEM.013
+// Test the behavior of the previous test cases in OOM situations.
+// Successfully operates or leaves with OOM error, without any memory leaks.
+void CExifCreateTest::ExifCreate113L()
+ {
+//OOM in EXIF.Create.101- EXIF.Create.112
+ TInt error = KErrGeneral;
+ TInt i = 0;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate101L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate102L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate103L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate104L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate105L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate106L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate107L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate108L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate109L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate110L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate111L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifCreate112L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/src/ExifIopTest.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,846 @@
+/*
+* Copyright (c) 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: ExifLibTest
+*
+*/
+#include "ExifLibTestInc.h"
+
+const TInt gpsTagsNo = 3;
+const TUint gpsTags[3][4] = {
+ {5,1,1,0},
+ {27,7,1,0},
+ {28,7,1,0}
+ };
+// Exif.Iop.001
+// Parse the data of various Exif images
+// Writes the Exif data and the thumbnail image of each image into associated files.
+void CExifIopTest::ExifIop001L()
+ {
+//Various Exif images having different versions and content.
+ TFindFile file_finder(iFs);
+ CDir* file_list;
+ TInt error = file_finder.FindWildByDir(_L("Exif*.jpg"), KIopDir, file_list);
+ while (error == KErrNone)
+ {
+ CleanupStack::PushL(file_list);
+ TInt i;
+ for (i=0; i<file_list->Count(); i++)
+ {
+ TParse fullentry;
+ fullentry.Set((*file_list)[i].iName,& file_finder.File(),NULL);
+ ExifIop1L(fullentry.FullName());
+ }
+ CleanupStack::PopAndDestroy(file_list);;
+ error = file_finder.FindWild(file_list);
+ }
+ if(error == KErrNoMemory)
+ {
+ User::Leave(KErrNoMemory);
+ }
+ }
+
+
+// Exif.Iop.002
+// Modify the data of various Exif images.
+// Writes out the modified Exif images into new files.
+void CExifIopTest::ExifIop002L()
+ {
+//Various Exif images having different versions and content.
+ TFindFile file_finder(iFs);
+ CDir* file_list;
+
+ TInt error = file_finder.FindWildByDir(_L("Exif*.jpg"), KIopDir, file_list);
+ while (error == KErrNone)
+ {
+ CleanupStack::PushL(file_list);
+ TInt i;
+ for (i=0; i<file_list->Count(); i++)
+ {
+ TParse fullentry;
+ fullentry.Set((*file_list)[i].iName,& file_finder.File(),NULL);
+ ExifIop2L(fullentry.FullName());
+ }
+ CleanupStack::PopAndDestroy(file_list);;
+ error = file_finder.FindWild(file_list);
+ }
+ if(error == KErrNoMemory)
+ {
+ User::Leave(KErrNoMemory);
+ }
+ }
+
+// Exif.Iop.003
+// Create new Exif images
+// Writes out the new Exif images into new files.
+void CExifIopTest::ExifIop003L()
+ {
+//Various Jpeg images having different content.
+ TFindFile file_finder(iFs);
+ CDir* file_list;
+ HBufC8* buffer2 = TUtils::ReadFileL(iFs, KFullExif);
+ CleanupStack::PushL(buffer2);
+ CExifRead* exifRead = 0;
+ exifRead = CExifRead::NewL(*buffer2);
+ CleanupStack::PushL(exifRead);
+
+ TInt error = file_finder.FindWildByDir(_L("*.jpg"), KIopDir, file_list);
+ while (error == KErrNone)
+ {
+ CleanupStack::PushL(file_list);
+ TInt i;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for (i=0; i<file_list->Count(); i++)
+#else
+ for (i=0; i<76; i++)
+#endif
+ {
+ TParse fullentry;
+ fullentry.Set((*file_list)[i].iName,& file_finder.File(),NULL);
+ ExifIop3L(exifRead, fullentry.FullName());
+ }
+ CleanupStack::PopAndDestroy(file_list);;
+//#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+// error = file_finder.FindWild(file_list);
+//#else
+ error = KErrNotFound;
+//#endif
+ }
+ if(error == KErrNoMemory)
+ {
+ User::Leave(KErrNoMemory);
+ }
+ CleanupStack::PopAndDestroy(exifRead);
+ CleanupStack::PopAndDestroy(buffer2);
+ }
+
+// Exif.Iop.MEM.004
+// Test the behavior of the previous test cases in OOM situations.
+// Successfully operates or leaves with OOM error, without any memory leaks.
+void CExifIopTest::ExifIop004L()
+ {
+ // OOM in EXIF.IOP.001- EXIF.IOP.003
+
+ iWrite = EFalse;
+ TInt error = KErrGeneral;
+ TInt i = 0;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 1500; i+=30)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifIop001L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 1500; i+=30)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifIop002L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 1500; i+=30)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifIop003L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+ }
+
+// Exif.Iop.005
+// Test case for CameraAPI project.
+void CExifIopTest::ExifIop005L()
+ {
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KCameraAPIJpeg);
+ CleanupStack::PushL(jpeg);
+
+ // Create EXIF modifier object.
+ CExifModify* exifModifier = CExifModify::NewL( jpeg->Des(), CExifModify::ECreate );
+
+ CleanupStack::PushL( exifModifier );
+ // Mandatory EXIF tags:
+
+ // EXIF tag: Orientation
+ exifModifier->SetOrientationL( 1 );
+
+ // EXIF tag: YCbCrPositioning
+ exifModifier->SetYCbCrPositioningL( 1 );
+
+ // EXIF tag: XResolution
+ exifModifier->SetXResolutionL( 300, 1 );
+
+ // EXIF tag: YResolution
+ exifModifier->SetYResolutionL( 300, 1 );
+
+ // EXIF tag: ResolutionUnit
+ exifModifier->SetResolutionUnitL( 2 );
+
+ // EXIF tag: ColorSpace
+ exifModifier->SetColorSpaceL( 1 );
+
+ // EXIF tag: ComponentsConfiguration
+ exifModifier->SetComponentsConfigurationL( 1, 2, 3, 0 );
+
+ TSize size(1152, 864);
+
+ // EXIF tag: PixelXDimension
+ exifModifier->SetPixelXDimensionL( size.iWidth );
+
+ // EXIF tag: PixelYDimension
+ exifModifier->SetPixelYDimensionL( size.iHeight );
+
+ // Optional EXIF tags:
+
+ // Get and format home time
+ TBuf8<20> timeStr;
+ TTime time;
+ TDateTime dateTime;
+ time.HomeTime();
+ dateTime=time.DateTime();
+ _LIT8(KFormatTxt,"%4d:%02d:%02d %02d:%02d:%02d\0");
+ timeStr.Format( KFormatTxt,
+ dateTime.Year(),
+ // Day and month ranges begin at zero (0-30 and 0-11),
+ // so add one when formatting
+ TInt(dateTime.Month()+1),
+ dateTime.Day()+1,
+ dateTime.Hour(),
+ dateTime.Minute(),
+ dateTime.Second() );
+
+ // EXIF tag: DateTimeOriginal
+ exifModifier->SetDateTimeOriginalL( timeStr );
+
+ // EXIF tag: DateTimeDigitized
+ exifModifier->SetDateTimeDigitizedL( timeStr );
+
+ // Get pointer to ancillary data
+ TUint8 timeByte1, timeByte2, timeByte3, fpsByte;
+
+ // Read fps value from ancillary data
+ fpsByte = 100;
+
+ // Read exposure time(1) bytes
+ timeByte1 = 1;
+ timeByte2 = 2;
+ timeByte3 = 3;
+
+ // Concatenate exposure time bytes together
+ TUint32 timeHorizPeriods;
+ timeHorizPeriods = ( (timeByte3 & 0x07) << 14 ) |
+ ( (timeByte2 & 0x7F) << 7 ) |
+ (timeByte1 & 0x7F);
+
+ TInt horizPeriodsInSec;
+ if ( fpsByte & 0x01 )
+ {
+ // 15 fps
+ horizPeriodsInSec = 15;
+ }
+ else
+ {
+ // 7.5 fps
+ horizPeriodsInSec = 15/2;
+ }
+
+ // Exposure time = 1/2 periods (=never happens?)
+ if ( !timeHorizPeriods )
+ {
+ timeHorizPeriods = 1;
+ horizPeriodsInSec *= 2;
+ }
+
+ // EXIF tag: ExposureTime
+ exifModifier->SetExposureTimeL( timeHorizPeriods, horizPeriodsInSec );
+
+ // Scene capture type can be normal or night
+ exifModifier->SetSceneCaptureTypeL( 0 );
+
+ // EXIF tag: Make
+ exifModifier->SetMakeL( _L8("NOKIA") );
+ exifModifier->SetModelL( _L8("66xx") );
+
+ // Setting FNumber does not have custom method in EXIF lib -> must use SetTagL()
+ TExifTagInfo fNumberTag( 0x829d , CExifTag::ETagRational, 1 ); // Tag id = 0x829d, data type = Rational, Data count = 1
+ TBuf8<8> tagValue;
+ tagValue.SetLength(8);
+ *reinterpret_cast<TUint32*>(const_cast<TUint8*>(tagValue.Ptr())) = 28;
+ *reinterpret_cast<TUint32*>(const_cast<TUint8*>(tagValue.Ptr()+4)) = 10;
+
+ // EXIF tag: FNumber
+ exifModifier->SetTagL( EIfdExif, fNumberTag, tagValue ); // The tag goes into the Exif IFD.
+
+ // Setting FocalLength does not have custom method in EXIF lib -> must use SetTagL()
+ TExifTagInfo focalLengthTag( 0x920a, CExifTag::ETagRational, 1 ); // Tag id = 0x920a, data type = Rational, Data count = 1
+ *reinterpret_cast<TUint32*>(const_cast<TUint8*>(tagValue.Ptr())) = 37;
+ *reinterpret_cast<TUint32*>(const_cast<TUint8*>(tagValue.Ptr()+4)) = 10;
+
+ // EXIF tag: FocalLength
+ exifModifier->SetTagL( EIfdExif, focalLengthTag, tagValue ); // The tag goes into the Exif IFD.
+
+ // EXIF tag: ExposureMode
+ exifModifier->SetExposureModeL( 0 ); // auto
+
+ // EXIF tag: WhiteBalance
+ exifModifier->SetWhiteBalanceL( 0 ); // auto
+
+ TExifTagInfo tag( 1, CExifTag::ETagAscii, 3 );
+ exifModifier->SetTagL( EIfdIntOp, tag, _L8("R98") );
+ tag.iDataCount = 4;
+ tag.iDataType = CExifTag::ETagUndefined;
+ tag.iId = 2;
+ TBuf8<4> buf;
+ buf.Copy( _L8("0100") );
+ exifModifier->SetTagL( EIfdIntOp, tag, buf );
+
+ HBufC8* thumbnail = TUtils::ReadFileL(iFs, KValidThumbnail);
+ CleanupStack::PushL(thumbnail);
+ exifModifier->SetThumbnailL(thumbnail->Des());
+ CleanupStack::PopAndDestroy(thumbnail);
+ exifModifier->SetThumbnailResolutionUnitL( 2 );
+ exifModifier->SetThumbnailXResolutionL( 72, 1 );
+ exifModifier->SetThumbnailYResolutionL( 72, 1 );
+
+
+ TReal tmp = 1;
+
+ TReal isoSpeedRating = 1600;
+
+ // Round isoSpeedRating to one of the values listed in
+ // ISO 12232:1998
+ const TUint16 isoSpeedRatingsLut[35] = { 4, 5, 6, 8, 10, 12, 16, 20, 25, 32, 40, 50, 64, 80,
+ 100, 125, 160, 200, 250, 320, 400, 500, 640, 800,
+ 1000, 1250, 1600, 2000, 2500, 3200, 4000, 5000, 6400, 8000,
+ 10000 };
+
+ if ( isoSpeedRating > 10000 )
+ {
+ isoSpeedRating = 10000;
+ }
+ else
+ {
+ TInt i=1;
+ while ( isoSpeedRatingsLut[i] < isoSpeedRating )
+ {
+ i++;
+ }
+ isoSpeedRating = isoSpeedRatingsLut[i-1];
+ }
+
+ // Put the iso speed rating value in a descriptor
+ TBuf8<2> isoSpeedDes;
+ isoSpeedDes.SetLength(2);
+ *reinterpret_cast<TUint16*>(const_cast<TUint8*>(isoSpeedDes.Ptr())) = static_cast<TUint16>(isoSpeedRating);
+
+ // EXIF tag: IsoSpeedRatings
+ exifModifier->SetIsoSpeedRatingsL( isoSpeedDes );
+
+ // Setting ShutterSpeedValue does not have custom method in EXIF lib -> must use SetTagL()
+ TExifTagInfo shutterSpeedValueTag( 0x9201, CExifTag::ETagSrational, 1 ); // Tag id = 0x9201, data type = Rational, Data count = 1
+
+ // Log( exposure time )
+ *reinterpret_cast<TInt32*>(const_cast<TUint8*>(tagValue.Ptr())) = static_cast<TInt32>(-1*tmp/0.00030103);// =-1*tmp/(log(2)/1000)
+ *reinterpret_cast<TInt32*>(const_cast<TUint8*>(tagValue.Ptr()+4)) = static_cast<TInt32>(1000);
+
+ // EXIF tag: ShutterSpeedValue
+ exifModifier->SetTagL( EIfdExif, shutterSpeedValueTag, tagValue ); // The tag goes into the Exif IFD.
+
+ // EXIF tag: ApertureValue
+ exifModifier->SetApertureValueL( 30, 10 );
+
+ // EXIF tag: DigitalZoomRatio
+ exifModifier->SetDigitalZoomRatioL( 100, 100 );
+
+ // Setting GainControl does not have custom method in EXIF lib -> must use SetTagL()
+ TExifTagInfo gainControlTag( 0xa407, CExifTag::ETagShort, 1 ); // Tag id = 0xa407, data type = Short, Data count = 1
+
+ // Put the gain control value in a descriptor
+ TBuf8<2> gainControlDes;
+ gainControlDes.SetLength(2);
+ TReal analogGain = 3;
+ if ( analogGain < -0.1 )
+ {
+ *reinterpret_cast<TUint16*>(const_cast<TUint8*>(gainControlDes.Ptr())) = static_cast<TUint16>( 3 ); // low gain down
+ }
+ else if ( analogGain >= -0.1 && analogGain < 0.1 )
+ {
+ *reinterpret_cast<TUint16*>(const_cast<TUint8*>(gainControlDes.Ptr())) = static_cast<TUint16>( 0 ); // none
+ }
+ else if ( analogGain >= 0.1 && analogGain < 6.0 )
+ {
+ *reinterpret_cast<TUint16*>(const_cast<TUint8*>(gainControlDes.Ptr())) = static_cast<TUint16>( 1 ); // low gain up
+ }
+ else // analogGain => 6.0
+ {
+ *reinterpret_cast<TUint16*>(const_cast<TUint8*>(gainControlDes.Ptr())) = static_cast<TUint16>( 2 ); // high gain up
+ }
+
+ // EXIF tag: GainControl
+ exifModifier->SetTagL( EIfdExif, gainControlTag, gainControlDes ); // The tag goes into the Exif IFD.
+
+ // EXIF tag: LightSource
+ exifModifier->SetLightSourceL( 0 ); // unknown
+
+ HBufC8* exif = exifModifier->WriteDataL(jpeg->Des());
+ CleanupStack::PushL(exif);
+
+ RFile file;
+ TBuf<255> fileName;
+
+ fileName.Copy(KRootOut);
+ fileName.Append(_L("out\\"));
+ // Create out folder, ignore errors
+ iFs.MkDir(fileName);
+ fileName.Append(_L("CameraApi.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootC);
+ fileName.Append(_L("out\\"));
+ // Create out folder, ignore errors
+ iFs.MkDir(fileName);
+ fileName.Append(_L("CameraApi.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootData);
+ fileName.Append(_L("out\\"));
+ // Create out folder, ignore errors
+ iFs.MkDir(fileName);
+ fileName.Append(_L("CameraApi.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+ }
+ }
+ }
+ }
+ }
+
+
+ file.Write(exif->Des());
+ file.Close();
+ CleanupStack::PopAndDestroy(exif);
+ CleanupStack::PopAndDestroy(exifModifier);
+ CleanupStack::PopAndDestroy(jpeg);
+ }
+
+void CExifIopTest::ExifIop1L(const TDesC& aFileName)
+ {
+ RDebug::Print(aFileName);
+ //RDebug::Print(_L("Read File..."));
+ HBufC8* buffer = TUtils::ReadFileL(iFs,aFileName);
+ CleanupStack::PushL(buffer);
+
+ //RDebug::Print(_L("Create reader.."));
+ CExifRead* exifRead = 0;
+ exifRead = CExifRead::NewL(*buffer);
+ CleanupStack::PushL(exifRead);
+
+ //RDebug::Print(_L("Get ifds.."));
+ TInt noIfds = 0;
+ TExifIfdType* ifds = exifRead->GetIfdTypesL(noIfds);
+ CleanupStack::PushL(ifds);
+ if((!ifds) || (!noIfds))
+ return;
+
+ //RDebug::Print(_L("Create file.."));
+ RFile file;
+ TBuf<255> fileName;
+ TInt flen = KIopDir.iTypeLength; // folder length
+ if(iWrite)
+ {
+ fileName.Copy(aFileName);
+ fileName.Insert(flen,_L("out\\"));
+ // Create out folder, ignore errors
+ iFs.MkDir(fileName);
+ fileName.Append(_L(".txt"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+ }
+
+ for(TInt i=0; i<noIfds; ++i)
+ {
+ if(iWrite)
+ {
+ User::LeaveIfError(file.Write(_L8("______________________________________________\n")));
+ switch(ifds[i])
+ {
+ case EIfd0:
+ User::LeaveIfError(file.Write(_L8("Ifd 0:\n\n")));
+ break;
+ case EIfdExif:
+ User::LeaveIfError(file.Write(_L8("Ifd Exif:\n\n")));
+ break;
+ case EIfd1:
+ User::LeaveIfError(file.Write(_L8("Ifd 1:\n\n")));
+ break;
+ case EIfdGps:
+ User::LeaveIfError(file.Write(_L8("Ifd GPS:\n\n")));
+ break;
+ case EIfdIntOp:
+ User::LeaveIfError(file.Write(_L8("Ifd IOP:\n\n")));
+ }
+ }
+
+ TInt noTags = 0;
+
+ //RDebug::Print(_L("Retrieve tag ids..."));
+ TUint16* tags = exifRead->GetTagIdsL(ifds[i], noTags);
+ //RDebug::Print(_L("Retrieved tag ids."));
+ CleanupStack::PushL(tags);
+ if((!tags) || (!noTags))
+ continue;
+
+ //RDebug::Print(_L("Write tags..."));
+ for(TInt j=0; j<noTags; ++j)
+ {
+ TBuf8<48> tagHeader;
+ tagHeader.Insert(0, _L8("Inf: "));
+ TBuf8<8> num;
+ TInt id = (exifRead->GetTagL(ifds[i], tags[j]))->TagInfo().iId;
+ num.Num(id, EHex);
+ tagHeader.Append(num);
+ tagHeader.Append(_L("\t"));
+ num.Num((exifRead->GetTagL(ifds[i], tags[j]))->TagInfo().iDataType);
+ tagHeader.Append(num);
+ tagHeader.Append(_L("\t"));
+ num.Num(static_cast<TUint16>( (exifRead->GetTagL(ifds[i], tags[j]))->TagInfo().iDataCount));
+ tagHeader.Append(num);
+ tagHeader.Append(_L("\t"));
+ if(iWrite)
+ {
+ User::LeaveIfError(file.Write(tagHeader));
+ User::LeaveIfError(file.Write((exifRead->GetTagL(ifds[i], tags[j]))->Data()));
+ User::LeaveIfError(file.Write(_L8("\n")));
+ }
+ }
+ CleanupStack::PopAndDestroy(tags);
+ }
+ if(iWrite)
+ file.Close();
+
+ //Thumbnail
+ TInt error;
+ HBufC8* thumbnail = 0;
+ //RDebug::Print(_L("Retrieve thumnail..."));
+ TRAP(error, thumbnail = exifRead->GetThumbnailL());
+ CleanupStack::PushL(thumbnail);
+ if(!error)
+ {
+ //RDebug::Print(_L("Thumbnail retrieved"));
+ fileName.Copy(aFileName);
+ fileName.Insert(flen,_L("out\\"));
+ // Create out folder, ignore errors
+ iFs.MkDir(fileName);
+ fileName.Append(_L(".thm.jpg"));
+ //RDebug::Print(_L("Open file..."));
+ if(iWrite)
+ {
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+ }
+ //RDebug::Print(_L("File opened"));
+ if(iWrite)
+ file.Write(thumbnail->Des());
+ //RDebug::Print(_L("File written."));
+ if(iWrite)
+ file.Close();
+ }
+ CleanupStack::PopAndDestroy(thumbnail);
+ CleanupStack::PopAndDestroy(ifds);
+ CleanupStack::PopAndDestroy(exifRead);
+ CleanupStack::PopAndDestroy(buffer);
+ }
+
+void CExifIopTest::ExifIop2L(const TDesC& aFileName)
+ {
+ RDebug::Print(aFileName);
+ HBufC8* buffer = TUtils::ReadFileL(iFs, aFileName);
+ CleanupStack::PushL(buffer);
+
+ CExifModify* exifModify = 0;
+ exifModify = CExifModify::NewL(*buffer, CExifModify::EModify);
+ CleanupStack::PushL(exifModify);
+
+ HBufC8* buf = 0;
+ TUint16 tmp1 = 0;
+ TUint32 tmp2 = 0;
+ TUint32 tmp3 = 0;
+ TInt error = 0;
+
+ buf = TUtils::CreateDummyBufL(5);
+ CleanupStack::PushL(buf);
+ exifModify->SetImageDescriptionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ error = exifModify->Reader()->GetXResolution(tmp2,tmp3);
+ exifModify->SetXResolutionL(tmp2,tmp3);
+ error = exifModify->Reader()->GetYResolution(tmp2,tmp3);
+ exifModify->SetYResolutionL(tmp2,tmp3);
+ error = exifModify->Reader()->GetResolutionUnit(tmp1);
+ exifModify->SetResolutionUnitL(tmp1);
+
+
+ buf = TUtils::CreateDummyBufL(768*2);
+ CleanupStack::PushL(buf);
+ exifModify->SetTransferFunctionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+
+ HBufC8* buffer2 = exifModify->WriteDataL(*buffer);
+ CleanupStack::PushL(buffer2);
+
+ if(iWrite)
+ {
+ RFile file;
+ TBuf<255> fileName;
+ TInt flen = KIopDir.iTypeLength; // folder length
+ fileName.Copy(aFileName);
+ fileName.Insert(flen,_L("out\\"));
+ // Create out folder, ignore errors
+ iFs.MkDir(fileName);
+ fileName.Append(_L(".cpy.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+
+ User::LeaveIfError(file.Write(*buffer2, buffer2->Length()));
+ file.Close();
+ }
+ CleanupStack::PopAndDestroy(buffer2);
+ CleanupStack::PopAndDestroy();
+ CleanupStack::PopAndDestroy(buffer);
+ }
+
+void CExifIopTest::ExifIop3L(CExifRead* aExifRead, const TDesC& aFileName)
+ {
+ RDebug::Print(aFileName);
+ CExifRead* exifRead = aExifRead;
+ HBufC8* buffer = TUtils::ReadFileL(iFs, aFileName);
+ CleanupStack::PushL(buffer);
+
+ CExifModify* exifModify = 0;
+ exifModify = CExifModify::NewL(*buffer, CExifModify::ECreate);
+ CleanupStack::PushL(exifModify);
+
+ // Insert Tags
+ HBufC8* tmp = 0;
+ HBufC8* buf = 0;
+ TUint16 tmp1 = 0;
+ TUint32 tmp3 = 1;
+ TUint32 tmp4 = 2;
+
+ buf = TUtils::CreateDummyBufL(5);
+ CleanupStack::PushL(buf);
+ exifModify->SetImageDescriptionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+
+ buf = TUtils::CreateDummyBufL(768*2);
+ CleanupStack::PushL(buf);
+ exifModify->SetTransferFunctionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ tmp = exifRead->GetDateTimeL();
+ CleanupStack::PushL(tmp);
+ exifModify->SetDateTimeL(tmp->Des());
+ CleanupStack::PopAndDestroy(tmp);
+
+ User::LeaveIfError(exifRead->GetYCbCrPositioning(tmp1));
+ exifModify->SetYCbCrPositioningL(tmp1);
+
+ buf = TUtils::CreateDummyBufL(5);
+ CleanupStack::PushL(buf);
+ exifModify->SetSoftwareL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(5);
+ CleanupStack::PushL(buf);
+ exifModify->SetCopyrightL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ exifModify->SetExposureTimeL(tmp3, tmp4);
+
+ User::LeaveIfError(exifRead->GetXResolution(tmp3, tmp4));
+ exifModify->SetXResolutionL(tmp3, tmp4);
+ User::LeaveIfError(exifRead->GetYResolution(tmp3, tmp4));
+ exifModify->SetYResolutionL(tmp3, tmp4);
+ User::LeaveIfError(exifRead->GetResolutionUnit(tmp1));
+ exifModify->SetResolutionUnitL(tmp1);
+
+ User::LeaveIfError(exifRead->GetPixelXDimension(tmp3));
+ exifModify->SetPixelXDimensionL(tmp3);
+ User::LeaveIfError(exifRead->GetPixelYDimension(tmp3));
+ exifModify->SetPixelYDimensionL(tmp3);
+
+ exifModify->SetComponentsConfigurationL(1, 2, 3, 0);
+ User::LeaveIfError(exifRead->GetFlash(tmp1));
+ exifModify->SetFlashL(tmp1);
+ User::LeaveIfError(exifRead->GetColorSpace(tmp1));
+ exifModify->SetColorSpaceL(tmp1);
+
+ exifModify->SetExposureModeL(0);
+ exifModify->SetWhiteBalanceL(0);
+ exifModify->SetSceneCaptureTypeL(0);
+ exifModify->SetExposureProgramL(0);
+
+ buf = TUtils::CreateDummyBufL(6);
+ CleanupStack::PushL(buf);
+ exifModify->SetIsoSpeedRatingsL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ exifModify->SetLightSourceL(0);
+
+ buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ exifModify->SetMakerNoteL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(12);
+ CleanupStack::PushL(buf);
+ exifModify->SetRelatedSoundFileL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ InsertGpsTagsL(exifModify);
+
+ exifModify->SetDigitalZoomRatioL(0,1);
+ exifModify->SetContrastL(0);
+ exifModify->SetSaturationL(0);
+ exifModify->SetSharpnessL(0);
+
+ buf = exifRead->GetThumbnailL();
+ CleanupStack::PushL(buf);
+ exifModify->SetThumbnailL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ User::LeaveIfError(exifRead->GetThumbnailResolutionUnit(tmp1));
+ exifModify->SetThumbnailResolutionUnitL(tmp1);
+ User::LeaveIfError(exifRead->GetThumbnailXResolution(tmp3, tmp4));
+ exifModify->SetThumbnailXResolutionL(tmp3, tmp4);
+ User::LeaveIfError(exifRead->GetThumbnailYResolution(tmp3, tmp4));
+ exifModify->SetThumbnailYResolutionL(tmp3, tmp4);
+
+
+ HBufC8* buffer3 = exifModify->WriteDataL(*buffer);
+ CleanupStack::PushL(buffer3);
+
+ if(iWrite)
+ {
+ RFile file;
+ TBuf<255> fileName;
+ TInt flen = KIopDir.iTypeLength; // folder length
+ fileName.Copy(aFileName);
+ fileName.Insert(flen,_L("out\\"));
+ // Create out folder, ignore errors
+ iFs.MkDir(fileName);
+ fileName.Append(_L(".new.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+
+ User::LeaveIfError(file.Write(*buffer3, buffer3->Length()));
+ file.Close();
+ }
+
+ CleanupStack::PopAndDestroy(buffer3);
+ CleanupStack::PopAndDestroy();
+ CleanupStack::PopAndDestroy(buffer);
+ }
+
+void CExifIopTest::InsertGpsTagsL(CExifModify* aModify)
+ {
+ for(TInt i = 0; i< gpsTagsNo; i++)
+ {
+ HBufC8* buf = HBufC8::NewL(1);
+ CleanupStack::PushL(buf);
+ buf->Des().SetLength(1);
+ *((TUint8*)buf + 4) = gpsTags[i][3];
+ TExifTagInfo tag(gpsTags[i][0], (CExifTag::TExifTagDataType)gpsTags[i][1], gpsTags[i][2]);
+ aModify->SetTagL(EIfdGps, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ }
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/src/ExifLibTest.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,81 @@
+/*
+* Copyright (c) 2003, 2004 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: Exif Library Test DLL
+*
+*/
+
+
+
+// INCLUDE FILES
+
+
+#include "ExifLibTest.h"
+
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+IMPORT_C MTest* CreateTopFct ();
+
+// FORWARD DECLARATIONS
+
+
+// Starting point of the DLL (Always needed)
+GLDEF_C TInt E32Dll(TDllReason)
+ {
+ return(KErrNone);
+ }
+
+// Exactly one exported function returning the suite of
+// test functions for the test runner in the framework.
+// (Always needed)
+//
+EXPORT_C MTest* CreateTopFct() //lint !e714
+ {
+ MTest * testSuite = NULL;
+ TRAPD(err, testSuite = CExifLibTest::suiteL() ) ;
+ if (err)
+ {
+ User::Panic(_L("suiteL has left !"), 99);
+ }
+ return ( testSuite );
+ }
+
+
+CExifLibTest::~CExifLibTest()
+ {
+ }
+
+
+MTest* CExifLibTest::suiteL ()
+ {
+ CTestSuite *suite = CTestSuite::NewL(_L8("Test Suite Container"));
+
+ suite->addTestL(CExifLibTestInc::suiteL());
+
+ return suite;
+
+ }
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/src/ExifLibTestInc.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,262 @@
+/*
+* Copyright (c) 2003, 2004 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: Exif Library Test DLL
+*
+*/
+
+
+#ifdef __WINSCW__
+#define KWinscwChar
+#else
+#define KWinscwChar &
+#endif
+// INCLUDE FILES
+#include "ExifLibTestInc.h"
+#include <fbs.h>
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+// #define MMC
+
+// MACROS
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+
+#else
+
+#endif
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+
+CExifLibTestInc::CExifLibTestInc()
+ {
+ }
+
+
+
+CExifLibTestInc::~CExifLibTestInc()
+ {
+ }
+
+
+void CExifLibTestInc::setUpL ()
+ {
+ }
+
+
+void CExifLibTestInc::tearDown ()
+ {
+ }
+
+//
+// Own test functions.
+//
+
+MTest* CExifLibTestInc::suiteL ()
+ {
+ // Always use NewL (Do not use NewLC) !!!
+ CTestSuite *suite = CTestSuite::NewL(_L8("ExifLibTest"));
+
+ suite->addTestL(CTestCaller<CExifTagTest>::NewL(_L8("EXIF.TAG.001"), KWinscwChar(CExifTagTest::ExifTag001L)));
+
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.001"), KWinscwChar(CExifReadTest::ExifRead001L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.002"), KWinscwChar(CExifReadTest::ExifRead002L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.003"), KWinscwChar(CExifReadTest::ExifRead003L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.004"), KWinscwChar(CExifReadTest::ExifRead004L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.005"), KWinscwChar(CExifReadTest::ExifRead005L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.006"), KWinscwChar(CExifReadTest::ExifRead006L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.007"), KWinscwChar(CExifReadTest::ExifRead007L)));
+
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.008"), KWinscwChar(CExifReadTest::ExifRead008L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.009"), KWinscwChar(CExifReadTest::ExifRead009L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.010"), KWinscwChar(CExifReadTest::ExifRead010L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.011"), KWinscwChar(CExifReadTest::ExifRead011L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.012"), KWinscwChar(CExifReadTest::ExifRead012L)));
+
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.013"), KWinscwChar(CExifReadTest::ExifRead013L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.014"), KWinscwChar(CExifReadTest::ExifRead014L)));
+
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.016"), KWinscwChar(CExifReadTest::ExifRead016L)));
+
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.001"), KWinscwChar(CExifCreateTest::ExifCreate001L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.002"), KWinscwChar(CExifCreateTest::ExifCreate002L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.003"), KWinscwChar(CExifCreateTest::ExifCreate003L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.004"), KWinscwChar(CExifCreateTest::ExifCreate004L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.005"), KWinscwChar(CExifCreateTest::ExifCreate005L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.006"), KWinscwChar(CExifCreateTest::ExifCreate006L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.007"), KWinscwChar(CExifCreateTest::ExifCreate007L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.008"), KWinscwChar(CExifCreateTest::ExifCreate008L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.009"), KWinscwChar(CExifCreateTest::ExifCreate009L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.010"), KWinscwChar(CExifCreateTest::ExifCreate010L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.011"), KWinscwChar(CExifCreateTest::ExifCreate011L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.012"), KWinscwChar(CExifCreateTest::ExifCreate012L)));
+
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.001"), KWinscwChar(CExifModifyTest::ExifModify001L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.002"), KWinscwChar(CExifModifyTest::ExifModify002L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.003"), KWinscwChar(CExifModifyTest::ExifModify003L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.004"), KWinscwChar(CExifModifyTest::ExifModify004L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.005"), KWinscwChar(CExifModifyTest::ExifModify005L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.006"), KWinscwChar(CExifModifyTest::ExifModify006L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.007"), KWinscwChar(CExifModifyTest::ExifModify007L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.008"), KWinscwChar(CExifModifyTest::ExifModify008L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.009"), KWinscwChar(CExifModifyTest::ExifModify009L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.010"), KWinscwChar(CExifModifyTest::ExifModify010L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.011"), KWinscwChar(CExifModifyTest::ExifModify011L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.012"), KWinscwChar(CExifModifyTest::ExifModify012L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.013"), KWinscwChar(CExifModifyTest::ExifModify013L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.014"), KWinscwChar(CExifModifyTest::ExifModify014L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.015"), KWinscwChar(CExifModifyTest::ExifModify015L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.016"), KWinscwChar(CExifModifyTest::ExifModify016L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.018"), KWinscwChar(CExifModifyTest::ExifModify018L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.019"), KWinscwChar(CExifModifyTest::ExifModify019L)));
+
+ suite->addTestL(CTestCaller<CExifModifyTest2>::NewL(_L8("EXIF.MODIFY2.001"), KWinscwChar(CExifModifyTest2::ExifModify001L)));
+ suite->addTestL(CTestCaller<CExifModifyTest2>::NewL(_L8("EXIF.MODIFY2.002"), KWinscwChar(CExifModifyTest2::ExifModify002L)));
+ suite->addTestL(CTestCaller<CExifModifyTest2>::NewL(_L8("EXIF.MODIFY2.003"), KWinscwChar(CExifModifyTest2::ExifModify003L)));
+ suite->addTestL(CTestCaller<CExifModifyTest2>::NewL(_L8("EXIF.MODIFY2.004"), KWinscwChar(CExifModifyTest2::ExifModify004L)));
+ suite->addTestL(CTestCaller<CExifModifyTest2>::NewL(_L8("EXIF.MODIFY2.005"), KWinscwChar(CExifModifyTest2::ExifModify005L)));
+ suite->addTestL(CTestCaller<CExifModifyTest2>::NewL(_L8("EXIF.MODIFY2.006"), KWinscwChar(CExifModifyTest2::ExifModify006L)));
+ suite->addTestL(CTestCaller<CExifModifyTest2>::NewL(_L8("EXIF.MODIFY2.007"), KWinscwChar(CExifModifyTest2::ExifModify007L)));
+ suite->addTestL(CTestCaller<CExifModifyTest2>::NewL(_L8("EXIF.MODIFY2.008"), KWinscwChar(CExifModifyTest2::ExifModify008L)));
+ suite->addTestL(CTestCaller<CExifModifyTest2>::NewL(_L8("EXIF.MODIFY2.009"), KWinscwChar(CExifModifyTest2::ExifModify009L)));
+ suite->addTestL(CTestCaller<CExifModifyTest2>::NewL(_L8("EXIF.MODIFY2.010"), KWinscwChar(CExifModifyTest2::ExifModify010L)));
+ suite->addTestL(CTestCaller<CExifModifyTest2>::NewL(_L8("EXIF.MODIFY2.011"), KWinscwChar(CExifModifyTest2::ExifModify011L)));
+ suite->addTestL(CTestCaller<CExifModifyTest2>::NewL(_L8("EXIF.MODIFY2.012"), KWinscwChar(CExifModifyTest2::ExifModify012L)));
+ suite->addTestL(CTestCaller<CExifModifyTest2>::NewL(_L8("EXIF.MODIFY2.013"), KWinscwChar(CExifModifyTest2::ExifModify013L)));
+ suite->addTestL(CTestCaller<CExifModifyTest2>::NewL(_L8("EXIF.MODIFY2.014"), KWinscwChar(CExifModifyTest2::ExifModify014L)));
+ suite->addTestL(CTestCaller<CExifModifyTest2>::NewL(_L8("EXIF.MODIFY2.015"), KWinscwChar(CExifModifyTest2::ExifModify015L)));
+ suite->addTestL(CTestCaller<CExifModifyTest2>::NewL(_L8("EXIF.MODIFY2.016"), KWinscwChar(CExifModifyTest2::ExifModify016L)));
+ suite->addTestL(CTestCaller<CExifModifyTest2>::NewL(_L8("EXIF.MODIFY2.018"), KWinscwChar(CExifModifyTest2::ExifModify018L)));
+ suite->addTestL(CTestCaller<CExifModifyTest2>::NewL(_L8("EXIF.MODIFY2.019"), KWinscwChar(CExifModifyTest2::ExifModify019L)));
+
+ // Fast parser test cases
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.101"), KWinscwChar(CExifReadTest::ExifRead101L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.102"), KWinscwChar(CExifReadTest::ExifRead102L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.103"), KWinscwChar(CExifReadTest::ExifRead103L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.104"), KWinscwChar(CExifReadTest::ExifRead104L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.105"), KWinscwChar(CExifReadTest::ExifRead105L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.106"), KWinscwChar(CExifReadTest::ExifRead106L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.107"), KWinscwChar(CExifReadTest::ExifRead107L)));
+
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.108"), KWinscwChar(CExifReadTest::ExifRead108L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.109"), KWinscwChar(CExifReadTest::ExifRead109L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.110"), KWinscwChar(CExifReadTest::ExifRead110L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.111"), KWinscwChar(CExifReadTest::ExifRead111L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.112"), KWinscwChar(CExifReadTest::ExifRead112L)));
+
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.113"), KWinscwChar(CExifReadTest::ExifRead113L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.114"), KWinscwChar(CExifReadTest::ExifRead114L)));
+
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.116"), KWinscwChar(CExifReadTest::ExifRead116L)));
+
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.101"), KWinscwChar(CExifCreateTest::ExifCreate101L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.102"), KWinscwChar(CExifCreateTest::ExifCreate102L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.103"), KWinscwChar(CExifCreateTest::ExifCreate103L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.104"), KWinscwChar(CExifCreateTest::ExifCreate104L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.105"), KWinscwChar(CExifCreateTest::ExifCreate105L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.106"), KWinscwChar(CExifCreateTest::ExifCreate106L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.107"), KWinscwChar(CExifCreateTest::ExifCreate107L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.108"), KWinscwChar(CExifCreateTest::ExifCreate108L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.109"), KWinscwChar(CExifCreateTest::ExifCreate109L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.110"), KWinscwChar(CExifCreateTest::ExifCreate110L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.111"), KWinscwChar(CExifCreateTest::ExifCreate111L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.112"), KWinscwChar(CExifCreateTest::ExifCreate112L)));
+
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.101"), KWinscwChar(CExifModifyTest::ExifModify101L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.102"), KWinscwChar(CExifModifyTest::ExifModify102L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.103"), KWinscwChar(CExifModifyTest::ExifModify103L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.104"), KWinscwChar(CExifModifyTest::ExifModify104L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.105"), KWinscwChar(CExifModifyTest::ExifModify105L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.106"), KWinscwChar(CExifModifyTest::ExifModify106L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.107"), KWinscwChar(CExifModifyTest::ExifModify107L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.108"), KWinscwChar(CExifModifyTest::ExifModify108L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.109"), KWinscwChar(CExifModifyTest::ExifModify109L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.110"), KWinscwChar(CExifModifyTest::ExifModify110L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.111"), KWinscwChar(CExifModifyTest::ExifModify111L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.112"), KWinscwChar(CExifModifyTest::ExifModify112L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.113"), KWinscwChar(CExifModifyTest::ExifModify113L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.114"), KWinscwChar(CExifModifyTest::ExifModify114L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.115"), KWinscwChar(CExifModifyTest::ExifModify115L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.116"), KWinscwChar(CExifModifyTest::ExifModify116L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.118"), KWinscwChar(CExifModifyTest::ExifModify118L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.119"), KWinscwChar(CExifModifyTest::ExifModify119L)));
+
+ // No tag validity check test cases
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.201"), KWinscwChar(CExifReadTest::ExifRead201L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.202"), KWinscwChar(CExifReadTest::ExifRead202L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.203"), KWinscwChar(CExifReadTest::ExifRead203L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.204"), KWinscwChar(CExifReadTest::ExifRead204L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.205"), KWinscwChar(CExifReadTest::ExifRead205L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.206"), KWinscwChar(CExifReadTest::ExifRead206L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.207"), KWinscwChar(CExifReadTest::ExifRead207L)));
+
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.208"), KWinscwChar(CExifReadTest::ExifRead208L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.209"), KWinscwChar(CExifReadTest::ExifRead209L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.210"), KWinscwChar(CExifReadTest::ExifRead210L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.211"), KWinscwChar(CExifReadTest::ExifRead211L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.212"), KWinscwChar(CExifReadTest::ExifRead212L)));
+
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.213"), KWinscwChar(CExifReadTest::ExifRead213L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.214"), KWinscwChar(CExifReadTest::ExifRead214L)));
+
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.216"), KWinscwChar(CExifReadTest::ExifRead216L)));
+
+ // IOP test
+
+ suite->addTestL(CTestCaller<CExifIopTest>::NewL(_L8("EXIF.IOP.001"), KWinscwChar(CExifIopTest::ExifIop001L)));
+ suite->addTestL(CTestCaller<CExifIopTest>::NewL(_L8("EXIF.IOP.002"), KWinscwChar(CExifIopTest::ExifIop002L)));
+
+ suite->addTestL(CTestCaller<CExifIopTest>::NewL(_L8("EXIF.IOP.003"), KWinscwChar(CExifIopTest::ExifIop003L)));
+
+ // CameraAPI test case
+ suite->addTestL(CTestCaller<CExifIopTest>::NewL(_L8("EXIF.IOP.005"), KWinscwChar(CExifIopTest::ExifIop005L)));
+
+ // OOM tests
+//#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.MEM.015"), KWinscwChar(CExifReadTest::ExifRead015L)));
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.MEM.115"), KWinscwChar(CExifReadTest::ExifRead115L)));
+ suite->addTestL(CTestCaller<CExifTagTest>::NewL(_L8("EXIF.TAG.MEM.002"), KWinscwChar(CExifTagTest::ExifTag002L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.MEM.013"), KWinscwChar(CExifCreateTest::ExifCreate013L)));
+ suite->addTestL(CTestCaller<CExifCreateTest>::NewL(_L8("EXIF.CREATE.MEM.113"), KWinscwChar(CExifCreateTest::ExifCreate113L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.MEM.017"), KWinscwChar(CExifModifyTest::ExifModify017L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.MEM.117"), KWinscwChar(CExifModifyTest::ExifModify117L)));
+ suite->addTestL(CTestCaller<CExifModifyTest2>::NewL(_L8("EXIF.MODIFY2.MEM.017"), KWinscwChar(CExifModifyTest2::ExifModify017L)));
+ suite->addTestL(CTestCaller<CExifIopTest>::NewL(_L8("EXIF.IOP.MEM.004"), KWinscwChar(CExifIopTest::ExifIop004L)));
+
+//#endif
+ // Fast parser test cases
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.FAST.017"), KWinscwChar(CExifReadTest::ExifRead017L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.FAST.020"), KWinscwChar(CExifModifyTest::ExifModify020L)));
+
+ // Unknown tags test cases
+ // Modify image that has unknown (vendor specific) tags and write it back. This needs manual verification
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.UNKNOWN.021"), KWinscwChar(CExifModifyTest::ExifModify021L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.UNKNOWN.022"), KWinscwChar(CExifModifyTest::ExifModify022L)));
+ suite->addTestL(CTestCaller<CExifModifyTest>::NewL(_L8("EXIF.MODIFY.UNKNOWN.023"), KWinscwChar(CExifModifyTest::ExifModify023L)));
+
+ // No tag validity checking test cases
+ suite->addTestL(CTestCaller<CExifReadTest>::NewL(_L8("EXIF.READ.NOTAGCHECKING.018"), KWinscwChar(CExifReadTest::ExifRead018L)));
+
+ return suite;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/src/ExifLibTestStif.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,242 @@
+/*
+* Copyright (c) 2003-2006 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: Exif Library Test DLL
+*
+*/
+
+
+
+// INCLUDE FILES
+
+
+#include "ExifLibTestStif.h"
+
+// ================= MEMBER FUNCTIONS =========================================
+
+
+CTestModule::CTestModule()
+ {
+ }
+
+
+void CTestModule::ConstructL()
+ {
+ iTestSuite = CTestSuite::NewL( _L8( "ExifLibTest" ) );
+
+ iTestSuite->addTestL( CExifLibTestInc::suiteL() );
+
+ /* Install an active scheduler */
+ iScheduler = new(ELeave)CActiveScheduler;
+ CActiveScheduler::Install(iScheduler);
+
+ }
+
+
+CTestModule* CTestModule::NewL()
+ {
+
+ // Construct new CTestModule instance.
+ CTestModule* self = new ( ELeave ) CTestModule();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+
+ return self;
+
+ }
+
+
+CTestModule::~CTestModule()
+ {
+ delete iTestSuite;
+ delete iScheduler;
+ }
+
+
+EXPORT_C TInt SetRequirements( CTestModuleParam*& aTestModuleParam,
+ TUint32& aParameterValid )
+ {
+
+ /* --------------------------------- NOTE ---------------------------------
+ USER PANICS occurs in test thread creation when:
+ 1) "The panic occurs when the value of the stack size is negative."
+ 2) "The panic occurs if the minimum heap size specified is less
+ than KMinHeapSize".
+ KMinHeapSize: "Functions that require a new heap to be allocated will
+ either panic, or will reset the required heap size to this value if
+ a smaller heap size is specified".
+ 3) "The panic occurs if the minimum heap size specified is greater than
+ the maximum size to which the heap can grow".
+ Other:
+ 1) Make sure that your hardware or Symbian OS is supporting given sizes.
+ e.g. Hardware might support only sizes that are divisible by four.
+ ------------------------------- NOTE end ------------------------------- */
+
+ // Normally STIF uses default heap and stack sizes for test thread, see:
+ // KTestThreadMinHeap, KTestThreadMinHeap and KStackSize.
+ // If needed heap and stack sizes can be configured here by user. Remove
+ // comments and define sizes.
+
+
+ aParameterValid = KStifTestModuleParameterChanged;
+
+ CTestModuleParamVer01* param = CTestModuleParamVer01::NewL();
+ // Stack size
+ param->iTestThreadStackSize= 2*16384; // 2*16K stack
+ // Heap sizes
+ param->iTestThreadMinHeap = 4096; // 4K heap min
+ param->iTestThreadMaxHeap = 8*1048576;// 8M heap max
+
+ aTestModuleParam = param;
+
+ return KErrNone;
+
+ }
+
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModule
+
+ Method: GetTestCases
+
+ Description: GetTestCases is used to inquire test cases
+ from the test module. Because this test module have hard coded test cases
+ (i.e cases are not read from file), paramter aConfigFile is not used.
+
+ This function loops through all cases defined in Cases() function and
+ adds corresponding items to aTestCases array.
+
+ Parameters: const TFileName& : in: Configuration file name. Not used
+ RPointerArray<TTestCaseInfo>& aTestCases: out:
+ Array of TestCases.
+
+ Return Values: KErrNone: No error
+
+ Errors/Exceptions: Function leaves if any memory allocation operation fails
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestModule::GetTestCasesL( const TFileName& /*aConfigFile*/,
+ RPointerArray<TTestCaseInfo>& aTestCases )
+ {
+
+ // Loop through all test cases and create new
+ // TTestCaseInfo items and append items to aTestCase array
+ for( TInt i = 0; i< iTestSuite->CountTestCases(); i++ )
+ {
+
+ // Allocate new TTestCaseInfo from heap for a testcase definition.
+ TTestCaseInfo* newCase = new( ELeave ) TTestCaseInfo();
+
+ // PushL TTestCaseInfo to CleanupStack.
+ CleanupStack::PushL( newCase );
+
+ // Set number for the testcase.
+ // When the testcase is run, this comes as a parameter to RunTestCaseL.
+ newCase->iCaseNumber = i;
+
+ // Set title for the test case. This is shown in UI to user.
+ newCase->iTitle.Copy( iTestSuite->TestCaseName(i) );
+
+ // Append TTestCaseInfo to the testcase array. After appended
+ // successfully the TTestCaseInfo object is owned (and freed)
+ // by the TestServer.
+ User::LeaveIfError(aTestCases.Append ( newCase ) );
+
+ // Pop TTestCaseInfo from the CleanupStack.
+ CleanupStack::Pop( newCase );
+
+ }
+
+ return KErrNone;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModule
+
+ Method: RunTestCase
+
+ Description: Run a specified testcase.
+
+ Function runs a test case specified by test case number. Test case file
+ parameter is not used.
+
+ If case number is valid, this function runs a test case returned by
+ function Cases().
+
+ Parameters: const TInt aCaseNumber: in: Testcase number
+ const TFileName& : in: Configuration file name. Not used
+ TTestResult& aResult: out: Testcase result
+
+ Return Values: KErrNone: Testcase ran.
+ KErrNotFound: Unknown testcase
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestModule::RunTestCaseL( const TInt aCaseNumber,
+ const TFileName& /*aConfig*/,
+ TTestResult& aResult )
+ {
+
+ // Return value
+ TInt execStatus = KErrNone;
+ iTestSuite->ExecuteTestL(aResult, aCaseNumber);
+
+ // Return case execution status (not the result of the case execution)
+ return execStatus;
+
+ }
+
+
+// ================= OTHER EXPORTED FUNCTIONS =================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Function: LibEntryL
+
+ Description: Polymorphic Dll Entry Point
+
+ Test framework calls this function to obtain new instance of test module
+ class.
+
+ Parameters: None
+
+ Return Values: CTestModule* Pointer to CTestModule instance
+
+ Errors/Exceptions: Leaves if CTestModule::NewL leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+EXPORT_C CTestModule* LibEntryL()
+ {
+ return CTestModule::NewL();
+
+ }
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/src/ExifModifyTest.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,2418 @@
+/*
+* Copyright (c) 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: ExifLibTest
+*
+*/
+#include "ExifLibTestInc.h"
+
+
+// Exif.Modify.001
+// Instantiate an Exif modifier with valid Exif image
+// Modified Exif modifier instance in EModify mode is returned.
+void CExifModifyTest::ExifModify001L()
+ {
+
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify);
+ if(!modify)
+ User::Leave(KErrGeneral);
+ delete modify;
+ CleanupStack::PopAndDestroy(exif);
+
+ /*
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify);
+ if(!modify)
+ User::Leave(KErrGeneral);
+ modify->SetCustomRenderedL(0);
+ HBufC8* b = modify->WriteDataL(*exif);
+ RFile file;
+ User::LeaveIfError(file.Open(iFs, _L("C:\\FullExif.jpg"), EFileWrite));
+
+ file.Write(b->Des());
+ file.Close();
+ delete b;
+*/
+ }
+
+// Exif.Modify.002
+// Try to instantiate an Exif modifier with invalid/ corrupted Exif image
+// Leaves with proper error code.
+void CExifModifyTest::ExifModify002L()
+ {
+ // Various invalid/ corrupted Exif images
+ HBufC8* exif = TUtils::ReadFileL(iFs, KInvalidExif1);
+ if ( !exif )
+ {
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PushL(exif);
+ CExifModify* modify = 0;
+ TRAPD( error, modify = CExifModify::NewL(*exif, CExifModify::EModify) );
+ if ( ( error != KErrCorrupt ) || ( modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif2);
+ CleanupStack::PushL(exif);
+ TRAP( error, modify = CExifModify::NewL(*exif, CExifModify::EModify) );
+ if ( ( error != KErrCorrupt ) || ( modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif3);
+ CleanupStack::PushL(exif);
+ TRAP( error, modify = CExifModify::NewL(*exif, CExifModify::EModify) );
+ if ( ( error != KErrCorrupt ) || ( modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif4);
+ CleanupStack::PushL(exif);
+ TRAP( error, modify = CExifModify::NewL(*exif, CExifModify::EModify) );
+ if ( ( error != KErrCorrupt ) || ( modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif5);
+ CleanupStack::PushL(exif);
+ TRAP( error, modify = CExifModify::NewL(*exif, CExifModify::EModify) );
+ if ( ( error != KErrCorrupt ) || ( modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif6);
+ CleanupStack::PushL(exif);
+ TRAP( error, modify = CExifModify::NewL(*exif, CExifModify::EModify) );
+ if ( ( error != KErrCorrupt ) || ( modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ /* Supported, but uncompressed thumbnail is skipped */
+ exif = TUtils::ReadFileL(iFs, KNotSupportedExif1);
+ CleanupStack::PushL(exif);
+ TRAP( error, modify = CExifModify::NewL(*exif, CExifModify::EModify) );
+ if ( ( error != KErrNone ) || ( !modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ delete modify;
+ modify = NULL;
+ CleanupStack::PopAndDestroy(exif);
+
+ /* Supported, but unsupported (uncompressed) thumbnail is skipped */
+ exif = TUtils::ReadFileL(iFs, KNotSupportedExif2);
+ CleanupStack::PushL(exif);
+ TRAP( error, modify = CExifModify::NewL(*exif, CExifModify::EModify) );
+ if ( ( error != KErrCorrupt ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ delete modify;
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.003
+// Retrieve reader instance for the related Exif data.
+// Returns unmodifiable reader instance.
+void CExifModifyTest::ExifModify003L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify);
+ CleanupStack::PushL(modify);
+
+ const CExifRead* reader = modify->Reader();
+ if(!reader)
+ User::Leave(KErrGeneral);
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.004
+// Insert/ Update a valid tag into the specified IFD in Exif data.
+// The given tag instance is inserted or updated.
+void CExifModifyTest::ExifModify004L()
+ {
+// For each IFD.
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify);
+ CleanupStack::PushL(modify);
+
+
+ HBufC8* buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ TExifTagInfo tag(KIdImageDescription, CExifTag::ETagAscii, 16);
+ modify->SetTagL(EIfd0, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(20);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdUserComment;
+ tag.iDataType = CExifTag::ETagUndefined;
+ tag.iDataCount = 20;
+ modify->SetTagL(EIfdExif, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 0;
+ tag.iId = KIdExposureProgram;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 1;
+ modify->SetTagL(EIfdExif, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(1);
+ CleanupStack::PushL(buf);
+ tag.iId = 3;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 1;
+ modify->SetTagL(EIfdGps, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(3);
+ CleanupStack::PushL(buf);
+ tag.iId = 1;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 3;
+ modify->SetTagL(EIfdIntOp, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 2;
+ tag.iId = KIdResolutionUnit;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 1;
+ modify->SetTagL(EIfd1, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.005
+// Try to insert/ update a valid tag into the specified IFD in Exif data.
+// Leaves with proper error code.
+void CExifModifyTest::ExifModify005L()
+ {
+//* Tag is not allowed to be inserted into the specified IFD,
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify);
+ CleanupStack::PushL(modify);
+
+
+ HBufC8* buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ TExifTagInfo tag(KIdImageDescription, CExifTag::ETagAscii, 16);
+ TRAPD(error, modify->SetTagL(EIfdExif, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(20);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdUserComment;
+ tag.iDataType = CExifTag::ETagUndefined;
+ tag.iDataCount = 20;
+ TRAP(error, modify->SetTagL(EIfd1, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 0;
+ tag.iId = KIdExposureProgram;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 1;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ tag.iId = 3;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 2;
+ TRAP(error, modify->SetTagL(EIfdIntOp, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(3);
+ CleanupStack::PushL(buf);
+ tag.iId = 1;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 3;
+ TRAP(error, modify->SetTagL(EIfdExif, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 2;
+ tag.iId = KIdResolutionUnit;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 1;
+ TRAP(error, modify->SetTagL(EIfdGps, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ //* The Exif data size exceeds 64K"
+ buf = TUtils::CreateDummyBufL(65000);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdImageDescription;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 65000;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrOverflow)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ // Tag ID is invalid,
+ buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ tag.iId = 200;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 19;
+ TRAP(error, modify->SetTagL(EIfdGps, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ //Tag ID doesn't match with the data type, (Full validity)
+ //* Not supported yet!!!
+ buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdImageDescription;
+ tag.iDataType = CExifTag::ETagByte;
+ tag.iDataCount = 19;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ //*/
+
+ //Data count doesn't match with the given tag data size
+ buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdImageDescription;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 24;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrArgument)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ //Tag data value is not valid (Full validity)
+ // !! DROPPED
+ /* Not supported yet!!!
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdImageDescription;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 2;
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 200;
+ TRAP(error, modify->SetTagL(EIfdExif, tag, buf->Des()));
+ if(error != KErrArgument)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ */
+
+ // Tag cannot be modified
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdExifIfdPointer;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdGpsIfdPointer;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdIntOpIfdPointer;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdJpegInterchangeFormat;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdJpegInterchangeFormatLength;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdExifVersion;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdGpsVersion;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdFlashPixVersion;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdCompression;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.06
+// Remove a tag from the specified IFD in Exif data.
+// Removes the tag from the specified IFD.
+void CExifModifyTest::ExifModify006L()
+ {
+ // For each IFD.
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify);
+ CleanupStack::PushL(modify);
+
+ User::LeaveIfError(modify->DeleteTag(EIfd0, KIdXResolution));
+
+ User::LeaveIfError(modify->DeleteTag(EIfdExif, KIdExposureProgram));
+
+ User::LeaveIfError(modify->DeleteTag(EIfd1, KIdResolutionUnit));
+
+ User::LeaveIfError(modify->DeleteTag(EIfdGps, 27));
+
+ User::LeaveIfError(modify->DeleteTag(EIfdIntOp, 1));
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.07
+// Try to remove a tag from the specified IFD in Exif data.
+// Returns proper error code.
+void CExifModifyTest::ExifModify007L()
+ {
+ //"For each IFD;
+//* IFD exists but tag doesn't exist,
+//* IFD doesn't exist"
+
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify);
+ CleanupStack::PushL(modify);
+ TInt error = modify->DeleteTag(EIfd0, 0x013f);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+ error = modify->DeleteTag(EIfdExif, KIdMakerNote);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+ error = modify->DeleteTag(EIfd1, KIdCompression);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+ error = modify->DeleteTag(EIfdIntOp, 4);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+ error = modify->DeleteTag(EIfdGps, 27);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+//* Invalid tag ID
+ error = modify->DeleteTag(EIfdExif, 0x0205);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+//* Tag cannot be removed!
+ error = modify->DeleteTag(EIfdExif, KIdGpsIfdPointer);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ error = modify->DeleteTag(EIfdExif, KIdFlashPixVersion);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ error = modify->DeleteTag(EIfdExif, KIdExifIfdPointer);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ error = modify->DeleteTag(EIfdExif, KIdIntOpIfdPointer);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ error = modify->DeleteTag(EIfdExif, KIdJpegInterchangeFormat);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ error = modify->DeleteTag(EIfdExif, KIdGpsVersion);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ error = modify->DeleteTag(EIfdExif, KIdJpegInterchangeFormatLength);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ error = modify->DeleteTag(EIfdExif, KIdExifVersion);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.08
+// Remove an IFD from the Exif data.
+// Removes the IFD from the Exif data.
+void CExifModifyTest::ExifModify008L()
+ {
+ // For each IFD.
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify);
+ CleanupStack::PushL(modify);
+
+ // Not allowed to delete Ifd0 and ExifIfd
+ // User::LeaveIfError(modify->DeleteIfd(EIfd0));
+ // User::LeaveIfError(modify->DeleteIfd(EIfdExif));
+ User::LeaveIfError(modify->DeleteIfd(EIfd1));
+ User::LeaveIfError(modify->DeleteIfd(EIfdGps));
+ User::LeaveIfError(modify->DeleteIfd(EIfdIntOp));
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.09
+// Try to remove an IFD from the Exif data, which doesn't contain that IFD.
+// Returns proper error code.
+void CExifModifyTest::ExifModify009L()
+ {
+ // For each IFD.
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify);
+ CleanupStack::PushL(modify);
+ TInt error = modify->DeleteIfd(EIfdGps);
+
+ if(error != KErrNotFound)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+ error = modify->DeleteIfd(EIfd0);
+ if(error != KErrArgument)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+ // IFD cannot be removed
+ error = modify->DeleteIfd(EIfd0);
+ if( error != KErrArgument)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+ error = modify->DeleteIfd(EIfdExif);
+ if( error != KErrArgument)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.010
+// Insert/ Update compressed Exif thumbnail image into the the Exif data.
+// Inserts/ Updates the Exif thumbnail image
+void CExifModifyTest::ExifModify010L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KNoThumbnail);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify);
+ CleanupStack::PushL(modify);
+
+ HBufC8* thumbnail = TUtils::ReadFileL(iFs, KValidThumbnail);
+ CleanupStack::PushL(thumbnail);
+ modify->SetThumbnailL(thumbnail->Des());
+ CleanupStack::PopAndDestroy(thumbnail);
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.011
+// Try to Insert/ Update compressed Exif thumbnail image with in invalid cases.
+// Leaves with proper error code.
+void CExifModifyTest::ExifModify011L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify);
+ CleanupStack::PushL(modify);
+
+//"* Given thumbnail data is not valid compressed Exif thumbnail image, !! Not supported yet !!
+ HBufC8* buf = TUtils::CreateDummyBufL(8000);
+ CleanupStack::PushL(buf);
+ TRAPD( error, modify->SetThumbnailL(buf->Des()) );
+ if ( error != KErrCorrupt )
+ {
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( buf );
+
+//* The Exif data size exceeds 64K"
+ TExifTagInfo tag(KIdImageDescription, CExifTag::ETagAscii, 52000);
+ buf = TUtils::CreateDummyBufL(52000);
+ CleanupStack::PushL(buf);
+ modify->SetTagL(EIfd0, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ HBufC8* thumbnail = TUtils::ReadFileL(iFs, KValidThumbnail);
+ CleanupStack::PushL(thumbnail);
+ TRAP( error, modify->SetThumbnailL(thumbnail->Des()) );
+ if ( error != KErrOverflow )
+ {
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(thumbnail);
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.012
+// Remove compressed Exif thumbnail image from the Exif data.
+// Removes the thumbnail image.
+void CExifModifyTest::ExifModify012L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify);
+ CleanupStack::PushL(modify);
+
+ User::LeaveIfError(modify->RemoveThumbnail());
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.013
+// Try to remove compressed Exif thumbnail image from the Exif data.
+// Returns proper error code.
+void CExifModifyTest::ExifModify013L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KNoThumbnail);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify);
+ CleanupStack::PushL(modify);
+ TInt error = modify->RemoveThumbnail();
+
+ if(error != KErrNotFound)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.014
+// Write the final Exif image to a buffer.
+// Writes the whole Exif image in a buffer, and returns the buffer.
+void CExifModifyTest::ExifModify014L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify);
+ CleanupStack::PushL(modify);
+
+ // Insert Tags
+ HBufC8* buf = 0;
+ TUint16 tmp1 = 0;
+ TUint32 tmp3 = 0;
+ TUint32 tmp4 = 0;
+ TInt32 tmp5 = 0;
+ TInt32 tmp6 = 0;
+
+ buf = TUtils::CreateDummyBufL(10);
+ CleanupStack::PushL(buf);
+ modify->SetUserCommentL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ modify->SetModelL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ tmp1 = 0;
+ modify->SetMeteringModeL(tmp1);
+
+ tmp5 = 1;
+ tmp6 = 1;
+ modify->SetExposureBiasValueL(tmp5, tmp6);
+
+ tmp5 = 0;
+ tmp6 = 1;
+ modify->SetShutterSpeedValueL(tmp5, tmp6);
+
+ modify->SetBrightnessValueL(tmp5, tmp6);
+
+ modify->SetCustomRenderedL(0);
+
+ modify->SetGainControlL(0);
+
+ buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ buf->Des().Copy(_L("2004:01:19 11:00:00"));
+ modify->SetDateTimeOriginalL(buf->Des());
+ modify->SetDateTimeDigitizedL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ tmp5 = 1;
+ tmp6 = 1;
+ modify->SetApertureValueL(tmp5, tmp6);
+
+ tmp3 = 72;
+ tmp4 = 1;
+ modify->SetXResolutionL(tmp3, tmp4);
+ modify->SetYResolutionL(tmp3, tmp4);
+ tmp1 = 2;
+ modify->SetResolutionUnitL(tmp1);
+ tmp1 = 1;
+ modify->SetYCbCrPositioningL(tmp1);
+
+ modify->SetComponentsConfigurationL(1, 2, 3, 0);
+ tmp1 = 1;
+ modify->SetColorSpaceL(tmp1);
+ tmp3 = 1024;
+ modify->SetPixelXDimensionL(tmp3);
+ tmp3 = 768;
+ modify->SetPixelYDimensionL(tmp3);
+
+
+ buf = TUtils::CreateDummyBufL(5);
+ CleanupStack::PushL(buf);
+ modify->SetImageDescriptionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+
+ buf = TUtils::CreateDummyBufL(768*2);
+ CleanupStack::PushL(buf);
+ modify->SetTransferFunctionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ modify->SetExposureModeL(0);
+ modify->SetWhiteBalanceL(0);
+ modify->SetSceneCaptureTypeL(0);
+ modify->SetExposureProgramL(0);
+
+ modify->SetLightSourceL(0);
+
+ buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ modify->SetMakerNoteL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ HBufC8* buffer = modify->WriteDataL(exif->Des());
+ if(!buffer)
+ User::Leave(KErrGeneral);
+ delete buffer;
+ buffer = 0;
+
+ TPtrC8 tmpDes;
+ buffer = modify->WriteDataL( tmpDes );
+ if(!buffer)
+ User::Leave(KErrGeneral);
+ delete buffer;
+
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Modify.015
+// Try to write the final Exif image to a buffer for invalid cases or incorrect original data buffer
+// Leaves with proper error code.
+void CExifModifyTest::ExifModify015L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify);
+ CleanupStack::PushL(modify);
+
+//"* Given buffer content is not the same with the original buffer content.
+ TInt error = 0;
+ HBufC8* buf = 0;
+ HBufC8* buffer = 0;
+
+ buf = TUtils::CreateDummyBufL( exif->Length() );
+ CleanupStack::PushL( buf );
+ TRAP( error, buffer = modify->WriteDataL( *buf ) );
+ if ( ( error != KErrArgument ) || ( buffer ) )
+ {
+ if ( buffer )
+ delete buffer;
+ buffer = 0;
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( buf );
+
+ buf = TUtils::CreateDummyBufL( exif->Length() - 5 );
+ CleanupStack::PushL( buf );
+ TRAP( error, buffer = modify->WriteDataL( *buf ) );
+ if ( ( error != KErrArgument ) || ( buffer ) )
+ {
+ if ( buffer )
+ delete buffer;
+ buffer = 0;
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( buf );
+
+ buf = TUtils::CreateDummyBufL( exif->Length() );
+ CleanupStack::PushL( buf );
+ buf->Des().Copy( exif->Ptr(), exif->Length() / 2 - 10 );
+ buf->Des().SetLength( exif->Length() );
+ TRAP( error, buffer = modify->WriteDataL( *buf ) );
+ if ( ( error != KErrArgument ) || ( buffer ) )
+ {
+ if ( buffer )
+ delete buffer;
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( buf );
+
+ buf = TUtils::CreateDummyBufL( exif->Length() );
+ CleanupStack::PushL( buf );
+ buf->Des().Copy( exif->Ptr(), exif->Length() / 2 + 10 );
+ buf->Des().SetLength( exif->Length() );
+ TRAP( error, buffer = modify->WriteDataL( *buf ) );
+ if ( ( error != KErrArgument ) || ( buffer ) )
+ {
+ if ( buffer )
+ delete buffer;
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( buf );
+
+//* The Exif data doesn't contain all mandatory tags"
+
+ // Insert Tags
+ TUint16 tmp1 = 0;
+ TUint32 tmp3 = 0;
+ TUint32 tmp4 = 0;
+
+ tmp3 = 72;
+ tmp4 = 1;
+ modify->SetXResolutionL(tmp3, tmp4);
+ tmp1 = 2;
+ modify->SetResolutionUnitL(tmp1);
+
+ modify->SetComponentsConfigurationL(1, 2, 3, 0);
+ tmp1 = 1;
+ modify->SetColorSpaceL(tmp1);
+ tmp3 = 768;
+ modify->SetPixelYDimensionL(tmp3);
+ modify->DeleteTag(EIfdExif, KIdPixelXDimension);
+
+
+ buf = TUtils::CreateDummyBufL(5);
+ CleanupStack::PushL(buf);
+ modify->SetImageDescriptionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+
+ buf = TUtils::CreateDummyBufL(768*2);
+ CleanupStack::PushL(buf);
+ modify->SetTransferFunctionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ modify->SetExposureModeL(0);
+ modify->SetWhiteBalanceL(0);
+ modify->SetSceneCaptureTypeL(0);
+ modify->SetExposureProgramL(0);
+
+ modify->SetLightSourceL(0);
+
+ buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ modify->SetMakerNoteL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buffer = 0;
+ TRAP(error, buffer = modify->WriteDataL(exif->Des()));
+ if(buffer)
+ {
+ delete buffer;
+ User::Leave(KErrGeneral);
+ }
+ if(error != KErrNotReady)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+
+ buffer = 0;
+ TPtrC8 tmpDes;
+ TRAP(error, buffer = modify->WriteDataL( tmpDes ));
+ if(buffer)
+ {
+ delete buffer;
+ User::Leave(KErrGeneral);
+ }
+ if(error != KErrNotReady)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.016
+// Test the behavior of the previous test cases after the Exif image is written into a buffer (WriteDataL) called.
+// Leaves with or returns proper error code.
+// CHANGED:
+// This feature is changed. Multiple usage is allowed any more. Test using the modifier after WriteDataL function.
+void CExifModifyTest::ExifModify016L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify);
+ CleanupStack::PushL(modify);
+
+ // Insert Tags
+ TUint16 tmp1 = 0;
+ TUint32 tmp3 = 0;
+ TUint32 tmp4 = 0;
+
+ tmp3 = 72;
+ tmp4 = 1;
+ modify->SetXResolutionL(tmp3, tmp4);
+ tmp1 = 2;
+ modify->SetResolutionUnitL(tmp1);
+
+ modify->SetComponentsConfigurationL(1, 2, 3, 0);
+ tmp1 = 1;
+ modify->SetColorSpaceL(tmp1);
+ tmp3 = 768;
+ modify->SetPixelYDimensionL(tmp3);
+ modify->DeleteTag(EIfdExif, KIdPixelXDimension);
+
+ HBufC8* buffer = NULL;
+ TRAPD( error, buffer = modify->WriteDataL( exif->Des() ) );
+ if( (error != KErrNotReady) || (buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ TPtrC8 tmpDes;
+
+ TRAP( error, buffer = modify->WriteDataL( tmpDes ) );
+ if( (error != KErrNotReady) || (buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ modify->SetPixelXDimensionL(1024);
+
+ TRAP( error, buffer = modify->WriteDataL( tmpDes ) );
+ if( (error != KErrNone) || (!buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+ delete buffer;
+ buffer = 0;
+
+ TRAP( error, buffer = modify->WriteDataL( exif->Des() ) );
+ if( (error != KErrNone) || (!buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ CleanupStack::PushL(buffer);
+ RFile file;
+ TBuf<255> fileName;
+ fileName.Copy(KRootOut);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Modify16_01.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootC);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Modify16_01.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootData);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Modify16_01.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+ }
+ }
+ }
+ }
+ }
+
+ file.Write(buffer->Des());
+ file.Close();
+ CleanupStack::PopAndDestroy(buffer);
+ buffer = 0;
+
+ TRAP( error, buffer = modify->WriteDataL( tmpDes ) );
+ if( (error != KErrNone) || (!buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+ delete buffer;
+ buffer = 0;
+
+ TRAP( error, buffer = modify->WriteDataL( exif->Des() ) );
+ if( (error != KErrNone) || (!buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ CleanupStack::PushL(buffer);
+ fileName.Copy(KRootOut);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Modify16_02.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootC);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Modify16_02.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootData);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Modify16_02.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+ }
+ }
+ }
+ }
+ }
+
+ file.Write(buffer->Des());
+ file.Close();
+ CleanupStack::PopAndDestroy(buffer);
+ buffer = 0;
+
+ modify->DeleteTag(EIfdExif, KIdPixelXDimension);
+
+ TRAP( error, buffer = modify->WriteDataL( exif->Des() ) );
+ if( (error != KErrNotReady) || (buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ TRAP( error, buffer = modify->WriteDataL( tmpDes ) );
+ if( (error != KErrNotReady) || (buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.018
+// Try to retrieve the Exif APP1 segment when the Exif is not complete yet.
+// Leaves with KErrNotReady.
+void CExifModifyTest::ExifModify018L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL( *exif, CExifModify::EModify );
+ CleanupStack::PushL( modify );
+
+ modify->DeleteTag( EIfd0, KIdXResolution );
+ HBufC8* appSegment = 0;
+ TRAPD( error, appSegment = modify->Reader()->GetExifAppSegmentL() );
+ if ( (error != KErrNotReady) || ( appSegment ) )
+ {
+ if ( appSegment )
+ delete appSegment;
+ User::Leave( KErrGeneral );
+ }
+
+ CleanupStack::PopAndDestroy( modify );
+ CleanupStack::PopAndDestroy( exif );
+ }
+
+// Exif.Modify.019
+// Check NULL character at the end of ASCII type tags
+// Returns error for invalid cases and behaves properly for other cases.
+void CExifModifyTest::ExifModify019L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL( *exif, CExifModify::EModify );
+ CleanupStack::PushL( modify );
+
+ HBufC8* buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ buf->Des().Copy(_L("2004:01:19 11:00:00"));
+ modify->SetDateTimeOriginalL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+ buf = modify->Reader()->GetDateTimeOriginalL();
+ CleanupStack::PushL(buf);
+ if ( ( buf->Des().Ptr()[buf->Des().Length() - 1] != NULL ) &&
+ ( buf->Des().Length() != 20 ) )
+ {
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(20);
+ CleanupStack::PushL(buf);
+ buf->Des().Copy(_L("2004:01:19 11:00:00\0"));
+ modify->SetDateTimeOriginalL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+ buf = modify->Reader()->GetDateTimeOriginalL();
+ CleanupStack::PushL(buf);
+ if ( ( buf->Des().Ptr()[buf->Des().Length() - 1] != NULL ) &&
+ ( buf->Des().Length() != 20 ) )
+ {
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(18);
+ CleanupStack::PushL(buf);
+ buf->Des().Copy(_L("2004:01:19 11:00:0"));
+ TRAPD( error, modify->SetDateTimeOriginalL(buf->Des()) );
+ if ( error != KErrNotSupported )
+ {
+ User::LeaveIfError( error );
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(20);
+ CleanupStack::PushL(buf);
+ buf->Des().Copy(_L("2004:01:19 11:00:001"));
+ TRAP( error, modify->SetDateTimeOriginalL(buf->Des()) );
+ if ( error != KErrNotSupported )
+ {
+ User::LeaveIfError( error );
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(12);
+ CleanupStack::PushL(buf);
+ TExifTagInfo tag(KIdRelatedSoundFile, CExifTag::ETagAscii, 12);
+ modify->SetTagL(EIfdExif, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = modify->Reader()->GetRelatedSoundFileL();
+ CleanupStack::PushL(buf);
+ if ( ( buf->Des().Ptr()[buf->Des().Length() - 1] != NULL ) &&
+ ( buf->Des().Length() != 13 ) )
+ {
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(13);
+ CleanupStack::PushL(buf);
+ TExifTagInfo tag2(KIdRelatedSoundFile, CExifTag::ETagAscii, 13);
+ *( CONST_CAST( TUint8*, buf->Des().Ptr()) + 12 ) = NULL;
+ modify->SetTagL(EIfdExif, tag2, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = modify->Reader()->GetRelatedSoundFileL();
+ CleanupStack::PushL(buf);
+ if ( ( buf->Des().Ptr()[buf->Des().Length() - 1] != NULL ) &&
+ ( buf->Des().Length() != 13 ) )
+ {
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(14);
+ CleanupStack::PushL(buf);
+ *( CONST_CAST( TUint8*, buf->Des().Ptr()) + 13 ) = NULL;
+ TExifTagInfo tag3(KIdRelatedSoundFile, CExifTag::ETagAscii, 14);
+ TRAP( error, modify->SetTagL(EIfdExif, tag3, buf->Des()) );
+ if ( error != KErrNotSupported )
+ {
+ User::LeaveIfError( error );
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(11);
+ CleanupStack::PushL(buf);
+ TExifTagInfo tag4(KIdRelatedSoundFile, CExifTag::ETagAscii, 11);
+ TRAP( error, modify->SetTagL(EIfdExif, tag4, buf->Des()) );
+ if ( error != KErrNotSupported )
+ {
+ User::LeaveIfError( error );
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ CleanupStack::PopAndDestroy( modify );
+ CleanupStack::PopAndDestroy( exif );
+ }
+
+// Exif.Modify.MEM.017
+// Test the behavior of the previous test cases in OOM situations.
+// Successfully operates or leaves with OOM error, without any memory leaks.
+void CExifModifyTest::ExifModify017L()
+ {
+ // OOM in EXIF.MODIFY.001- EXIF.MODIFY.016
+ TInt error = KErrGeneral;
+ TInt i = 0;
+
+ RDebug::Print(_L("ExifModify001L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify001L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify002L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify002L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify003L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify003L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify004L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify004L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify005L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify005L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify006L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify006L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify007L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify007L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify008L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify008L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify009L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify009L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify010L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify010L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify011L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify011L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify012L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify012L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify013L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify013L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify014L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify014L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify015L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify015L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify016L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify016L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify018L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify018L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify019L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify019L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ }
+
+// Exif.Modify.Fast.020
+// Instantiate an Exif modifier with valid Exif image with fast option
+// Modified Exif modifier instance in EModify mode is returned.
+// Write buffer to file
+void CExifModifyTest::ExifModify020L()
+ {
+ /*
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify);
+ if(!modify)
+ User::Leave(KErrGeneral);
+ delete modify;
+ CleanupStack::PopAndDestroy(exif);
+ */
+
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing);
+ if(!modify)
+ User::Leave(KErrGeneral);
+ CleanupStack::PushL(modify);
+ modify->SetCustomRenderedL(0);
+ HBufC8* buffer = modify->WriteDataL(*exif);
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PushL(buffer);
+
+ RFile file;
+ TBuf<255> fileName;
+ fileName.Copy(KRootOut);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Modify20_01.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootC);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Modify20_01.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootData);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Modify20_01.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+ }
+ }
+ }
+ }
+ }
+
+ file.Write(buffer->Des());
+ file.Close();
+ CleanupStack::PopAndDestroy(buffer);
+ buffer = 0;
+
+/*
+ CleanupStack::PushL(b);
+ RFile file;
+ User::LeaveIfError(file.Open(iFs, _L("C:\\FullExif_Modify020.jpg"), EFileWrite));
+
+ file.Write(b->Des());
+ file.Close();
+ CleanupStack::PopAndDestroy(b);
+*/
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.Unknown.021
+// Instantiate an Exif modifier with Exif image that has extra tags with ENoJpegParsing + ENoTagChecking options
+// Modified Exif modifier instance in EModify mode is returned.
+// Change Orientation tag and write buffer to file
+void CExifModifyTest::ExifModify021L()
+ {
+ RDebug::Print(_L("CExifModifyTest::ExifModify021L: Read file to be modified"));
+ HBufC8* exif = TUtils::ReadFileL(iFs, KUnknown_tags);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing | CExifModify::ENoTagChecking );
+ if(!modify)
+ User::Leave(KErrGeneral);
+ CleanupStack::PushL(modify);
+
+
+ RDebug::Print(_L("CExifModifyTest: modify tag SetOrientationL"));
+ modify->SetOrientationL(8);
+
+ RDebug::Print(_L("CExifModifyTest: write data to buffer"));
+ HBufC8* buffer = modify->WriteDataL(*exif);
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PushL(buffer);
+
+ RDebug::Print(_L("CExifModifyTest: RFile"));
+ RFile file;
+ TBuf<255> fileName;
+ fileName.Copy(KRootOut);
+ fileName.Append(_L("out\\"));
+ fileName.Append(KUnknown_tags_out);
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootC);
+ fileName.Append(_L("out\\"));
+ fileName.Append(KUnknown_tags_out);
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootData);
+ fileName.Append(_L("out\\"));
+ fileName.Append(KUnknown_tags_out);
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+ }
+ }
+ }
+ }
+ }
+
+ RDebug::Print(_L("CExifModifyTest: write data to file"));
+ file.Write(buffer->Des());
+ file.Close();
+ CleanupStack::PopAndDestroy(buffer);
+ buffer = 0;
+
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.Unknown.022
+// Instantiate an Exif modifier with Exif image that has extra tags with ENoJpegParsing + ENoTagChecking options
+// Modified Exif modifier instance in EModify mode is returned.
+// Change Orientation tag and write buffer to file
+void CExifModifyTest::ExifModify022L()
+ {
+ RDebug::Print(_L("CExifModifyTest::ExifModify022L: Read file to be modified"));
+ HBufC8* exif = TUtils::ReadFileL(iFs, KNoTagChk_IMG_AN19);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing | CExifModify::ENoTagChecking );
+ if(!modify)
+ User::Leave(KErrGeneral);
+ CleanupStack::PushL(modify);
+
+
+ RDebug::Print(_L("CExifModifyTest: modify tag SetOrientationL"));
+ modify->SetOrientationL(8);
+
+ RDebug::Print(_L("CExifModifyTest: write data to buffer"));
+ HBufC8* buffer = modify->WriteDataL(*exif);
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PushL(buffer);
+
+ RDebug::Print(_L("CExifModifyTest: RFile"));
+ RFile file;
+ TBuf<255> fileName;
+ fileName.Copy(KRootOut);
+ fileName.Append(_L("out\\"));
+ fileName.Append(KNoTagChk_IMG_AN19_out);
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootC);
+ fileName.Append(_L("out\\"));
+ fileName.Append(KNoTagChk_IMG_AN19_out);
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootData);
+ fileName.Append(_L("out\\"));
+ fileName.Append(KNoTagChk_IMG_AN19_out);
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+ }
+ }
+ }
+ }
+ }
+
+ RDebug::Print(_L("CExifModifyTest: write data to file"));
+ file.Write(buffer->Des());
+ file.Close();
+ CleanupStack::PopAndDestroy(buffer);
+ buffer = 0;
+
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.Unknown.023
+// Instantiate an Exif modifier with Exif image that has extra tags with ENoJpegParsing + ENoTagChecking options
+// Modified Exif modifier instance in EModify mode is returned.
+// Change Orientation tag and write buffer to file
+void CExifModifyTest::ExifModify023L()
+ {
+ RDebug::Print(_L("CExifModifyTest:ExifModify023L: Read file to be modified"));
+ HBufC8* exif = TUtils::ReadFileL(iFs, KtagInWrongIfd);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing | CExifModify::ENoTagChecking );
+ if(!modify)
+ User::Leave(KErrGeneral);
+ CleanupStack::PushL(modify);
+
+
+ RDebug::Print(_L("CExifModifyTest: modify tag SetOrientationL"));
+ modify->SetOrientationL(8);
+
+ RDebug::Print(_L("CExifModifyTest: write data to buffer"));
+ HBufC8* buffer = modify->WriteDataL(*exif);
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PushL(buffer);
+
+ RDebug::Print(_L("CExifModifyTest: RFile"));
+ RFile file;
+ TBuf<255> fileName;
+ fileName.Copy(KRootOut);
+ fileName.Append(_L("out\\"));
+ fileName.Append(KtagInWrongIfd_out);
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootC);
+ fileName.Append(_L("out\\"));
+ fileName.Append(KtagInWrongIfd_out);
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootData);
+ fileName.Append(_L("out\\"));
+ fileName.Append(KtagInWrongIfd_out);
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+ }
+ }
+ }
+ }
+ }
+
+ RDebug::Print(_L("CExifModifyTest: write data to file"));
+ file.Write(buffer->Des());
+ file.Close();
+ CleanupStack::PopAndDestroy(buffer);
+ buffer = 0;
+
+ CleanupStack::PopAndDestroy(exif);
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/src/ExifModifyTest100.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,2160 @@
+/*
+* Copyright (c) 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: ExifLibTest
+*
+*/
+#include "ExifLibTestInc.h"
+
+// Test for fast option
+
+// Exif.Modify.101
+// Instantiate an Exif modifier with valid Exif image
+// Modified Exif modifier instance in EModify mode is returned.
+void CExifModifyTest::ExifModify101L()
+ {
+
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing);
+ if(!modify)
+ User::Leave(KErrGeneral);
+ delete modify;
+ CleanupStack::PopAndDestroy(exif);
+
+ /*
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify);
+ if(!modify)
+ User::Leave(KErrGeneral);
+ modify->SetCustomRenderedL(0);
+ HBufC8* b = modify->WriteDataL(*exif);
+ RFile file;
+ User::LeaveIfError(file.Open(iFs, _L("C:\\FullExif.jpg"), EFileWrite));
+
+ file.Write(b->Des());
+ file.Close();
+ delete b;
+*/
+ }
+
+// Exif.Modify.102
+// Try to instantiate an Exif modifier with invalid/ corrupted Exif image
+// Leaves with proper error code.
+void CExifModifyTest::ExifModify102L()
+ {
+ // Various invalid/ corrupted Exif images
+ HBufC8* exif = TUtils::ReadFileL(iFs, KInvalidExif1);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = 0;
+ TRAPD( error, modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing) );
+ if ( ( error != KErrCorrupt ) || ( modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif2);
+ CleanupStack::PushL(exif);
+ TRAP( error, modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing) );
+ if ( ( error != KErrCorrupt ) || ( modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif3);
+ CleanupStack::PushL(exif);
+ TRAP( error, modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing) );
+ if ( ( error != KErrCorrupt ) || ( modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif4);
+ CleanupStack::PushL(exif);
+ TRAP( error, modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing) );
+ if ( ( error != KErrCorrupt ) || ( modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif5);
+ CleanupStack::PushL(exif);
+ TRAP( error, modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing) );
+ if ( ( error != KErrCorrupt ) || ( modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif6);
+ CleanupStack::PushL(exif);
+ TRAP( error, modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing) );
+ if ( ( error != KErrCorrupt ) || ( modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ /* Supported, but uncompressed thumbnail is skipped */
+ exif = TUtils::ReadFileL(iFs, KNotSupportedExif1);
+ CleanupStack::PushL(exif);
+ TRAP( error, modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing) );
+ if ( ( error != KErrNone ) || ( !modify ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ delete modify;
+ modify = NULL;
+ CleanupStack::PopAndDestroy(exif);
+
+ /* Supported, but unsupported (uncompressed) thumbnail is skipped */
+ exif = TUtils::ReadFileL(iFs, KNotSupportedExif2);
+ CleanupStack::PushL(exif);
+ TRAP( error, modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing) );
+ if ( ( error != KErrCorrupt ) )
+ {
+ if ( modify )
+ {
+ delete modify;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ delete modify;
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.103
+// Retrieve reader instance for the related Exif data.
+// Returns unmodifiable reader instance.
+void CExifModifyTest::ExifModify103L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+
+ const CExifRead* reader = modify->Reader();
+ if(!reader)
+ User::Leave(KErrGeneral);
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.104
+// Insert/ Update a valid tag into the specified IFD in Exif data.
+// The given tag instance is inserted or updated.
+void CExifModifyTest::ExifModify104L()
+ {
+// For each IFD.
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+
+
+ HBufC8* buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ TExifTagInfo tag(KIdImageDescription, CExifTag::ETagAscii, 16);
+ modify->SetTagL(EIfd0, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(20);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdUserComment;
+ tag.iDataType = CExifTag::ETagUndefined;
+ tag.iDataCount = 20;
+ modify->SetTagL(EIfdExif, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 0;
+ tag.iId = KIdExposureProgram;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 1;
+ modify->SetTagL(EIfdExif, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(1);
+ CleanupStack::PushL(buf);
+ tag.iId = 3;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 1;
+ modify->SetTagL(EIfdGps, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(3);
+ CleanupStack::PushL(buf);
+ tag.iId = 1;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 3;
+ modify->SetTagL(EIfdIntOp, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 2;
+ tag.iId = KIdResolutionUnit;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 1;
+ modify->SetTagL(EIfd1, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.105
+// Try to insert/ update a valid tag into the specified IFD in Exif data.
+// Leaves with proper error code.
+void CExifModifyTest::ExifModify105L()
+ {
+//* Tag is not allowed to be inserted into the specified IFD,
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+
+
+ HBufC8* buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ TExifTagInfo tag(KIdImageDescription, CExifTag::ETagAscii, 16);
+ TRAPD(error, modify->SetTagL(EIfdExif, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(20);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdUserComment;
+ tag.iDataType = CExifTag::ETagUndefined;
+ tag.iDataCount = 20;
+ TRAP(error, modify->SetTagL(EIfd1, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 0;
+ tag.iId = KIdExposureProgram;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 1;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ tag.iId = 3;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 2;
+ TRAP(error, modify->SetTagL(EIfdIntOp, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(3);
+ CleanupStack::PushL(buf);
+ tag.iId = 1;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 3;
+ TRAP(error, modify->SetTagL(EIfdExif, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 2;
+ tag.iId = KIdResolutionUnit;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 1;
+ TRAP(error, modify->SetTagL(EIfdGps, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ //* The Exif data size exceeds 64K"
+ buf = TUtils::CreateDummyBufL(65000);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdImageDescription;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 65000;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrOverflow)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ // Tag ID is invalid,
+ buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ tag.iId = 200;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 19;
+ TRAP(error, modify->SetTagL(EIfdGps, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ //Tag ID doesn't match with the data type, (Full validity)
+ //* Not supported yet!!!
+ buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdImageDescription;
+ tag.iDataType = CExifTag::ETagByte;
+ tag.iDataCount = 19;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ //*/
+
+ //Data count doesn't match with the given tag data size
+ buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdImageDescription;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 24;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrArgument)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ //Tag data value is not valid (Full validity)
+ // !! DROPPED
+ /* Not supported yet!!!
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdImageDescription;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 2;
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 200;
+ TRAP(error, modify->SetTagL(EIfdExif, tag, buf->Des()));
+ if(error != KErrArgument)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ */
+
+ // Tag cannot be modified
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdExifIfdPointer;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdGpsIfdPointer;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdIntOpIfdPointer;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdJpegInterchangeFormat;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdJpegInterchangeFormatLength;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdExifVersion;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdGpsVersion;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdFlashPixVersion;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdCompression;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.106
+// Remove a tag from the specified IFD in Exif data.
+// Removes the tag from the specified IFD.
+void CExifModifyTest::ExifModify106L()
+ {
+ // For each IFD.
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+
+ User::LeaveIfError(modify->DeleteTag(EIfd0, KIdXResolution));
+
+ User::LeaveIfError(modify->DeleteTag(EIfdExif, KIdExposureProgram));
+
+ User::LeaveIfError(modify->DeleteTag(EIfd1, KIdResolutionUnit));
+
+ User::LeaveIfError(modify->DeleteTag(EIfdGps, 27));
+
+ User::LeaveIfError(modify->DeleteTag(EIfdIntOp, 1));
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.107
+// Try to remove a tag from the specified IFD in Exif data.
+// Returns proper error code.
+void CExifModifyTest::ExifModify107L()
+ {
+ //"For each IFD;
+//* IFD exists but tag doesn't exist,
+//* IFD doesn't exist"
+
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+ TInt error = modify->DeleteTag(EIfd0, 0x013f);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+ error = modify->DeleteTag(EIfdExif, KIdMakerNote);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+ error = modify->DeleteTag(EIfd1, KIdCompression);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+ error = modify->DeleteTag(EIfdIntOp, 4);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+ error = modify->DeleteTag(EIfdGps, 27);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+//* Invalid tag ID
+ error = modify->DeleteTag(EIfdExif, 0x0205);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+//* Tag cannot be removed!
+ error = modify->DeleteTag(EIfdExif, KIdGpsIfdPointer);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ error = modify->DeleteTag(EIfdExif, KIdFlashPixVersion);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ error = modify->DeleteTag(EIfdExif, KIdExifIfdPointer);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ error = modify->DeleteTag(EIfdExif, KIdIntOpIfdPointer);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ error = modify->DeleteTag(EIfdExif, KIdJpegInterchangeFormat);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ error = modify->DeleteTag(EIfdExif, KIdGpsVersion);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ error = modify->DeleteTag(EIfdExif, KIdJpegInterchangeFormatLength);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ error = modify->DeleteTag(EIfdExif, KIdExifVersion);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.108
+// Remove an IFD from the Exif data.
+// Removes the IFD from the Exif data.
+void CExifModifyTest::ExifModify108L()
+ {
+ // For each IFD.
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+
+ // Not allowed to delete Ifd0 and ExifIfd
+ // User::LeaveIfError(modify->DeleteIfd(EIfd0));
+ // User::LeaveIfError(modify->DeleteIfd(EIfdExif));
+ User::LeaveIfError(modify->DeleteIfd(EIfd1));
+ User::LeaveIfError(modify->DeleteIfd(EIfdGps));
+ User::LeaveIfError(modify->DeleteIfd(EIfdIntOp));
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.109
+// Try to remove an IFD from the Exif data, which doesn't contain that IFD.
+// Returns proper error code.
+void CExifModifyTest::ExifModify109L()
+ {
+ // For each IFD.
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+ TInt error = modify->DeleteIfd(EIfdGps);
+
+ if(error != KErrNotFound)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+ error = modify->DeleteIfd(EIfd0);
+ if(error != KErrArgument)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+ // IFD cannot be removed
+ error = modify->DeleteIfd(EIfd0);
+ if( error != KErrArgument)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+ error = modify->DeleteIfd(EIfdExif);
+ if( error != KErrArgument)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.110
+// Insert/ Update compressed Exif thumbnail image into the the Exif data.
+// Inserts/ Updates the Exif thumbnail image
+void CExifModifyTest::ExifModify110L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KNoThumbnail);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+
+ HBufC8* thumbnail = TUtils::ReadFileL(iFs, KValidThumbnail);
+ CleanupStack::PushL(thumbnail);
+ modify->SetThumbnailL(thumbnail->Des());
+ CleanupStack::PopAndDestroy(thumbnail);
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.111
+// Try to Insert/ Update compressed Exif thumbnail image with in invalid cases.
+// Leaves with proper error code.
+void CExifModifyTest::ExifModify111L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+
+//"* Given thumbnail data is not valid compressed Exif thumbnail image, !! Not supported yet !!
+ HBufC8* buf = TUtils::CreateDummyBufL(8000);
+ CleanupStack::PushL(buf);
+ TRAPD( error, modify->SetThumbnailL(buf->Des()) );
+ if ( error != KErrCorrupt )
+ {
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( buf );
+
+//* The Exif data size exceeds 64K"
+ TExifTagInfo tag(KIdImageDescription, CExifTag::ETagAscii, 52000);
+ buf = TUtils::CreateDummyBufL(52000);
+ CleanupStack::PushL(buf);
+ modify->SetTagL(EIfd0, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ HBufC8* thumbnail = TUtils::ReadFileL(iFs, KValidThumbnail);
+ CleanupStack::PushL(thumbnail);
+ TRAP( error, modify->SetThumbnailL(thumbnail->Des()) );
+ if ( error != KErrOverflow )
+ {
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(thumbnail);
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.112
+// Remove compressed Exif thumbnail image from the Exif data.
+// Removes the thumbnail image.
+void CExifModifyTest::ExifModify112L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+
+ User::LeaveIfError(modify->RemoveThumbnail());
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.113
+// Try to remove compressed Exif thumbnail image from the Exif data.
+// Returns proper error code.
+void CExifModifyTest::ExifModify113L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KNoThumbnail);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+ TInt error = modify->RemoveThumbnail();
+
+ if(error != KErrNotFound)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.114
+// Write the final Exif image to a buffer.
+// Writes the whole Exif image in a buffer, and returns the buffer.
+void CExifModifyTest::ExifModify114L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+
+ // Insert Tags
+ HBufC8* buf = 0;
+ TUint16 tmp1 = 0;
+ TUint32 tmp3 = 0;
+ TUint32 tmp4 = 0;
+ TInt32 tmp5 = 0;
+ TInt32 tmp6 = 0;
+
+ buf = TUtils::CreateDummyBufL(10);
+ CleanupStack::PushL(buf);
+ modify->SetUserCommentL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ modify->SetModelL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ tmp1 = 0;
+ modify->SetMeteringModeL(tmp1);
+
+ tmp5 = 1;
+ tmp6 = 1;
+ modify->SetExposureBiasValueL(tmp5, tmp6);
+
+ tmp5 = 0;
+ tmp6 = 1;
+ modify->SetShutterSpeedValueL(tmp5, tmp6);
+
+ modify->SetBrightnessValueL(tmp5, tmp6);
+
+ modify->SetCustomRenderedL(0);
+
+ modify->SetGainControlL(0);
+
+ buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ buf->Des().Copy(_L("2004:01:19 11:00:00"));
+ modify->SetDateTimeOriginalL(buf->Des());
+ modify->SetDateTimeDigitizedL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ tmp5 = 1;
+ tmp6 = 1;
+ modify->SetApertureValueL(tmp5, tmp6);
+
+ tmp3 = 72;
+ tmp4 = 1;
+ modify->SetXResolutionL(tmp3, tmp4);
+ modify->SetYResolutionL(tmp3, tmp4);
+ tmp1 = 2;
+ modify->SetResolutionUnitL(tmp1);
+ tmp1 = 1;
+ modify->SetYCbCrPositioningL(tmp1);
+
+ modify->SetComponentsConfigurationL(1, 2, 3, 0);
+ tmp1 = 1;
+ modify->SetColorSpaceL(tmp1);
+ tmp3 = 1024;
+ modify->SetPixelXDimensionL(tmp3);
+ tmp3 = 768;
+ modify->SetPixelYDimensionL(tmp3);
+
+
+ buf = TUtils::CreateDummyBufL(5);
+ CleanupStack::PushL(buf);
+ modify->SetImageDescriptionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+
+ buf = TUtils::CreateDummyBufL(768*2);
+ CleanupStack::PushL(buf);
+ modify->SetTransferFunctionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ modify->SetExposureModeL(0);
+ modify->SetWhiteBalanceL(0);
+ modify->SetSceneCaptureTypeL(0);
+ modify->SetExposureProgramL(0);
+
+ modify->SetLightSourceL(0);
+
+ buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ modify->SetMakerNoteL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ HBufC8* buffer = modify->WriteDataL(exif->Des());
+ if(!buffer)
+ User::Leave(KErrGeneral);
+ delete buffer;
+ buffer = 0;
+
+ TPtrC8 tmpDes;
+ buffer = modify->WriteDataL( tmpDes );
+ if(!buffer)
+ User::Leave(KErrGeneral);
+ delete buffer;
+
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Modify.115
+// Try to write the final Exif image to a buffer for invalid cases or incorrect original data buffer
+// Leaves with proper error code.
+void CExifModifyTest::ExifModify115L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+
+//"* Given buffer content is not the same with the original buffer content.
+ TInt error = 0;
+ HBufC8* buf = 0;
+ HBufC8* buffer = 0;
+
+ buf = TUtils::CreateDummyBufL( exif->Length() );
+ CleanupStack::PushL( buf );
+ TRAP( error, buffer = modify->WriteDataL( *buf ) );
+ if ( ( error != KErrArgument ) || ( buffer ) )
+ {
+ if ( buffer )
+ delete buffer;
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( buf );
+
+ buf = TUtils::CreateDummyBufL( exif->Length() - 5 );
+ CleanupStack::PushL( buf );
+ TRAP( error, buffer = modify->WriteDataL( *buf ) );
+ if ( ( error != KErrArgument ) || ( buffer ) )
+ {
+ if ( buffer )
+ delete buffer;
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( buf );
+
+ buf = TUtils::CreateDummyBufL( exif->Length() );
+ CleanupStack::PushL( buf );
+ buf->Des().Copy( exif->Ptr(), exif->Length() / 2 - 10 );
+ buf->Des().SetLength( exif->Length() );
+ TRAP( error, buffer = modify->WriteDataL( *buf ) );
+ if ( ( error != KErrArgument ) || ( buffer ) )
+ {
+ if ( buffer )
+ delete buffer;
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( buf );
+
+ buf = TUtils::CreateDummyBufL( exif->Length() );
+ CleanupStack::PushL( buf );
+ buf->Des().Copy( exif->Ptr(), exif->Length() / 2 + 10 );
+ buf->Des().SetLength( exif->Length() );
+ TRAP( error, buffer = modify->WriteDataL( *buf ) );
+ if ( ( error != KErrArgument ) || ( buffer ) )
+ {
+ if ( buffer )
+ delete buffer;
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( buf );
+
+//* The Exif data doesn't contain all mandatory tags"
+
+ // Insert Tags
+ TUint16 tmp1 = 0;
+ TUint32 tmp3 = 0;
+ TUint32 tmp4 = 0;
+
+ tmp3 = 72;
+ tmp4 = 1;
+ modify->SetXResolutionL(tmp3, tmp4);
+ tmp1 = 2;
+ modify->SetResolutionUnitL(tmp1);
+
+ modify->SetComponentsConfigurationL(1, 2, 3, 0);
+ tmp1 = 1;
+ modify->SetColorSpaceL(tmp1);
+ tmp3 = 768;
+ modify->SetPixelYDimensionL(tmp3);
+ modify->DeleteTag(EIfdExif, KIdPixelXDimension);
+
+
+ buf = TUtils::CreateDummyBufL(5);
+ CleanupStack::PushL(buf);
+ modify->SetImageDescriptionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+
+ buf = TUtils::CreateDummyBufL(768*2);
+ CleanupStack::PushL(buf);
+ modify->SetTransferFunctionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ modify->SetExposureModeL(0);
+ modify->SetWhiteBalanceL(0);
+ modify->SetSceneCaptureTypeL(0);
+ modify->SetExposureProgramL(0);
+
+ modify->SetLightSourceL(0);
+
+ buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ modify->SetMakerNoteL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buffer = 0;
+ TRAP(error, buffer = modify->WriteDataL(exif->Des()));
+ if(buffer)
+ {
+ delete buffer;
+ User::Leave(KErrGeneral);
+ }
+ if(error != KErrNotReady)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+
+ buffer = 0;
+ TPtrC8 tmpDes;
+ TRAP(error, buffer = modify->WriteDataL( tmpDes ));
+ if(buffer)
+ {
+ delete buffer;
+ User::Leave(KErrGeneral);
+ }
+ if(error != KErrNotReady)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.116
+// Test the behavior of the previous test cases after the Exif image is written into a buffer (WriteDataL) called.
+// Leaves with or returns proper error code.
+// CHANGED:
+// This feature is changed. Multiple usage is allowed any more. Test using the modifier after WriteDataL function.
+void CExifModifyTest::ExifModify116L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL(*exif, CExifModify::EModify, CExifModify::ENoJpegParsing);
+ CleanupStack::PushL(modify);
+
+ // Insert Tags
+ TUint16 tmp1 = 0;
+ TUint32 tmp3 = 0;
+ TUint32 tmp4 = 0;
+
+ tmp3 = 72;
+ tmp4 = 1;
+ modify->SetXResolutionL(tmp3, tmp4);
+ tmp1 = 2;
+ modify->SetResolutionUnitL(tmp1);
+
+ modify->SetComponentsConfigurationL(1, 2, 3, 0);
+ tmp1 = 1;
+ modify->SetColorSpaceL(tmp1);
+ tmp3 = 768;
+ modify->SetPixelYDimensionL(tmp3);
+ modify->DeleteTag(EIfdExif, KIdPixelXDimension);
+
+ HBufC8* buffer = NULL;
+ TRAPD( error, buffer = modify->WriteDataL( exif->Des() ) );
+ if( (error != KErrNotReady) || (buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ TPtrC8 tmpDes;
+
+ TRAP( error, buffer = modify->WriteDataL( tmpDes ) );
+ if( (error != KErrNotReady) || (buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ modify->SetPixelXDimensionL(1024);
+
+ TRAP( error, buffer = modify->WriteDataL( tmpDes ) );
+ if( (error != KErrNone) || (!buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+ delete buffer;
+ buffer = 0;
+
+ TRAP( error, buffer = modify->WriteDataL( exif->Des() ) );
+ if( (error != KErrNone) || (!buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ CleanupStack::PushL(buffer);
+ RFile file;
+ TBuf<255> fileName;
+ fileName.Copy(KRootOut);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Modify116_01.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootC);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Modify116_01.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootData);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Modify116_01.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+ }
+ }
+ }
+ }
+ }
+
+ file.Write(buffer->Des());
+ file.Close();
+ CleanupStack::PopAndDestroy(buffer);
+ buffer = 0;
+
+ TRAP( error, buffer = modify->WriteDataL( tmpDes ) );
+ if( (error != KErrNone) || (!buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+ delete buffer;
+ buffer = 0;
+
+ TRAP( error, buffer = modify->WriteDataL( exif->Des() ) );
+ if( (error != KErrNone) || (!buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ CleanupStack::PushL(buffer);
+ fileName.Copy(KRootOut);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Modify116_02.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootC);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Modify116_02.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootData);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Modify116_02.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+ }
+ }
+ }
+ }
+ }
+
+ file.Write(buffer->Des());
+ file.Close();
+ CleanupStack::PopAndDestroy(buffer);
+ buffer = 0;
+
+ modify->DeleteTag(EIfdExif, KIdPixelXDimension);
+
+ TRAP( error, buffer = modify->WriteDataL( exif->Des() ) );
+ if( (error != KErrNotReady) || (buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ TRAP( error, buffer = modify->WriteDataL( tmpDes ) );
+ if( (error != KErrNotReady) || (buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ CleanupStack::PopAndDestroy(modify);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Modify.118
+// Try to retrieve the Exif APP1 segment when the Exif is not complete yet.
+// Leaves with KErrNotReady.
+void CExifModifyTest::ExifModify118L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL( *exif, CExifModify::EModify );
+ CleanupStack::PushL( modify );
+
+ modify->DeleteTag( EIfd0, KIdXResolution );
+ HBufC8* appSegment = 0;
+ TRAPD( error, appSegment = modify->Reader()->GetExifAppSegmentL() );
+ if ( (error != KErrNotReady) || ( appSegment ) )
+ {
+ if ( appSegment )
+ delete appSegment;
+ User::Leave( KErrGeneral );
+ }
+
+ CleanupStack::PopAndDestroy( modify );
+ CleanupStack::PopAndDestroy( exif );
+ }
+
+// Exif.Modify.119
+// Check NULL character at the end of ASCII type tags
+// Returns error for invalid cases and behaves properly for other cases.
+void CExifModifyTest::ExifModify119L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifModify* modify = CExifModify::NewL( *exif, CExifModify::EModify );
+ CleanupStack::PushL( modify );
+
+ HBufC8* buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ buf->Des().Copy(_L("2004:01:19 11:00:00"));
+ modify->SetDateTimeOriginalL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+ buf = modify->Reader()->GetDateTimeOriginalL();
+ CleanupStack::PushL(buf);
+ if ( ( buf->Des().Ptr()[buf->Des().Length() - 1] != NULL ) &&
+ ( buf->Des().Length() != 20 ) )
+ {
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(20);
+ CleanupStack::PushL(buf);
+ buf->Des().Copy(_L("2004:01:19 11:00:00\0"));
+ modify->SetDateTimeOriginalL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+ buf = modify->Reader()->GetDateTimeOriginalL();
+ CleanupStack::PushL(buf);
+ if ( ( buf->Des().Ptr()[buf->Des().Length() - 1] != NULL ) &&
+ ( buf->Des().Length() != 20 ) )
+ {
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(18);
+ CleanupStack::PushL(buf);
+ buf->Des().Copy(_L("2004:01:19 11:00:0"));
+ TRAPD( error, modify->SetDateTimeOriginalL(buf->Des()) );
+ if ( error != KErrNotSupported )
+ {
+ User::LeaveIfError( error );
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(20);
+ CleanupStack::PushL(buf);
+ buf->Des().Copy(_L("2004:01:19 11:00:001"));
+ TRAP( error, modify->SetDateTimeOriginalL(buf->Des()) );
+ if ( error != KErrNotSupported )
+ {
+ User::LeaveIfError( error );
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(12);
+ CleanupStack::PushL(buf);
+ TExifTagInfo tag(KIdRelatedSoundFile, CExifTag::ETagAscii, 12);
+ modify->SetTagL(EIfdExif, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = modify->Reader()->GetRelatedSoundFileL();
+ CleanupStack::PushL(buf);
+ if ( ( buf->Des().Ptr()[buf->Des().Length() - 1] != NULL ) &&
+ ( buf->Des().Length() != 13 ) )
+ {
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(13);
+ CleanupStack::PushL(buf);
+ TExifTagInfo tag2(KIdRelatedSoundFile, CExifTag::ETagAscii, 13);
+ *( CONST_CAST( TUint8*, buf->Des().Ptr()) + 12 ) = NULL;
+ modify->SetTagL(EIfdExif, tag2, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = modify->Reader()->GetRelatedSoundFileL();
+ CleanupStack::PushL(buf);
+ if ( ( buf->Des().Ptr()[buf->Des().Length() - 1] != NULL ) &&
+ ( buf->Des().Length() != 13 ) )
+ {
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(14);
+ CleanupStack::PushL(buf);
+ *( CONST_CAST( TUint8*, buf->Des().Ptr()) + 13 ) = NULL;
+ TExifTagInfo tag3(KIdRelatedSoundFile, CExifTag::ETagAscii, 14);
+ TRAP( error, modify->SetTagL(EIfdExif, tag3, buf->Des()) );
+ if ( error != KErrNotSupported )
+ {
+ User::LeaveIfError( error );
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(11);
+ CleanupStack::PushL(buf);
+ TExifTagInfo tag4(KIdRelatedSoundFile, CExifTag::ETagAscii, 11);
+ TRAP( error, modify->SetTagL(EIfdExif, tag4, buf->Des()) );
+ if ( error != KErrNotSupported )
+ {
+ User::LeaveIfError( error );
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ CleanupStack::PopAndDestroy( modify );
+ CleanupStack::PopAndDestroy( exif );
+ }
+
+// Exif.Modify.117
+// Test the behavior of the previous test cases in OOM situations.
+// Successfully operates or leaves with OOM error, without any memory leaks.
+void CExifModifyTest::ExifModify117L()
+ {
+ // OOM in EXIF.Modify.101- EXIF.Modify.116
+ TInt error = KErrGeneral;
+ TInt i = 0;
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify101L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify101L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify102L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify102L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify103L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify103L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify104L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify104L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify105L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify105L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify106L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify106L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify107L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify107L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify108L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify108L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify109L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify109L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify110L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify110L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify111L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify111L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify112L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify112L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify113L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify113L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify114L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify114L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify115L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify115L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify116L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify116L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify118L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify118L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifModify119L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify119L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/src/ExifModifyTest2.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,2030 @@
+/*
+* Copyright (c) 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: ExifLibTest
+*
+*/
+#include "ExifLibTestInc.h"
+
+
+// Exif.Modify.001
+// Instantiate an Exif modifier with valid Exif image
+// Modified Exif modifier instance in EModify mode is returned.
+void CExifModifyTest2::ExifModify001L()
+ {
+ CExifModify* modify = CExifModify::NewL();
+ if(!modify)
+ User::Leave(KErrGeneral);
+ delete modify;
+ }
+
+// Exif.Modify.002
+// Try to instantiate an Exif modifier with invalid/ corrupted Exif image
+// Leaves with proper error code.
+void CExifModifyTest2::ExifModify002L()
+ {
+
+ CExifModify* modify = CExifModify::NewL();
+ CleanupStack::PushL(modify);
+
+ // Insert Tags
+ HBufC8* buf = 0;
+ TUint16 tmp1 = 0;
+ TUint32 tmp3 = 0;
+ TUint32 tmp4 = 0;
+ TInt32 tmp5 = 0;
+ TInt32 tmp6 = 0;
+
+ buf = TUtils::CreateDummyBufL(10);
+ CleanupStack::PushL(buf);
+ modify->SetUserCommentL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ modify->SetModelL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ tmp1 = 0;
+ modify->SetMeteringModeL(tmp1);
+
+ tmp5 = 1;
+ tmp6 = 1;
+ modify->SetExposureBiasValueL(tmp5, tmp6);
+
+ tmp5 = 0;
+ tmp6 = 1;
+ modify->SetShutterSpeedValueL(tmp5, tmp6);
+
+ modify->SetBrightnessValueL(tmp5, tmp6);
+
+ modify->SetCustomRenderedL(0);
+
+ modify->SetGainControlL(0);
+
+ buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ buf->Des().Copy(_L("2004:01:19 11:00:00"));
+ modify->SetDateTimeOriginalL(buf->Des());
+ modify->SetDateTimeDigitizedL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ tmp5 = 1;
+ tmp6 = 1;
+ modify->SetApertureValueL(tmp5, tmp6);
+
+ tmp3 = 72;
+ tmp4 = 1;
+ modify->SetXResolutionL(tmp3, tmp4);
+ modify->SetYResolutionL(tmp3, tmp4);
+ tmp1 = 2;
+ modify->SetResolutionUnitL(tmp1);
+ tmp1 = 1;
+ modify->SetYCbCrPositioningL(tmp1);
+
+ modify->SetComponentsConfigurationL(1, 2, 3, 0);
+ tmp1 = 1;
+ modify->SetColorSpaceL(tmp1);
+ tmp3 = 1024;
+ modify->SetPixelXDimensionL(tmp3);
+ tmp3 = 768;
+ modify->SetPixelYDimensionL(tmp3);
+
+
+ buf = TUtils::CreateDummyBufL(5);
+ CleanupStack::PushL(buf);
+ modify->SetImageDescriptionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+
+ buf = TUtils::CreateDummyBufL(768*2);
+ CleanupStack::PushL(buf);
+ modify->SetTransferFunctionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ modify->SetExposureModeL(0);
+ modify->SetWhiteBalanceL(0);
+ modify->SetSceneCaptureTypeL(0);
+ modify->SetExposureProgramL(0);
+
+ modify->SetLightSourceL(0);
+
+ buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ modify->SetMakerNoteL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ TPtrC8 tmpDes;
+ HBufC8* buffer = modify->WriteDataL( tmpDes );
+ if(!buffer)
+ User::Leave(KErrGeneral);
+ delete buffer;
+ buffer = 0;
+
+ HBufC8* exif = TUtils::ReadFileL(iFs, KInvalidJpeg1);
+ CleanupStack::PushL(exif);
+ TRAPD( error, buffer = modify->WriteDataL( exif->Des() ) );
+ if( (error!=KErrNotSupported) || buffer)
+ {
+ if ( buffer )
+ delete buffer;
+ buffer = 0;
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy( exif );
+
+ CleanupStack::PopAndDestroy(modify);
+ }
+
+// Exif.Modify.003
+// Retrieve reader instance for the related Exif data.
+// Returns unmodifiable reader instance.
+void CExifModifyTest2::ExifModify003L()
+ {
+ CExifModify* modify = CExifModify::NewL();
+ CleanupStack::PushL(modify);
+
+ const CExifRead* reader = modify->Reader();
+ if(!reader)
+ User::Leave(KErrGeneral);
+
+ CleanupStack::PopAndDestroy(modify);
+ }
+
+// Exif.Modify.004
+// Insert/ Update a valid tag into the specified IFD in Exif data.
+// The given tag instance is inserted or updated.
+void CExifModifyTest2::ExifModify004L()
+ {
+// For each IFD.
+
+
+ CExifModify* modify = CExifModify::NewL();
+ CleanupStack::PushL(modify);
+
+
+ HBufC8* buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ TExifTagInfo tag(KIdImageDescription, CExifTag::ETagAscii, 16);
+ modify->SetTagL(EIfd0, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(20);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdUserComment;
+ tag.iDataType = CExifTag::ETagUndefined;
+ tag.iDataCount = 20;
+ modify->SetTagL(EIfdExif, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 0;
+ tag.iId = KIdExposureProgram;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 1;
+ modify->SetTagL(EIfdExif, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(1);
+ CleanupStack::PushL(buf);
+ tag.iId = 3;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 1;
+ modify->SetTagL(EIfdGps, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(3);
+ CleanupStack::PushL(buf);
+ tag.iId = 1;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 3;
+ modify->SetTagL(EIfdIntOp, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 2;
+ tag.iId = KIdResolutionUnit;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 1;
+ modify->SetTagL(EIfd1, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ CleanupStack::PopAndDestroy(modify);
+
+ }
+
+// Exif.Modify.005
+// Try to insert/ update a valid tag into the specified IFD in Exif data.
+// Leaves with proper error code.
+void CExifModifyTest2::ExifModify005L()
+ {
+//* Tag is not allowed to be inserted into the specified IFD,
+
+
+ CExifModify* modify = CExifModify::NewL();
+ CleanupStack::PushL(modify);
+
+
+ HBufC8* buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ TExifTagInfo tag(KIdImageDescription, CExifTag::ETagAscii, 16);
+ TRAPD(error, modify->SetTagL(EIfdExif, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(20);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdUserComment;
+ tag.iDataType = CExifTag::ETagUndefined;
+ tag.iDataCount = 20;
+ TRAP(error, modify->SetTagL(EIfd1, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 0;
+ tag.iId = KIdExposureProgram;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 1;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ tag.iId = 3;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 2;
+ TRAP(error, modify->SetTagL(EIfdIntOp, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(3);
+ CleanupStack::PushL(buf);
+ tag.iId = 1;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 3;
+ TRAP(error, modify->SetTagL(EIfdExif, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 2;
+ tag.iId = KIdResolutionUnit;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 1;
+ TRAP(error, modify->SetTagL(EIfdGps, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ //* The Exif data size exceeds 64K"
+ buf = TUtils::CreateDummyBufL(65520);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdImageDescription;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 65520;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrOverflow)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ // Tag ID is invalid,
+ buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ tag.iId = 200;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 19;
+ TRAP(error, modify->SetTagL(EIfdGps, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ //Tag ID doesn't match with the data type, (Full validity)
+ //* Not supported yet!!!
+ buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdImageDescription;
+ tag.iDataType = CExifTag::ETagByte;
+ tag.iDataCount = 19;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ //*/
+
+ //Data count doesn't match with the given tag data size
+ buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdImageDescription;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 24;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrArgument)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ //Tag data value is not valid (Full validity)
+ // !! DROPPED
+ /* Not supported yet!!!
+ buf = TUtils::CreateDummyBufL(2);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdImageDescription;
+ tag.iDataType = CExifTag::ETagShort;
+ tag.iDataCount = 2;
+ *(reinterpret_cast<TUint16*>(const_cast<TUint8*>(buf->Ptr()))) = 200;
+ TRAP(error, modify->SetTagL(EIfdExif, tag, buf->Des()));
+ if(error != KErrArgument)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ */
+
+ // Tag cannot be modified
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdExifIfdPointer;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdGpsIfdPointer;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdIntOpIfdPointer;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdJpegInterchangeFormat;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdJpegInterchangeFormatLength;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdExifVersion;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdGpsVersion;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdFlashPixVersion;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ tag.iId = KIdCompression;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 4;
+ TRAP(error, modify->SetTagL(EIfd0, tag, buf->Des()));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+
+ CleanupStack::PopAndDestroy(modify);
+
+ }
+
+// Exif.Modify.06
+// Remove a tag from the specified IFD in Exif data.
+// Removes the tag from the specified IFD.
+void CExifModifyTest2::ExifModify006L()
+ {
+ // For each IFD.
+
+
+ CExifModify* modify = CExifModify::NewL();
+ CleanupStack::PushL(modify);
+
+ modify->SetXResolutionL( 72, 1 );
+
+ modify->SetExposureProgramL( 1 );
+
+ modify->SetThumbnailResolutionUnitL( 2 );
+
+
+ User::LeaveIfError(modify->DeleteTag(EIfd1, KIdResolutionUnit));
+
+ User::LeaveIfError(modify->DeleteTag(EIfd0, KIdXResolution));
+
+ User::LeaveIfError(modify->DeleteTag(EIfdExif, KIdExposureProgram));
+
+ CleanupStack::PopAndDestroy(modify);
+
+ }
+
+// Exif.Modify.07
+// Try to remove a tag from the specified IFD in Exif data.
+// Returns proper error code.
+void CExifModifyTest2::ExifModify007L()
+ {
+ //"For each IFD;
+//* IFD exists but tag doesn't exist,
+//* IFD doesn't exist"
+
+
+
+ CExifModify* modify = CExifModify::NewL();
+ CleanupStack::PushL(modify);
+ TInt error = modify->DeleteTag(EIfd0, 0x013f);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+ error = modify->DeleteTag(EIfdExif, KIdMakerNote);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+ error = modify->DeleteTag(EIfd1, KIdCompression);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+ error = modify->DeleteTag(EIfdIntOp, 4);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+ error = modify->DeleteTag(EIfdGps, 27);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+//* Invalid tag ID
+ error = modify->DeleteTag(EIfdExif, 0x0205);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+//* Tag cannot be removed!
+ error = modify->DeleteTag(EIfdExif, KIdGpsIfdPointer);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ error = modify->DeleteTag(EIfdExif, KIdFlashPixVersion);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ error = modify->DeleteTag(EIfdExif, KIdExifIfdPointer);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ error = modify->DeleteTag(EIfdExif, KIdIntOpIfdPointer);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ error = modify->DeleteTag(EIfdExif, KIdJpegInterchangeFormat);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ error = modify->DeleteTag(EIfdExif, KIdGpsVersion);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ error = modify->DeleteTag(EIfdExif, KIdJpegInterchangeFormatLength);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ error = modify->DeleteTag(EIfdExif, KIdExifVersion);
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(modify);
+
+ }
+
+// Exif.Modify.08
+// Remove an IFD from the Exif data.
+// Removes the IFD from the Exif data.
+void CExifModifyTest2::ExifModify008L()
+ {
+ // For each IFD.
+
+
+ CExifModify* modify = CExifModify::NewL();
+ CleanupStack::PushL(modify);
+
+ // Not allowed to delete Ifd0 and ExifIfd
+ // User::LeaveIfError(modify->DeleteIfd(EIfd0));
+ // User::LeaveIfError(modify->DeleteIfd(EIfdExif));
+ TExifTagInfo tag( 3, CExifTag::ETagAscii, 1 );
+ HBufC8* buf = TUtils::CreateDummyBufL(1);
+ CleanupStack::PushL(buf);
+ modify->SetTagL(EIfdGps, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = TUtils::CreateDummyBufL(3);
+ CleanupStack::PushL(buf);
+ tag.iId = 1;
+ tag.iDataType = CExifTag::ETagAscii;
+ tag.iDataCount = 3;
+ modify->SetTagL(EIfdIntOp, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ modify->SetThumbnailResolutionUnitL( 2 );
+
+ User::LeaveIfError(modify->DeleteIfd(EIfd1));
+ User::LeaveIfError(modify->DeleteIfd(EIfdGps));
+ User::LeaveIfError(modify->DeleteIfd(EIfdIntOp));
+
+ CleanupStack::PopAndDestroy(modify);
+
+ }
+
+// Exif.Modify.09
+// Try to remove an IFD from the Exif data, which doesn't contain that IFD.
+// Returns proper error code.
+void CExifModifyTest2::ExifModify009L()
+ {
+ // For each IFD.
+
+
+ CExifModify* modify = CExifModify::NewL();
+ CleanupStack::PushL(modify);
+ TInt error = modify->DeleteIfd(EIfdGps);
+
+ if(error != KErrNotFound)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+ error = modify->DeleteIfd(EIfd0);
+ if(error != KErrArgument)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+ // IFD cannot be removed
+ error = modify->DeleteIfd(EIfd0);
+ if( error != KErrArgument)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+ error = modify->DeleteIfd(EIfdExif);
+ if( error != KErrArgument)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(modify);
+
+ }
+
+// Exif.Modify.010
+// Insert/ Update compressed Exif thumbnail image into the the Exif data.
+// Inserts/ Updates the Exif thumbnail image
+void CExifModifyTest2::ExifModify010L()
+ {
+
+ CExifModify* modify = CExifModify::NewL();
+ CleanupStack::PushL(modify);
+
+ HBufC8* thumbnail = TUtils::ReadFileL(iFs, KValidThumbnail);
+ CleanupStack::PushL(thumbnail);
+ modify->SetThumbnailL(thumbnail->Des());
+ CleanupStack::PopAndDestroy(thumbnail);
+
+ CleanupStack::PopAndDestroy(modify);
+
+ }
+
+// Exif.Modify.011
+// Try to Insert/ Update compressed Exif thumbnail image with in invalid cases.
+// Leaves with proper error code.
+void CExifModifyTest2::ExifModify011L()
+ {
+
+
+ CExifModify* modify = CExifModify::NewL();
+ CleanupStack::PushL(modify);
+
+//"* Given thumbnail data is not valid compressed Exif thumbnail image, !! Not supported yet !!
+ HBufC8* buf = TUtils::CreateDummyBufL(8000);
+ CleanupStack::PushL(buf);
+ TRAPD( error, modify->SetThumbnailL(buf->Des()) );
+ if ( error != KErrCorrupt )
+ {
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( buf );
+
+//* The Exif data size exceeds 64K"
+ TExifTagInfo tag(KIdImageDescription, CExifTag::ETagAscii, 59000);
+ buf = TUtils::CreateDummyBufL(59000);
+ CleanupStack::PushL(buf);
+ modify->SetTagL(EIfd0, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+
+ HBufC8* thumbnail = TUtils::ReadFileL(iFs, KValidThumbnail);
+ CleanupStack::PushL(thumbnail);
+ TRAP( error, modify->SetThumbnailL(thumbnail->Des()) );
+ if ( error != KErrOverflow )
+ {
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(thumbnail);
+
+ CleanupStack::PopAndDestroy(modify);
+
+ }
+
+// Exif.Modify.012
+// Remove compressed Exif thumbnail image from the Exif data.
+// Removes the thumbnail image.
+void CExifModifyTest2::ExifModify012L()
+ {
+
+
+ CExifModify* modify = CExifModify::NewL();
+ CleanupStack::PushL(modify);
+
+ HBufC8* thumbnail = TUtils::ReadFileL(iFs, KValidThumbnail);
+ CleanupStack::PushL(thumbnail);
+ modify->SetThumbnailL(thumbnail->Des());
+
+ User::LeaveIfError(modify->RemoveThumbnail());
+
+ CleanupStack::PopAndDestroy( thumbnail );
+
+ CleanupStack::PopAndDestroy(modify);
+
+ }
+
+// Exif.Modify.013
+// Try to remove compressed Exif thumbnail image from the Exif data.
+// Returns proper error code.
+void CExifModifyTest2::ExifModify013L()
+ {
+ CExifModify* modify = CExifModify::NewL();
+ CleanupStack::PushL(modify);
+ TInt error = modify->RemoveThumbnail();
+
+ if(error != KErrNotFound)
+ {
+ if(error)
+ {
+ User::Leave(error);
+ }
+ User::Leave(KErrGeneral);
+ }
+
+
+ CleanupStack::PopAndDestroy(modify);
+
+ }
+
+// Exif.Modify.014
+// Write the final Exif image to a buffer.
+// Writes the whole Exif image in a buffer, and returns the buffer.
+void CExifModifyTest2::ExifModify014L()
+ {
+
+
+ CExifModify* modify = CExifModify::NewL();
+ CleanupStack::PushL(modify);
+
+ // Insert Tags
+ HBufC8* buf = 0;
+ TUint16 tmp1 = 0;
+ TUint32 tmp3 = 0;
+ TUint32 tmp4 = 0;
+ TInt32 tmp5 = 0;
+ TInt32 tmp6 = 0;
+
+ buf = TUtils::CreateDummyBufL(10);
+ CleanupStack::PushL(buf);
+ modify->SetUserCommentL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(4);
+ CleanupStack::PushL(buf);
+ modify->SetModelL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ tmp1 = 0;
+ modify->SetMeteringModeL(tmp1);
+
+ tmp5 = 1;
+ tmp6 = 1;
+ modify->SetExposureBiasValueL(tmp5, tmp6);
+
+ tmp5 = 0;
+ tmp6 = 1;
+ modify->SetShutterSpeedValueL(tmp5, tmp6);
+
+ modify->SetBrightnessValueL(tmp5, tmp6);
+
+ modify->SetCustomRenderedL(0);
+
+ modify->SetGainControlL(0);
+
+ buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ buf->Des().Copy(_L("2004:01:19 11:00:00"));
+ modify->SetDateTimeOriginalL(buf->Des());
+ modify->SetDateTimeDigitizedL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ tmp5 = 1;
+ tmp6 = 1;
+ modify->SetApertureValueL(tmp5, tmp6);
+
+ tmp3 = 72;
+ tmp4 = 1;
+ modify->SetXResolutionL(tmp3, tmp4);
+ modify->SetYResolutionL(tmp3, tmp4);
+ tmp1 = 2;
+ modify->SetResolutionUnitL(tmp1);
+ tmp1 = 1;
+ modify->SetYCbCrPositioningL(tmp1);
+
+ modify->SetComponentsConfigurationL(1, 2, 3, 0);
+ tmp1 = 1;
+ modify->SetColorSpaceL(tmp1);
+ tmp3 = 1024;
+ modify->SetPixelXDimensionL(tmp3);
+ tmp3 = 768;
+ modify->SetPixelYDimensionL(tmp3);
+
+
+ buf = TUtils::CreateDummyBufL(5);
+ CleanupStack::PushL(buf);
+ modify->SetImageDescriptionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+
+ buf = TUtils::CreateDummyBufL(768*2);
+ CleanupStack::PushL(buf);
+ modify->SetTransferFunctionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ modify->SetExposureModeL(0);
+ modify->SetWhiteBalanceL(0);
+ modify->SetSceneCaptureTypeL(0);
+ modify->SetExposureProgramL(0);
+
+ modify->SetLightSourceL(0);
+
+ buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ modify->SetMakerNoteL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ TPtrC8 tmpDes;
+ HBufC8* buffer = modify->WriteDataL( tmpDes );
+ if(!buffer)
+ User::Leave(KErrGeneral);
+ delete buffer;
+ buffer = 0;
+
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(exif);
+ buffer = modify->WriteDataL( exif->Des() );
+ if(!buffer)
+ User::Leave(KErrGeneral);
+ delete buffer;
+ CleanupStack::PopAndDestroy( exif );
+
+ CleanupStack::PopAndDestroy(modify);
+
+ }
+
+
+// Exif.Modify.015
+// Try to write the final Exif image to a buffer for invalid cases or incorrect original data buffer
+// Leaves with proper error code.
+void CExifModifyTest2::ExifModify015L()
+ {
+
+
+ CExifModify* modify = CExifModify::NewL();
+ CleanupStack::PushL(modify);
+
+//"* Given buffer content is not the same with the original buffer content.
+ TInt error = 0;
+ HBufC8* buf = 0;
+ HBufC8* buffer = 0;
+
+//* The Exif data doesn't contain all mandatory tags"
+
+ // Insert Tags
+ TUint16 tmp1 = 0;
+ TUint32 tmp3 = 0;
+ TUint32 tmp4 = 0;
+
+ tmp3 = 72;
+ tmp4 = 1;
+ modify->SetXResolutionL(tmp3, tmp4);
+ tmp1 = 2;
+ modify->SetResolutionUnitL(tmp1);
+
+ modify->SetComponentsConfigurationL(1, 2, 3, 0);
+ tmp1 = 1;
+ modify->SetColorSpaceL(tmp1);
+ tmp3 = 768;
+ modify->SetPixelYDimensionL(tmp3);
+ modify->DeleteTag(EIfdExif, KIdPixelXDimension);
+
+
+ buf = TUtils::CreateDummyBufL(5);
+ CleanupStack::PushL(buf);
+ modify->SetImageDescriptionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+
+ buf = TUtils::CreateDummyBufL(768*2);
+ CleanupStack::PushL(buf);
+ modify->SetTransferFunctionL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ modify->SetExposureModeL(0);
+ modify->SetWhiteBalanceL(0);
+ modify->SetSceneCaptureTypeL(0);
+ modify->SetExposureProgramL(0);
+
+ modify->SetLightSourceL(0);
+
+ buf = TUtils::CreateDummyBufL(16);
+ CleanupStack::PushL(buf);
+ modify->SetMakerNoteL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buffer = 0;
+ TPtrC8 tmpDes;
+ TRAP(error, modify->WriteDataL( tmpDes ));
+ if(buffer)
+ {
+ delete buffer;
+ User::Leave(KErrGeneral);
+ }
+ if(error != KErrNotReady)
+ {
+ if(error)
+ User::Leave(error);
+ User::Leave(KErrGeneral);
+ }
+
+ CleanupStack::PopAndDestroy(modify);
+
+ }
+
+// Exif.Modify.016
+// Test the behavior of the previous test cases after the Exif image is written into a buffer (WriteDataL) called.
+// Leaves with or returns proper error code.
+// CHANGED:
+// This feature is changed. Multiple usage is allowed any more. Test using the modifier after WriteDataL function.
+void CExifModifyTest2::ExifModify016L()
+ {
+ CExifModify* modify = CExifModify::NewL();
+ CleanupStack::PushL(modify);
+
+ HBufC8* jpeg = TUtils::ReadFileL(iFs, KValidJpeg);
+ CleanupStack::PushL(jpeg);
+
+ // Insert Tags
+ TUint16 tmp1 = 0;
+ TUint32 tmp3 = 0;
+ TUint32 tmp4 = 0;
+
+ modify->SetYCbCrPositioningL(2);
+ modify->SetComponentsConfigurationL(1, 2, 3, 0);
+ tmp1 = 1;
+ modify->SetColorSpaceL(tmp1);
+ tmp3 = 480;
+ modify->SetPixelYDimensionL(tmp3);
+
+ tmp3 = 72;
+ tmp4 = 1;
+ modify->SetXResolutionL(tmp3, tmp4);
+ modify->SetYResolutionL(tmp3, tmp4);
+ tmp1 = 2;
+ modify->SetResolutionUnitL(tmp1);
+
+ HBufC8* buffer = NULL;
+ TPtrC8 tmpDes;
+ TRAPD( error, buffer = modify->WriteDataL( tmpDes ) );
+ if( (error != KErrNotReady) || (buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ TRAP( error, buffer = modify->WriteDataL( jpeg->Des() ) );
+ if( (error != KErrNotReady) || (buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ modify->SetPixelXDimensionL(640);
+
+ TRAP( error, buffer = modify->WriteDataL( tmpDes ) );
+ if( (error != KErrNone) || (!buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+ delete buffer;
+ buffer = 0;
+
+ TRAP( error, buffer = modify->WriteDataL( jpeg->Des() ) );
+ if( (error != KErrNone) || (!buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PushL(buffer);
+
+ RFile file;
+ TBuf<255> fileName;
+ fileName.Copy(KRootOut);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Modify216_01.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootC);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Modify216_01.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootData);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Modify216_01.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+ }
+ }
+ }
+ }
+ }
+
+ file.Write(buffer->Des());
+ file.Close();
+
+ CleanupStack::PopAndDestroy(buffer);
+ buffer = 0;
+
+
+ TRAP( error, buffer = modify->WriteDataL( tmpDes ) );
+ if( (error != KErrNone) || (!buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+ delete buffer;
+ buffer = 0;
+
+ TRAP( error, buffer = modify->WriteDataL( jpeg->Des() ) );
+ if( (error != KErrNone) || (!buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PushL(buffer);
+
+ fileName.Copy(KRootOut);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Modify216_02.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootC);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Modify216_02.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ if(file.Create(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ fileName.Copy(KRootData);
+ fileName.Append(_L("out\\"));
+ fileName.Append(_L("Modify216_02.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ {
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+ }
+ }
+ }
+ }
+ }
+
+ file.Write(buffer->Des());
+ file.Close();
+ CleanupStack::PopAndDestroy(buffer);
+ buffer = 0;
+
+ modify->DeleteTag(EIfdExif, KIdPixelXDimension);
+
+ TRAP( error, buffer = modify->WriteDataL( jpeg->Des() ) );
+ if( (error != KErrNotReady) || (buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ TRAP( error, buffer = modify->WriteDataL( tmpDes ) );
+ if( (error != KErrNotReady) || (buffer) )
+ {
+ if( buffer )
+ delete buffer;
+ buffer = 0;
+ if( error )
+ {
+ User::Leave( error);
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ CleanupStack::PopAndDestroy( jpeg );
+ CleanupStack::PopAndDestroy(modify);
+
+ }
+
+// Exif.Modify.018
+// Try to retrieve the Exif APP1 segment when the Exif is not complete yet.
+// Leaves with KErrNotReady.
+void CExifModifyTest2::ExifModify018L()
+ {
+
+
+ CExifModify* modify = CExifModify::NewL( );
+ CleanupStack::PushL( modify );
+
+ modify->DeleteTag( EIfd0, KIdXResolution );
+ HBufC8* appSegment = 0;
+ TRAPD( error, appSegment = modify->Reader()->GetExifAppSegmentL() );
+ if ( (error != KErrNotReady) || ( appSegment ) )
+ {
+ if ( appSegment )
+ delete appSegment;
+ if ( error == KErrNoMemory )
+ {
+ User::Leave( error );
+ }
+ User::Leave( KErrGeneral );
+ }
+
+ CleanupStack::PopAndDestroy( modify );
+ }
+
+// Exif.Modify.019
+// Check NULL character at the end of ASCII type tags
+// Returns error for invalid cases and behaves properly for other cases.
+void CExifModifyTest2::ExifModify019L()
+ {
+
+
+ CExifModify* modify = CExifModify::NewL( );
+ CleanupStack::PushL( modify );
+
+ HBufC8* buf = TUtils::CreateDummyBufL(19);
+ CleanupStack::PushL(buf);
+ buf->Des().Copy(_L("2004:01:19 11:00:00"));
+ modify->SetDateTimeOriginalL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+ buf = modify->Reader()->GetDateTimeOriginalL();
+ CleanupStack::PushL(buf);
+ if ( ( buf->Des().Ptr()[buf->Des().Length() - 1] != NULL ) &&
+ ( buf->Des().Length() != 20 ) )
+ {
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(20);
+ CleanupStack::PushL(buf);
+ buf->Des().Copy(_L("2004:01:19 11:00:00\0"));
+ modify->SetDateTimeOriginalL(buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+ buf = modify->Reader()->GetDateTimeOriginalL();
+ CleanupStack::PushL(buf);
+ if ( ( buf->Des().Ptr()[buf->Des().Length() - 1] != NULL ) &&
+ ( buf->Des().Length() != 20 ) )
+ {
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(18);
+ CleanupStack::PushL(buf);
+ buf->Des().Copy(_L("2004:01:19 11:00:0"));
+ TRAPD( error, modify->SetDateTimeOriginalL(buf->Des()) );
+ if ( error != KErrNotSupported )
+ {
+ User::LeaveIfError( error );
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(20);
+ CleanupStack::PushL(buf);
+ buf->Des().Copy(_L("2004:01:19 11:00:001"));
+ TRAP( error, modify->SetDateTimeOriginalL(buf->Des()) );
+ if ( error != KErrNotSupported )
+ {
+ User::LeaveIfError( error );
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(12);
+ CleanupStack::PushL(buf);
+ TExifTagInfo tag(KIdRelatedSoundFile, CExifTag::ETagAscii, 12);
+ modify->SetTagL(EIfdExif, tag, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = modify->Reader()->GetRelatedSoundFileL();
+ CleanupStack::PushL(buf);
+ if ( ( buf->Des().Ptr()[buf->Des().Length() - 1] != NULL ) &&
+ ( buf->Des().Length() != 13 ) )
+ {
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(13);
+ CleanupStack::PushL(buf);
+ TExifTagInfo tag2(KIdRelatedSoundFile, CExifTag::ETagAscii, 13);
+ *( CONST_CAST( TUint8*, buf->Des().Ptr()) + 12 ) = NULL;
+ modify->SetTagL(EIfdExif, tag2, buf->Des());
+ CleanupStack::PopAndDestroy(buf);
+ buf = modify->Reader()->GetRelatedSoundFileL();
+ CleanupStack::PushL(buf);
+ if ( ( buf->Des().Ptr()[buf->Des().Length() - 1] != NULL ) &&
+ ( buf->Des().Length() != 13 ) )
+ {
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(14);
+ CleanupStack::PushL(buf);
+ *( CONST_CAST( TUint8*, buf->Des().Ptr()) + 13 ) = NULL;
+ TExifTagInfo tag3(KIdRelatedSoundFile, CExifTag::ETagAscii, 14);
+ TRAP( error, modify->SetTagL(EIfdExif, tag3, buf->Des()) );
+ if ( error != KErrNotSupported )
+ {
+ User::LeaveIfError( error );
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ buf = TUtils::CreateDummyBufL(11);
+ CleanupStack::PushL(buf);
+ TExifTagInfo tag4(KIdRelatedSoundFile, CExifTag::ETagAscii, 11);
+ TRAP( error, modify->SetTagL(EIfdExif, tag4, buf->Des()) );
+ if ( error != KErrNotSupported )
+ {
+ User::LeaveIfError( error );
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ buf = 0;
+
+ CleanupStack::PopAndDestroy( modify );
+
+ }
+
+// Exif.Modify.MEM.017
+// Test the behavior of the previous test cases in OOM situations.
+// Successfully operates or leaves with OOM error, without any memory leaks.
+void CExifModifyTest2::ExifModify017L()
+ {
+ // OOM in EXIF.MODIFY.001- EXIF.MODIFY.016
+ TInt error = KErrGeneral;
+ TInt i = 0;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify001L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify002L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify003L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify004L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify005L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify006L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify007L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify008L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify009L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify010L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify011L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify012L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify013L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify014L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify015L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify016L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify018L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifModify019L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/src/ExifReadTest.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,1680 @@
+/*
+* Copyright (c) 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: ExifLibTest
+*
+*/
+#include "ExifLibTestInc.h"
+
+
+// Exif.Read.001
+// Instantiate an Exif reader with valid Exif image
+// Created Exif reader instance is returned.
+void CExifReadTest::ExifRead001L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif);
+ if(!read)
+ User::Leave(KErrGeneral);
+ delete read;
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Read.002
+// Try to instantiate an Exif reader with invalid/corrupted Exif image
+// Leaves with proper error code.
+void CExifReadTest::ExifRead002L()
+ {
+ // Various invalid/ corrupted Exif images
+ HBufC8* exif = TUtils::ReadFileL(iFs, KInvalidExif1);
+ CleanupStack::PushL(exif);
+ CExifRead* read = 0;
+ TRAPD( error, read = CExifRead::NewL(*exif) );
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif2);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif) );
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::CreateDummyBufL(120000);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif) );
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif3);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif) );
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif4);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif) );
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif5);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif) );
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif7);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif) );
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif8);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif) );
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif9);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif) );
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif10);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif) );
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif11);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif) );
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif12);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif) );
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif13);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif) );
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ /* Supported, but uncompressed thumbnail is skipped */
+ exif = TUtils::ReadFileL(iFs, KNotSupportedExif1);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif) );
+ if ( ( error ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ /* Supported, but unsupported (uncompressed) thumbnail is skipped */
+ exif = TUtils::ReadFileL(iFs, KNotSupportedExif2);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif) );
+ if ( ( !error ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ // Corrupted image with too big (>64k) data
+ exif = TUtils::ReadFileL(iFs, KInvalidExif14);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif) );
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ }
+
+
+// Exif.Read.003
+// Retrieve a tag existing in the specified IFD from Exif data.
+// The requested tag instance (unmodifiable / const) is returned.
+void CExifReadTest::ExifRead003L()
+ {
+ // For each IFD.
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif);
+ CleanupStack::PushL(read);
+
+ const CExifTag* tag = read->GetTagL(EIfd0, KIdXResolution);
+ if(!tag)
+ User::Leave(KErrGeneral);
+
+ tag = read->GetTagL(EIfdExif, KIdColorSpace);
+ if(!tag)
+ User::Leave(KErrGeneral);
+
+ tag = read->GetTagL(EIfd1, KIdCompression);
+ if(!tag)
+ User::Leave(KErrGeneral);
+
+ tag = read->GetTagL(EIfdIntOp, 1);
+ if(!tag)
+ User::Leave(KErrGeneral);
+
+ tag = read->GetTagL(EIfdGps, KIdGpsVersion);
+ if(!tag)
+ User::Leave(KErrGeneral);
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.004
+// Try to retrieve a tag which doesn't exist in the Exif data.
+// Leaves with proper error code.
+void CExifReadTest::ExifRead004L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif);
+ CleanupStack::PushL(read);
+
+ const CExifTag* tag = NULL;
+ // IFD exists but tag doesn't exist,
+ TRAPD(error, tag = read->GetTagL(EIfd0, KIdArtist));
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+
+ // IFD doesn't exist
+ TRAP(error, tag = read->GetTagL(EIfdGps, KIdGpsVersion));
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.005
+// Try to retrieve a tag with invalid parameters.
+// Leaves with proper error code.
+void CExifReadTest::ExifRead005L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif);
+ CleanupStack::PushL(read);
+
+ const CExifTag* tag;
+ // Tag ID is invalid
+ TRAPD(error, tag = read->GetTagL(EIfdExif, 200));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+
+ // Tag cannot exist in the specified IFD.
+ TRAP(error, tag = read->GetTagL(EIfdGps, KIdImageDescription));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.006
+// Retrieve the IDs of tags from an IFD in Exif data.
+// Returns the tag IDs and the number of IDs
+void CExifReadTest::ExifRead006L()
+ {
+ // For each IFD.
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif);
+ CleanupStack::PushL(read);
+
+ TInt no = 0;
+ TUint16* tags = read->GetTagIdsL(EIfd0, no);
+ if((!tags) || (no != 14))
+ {
+ if(tags)
+ delete tags;
+ User::Leave(KErrGeneral);
+ }
+ delete tags;
+ tags = 0;
+
+ tags = read->GetTagIdsL(EIfdExif, no);
+ if((!tags) || (no != 41))
+ {
+ if(tags)
+ delete tags;
+ User::Leave(KErrGeneral);
+ }
+ delete tags;
+ tags = 0;
+
+ tags = read->GetTagIdsL(EIfd1, no);
+ if((!tags) || (no != 6))
+ {
+ if(tags)
+ delete tags;
+ User::Leave(KErrGeneral);
+ }
+ delete tags;
+ tags = 0;
+
+ tags = read->GetTagIdsL(EIfdIntOp, no);
+ if((!tags) || (no != 4))
+ {
+ if(tags)
+ delete tags;
+ User::Leave(KErrGeneral);
+ }
+ delete tags;
+ tags = 0;
+
+ tags = read->GetTagIdsL(EIfdGps, no);
+ if((!tags) || (no != 4))
+ {
+ if(tags)
+ delete tags;
+ User::Leave(KErrGeneral);
+ }
+ delete tags;
+ tags = 0;
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.007
+// Try to retrieve the IDs of tags from an IFD, which doesn't exist in Exif data.
+// Leaves with proper error code.
+void CExifReadTest::ExifRead007L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif);
+ CleanupStack::PushL(read);
+
+ TInt no = 0;
+ TUint16* tags = NULL;
+ TRAPD(error, tags = read->GetTagIdsL(EIfdGps, no));
+ if(tags)
+ delete tags;
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.008
+// Retrieve the types of IFDs included in Exif data.
+// Returns the IFD types and the number of IFDs.
+void CExifReadTest::ExifRead008L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif);
+ CleanupStack::PushL(read);
+
+ TInt no = 0;
+ TExifIfdType* ifds = read->GetIfdTypesL(no);
+ if((!ifds) && (no != 4))
+ {
+ if(ifds)
+ delete ifds;
+ User::Leave(KErrGeneral);
+ }
+ delete ifds;
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.009
+// Retrieve a copy of existing Exif thumbnail image from Exif data.
+// Returns the Exif thumbnail image.
+void CExifReadTest::ExifRead009L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif);
+ CleanupStack::PushL(read);
+
+ HBufC8* thumbnail = read->GetThumbnailL();
+ if(!thumbnail)
+ User::Leave(KErrGeneral);
+
+ delete thumbnail;
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.010
+// Try to retrieve a copy of Exif thumbnail image from Exif data that doesn't contain compressed Exif thumbnail image.
+// Leaves with proper error code.
+void CExifReadTest::ExifRead010L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KNoThumbnail);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif);
+ CleanupStack::PushL(read);
+
+ HBufC8* thumbnail = NULL;
+ TRAPD(error, thumbnail = read->GetThumbnailL());
+ if(thumbnail)
+ delete thumbnail;
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.011
+// Check if an IFD exists in Exif data.
+// Returns ETrue if specified IFD exists, EFalse otherwise.
+void CExifReadTest::ExifRead011L()
+ {
+ // For each IFD
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif);
+ CleanupStack::PushL(read);
+
+ // IFD exists,
+ if(!read->IfdExists(EIfd0))
+ User::Leave(KErrGeneral);
+ if(!read->IfdExists(EIfdExif))
+ User::Leave(KErrGeneral);
+ if(!read->IfdExists(EIfd1))
+ User::Leave(KErrGeneral);
+ if(!read->IfdExists(EIfdIntOp))
+ User::Leave(KErrGeneral);
+ // IFD doesn't exist.
+ if(read->IfdExists(EIfdGps))
+ User::Leave(KErrGeneral);
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.012
+// Check if a tag exists in the specified IFD of Exif data.
+// Returns ETrue if tag exists in the specified IFD, EFalse otherwise.
+void CExifReadTest::ExifRead012L()
+ {
+ // For each IFD;
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif);
+ CleanupStack::PushL(read);
+
+ // Tag exists in IFD,
+ if(!read->TagExists(KIdXResolution, EIfd0))
+ User::Leave(KErrGeneral);
+ if(!read->TagExists(KIdComponentsConfiguration, EIfdExif))
+ User::Leave(KErrGeneral);
+ if(!read->TagExists(1, EIfdIntOp))
+ User::Leave(KErrGeneral);
+ // IFD exists but tag doesn't exist,
+ if(read->TagExists(KIdCopyright, EIfd1))
+ User::Leave(KErrGeneral);
+ // IFD doesn't exist
+ if(read->TagExists(KIdGpsVersion, EIfdGps))
+ User::Leave(KErrGeneral);
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.013
+// Retrieve specific data using Get functions.
+// Returns the requested data.
+void CExifReadTest::ExifRead013L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif);
+ CleanupStack::PushL(read);
+
+ // For some Get functions.
+ HBufC8* data = read->GetImageDescriptionL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetMakeL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetDateTimeOriginalL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetTransferFunctionL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetRelatedSoundFileL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetModelL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetMakerNoteL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetIsoSpeedRatingsL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetDateTimeDigitizedL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetCopyrightL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+
+ TUint16 uInt16 = 0;
+ TUint32 uInt32 = 0;
+ TUint32 uInt32i = 0;
+ TInt32 int32 = 0;
+ TInt32 int32i = 0;
+ TInt8 int8 = 0;
+ TUint8 a1 = 0;
+ TUint8 a2 = 0;
+ TUint8 a3 = 0;
+ TUint8 a4 = 0;
+
+ User::LeaveIfError(read->GetExposureTime(uInt32, uInt32i));
+ if((uInt32 != 0) || (uInt32i != 0))
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetShutterSpeedValue(int32, int32i));
+ if((int32 != 0x00087383) || (int32i != 0x00010000))
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetBrightnessValue(int32, int32i));
+ if((int32 != 0) || (int32i != 1))
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetCustomRendered(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetGainControl(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetGpsVersion(uInt32));
+ if(uInt32 != 0x00000202)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetComponentsConfiguration(a1, a2, a3, a4));
+ if((a1 != 1) || (a2 != 2) || (a3 != 3 ) || (a4 != 0))
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetOrientation(uInt16));
+ if(uInt16 != 1)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetXResolution(uInt32, uInt32i));
+ if((uInt32 != 180) || (uInt32i != 1))
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetExifIfdPointer(uInt32));
+ if(uInt32 != 1798)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetFileSource(int8));
+ if(int8 != 3)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetSharpness(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetExifVersion(uInt32));
+ if(uInt32 != 0x30323230)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetThumbnailXResolution(uInt32, uInt32i));
+ if((uInt32 != 180) || (uInt32i != 1))
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetThumbnailCompression(uInt16));
+ if(uInt16 != 6)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetJpegInterchangeFormat(uInt32));
+ if(uInt32 != 2814)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetWhiteBalance(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetSceneCaptureType(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetSaturation(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetMeteringMode(uInt16));
+ if(uInt16 != 2)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetJpegInterchangeFormatLength(uInt32));
+ if(uInt32 != 5342)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetInteroperabilityIfdPointer(uInt32));
+ if(uInt32 != 2666)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetGpsInfoIfdPointer(uInt32));
+ if(uInt32 != 2612)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetFlashPixVersion(uInt32));
+ if(uInt32 != 0x30303130)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetExposureProgram(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetExposureMode(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetExposureBiasValue(int32, int32i));
+ if((int32 != 0) || (int32i != 3))
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetContrast(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetApertureValue(uInt32, uInt32i));
+ if((uInt32 != 262144) || (uInt32i != 65536))
+ User::Leave(KErrGeneral);
+
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.014
+// Try to retrieve specific data that is not present in the Exif data using Get functions.
+// Leaves with or returns proper error code.
+void CExifReadTest::ExifRead014L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KNoThumbnail);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif);
+ CleanupStack::PushL(read);
+
+ // For some Get functions.
+ HBufC8* data = NULL;
+ TRAPD(error, data = read->GetSoftwareL());
+ if(data)
+ delete data;
+ data = 0;
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+ TRAP(error, data = read->GetUserCommentL());
+ if(data)
+ delete data;
+ data = 0;
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+
+ TUint16 uInt16 = 0;
+ TUint32 uInt32 = 0;
+ TUint32 uInt32i = 0;
+ TInt8 int8 = 0;
+ error = read->GetLightSource(uInt16);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+ error = read->GetFileSource(int8);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+ error = read->GetDigitalZoomRatio(uInt32, uInt32i);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+ error = read->GetThumbnailCompression(uInt16);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+ error = read->GetJpegInterchangeFormat(uInt32);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Read.016
+// Retrieve the Exif APP1 segment.
+// Returns the whole Exif APP1 segment.
+void CExifReadTest::ExifRead016L()
+ {
+
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif);
+ CleanupStack::PushL(read);
+
+ HBufC8* appSegment = read->GetExifAppSegmentL();
+ CleanupStack::PushL( appSegment );
+ if ( appSegment->Length() != 12670 )
+ {
+ User::Leave( KErrGeneral );
+ }
+ if ( *appSegment->Ptr() != 0xff )
+ {
+ User::Leave( KErrGeneral );
+ }
+ if ( *( appSegment->Ptr() + appSegment->Length() - 1 ) != 0xd9 )
+ {
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( appSegment );
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KFullExif);
+ CleanupStack::PushL(exif);
+ read = CExifRead::NewL(*exif);
+ CleanupStack::PushL(read);
+
+ appSegment = read->GetExifAppSegmentL();
+ CleanupStack::PushL( appSegment );
+ if ( appSegment->Length() != 8166 )
+ {
+ User::Leave( KErrGeneral );
+ }
+ if ( *appSegment->Ptr() != 0xff )
+ {
+ User::Leave( KErrGeneral );
+ }
+ if ( *( appSegment->Ptr() + appSegment->Length() - 1 ) != 0xd9 )
+ {
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( appSegment );
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Read.MEM.015
+// Test the behavior of the previous test cases in OOM situations.
+// Successfully operates or leaves with OOM error, without any memory leaks.
+void CExifReadTest::ExifRead015L()
+ {
+ // OOM in EXIF.READ.001- EXIF.READ.014
+ TInt error = KErrGeneral;
+ TInt i = 0;
+
+ RDebug::Print(_L("ExifRead001L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead001L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead002L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead002L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead003L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead003L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead004L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead004L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead005L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead005L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead006L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead006L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead007L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead007L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead008L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead008L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead009L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead009L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead010L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead010L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead011L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead011L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead012L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead012L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead013L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead013L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead014L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead014L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead016L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead016L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ }
+
+// Exif.Read.Fast.017
+// Instantiate an Exif reader with valid Exif image
+// Created Exif reader instance is returned.
+void CExifReadTest::ExifRead017L()
+ {
+ RDebug::Print(_L("1.Open file KFullExif..."));
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif);
+ CleanupStack::PushL(exif);
+
+ RDebug::Print(_L("Instantiate CExifRead..."));
+ CExifRead* read = CExifRead::NewL(*exif);
+ if(!read)
+ User::Leave(KErrGeneral);
+ CleanupStack::PushL(read);
+
+ RDebug::Print(_L("Read thumbnail..."));
+ HBufC8* thumbnail = read->GetThumbnailL();
+ CleanupStack::PushL(thumbnail);
+
+ if(thumbnail)
+ RDebug::Print(_L("thumbnail ok, size %d ..."), thumbnail->Des().Size());
+ else
+ RDebug::Print(_L("no thumbnail..."));
+
+ RDebug::Print(_L("delete buffers..."));
+ CleanupStack::PopAndDestroy(thumbnail);
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+
+ RDebug::Print(_L("2.Open file KFullExif 64k..."));
+ exif = TUtils::ReadFileL(iFs, KFullExif, 65536);
+ CleanupStack::PushL(exif);
+
+ RDebug::Print(_L("Instantiate CExifRead no jpeg..."));
+ read = CExifRead::NewL(*exif, CExifRead::ENoJpeg);
+ if(!read)
+ User::Leave(KErrGeneral);
+ CleanupStack::PushL(read);
+
+ RDebug::Print(_L("Read thumbnail..."));
+ thumbnail = read->GetThumbnailL();
+ CleanupStack::PushL(thumbnail);
+
+ if(thumbnail)
+ RDebug::Print(_L("thumbnail ok, size %d ..."), thumbnail->Des().Size());
+ else
+ RDebug::Print(_L("no thumbnail..."));
+ RDebug::Print(_L("delete buffers..."));
+ CleanupStack::PopAndDestroy(thumbnail);
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+
+ RDebug::Print(_L("3.Open file KFullExif3mpix..."));
+ exif = TUtils::ReadFileL(iFs, KFullExif3mpix);
+ CleanupStack::PushL(exif);
+
+ RDebug::Print(_L("Instantiate CExifRead..."));
+ read = CExifRead::NewL(*exif);
+ if(!read)
+ User::Leave(KErrGeneral);
+ CleanupStack::PushL(read);
+
+ RDebug::Print(_L("Read thumbnail..."));
+ thumbnail = read->GetThumbnailL();
+ CleanupStack::PushL(thumbnail);
+
+ if(thumbnail)
+ RDebug::Print(_L("thumbnail ok, size %d ..."), thumbnail->Des().Size());
+ else
+ RDebug::Print(_L("no thumbnail..."));
+ RDebug::Print(_L("delete buffers..."));
+ CleanupStack::PopAndDestroy(thumbnail);
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+
+ RDebug::Print(_L("4.Open file KFullExif3mpix 64k..."));
+ exif = TUtils::ReadFileL(iFs, KFullExif3mpix, 65536);
+ CleanupStack::PushL(exif);
+
+ RDebug::Print(_L("Instantiate CExifRead no jpeg..."));
+ read = CExifRead::NewL(*exif, CExifRead::ENoJpeg);
+ if(!read)
+ User::Leave(KErrGeneral);
+ CleanupStack::PushL(read);
+
+ RDebug::Print(_L("Read thumbnail..."));
+ thumbnail = read->GetThumbnailL();
+ CleanupStack::PushL(thumbnail);
+
+ if(thumbnail)
+ RDebug::Print(_L("thumbnail ok, size %d ..."), thumbnail->Des().Size());
+ else
+ RDebug::Print(_L("no thumbnail..."));
+
+ RDebug::Print(_L("delete buffers and exit..."));
+ CleanupStack::PopAndDestroy(thumbnail);
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Read.NOTAGCHECKING.018
+// Instantiate an Exif reader with Exif image that has unknown tags or missing mandatory tags
+// Created Exif reader instance is returned.
+void CExifReadTest::ExifRead018L()
+ {
+ // file 0
+ RDebug::Print(_L("0.Open file KNoTagChk_IMG_AN19..."));
+ HBufC8* exif = TUtils::ReadFileL(iFs, KNoTagChk_IMG_AN19);
+ CleanupStack::PushL(exif);
+
+ RDebug::Print(_L("Instantiate CExifRead and ignore unknown/missing tags..."));
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoTagChecking);
+ if(!read)
+ User::Leave(KErrGeneral);
+ CleanupStack::PushL(read);
+
+ RDebug::Print(_L("Read thumbnail..."));
+ HBufC8* thumbnail = read->GetThumbnailL();
+ CleanupStack::PushL(thumbnail);
+
+ if(thumbnail)
+ RDebug::Print(_L("thumbnail ok, size %d ..."), thumbnail->Des().Size());
+ else
+ RDebug::Print(_L("no thumbnail..."));
+
+ // Save Thumbnail
+ /*
+ if(thumbnail)
+ {
+ RFile file;
+ TBuf<255> fileName;
+
+ fileName.Copy(_L("c:\\NoTagChecking_thumbnail.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+ RDebug::Print(_L("File opened"));
+ file.Write(thumbnail->Des());
+ RDebug::Print(_L("File written."));
+ file.Close();
+ }
+ */
+ TUtils::GetAllTagsTestL( read, KNoTagChk_IMG_AN19 );
+
+ RDebug::Print(_L("delete buffers..."));
+ CleanupStack::PopAndDestroy(thumbnail);
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+
+ // File 1
+ RDebug::Print(_L("1.Open file KNoTagChk_Original..."));
+ exif = TUtils::ReadFileL(iFs, KNoTagChk_Original);
+ CleanupStack::PushL(exif);
+
+ RDebug::Print(_L("Instantiate CExifRead and ignore unknown/missing tags..."));
+ read = CExifRead::NewL(*exif, CExifRead::ENoTagChecking);
+ if(!read)
+ User::Leave(KErrGeneral);
+ CleanupStack::PushL(read);
+
+ RDebug::Print(_L("Read thumbnail..."));
+ thumbnail = read->GetThumbnailL();
+ CleanupStack::PushL(thumbnail);
+
+ if(thumbnail)
+ RDebug::Print(_L("thumbnail ok, size %d ..."), thumbnail->Des().Size());
+ else
+ RDebug::Print(_L("no thumbnail..."));
+
+ // Save Thumbnail
+ /*
+ if(thumbnail)
+ {
+ RFile file;
+ TBuf<255> fileName;
+
+ fileName.Copy(_L("c:\\NoTagChecking_thumbnail.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+ RDebug::Print(_L("File opened"));
+ file.Write(thumbnail->Des());
+ RDebug::Print(_L("File written."));
+ file.Close();
+ }
+ */
+ TUtils::GetAllTagsTestL( read, KNoTagChk_Original );
+
+ RDebug::Print(_L("delete buffers..."));
+ CleanupStack::PopAndDestroy(thumbnail);
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+
+ // File 2
+ RDebug::Print(_L("1.Open file KtagInWrongIfd..."));
+ exif = TUtils::ReadFileL(iFs, KtagInWrongIfd);
+ CleanupStack::PushL(exif);
+
+ RDebug::Print(_L("Instantiate CExifRead and ignore unknown/missing tags..."));
+ read = CExifRead::NewL(*exif, CExifRead::ENoTagChecking);
+ if(!read)
+ User::Leave(KErrGeneral);
+ CleanupStack::PushL(read);
+
+ RDebug::Print(_L("Read thumbnail..."));
+ thumbnail = read->GetThumbnailL();
+ CleanupStack::PushL(thumbnail);
+
+ if(thumbnail)
+ RDebug::Print(_L("thumbnail ok, size %d ..."), thumbnail->Des().Size());
+ else
+ RDebug::Print(_L("no thumbnail..."));
+
+ // Save Thumbnail
+ /*
+ if(thumbnail)
+ {
+ RFile file;
+ TBuf<255> fileName;
+
+ fileName.Copy(_L("c:\\KtagInWrongIfd_thumbnail.jpg"));
+ if(file.Open(iFs, fileName, EFileWrite) != KErrNone)
+ User::LeaveIfError(file.Create(iFs, fileName, EFileWrite));
+ RDebug::Print(_L("File opened"));
+ file.Write(thumbnail->Des());
+ RDebug::Print(_L("File written."));
+ file.Close();
+ }
+ */
+
+ RDebug::Print(_L("delete buffers..."));
+ CleanupStack::PopAndDestroy(thumbnail);
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+
+
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/src/ExifReadTest100.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,1527 @@
+/*
+* Copyright (c) 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: ExifLibTest
+*
+*/
+#include "ExifLibTestInc.h"
+
+// Test cases modified for no jpeg parsing option
+
+// Exif.Read.101
+// Instantiate an Exif reader with valid Exif image
+// Created Exif reader instance is returned.
+void CExifReadTest::ExifRead101L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg);
+ if(!read)
+ User::Leave(KErrGeneral);
+ delete read;
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Read.102
+// Try to instantiate an Exif reader with invalid/corrupted Exif image
+// Leaves with proper error code or doesn't detect the error
+void CExifReadTest::ExifRead102L()
+ {
+ // Various invalid/ corrupted Exif images
+ HBufC8* exif = TUtils::ReadFileL(iFs, KInvalidExif1, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = 0;
+ TRAPD( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif2, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::CreateDummyBufL(120000);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg) );
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif3, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif4, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif5, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif7, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif8, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif9, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif10, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif11, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif12, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif13, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ /* Supported, but uncompressed thumbnail is skipped */
+ exif = TUtils::ReadFileL(iFs, KNotSupportedExif1, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg) );
+ if ( ( error != KErrNone ) || ( !read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ /* Supported, but unsupported (uncompressed) thumbnail is skipped */
+ exif = TUtils::ReadFileL(iFs, KNotSupportedExif2, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg) );
+ if ( ( error != KErrCorrupt ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ // Corrupted with more than 64k tag data
+ exif = TUtils::ReadFileL(iFs, KInvalidExif14, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ }
+
+
+// Exif.Read.103
+// Retrieve a tag existing in the specified IFD from Exif data.
+// The requested tag instance (unmodifiable / const) is returned.
+void CExifReadTest::ExifRead103L()
+ {
+ // For each IFD.
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg);
+ CleanupStack::PushL(read);
+
+ const CExifTag* tag = read->GetTagL(EIfd0, KIdXResolution);
+ if(!tag)
+ User::Leave(KErrGeneral);
+
+ tag = read->GetTagL(EIfdExif, KIdColorSpace);
+ if(!tag)
+ User::Leave(KErrGeneral);
+
+ tag = read->GetTagL(EIfd1, KIdCompression);
+ if(!tag)
+ User::Leave(KErrGeneral);
+
+ tag = read->GetTagL(EIfdIntOp, 1);
+ if(!tag)
+ User::Leave(KErrGeneral);
+
+ tag = read->GetTagL(EIfdGps, KIdGpsVersion);
+ if(!tag)
+ User::Leave(KErrGeneral);
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.104
+// Try to retrieve a tag which doesn't exist in the Exif data.
+// Leaves with proper error code.
+void CExifReadTest::ExifRead104L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg);
+ CleanupStack::PushL(read);
+
+ const CExifTag* tag = NULL;
+ // IFD exists but tag doesn't exist,
+ TRAPD(error, tag = read->GetTagL(EIfd0, KIdArtist));
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+
+ // IFD doesn't exist
+ TRAP(error, tag = read->GetTagL(EIfdGps, KIdGpsVersion));
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.105
+// Try to retrieve a tag with invalid parameters.
+// Leaves with proper error code.
+void CExifReadTest::ExifRead105L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg);
+ CleanupStack::PushL(read);
+
+ const CExifTag* tag;
+ // Tag ID is invalid
+ TRAPD(error, tag = read->GetTagL(EIfdExif, 200));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+
+ // Tag cannot exist in the specified IFD.
+ TRAP(error, tag = read->GetTagL(EIfdGps, KIdImageDescription));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.106
+// Retrieve the IDs of tags from an IFD in Exif data.
+// Returns the tag IDs and the number of IDs
+void CExifReadTest::ExifRead106L()
+ {
+ // For each IFD.
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg);
+ CleanupStack::PushL(read);
+
+ TInt no = 0;
+ TUint16* tags = read->GetTagIdsL(EIfd0, no);
+ if((!tags) || (no != 14))
+ {
+ if(tags)
+ delete tags;
+ User::Leave(KErrGeneral);
+ }
+ delete tags;
+ tags = 0;
+
+ tags = read->GetTagIdsL(EIfdExif, no);
+ if((!tags) || (no != 41))
+ {
+ if(tags)
+ delete tags;
+ User::Leave(KErrGeneral);
+ }
+ delete tags;
+ tags = 0;
+
+ tags = read->GetTagIdsL(EIfd1, no);
+ if((!tags) || (no != 6))
+ {
+ if(tags)
+ delete tags;
+ User::Leave(KErrGeneral);
+ }
+ delete tags;
+ tags = 0;
+
+ tags = read->GetTagIdsL(EIfdIntOp, no);
+ if((!tags) || (no != 4))
+ {
+ if(tags)
+ delete tags;
+ User::Leave(KErrGeneral);
+ }
+ delete tags;
+ tags = 0;
+
+ tags = read->GetTagIdsL(EIfdGps, no);
+ if((!tags) || (no != 4))
+ {
+ if(tags)
+ delete tags;
+ User::Leave(KErrGeneral);
+ }
+ delete tags;
+ tags = 0;
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.107
+// Try to retrieve the IDs of tags from an IFD, which doesn't exist in Exif data.
+// Leaves with proper error code.
+void CExifReadTest::ExifRead107L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg);
+ CleanupStack::PushL(read);
+
+ TInt no = 0;
+ TUint16* tags = NULL;
+ TRAPD(error, tags = read->GetTagIdsL(EIfdGps, no));
+ if(tags)
+ delete tags;
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.108
+// Retrieve the types of IFDs included in Exif data.
+// Returns the IFD types and the number of IFDs.
+void CExifReadTest::ExifRead108L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg);
+ CleanupStack::PushL(read);
+
+ TInt no = 0;
+ TExifIfdType* ifds = read->GetIfdTypesL(no);
+ if((!ifds) && (no != 4))
+ {
+ if(ifds)
+ delete ifds;
+ User::Leave(KErrGeneral);
+ }
+ delete ifds;
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.109
+// Retrieve a copy of existing Exif thumbnail image from Exif data.
+// Returns the Exif thumbnail image.
+void CExifReadTest::ExifRead109L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg);
+ CleanupStack::PushL(read);
+
+ HBufC8* thumbnail = read->GetThumbnailL();
+ if(!thumbnail)
+ User::Leave(KErrGeneral);
+
+ delete thumbnail;
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.110
+// Try to retrieve a copy of Exif thumbnail image from Exif data that doesn't contain compressed Exif thumbnail image.
+// Leaves with proper error code.
+void CExifReadTest::ExifRead110L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KNoThumbnail, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg);
+ CleanupStack::PushL(read);
+
+ HBufC8* thumbnail = NULL;
+ TRAPD(error, thumbnail = read->GetThumbnailL());
+ if(thumbnail)
+ delete thumbnail;
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.111
+// Check if an IFD exists in Exif data.
+// Returns ETrue if specified IFD exists, EFalse otherwise.
+void CExifReadTest::ExifRead111L()
+ {
+ // For each IFD
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg);
+ CleanupStack::PushL(read);
+
+ // IFD exists,
+ if(!read->IfdExists(EIfd0))
+ User::Leave(KErrGeneral);
+ if(!read->IfdExists(EIfdExif))
+ User::Leave(KErrGeneral);
+ if(!read->IfdExists(EIfd1))
+ User::Leave(KErrGeneral);
+ if(!read->IfdExists(EIfdIntOp))
+ User::Leave(KErrGeneral);
+ // IFD doesn't exist.
+ if(read->IfdExists(EIfdGps))
+ User::Leave(KErrGeneral);
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.112
+// Check if a tag exists in the specified IFD of Exif data.
+// Returns ETrue if tag exists in the specified IFD, EFalse otherwise.
+void CExifReadTest::ExifRead112L()
+ {
+ // For each IFD;
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg);
+ CleanupStack::PushL(read);
+
+ // Tag exists in IFD,
+ if(!read->TagExists(KIdXResolution, EIfd0))
+ User::Leave(KErrGeneral);
+ if(!read->TagExists(KIdComponentsConfiguration, EIfdExif))
+ User::Leave(KErrGeneral);
+ if(!read->TagExists(1, EIfdIntOp))
+ User::Leave(KErrGeneral);
+ // IFD exists but tag doesn't exist,
+ if(read->TagExists(KIdCopyright, EIfd1))
+ User::Leave(KErrGeneral);
+ // IFD doesn't exist
+ if(read->TagExists(KIdGpsVersion, EIfdGps))
+ User::Leave(KErrGeneral);
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.113
+// Retrieve specific data using Get functions.
+// Returns the requested data.
+void CExifReadTest::ExifRead113L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg);
+ CleanupStack::PushL(read);
+
+ // For some Get functions.
+ HBufC8* data = read->GetImageDescriptionL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetMakeL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetDateTimeOriginalL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetTransferFunctionL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetRelatedSoundFileL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetModelL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetMakerNoteL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetIsoSpeedRatingsL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetDateTimeDigitizedL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetCopyrightL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+
+ TUint16 uInt16 = 0;
+ TUint32 uInt32 = 0;
+ TUint32 uInt32i = 0;
+ TInt32 int32 = 0;
+ TInt32 int32i = 0;
+ TInt8 int8 = 0;
+ TUint8 a1 = 0;
+ TUint8 a2 = 0;
+ TUint8 a3 = 0;
+ TUint8 a4 = 0;
+
+ User::LeaveIfError(read->GetExposureTime(uInt32, uInt32i));
+ if((uInt32 != 0) || (uInt32i != 0))
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetShutterSpeedValue(int32, int32i));
+ if((int32 != 0x00087383) || (int32i != 0x00010000))
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetBrightnessValue(int32, int32i));
+ if((int32 != 0) || (int32i != 1))
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetCustomRendered(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetGainControl(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetGpsVersion(uInt32));
+ if(uInt32 != 0x00000202)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetComponentsConfiguration(a1, a2, a3, a4));
+ if((a1 != 1) || (a2 != 2) || (a3 != 3 ) || (a4 != 0))
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetOrientation(uInt16));
+ if(uInt16 != 1)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetXResolution(uInt32, uInt32i));
+ if((uInt32 != 180) || (uInt32i != 1))
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetExifIfdPointer(uInt32));
+ if(uInt32 != 1798)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetFileSource(int8));
+ if(int8 != 3)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetSharpness(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetExifVersion(uInt32));
+ if(uInt32 != 0x30323230)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetThumbnailXResolution(uInt32, uInt32i));
+ if((uInt32 != 180) || (uInt32i != 1))
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetThumbnailCompression(uInt16));
+ if(uInt16 != 6)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetJpegInterchangeFormat(uInt32));
+ if(uInt32 != 2814)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetWhiteBalance(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetSceneCaptureType(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetSaturation(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetMeteringMode(uInt16));
+ if(uInt16 != 2)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetJpegInterchangeFormatLength(uInt32));
+ if(uInt32 != 5342)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetInteroperabilityIfdPointer(uInt32));
+ if(uInt32 != 2666)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetGpsInfoIfdPointer(uInt32));
+ if(uInt32 != 2612)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetFlashPixVersion(uInt32));
+ if(uInt32 != 0x30303130)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetExposureProgram(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetExposureMode(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetExposureBiasValue(int32, int32i));
+ if((int32 != 0) || (int32i != 3))
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetContrast(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetApertureValue(uInt32, uInt32i));
+ if((uInt32 != 262144) || (uInt32i != 65536))
+ User::Leave(KErrGeneral);
+
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.114
+// Try to retrieve specific data that is not present in the Exif data using Get functions.
+// Leaves with or returns proper error code.
+void CExifReadTest::ExifRead114L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KNoThumbnail, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg);
+ CleanupStack::PushL(read);
+
+ // For some Get functions.
+ HBufC8* data = NULL;
+ TRAPD(error, data = read->GetSoftwareL());
+ if(data)
+ delete data;
+ data = 0;
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+ TRAP(error, data = read->GetUserCommentL());
+ if(data)
+ delete data;
+ data = 0;
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+
+ TUint16 uInt16 = 0;
+ TUint32 uInt32 = 0;
+ TUint32 uInt32i = 0;
+ TInt8 int8 = 0;
+ error = read->GetLightSource(uInt16);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+ error = read->GetFileSource(int8);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+ error = read->GetDigitalZoomRatio(uInt32, uInt32i);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+ error = read->GetThumbnailCompression(uInt16);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+ error = read->GetJpegInterchangeFormat(uInt32);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Read.116
+// Retrieve the Exif APP1 segment.
+// Returns the whole Exif APP1 segment.
+void CExifReadTest::ExifRead116L()
+ {
+
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg);
+ CleanupStack::PushL(read);
+
+ HBufC8* appSegment = read->GetExifAppSegmentL();
+ CleanupStack::PushL( appSegment );
+ if ( appSegment->Length() != 12670 )
+ {
+ User::Leave( KErrGeneral );
+ }
+ if ( *appSegment->Ptr() != 0xff )
+ {
+ User::Leave( KErrGeneral );
+ }
+ if ( *( appSegment->Ptr() + appSegment->Length() - 1 ) != 0xd9 )
+ {
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( appSegment );
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KFullExif, 65536);
+ CleanupStack::PushL(exif);
+ read = CExifRead::NewL(*exif, CExifRead::ENoJpeg);
+ CleanupStack::PushL(read);
+
+ appSegment = read->GetExifAppSegmentL();
+ CleanupStack::PushL( appSegment );
+ if ( appSegment->Length() != 8166 )
+ {
+ User::Leave( KErrGeneral );
+ }
+ if ( *appSegment->Ptr() != 0xff )
+ {
+ User::Leave( KErrGeneral );
+ }
+ if ( *( appSegment->Ptr() + appSegment->Length() - 1 ) != 0xd9 )
+ {
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( appSegment );
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Read.115
+// Test the behavior of the previous test cases in OOM situations.
+// Successfully operates or leaves with OOM error, without any memory leaks.
+void CExifReadTest::ExifRead115L()
+ {
+ // OOM in EXIF.READ.101- EXIF.READ.116
+ TInt error = KErrGeneral;
+ TInt i = 0;
+
+ RDebug::Print(_L("ExifRead101L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead101L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print((_L("ExifRead115L() TRAP error=%d")),error);
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead102L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+// RDebug::Print((_L("ExifRead102L() memory test i=%d")),i);
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead102L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead115L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead103L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead103L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead115L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead104L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead104L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead115L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead105L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead105L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead115L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead106L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead106L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead115L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead107L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead107L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead115L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead108L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead108L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead115L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead109L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead109L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead115L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead110L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead110L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead115L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead111L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead111L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead115L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead112L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead112L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead115L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead113L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead113L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead115L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead114L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead114L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead115L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead116L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead116L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead115L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/src/ExifReadTest200.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,1678 @@
+/*
+* Copyright (c) 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: ExifLibTest
+*
+*/
+#include "ExifLibTestInc.h"
+
+// Test cases modified for no jpeg parsing and no tag validity checking options
+
+// Exif.Read.201
+// Instantiate an Exif reader with valid Exif image
+// Created Exif reader instance is returned.
+void CExifReadTest::ExifRead201L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking );
+ if(!read)
+ User::Leave(KErrGeneral);
+ delete read;
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Read.202
+// Try to instantiate an Exif reader with invalid/corrupted Exif image
+// Leaves with proper error code or doesn't detect the error
+void CExifReadTest::ExifRead202L()
+ {
+ // Various invalid/ corrupted Exif images
+ HBufC8* exif = TUtils::ReadFileL(iFs, KInvalidExif1, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = 0;
+ TRAPD( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ else if( read )
+ {
+ CleanupStack::PushL(read);
+ TUtils::GetAllTagsTestL( read, KInvalidExif1 );
+ CleanupStack::Pop(read);
+ }
+ else
+ {
+ RDebug::Print(_L("CExifReadTest::ExifRead202L(): KInvalidExif1 return no buffer"));
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif2, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ else if( read )
+ {
+ CleanupStack::PushL(read);
+ TUtils::GetAllTagsTestL( read, KInvalidExif2 );
+ CleanupStack::Pop(read);
+ }
+ else
+ {
+ RDebug::Print(_L("CExifReadTest::ExifRead202L(): KInvalidExif2 return no buffer"));
+ }
+
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::CreateDummyBufL(120000);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking) );
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif3, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ else if( read )
+ {
+ CleanupStack::PushL(read);
+ TUtils::GetAllTagsTestL( read, KInvalidExif3 );
+ CleanupStack::Pop(read);
+ }
+ else
+ {
+ RDebug::Print(_L("CExifReadTest::ExifRead202L(): KInvalidExif3 return no buffer"));
+ }
+
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif4, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ else if( read )
+ {
+ CleanupStack::PushL(read);
+ TUtils::GetAllTagsTestL( read, KInvalidExif4 );
+ CleanupStack::Pop(read);
+ }
+ else
+ {
+ RDebug::Print(_L("CExifReadTest::ExifRead202L(): KInvalidExif4 return no buffer"));
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif5, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ else if( read )
+ {
+ CleanupStack::PushL(read);
+ TUtils::GetAllTagsTestL( read, KInvalidExif5 );
+ CleanupStack::Pop(read);
+ }
+ else
+ {
+ RDebug::Print(_L("CExifReadTest::ExifRead202L(): KInvalidExif5 return no buffer"));
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif7, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ else if( read )
+ {
+ CleanupStack::PushL(read);
+ TUtils::GetAllTagsTestL( read, KInvalidExif7 );
+ CleanupStack::Pop(read);
+ }
+ else
+ {
+ RDebug::Print(_L("CExifReadTest::ExifRead202L(): KInvalidExif7 return no buffer"));
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif8, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ else if( read )
+ {
+ CleanupStack::PushL(read);
+ TUtils::GetAllTagsTestL( read, KInvalidExif8 );
+ CleanupStack::Pop(read);
+ }
+ else
+ {
+ RDebug::Print(_L("CExifReadTest::ExifRead202L(): KInvalidExif8 return no buffer"));
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif9, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ else if( read )
+ {
+ CleanupStack::PushL(read);
+ TUtils::GetAllTagsTestL( read, KInvalidExif9 );
+ CleanupStack::Pop(read);
+ }
+ else
+ {
+ RDebug::Print(_L("CExifReadTest::ExifRead202L(): KInvalidExif9 return no buffer"));
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif10, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ else if( read )
+ {
+ CleanupStack::PushL(read);
+ TUtils::GetAllTagsTestL( read, KInvalidExif10 );
+ CleanupStack::Pop(read);
+ }
+ else
+ {
+ RDebug::Print(_L("CExifReadTest::ExifRead202L(): KInvalidExif10 return no buffer"));
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif11, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ else if( read )
+ {
+ CleanupStack::PushL(read);
+ TUtils::GetAllTagsTestL( read, KInvalidExif11 );
+ CleanupStack::Pop(read);
+ }
+ else
+ {
+ RDebug::Print(_L("CExifReadTest::ExifRead202L(): KInvalidExif11 return no buffer"));
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif12, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ else if( read )
+ {
+ CleanupStack::PushL(read);
+ TUtils::GetAllTagsTestL( read, KInvalidExif12 );
+ CleanupStack::Pop(read);
+ }
+ else
+ {
+ RDebug::Print(_L("CExifReadTest::ExifRead202L(): KInvalidExif12 return no buffer"));
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KInvalidExif13, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ else if( read )
+ {
+ CleanupStack::PushL(read);
+ TUtils::GetAllTagsTestL( read, KInvalidExif13 );
+ CleanupStack::Pop(read);
+ }
+ else
+ {
+ RDebug::Print(_L("CExifReadTest::ExifRead202L(): KInvalidExif13 return no buffer"));
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ /* Supported, but uncompressed thumbnail is skipped */
+ exif = TUtils::ReadFileL(iFs, KNotSupportedExif1, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking) );
+ if ( ( error != KErrNone ) || ( !read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ else if( read )
+ {
+ CleanupStack::PushL(read);
+ TUtils::GetAllTagsTestL( read, KNotSupportedExif1 );
+ CleanupStack::Pop(read);
+ }
+ else
+ {
+ RDebug::Print(_L("CExifReadTest::ExifRead202L(): KNotSupportedExif1 return no buffer"));
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ /* Supported, but unsupported (uncompressed) thumbnail is skipped */
+ exif = TUtils::ReadFileL(iFs, KNotSupportedExif2, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking) );
+ if ( ( error != KErrNone ) || ( !read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ else if( read )
+ {
+ CleanupStack::PushL(read);
+ TUtils::GetAllTagsTestL( read, KNotSupportedExif2 );
+ CleanupStack::Pop(read);
+ }
+ else
+ {
+ RDebug::Print(_L("CExifReadTest::ExifRead202L(): KNotSupportedExif2 return no buffer"));
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+
+ // Corrupted over 64k tag data
+ exif = TUtils::ReadFileL(iFs, KInvalidExif14, 65536);
+ CleanupStack::PushL(exif);
+ TRAP( error, read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking) );
+ if ( error ) // jpeg error detected
+ {
+ if ( ( error != KErrCorrupt ) || ( read ) )
+ {
+ if ( read )
+ {
+ delete read;
+ }
+ if ( error )
+ {
+ User::Leave( error );
+ }
+ User::Leave(KErrGeneral);
+ }
+ }
+ else if( read )
+ {
+ CleanupStack::PushL(read);
+ TUtils::GetAllTagsTestL( read, KInvalidExif14 );
+ CleanupStack::Pop(read);
+ }
+ else
+ {
+ RDebug::Print(_L("CExifReadTest::ExifRead202L(): KInvalidExif14 return no buffer"));
+ }
+ delete read;
+ read = 0;
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.203
+// Retrieve a tag existing in the specified IFD from Exif data.
+// The requested tag instance (unmodifiable / const) is returned.
+void CExifReadTest::ExifRead203L()
+ {
+ // For each IFD.
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking);
+ CleanupStack::PushL(read);
+
+ const CExifTag* tag = read->GetTagL(EIfd0, KIdXResolution);
+ if(!tag)
+ User::Leave(KErrGeneral);
+
+ tag = read->GetTagL(EIfdExif, KIdColorSpace);
+ if(!tag)
+ User::Leave(KErrGeneral);
+
+ tag = read->GetTagL(EIfd1, KIdCompression);
+ if(!tag)
+ User::Leave(KErrGeneral);
+
+ tag = read->GetTagL(EIfdIntOp, 1);
+ if(!tag)
+ User::Leave(KErrGeneral);
+
+ tag = read->GetTagL(EIfdGps, KIdGpsVersion);
+ if(!tag)
+ User::Leave(KErrGeneral);
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.204
+// Try to retrieve a tag which doesn't exist in the Exif data.
+// Leaves with proper error code.
+void CExifReadTest::ExifRead204L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking);
+ CleanupStack::PushL(read);
+
+ const CExifTag* tag = NULL;
+ // IFD exists but tag doesn't exist,
+ TRAPD(error, tag = read->GetTagL(EIfd0, KIdArtist));
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+
+ // IFD doesn't exist
+ TRAP(error, tag = read->GetTagL(EIfdGps, KIdGpsVersion));
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.205
+// Try to retrieve a tag with invalid parameters.
+// Leaves with proper error code.
+void CExifReadTest::ExifRead205L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking);
+ CleanupStack::PushL(read);
+
+ const CExifTag* tag;
+ // Tag ID is invalid
+ TRAPD(error, tag = read->GetTagL(EIfdExif, 200));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+
+ // Tag cannot exist in the specified IFD.
+ TRAP(error, tag = read->GetTagL(EIfdGps, KIdImageDescription));
+ if(error != KErrNotSupported)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.206
+// Retrieve the IDs of tags from an IFD in Exif data.
+// Returns the tag IDs and the number of IDs
+void CExifReadTest::ExifRead206L()
+ {
+ // For each IFD.
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking);
+ CleanupStack::PushL(read);
+
+ TInt no = 0;
+ TUint16* tags = read->GetTagIdsL(EIfd0, no);
+ if((!tags) || (no != 14))
+ {
+ if(tags)
+ delete tags;
+ User::Leave(KErrGeneral);
+ }
+ delete tags;
+ tags = 0;
+
+ tags = read->GetTagIdsL(EIfdExif, no);
+ if((!tags) || (no != 41))
+ {
+ if(tags)
+ delete tags;
+ User::Leave(KErrGeneral);
+ }
+ delete tags;
+ tags = 0;
+
+ tags = read->GetTagIdsL(EIfd1, no);
+ if((!tags) || (no != 6))
+ {
+ if(tags)
+ delete tags;
+ User::Leave(KErrGeneral);
+ }
+ delete tags;
+ tags = 0;
+
+ tags = read->GetTagIdsL(EIfdIntOp, no);
+ if((!tags) || (no != 4))
+ {
+ if(tags)
+ delete tags;
+ User::Leave(KErrGeneral);
+ }
+ delete tags;
+ tags = 0;
+
+ tags = read->GetTagIdsL(EIfdGps, no);
+ if((!tags) || (no != 4))
+ {
+ if(tags)
+ delete tags;
+ User::Leave(KErrGeneral);
+ }
+ delete tags;
+ tags = 0;
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.207
+// Try to retrieve the IDs of tags from an IFD, which doesn't exist in Exif data.
+// Leaves with proper error code.
+void CExifReadTest::ExifRead207L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking);
+ CleanupStack::PushL(read);
+
+ TInt no = 0;
+ TUint16* tags = NULL;
+ TRAPD(error, tags = read->GetTagIdsL(EIfdGps, no));
+ if(tags)
+ delete tags;
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.208
+// Retrieve the types of IFDs included in Exif data.
+// Returns the IFD types and the number of IFDs.
+void CExifReadTest::ExifRead208L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking);
+ CleanupStack::PushL(read);
+
+ TInt no = 0;
+ TExifIfdType* ifds = read->GetIfdTypesL(no);
+ if((!ifds) && (no != 4))
+ {
+ if(ifds)
+ delete ifds;
+ User::Leave(KErrGeneral);
+ }
+ delete ifds;
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.209
+// Retrieve a copy of existing Exif thumbnail image from Exif data.
+// Returns the Exif thumbnail image.
+void CExifReadTest::ExifRead209L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking);
+ CleanupStack::PushL(read);
+
+ HBufC8* thumbnail = read->GetThumbnailL();
+ if(!thumbnail)
+ User::Leave(KErrGeneral);
+
+ delete thumbnail;
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.210
+// Try to retrieve a copy of Exif thumbnail image from Exif data that doesn't contain compressed Exif thumbnail image.
+// Leaves with proper error code.
+void CExifReadTest::ExifRead210L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KNoThumbnail, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking);
+ CleanupStack::PushL(read);
+
+ HBufC8* thumbnail = NULL;
+ TRAPD(error, thumbnail = read->GetThumbnailL());
+ if(thumbnail)
+ delete thumbnail;
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.211
+// Check if an IFD exists in Exif data.
+// Returns ETrue if specified IFD exists, EFalse otherwise.
+void CExifReadTest::ExifRead211L()
+ {
+ // For each IFD
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking);
+ CleanupStack::PushL(read);
+
+ // IFD exists,
+ if(!read->IfdExists(EIfd0))
+ User::Leave(KErrGeneral);
+ if(!read->IfdExists(EIfdExif))
+ User::Leave(KErrGeneral);
+ if(!read->IfdExists(EIfd1))
+ User::Leave(KErrGeneral);
+ if(!read->IfdExists(EIfdIntOp))
+ User::Leave(KErrGeneral);
+ // IFD doesn't exist.
+ if(read->IfdExists(EIfdGps))
+ User::Leave(KErrGeneral);
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.212
+// Check if a tag exists in the specified IFD of Exif data.
+// Returns ETrue if tag exists in the specified IFD, EFalse otherwise.
+void CExifReadTest::ExifRead212L()
+ {
+ // For each IFD;
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking);
+ CleanupStack::PushL(read);
+
+ // Tag exists in IFD,
+ if(!read->TagExists(KIdXResolution, EIfd0))
+ User::Leave(KErrGeneral);
+ if(!read->TagExists(KIdComponentsConfiguration, EIfdExif))
+ User::Leave(KErrGeneral);
+ if(!read->TagExists(1, EIfdIntOp))
+ User::Leave(KErrGeneral);
+ // IFD exists but tag doesn't exist,
+ if(read->TagExists(KIdCopyright, EIfd1))
+ User::Leave(KErrGeneral);
+ // IFD doesn't exist
+ if(read->TagExists(KIdGpsVersion, EIfdGps))
+ User::Leave(KErrGeneral);
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.213
+// Retrieve specific data using Get functions.
+// Returns the requested data.
+void CExifReadTest::ExifRead213L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking);
+ CleanupStack::PushL(read);
+
+ // For some Get functions.
+ HBufC8* data = read->GetImageDescriptionL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetMakeL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetDateTimeOriginalL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetTransferFunctionL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetRelatedSoundFileL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetModelL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetMakerNoteL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetIsoSpeedRatingsL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetDateTimeDigitizedL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+ data = read->GetCopyrightL();
+ if(!data)
+ User::Leave(KErrGeneral);
+ delete data;
+ data = 0;
+
+
+ TUint16 uInt16 = 0;
+ TUint32 uInt32 = 0;
+ TUint32 uInt32i = 0;
+ TInt32 int32 = 0;
+ TInt32 int32i = 0;
+ TInt8 int8 = 0;
+ TUint8 a1 = 0;
+ TUint8 a2 = 0;
+ TUint8 a3 = 0;
+ TUint8 a4 = 0;
+
+ User::LeaveIfError(read->GetExposureTime(uInt32, uInt32i));
+ if((uInt32 != 0) || (uInt32i != 0))
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetShutterSpeedValue(int32, int32i));
+ if((int32 != 0x00087383) || (int32i != 0x00010000))
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetBrightnessValue(int32, int32i));
+ if((int32 != 0) || (int32i != 1))
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetCustomRendered(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetGainControl(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetGpsVersion(uInt32));
+ if(uInt32 != 0x00000202)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetComponentsConfiguration(a1, a2, a3, a4));
+ if((a1 != 1) || (a2 != 2) || (a3 != 3 ) || (a4 != 0))
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetOrientation(uInt16));
+ if(uInt16 != 1)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetXResolution(uInt32, uInt32i));
+ if((uInt32 != 180) || (uInt32i != 1))
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetExifIfdPointer(uInt32));
+ if(uInt32 != 1798)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetFileSource(int8));
+ if(int8 != 3)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetSharpness(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetExifVersion(uInt32));
+ if(uInt32 != 0x30323230)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetThumbnailXResolution(uInt32, uInt32i));
+ if((uInt32 != 180) || (uInt32i != 1))
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetThumbnailCompression(uInt16));
+ if(uInt16 != 6)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetJpegInterchangeFormat(uInt32));
+ if(uInt32 != 2814)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetWhiteBalance(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetSceneCaptureType(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetSaturation(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetMeteringMode(uInt16));
+ if(uInt16 != 2)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetJpegInterchangeFormatLength(uInt32));
+ if(uInt32 != 5342)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetInteroperabilityIfdPointer(uInt32));
+ if(uInt32 != 2666)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetGpsInfoIfdPointer(uInt32));
+ if(uInt32 != 2612)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetFlashPixVersion(uInt32));
+ if(uInt32 != 0x30303130)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetExposureProgram(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetExposureMode(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetExposureBiasValue(int32, int32i));
+ if((int32 != 0) || (int32i != 3))
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetContrast(uInt16));
+ if(uInt16 != 0)
+ User::Leave(KErrGeneral);
+ User::LeaveIfError(read->GetApertureValue(uInt32, uInt32i));
+ if((uInt32 != 262144) || (uInt32i != 65536))
+ User::Leave(KErrGeneral);
+
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Read.214
+// Try to retrieve specific data that is not present in the Exif data using Get functions.
+// Leaves with or returns proper error code.
+void CExifReadTest::ExifRead214L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KNoThumbnail, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking);
+ CleanupStack::PushL(read);
+
+ // For some Get functions.
+ HBufC8* data = NULL;
+ TRAPD(error, data = read->GetSoftwareL());
+ if(data)
+ delete data;
+ data = 0;
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+ TRAP(error, data = read->GetUserCommentL());
+ if(data)
+ delete data;
+ data = 0;
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+
+ TUint16 uInt16 = 0;
+ TUint32 uInt32 = 0;
+ TUint32 uInt32i = 0;
+ TInt8 int8 = 0;
+ error = read->GetLightSource(uInt16);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+ error = read->GetFileSource(int8);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+ error = read->GetDigitalZoomRatio(uInt32, uInt32i);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+ error = read->GetThumbnailCompression(uInt16);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+ error = read->GetJpegInterchangeFormat(uInt32);
+ if(error != KErrNotFound)
+ {
+ if(error)
+ User::Leave(error);
+ else
+ User::Leave(KErrGeneral);
+ }
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Read.216
+// Retrieve the Exif APP1 segment.
+// Returns the whole Exif APP1 segment.
+void CExifReadTest::ExifRead216L()
+ {
+
+ HBufC8* exif = TUtils::ReadFileL(iFs, KValidExif, 65536);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking);
+ CleanupStack::PushL(read);
+
+ HBufC8* appSegment = read->GetExifAppSegmentL();
+ CleanupStack::PushL( appSegment );
+ if ( appSegment->Length() != 12670 )
+ {
+ User::Leave( KErrGeneral );
+ }
+ if ( *appSegment->Ptr() != 0xff )
+ {
+ User::Leave( KErrGeneral );
+ }
+ if ( *( appSegment->Ptr() + appSegment->Length() - 1 ) != 0xd9 )
+ {
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( appSegment );
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+
+ exif = TUtils::ReadFileL(iFs, KFullExif, 65536);
+ CleanupStack::PushL(exif);
+ read = CExifRead::NewL(*exif, CExifRead::ENoJpeg | CExifRead::ENoTagChecking);
+ CleanupStack::PushL(read);
+
+ appSegment = read->GetExifAppSegmentL();
+ CleanupStack::PushL( appSegment );
+ if ( appSegment->Length() != 8166 )
+ {
+ User::Leave( KErrGeneral );
+ }
+ if ( *appSegment->Ptr() != 0xff )
+ {
+ User::Leave( KErrGeneral );
+ }
+ if ( *( appSegment->Ptr() + appSegment->Length() - 1 ) != 0xd9 )
+ {
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PopAndDestroy( appSegment );
+
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+// Exif.Read.215
+// Test the behavior of the previous test cases in OOM situations.
+// Successfully operates or leaves with OOM error, without any memory leaks.
+void CExifReadTest::ExifRead215L()
+ {
+ // OOM in EXIF.READ.201- EXIF.READ.216
+ TInt error = KErrGeneral;
+ TInt i = 0;
+
+ RDebug::Print(_L("ExifRead201L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead201L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print((_L("ExifRead215L() TRAP error=%d")),error);
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead102L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+// RDebug::Print((_L("ExifRead102L() memory test i=%d")),i);
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead102L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead215L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead103L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead103L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead215L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead104L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead104L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead215L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead105L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead105L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead215L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead106L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead106L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead215L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead107L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead107L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead215L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead108L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead108L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead215L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead109L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead109L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead215L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead210L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead210L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead215L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead211L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead211L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead215L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead212L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead212L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead215L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead213L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead213L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead215L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead214L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead214L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead215L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ RDebug::Print(_L("ExifRead216L() memory test"));
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(i = 1; i < 500; i++)
+#else
+ for(i = 1; i < 10; i++)
+#endif
+ {
+ __UHEAP_MARK;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifRead216L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ RDebug::Print((_L("ExifRead215L() TRAP error=%d")),error);
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ __UHEAP_MARKEND;
+ break;
+ }
+ __UHEAP_MARKEND;
+ }
+
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/src/ExifTagTest.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,84 @@
+/*
+* Copyright (c) 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: ExifLibTest
+*
+*/
+#include "ExifLibTestInc.h"
+
+// Exif.Tag.001
+// Duplicate an existing tag, and get related information of the tag.
+// Created tag instance is returned.
+void CExifTagTest::ExifTag001L()
+ {
+ HBufC8* exif = TUtils::ReadFileL(iFs, KFullExif);
+ CleanupStack::PushL(exif);
+ CExifRead* read = CExifRead::NewL(*exif);
+ if(!read)
+ User::Leave(KErrGeneral);
+ CleanupStack::PushL(read);
+
+ const CExifTag* tag = read->GetTagL(EIfd0, KIdImageDescription);
+ CExifTag* copyTag = tag->DuplicateL();
+ if(!copyTag)
+ User::Leave(KErrGeneral);
+ CleanupStack::PushL(copyTag);
+
+ if(copyTag->TagInfo().iId != KIdImageDescription)
+ User::Leave(KErrGeneral);
+
+ if(copyTag->TagInfo().iDataType != CExifTag::ETagAscii)
+ User::Leave(KErrGeneral);
+
+ if(copyTag->TagInfo().iDataCount != tag->TagInfo().iDataCount)
+ User::Leave(KErrGeneral);
+
+ if(copyTag->Data().Length() != tag->TagInfo().iDataCount)
+ User::Leave(KErrGeneral);
+
+ CleanupStack::PopAndDestroy(copyTag);
+ CleanupStack::PopAndDestroy(read);
+ CleanupStack::PopAndDestroy(exif);
+ }
+
+
+// Exif.Tag.MEM.002
+// Test the behavior of the previous test cases in OOM situations.
+// Successfully operates or leaves with OOM error, without any memory leaks.
+void CExifTagTest::ExifTag002L()
+ {
+ // EXIF.TAG.001
+ TInt error = KErrGeneral;
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ for(TInt i = 1; i < 50 && error != KErrNone; i++)
+#else
+ for(TInt i = 1; i < 10 && error != KErrNone; i++)
+#endif
+ {
+#if ( ( defined __WINS__ ) || ( defined __WINSCW__) )
+ __UHEAP_SETFAIL( RHeap::EFailNext, i );
+#else
+ __UHEAP_SETFAIL( RHeap::ERandom, i );
+#endif
+ TRAP(error, ExifTag001L());
+ if(error)
+ {
+ if(error != KErrNoMemory)
+ {
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ User::Leave(KErrGeneral);
+ }
+ }
+ }
+ __UHEAP_SETFAIL( RHeap::ENone, 0 );
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/src/TestFrameWork/AssertFailure.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,122 @@
+/*
+* Copyright (c) 2002 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: ExifLibTest
+*
+*/
+
+
+#include "AssertFailure.h"
+
+
+CAssertFailure* CAssertFailure::NewL (const TDesC8& aMessage,
+ TInt aLineNumber,
+ const TDesC8& aFileName)
+ {
+ CAssertFailure* self=NewLC(aMessage, aLineNumber, aFileName);
+ CleanupStack::Pop();
+ return self;
+ }
+
+
+CAssertFailure* CAssertFailure::NewLC (const TDesC8& aMessage,
+ TInt aLineNumber,
+ const TDesC8& aFileName)
+
+ {
+ CAssertFailure* self = new (ELeave) CAssertFailure(aLineNumber);
+ CleanupStack::PushL(self);
+ self->ConstructL(aMessage, aFileName);
+ return self;
+ }
+
+
+CAssertFailure* CAssertFailure::NewL (CAssertFailure& aAssertFailure)
+ {
+ CAssertFailure* self=NewLC(aAssertFailure);
+ CleanupStack::Pop();
+ return self;
+ }
+
+
+CAssertFailure* CAssertFailure::NewLC (CAssertFailure& aAssertFailure)
+ {
+ CAssertFailure* self = new(ELeave)CAssertFailure;
+ CleanupStack::PushL(self);
+ self->ConstructL(aAssertFailure);
+ return self;
+ }
+
+
+void CAssertFailure::ConstructL (const TDesC8& aMessage,
+ const TDesC8& aFileName)
+ {
+ iMessage = aMessage.AllocL();
+ iFileName = aFileName.AllocL();
+ }
+
+
+void CAssertFailure::ConstructL (CAssertFailure& aAssertFailure)
+ {
+ iLineNumber = aAssertFailure.iLineNumber;
+ iMessage = aAssertFailure.iMessage->AllocL();
+ iFileName = aAssertFailure.iFileName->AllocL();
+ }
+
+
+CAssertFailure::CAssertFailure ()
+ {
+ }
+
+
+CAssertFailure::CAssertFailure (TInt aLineNumber)
+ : iLineNumber (aLineNumber)
+ {
+ }
+
+
+CAssertFailure::~CAssertFailure ()
+ {
+ delete iFileName;
+ delete iMessage;
+ }
+
+
+const TDesC8& CAssertFailure::What() const
+ {
+ return *iMessage;
+ }
+
+
+TInt CAssertFailure::LineNumber() const
+ {
+ return iLineNumber;
+ }
+
+
+const TDesC8& CAssertFailure::FileName() const
+ {
+ return *iFileName;
+ }
+
+
+void CAssertFailure::SetMyHeapCellCount (TInt aHeapCellCount)
+ {
+ iMyHeapCellCount = aHeapCellCount;
+ }
+
+
+TInt CAssertFailure::MyHeapCellCount ()
+ {
+ return iMyHeapCellCount;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/src/TestFrameWork/TestCase.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,293 @@
+/*
+* Copyright (c) 2002 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: ExifLibTest
+*
+*/
+
+
+#include <utf.h>
+
+#include "TestFrameWork/testCase.h"
+#include "TestFrameWork/AssertFailure.h"
+#include <StifTestModule.h>
+
+// Assertion failure message formats:
+_LIT8(KIntsNotEqualFormat,"expected: %d but was: %d");
+_LIT8(KRealsNotEqualFormat,"expected: %g but was: %g");
+_LIT8(KDesCsNotEqualFormat,"expected: '%S' but was: '%S'");
+
+
+// A unique error code:
+const TInt KErrCppUnitAssertionFailed=(-99999999);
+
+
+
+void CTestCase::ConstructL (const TDesC8& aName)
+ {
+ iName = aName.AllocL();
+ User::LeaveIfError(Dll::SetTls(0));
+ }
+
+
+CTestCase::CTestCase ()
+: iAllocFailureType(RHeap::ENone),
+iAllocFailureRate(0)
+ {
+ }
+
+
+CTestCase::~CTestCase ()
+ {
+ delete iName;
+ }
+
+
+// From MTest:
+void CTestCase::ExecuteL (TTestResult& aResult)
+ {
+ TInt error = ExecuteImplL();
+ aResult.iResult = error;
+ // add the possible failure or error to the result
+
+ if (error == KErrCppUnitAssertionFailed)
+ {
+ CAssertFailure* assertFailure = AssertFailureFromTlsL ();
+ CleanupStack::PushL(assertFailure);
+ TBuf16 <0x80> convertBuf;
+ convertBuf.Copy(assertFailure->What());
+ aResult.iResultDes.Append(convertBuf);
+ aResult.iResultDes.AppendFormat(_L(" at Line %i of"), assertFailure->LineNumber());
+ convertBuf.Copy(assertFailure->FileName());
+ aResult.iResultDes.Append(convertBuf);
+ CleanupStack::PopAndDestroy(assertFailure);
+ }
+ }
+
+// From MTest:
+TInt CTestCase::CountTestCases ()
+ {
+ return 1;
+ }
+
+
+// From MTest:
+const TDesC8& CTestCase::Name ()
+ {
+ return *iName;
+ }
+
+
+
+#if 1
+// From MTest:
+void CTestCase::ExecuteTestL(TTestResult& aResult,
+ TInt /*aIndex */)
+ {
+ ExecuteL(aResult);
+ }
+
+const TDesC8& CTestCase::TestCaseName (TInt /*aIndex*/)
+ {
+ return Name();
+ }
+#endif
+
+
+
+// Check for a failed general assertion
+void CTestCase::AssertL (TBool aCondition,
+ const TDesC8& aConditionExpression,
+ TInt aLineNumber,
+ const TDesC8& aFileName)
+ {
+ if (!aCondition)
+ {
+ AllocFailureSimulation(EFalse);
+ AssertFailureToTlsL (aConditionExpression,aLineNumber,aFileName);
+ User::Leave (KErrCppUnitAssertionFailed);
+ }
+ }
+
+
+// Check for a failed equality assertion
+void CTestCase::AssertEqualsL (TInt anExpected,
+ TInt anActual,
+ TInt aLineNumber,
+ const TDesC8& aFileName)
+ {
+ if (anExpected != anActual)
+ {
+ AllocFailureSimulation(EFalse);
+ HBufC8* msg = HBufC8::NewLC (KIntsNotEqualFormat().Size()+100);
+ msg->Des().Format(KIntsNotEqualFormat, anExpected, anActual);
+ AssertFailureToTlsL(*msg,aLineNumber,aFileName);
+ CleanupStack::PopAndDestroy(); // msg
+ User::Leave (KErrCppUnitAssertionFailed);
+ }
+ }
+
+
+// Check for a failed equality assertion
+void CTestCase::AssertEqualsL (TReal anExpected,
+ TReal anActual,
+ TReal aDelta,
+ TInt aLineNumber,
+ const TDesC8& aFileName)
+ {
+ if (Abs(anExpected-anActual) > aDelta)
+ {
+ AllocFailureSimulation(EFalse);
+ HBufC8* msg = HBufC8::NewLC (KRealsNotEqualFormat().Size()+100);
+ msg->Des().Format(KRealsNotEqualFormat, anExpected, anActual);
+ AssertFailureToTlsL(*msg,aLineNumber,aFileName);
+ CleanupStack::PopAndDestroy(); // msg
+ User::Leave (KErrCppUnitAssertionFailed);
+ }
+ }
+
+
+// Check equality of the contents of two 8-bit descriptors
+void CTestCase::AssertEqualsL (const TDesC8& anExpected,
+ const TDesC8& anActual,
+ TInt aLineNumber,
+ const TDesC8& aFileName)
+ {
+ if (anExpected.Compare(anActual) != 0)
+ {
+ AllocFailureSimulation(EFalse);
+ HBufC8* msg = NotEqualsMessageLC (anExpected, anActual);
+ AssertFailureToTlsL(*msg,aLineNumber,aFileName);
+ CleanupStack::PopAndDestroy(); // msg
+ User::Leave (KErrCppUnitAssertionFailed);
+ }
+ }
+
+
+// Check equality of the contents of two 16-bit descriptors
+void CTestCase::AssertEqualsL (const TDesC16& aExpected,
+ const TDesC16& aActual,
+ TInt aLineNumber,
+ const TDesC8& aFileName)
+ {
+ if (aExpected.Compare(aActual) != 0)
+ {
+ AllocFailureSimulation(EFalse);
+ HBufC8* msg = NotEqualsMessageLC (aExpected, aActual);
+ AssertFailureToTlsL(*msg,aLineNumber,aFileName);
+ CleanupStack::PopAndDestroy(); // msg
+ User::Leave (KErrCppUnitAssertionFailed);
+ }
+ }
+
+
+void CTestCase::AllocFailureSimulation (TBool aSwitchedOn)
+ {
+ if (aSwitchedOn)
+ {
+ __UHEAP_SETFAIL (iAllocFailureType, iAllocFailureRate);
+ }
+ else
+ {
+ __UHEAP_RESET;
+ }
+ }
+
+
+TInt CTestCase::ExecuteImplL ()
+ {
+
+ __UHEAP_MARK;
+ TRAPD (setupError, setUpL());
+ if (setupError != KErrNone)
+ {
+ tearDown();
+ __UHEAP_MARKEND;
+ User::Leave(setupError);
+ }
+
+ TRAPD (executionError, executeTestL());
+
+ tearDown();
+ __UHEAP_MARKENDC(HeapCellsReservedByAssertFailure());
+
+ return executionError;
+ }
+
+
+// Construct the message and put it in the cleanup stack
+HBufC8* CTestCase::NotEqualsMessageLC (const TDesC8& aExpected,
+ const TDesC8& aActual)
+ {
+ TInt size = KDesCsNotEqualFormat().Size()+aExpected.Size()+aActual.Size();
+ HBufC8 *msg = HBufC8::NewLC(size);
+ msg->Des().Format(KDesCsNotEqualFormat, &aExpected, &aActual);
+ return msg;
+ }
+
+
+// Construct the message and put it in the cleanup stack
+HBufC8* CTestCase::NotEqualsMessageLC (const TDesC16& aExpected,
+ const TDesC16& aActual)
+ {
+ TInt length = KDesCsNotEqualFormat().Length() +
+ aExpected.Length() + aActual.Length();
+
+ HBufC8* msg = HBufC8::NewLC(length);
+
+ // Convert 16-bit to 8-bit to ensure readability
+ // of the output possibly directed to a file.
+ HBufC8* expected = HBufC8::NewLC(aExpected.Length());
+ expected->Des().Copy(aExpected);
+
+ HBufC8* actual = HBufC8::NewLC(aActual.Length());
+ actual->Des().Copy(aActual);
+
+ msg->Des().Format(KDesCsNotEqualFormat,expected,actual);
+
+ // pop and destroy actual and expected
+ CleanupStack::PopAndDestroy(2);
+ return msg;
+ }
+
+
+void CTestCase::AssertFailureToTlsL (const TDesC8& aMessage,
+ TInt aLineNumber,
+ const TDesC8& aFileName)
+ {
+ TInt cellsBefore = User::CountAllocCells();
+ CAssertFailure* assertFailure =
+ CAssertFailure::NewLC(aMessage,aLineNumber,aFileName);
+ User::LeaveIfError(Dll::SetTls(assertFailure));
+ CleanupStack::Pop(); // assertFailure
+ TInt cellsAfter = User::CountAllocCells();
+ assertFailure->SetMyHeapCellCount(cellsAfter-cellsBefore);
+ }
+
+
+CAssertFailure* CTestCase::AssertFailureFromTlsL ()
+ {
+ CAssertFailure* assertFailure = static_cast<CAssertFailure*>(Dll::Tls());
+ CAssertFailure* copy = CAssertFailure::NewL(*assertFailure);
+ delete assertFailure;
+ Dll::SetTls(0);
+ return copy;
+ }
+
+
+TInt CTestCase::HeapCellsReservedByAssertFailure ()
+ {
+ if (Dll::Tls() == 0) return 0;
+ CAssertFailure* assertFailure = static_cast<CAssertFailure*>(Dll::Tls());
+ return assertFailure->MyHeapCellCount();
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/exif_api/tsrc/src/TestFrameWork/TestSuite.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,126 @@
+/*
+* Copyright (c) 2002 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: ExifLibTest
+*
+*/
+
+
+
+#include "TestFrameWork/testSuite.h"
+#include <StifTestModule.h>
+
+
+CTestSuite* CTestSuite::NewLC (const TDesC8& aName)
+ {
+ CTestSuite* self=new(ELeave) CTestSuite();
+ CleanupStack::PushL(self);
+ self->ConstructL(aName);
+ return self;
+ }
+
+
+CTestSuite* CTestSuite::NewL (const TDesC8& aName)
+ {
+ CTestSuite* self=NewLC(aName);
+ CleanupStack::Pop();
+ return self;
+ }
+
+
+void CTestSuite::ConstructL (const TDesC8& aName)
+ {
+ iName = aName.AllocL();
+ }
+
+
+CTestSuite::~CTestSuite ()
+ {
+ iTests.ResetAndDestroy();
+ delete iName;
+ }
+
+
+void CTestSuite::addTestL (MTest* aTest)
+ {
+ User::LeaveIfError (iTests.Append(aTest));
+ }
+
+
+// Runs the tests and collects their result in a TestResult.
+// Deprecated.
+// Version with index should be used instead.
+
+void CTestSuite::ExecuteL (TTestResult& aResult)
+ {
+ for (TInt i=0; i < iTests.Count(); i++)
+ {
+ iTests[i]->ExecuteL(aResult);
+ }
+ }
+
+
+// Counts the number of test cases that will be run by this test.
+TInt CTestSuite::CountTestCases ()
+ {
+ TInt count = 0;
+ for (TInt i=0; i < iTests.Count(); i++)
+ {
+ count += iTests[i]->CountTestCases ();
+ }
+ return count;
+ }
+
+
+const TDesC8& CTestSuite::Name ()
+ {
+ return *iName;
+ }
+
+#if 1
+void CTestSuite::ExecuteTestL(TTestResult& aResult,
+ TInt aIndex)
+ {
+ for (TInt i=0; i< iTests.Count(); i++)
+ {
+ TInt count = iTests[i]->CountTestCases();
+ if ( aIndex > ( count - 1 ) )
+ {
+ aIndex -= count;
+ }
+ else
+ {
+ iTests[i]->ExecuteTestL(aResult, aIndex);
+ return ;
+ }
+ }
+ }
+
+const TDesC8& CTestSuite::TestCaseName (TInt aIndex)
+ {
+ for (TInt i=0; i< iTests.Count(); i++)
+ {
+ TInt count = iTests[i]->CountTestCases();
+ if ( aIndex > ( count - 1 ) )
+ {
+ aIndex -= count;
+ }
+ else
+ {
+ return ( iTests[i]->TestCaseName(aIndex) ) ;
+ }
+ }
+ // It's an error if we reached that point.
+ return(KNullDesC8);
+ }
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingext_pub/group/bld.inf Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,21 @@
+/*
+* Copyright (c) 2006 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: Includes all the SDK API specific bld.inf files, which
+* export files.
+*
+*/
+
+
+
+#include "../exif_api/group/bld.inf"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/BMARM/EXIFLIBU.DEF Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,6 @@
+EXPORTS
+ NewL__11CExifModifyRC6TDesC8Q211CExifModify14TOperationMode @ 1 NONAME R3UNUSED ; CExifModify::NewL(TDesC8 const &, CExifModify::TOperationMode)
+ NewL__9CExifReadRC6TDesC8 @ 2 NONAME R3UNUSED ; CExifRead::NewL(TDesC8 const &)
+ __12TExifTagInfoUsQ28CExifTag16TExifTagDataTypeUl @ 3 NONAME ; TExifTagInfo::TExifTagInfo(unsigned short, CExifTag::TExifTagDataType, unsigned long)
+ NewL__11CExifModify @ 4 NONAME R3UNUSED ; CExifModify::NewL(void)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/BWINS/EXIFLIBU.DEF Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,6 @@
+EXPORTS
+ ??0TExifTagInfo@@QAE@GW4TExifTagDataType@CExifTag@@K@Z @ 1 NONAME ; public: __thiscall TExifTagInfo::TExifTagInfo(unsigned short,enum CExifTag::TExifTagDataType,unsigned long)
+ ?NewL@CExifModify@@SAPAV1@ABVTDesC8@@W4TOperationMode@1@@Z @ 2 NONAME ; public: static class CExifModify * __cdecl CExifModify::NewL(class TDesC8 const &,enum CExifModify::TOperationMode)
+ ?NewL@CExifRead@@SAPAV1@ABVTDesC8@@@Z @ 3 NONAME ; public: static class CExifRead * __cdecl CExifRead::NewL(class TDesC8 const &)
+ ?NewL@CExifModify@@SAPAV1@XZ @ 4 NONAME ; public: static class CExifModify * __cdecl CExifModify::NewL(void)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/Bwinscw/ExifLibU.DEF Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,8 @@
+EXPORTS
+ ??0TExifTagInfo@@QAE@GW4TExifTagDataType@CExifTag@@K@Z @ 1 NONAME ; TExifTagInfo::TExifTagInfo(unsigned short, enum CExifTag::TExifTagDataType, unsigned long)
+ ?NewL@CExifModify@@SAPAV1@ABVTDesC8@@W4TOperationMode@1@@Z @ 2 NONAME ; class CExifModify * CExifModify::NewL(class TDesC8 const &, enum CExifModify::TOperationMode)
+ ?NewL@CExifModify@@SAPAV1@XZ @ 3 NONAME ; class CExifModify * CExifModify::NewL(void)
+ ?NewL@CExifRead@@SAPAV1@ABVTDesC8@@@Z @ 4 NONAME ; class CExifRead * CExifRead::NewL(class TDesC8 const &)
+ ?NewL@CExifRead@@SAPAV1@ABVTDesC8@@I@Z @ 5 NONAME ; class CExifRead * CExifRead::NewL(class TDesC8 const &, unsigned int)
+ ?NewL@CExifModify@@SAPAV1@ABVTDesC8@@W4TOperationMode@1@I@Z @ 6 NONAME ; class CExifModify * CExifModify::NewL(class TDesC8 const &, enum CExifModify::TOperationMode, unsigned int)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/EABI/ExifLibU.DEF Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,9 @@
+EXPORTS
+ _ZN11CExifModify4NewLERK6TDesC8NS_14TOperationModeE @ 1 NONAME
+ _ZN12TExifTagInfoC1EtN8CExifTag16TExifTagDataTypeEm @ 2 NONAME
+ _ZN12TExifTagInfoC2EtN8CExifTag16TExifTagDataTypeEm @ 3 NONAME
+ _ZN9CExifRead4NewLERK6TDesC8 @ 4 NONAME
+ _ZN11CExifModify4NewLEv @ 5 NONAME
+ _ZN9CExifRead4NewLERK6TDesC8j @ 6 NONAME
+ _ZN11CExifModify4NewLERK6TDesC8NS_14TOperationModeEj @ 7 NONAME
+
Binary file imagingmodules/exiflib/data/ExifLib.SIS has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/data/ExifLib.pkg Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,29 @@
+;
+; Copyright (c) 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: ExifLib
+;
+; Languages
+&EN
+
+; Header
+#{"ExifLib"}, (0x101F864A), 1, 0, 0, TYPE=SA
+
+; Localised Vendor name
+%{"Nokia"}
+
+; Unique Vendor name
+:"Nokia"
+
+;Files
+""-"z:\sys\bin\ExifLib.dll"
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/group/ExifLib.mmp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,59 @@
+/*
+* Copyright (c) 2003-2006 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: Project specification file for ExifLib.
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+TARGET ExifLib.dll
+TARGETTYPE DLL
+
+UID 0x1000008D 0x101F864A
+
+CAPABILITY CAP_GENERAL_DLL
+VENDORID VID_DEFAULT
+
+// Define directories for the .def-files of WINS and WINSCW builds separately.
+// IMPORTANT NOTICE: The lines in the example that end with a backslash
+// must have one space after the backslash.
+#if defined(ARMCC)
+deffile ../EABI/
+#elif defined( WINSCW )
+deffile ../Bwinscw/
+#elif defined( WINS )
+deffile ../Bwins/
+#else
+deffile ../Bmarm/
+#endif
+
+SOURCEPATH ../src
+SOURCE ExifCommon.cpp
+SOURCE ExifTag.cpp
+SOURCE ExifIfd.cpp
+SOURCE ExifRead.cpp
+SOURCE ExifModify.cpp
+SOURCE ExifCore.cpp
+SOURCE ExifEndian.cpp
+
+USERINCLUDE ../inc
+USERINCLUDE ../../inc // subsystem level inc dir
+USERINCLUDE ../../../inc // ADo level inc dir
+
+OS_LAYER_SYSTEMINCLUDE
+
+LIBRARY euser.lib
+
+// End of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/group/bld.inf Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,33 @@
+/*
+* Copyright (c) 2003-2006 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: Build information file for Exif Library.
+*
+*/
+
+
+#include <platform_paths.hrh>
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_EXPORTS
+// SIS stub
+../data/ExifLib.SIS /epoc32/data/z/system/install/ExifLib.sis
+../rom/ExifLib.iby CORE_OS_LAYER_IBY_EXPORT_PATH(ExifLib.iby)
+
+PRJ_MMPFILES
+ExifLib.mmp
+
+PRJ_TESTMMPFILES
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/inc/ExifCommon.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,391 @@
+/*
+* Copyright (c) 2003, 2004 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: Defines Exif-related constant data used internally by the
+* service classes, and a utility class providing internal common
+* services.
+*
+*/
+
+
+#ifndef EXIFCOMMON_H
+#define EXIFCOMMON_H
+
+// INCLUDES
+#include <e32base.h>
+#include "ExifTag.h"
+
+// STRUCTURES
+
+struct TReferenceTag
+ {
+ enum TExtraDataType
+ {
+ ETagLongOrShort = 11
+ };
+ // Tag ID
+ TUint16 iId;
+
+ // Tag data type
+ TInt iDataType;
+
+ // Number of tag data elements (having tag data type).
+ TUint32 iDataCount;
+ };
+
+// CONSTANTS
+
+// Jpeg markers
+const TUint8 KMarkerStart = 0xff;
+const TUint16 KSoi = 0xffd8;
+const TUint8 KSoiEnd = 0xd8;
+const TUint16 KSoiRev = 0xd8ff;
+const TUint16 KEoi = 0xffd9;
+const TUint16 KApp1Rev = 0xe1ff;
+const TUint8 KApp1End = 0xe1;
+const TUint16 KDqt = 0xffdb;
+const TUint16 KDht = 0xffc4;
+const TUint16 KDri = 0xffdd;
+const TUint16 KSof0 = 0xffc0;
+
+// Exif header related
+const TUint16 KLittleEndian = 0x4949;
+const TUint16 KBigEndian = 0x4d4d;
+const TUint16 KExifDummy = 0x2a00;
+const TUint16 KExifDummyRev = 0x002a;
+const TUint32 KExifIdentifierRev = 0x66697845;
+const TUint8 KExifPad = 0x00;
+const TUint32 KHeaderOffset = 0x00000008;
+
+// Masks
+const TUint32 KThreeByteMask = 0x00ffffff;
+const TUint32 KTwoByteMask = 0x0000ffff;
+const TUint32 KOneByteMask = 0x000000ff;
+
+const TUint KMaxApp1Size = 65535;
+const TUint KIfdNo = 5;
+
+const TInt KNoIfd0Tags = 19;
+const TInt KNoMandatoryIfd0Tags = 5;
+const TInt KNoIfdExifTags = 57;
+const TInt KNoMandatoryIfdExifTags = 6;
+const TInt KNoIfd1Tags = 22;
+const TInt KNoMandatoryIfd1Tags = 6;
+const TInt KNoIfdGpsTags = 31;
+const TInt KNoMandatoryIfdGpsTags = 1;
+const TInt KNoIfdIntOpTags = 5;
+const TInt KNoMandatoryIfdIntOpTags = 0;
+
+const TUint KAny = 0;
+
+const TReferenceTag ifd0Tags[KNoIfd0Tags] =
+ {
+ { 0x011A, CExifTag::ETagRational, 1 },
+ { 0x011B, CExifTag::ETagRational, 1 },
+ { 0x0128, CExifTag::ETagShort, 1 },
+ { 0x0213, CExifTag::ETagShort, 1 },
+ { 0x8769, CExifTag::ETagLong, 1 },
+ { 0x0110, CExifTag::ETagAscii, KAny },
+ { 0x0112, CExifTag::ETagShort, 1 },
+ { 0x012D, CExifTag::ETagShort, 768 },
+ { 0x0131, CExifTag::ETagAscii, KAny },
+ { 0x0132, CExifTag::ETagAscii, 20 },
+ { 0x013B, CExifTag::ETagAscii, KAny },
+ { 0x013E, CExifTag::ETagRational, 2 },
+ { 0x013F, CExifTag::ETagRational, 6 },
+ { 0x0211, CExifTag::ETagRational, 3 },
+ { 0x010E, CExifTag::ETagAscii, KAny },
+ { 0x0214, CExifTag::ETagRational, 6 },
+ { 0x8298, CExifTag::ETagAscii, KAny },
+ { 0x8825, CExifTag::ETagLong, 1 },
+ { 0x010F, CExifTag::ETagAscii, KAny }
+ };
+
+const TReferenceTag ifdExifTags[KNoIfdExifTags] =
+ {
+ { 0x9000, CExifTag::ETagUndefined, 4 },
+ { 0x9101, CExifTag::ETagUndefined, 4 },
+ { 0xA000, CExifTag::ETagUndefined, 4 },
+ { 0xA001, CExifTag::ETagShort, 1 },
+ { 0xA002, TReferenceTag::ETagLongOrShort, 1 },
+ { 0xA003, TReferenceTag::ETagLongOrShort, 1 },
+ { 0x8828, CExifTag::ETagUndefined, KAny },
+ { 0x9003, CExifTag::ETagAscii, 20 },
+ { 0x9004, CExifTag::ETagAscii, 20 },
+ { 0x8824, CExifTag::ETagAscii, KAny },
+ { 0x9102, CExifTag::ETagRational, 1 },
+ { 0x9201, CExifTag::ETagSrational, 1 },
+ { 0x9202, CExifTag::ETagRational, 1 },
+ { 0x9203, CExifTag::ETagSrational, 1 },
+ { 0x9204, CExifTag::ETagSrational, 1 },
+ { 0x9205, CExifTag::ETagRational, 1 },
+ { 0x9206, CExifTag::ETagRational, 1 },
+ { 0x9207, CExifTag::ETagShort, 1 },
+ { 0x9208, CExifTag::ETagShort, 1 },
+ { 0x9209, CExifTag::ETagShort, 1 },
+ { 0x920A, CExifTag::ETagRational, 1 },
+ { 0x9214, CExifTag::ETagShort, KAny },
+ { 0x927C, CExifTag::ETagUndefined, KAny },
+ { 0x9286, CExifTag::ETagUndefined, KAny },
+ { 0x9290, CExifTag::ETagAscii, KAny },
+ { 0x9291, CExifTag::ETagAscii, KAny },
+ { 0x9292, CExifTag::ETagAscii, KAny },
+ { 0x829A, CExifTag::ETagRational, 1 },
+ { 0x829d, CExifTag::ETagRational, 1 },
+ { 0x8822, CExifTag::ETagShort, 1 },
+ { 0xA004, CExifTag::ETagAscii, 13 },
+ { 0xA005, CExifTag::ETagLong, 1 },
+ { 0xA20B, CExifTag::ETagRational, 1 },
+ { 0xA20C, CExifTag::ETagUndefined, KAny },
+ { 0x8827, CExifTag::ETagShort, KAny },
+ { 0xA20E, CExifTag::ETagRational, 1 },
+ { 0xA20F, CExifTag::ETagRational, 1 },
+ { 0xA210, CExifTag::ETagShort, 1 },
+ { 0xA214, CExifTag::ETagShort, 2 },
+ { 0xA215, CExifTag::ETagRational, 1 },
+ { 0xA217, CExifTag::ETagShort, 1 },
+ { 0xA300, CExifTag::ETagUndefined, 1 },
+ { 0xA301, CExifTag::ETagUndefined, 1 },
+ { 0xA302, CExifTag::ETagUndefined, KAny },
+ { 0xA401, CExifTag::ETagShort, 1 },
+ { 0xA402, CExifTag::ETagShort, 1 },
+ { 0xA403, CExifTag::ETagShort, 1 },
+ { 0xA404, CExifTag::ETagRational, 1 },
+ { 0xA405, CExifTag::ETagShort, 1 },
+ { 0xA406, CExifTag::ETagShort, 1 },
+ { 0xA407, CExifTag::ETagShort, 1 },
+ { 0xA408, CExifTag::ETagShort, 1 },
+ { 0xA409, CExifTag::ETagShort, 1 },
+ { 0xA40A, CExifTag::ETagShort, 1 },
+ { 0xA40B, CExifTag::ETagUndefined, KAny },
+ { 0xA40C, CExifTag::ETagShort, 1 },
+ { 0xA420, CExifTag::ETagAscii, 33 }
+ };
+
+const TReferenceTag ifd1Tags[KNoIfd1Tags] =
+ {
+ { 0x0103, CExifTag::ETagShort, 1 },
+ { 0x011A, CExifTag::ETagRational, 1 },
+ { 0x011B, CExifTag::ETagRational, 1 },
+ { 0x0128, CExifTag::ETagShort, 1 },
+ { 0x0201, CExifTag::ETagLong, 1 },
+ { 0x0202, CExifTag::ETagLong, 1 },
+ { 0x0112, CExifTag::ETagShort, 1 },
+ { 0x012D, CExifTag::ETagShort, 768 },
+ { 0x010F, CExifTag::ETagAscii, KAny },
+ { 0x0110, CExifTag::ETagAscii, KAny },
+ { 0x0131, CExifTag::ETagAscii, KAny },
+ { 0x0132, CExifTag::ETagAscii, 20 },
+ { 0x013B, CExifTag::ETagAscii, KAny },
+ { 0x013E, CExifTag::ETagRational, 2 },
+ { 0x013F, CExifTag::ETagRational, 6 },
+ { 0x0211, CExifTag::ETagRational, 3 },
+ { 0x0213, CExifTag::ETagShort, 1 },
+ { 0x0214, CExifTag::ETagRational, 6 },
+ { 0x010E, CExifTag::ETagAscii, KAny },
+ { 0x8298, CExifTag::ETagAscii, KAny },
+ { 0x8769, CExifTag::ETagLong, 1 },
+ { 0x8825, CExifTag::ETagLong, 1 }
+ };
+
+const TReferenceTag ifdGpsTags[KNoIfdGpsTags] =
+ {
+ { 0x0000, CExifTag::ETagByte, 4 },
+ { 0x0001, CExifTag::ETagAscii, 2 },
+ { 0x0002, CExifTag::ETagRational, 3 },
+ { 0x0003, CExifTag::ETagAscii, 2 },
+ { 0x0004, CExifTag::ETagRational, 3 },
+ { 0x0005, CExifTag::ETagByte, 1 },
+ { 0x0006, CExifTag::ETagRational, 1 },
+ { 0x0007, CExifTag::ETagRational, 3 },
+ { 0x0008, CExifTag::ETagAscii, KAny },
+ { 0x0009, CExifTag::ETagAscii, 2 },
+ { 0x000A, CExifTag::ETagAscii, 2 },
+ { 0x000B, CExifTag::ETagRational, 1 },
+ { 0x000C, CExifTag::ETagAscii, 2 },
+ { 0x000D, CExifTag::ETagRational, 1 },
+ { 0x000E, CExifTag::ETagAscii, 2 },
+ { 0x000F, CExifTag::ETagRational, 1 },
+ { 0x0010, CExifTag::ETagAscii, 2 },
+ { 0x0011, CExifTag::ETagRational, 1 },
+ { 0x0012, CExifTag::ETagAscii, KAny },
+ { 0x0013, CExifTag::ETagAscii, 2 },
+ { 0x0014, CExifTag::ETagRational, 3 },
+ { 0x0015, CExifTag::ETagAscii, 2 },
+ { 0x0016, CExifTag::ETagRational, 3 },
+ { 0x0017, CExifTag::ETagAscii, 2 },
+ { 0x0018, CExifTag::ETagRational, 1 },
+ { 0x0019, CExifTag::ETagAscii, 2 },
+ { 0x001A, CExifTag::ETagRational, 1 },
+ { 0x001B, CExifTag::ETagUndefined, KAny },
+ { 0x001C, CExifTag::ETagUndefined, KAny },
+ { 0x001D, CExifTag::ETagAscii, 11 },
+ { 0x001E, CExifTag::ETagShort, 1 }
+ };
+
+const TReferenceTag ifdIntOpTags[KNoIfdIntOpTags] =
+ {
+ { 0x0001, CExifTag::ETagAscii, KAny },
+ { 0x0002, CExifTag::ETagUndefined, 4 },
+ { 0x1000, CExifTag::ETagAscii, KAny },
+ { 0x1001, TReferenceTag::ETagLongOrShort, 1 },
+ { 0x1002, TReferenceTag::ETagLongOrShort, 1 }
+ };
+
+// MACROS
+
+// Logging support
+// Serial port logging is enabled in _DEBUG builds by default
+// USE_FILE_LOGGER or USE_SERIAL_LOGGER can also be explicitely defined e.g. in MMP file.
+//
+
+// #define USE_FILE_LOGGER
+
+#if defined (_DEBUG) && !defined(USE_FILE_LOGGER)
+ #define USE_SERIAL_LOGGER
+#endif
+
+#if defined (USE_FILE_LOGGER)
+ #include <flogger.h>
+ _LIT(KLogFile,"exiflib.txt");
+ _LIT(KLogFolder,"exiflib");
+ #define LOGTEXT(AAA) RFileLogger::Write(KLogFolder(),KLogFile(),EFileLoggingModeAppend,AAA)
+ #define LOGTEXT2(AAA,BBB) RFileLogger::WriteFormat(KLogFolder(),KLogFile(),EFileLoggingModeAppend,TRefByValue<const TDesC>(AAA),BBB)
+ #define LOGTEXT3(AAA,BBB,CC) RFileLogger::WriteFormat(KLogFolder(),KLogFile(),EFileLoggingModeAppend,TRefByValue<const TDesC>(AAA),BBB,CC)
+ #define LOGTEXT4(AAA,BBB,CC,DDD) RFileLogger::WriteFormat(KLogFolder(),KLogFile(),EFileLoggingModeAppend,TRefByValue<const TDesC>(AAA),BBB,CC,DDD)
+ #define LOGHEXDUMP(AAA,BBB,CC,DDD) RFileLogger::HexDump(KLogFolder(),KLogFile(),EFileLoggingModeAppend,AAA,BBB,CC,DDD)
+#elif defined (USE_SERIAL_LOGGER)
+ #include <e32svr.h>
+ #define LOGTEXT(AAA) RDebug::Print(AAA)
+ #define LOGTEXT2(AAA,BBB) RDebug::Print(AAA,BBB)
+ #define LOGTEXT3(AAA,BBB,CC) RDebug::Print(AAA,BBB,CC)
+ #define LOGTEXT4(AAA,BBB,CC,DDD) RDebug::Print(AAA,BBB,CC,DDD)
+ #define LOGHEXDUMP(AAA,BBB,CC,DDD)
+#else
+ #define LOGTEXT(AAA)
+ #define LOGTEXT2(AAA,BBB)
+ #define LOGTEXT3(AAA,BBB,CC)
+ #define LOGTEXT4(AAA,BBB,CC,DDD)
+ #define LOGHEXDUMP(AAA,BBB,CC,DDD)
+#endif
+
+// CLASS DECLARATION
+
+/**
+* Internal common utility class.
+* Provides commonly used functions to other internal service classes.
+*
+* @lib ExifLib
+* @since 2.6
+*/
+class TExifCommon
+ {
+ public: // New functions
+
+ /**
+ * Puts the given 32-bit unsigned integer to the 4-byte location,
+ * whose start point is specified with the given 8-bit unsigned integer
+ * pointer.
+ * @since 2.6
+ * @param aPtr 8-bit unsigned integer pointer, locating where the
+ * 32-bit unsigned integer is written.
+ * @param aUint32 32-bit unsigned integer that is written.
+ * @return void
+ */
+ static TInt SetUint32( TUint8* aPtr, TUint32 aUint32 );
+
+ /**
+ * Puts the given 16-bit unsigned integer to the 2-byte location, whose
+ * start point is specified with the given 8-bit unsigned integer pointer
+ * @since 2.6
+ * @param aPtr 8-bit unsigned integer pointer, locating where the 16-bit
+ * unsigned integer is written.
+ * @param aUint16 16-bit unsigned integer that is written.
+ * @return void
+ */
+ static TInt SetUint16( TUint8* aPtr, TUint16 aUint16 );
+
+ /**
+ * Returns a 32-bit unsigned integer from the location, whose start point
+ * is specified with the given 8-bit unsigned integer pointer.
+ * @since 2.6
+ * @param aPtr 8-bit unsigned integer pointer, locating where the 32-bit
+ * unsigned integer is read.
+ * @return 32-bit unsigned integer that is read from the specified
+ * location
+ */
+ static TUint32 Uint32L( TUint8* aPtr );
+
+ /**
+ * Returns a 16-bit unsigned integer from the location, whose start point
+ * is specified with the given 8-bit unsigned integer pointer.
+ * @since 2.6
+ * @param aPtr 8-bit unsigned integer pointer, locating where the 16-bit
+ * unsigned integer is read.
+ * @return 16-bit unsigned integer that is read from the specified
+ * location
+ */
+ static TUint16 Uint16L( TUint8* aPtr );
+
+ /**
+ * Returns a 32-bit signed integer from the location, whose start point
+ * is specified with the given 8-bit unsigned integer pointer.
+ * @since 2.6
+ * @param aPtr 8-bit unsigned integer pointer, locating where the 32-bit
+ * signed integer is read.
+ * @return 32-bit signed integer that is read from the specified location
+ */
+ static TInt32 Int32L( TUint8* aPtr );
+
+ /**
+ * Checks if the given 16-bit unsigned integer is one of the defined tag
+ * IDs
+ * @since 2.6
+ * @param aTagId 16-bit unsigned integer that is checked for validity
+ * @return Boolean stating whether the tag is valid or not.
+ */
+ static TBool IsValidTagId( TUint16 aTagId );
+
+ /**
+ * Locates the pointer to the first specified Jpeg Marker from the
+ * begining
+ * inside the given interval
+ * @since 2.6
+ * @param aMarker The Jpeg marker that is searched for.
+ * @param aStartPtr The start of the interval
+ * @param aEndPtr The end of the interval
+ * @return The pointer to the marker. NULL if not found.
+ */
+ static TUint8* LocateJpegMarkerPtr(
+ TUint16 aMarker,
+ TUint8* aStartPtr,
+ TUint8* aEndPtr);
+
+ /**
+ * Locates the pointer to the first specified Jpeg Marker from the end
+ * inside the given interval
+ * @since 2.6
+ * @param aMarker The Jpeg marker that is searched for.
+ * @param aStartPtr The start of the interval
+ * @param aEndPtr The end of the interval
+ * @return The pointer to the marker. NULL if not found.
+ */
+ static TUint8* LocateJpegMarkerPtrFromEnd(
+ TUint16 aMarker,
+ TUint8* aStartPtr,
+ TUint8* aEndPtr);
+ };
+
+#endif // EXIFCOMMON_H
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/inc/ExifCore.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,541 @@
+/*
+* Copyright (c) 2003, 2004 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: Core Exif file format handler class providing services to the
+* API classes
+*
+*/
+
+
+#ifndef EXIFCORE_H
+#define EXIFCORE_H
+
+// INCLUDES
+#include <e32base.h>
+#include "ExifRead.h"
+#include "ExifTagImpl.h"
+#include "ExifCommon.h"
+
+// FORWARD DECLARATIONS
+class CExifIfd;
+class CExifTagImpl;
+
+// CLASS DECLARATION
+
+/**
+* Exif core handler class.
+* Handles writing and reading Exif v2.2 format, and stores Exif data structures.
+*
+* @lib ExifLib
+* @since 2.6
+*/
+NONSHARABLE_CLASS( CExifCore ): public CBase
+ {
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor.
+ */
+ static CExifCore* NewL();
+
+ /**
+ * Destructor.
+ */
+ virtual ~CExifCore();
+
+ public: // New functions
+
+ /**
+ * Inserts/Updates the given tag into the specified IFD structure.
+ * @since 2.6
+ * @param aIfdType The IFD type
+ * @param aExifTag The tag instance that is updated
+ * @param aCheckValidity When ETrue then tag validity is checked
+ * @return void
+ */
+ void InsertTagL( TExifIfdType aIfdType, CExifTagImpl* aExifTag, TBool aCheckValidity );
+
+ /**
+ * Sets the given 8-bit integer to the data of a tag specified by the
+ * given tag ID.
+ * @since 2.6
+ * @param aTagId The tag ID
+ * @param aTagData The tag data that is updated
+ * @return void
+ */
+ void SetTagDataL( TUint16 aTagId, TInt8 aTagData );
+
+ /**
+ * Sets the given 16-bit unsigned integer to the data of a tag specified
+ * by the given tag ID.
+ * @since 2.6
+ * @param aTagId The tag ID
+ * @param aTagData The tag data that is updated
+ * @return void
+ */
+ void SetTagDataL( TUint16 aTagId, TUint16 aTagData );
+
+ /**
+ * Sets the given 32-bit integer to the data of a tag specified by the
+ * given tag ID.
+ * @since 2.6
+ * @param aTagId The tag ID
+ * @param aTagData The tag data that is updated
+ * @return void
+ */
+ void SetTagDataL( TUint16 aTagId, TUint32 aTagData );
+
+ /**
+ * Sets the given data buffer to the data of a tag specified by the
+ * given tag ID.
+ * @since 2.6
+ * @param aTagId The tag ID
+ * @param aTagData The tag data that is updated
+ * @return void
+ */
+ void SetTagDataL( TUint16 aTagId, const TDesC8& aTagData );
+
+ /**
+ * Sets the given 64-bit (2 x 32-bit ) unsigned integers to the data of
+ * a tag specified by the given tag ID.
+ * @since 2.6
+ * @param aTagId The tag ID
+ * @param aNumerator The first 32-bit unsigned integer (the numerator)
+ * that is updated
+ * @param aDenominator The second 32-bit unsigned integer (the
+ * Denominator) that is updated
+ * @return void
+ */
+ void SetTagDataL(
+ TUint16 aTagId,
+ TUint32 aNumerator,
+ TUint32 aDenominator );
+
+
+ /**
+ * Sets the given 64-bit (2 x 32-bit ) integers to the data of a tag
+ * specified by the given tag ID.
+ * @since 2.6
+ * @param aTagId The tag ID
+ * @param aNumerator The first 32-bit integer (the numerator) that is
+ * updated
+ * @param aDenominator The second 32-bit integer (the Denominator) that
+ * is updated
+ * @return void
+ */
+ void SetTagDataL(
+ TUint16 aTagId,
+ TInt32 aNumerator,
+ TInt32 aDenominator );
+
+
+ /**
+ * Sets the given 16-bit unsigned integer to the data of a thumbnail
+ * (IFD1) tag specified by the given tag ID.
+ * @since 2.6
+ * @param aTagId The tag ID
+ * @param aTagData The tag data that is updated
+ * @return void
+ */
+ void SetThumbnailTagDataL( TUint16 aTagId, TUint16 aTagData );
+
+ /**
+ * Sets the given 32-bit unsigned integer to the data of a thumbnail
+ * (IFD1) tag specified by the given tag ID,
+ * @since 2.6
+ * @param aTagId The tag ID
+ * @param aTagData The tag data that is updated
+ * @return void
+ */
+ void SetThumbnailTagDataL( TUint16 aTagId, TUint32 aTagData );
+
+ /**
+ * Sets the given 64-bit (2 x 32-bit ) unsigned integers to the data
+ * of a thumbnail (IFD1) tag specified by the given tag ID.
+ * @since 2.6
+ * @param aTagId The tag ID.
+ * @param aNumerator The first 32-bit unsigned integer (the numerator)
+ * that is updated.
+ * @param aDenominator The second 32-bit unsigned integer (the
+ * Denominator) that is updated.
+ * @return void
+ */
+ void SetThumbnailTagDataL(
+ TUint16 aTagId,
+ TUint32 aNumerator,
+ TUint32 aDenominator );
+
+ /**
+ * Gets the 8-bit integer data of a tag specified by the given tag ID.
+ * @since 2.6
+ * @param aTagId The tag ID.
+ * @param aTagData The tag data that is returned.
+ * @return Error code. KErrNotFound if tag doesn't exist.
+ */
+ TInt GetTagData( TUint16 aTagId, TInt8& aTagData ) const;
+
+ /**
+ * Gets the 16-bit unsigned integer data of a tag specified by the
+ * given tag ID.
+ * @since 2.6
+ * @param aTagId The tag ID.
+ * @param aTagData The tag data that is returned.
+ * @return Error code. KErrNotFound if tag doesn't exist.
+ */
+ TInt GetTagData( TUint16 aTagId, TUint16& aTagData ) const;
+
+ /**
+ * Gets the 32-bit unsigned integer data of a tag specified by the given
+ * tag ID.
+ * @since 2.6
+ * @param aTagId The tag ID.
+ * @param aTagData The tag data that is returned.
+ * @return Error code. KErrNotFound if tag doesn't exist.
+ */
+ TInt GetTagData( TUint16 aTagId, TUint32& aTagData ) const;
+
+ /**
+ * Gets the data buffer of a tag specified by the given tag ID.
+ * @since 2.6
+ * @param aTagId The tag ID.
+ * @return The tag data buffer.
+ */
+ HBufC8* GetTagDataL( TUint16 aTagId ) const;
+
+ /**
+ * Gets the 64-bit (2 x 32-bit) unsigned integer data of a tag specified
+ * by the given tag ID.
+ * @since 2.6
+ * @param aTagId The tag ID.
+ * @param aNumerator The first 32-bit unsigned integer (the numerator)
+ * that is returned.
+ * @param aDenominator The second 32-bit unsigned integer (the
+ * Denominator) that is returned.
+ * @return Error code. KErrNotFound if tag doesn't exist.
+ */
+ TInt GetTagData(
+ TUint16 aTagId,
+ TUint32& aNumerator,
+ TUint32& aDenominator ) const;
+
+ /**
+ * Gets the 64-bit (2 x 32-bit) integer data of a tag specified by the
+ * given tag ID.
+ * @since 2.6
+ * @param aTagId The tag ID.
+ * @param aNumerator The first 32-bit integer (the numerator) that is
+ * returned.
+ * @param aDenominator The second 32-bit integer (the Denominator) that
+ * is returned.
+ * @return Error code. KErrNotFound if tag doesn't exist.
+ */
+ TInt GetTagData(
+ TUint16 aTagId,
+ TInt32& aNumerator,
+ TInt32& aDenominator ) const;
+
+ /**
+ * Gets the 16-bit unsigned integer data of a thumbnail (IFD1) tag
+ * specified by the given tag ID.
+ * @since 2.6
+ * @param aTagId The tag ID.
+ * @param aTagData The tag data that is returned.
+ * @return Error code. KErrNotFound if tag doesn't exist.
+ */
+ TInt GetThumbnailTagData( TUint16 aTagId, TUint16& aTagData ) const;
+
+ /**
+ * Gets the 32-bit unsigned integer data of a thumbnail (IFD1) tag
+ * specified by the given tag ID.
+ * @since 2.6
+ * @param aTagId The tag ID.
+ * @param aTagData The tag data that is returned.
+ * @return Error code. KErrNotFound if tag doesn't exist.
+ */
+ TInt GetThumbnailTagData( TUint16 aTagId, TUint32& aTagData ) const;
+
+ /**
+ * Gets the 64-bit (2 x 32-bit) unsigned integer data of a thumbnail
+ * (IFD1) tag specified by the given tag ID.
+ * @since 2.6
+ * @param aTagId The tag ID.
+ * @param aNumerator The first 32-bit integer (the numerator) that is
+ * returned.
+ * @param aDenominator The second 32-bit integer (the Denominator) that
+ * is returned.
+ * @return Error code. KErrNotFound if tag doesn't exist.
+ */
+ TInt GetThumbnailTagData(
+ TUint16 aTagId,
+ TUint32& aNumerator,
+ TUint32& aDenominator ) const;
+
+ /**
+ * Gets the tag instance having the given tag ID from the specified
+ * IFD structure.
+ * @since 2.6
+ * @param aIfdType The hosting IFD type
+ * @param aTagId The tag ID
+ * @return Constant tag instance pointer
+ */
+ const CExifTagImpl* GetTagL(
+ TExifIfdType aIfdType,
+ TUint16 aTagId ) const;
+
+ /**
+ * Removes the tag instance having the given tag ID from the specified
+ * IFD structure.
+ * @since 2.6
+ * @param aIfdType The hosting IFD type
+ * @param aTagId The tag ID
+ * @return Error code. KErrNotFound if tag or IFD doesn't exist.
+ */
+ TInt DeleteTag( TExifIfdType aIfdType, TUint16 aTagId );
+
+ /**
+ * Gets the tag IDs and the number of tags in the specified IFD
+ * structure.
+ * @since 2.6
+ * @param aIfdType The hosting IFD type
+ * @param aNoTags The number of tag IDs returned
+ * @return Pointer to tag IDs
+ */
+ TUint16* GetTagIdsL( TExifIfdType aIfdType, TInt& aNoTags ) const;
+
+ /**
+ * Instantiates the specified IFD structure.
+ * @since 2.6
+ * @param aIfdType The target IFD type
+ * @return void
+ */
+ void CreateIfdL( TExifIfdType aIfdType );
+
+ /**
+ * Removes the specified IFD structure and all its tags.
+ * @since 2.6
+ * @param aIfdType The target IFD type
+ * @return Error code. KErrNotFound if IFD doesn't exist.
+ */
+ TInt DeleteIfd( TExifIfdType aIfdType );
+
+ /**
+ * Gets the IFD types and number of IFDs in the file format.
+ * @since 2.6
+ * @param aNoIfd The number of IFD types returned
+ * @return Pointer to IFD types
+ */
+ TExifIfdType* GetIfdTypesL( TInt& aNoIfd ) const;
+
+ /**
+ * Gets the Exif thumbnail image data from the IFD1 structure.
+ * @since 2.6
+ * @return Pointer to heap descriptor containing a copy of thumbnail
+ * image.
+ */
+ HBufC8* GetThumbnailL() const;
+
+ /**
+ * Inserts/Updates the given Exif thumbnail image data in the IFD1
+ * structure.
+ * @since 2.6
+ * @param aThumbnailData Pointer to descriptor containing new thumbnail
+ * image.
+ * @return void
+ */
+ void InsertThumbnailL( TDesC8* aThumbnailData );
+
+ /**
+ * Removes the Exif thumbnail image data from the IFD1 structure.
+ * @since 2.6
+ * @return Error code. KErrNotFounc if thumbnail image doesn't exist.
+ */
+ TInt RemoveThumbnail();
+
+ /**
+ * Writes the Exif data to the given descriptor starting from the
+ * specified position/offset.
+ * @since 2.6
+ * @param aExifData Pointer reference to the target descriptor
+ * @param aPos Offset for the start of the target data.
+ * @return void
+ */
+ void WriteExifDataL( HBufC8*& aExifData, TUint& aPos );
+
+ /**
+ * Writes the Jpeg header to the given descriptor starting from the
+ * specified position/offset.
+ * @since 2.6
+ * @param aExifData Pointer reference to the target descriptor
+ * @param aPos Offset for the start of the target data.
+ * @return void
+ */
+ void WriteJpegHeaderL( HBufC8*& aExifData, TUint& aPos );
+
+ /**
+ * Finalizes the Exif data to ensure the validity, updates the internal
+ * offsets.
+ * @since 2.6
+ * @return Error code.
+ */
+ TInt Finalize();
+
+ /**
+ * Returns the total size of the Exif file format in bytes.
+ * @since 2.6
+ * @return Total size
+ */
+ TUint TotalSize() const;
+
+ /**
+ * Returns the size of the Jpeg image in the Exif file format, excluding
+ * SOI and APP markers in bytes.
+ * @since 2.6
+ * @return Jpeg data size
+ */
+ TUint JpegSize() const;
+
+ /**
+ * Returns the size of the APP1 marker, which includes the Exif-specific
+ * data in bytes
+ * @since 2.6
+ * @return APP1 marker size
+ */
+ TUint16 App1Size() const;
+
+ /**
+ * Checks if the Exif data is in valid Exif v2.2 format and contains all
+ * mandatory information.
+ * @since 2.6
+ * @return Boolean stating if the Exif data is in valid format or not.
+ */
+ TBool IsValid() const;
+
+ /**
+ * Checks if the specified tag information conforms to the Full Validity
+ * characteristics (Data count is correct, data type matches tag ID and
+ * data value falls into the predefined range).
+ * @since 2.6
+ * @param aTagInfo The Tag information structure that will be verified.
+ * @param aIfdType The Exif Ifd for which the validity of the tag is
+ * verified.
+ * @return Boolean stating if the given Tag information is valid.
+ */
+ TBool TagIsValid( TExifTagInfo aTagInfo, TExifIfdType aIfdType ) const;
+
+ /**
+ * Checks if the specified IFD structure exists in the Exif data.
+ * @since 2.6
+ * @param aIfdType The queried IFD type
+ * @return Boolean stating if the specified IFD type exists or not.
+ */
+ TBool IfdExists( TExifIfdType aIfdType ) const;
+
+ /**
+ * Checks if the tag having the given tag ID exists in the specified
+ * IFD structure.
+ * @since 2.6
+ * @param aTagId The queried tag ID
+ * @param aIfdType The hosting IFD type
+ * @return Boolean stating if the specified tag exists or not.
+ */
+ TBool TagExists( TUint16 aTagId, TExifIfdType aIfdType ) const;
+
+ /**
+ * Sets the given Jpeg data start and end offsets.
+ * @since 2.6
+ * @param aJpgStartOffset Jpeg data start offset
+ * @param aJpgEndOffset Jpeg data end offset
+ * @return void
+ */
+ void SetJpgOffsets( TUint32 aJpgStartOffset, TUint32 aJpgEndOffset );
+
+ /**
+ * Gets the pure Jpeg image data excluding the SOI and APP1 markers.
+ * @since 2.6
+ * @param aJpegPtr Pointer to a copy of Jpeg data.
+ * @return TInt Error code.
+ */
+ TInt GetJpegData( TPtr8 aJpegPtr ) const;
+
+ /**
+ * Sets the Exif data start pointer.
+ * @since 2.6
+ * @param aPtr Pointer to the beginning of Exif data.
+ * @return void
+ */
+ void SetDataStartPtr(const TUint8* aPtr );
+
+ private:
+
+ /**
+ * C++ default constructor.
+ */
+ CExifCore();
+
+ /**
+ * By default Symbian 2nd phase constructor is private.
+ */
+ void ConstructL();
+
+ /**
+ * Writes the Exif header to the location, which is defined by the given
+ * pointer and the offset.
+ * @since 2.6
+ * @param aExifDataPtr Pointer to the target Exif data.
+ * @param aPos Offset of the Exif header.
+ * @return void
+ */
+ void WriteExifHeaderL( TUint16*& aExifDataPtr, TUint& aPos );
+
+ /**
+ * Writes the specified IFD data to the location, which is defined by the
+ * given pointer and the offset.
+ * @since 2.6
+ * @param aExifDataPtr Pointer to the target Exif data.
+ * @TExifIfdType aIfdType Written IFD structure.
+ * @param aPos Offset of the specified IFD structure.
+ * @return void
+ */
+ void WriteIfdL(
+ TUint16*& aExifDataPtr,
+ TExifIfdType aIfdType,
+ TUint& aPos );
+
+ /**
+ * Returns the offset of the specified IFD structure in the Exif data.
+ * @since 2.6
+ * @param aIfdType The queried IFD type.
+ * @return Found IFD offset.
+ */
+ TUint32 FindIfdOffset( TExifIfdType aIfdType ) const;
+
+ private: // Data
+
+ // IFD structure array, containing 0th, EXIF, 1st, GPS and
+ // Interoperability IFDs.
+ TFixedArray< CExifIfd*, KIfdNo > iIfdArray;
+
+ // Start Offset of the Jpeg image in the Exif data
+ TUint32 iJpgStartOffset;
+
+ // End Offset of the Jpeg image in the Exif data
+ TUint32 iJpgEndOffset;
+
+ // Pointer to the beginning of the Exif data.
+ const TUint8* iDataStartPtr;
+ };
+
+#endif // EXIFCORE_H
+
+// End of File
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/inc/ExifEndian.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,426 @@
+/*
+* Copyright (c) 2003, 2004 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: Exif data parser for both Little and Big Endian formats.
+*
+*/
+
+
+#ifndef EXIFENDIAN_H
+#define EXIFENDIAN_H
+
+// INCLUDES
+#include <e32base.h>
+
+// CLASS DECLARATION
+
+/**
+* Exif data parser base class.
+* Provides the base for Little and Big endian parsers.
+*
+* @lib ExifLib
+* @since 2.6
+*/
+NONSHARABLE_CLASS( CExifEndianBase ): public CBase
+ {
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor.
+ */
+ static CExifEndianBase* NewBaseL(
+ const TUint8* aExifDataPtr,
+ TUint aDataLength,
+ TBool aIsExif );
+
+ /**
+ * Destructor.
+ */
+ virtual ~CExifEndianBase();
+
+ /**
+ * Gets the next 8-bit unsigned integer from the data.
+ * @since 2.6
+ * @param aUint8 The 8-bit integer returned.
+ * @return Error code.
+ */
+ TInt ReadUint8( TUint8& aUint8 );
+
+ /**
+ * Gets the next 16-bit unsigned integer from the data.
+ * @since 2.6
+ * @param aUint16 The 16-bit integer returned.
+ * @return Error code.
+ */
+ virtual TInt ReadUInt16( TUint16& aUint16 ) = 0;
+
+ /**
+ * Gets the next 32-bit unsigned integer from the data.
+ * @since 2.6
+ * @param aUint32 The 32-bit integer returned.
+ * @return Error code.
+ */
+ virtual TInt ReadUInt32( TUint32& aUint32 ) = 0;
+
+ /**
+ * Copies the data from the location, which starts and ends with the
+ * given Jpeg Markers.
+ * @since 2.6
+ * @param aStartMarker Jpeg Marker for the beginning of copying.
+ * @param aEndMarker Jpeg Marker for the end of copying.
+ * @param aDestBuffer Pointer to the target descriptor.
+ * @param aIncludeEnd States if the ending Jpeg Marker will be copied
+ * or not.
+ * @return void
+ */
+ void CopyBufferL(
+ TUint16 aStartMarker,
+ TUint16 aEndMarker,
+ HBufC8*& aDestBuffer,
+ TBool aIncludeEnd = ETrue );
+
+ /**
+ * Copies the next specified amount of data to the given descriptor.
+ * @since 2.6
+ * @param aCount Number of words to copy
+ * @param aWordSize Word size
+ * @param aBuffer Pointer to the target descriptor.
+ * @return void
+ */
+ virtual TInt CopyBuffer(
+ TUint32 aCount,
+ TUint8 aWordSize,
+ HBufC8*& aBuffer ) = 0;
+
+ /**
+ * Copies the specified amount of data located in the given offset to
+ * the given descriptor.
+ * @since 2.6
+ * @param aOffset Offset for starting copying
+ * @param aCount Number of words to copy
+ * @param aWordSize Word size
+ * @param aBuffer Pointer to the target descriptor.
+ * @return void
+ */
+ virtual TInt CopyBuffer(
+ TUint32 aOffset,
+ TUint32 aCount,
+ TUint8 aWordSize,
+ HBufC8*& aBuffer ) = 0;
+
+ /**
+ * Moves to the specified offset.
+ * @since 2.6
+ * @param aOffset Target offset.
+ * @return Error code.
+ */
+ TInt MoveTo( TUint aOffset );
+
+ /**
+ * Moves the current position forward by the given number of bytes.
+ * @since 2.6
+ * @param aNoBytes Number of bytes to skip
+ * @return Error code.
+ */
+ TInt Skip( TUint aNoBytes );
+
+ /**
+ * Locates the offset of the next specified 8-bit unsigned integer
+ * @since 2.6
+ * @param aSearch Queried 8-bit unsigned integer
+ * @param aOffset The offset of the found location.
+ * @return Error code.
+ */
+ TInt Locate8( TUint8 aSearch, TUint32& aOffset );
+
+ /**
+ * Locates the offset of the next specified 16-bit unsigned integer
+ * @since 2.6
+ * @param aSearch Queried 16-bit integer
+ * @param aOffset The offset of the found location.
+ * @return Error code.
+ */
+ virtual TInt Locate16( TUint16 aSearch, TUint32& aOffset ) = 0;
+
+ /**
+ * Locates the offset of the specified Jpeg Marker, which resides
+ * inside the given interval.
+ * @since 2.6
+ * @param aMarker The queried Jpeg Marker
+ * @param aOffset The offset of the found location.
+ * @param aAfter Offset for starting searching.
+ * @param aBefore Offset for ending searching.
+ * @return Error code.
+ */
+ TInt LocateJpegMarker(
+ TUint16 aMarker,
+ TUint32& aOffset,
+ TUint32 aAfter = 0,
+ TUint32 aBefore = 0 );
+
+ /**
+ * Locates the offset of the last specified Jpeg Marker, which resides
+ * inside the given interval
+ * @since 2.6
+ * @param aMarker The queried Jpeg Marker
+ * @param aOffset The offset of the found location.
+ * @param aAfter Offset for starting searching.
+ * @param aBefore Offset for ending searching.
+ * @return Error code.
+ */
+ TInt LocateJpegMarkerFromEnd(
+ TUint16 aMarker,
+ TUint32& aOffset,
+ TUint32 aAfter = 0,
+ TUint32 aBefore = 0 );
+
+ /**
+ * Returns the current offset position
+ * @since 3.1
+ * @param aOffset The offset of the location.
+ * @return void.
+ */
+ void CurrentPosOffset( TUint32& aOffset );
+
+ protected:
+
+ /**
+ * C++ default constructor.
+ */
+ CExifEndianBase();
+
+ private:
+
+ /**
+ * By default Symbian 2nd phase constructor is private.
+ */
+ void ConstructL();
+
+ protected: // Data
+
+ // The offset of the current position in the Exif data.
+ TUint32 iPosOffset;
+
+ // The offset of the Exif header (APP1 header) in the Exif data.
+ TUint32 iExifStartOffset;
+
+ // The offset for the end of Exif data.
+ TUint32 iExifEndOffset;
+
+ // The pointer to the beginning of the Exif data.
+ TUint8* iDataStartPtr;
+
+ };
+
+
+/**
+* Exif data parser class for Little endian format.
+*
+* @lib ExifLib
+* @since 2.6
+*/
+NONSHARABLE_CLASS( CExifLittleEndian ): public CExifEndianBase
+ {
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor.
+ */
+ static CExifLittleEndian* NewL(
+ const TUint8* aDataStartPtr,
+ TUint8* aExifStartPtr,
+ TUint8* aExifEndPtr,
+ TBool aIsExif );
+
+ /**
+ * C++ default constructor.
+ */
+ CExifLittleEndian();
+
+ /**
+ * Destructor.
+ */
+ virtual ~CExifLittleEndian();
+
+ public: // Functions from base classes
+
+ /**
+ * From CExifEndianBase Gets the next 16-bit unsigned integer from the
+ * data.
+ * @since 2.6
+ * @param aUint16 The 16-bit integer returned.
+ * @return Error code.
+ */
+ TInt ReadUInt16( TUint16& aUint16 );
+
+ /**
+ * From CExifEndianBase Gets the next 32-bit unsigned integer from the
+ * data.
+ * @since 2.6
+ * @param aUint32 The 32-bit integer returned.
+ * @return Error code.
+ */
+ TInt ReadUInt32( TUint32& aUint32 );
+
+ /**
+ * From CExifEndianBase Copies the next specified amount of data to the
+ * given descriptor.
+ * @since 2.6
+ * @param aCount Number of words to copy
+ * @param aWordSize Word size
+ * @param aBuffer Pointer to the target descriptor.
+ * @return void
+ */
+ TInt CopyBuffer( TUint32 aCount, TUint8 aWordSize, HBufC8*& aBuffer );
+
+ /**
+ * From CExifEndianBase Copies the specified amount of data located in
+ * the given offset to the given descriptor.
+ * @since 2.6
+ * @param aOffset Offset for starting copying
+ * @param aCount Number of words to copy
+ * @param aWordSize Word size
+ * @param aBuffer Pointer to the target descriptor.
+ * @return void
+ */
+ TInt CopyBuffer(
+ TUint32 aOffset,
+ TUint32 aCount,
+ TUint8 aWordSize,
+ HBufC8*& aBuffer );
+
+ /**
+ * From CExifEndianBase Locates the offset of the next specified 16-bit
+ * unsigned integer
+ * @since 2.6
+ * @param aSearch Queried 16-bit integer
+ * @param aOffset The offset of the found location.
+ * @return Error code.
+ */
+ TInt Locate16( TUint16 aSearch, TUint32& aOffset );
+
+ private:
+
+ /**
+ * By default Symbian 2nd phase constructor is private.
+ */
+ void ConstructL(
+ TUint8* aDataStartPtr,
+ TUint8* aExifStartPtr,
+ TUint8* aExifEndPtr,
+ TBool aIsExif );
+
+ };
+
+
+/**
+* Exif data parser class for Big endian format.
+*
+* @lib ExifLib
+* @since 2.6
+*/
+NONSHARABLE_CLASS( CExifBigEndian ): public CExifEndianBase
+ {
+ public:
+
+ /**
+ * Two-phased constructor.
+ */
+ static CExifBigEndian* NewL(
+ const TUint8* aDataStartPtr,
+ TUint8* aExifStartPtr,
+ TUint8* aExifEndPtr,
+ TBool aIsExif );
+
+ /**
+ * C++ default constructor.
+ */
+ CExifBigEndian();
+
+ /**
+ * Destructor.
+ */
+ virtual ~CExifBigEndian();
+
+ public: // Functions from base classes
+
+ /**
+ * From CExifEndianBase Gets the next 16-bit unsigned integer from the
+ * data.
+ * @since 2.6
+ * @param aUint16 The 16-bit integer returned.
+ * @return Error code.
+ */
+ TInt ReadUInt16( TUint16& aUint16 );
+
+ /**
+ * From CExifEndianBase Gets the next 32-bit unsigned integer from the
+ * data.
+ * @since 2.6
+ * @param aUint32 The 32-bit integer returned.
+ * @return Error code.
+ */
+ TInt ReadUInt32( TUint32& aUint32 );
+
+ /**
+ * From CExifEndianBase Copies the next specified amount of data to the
+ * given descriptor.
+ * @since 2.6
+ * @param aCount Number of words to copy
+ * @param aWordSize Word size
+ * @param aBuffer Pointer to the target descriptor.
+ * @return void
+ */
+ TInt CopyBuffer( TUint32 aCount, TUint8 aWordSize, HBufC8*& aBuffer );
+
+ /**
+ * From CExifEndianBase Copies the specified amount of data located in
+ * the given offset to the given descriptor.
+ * @since 2.6
+ * @param aOffset Offset for starting copying
+ * @param aCount Number of words to copy
+ * @param aWordSize Word size
+ * @param aBuffer Pointer to the target descriptor.
+ * @return void
+ */
+ TInt CopyBuffer(
+ TUint32 aOffset,
+ TUint32 aCount,
+ TUint8 aWordSize,
+ HBufC8*& aBuffer );
+
+ /**
+ * From CExifEndianBase Locates the offset of the next specified 16-bit
+ * unsigned integer
+ * @since 2.6
+ * @param aSearch Queried 16-bit integer
+ * @param aOffset The offset of the found location.
+ * @return Error code.
+ */
+ TInt Locate16( TUint16 aSearch, TUint32& aOffset );
+
+ private:
+
+ /**
+ * By default Symbian 2nd phase constructor is private.
+ */
+ void ConstructL(
+ TUint8* aDataStartPtr,
+ TUint8* aExifStartPtr,
+ TUint8* aExifEndPtr,
+ TBool aIsExif );
+ };
+
+#endif // EXIFENDIAN_H
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/inc/ExifIfd.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,449 @@
+/*
+* Copyright (c) 2003, 2004 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: Exif IFD wrapper class for handling the storage of the tags
+* and manipulating IFDs.
+*
+*/
+
+
+#ifndef EXIFIFD_H
+#define EXIFIFD_H
+
+// INCLUDES
+#include "ExifRead.h"
+#include <e32base.h>
+
+// FORWARD DECLARATIONS
+class CExifTagImpl;
+
+/**
+* Exif IFD wrapper base class
+* Provides the base for the other IFD structures.
+*
+* @lib ExifLib
+* @since 2.6
+*/
+NONSHARABLE_CLASS( CExifIfd ): public CBase
+ {
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor.
+ */
+ static CExifIfd* NewBaseL( TExifIfdType aIfdType );
+
+ /**
+ * Destructor.
+ */
+ virtual ~CExifIfd();
+
+ public: // New functions
+
+ /**
+ * Checks if the IFD is in valid format, and contains all mandatory tags.
+ * @since 2.6
+ * @return Boolean stating if the IFD is valid.
+ */
+ virtual TBool IsValid() const;
+
+ /**
+ * Checks if specified tag exists in the IFD.
+ * @since 2.6
+ * @param aTagId The queried tag ID
+ * @return Boolean stating if the tag exists.
+ */
+ TBool TagExists( TUint16 aTagId ) const;
+
+ /**
+ * Returns the size of the IFD structure in bytes.
+ * @since 2.6
+ * @return Size of the IFD in bytes.
+ */
+ TUint16 Size() const;
+
+ /**
+ * Sets the next IFD offset.
+ * @since 2.6
+ * @param aIfdOffset Next IFD offset
+ * @return void
+ */
+ void SetNextIfdOffset( TUint32 aIfdOffset );
+
+ /**
+ * Writes the tag data in the IFD structure to the location defined by
+ * the given pointer and the offset.
+ * @since 2.6
+ * @param aExifDataPtr Pointer to the Exif data
+ * @param aPos Offset for the beginning of the IFD data.
+ * @return void
+ */
+ void WriteTagsL( TUint16*& aExifDataPtr, TUint& aPos ) const;
+
+ /**
+ * Inserts/Replaces the given tag in the IFD structure.
+ * @since 2.6
+ * @param aExifTag Pointer to the tag instance updated.
+ * @param aCheckValidity When ETrue then tag validity is checked
+ * @return void
+ */
+ virtual void InsertTagL( CExifTagImpl* aExifTag, TBool aCheckValidity );
+
+ /**
+ * Removes the specified tag from the IFD structure
+ * @since 2.6
+ * @param aTagId The target tag ID.
+ * @return Error code.
+ */
+ TInt DeleteTag( TUint16 aTagId );
+
+ /**
+ * Gets the unmodifiable specified tag instance from the IFD structure.
+ * @since 2.6
+ * @param aTagId The queried tag ID.
+ * @return Constant pointer to the tag instance.
+ */
+ const CExifTagImpl* GetTagL( TUint16 aTagId ) const;
+
+ /**
+ * Gets the IDs and amount of the tags existing in the IFD structure.
+ * @since 2.6
+ * @param aNoTags Number of tag IDs returned.
+ * @return Pointer to the tag IDs.
+ */
+ TUint16* GetTagIdsL( TInt& aNoTags ) const;
+
+ /**
+ * Checks if the given tag ID is one of the IDs that can be stored in
+ * the IFD structure.
+ * @since 2.6
+ * @param aTagId The queried tag ID.
+ * @return Boolean stating if the specified tag ID is valid for the IFD.
+ */
+ TBool IsAcceptableTagId( TUint16 aTagId ) const;
+
+ protected: // New functions
+
+ /**
+ * C++ default constructor.
+ */
+ CExifIfd();
+
+ private:
+
+ /**
+ * By default Symbian 2nd phase constructor is private.
+ */
+ void ConstructL();
+
+ protected:
+
+ // The tag instances stored in the IFD.
+ CArrayPtrSeg< CExifTagImpl > iTagArray;
+
+ // Type of the IFD.
+ TExifIfdType iIfdType;
+
+ // Next IFD's offset.
+ TUint32 iNextIfdOffset;
+
+ // Size of the IFD data in bytes.
+ TUint16 iSize;
+
+ };
+
+
+/**
+* Exif IFD0 wrapper class
+*
+*
+* @lib ExifLib
+* @since 2.6
+*/
+NONSHARABLE_CLASS( CExifIfd0 ) : public CExifIfd
+ {
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor.
+ */
+ static CExifIfd0* NewL();
+
+ /**
+ * C++ default constructor.
+ */
+ CExifIfd0();
+
+ /**
+ * Destructor.
+ */
+ virtual ~CExifIfd0();
+
+ public: // Functions from base classes
+
+ /**
+ * From CExifIfd Checks if the IFD is in valid format, and contains all
+ * mandatory tags.
+ * @since 2.6
+ * @return Boolean stating if the IFD is valid.
+ */
+ TBool IsValid() const;
+
+ private:
+
+ /**
+ * By default Symbian 2nd phase constructor is private.
+ */
+ void ConstructL();
+
+ };
+
+
+/**
+* Exif Exif-IFD wrapper class
+*
+*
+* @lib ExifLib
+* @since 2.6
+*/
+NONSHARABLE_CLASS( CExifIfdExif ): public CExifIfd
+ {
+ public:
+
+ /**
+ * Two-phased constructor.
+ */
+ static CExifIfdExif* NewL();
+
+ /**
+ * C++ default constructor.
+ */
+ CExifIfdExif();
+
+ /**
+ * Destructor.
+ */
+ virtual ~CExifIfdExif();
+
+ public: // Functions from base classes
+
+ /**
+ * From CExifIfd Checks if the IFD is in valid format, and contains all
+ * mandatory tags.
+ * @since 2.6
+ * @return Boolean stating if the IFD is valid.
+ */
+ TBool IsValid() const;
+
+ private:
+
+ /**
+ * By default Symbian 2nd phase constructor is private.
+ */
+ void ConstructL();
+ };
+
+
+/**
+* Exif IFD1 wrapper class
+*
+*
+* @lib ExifLib
+* @since 2.6
+*/
+NONSHARABLE_CLASS( CExifIfd1 ): public CExifIfd
+ {
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor.
+ */
+ static CExifIfd1* NewL();
+
+ /**
+ * C++ default constructor.
+ */
+ CExifIfd1();
+
+ /**
+ * Destructor.
+ */
+ virtual ~CExifIfd1();
+
+ public: // New functions
+
+ /**
+ * Inserts/Updates the given Exif thumbnail image.
+ * @since 2.6
+ * @param aThumbnailData The Exif thumbnail image data that is updated
+ * @return Error code.
+ */
+ TInt SetThumbnailData( TDesC8* aThumbnailData );
+
+ /**
+ * Gets the Exif thumbnail image.
+ * @since 2.6
+ * @param aThumbnailData The Exif thumbnail image data returned.
+ * @return Error code.
+ */
+ TInt GetThumbnailData( TDesC8*& aThumbnailData ) const;
+
+ /**
+ * Removes the Exif thumbnail image.
+ * @since 2.6
+ * @return Error code.
+ */
+ TInt RemoveThumbnailData();
+
+ /**
+ * Returns the size of the Exif thumbnail image in bytes.
+ * @since 2.6
+ * @return Thumbnail image size
+ */
+ TUint16 ThumbnailSize() const;
+
+ /**
+ * Writes the Exif thumbnail image to the location defined by the given
+ * pointer and the offset.
+ * @since 2.6
+ * @param aExifDataPtr Pointer to the Exif data.
+ * @param aPos Offset for the beginning of the thumbnail image data.
+ * @return Thumbnail image size
+ */
+ void WriteThumbnailL( TUint8*& aExifDataPtr, TUint& aPos ) const;
+
+ public: // Functions from base classes
+
+ /**
+ * From CExifIfd Checks if the IFD is in valid format, and contains all
+ * mandatory tags.
+ * @since 2.6
+ * @return Boolean stating if the IFD is valid.
+ */
+ TBool IsValid() const;
+
+ /**
+ * From CExifIfd Inserts/Replaces the given tag in the IFD structure.
+ * @since 2.6
+ * @param aExifTag Pointer to the tag instance updated.
+ * @param aCheckValidity When ETrue then tag validity is checked
+ * @return void
+ */
+ void InsertTagL( CExifTagImpl* aExifTag, TBool aCheckValidity );
+
+ private:
+ /**
+ * By default Symbian 2nd phase constructor is private.
+ */
+ void ConstructL();
+
+ private:
+
+ // Pointer to the descriptor containing thumbnail image data.
+ TDesC8* iThumbnailBuffer;
+ };
+
+
+/**
+* Exif Interoperability IFD wrapper class
+*
+*
+* @lib ExifLib
+* @since 2.6
+*/
+NONSHARABLE_CLASS( CExifIfdIntOp ): public CExifIfd
+ {
+ public:
+
+ /**
+ * Two-phased constructor.
+ */
+ static CExifIfdIntOp* NewL();
+
+ /**
+ * C++ default constructor.
+ */
+ CExifIfdIntOp();
+
+ /**
+ * Destructor.
+ */
+ virtual ~CExifIfdIntOp();
+
+ public: // Functions from base classes
+
+ /**
+ * From CExifIfd Checks if the IFD is in valid format, and contains all
+ * mandatory tags.
+ * @since 2.6
+ * @return Boolean stating if the IFD is valid.
+ */
+ TBool IsValid() const;
+
+ private:
+
+ /**
+ * By default Symbian 2nd phase constructor is private.
+ */
+ void ConstructL();
+ };
+
+
+/**
+* Exif Gps IFD wrapper class
+*
+*
+* @lib ExifLib
+* @since 2.6
+*/
+
+NONSHARABLE_CLASS( CExifIfdGps ): public CExifIfd
+ {
+ public:
+
+ /**
+ * Two-phased constructor.
+ */
+ static CExifIfdGps* NewL();
+
+ /**
+ * C++ default constructor.
+ */
+ CExifIfdGps();
+
+ /**
+ * Destructor.
+ */
+ virtual ~CExifIfdGps();
+
+ public: // Functions from base classes
+
+ /**
+ * From CExifIfd Checks if the IFD is in valid format, and contains all
+ * mandatory tags.
+ * @since 2.6
+ * @return Boolean stating if the IFD is valid.
+ */
+ TBool IsValid() const;
+
+ private:
+
+ /**
+ * By default Symbian 2nd phase constructor is private.
+ */
+ void ConstructL();
+ };
+
+#endif // EXIFIFD_H
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/inc/ExifModifyImpl.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,590 @@
+/*
+* Copyright (c) 2003, 2004 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: Exif file format creator/modifier class implementation
+*
+*/
+
+
+#ifndef EXIFMODIFYIMPL_H
+#define EXIFMODIFYIMPL_H
+
+// INCLUDES
+#include "ExifModify.h"
+
+// CONSTANTS
+
+// MACROS
+
+// DATA TYPES
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+class CExifReadImpl;
+class CExifCore;
+
+/**
+* CExifModify
+* Implementation class for modifying existing Exif v2.2 (or prior) file
+* format or creating Exif v2.2 file format using valid Jpeg image.
+* An instance of this class can be instantiated in one of two ways:
+* by providing valid Exif data or by providing valid Jpeg image.
+*
+* @lib ExifLib.lib
+* @since 2.6
+*/
+NONSHARABLE_CLASS( CExifModifyImpl ): public CExifModify
+ {
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor.
+ */
+ static CExifModifyImpl* NewL( const TDesC8& aExifData, TBool aCreate, TUint aExifModifyOption );
+
+ /**
+ * Two-phased constructor.
+ */
+ static CExifModifyImpl* NewL();
+
+ /**
+ * Destructor.
+ */
+ virtual ~CExifModifyImpl();
+
+ protected: // Functions from base classes
+
+ /**
+ * From CExifModify. Returns a constant pointer to a CExifRead instance
+ * that can be used to parse the associated Exif image.
+ * @since 2.6
+ * @return Unmodifiable pointer to Exif reader instance.
+ */
+ const CExifRead* Reader() const;
+
+ /**
+ * From CExifModify. Inserts/Updates the given tag in the specified IFD
+ * structure of the Exif data.
+ * @since 2.6
+ * @param aIfdType The hosting IFD type.
+ * @param aExifTagInfo The informative fields of tag that is updated.
+ * @param aExifData Data of the tag that is updated.
+ * @return void
+ */
+ void SetTagL(
+ TExifIfdType aIfdType,
+ TExifTagInfo aExifTagInfo,
+ const TDesC8& aTagData );
+
+ /**
+ * From CExifModify. Removes the tag with the given tag ID from the
+ * specified IFD structure in the Exif data.
+ * @since 2.6
+ * @param aIfdType The hosting IFD type.
+ * @param aTagId The target tag ID.
+ * @return Error code.
+ */
+ TInt DeleteTag( TExifIfdType aIfdType, TUint16 aTagId );
+
+ /**
+ * From CExifModify. Removes the specified IFD structure and all its tags
+ * from the Exif data.
+ * @since 2.6
+ * @param aIfdType The target IFD type.
+ * @return Error code.
+ */
+ TInt DeleteIfd( TExifIfdType aIfdType );
+
+ /**
+ * From CExifModify. Inserts/Updates the given thumbnail Jpeg image data
+ * into the 1st IFD structure in the Exif data.
+ * @since 2.6
+ * @param aThumbnailData The Exif thumbnail image data that is updated.
+ * @return void
+ */
+ void SetThumbnailL( const TDesC8& aThumbnailData );
+
+ /**
+ * From CExifModify. Removes the thumbnail Jpeg image data from the 1st
+ * IFD structure in the Exif data.
+ * @since 2.6
+ * @return Error code.
+ */
+ TInt RemoveThumbnail();
+
+ /**
+ * From CExifModify. Flushes the Exif data into the given data buffer,
+ * and releases the internal structures.
+ * @since 2.6
+ * @param aInData The original Exif image data, which contains identical
+ * data provided while calling the NewL function.
+ * @return Pointer to descriptor containing new Exif image data.
+ */
+ HBufC8* WriteDataL( const TDesC8& aInData );
+
+ /**
+ * From CExifModify. Inserts/Updates given Image Description in the Exif
+ * data.
+ * @since 2.6
+ * @param aImageDescription Updated Image Description data.
+ * @return void
+ */
+ void SetImageDescriptionL( const TDesC8& aImageDescription );
+
+ /**
+ * From CExifModify. Inserts/Updates given Make in the Exif data.
+ * @since 2.6
+ * @param aMake Updated Make data.
+ * @return void
+ */
+ void SetMakeL( const TDesC8& aMake );
+
+ /**
+ * From CExifModify. Inserts/Updates given Model in the Exif data.
+ * @since 2.6
+ * @param aModel Updated Model data.
+ * @return void
+ */
+ void SetModelL( const TDesC8& aModel );
+
+ /**
+ * From CExifModify. Inserts/Updates given Orientation in the Exif data.
+ * @since 2.6
+ * @param aOrientation Updated Orientation data.
+ * @return void
+ */
+ void SetOrientationL( TUint16 aOrientation );
+
+ /**
+ * From CExifModify. Inserts/Updates given X Resolution in the Exif data.
+ * @since 2.6
+ * @param aXResolution1 Updated X Resolution numerator.
+ * @param aXResolution2 Updated X Resolution denominator.
+ * @return void
+ */
+ void SetXResolutionL( TUint32 aXResolution1, TUint32 aXResolution2 );
+
+ /**
+ * From CExifModify. Inserts/Updates given Y Resolution in the Exif data.
+ * @since 2.6
+ * @param aYResolution1 Updated Y Resolution numerator.
+ * @param aYResolution2 Updated Y Resolution denominator.
+ * @return void
+ */
+ void SetYResolutionL( TUint32 aYResolution1, TUint32 aYResolution2 );
+
+ /**
+ * From CExifModify. Inserts/Updates given Resolution Unit in the Exif
+ * data.
+ * @since 2.6
+ * @param aResolutionUnit Updated Resolution Unit data.
+ * @return void
+ */
+ void SetResolutionUnitL( TUint16 aResolutionUnit );
+
+ /**
+ * From CExifModify. Inserts/Updates given Transfer Function in the Exif
+ * data.
+ * @since 2.6
+ * @param aTransferFunction Updated Transfer Function data.
+ * @return void
+ */
+ void SetTransferFunctionL( const TDesC8& aTransferFunction );
+
+ /**
+ * From CExifModify. Inserts/Updates given Date Time in the Exif data.
+ * @since 2.6
+ * @param aDateTime Updated Date Time data.
+ * @return void
+ */
+ void SetDateTimeL( const TDesC8& aDateTime );
+
+ /**
+ * From CExifModify. Inserts/Updates given YCbCr Positioning in the Exif
+ * data.
+ * @since 2.6
+ * @param aYCbCrPositioning YCbCr Positioning data.
+ * @return void
+ */
+ void SetYCbCrPositioningL( TUint16 aYCbCrPositioning);
+
+ /**
+ * From CExifModify. Inserts/Updates given Software in the Exif data.
+ * @since 2.6
+ * @param aSoftware Updated Software data.
+ * @return void
+ */
+ void SetSoftwareL( const TDesC8& aSoftware );
+
+ /**
+ * From CExifModify. Inserts/Updates given Copyright in the Exif data.
+ * @since 2.6
+ * @param aCopyright Updated Copyright data.
+ * @return void
+ */
+ void SetCopyrightL( const TDesC8& aCopyright );
+
+ /**
+ * From CExifModify. Inserts/Updates given Exposure Time in the Exif
+ * data.
+ * @since 2.6
+ * @param aExposureTime1 Updated Exposure Time numerator.
+ * @param aExposureTime2 Updated Exposure Time denominator.
+ * @return void
+ */
+ void SetExposureTimeL( TUint32 aExposureTime1, TUint32 aExposureTime2 );
+
+ /**
+ * From CExifModify. Inserts/Updates given Components Configuration in
+ * the Exif data.
+ * @since 2.6
+ * @param aComponentsConfiguration Updated Components Configuration data.
+ * @return void
+ */
+ void SetComponentsConfigurationL(
+ TUint8 aFirstComponent, TUint8 aSecondComponent,
+ TUint8 aThirdComponent, TUint8 aFourthComponent );
+
+ /**
+ * From CExifModify. Inserts/Updates given Flash in the Exif data.
+ * @since 2.6
+ * @param aFlash Updated Flash data.
+ * @return void
+ */
+ void SetFlashL( TUint16 aFlash );
+
+ /**
+ * From CExifModify. Inserts/Updates given Color Space in the Exif data.
+ * @since 2.6
+ * @param aColorSpace Updated Color Space data.
+ * @return void
+ */
+ void SetColorSpaceL( TUint16 aColorSpace );
+
+ /**
+ * From CExifModify. Inserts/Updates given Pixel X Dimension in the Exif
+ * data.
+ * @since 2.6
+ * @param aPixelXDimension Updated Pixel X Dimension data.
+ * @return void
+ */
+ void SetPixelXDimensionL( TUint32 aPixelXDimension );
+
+ /**
+ * From CExifModify. Inserts/Updates given Pixel Y Dimension in the Exif
+ * data.
+ * @since 2.6
+ * @param aPixelYDimension Updated Pixel Y Dimension data.
+ * @return void
+ */
+ void SetPixelYDimensionL( TUint32 aPixelYDimension );
+
+ /**
+ * From CExifModify. Inserts/Updates given Exposure Mode in the Exif
+ * data.
+ * @since 2.6
+ * @param aExposureMode Updated Exposure Mode data.
+ * @return void
+ */
+ void SetExposureModeL( TUint16 aExposureMode );
+
+ /**
+ * From CExifModify. Inserts/Updates given White Balance in the Exif
+ * data.
+ * @since 2.6
+ * @param aWhiteBalance Updated White Balance data.
+ * @return void
+ */
+ void SetWhiteBalanceL( TUint16 aWhiteBalance );
+
+ /**
+ * From CExifModify. Inserts/Updates given Scene Capture Type in the Exif
+ * data.
+ * @since 2.6
+ * @param aSceneCaptureType Updated Scene Capture Type data.
+ * @return void
+ */
+ void SetSceneCaptureTypeL( TUint16 aSceneCaptureType );
+
+
+ /**
+ * From CExifModify. Inserts/Updates given Exposure Program in the Exif
+ * data.
+ * @since 2.6
+ * @param aExposureProgram Updated Exposure Program data.
+ * @return void
+ */void SetExposureProgramL( TUint16 aExposureProgram );
+
+ /**
+ * From CExifModify. Inserts/Updates given Iso Speed Ratings in the Exif
+ * data.
+ * @since 2.6
+ * @param aIsoSpeedRatings Updated Iso Speed Ratings data.
+ * @return void
+ */
+ void SetIsoSpeedRatingsL( const TDesC8& aIsoSpeedRatings );
+
+ /**
+ * From CExifModify. Inserts/Updates given Date Time Original in the Exif
+ * data.
+ * @since 2.6
+ * @param aDateTimeOriginal Updated Date Time Original data.
+ * @return void
+ */
+ void SetDateTimeOriginalL( const TDesC8& aDateTimeOriginal );
+
+ /**
+ * From CExifModify. Inserts/Updates given Date Time Digitized in the
+ * Exif data.
+ * @since 2.6
+ * @param aDateTimeDigitized Updated Date Time Digitized data.
+ * @return void
+ */
+ void SetDateTimeDigitizedL( const TDesC8& aDateTimeDigitized );
+
+ /**
+ * From CExifModify. Inserts/Updates given Aperture Value in the Exif
+ * data.
+ * @since 2.6
+ * @param aApertureValue1 Updated Aperture Value numerator.
+ * @param aApertureValue2 Updated Aperture Value denominator.
+ * @return void
+ */
+ void SetApertureValueL(
+ TUint32 aApertureValue1,
+ TUint32 aApertureValue2 );
+
+ /**
+ * From CExifModify. Inserts/Updates given Exposure Bias Value in the
+ * Exif data.
+ * @since 2.6
+ * @param aExposureBiasValue1 Updated Exposure Bias Value numerator.
+ * @param aExposureBiasValue2 Updated Exposure Bias Value denominator.
+ * @return void
+ */
+ void SetExposureBiasValueL(
+ TInt32 aExposureBiasValue1,
+ TInt32 aExposureBiasValue2 );
+
+ /**
+ * From CExifModify. Inserts/Updates given Metering Mode in the Exif data.
+ * @since 2.6
+ * @param aMeteringMode Updated Metering Mode data.
+ * @return void
+ */
+ void SetMeteringModeL( TUint16 aMeteringMode );
+
+ /**
+ * From CExifModify. Inserts/Updates given Light Source in the Exif data.
+ * @since 2.6
+ * @param aLightSource Updated Light Source data.
+ * @return void
+ */
+ void SetLightSourceL( TUint16 aLightSource );
+
+ /**
+ * From CExifModify. Inserts/Updates given Maker Note in the Exif data.
+ * @since 2.6
+ * @param aMakerNote Updated Maker Note data.
+ * @return void
+ */
+ void SetMakerNoteL( const TDesC8& aMakerNote );
+
+ /**
+ * From CExifModify. Inserts/Updates given User Comment in the Exif data.
+ * @since 2.6
+ * @param aUserComment Updated User Comment data.
+ * @return void
+ */
+ void SetUserCommentL( const TDesC8& aUserComment );
+
+ /**
+ * From CExifModify. Inserts/Updates given Related Sound File in the Exif
+ * data.
+ * @since 2.6
+ * @param aRelatedSoundFile Updated Related Sound File data.
+ * @return void
+ */
+ void SetRelatedSoundFileL( const TDesC8& aRelatedSoundFile );
+
+ /**
+ * From CExifModify. Inserts/Updates given File Source in the Exif data.
+ * @since 2.6
+ * @param aFileSource Updated File Source data.
+ * @return void
+ */
+ void SetFileSourceL( TInt8 aFileSource );
+
+ /**
+ * From CExifModify. Inserts/Updates given Digital Zoom Ratio in the Exif
+ * data.
+ * @since 2.6
+ * @param aDigitalZoomRatio1 Updated Digital Zoom Ratio numerator.
+ * @param aDigitalZoomRatio2 Updated Digital Zoom Ratio denominator.
+ * @return void
+ */
+ void SetDigitalZoomRatioL(
+ TUint32 aDigitalZoomRatio1,
+ TUint32 aDigitalZoomRatio2 );
+
+ /**
+ * From CExifModify. Inserts/Updates given Contrast in the Exif data.
+ * @since 2.6
+ * @param aContrast Updated Contrast data.
+ * @return void
+ */
+ void SetContrastL( TUint16 aContrast );
+
+ /**
+ * From CExifModify. Inserts/Updates given Saturation in the Exif data.
+ * @since 2.6
+ * @param aSaturation Updated Saturation data.
+ * @return void
+ */
+ void SetSaturationL( TUint16 aSaturation );
+
+ /**
+ * From CExifModify. Inserts/Updates given Sharpness in the Exif data.
+ * @since 2.6
+ * @param aSharpness Updated Sharpness data.
+ * @return void
+ */
+ void SetSharpnessL( TUint16 aSharpness );
+
+ /**
+ * From CExifModify. Inserts/Updates given thumbnail X Resolution in the
+ * Exif data.
+ * @since 2.6
+ * @param aXResolution1 Updated thumbnail X Resolution numerator.
+ * @param aXResolution2 Updated thumbnail X Resolution numerator.
+ * @return void
+ */
+ void SetThumbnailXResolutionL(
+ TUint32 aXResolution1,
+ TUint32 aXResolution2 );
+
+ /**
+ * From CExifModify. Inserts/Updates given thumbnail Y Resolution in the
+ * Exif data.
+ * @since 2.6
+ * @param aYResolution1 Updated thumbnail Y Resolution numerator.
+ * @param aYResolution2 Updated thumbnail Y Resolution numerator.
+ * @return void
+ */
+ void SetThumbnailYResolutionL(
+ TUint32 aYResolution1,
+ TUint32 aYResolution2 );
+
+ /**
+ * From CExifModify. Inserts/Updates given thumbnail Resolution Unit in
+ * the Exif data.
+ * @since 2.6
+ * @param aResolutionUnit Updated thumbnail Resolution Unit data.
+ * @return void
+ */
+ void SetThumbnailResolutionUnitL( TUint16 aResolutionUnit );
+
+ /**
+ * From CExifModify. Inserts/Updates given Shutter Speed Value in the
+ * Exif data.
+ * @since 2.6
+ * @param aShutterSpeedValue1 Updated Shutter Speed Value numerator.
+ * @param aShutterSpeedValue2 Updated Shutter Speed Value denominator.
+ * @return void
+ */
+ void SetShutterSpeedValueL(
+ TInt32 aShutterSpeedValue1,
+ TInt32 aShutterSpeedValue2 );
+
+ /**
+ * From CExifModify. Inserts/Updates given Brightness Value in the Exif
+ * data.
+ * @since 2.6
+ * @param aBrightnessValue1 Updated Brightness Value numerator.
+ * @param aBrightnessValue2 Updated Brightness Value denominator.
+ * @return void
+ */
+ void SetBrightnessValueL(
+ TInt32 aBrightnessValue1,
+ TInt32 aBrightnessValue2 );
+
+ /**
+ * From CExifModify. Inserts/Updates given CustomRendered in the Exif
+ * data.
+ * @since 2.6
+ * @param aCustomRendered Updated Custom Rendered data.
+ * @return void
+ */
+ void SetCustomRenderedL( TUint16 aCustomRendered );
+
+ /**
+ * From CExifModify. Inserts/Updates given Gain Control in the Exif
+ * data.
+ * @since 2.6
+ * @param aGainControl Updated Gain Control data.
+ * @return void
+ */
+ void SetGainControlL( TUint16 aGainControl );
+
+ private:
+
+ /**
+ * C++ default constructor.
+ */
+ CExifModifyImpl();
+
+ /**
+ * By default Symbian 2nd phase constructor is private.
+ */
+ void ConstructL( const TDesC8& aExifData, TBool aCreate, TUint aExifModifyOption );
+
+ /**
+ * By default Symbian 2nd phase constructor is private.
+ */
+ void ConstructL();
+
+ private:
+
+ // Exif reader class
+ CExifReadImpl* iExifRead;
+
+ // Core Exif data structure storing the IFDs and tags.
+ CExifCore* iExifCore;
+
+ // The first 4 bytes of the data provided during instantiation.
+ // Used for cross-checking while returning the final Exif data.
+ TUint32 iCrossCheckBegin;
+
+ // The 4 bytes in the middle of the data provided during instantiation.
+ // Used for cross-checking while returning the final Exif data.
+ TUint32 iCrossCheckMiddle;
+
+ // The 4 bytes at the end of the data provided during instantiation.
+ // Used for cross-checking while returning the final Exif data.
+ TUint32 iCrossCheckEnd;
+
+ // The length of the data provided during instantiation.
+ // Used for cross-checking while returning the final Exif data.
+ TInt iCrossCheckLength;
+
+ private:
+
+ // Exif modify options
+ TUint iExifModifyOption;
+
+ }; // CExifModifyImpl
+
+#endif // EXIFMODIFYIMPL_H
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/inc/ExifReadImpl.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,691 @@
+/*
+* Copyright (c) 2003, 2004 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: Exif file format parser ( reader ) class implementation
+*
+*/
+
+
+#ifndef EXIFREADIMPL_H
+#define EXIFREADIMPL_H
+
+// INCLUDES
+#include "ExifRead.h"
+#include "ExifValueTable.h"
+
+// CONSTANTS
+
+// MACROS
+
+// DATA TYPES
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+class CExifEndianBase;
+class CExifCore;
+
+// CLASS DECLARATION
+
+/**
+* CExifReadImpl
+* Implementation class for parsing Exif v2.2 file format. An instance of this
+* class can be instantiated providing valid Exif data.
+*
+* @lib ExifLib
+* @since 2.6
+*/
+NONSHARABLE_CLASS( CExifReadImpl ): public CExifRead
+ {
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor.
+ */
+ static CExifReadImpl* NewL( const TDesC8& aExifData, TBool aCreate, TUint aExifReadOption );
+
+ /**
+ * Two-phased constructor.
+ */
+ static CExifReadImpl* NewL();
+
+ /**
+ * Destructor.
+ */
+ virtual ~CExifReadImpl();
+
+ public: // Functions from base classes
+
+ /**
+ * From CExifRead. Returns the Tag instance, which has the specified ID
+ * from the requested IFD.
+ * @since 2.6
+ * @param aIfdType The hosting IFD type
+ * @param aTagId The queried tag ID.
+ * @return Unmodifiable tag instance returned.
+ */
+ const CExifTag* GetTagL( TExifIfdType aIfdType, TUint16 aTagId ) const;
+
+ /**
+ * From CExifRead. Returns the IDs of all the tags that are stored in
+ * the Exif data.
+ * @since 2.6
+ * @param aIfdType The hosting IFD type.
+ * @param aNoTags Number of tag IDs returned.
+ * @return Pointer to the tag IDs.
+ */
+ TUint16* GetTagIdsL( TExifIfdType aIfdType, TInt& aNoTags ) const;
+
+ /**
+ * From CExifRead. Returns the types of the IFDs stored in the Exif data.
+ * @since 2.6
+ * @param aNoIfd Number of IFD types returned.
+ * @return Pointer to the IFD types.
+ */
+ TExifIfdType* GetIfdTypesL( TInt& aNoIfd ) const;
+
+ /**
+ * From CExifRead. Returns pointer to a copy of the thumbnail image data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing a copy of the Exif
+ * thumbnail image.
+ */
+ HBufC8* GetThumbnailL() const;
+
+ /**
+ * From CExifRead. Returns a boolean stating if the queried IFD
+ * structure exists in the Exif data.
+ * @since 2.6
+ * @param aIfdType The queried IFD type.
+ * @return Boolean stating if the specified IFD exists or not.
+ */
+ TBool IfdExists( TExifIfdType aIfdType ) const;
+
+ /**
+ * From CExifRead. Returns a boolean stating if the queried tag exists
+ * in the specified IFD structure.
+ * @since 2.6
+ * @param aTagId Queried tag ID.
+ * @param aIfdType The hosting IFD type.
+ * @return Boolean stating if the specified tag exists or not.
+ */
+ TBool TagExists( TUint16 aTagId, TExifIfdType aIfdType ) const;
+
+ /**
+ * From CExifRead. Gets the Image Description tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Image
+ * Description data.
+ */
+ HBufC8* GetImageDescriptionL() const;
+
+ /**
+ * From CExifRead. Gets the Make tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Make data.
+ */
+ HBufC8* GetMakeL() const;
+
+ /**
+ * From CExifRead. Gets the Model tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Model data.
+ */
+ HBufC8* GetModelL() const;
+
+ /**
+ * From CExifRead. Gets the Transfer Function tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Transfer
+ * Function data.
+ */
+ HBufC8* GetTransferFunctionL() const;
+
+ /**
+ * From CExifRead. Gets the Date Time tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Date Time
+ * data.
+ */
+ HBufC8* GetDateTimeL() const;
+
+ /**
+ * From CExifRead. Gets the Software tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Software
+ * data.
+ */
+ HBufC8* GetSoftwareL() const;
+
+ /**
+ * From CExifRead. Gets the Copyright tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Copyright
+ * data.
+ */
+ HBufC8* GetCopyrightL() const;
+
+ /**
+ * From CExifRead. Gets the Orientation tag data.
+ * @since 2.6
+ * @param aOrientation Returned Orientation data.
+ * @return Error code.
+ */
+ TInt GetOrientation( TUint16& aOrientation ) const;
+
+ /**
+ * From CExifRead. Gets the X Resolution tag data.
+ * @since 2.6
+ * @param aXResolution1 Returned X Resolution numerator.
+ * @param aXResolution2 Returned X Resolution denominator.
+ * @return Error code.
+ */
+ TInt GetXResolution(
+ TUint32& aXResolution1,
+ TUint32& aXResolution2 ) const;
+
+ /**
+ * From CExifRead. Gets the Y Resolution tag data.
+ * @since 2.6
+ * @param aYResolution1 Returned Y Resolution numerator.
+ * @param aYResolution2 Returned Y Resolution denominator.
+ * @return Error code.
+ */
+ TInt GetYResolution(
+ TUint32& aYResolution1,
+ TUint32& aYResolution2 ) const;
+
+ /**
+ * From CExifRead. Gets the Resolution Unit tag data.
+ * @since 2.6
+ * @param aResolutionUnit Returned Resolution Unit data.
+ * @return Error code.
+ */
+ TInt GetResolutionUnit( TUint16& aResolutionUnit ) const;
+
+ /**
+ * From CExifRead. Gets the YCbCr Positioning tag data.
+ * @since 2.6
+ * @param aYCbCrPositioning Returned YCbCr Positioning data.
+ * @return Error code.
+ */
+ TInt GetYCbCrPositioning( TUint16& aYCbCrPositioning ) const;
+
+ /**
+ * From CExifRead. Gets the Exif Ifd Pointer tag data.
+ * @since 2.6
+ * @param aExifIfdPointer Returned Exif Ifd Pointer data.
+ * @return Error code.
+ */
+ TInt GetExifIfdPointer( TUint32& aExifIfdPointer ) const;
+
+ /**
+ * From CExifRead. Gets the Gps Info Ifd Pointer tag data.
+ * @since 2.6
+ * @param aGpsInfoIfdPointer Returned Gps Info Ifd Pointer data.
+ * @return Error code.
+ */
+ TInt GetGpsInfoIfdPointer( TUint32& aGpsInfoIfdPointer ) const;
+
+ /**
+ * From CExifRead. Gets the Iso Speed Ratings tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Iso Speed
+ * Ratings data.
+ */
+ HBufC8* GetIsoSpeedRatingsL() const;
+
+ /**
+ * From CExifRead. Gets the Date Time Original tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Date Time
+ * Original data.
+ */
+ HBufC8* GetDateTimeOriginalL() const;
+
+ /**
+ * From CExifRead. Gets the Date Time Digitized tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Date Time
+ * Digitized data.
+ */
+ HBufC8* GetDateTimeDigitizedL() const;
+
+ /**
+ * From CExifRead. Gets the Maker Note tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Maker Note
+ * data.
+ */
+ HBufC8* GetMakerNoteL() const;
+
+ /**
+ * From CExifRead. Gets the User Comment tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the User Comment
+ * data.
+ */
+ HBufC8* GetUserCommentL() const;
+
+ /**
+ * From CExifRead. Gets the Related Sound File tag data.
+ * @since 2.6
+ * @return Pointer to the descriptor containing copy of the Related
+ * Sound File data.
+ */
+ HBufC8* GetRelatedSoundFileL() const;
+
+ /**
+ * From CExifRead. Gets the Exposure Time tag data.
+ * @since 2.6
+ * @param ExposureTime Returned Exposure Time data.
+ * @return Error code.
+ */
+ TInt GetExposureTime(
+ TUint32& aExposureTime1,
+ TUint32& aExposureTime2 ) const;
+
+ /**
+ * From CExifRead. Gets the Components Configuration tag data.
+ * @since 2.6
+ * @param aComponentsConfiguration Returned Components Configuration
+ * data.
+ * @return Error code.
+ */
+ TInt GetComponentsConfiguration(
+ TUint8& aFirstComponent, TUint8& aSecondComponent,
+ TUint8& aThirdComponent, TUint8& aFourthComponent) const;
+
+
+ /**
+ * From CExifRead. Gets the Flash tag data.
+ * @since 2.6
+ * @param aFlash Returned Flash data.
+ * @return Error code.
+ */
+ TInt GetFlash( TUint16& aFlash ) const;
+
+ /**
+ * From CExifRead. Gets the ColorSpace tag data.
+ * @since 2.6
+ * @param aColorSpace Returned ColorSpace data.
+ * @return Error code.
+ */
+ TInt GetColorSpace( TUint16& aColorSpace ) const;
+
+ /**
+ * From CExifRead. Gets the Pixel X Dimension tag data.
+ * @since 2.6
+ * @param aPixelXDimension Returned Pixel X Dimension data.
+ * @return Error code.
+ */
+ TInt GetPixelXDimension( TUint32& aPixelXDimension ) const;
+
+ /**
+ * From CExifRead. Gets the Pixel Y Dimension tag data.
+ * @since 2.6
+ * @param aPixelYDimension Returned Pixel Y Dimension data.
+ * @return Error code.
+ */
+ TInt GetPixelYDimension( TUint32& aPixelYDimension ) const;
+
+ /**
+ * From CExifRead. Gets the Exposure Mode tag data.
+ * @since 2.6
+ * @param aExposureMode Returned Exposure Mode data.
+ * @return Error code.
+ */
+ TInt GetExposureMode( TUint16& aExposureMode ) const;
+
+ /**
+ * From CExifRead. Gets the White Balance tag data.
+ * @since 2.6
+ * @param aWhiteBalance Returned White Balance data.
+ * @return Error code.
+ */
+ TInt GetWhiteBalance( TUint16& aWhiteBalance ) const;
+
+ /**
+ * From CExifRead. Gets the Scene Capture Type tag data.
+ * @since 2.6
+ * @param aSceneCaptureType Returned Scene Capture Type data.
+ * @return Error code.
+ */
+ TInt GetSceneCaptureType( TUint16& aSceneCaptureType ) const;
+
+ /**
+ * From CExifRead. Gets the Exposure Program tag data.
+ * @since 2.6
+ * @param aExposureProgram Returned Exposure Program data.
+ * @return Error code.
+ */
+ TInt GetExposureProgram( TUint16& aExposureProgram ) const;
+
+ /**
+ * From CExifRead. Gets the Aperture Value tag data.
+ * @since 2.6
+ * @param aApertureValue1 Returned Aperture Value numerator.
+ * @param aApertureValue2 Returned Aperture Value denominator.
+ * @return Error code.
+ */
+ TInt GetApertureValue(
+ TUint32& aApertureValue1,
+ TUint32& aApertureValue2 ) const;
+
+ /**
+ * From CExifRead. Gets the Exposure Bias Value tag data.
+ * @since 2.6
+ * @param aExposureBiasValue1 Returned Exposure Bias Value numerator.
+ * @param aExposureBiasValue1 Returned Exposure Bias Value denominator.
+ * @return Error code.
+ */
+ TInt GetExposureBiasValue(
+ TInt32& aExposureBiasValue1,
+ TInt32& aExposureBiasValue2 ) const;
+
+ /**
+ * From CExifRead. Gets the Metering Mode tag data.
+ * @since 2.6
+ * @param aMeteringMode Returned Metering Mode data.
+ * @return Error code.
+ */
+ TInt GetMeteringMode( TUint16& aMeteringMode ) const;
+
+ /**
+ * From CExifRead. Gets the Light Source tag data.
+ * @since 2.6
+ * @param aLightSource Returned Light Source data.
+ * @return Error code.
+ */
+ TInt GetLightSource( TUint16& aLightSource ) const;
+
+ /**
+ * From CExifRead. Gets the File Source tag data.
+ * @since 2.6
+ * @param aFileSource Returned File Source data.
+ * @return Error code.
+ */
+ TInt GetFileSource( TInt8& aFileSource ) const;
+
+ /**
+ * From CExifRead. Gets the Digital Zoom Ratio tag data.
+ * @since 2.6
+ * @param aDigitalZoomRatio1 Returned Digital Zoom Ratio numerator.
+ * @param aDigitalZoomRatio2 Returned Digital Zoom Ratio denominator.
+ * @return Error code.
+ */
+ TInt GetDigitalZoomRatio(
+ TUint32& aDigitalZoomRatio1,
+ TUint32& aDigitalZoomRatio2 ) const;
+
+ /**
+ * From CExifRead. Gets the Contrast tag data.
+ * @since 2.6
+ * @param aContrast Returned Contrast data.
+ * @return Error code.
+ */
+ TInt GetContrast( TUint16& aContrast ) const;
+
+ /**
+ * From CExifRead. Gets the Saturation tag data.
+ * @since 2.6
+ * @param aSaturation Returned Saturation data.
+ * @return Error code.
+ */
+ TInt GetSaturation( TUint16& aSaturation ) const;
+
+ /**
+ * From CExifRead. Gets the Sharpness tag data.
+ * @since 2.6
+ * @param aSharpness Returned Sharpness data.
+ * @return Error code.
+ */
+ TInt GetSharpness( TUint16& aSharpness ) const;
+
+ /**
+ * From CExifRead. Gets the Exif Version tag data.
+ * @since 2.6
+ * @param aExifVersion Returned Exif Version data.
+ * @return Error code.
+ */
+ TInt GetExifVersion( TUint32& aExifVersion ) const;
+
+ /**
+ * From CExifRead. Gets the Flash Pix Version tag data.
+ * @since 2.6
+ * @param aFlashPixVersion Returned Flash Pix Version data.
+ * @return Error code.
+ */
+ TInt GetFlashPixVersion( TUint32& aFlashPixVersion ) const;
+
+ /**
+ * From CExifRead. Gets the Interoperability Ifd Pointer tag data.
+ * @since 2.6
+ * @param aInteroperabilityIfdPointer Returned Interoperability Ifd
+ * Pointer data.
+ * @return Error code.
+ */
+ TInt GetInteroperabilityIfdPointer(
+ TUint32& aInteroperabilityIfdPointer ) const;
+
+ /**
+ * From CExifRead. Gets the thumbnail X Resolution tag data.
+ * @since 2.6
+ * @param aXResolution1 Returned thumbnail X Resolution numerator.
+ * @param aXResolution1 Returned thumbnail X Resolution denominator.
+ * @return Error code.
+ */
+ TInt GetThumbnailXResolution(
+ TUint32& aXResolution1,
+ TUint32& aXResolution2 ) const;
+
+ /**
+ * From CExifRead. Gets the thumbnail Y Resolution tag data.
+ * @since 2.6
+ * @param aYResolution1 Returned thumbnail Y Resolution numerator.
+ * @param aYResolution1 Returned thumbnail Y Resolution denominator.
+ * @return Error code.
+ */
+ TInt GetThumbnailYResolution(
+ TUint32& aYResolution1,
+ TUint32& aYResolution2 ) const;
+
+ /**
+ * From CExifRead. Gets the thumbnail Resolution Unit tag data.
+ * @since 2.6
+ * @param aResolutionUnit Returned thumbnail Resolution Unit data.
+ * @return Error code.
+ */
+ TInt GetThumbnailResolutionUnit( TUint16& aResolutionUnit ) const;
+
+ /**
+ * From CExifRead. Gets the thumbnail Compression tag data.
+ * @since 2.6
+ * @param aCompression Returned thumbnail Compression data.
+ * @return Error code.
+ */
+ TInt GetThumbnailCompression( TUint16& aCompression ) const;
+
+ /**
+ * From CExifRead. Gets the thumbnail Jpeg Interchange Format tag data.
+ * @since 2.6
+ * @param aJpegInterchangeFormat Returned thumbnail Jpeg Interchange
+ * Format data.
+ * @return Error code.
+ */
+ TInt GetJpegInterchangeFormat( TUint32& aJpegInterchangeFormat ) const;
+
+ /**
+ * From CExifRead. Gets the thumbnail Jpeg Interchange Format Length tag
+ * data.
+ * @since 2.6
+ * @param aJpegInterchangeFormatLength Returned thumbnail Jpeg
+ * Interchange Format Length data.
+ * @return Error code.
+ */
+ TInt GetJpegInterchangeFormatLength(
+ TUint32& aJpegInterchangeFormatLength ) const;
+
+ /**
+ * From CExifRead. Returns a copy of whole Exif APP1 segment in a
+ * descriptor.
+ * @since 2.6
+ * @return Descriptor containing the Exif APP1 segment data.
+ */
+ HBufC8* GetExifAppSegmentL() const;
+
+ /**
+ * From CExifRead. Gets the Shutter Speed Value tag data.
+ * @since 2.6
+ * @param aShutterSpeedValue1 Shutter Speed Value numerator.
+ * @param aShutterSpeedValue2 Shutter Speed Value denominator.
+ * @return Error code.
+ */
+ TInt GetShutterSpeedValue( TInt32& aShutterSpeedValue1,
+ TInt32& aShutterSpeedValue2 ) const;
+
+ /**
+ * From CExifRead. Gets the Brightness Value tag data.
+ * @since 2.6
+ * @param aBrightnessValue1 Brightness Value numerator.
+ * @param aBrightnessValue2 Brightness Value denominator.
+ * @return Error code.
+ */
+ TInt GetBrightnessValue( TInt32& aBrightnessValue1,
+ TInt32& aBrightnessValue2 ) const;
+
+ /**
+ * From CExifRead. Gets the Custom Rendered tag data.
+ * @since 2.6
+ * @param aCustomRendered Returned Custom Rendered data.
+ * @return Error code.
+ */
+ TInt GetCustomRendered( TUint16& aCustomRendered ) const;
+
+ /**
+ * From CExifRead. Gets the Gain Control tag data.
+ * @since 2.6
+ * @param aGainControl Returned Gain Control data.
+ * @return Error code.
+ */
+ TInt GetGainControl( TUint16& aGainControl ) const;
+
+ /**
+ * From CExifRead. Gets the Gps Version tag data.
+ * @since 2.6
+ * @param aGpsVersion Returned Gps Version data.
+ * @return Error code.
+ */
+ TInt GetGpsVersion( TUint32& aGpsVersion ) const;
+
+ /**
+ * Parses the Jpeg primary image data and initializes the Jpeg primary
+ * image structures.
+ * @since 2.6
+ * @return void.
+ */
+ void ParseJpegDataL( const TDesC8& aJpegData );
+
+ private:
+
+ /**
+ * C++ default constructor.
+ */
+ CExifReadImpl();
+
+ /**
+ * By default Symbian 2nd phase constructor is private.
+ */
+ void ConstructL( const TDesC8& aExifData, TBool aCreate, TUint aReadOption );
+
+ /**
+ * By default Symbian 2nd phase constructor is private.
+ */
+ void ConstructL();
+
+ private: // New functions
+
+ /**
+ * Parses the Exif data format and creates/initializes the internal
+ * Exif data structures.
+ * @since 2.6
+ * @return void.
+ */
+ void ParseExifFormatL();
+
+ /**
+ * Parses the IFD data according to the specified IFD type.
+ * Creates/initializes the internal IFD data structures.
+ * Returns the offset of the next IFD in the parameter.
+ * @since 2.6
+ * @param aIfdType The parsed IFD type
+ * @param aNextIfdOffset The next IFD offset returned.
+ * @return void.
+ */
+ void ParseIfdL( TExifIfdType aIfdType, TUint32& aNextIfdOffset );
+
+ /**
+ * Parses the Jpeg primary image data and initializes the Jpeg primary
+ * image structures.
+ * @since 2.6
+ * @return void.
+ */
+ void ParseJpegDataL();
+
+ /**
+ * Parses the Jpeg thumbnail image data and initializes the Jpeg
+ * thumbnail structures.
+ * @since 2.6
+ * @return void.
+ */
+ void ParseThumbnailL();
+
+ /**
+ * Reads the tag header, and returns the header information in the
+ * parameters.
+ * @since 2.6
+ * @param aTagId The tag ID read.
+ * @param aTagType The tag data type read
+ * @param aTagCount The number of tag data elements read.
+ * @return Error code.
+ */
+ TInt ReadTagHeader(
+ TUint16& aTagId,
+ TUint16& aTagType,
+ TUint32& aTagCount ) const;
+
+
+ private:
+
+ // Exif data reader/parser
+ CExifEndianBase* iReader;
+
+ // Core Exif data structure storing the IFDs and tags.
+ CExifCore* iExifCore;
+
+ private:
+
+ // CExifModifyImpl (only) needs to access iExifCore member of this
+ // class. Thus, it is defined as friend.
+ friend class CExifModifyImpl;
+
+ private:
+
+ // Exif read options
+ TUint iExifReadOption;
+
+ };
+
+#endif // EXIFREADIMPL_H
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/inc/ExifTagImpl.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,146 @@
+/*
+* Copyright (c) 2003, 2004 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: Exif tag wrapper implementation
+*
+*/
+
+
+
+#ifndef EXIFTAGIMPL_H
+#define EXIFTAGIMPL_H
+
+// INCLUDES
+#include "ExifTag.h"
+
+// CONSTANTS
+
+// MACROS
+
+// DATA TYPES
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// CLASS DECLARATION
+
+/**
+* CExifTagImpl
+* Implementation class for manipulating Exif Tags. An instance of this class
+* can be instantiated
+* providing the internal data to insert into the Exif data.
+*
+* @lib ExifLib
+* @since 2.6
+*/
+NONSHARABLE_CLASS( CExifTagImpl ): public CExifTag
+ {
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor.
+ */
+ static CExifTagImpl* NewL(
+ TUint16 aTagId,
+ TExifTagDataType aDataType,
+ TUint32 aDataCount,
+ HBufC8* aDataBuffer,
+ TBool aCheckValidity );
+
+ /**
+ * Two-phased constructor.
+ */
+ static CExifTagImpl* NewL( TExifTagInfo aTagInfo, HBufC8* aDataBuffer, TBool aCheckValidity );
+
+ /**
+ * Destructor.
+ */
+ virtual ~CExifTagImpl();
+
+ public: // Functions from base classes
+
+ /**
+ * Duplicate constructor. Creates an exact copy instance of the tag.
+ * @since 2.6
+ * @return Pointer to the new tag instance.
+ */
+ CExifTag* DuplicateL() const;
+
+ /**
+ * Returns the informative fields of a tag.
+ * @since 2.6
+ * @return Informative fields of the tag in associated structure.
+ */
+ TExifTagInfo TagInfo() const;
+
+ /**
+ * Returns the ID of the tag.
+ * @since 2.6
+ * @return The tag ID
+ */
+ TUint16 Id() const;
+
+ /**
+ * Returns the data type of the tag.
+ * @since 2.6
+ * @return The tag data type
+ */
+ TExifTagDataType DataType() const;
+
+ /**
+ * Returns the data count of the tag. Data count is not in bytes,
+ * it specifies the number of elements in the data type.
+ * @since 2.6
+ * @return The number of tag data elements
+ */
+ TUint32 DataCount() const;
+
+ /**
+ * Returns the data stored in the tag.
+ * @since 2.6
+ * @return Unmodifiable pointer to the tag data.
+ */
+ TPtrC8 Data() const;
+
+ /**
+ * Returns the total size of the tag in bytes.
+ * @since 2.6
+ * @return The total size of the tag in bytes
+ */
+ TUint Size() const;
+
+ private:
+
+ /**
+ * Constructor.
+ */
+ CExifTagImpl( TExifTagInfo aTagInfo );
+
+ /**
+ * By default Symbian 2nd phase constructor is private.
+ */
+ void ConstructL( HBufC8* aDataBuffer, TBool aCheckValidity );
+
+ private:
+
+ // Informative fields of a tag
+ TExifTagInfo iTagInfo;
+
+ // Data of the tag.
+ HBufC8* iData;
+
+ };
+
+#endif // EXIFTAGIMPL_H
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/inc/ExifValueTable.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,111 @@
+/*
+* Copyright (c) 2003, 2004 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: Defines Exif-specific numbers (i.e. tag IDs) used by internal
+* service classes.
+*
+*/
+
+
+#ifndef EXIFTABLE_H
+#define EXIFTABLE_H
+
+// CONSTANTS
+
+// Constant Exif data
+const TUint32 KExifVersion = 0x30323230;
+const TUint32 KFlashPixVersion = 0x30303130;
+const TUint32 KGpsVersion = 0x00000202;
+const TUint16 KCompressed = 0x0006;
+
+/* Exif Tag IDs */
+// ___________________________________________________________
+
+/* Non-modifiable tags */
+const TUint16 KIdExifIfdPointer = 0x8769;
+const TUint16 KIdGpsIfdPointer = 0x8825;
+const TUint16 KIdExifVersion = 0x9000;
+const TUint16 KIdFlashPixVersion = 0xa000;
+const TUint16 KIdCompression = 0x0103;
+const TUint16 KIdJpegInterchangeFormat = 0x0201;
+const TUint16 KIdJpegInterchangeFormatLength = 0x0202;
+const TUint16 KIdIntOpIfdPointer = 0xa005;
+const TUint16 KIdGpsVersion = 0x0000;
+
+/* Mandatory Ifd0 tags */
+const TUint16 KIdXResolution = 0x011A;
+const TUint16 KIdYResolution = 0x011B;
+const TUint16 KIdResolutionUnit = 0x0128;
+const TUint16 KIdYCbCrPositioning = 0x0213;
+// The following tag ID is also mandatory Ifd0 tag, but it is
+// already defined above.
+// const TUint16 KIdExifIfdPointer = 0x8769;
+
+/* Mandatory Exif Ifd tags */
+const TUint16 KIdComponentsConfiguration = 0x9101;
+const TUint16 KIdColorSpace = 0xA001;
+const TUint16 KIdPixelXDimension = 0xA002;
+const TUint16 KIdPixelYDimension = 0xA003;
+// The following two tag IDs are also mandatory Exif Ifd tags, but they are
+// already defined above.
+//const TUint16 KIdExifVersion = 0x9000;
+//const TUint16 KIdFlashPixVersion = 0xa000;
+
+
+/* Mandatary Ifd1 tags: */
+// The following six tag IDs are mandatory Ifd1 tags, but they are
+// already defined above.
+//const TUint16 KIdCompression = 0x0103;
+//const TUint16 KIdXResolution = 0x011A;
+//const TUint16 KIdYResolution = 0x011B;
+//const TUint16 KIdResolutionUnit = 0x0128;
+//const TUint16 KIdJpegInterchangeFormat = 0x0201; // already defined!
+//const TUint16 KIdJpegInterchangeFormatLength = 0x0202; // already defined!
+
+/* Others: */
+const TUint16 KIdImageDescription = 0x010E;
+const TUint16 KIdMake = 0x010F;
+const TUint16 KIdModel = 0x0110;
+const TUint16 KIdOrientation = 0x0112;
+const TUint16 KIdTransferFunction = 0x012D;
+const TUint16 KIdDateTime = 0x0132;
+const TUint16 KIdSoftware = 0x0131;
+const TUint16 KIdArtist = 0x013B;
+const TUint16 KIdCopyright = 0x8298;
+const TUint16 KIdExposureTime = 0x829A;
+const TUint16 KIdFlash = 0x9209;
+const TUint16 KIdExposureMode = 0xA402;
+const TUint16 KIdWhiteBalance = 0xA403;
+const TUint16 KIdSceneCaptureType = 0xA406;
+const TUint16 KIdExposureProgram = 0x8822;
+const TUint16 KIdIsoSpeedRatings = 0x8827;
+const TUint16 KIdDateTimeOriginal = 0x9003;
+const TUint16 KIdDateTimeDigitized = 0x9004;
+const TUint16 KIdApertureValue = 0x9202;
+const TUint16 KIdExposureBiasValue = 0x9204;
+const TUint16 KIdMeteringMode = 0x9207;
+const TUint16 KIdLightSource = 0x9208;
+const TUint16 KIdMakerNote = 0x927C;
+const TUint16 KIdUserComment = 0x9286;
+const TUint16 KIdRelatedSoundFile = 0xA004;
+const TUint16 KIdFileSource = 0xA300;
+const TUint16 KIdDigitalZoomRatio = 0xA404;
+const TUint16 KIdContrast = 0xA408;
+const TUint16 KIdSaturation = 0xA409;
+const TUint16 KIdSharpness = 0xA40A;
+const TUint16 KIdShutterSpeedValue = 0x9201;
+const TUint16 KIdBrightnessValue = 0x9203;
+const TUint16 KIdCustomRendered = 0xA401;
+const TUint16 KIdGainControl = 0xA407;
+
+#endif // EXIFTABLE_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/rom/ExifLib.iby Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,25 @@
+/*
+* Copyright (c) 2005 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: iby file of the ExifLib
+*
+*/
+
+
+#ifndef __EXIFLIB_IBY
+#define __EXIFLIB_IBY
+
+//ExifLib
+file=ABI_DIR\BUILD_DIR\ExifLib.dll SHARED_LIB_DIR\ExifLib.dll
+
+#endif //__EXIFLIB_IBY
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/src/ExifCommon.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,243 @@
+/*
+* Copyright (c) 2003, 2004 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: An internal service class including some utility functions.
+*
+*/
+
+
+// INCLUDE FILES
+#include "ExifCommon.h"
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// TExifCommon::SetUint32
+// Puts the given 32-bit unsigned integer to the 4-byte location, whose start
+// point is specified with the given 8-bit unsigned integer pointer.
+// -----------------------------------------------------------------------------
+//
+TInt TExifCommon::SetUint32( TUint8* aPtr, TUint32 aUint32 )
+ {
+ if ( !aPtr )
+ {
+ return KErrGeneral;
+ }
+ *( aPtr + 3 ) = STATIC_CAST( TUint8, ( aUint32 >> 24 ) & KOneByteMask );
+ *( aPtr + 2 ) = STATIC_CAST( TUint8, ( aUint32 >> 16 ) & KOneByteMask );
+ *( aPtr + 1 ) = STATIC_CAST( TUint8, ( aUint32 >> 8 ) & KOneByteMask );
+ *aPtr = STATIC_CAST( TUint8, aUint32 & KOneByteMask );
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// TExifCommon::SetUint16
+// Puts the given 16-bit unsigned integer to the 2-byte location, whose start
+// point is specified with the given 8-bit unsigned integer pointer.
+// -----------------------------------------------------------------------------
+//
+TInt TExifCommon::SetUint16( TUint8* aPtr, TUint16 aUint16 )
+ {
+ if ( !aPtr )
+ {
+ return KErrGeneral;
+ }
+ *( aPtr + 1 ) = STATIC_CAST( TUint8, ( aUint16 >> 8 ) & KOneByteMask );
+ *aPtr = STATIC_CAST( TUint8, aUint16 & KOneByteMask );
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// TExifCommon::Uint32
+// Returns a 32-bit unsigned integer from the location, whose start point is
+// specified with the given 8-bit unsigned integer pointer.
+// -----------------------------------------------------------------------------
+//
+TUint32 TExifCommon::Uint32L( TUint8* aPtr )
+ {
+ if ( !aPtr )
+ {
+ User::Leave( KErrGeneral );
+ }
+ TUint32 ret = 0;
+ ret = *( aPtr + 3 );
+ ret = ( ret << 8 ) + *( aPtr + 2 );
+ ret = ( ret << 8 ) + *( aPtr + 1 );
+ ret = ( ret << 8 ) + *aPtr;
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// TExifCommon::Int32
+// Returns a 32-bit integer from the location, whose start point is specified
+// with the given 8-bit integer pointer.
+// -----------------------------------------------------------------------------
+//
+TInt32 TExifCommon::Int32L( TUint8* aPtr )
+ {
+ if ( !aPtr )
+ {
+ User::Leave( KErrGeneral );
+ }
+ TUint32 ret = 0;
+ ret = *( aPtr + 3 );
+ ret = ( ret << 8 ) + *( aPtr + 2 );
+ ret = ( ret << 8 ) + *( aPtr + 1 );
+ ret = ( ret << 8 ) + *aPtr;
+ return STATIC_CAST( TInt32, ret );
+ }
+
+// -----------------------------------------------------------------------------
+// TExifCommon::Uint16
+// Returns a 16-bit unsigned integer from the location, whose start point is
+// specified with the given 8-bit unsigned integer pointer.
+// -----------------------------------------------------------------------------
+//
+TUint16 TExifCommon::Uint16L( TUint8* aPtr )
+ {
+ if ( !aPtr )
+ {
+ User::Leave( KErrGeneral );
+ }
+ TUint16 ret = 0;
+ ret = *( aPtr + 1 );
+ ret = STATIC_CAST( TUint16, ( ret << 8 ) + *aPtr );
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// TExifCommon::IsValidTagId
+// Checks if the given 16-bit unsigned integer is one of the defined tag IDs.
+// -----------------------------------------------------------------------------
+//
+TBool TExifCommon::IsValidTagId( TUint16 aTagId )
+ {
+ TInt i = 0;
+ for ( i = 0; i < KNoIfd0Tags; ++i )
+ {
+ if ( aTagId == ifd0Tags[i].iId )
+ {
+ return ETrue;
+ }
+ }
+ for ( i = 0; i < KNoIfdExifTags; ++i )
+ {
+ if ( aTagId == ifdExifTags[i].iId )
+ {
+ return ETrue;
+ }
+ }
+ for ( i = 0; i < KNoIfd1Tags; ++i )
+ {
+ if ( aTagId == ifd1Tags[i].iId )
+ {
+ return ETrue;
+ }
+ }
+ for ( i = 0; i < KNoIfdGpsTags; ++i )
+ {
+ if ( aTagId == ifdGpsTags[i].iId )
+ {
+ return ETrue;
+ }
+ }
+ for ( i = 0; i < KNoIfdIntOpTags; ++i )
+ {
+ if ( aTagId == ifdIntOpTags[i].iId )
+ {
+ return ETrue;
+ }
+ }
+ LOGTEXT2( _L( "ExifLib: TExifCommon::IsValidTagId() returning EFalse: aTagId=0x%x" ), aTagId );
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// TExifCommon::LocateJpegMarkerPtr
+// Locates the pointer to the first specified Jpeg Marker from the begining
+// inside the given interval.
+// -----------------------------------------------------------------------------
+//
+TUint8* TExifCommon::LocateJpegMarkerPtr(
+ TUint16 aMarker,
+ TUint8* aStartPtr,
+ TUint8* aEndPtr)
+ {
+ if ( ( !aStartPtr ) || ( !aEndPtr ) || ( !aMarker ) )
+ {
+ return NULL;
+ }
+
+ TUint16 revMarker =
+ STATIC_CAST( TUint16, ( aMarker << 8 ) + ( aMarker >> 8 ) );
+ --aStartPtr;
+ TUint16 atHand = 0;
+ TInt error = KErrNone;
+ do
+ {
+ if ( aStartPtr >= aEndPtr )
+ {
+ return NULL;
+ }
+ if ( *( ++aStartPtr ) == KMarkerStart )
+ {
+ TRAP( error, atHand = TExifCommon::Uint16L( aStartPtr ) );
+ }
+ }
+ while ( (atHand != revMarker ) && ( error == KErrNone) );
+ if ( error )
+ {
+ return NULL;
+ }
+ return aStartPtr;
+ }
+
+// -----------------------------------------------------------------------------
+// TExifCommon::LocateJpegMarkerPtrFromEnd
+// Locates the pointer to the first specified Jpeg Marker from the end
+// inside the given interval.
+// -----------------------------------------------------------------------------
+//
+TUint8* TExifCommon::LocateJpegMarkerPtrFromEnd(
+ TUint16 aMarker,
+ TUint8* aStartPtr,
+ TUint8* aEndPtr)
+ {
+ if ( ( !aStartPtr ) || ( !aEndPtr ) || ( !aMarker ) )
+ {
+ return NULL;
+ }
+
+ TUint16 revMarker =
+ STATIC_CAST( TUint16, ( aMarker << 8 ) + ( aMarker >> 8 ) );
+ --aEndPtr;
+ TUint16 atHand = 0;
+ TInt error = KErrNone;
+ do
+ {
+ if ( aEndPtr <= aStartPtr )
+ {
+ return NULL;
+ }
+ if ( *( --aEndPtr ) == KMarkerStart )
+ {
+ TRAP( error, atHand = TExifCommon::Uint16L( aEndPtr ) );
+ }
+ }
+ while ( (atHand != revMarker ) && ( error == KErrNone) );
+ if ( error )
+ {
+ return NULL;
+ }
+ return aEndPtr;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/src/ExifCore.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,1631 @@
+/*
+* Copyright (c) 2003, 2004 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: The core service class for handling Exif v2.2 File Format.
+*
+*/
+
+
+// INCLUDE FILES
+#include "ExifIfd.h"
+#include "ExifCore.h"
+#include "ExifReadImpl.h"
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CExifCore::CExifCore
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CExifCore::CExifCore()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CExifCore::ConstructL()
+ {
+ CreateIfdL( EIfd0 );
+ CreateIfdL( EIfdExif);
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CExifCore* CExifCore::NewL()
+ {
+ CExifCore* self = new( ELeave ) CExifCore();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+// Destructor
+CExifCore::~CExifCore()
+ {
+ for ( TUint i = 0; i < KIfdNo; ++i )
+ {
+ if ( iIfdArray[i] )
+ {
+ delete iIfdArray[i];
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::InsertTagL
+// Inserts the given tag into the specified IFD structure.
+// -----------------------------------------------------------------------------
+//
+void CExifCore::InsertTagL( TExifIfdType aIfdType, CExifTagImpl* aExifTag, TBool aCheckValidity )
+ {
+ LOGTEXT3( _L( "ExifLib: CExifCore::InsertTagL() entering: aIfdType=0x%x, aCheckValidity=%d" ), aIfdType, aCheckValidity);
+ switch ( aIfdType )
+ {
+ case EIfd0:
+ case EIfdExif:
+ case EIfd1:
+ case EIfdGps:
+ case EIfdIntOp:
+ if ( aCheckValidity && ( !TagIsValid( aExifTag->TagInfo(), aIfdType ) ) )
+ {
+ LOGTEXT( _L( "ExifLib: CExifCore::InsertTagL() Leaving: KErrNotSupported" ));
+ User::Leave( KErrNotSupported );
+ }
+ if ( !iIfdArray[aIfdType] )
+ {
+ // Since a new IFD should be created, 6 bytes more than tag
+ // size is required.
+ // Check if it exceeds 64K bytes after insertion.
+ if ( App1Size() + aExifTag->Size() + 6 > KMaxApp1Size )
+ {
+ LOGTEXT( _L( "ExifLib: CExifCore::InsertTagL() Leaving: KErrOverflow (>KMaxApp1Size)1" ));
+ User::Leave( KErrOverflow );
+ }
+ CreateIfdL( aIfdType );
+ TRAPD( error, iIfdArray[aIfdType]->InsertTagL( aExifTag, aCheckValidity ) );
+ if ( error != KErrNone )
+ {
+ delete( iIfdArray[aIfdType] );
+ iIfdArray[aIfdType] = 0;
+ LOGTEXT2( _L( "ExifLib: CExifCore::InsertTagL() Leaving: error=%d" ), error );
+ User::Leave( error );
+ }
+ }
+ else
+ {
+ // Check if it exceeds 64K bytes after insertion.
+ if ( !( TagExists( aExifTag->Id(), aIfdType ) ) &&
+ ( App1Size() + aExifTag->Size() > KMaxApp1Size ) )
+ {
+ LOGTEXT( _L( "ExifLib: CExifCore::InsertTagL() Leaving: KErrOverflow (>KMaxApp1Size)2" ));
+ User::Leave( KErrOverflow );
+ }
+ iIfdArray[aIfdType]->InsertTagL( aExifTag, aCheckValidity );
+ }
+ break;
+ default:
+ {
+ LOGTEXT( _L( "ExifLib: CExifCore::InsertTagL() Leaving: KErrArgument" ));
+ User::Leave( KErrArgument );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::SetTagDataL
+// Sets the given 8-bit integer to the data of tag specified by the given tag ID
+// -----------------------------------------------------------------------------
+//
+void CExifCore::SetTagDataL( TUint16 aTagId, TInt8 aTagData )
+ {
+ CExifTag::TExifTagDataType tagType = CExifTag::ETagUndefined;
+ // Total tag data size = 1 bytes.
+ TUint32 tagCount = 1;
+ TExifIfdType ifdType = EIfdExif;
+ HBufC8* buffer = HBufC8::NewL( 1 );
+ CleanupStack::PushL( buffer );
+ buffer->Des().SetLength( 1 );
+ switch ( aTagId )
+ {
+ case KIdFileSource:
+ break;
+ default:
+ {
+ LOGTEXT2( _L( "ExifLib: CExifCore::SetTagDataL() Leave( KErrNotSupported ) aTagId=0x%x" ), aTagId);
+ User::Leave( KErrNotSupported );
+ }
+ }
+ *REINTERPRET_CAST( TInt8*, CONST_CAST( TUint8*, buffer->Ptr() ) )
+ = aTagData;
+ CExifTagImpl* tag = CExifTagImpl::NewL( aTagId, tagType, tagCount, buffer, ETrue );
+ CleanupStack::Pop( buffer );
+ CleanupStack::PushL( tag );
+ InsertTagL( ifdType, tag, ETrue );
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::SetTagDataL
+// Sets the given 16-bit unsigned integer to the data of a tag specified by the
+// given tag ID.
+// -----------------------------------------------------------------------------
+//
+void CExifCore::SetTagDataL( TUint16 aTagId, TUint16 aTagData )
+ {
+ CExifTag::TExifTagDataType tagType = CExifTag::ETagShort;
+ // Total tag data size = 2 bytes.
+ // Since tag data type is 2-byte type, tagCount = 1.
+ TUint32 tagCount = 1;
+ TExifIfdType ifdType = EIfdExif;
+ HBufC8* buffer = HBufC8::NewL( 2 );
+ buffer->Des().SetLength( 2 );
+ CleanupStack::PushL( buffer );
+ switch ( aTagId )
+ {
+ case KIdCompression:
+ case KIdOrientation:
+ case KIdResolutionUnit:
+ case KIdYCbCrPositioning:
+ ifdType = EIfd0;
+ break;
+ case KIdFlash:
+ case KIdColorSpace:
+ case KIdExposureMode:
+ case KIdWhiteBalance:
+ case KIdSceneCaptureType:
+ case KIdExposureProgram:
+ case KIdMeteringMode:
+ case KIdLightSource:
+ case KIdContrast:
+ case KIdSaturation:
+ case KIdSharpness:
+ case KIdCustomRendered:
+ case KIdGainControl:
+ break;
+ default:
+ {
+ LOGTEXT2( _L( "ExifLib: CExifCore::SetTagDataL() Leave( KErrNotSupported ) 16 aTagId=0x%x" ), aTagId);
+ User::Leave( KErrNotSupported );
+ }
+ }
+ TExifCommon::SetUint16( CONST_CAST( TUint8*, buffer->Ptr() ), aTagData );
+ CExifTagImpl* tag = CExifTagImpl::NewL( aTagId, tagType, tagCount, buffer, ETrue );
+ CleanupStack::Pop( buffer );
+ CleanupStack::PushL( tag );
+ InsertTagL( ifdType, tag, ETrue );
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::SetTagDataL
+// Sets the given 32-bit integer to the data of tag specified by given tag ID
+// -----------------------------------------------------------------------------
+//
+void CExifCore::SetTagDataL( TUint16 aTagId, TUint32 aTagData )
+ {
+ CExifTag::TExifTagDataType tagType = CExifTag::ETagLong;
+
+ // Total tag data size = 4 bytes.
+ // If the tag data type is one of 4-byte types, tagCount = 1.
+ // If the tag data type is one of 1-byte types, tagCount = 4.
+ TUint32 tagCount = 1;
+ TExifIfdType ifdType = EIfdExif;
+ HBufC8* buffer = HBufC8::NewL(4 );
+ buffer->Des().SetLength(4 );
+
+ CleanupStack::PushL( buffer );
+ switch ( aTagId )
+ {
+ case KIdExifIfdPointer:
+ case KIdGpsIfdPointer:
+ ifdType = EIfd0;
+ break;
+ case KIdIntOpIfdPointer:
+ case KIdPixelXDimension:
+ case KIdPixelYDimension:
+ break;
+ case KIdComponentsConfiguration:
+ case KIdExifVersion:
+ case KIdFlashPixVersion:
+ tagType = CExifTag::ETagUndefined;
+ tagCount = 4;
+ break;
+ case KIdGpsVersion:
+ tagType = CExifTag::ETagByte;
+ tagCount = 4;
+ ifdType = EIfdGps;
+ break;
+ default:
+ {
+ LOGTEXT2( _L( "ExifLib: CExifCore::SetTagDataL() Leave( KErrNotSupported ) 32 aTagId=0x%x" ), aTagId);
+ User::Leave( KErrNotSupported );
+ }
+ }
+ TExifCommon::SetUint32( CONST_CAST( TUint8*, buffer->Ptr() ), aTagData );
+ CExifTagImpl* tag = CExifTagImpl::NewL( aTagId, tagType, tagCount, buffer, ETrue );
+ CleanupStack::Pop( buffer );
+ CleanupStack::PushL( tag );
+ InsertTagL( ifdType, tag, ETrue );
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::SetTagDataL
+// Sets the given data buffer to the data of a tag specified by the given tag ID
+// -----------------------------------------------------------------------------
+//
+void CExifCore::SetTagDataL( TUint16 aTagId, const TDesC8& aTagData )
+ {
+ if ( !aTagData.Length() )
+ {
+ User::Leave( KErrArgument );
+ }
+ CExifTag::TExifTagDataType tagType = CExifTag::ETagAscii;
+ TUint32 tagCount = aTagData.Length();
+ TExifIfdType ifdType = EIfd0;
+ switch ( aTagId )
+ {
+ case KIdImageDescription:
+ case KIdMake:
+ case KIdModel:
+ case KIdSoftware:
+ case KIdCopyright:
+ break;
+ case KIdTransferFunction:
+ tagType = CExifTag::ETagShort;
+ tagCount /= 2;
+ break;
+ case KIdDateTime:
+ break;
+ case KIdIsoSpeedRatings:
+ tagType = CExifTag::ETagShort;
+ tagCount /= 2;
+ ifdType = EIfdExif;
+ break;
+ case KIdDateTimeOriginal:
+ case KIdDateTimeDigitized:
+ case KIdRelatedSoundFile:
+ ifdType = EIfdExif;
+ break;
+ case KIdMakerNote:
+ case KIdUserComment:
+ tagType = CExifTag::ETagUndefined;
+ ifdType = EIfdExif;
+ break;
+ default:
+ {
+ LOGTEXT2( _L( "ExifLib: CExifCore::SetTagDataL() Leave( KErrNotSupported ) C8 aTagId=0x%x" ), aTagId);
+ User::Leave( KErrNotSupported );
+ }
+ }
+ // Check if ASCII string terminates with NULL character.
+ // If not add NULL.
+ HBufC8* buffer = NULL;
+ if ( ( tagType == CExifTag::ETagAscii ) &&
+ ( aTagData.Ptr()[aTagData.Length() - 1] ) )
+ {
+ ++tagCount;
+ buffer = HBufC8::NewL( aTagData.Length() + 1 );
+ buffer->Des().Copy( aTagData );
+ *( CONST_CAST( TUint8*, buffer->Des().Ptr() ) +
+ aTagData.Length() ) = NULL;
+ buffer->Des().SetLength( aTagData.Length() + 1 );
+ }
+ else
+ {
+ buffer = aTagData.AllocL();
+ }
+ CleanupStack::PushL( buffer );
+ CExifTagImpl* tag = CExifTagImpl::NewL( aTagId, tagType, tagCount, buffer, ETrue );
+ CleanupStack::Pop();
+ CleanupStack::PushL( tag );
+ InsertTagL( ifdType, tag, ETrue );
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::SetTagDataL
+// Sets the given 64-bit (2 x 32-bit ) unsigned integers to the data of a tag
+// specified by the given tag ID.
+// -----------------------------------------------------------------------------
+//
+void CExifCore::SetTagDataL(
+ TUint16 aTagId,
+ TUint32 aNumerator,
+ TUint32 aDenominator )
+ {
+ CExifTag::TExifTagDataType tagType = CExifTag::ETagRational;
+
+ // Total tag data size = 8 bytes.
+ // Since tag data type is 8-byte type, tagCount = 1.
+ TUint32 tagCount = 1;
+ TExifIfdType ifdType = EIfd0;
+ HBufC8* buffer = HBufC8::NewL( 8 );
+ buffer->Des().SetLength( 8 );
+ CleanupStack::PushL( buffer );
+ switch ( aTagId )
+ {
+ case KIdXResolution:
+ case KIdYResolution:
+ break;
+ case KIdExposureTime:
+ case KIdApertureValue:
+ case KIdDigitalZoomRatio:
+ ifdType = EIfdExif;
+ break;
+ default:
+ User::Leave( KErrNotSupported );
+ }
+ TExifCommon::SetUint32( CONST_CAST( TUint8*, buffer->Ptr() ), aNumerator );
+ TExifCommon::SetUint32(
+ CONST_CAST( TUint8*, buffer->Ptr() + 4 ), aDenominator );
+ CExifTagImpl* tag = CExifTagImpl::NewL( aTagId, tagType, tagCount, buffer, ETrue );
+ CleanupStack::Pop( buffer );
+ CleanupStack::PushL( tag );
+ InsertTagL( ifdType, tag, ETrue );
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::SetTagDataL
+// Sets the given 64-bit (2 x 32-bit ) integers to the data of a tag specified
+// by the given tag ID.
+// -----------------------------------------------------------------------------
+//
+void CExifCore::SetTagDataL(
+ TUint16 aTagId,
+ TInt32 aNumerator,
+ TInt32 aDenominator )
+ {
+ CExifTag::TExifTagDataType tagType = CExifTag::ETagSrational;
+ // Total tag data size = 8 bytes.
+ // Since tag data type is 8-byte type, tagCount = 1.
+ TUint32 tagCount = 1;
+ TExifIfdType ifdType = EIfdExif;
+ HBufC8* buffer = HBufC8::NewL( 8 );
+ buffer->Des().SetLength( 8 );
+ CleanupStack::PushL( buffer );
+ switch ( aTagId )
+ {
+ case KIdExposureBiasValue:
+ case KIdShutterSpeedValue:
+ case KIdBrightnessValue:
+ break;
+ default:
+ User::Leave( KErrNotSupported );
+ }
+ TExifCommon::SetUint32( CONST_CAST( TUint8*, buffer->Ptr() ), aNumerator );
+ TExifCommon::SetUint32(
+ CONST_CAST( TUint8*, buffer->Ptr() + 4 ), aDenominator );
+ CExifTagImpl* tag = CExifTagImpl::NewL( aTagId, tagType, tagCount, buffer, ETrue );
+ CleanupStack::Pop( buffer );
+ CleanupStack::PushL( tag );
+ InsertTagL( ifdType, tag, ETrue );
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::SetThumbnailTagDataL
+// Sets the given 16-bit unsigned integer to the data of a thumbnail (IFD1) tag
+// specified by the given tag ID.
+// -----------------------------------------------------------------------------
+//
+void CExifCore::SetThumbnailTagDataL( TUint16 aTagId, TUint16 aTagData )
+ {
+ CExifTag::TExifTagDataType tagType = CExifTag::ETagShort;
+ TUint32 tagCount = 1;
+ HBufC8* buffer = HBufC8::NewL( 2 );
+ buffer->Des().SetLength( 2 );
+ CleanupStack::PushL( buffer );
+ switch ( aTagId )
+ {
+ case KIdCompression:
+ case KIdResolutionUnit:
+ break;
+ default:
+ User::Leave( KErrNotSupported );
+ }
+ TExifCommon::SetUint16( CONST_CAST( TUint8*, buffer->Ptr() ), aTagData );
+ CExifTagImpl* tag = CExifTagImpl::NewL( aTagId, tagType, tagCount, buffer, ETrue );
+ CleanupStack::Pop( buffer );
+ CleanupStack::PushL( tag );
+ InsertTagL( EIfd1, tag, ETrue );
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::SetThumbnailTagDataL
+// Sets the given 32-bit unsigned integer to the data of a thumbnail (IFD1) tag
+// specified by the given tag ID,
+// -----------------------------------------------------------------------------
+//
+void CExifCore::SetThumbnailTagDataL( TUint16 aTagId, TUint32 aTagData )
+ {
+ CExifTag::TExifTagDataType tagType = CExifTag::ETagLong;
+ TUint32 tagCount = 1;
+ HBufC8* buffer = HBufC8::NewL( 4 );
+ buffer->Des().SetLength( 4 );
+ CleanupStack::PushL( buffer );
+ switch ( aTagId )
+ {
+ case KIdJpegInterchangeFormat:
+ case KIdJpegInterchangeFormatLength:
+ break;
+ default:
+ User::Leave( KErrNotSupported );
+ }
+ TExifCommon::SetUint32( CONST_CAST( TUint8*, buffer->Ptr() ), aTagData );
+ CExifTagImpl* tag = CExifTagImpl::NewL( aTagId, tagType, tagCount, buffer, ETrue );
+ CleanupStack::Pop( buffer );
+ CleanupStack::PushL( tag );
+ InsertTagL( EIfd1, tag, ETrue );
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::SetThumbnailTagDataL
+// Sets the given 64-bit (2 x 32-bit ) unsigned integers to the data of a
+// thumbnail (IFD1) tag specified by the given tag ID.
+// -----------------------------------------------------------------------------
+//
+void CExifCore::SetThumbnailTagDataL(
+ TUint16 aTagId,
+ TUint32 aNumerator,
+ TUint32 aDenominator )
+ {
+ CExifTag::TExifTagDataType tagType = CExifTag::ETagRational;
+ TUint32 tagCount = 1;
+ HBufC8* buffer = HBufC8::NewL( 8 );
+ buffer->Des().SetLength( 8 );
+ CleanupStack::PushL( buffer );
+ switch ( aTagId )
+ {
+ case KIdXResolution:
+ case KIdYResolution:
+ break;
+ default:
+ User::Leave( KErrNotSupported );
+ }
+ TExifCommon::SetUint32( CONST_CAST( TUint8*, buffer->Ptr() ), aNumerator );
+ TExifCommon::SetUint32(
+ CONST_CAST( TUint8*, buffer->Ptr() + 4 ), aDenominator );
+ CExifTagImpl* tag = CExifTagImpl::NewL( aTagId, tagType, tagCount, buffer, ETrue );
+ CleanupStack::Pop( buffer );
+ CleanupStack::PushL( tag );
+ InsertTagL( EIfd1, tag, ETrue );
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::GetTagData
+// Gets the 8-bit integer data of a tag specified by the given tag ID.
+// -----------------------------------------------------------------------------
+//
+TInt CExifCore::GetTagData( TUint16 aTagId, TInt8& aTagData ) const
+ {
+ TExifIfdType ifdType = EIfdExif;
+ switch ( aTagId )
+ {
+ case KIdFileSource:
+ break;
+ default:
+ return KErrNotSupported;
+ }
+ const CExifTagImpl* tag = NULL;
+ TRAPD( error, tag = GetTagL( ifdType, aTagId ) );
+ if ( ( error ) || ( !tag ) )
+ {
+ return KErrNotFound;
+ }
+ TPtrC8 tagData = tag->Data();
+ aTagData = *REINTERPRET_CAST( TInt8*, CONST_CAST( TUint8*, tagData.Ptr() ) );
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::GetTagData
+// Gets the 16-bit unsigned integer data of a tag specified by the given tag ID.
+// -----------------------------------------------------------------------------
+//
+TInt CExifCore::GetTagData( TUint16 aTagId, TUint16& aTagData ) const
+ {
+ TExifIfdType ifdType = EIfdExif;
+ switch ( aTagId )
+ {
+ case KIdFlash:
+ case KIdColorSpace:
+ case KIdExposureMode:
+ case KIdWhiteBalance:
+ case KIdSceneCaptureType:
+ case KIdExposureProgram:
+ case KIdMeteringMode:
+ case KIdLightSource:
+ case KIdContrast:
+ case KIdSaturation:
+ case KIdSharpness:
+ case KIdCustomRendered:
+ case KIdGainControl:
+ break;
+ case KIdOrientation:
+ case KIdResolutionUnit:
+ case KIdYCbCrPositioning:
+ ifdType = EIfd0;
+ break;
+ default:
+ return KErrNotSupported;
+ }
+ const CExifTagImpl* tag = NULL;
+ TRAPD( error, tag = GetTagL( ifdType, aTagId ) );
+ if ( ( error ) || ( !tag ) )
+ {
+ return KErrNotFound;
+ }
+ TPtrC8 tagData = tag->Data();
+ TRAP( error, aTagData = TExifCommon::Uint16L(
+ CONST_CAST( TUint8*, tagData.Ptr() ) ) );
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::GetTagData
+// Gets the 32-bit unsigned integer data of a tag specified by the given tag ID.
+// -----------------------------------------------------------------------------
+//
+TInt CExifCore::GetTagData( TUint16 aTagId, TUint32& aTagData ) const
+ {
+ TExifIfdType ifdType = EIfdExif;
+ switch ( aTagId )
+ {
+ case KIdComponentsConfiguration:
+ case KIdPixelXDimension:
+ case KIdPixelYDimension:
+ case KIdExifVersion:
+ case KIdFlashPixVersion:
+ case KIdIntOpIfdPointer:
+ break;
+ case KIdGpsVersion:
+ ifdType = EIfdGps;
+ break;
+ case KIdExifIfdPointer:
+ case KIdGpsIfdPointer:
+ ifdType = EIfd0;
+ break;
+ default:
+ return KErrNotSupported;
+ }
+ CExifTagImpl* tag = NULL;
+ TRAPD( error, tag =
+ CONST_CAST( CExifTagImpl*, GetTagL( ifdType, aTagId ) ) );
+ if ( ( error ) || ( !tag ) )
+ {
+ return KErrNotFound;
+ }
+ TPtrC8 tagData = tag->Data();
+ if ( tagData.Length() == 2)
+ {
+ TRAP( error, aTagData = STATIC_CAST( TUint32,
+ TExifCommon::Uint16L( CONST_CAST( TUint8*, tagData.Ptr() ) ) ) );
+ }
+ else
+ {
+ TRAP( error, aTagData = TExifCommon::Uint32L(
+ CONST_CAST( TUint8*, tagData.Ptr() ) ) );
+ }
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::GetTagDataL
+// Gets the data buffer of a tag specified by the given tag ID.
+// -----------------------------------------------------------------------------
+//
+HBufC8* CExifCore::GetTagDataL( TUint16 aTagId ) const
+ {
+ TExifIfdType ifdType = EIfd0;
+ switch ( aTagId )
+ {
+ case KIdImageDescription:
+ case KIdMake:
+ case KIdModel:
+ case KIdTransferFunction:
+ case KIdDateTime:
+ case KIdSoftware:
+ case KIdCopyright:
+ break;
+ case KIdIsoSpeedRatings:
+ case KIdDateTimeOriginal:
+ case KIdDateTimeDigitized:
+ case KIdMakerNote:
+ case KIdUserComment:
+ case KIdRelatedSoundFile:
+ ifdType = EIfdExif;
+ break;
+ default:
+ User::Leave( KErrNotSupported );
+ }
+ const CExifTagImpl* tag = GetTagL( ifdType, aTagId );
+
+ return tag->Data().AllocL();
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::GetTagData
+// Gets the 64-bit (2 x 32-bit) unsigned integer data of a tag specified by the
+// given tag ID.
+// -----------------------------------------------------------------------------
+//
+TInt CExifCore::GetTagData(
+ TUint16 aTagId,
+ TUint32& aNumerator,
+ TUint32& aDenominator ) const
+ {
+ TExifIfdType ifdType = EIfd0;
+ switch ( aTagId )
+ {
+ case KIdXResolution:
+ case KIdYResolution:
+ break;
+ case KIdExposureTime:
+ case KIdApertureValue:
+ case KIdDigitalZoomRatio:
+ ifdType = EIfdExif;
+ break;
+ default:
+ return KErrNotSupported;
+ }
+ const CExifTagImpl* tag = NULL;
+ TRAPD( error, tag = GetTagL( ifdType, aTagId ) );
+ if ( ( error ) || ( !tag ) )
+ {
+ return KErrNotFound;
+ }
+
+ TPtrC8 tagData = tag->Data();
+ TRAP( error, aNumerator = TExifCommon::Uint32L(
+ CONST_CAST( TUint8*, tagData.Ptr() ) ) );
+ if ( error )
+ {
+ return error;
+ }
+ TRAP( error, aDenominator = TExifCommon::Uint32L(
+ CONST_CAST( TUint8*, tagData.Ptr() + 4 ) ) );
+
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::GetTagData
+// Gets the 64-bit (2 x 32-bit) integer data of tag specified by the given tag
+// ID
+// -----------------------------------------------------------------------------
+//
+TInt CExifCore::GetTagData(
+ TUint16 aTagId,
+ TInt32& aNumerator,
+ TInt32& aDenominator ) const
+ {
+ TExifIfdType ifdType = EIfdExif;
+ switch ( aTagId )
+ {
+ case KIdExposureBiasValue:
+ case KIdShutterSpeedValue:
+ case KIdBrightnessValue:
+ break;
+ default:
+ return KErrNotSupported;
+ }
+ const CExifTagImpl* tag = NULL;
+ TRAPD( error, tag = GetTagL( ifdType, aTagId ) );
+ if ( ( error ) || ( !tag ) )
+ {
+ return KErrNotFound;
+ }
+
+ TPtrC8 tagData = tag->Data();
+ TRAP( error, aNumerator = TExifCommon::Int32L(
+ CONST_CAST( TUint8*, tagData.Ptr() ) ) );
+ if ( error )
+ {
+ return error;
+ }
+ TRAP( error, aDenominator = TExifCommon::Int32L(
+ CONST_CAST( TUint8*, tagData.Ptr() + 4 ) ));
+
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::GetThumbnailTagData
+// Gets the 16-bit unsigned integer data of a thumbnail (IFD1) tag specified by
+// the given tag ID.
+// -----------------------------------------------------------------------------
+//
+TInt CExifCore::GetThumbnailTagData( TUint16 aTagId, TUint16& aTagData ) const
+ {
+ LOGTEXT( _L( "ExifLib: CExifCore::GetThumbnailTagData TUint16 entering" ));
+ TExifIfdType ifdType = EIfd1;
+ switch ( aTagId )
+ {
+ case KIdResolutionUnit:
+ case KIdCompression:
+ break;
+ default:
+ LOGTEXT( _L( "ExifLib: CExifCore::GetThumbnailTagData returning: KErrNotSupported" ));
+ return KErrNotSupported;
+ }
+ const CExifTagImpl* tag = NULL;
+ TRAPD( error, tag = GetTagL( ifdType, aTagId ) );
+ if ( ( error ) || ( !tag ) )
+ {
+ LOGTEXT( _L( "ExifLib: CExifCore::GetThumbnailTagData returning: KErrNotFound" ));
+ return KErrNotFound;
+ }
+ TPtrC8 tagData = tag->Data();
+ TRAP( error, aTagData = TExifCommon::Uint16L(
+ CONST_CAST( TUint8*, tagData.Ptr() ) ) );
+ LOGTEXT2( _L( "ExifLib: CExifCore::GetThumbnailTagData returning: error=%d" ), error);
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::GetThumbnailTagData
+// Gets the 32-bit unsigned integer data of a thumbnail (IFD1) tag specified by
+// the given tag ID.
+// -----------------------------------------------------------------------------
+//
+TInt CExifCore::GetThumbnailTagData( TUint16 aTagId, TUint32& aTagData ) const
+ {
+ LOGTEXT( _L( "ExifLib: CExifCore::GetThumbnailTagData TUint32 entering" ));
+ TExifIfdType ifdType = EIfd1;
+ switch ( aTagId )
+ {
+ case KIdJpegInterchangeFormat:
+ case KIdJpegInterchangeFormatLength:
+ break;
+ default:
+ LOGTEXT( _L( "ExifLib: CExifCore::GetThumbnailTagData returning: KErrNotSupported" ));
+ return KErrNotSupported;
+ }
+ CExifTagImpl* tag = NULL;
+ TRAPD( error, tag = CONST_CAST( CExifTagImpl*, GetTagL( ifdType, aTagId ) ) );
+ if ( ( error ) || ( !tag ) )
+ {
+ LOGTEXT( _L( "ExifLib: CExifCore::GetThumbnailTagData returning: KErrNotFound" ));
+ return KErrNotFound;
+ }
+ TPtrC8 tagData = tag->Data();
+ TRAP( error, aTagData = TExifCommon::Uint32L(
+ CONST_CAST( TUint8*, tagData.Ptr() ) ) );
+ LOGTEXT2( _L( "ExifLib: CExifCore::GetThumbnailTagData returning: error=%d" ), error);
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::GetThumbnailTagData
+// Gets the 64-bit (2 x 32-bit) unsigned integer data of a thumbnail (IFD1) tag
+// specified by the given tag ID.
+// -----------------------------------------------------------------------------
+//
+TInt CExifCore::GetThumbnailTagData(
+ TUint16 aTagId,
+ TUint32& aNumerator,
+ TUint32& aDenominator ) const
+ {
+ TExifIfdType ifdType = EIfd1;
+ switch ( aTagId )
+ {
+ case KIdXResolution:
+ case KIdYResolution:
+ break;
+ default:
+ return KErrNotSupported;
+ }
+ const CExifTagImpl* tag = NULL;
+ TRAPD( error, tag = GetTagL( ifdType, aTagId ) );
+ if ( ( error ) || ( !tag ) )
+ {
+ return KErrNotFound;
+ }
+
+ TPtrC8 tagData = tag->Data();
+ TRAP( error, aNumerator =
+ TExifCommon::Uint32L( CONST_CAST( TUint8*, tagData.Ptr() ) ) );
+ if ( error )
+ {
+ return error;
+ }
+ TRAP( error, aDenominator =
+ TExifCommon::Uint32L( CONST_CAST( TUint8*, tagData.Ptr() + 4 ) ) );
+
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::GetTagL
+// Gets the tag instance having the given tag ID from the specified IFD
+// structure
+// -----------------------------------------------------------------------------
+//
+const CExifTagImpl* CExifCore::GetTagL(
+ TExifIfdType aIfdType, TUint16 aTagId ) const
+ {
+ switch ( aIfdType )
+ {
+ case EIfd0:
+ case EIfdExif:
+ case EIfd1:
+ case EIfdGps:
+ case EIfdIntOp:
+ if ( !iIfdArray[aIfdType] )
+ {
+ User::Leave( KErrNotFound );
+ }
+ return iIfdArray[aIfdType]->GetTagL( aTagId );
+ default:
+ User::Leave( KErrArgument );
+ }
+ return 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::DeleteTag
+// Removes the tag instance having the given tag ID from the specified IFD
+// structure
+// -----------------------------------------------------------------------------
+//
+TInt CExifCore::DeleteTag( TExifIfdType aIfdType, TUint16 aTagId )
+ {
+ switch ( aIfdType )
+ {
+ case EIfd0:
+ case EIfdExif:
+ case EIfd1:
+ case EIfdGps:
+ case EIfdIntOp:
+ {
+ if ( !iIfdArray[aIfdType] )
+ {
+ return KErrNotFound;
+ }
+ TInt error = iIfdArray[aIfdType]->DeleteTag( aTagId );
+ if ( error )
+ {
+ return error;
+ }
+ if ( iIfdArray[aIfdType]->Size() )
+ {
+ return KErrNone;
+ }
+ return DeleteIfd( aIfdType );
+ }
+ default:
+ return KErrArgument;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::GetTagIdsL
+// Gets the tag IDs and the number of tags in the specified IFD structure.
+// -----------------------------------------------------------------------------
+//
+TUint16* CExifCore::GetTagIdsL( TExifIfdType aIfdType, TInt& aNoTags ) const
+ {
+ switch ( aIfdType )
+ {
+ case EIfd0:
+ case EIfdExif:
+ case EIfd1:
+ case EIfdGps:
+ case EIfdIntOp:
+ if ( !iIfdArray[aIfdType] )
+ {
+ User::Leave( KErrNotFound );
+ }
+ return iIfdArray[aIfdType]->GetTagIdsL( aNoTags );
+ default:
+ User::Leave( KErrArgument );
+ }
+ return 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::iExifCore->CreateIfdL
+// Instantiates the specified IFD structure.
+// -----------------------------------------------------------------------------
+//
+void CExifCore::CreateIfdL( TExifIfdType aIfdType )
+ {
+ if ( App1Size() > ( KMaxApp1Size - 6 ) )
+ {
+ User::Leave( KErrOverflow );
+ }
+ switch ( aIfdType )
+ {
+ case EIfd0:
+ case EIfdExif:
+ case EIfd1:
+ case EIfdGps:
+ case EIfdIntOp:
+ iIfdArray[aIfdType] = CExifIfd::NewBaseL( aIfdType );
+ break;
+ default:
+ User::Leave( KErrArgument );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::DeleteIfd
+// Removes the specified IFD structure and all its tags.
+// -----------------------------------------------------------------------------
+//
+TInt CExifCore::DeleteIfd( TExifIfdType aIfdType )
+ {
+ switch ( aIfdType )
+ {
+ case EIfd0:
+ break;
+ case EIfdExif:
+ break;
+ case EIfd1:
+ iIfdArray[EIfd0]->SetNextIfdOffset( 0 );
+ break;
+ case EIfdGps:
+ iIfdArray[EIfd0]->DeleteTag( KIdGpsIfdPointer );
+ break;
+ case EIfdIntOp:
+ iIfdArray[EIfdExif]->DeleteTag( KIdIntOpIfdPointer );
+ break;
+ default:
+ return KErrArgument;
+ }
+ if ( iIfdArray[aIfdType] )
+ {
+ delete ( iIfdArray[aIfdType] );
+ iIfdArray[aIfdType] = 0;
+ return KErrNone;
+ }
+ else
+ {
+ return KErrNotFound;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::GetIfdTypesL
+// Gets the IFD types and number of IFDs in the file format.
+// -----------------------------------------------------------------------------
+//
+TExifIfdType* CExifCore::GetIfdTypesL( TInt& aNoIfd ) const
+ {
+ TInt noIfd = 0;
+ TUint i = 0;
+ for ( i = 0; i < KIfdNo; ++i )
+ {
+ if ( iIfdArray[i] )
+ {
+ ++noIfd;
+ }
+ }
+ if ( !noIfd )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ TExifIfdType* ifdTypes = STATIC_CAST( TExifIfdType*,
+ User::AllocL( sizeof( TExifIfdType ) * noIfd ) );
+ aNoIfd = noIfd;
+ noIfd = 0;
+ for ( i=EIfd0; i<=EIfdIntOp; ++i )
+ {
+ if ( iIfdArray[i] )
+ {
+ ifdTypes[noIfd] = STATIC_CAST( TExifIfdType, i );
+ ++noIfd;
+ }
+ }
+ return ifdTypes;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::GetThumbnailL
+// Gets the Exif thumbnail image data from the IFD1 structure.
+// -----------------------------------------------------------------------------
+//
+HBufC8* CExifCore::GetThumbnailL() const
+ {
+ if ( !iIfdArray[EIfd1] )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ TDesC8* thumbnailData = NULL;
+ User::LeaveIfError( ( STATIC_CAST( CExifIfd1*, iIfdArray[EIfd1] ) )->
+ GetThumbnailData( thumbnailData ) );
+
+ // Next check needed when option ENoTagChecking is used
+ if ( !thumbnailData )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ return thumbnailData->AllocL();
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::InsertThumbnailL
+// Inserts/Updates the given Exif thumbnail image data in the IFD1 structure.
+// -----------------------------------------------------------------------------
+//
+void CExifCore::InsertThumbnailL( TDesC8* aThumbnailData )
+ {
+ if ( STATIC_CAST( TUint, App1Size() + aThumbnailData->Length() ) >
+ KMaxApp1Size )
+ {
+ User::Leave( KErrOverflow );
+ }
+
+ TUint8* jpgStartPtr = CONST_CAST( TUint8*, aThumbnailData->Ptr() );
+ TUint8* jpgEndPtr = jpgStartPtr + aThumbnailData->Length();
+
+ jpgStartPtr = TExifCommon::LocateJpegMarkerPtr(
+ KSoi, jpgStartPtr, jpgEndPtr );
+ if( !jpgStartPtr )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ jpgStartPtr = TExifCommon::LocateJpegMarkerPtr(
+ KSof0, jpgStartPtr, jpgEndPtr );
+ if( !jpgStartPtr )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ jpgStartPtr = TExifCommon::LocateJpegMarkerPtr(
+ KEoi, jpgStartPtr, jpgEndPtr );
+ if( !jpgStartPtr )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ if ( !iIfdArray[EIfd1] )
+ {
+ CreateIfdL( EIfd1 );
+ }
+ User::LeaveIfError( ( STATIC_CAST( CExifIfd1*, iIfdArray[EIfd1] ) )->
+ SetThumbnailData( aThumbnailData ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::RemoveThumbnail
+// Removes the Exif thumbnail image data from the IFD1 structure.
+// -----------------------------------------------------------------------------
+//
+TInt CExifCore::RemoveThumbnail()
+ {
+ if ( !iIfdArray[EIfd1] )
+ {
+ return KErrNotFound;
+ }
+ return
+ ( STATIC_CAST( CExifIfd1*, iIfdArray[EIfd1] ) )->RemoveThumbnailData();
+ }
+
+
+// -----------------------------------------------------------------------------
+// CExifCore::WriteExifDataL
+// Writes the Exif data to the given descriptor starting from the specified
+// position/offset.
+// -----------------------------------------------------------------------------
+//
+void CExifCore::WriteExifDataL( HBufC8*& aExifData, TUint& aPos )
+ {
+ // Ensure byte alignment
+ if ( ( aExifData->Length() - aPos ) % 2 > 0 )
+ {
+ User::Leave( KErrGeneral );
+ }
+ TUint16* exifDataPtr = REINTERPRET_CAST( TUint16*,
+ CONST_CAST( TUint8*, aExifData->Ptr() ) + aPos );
+ WriteExifHeaderL( exifDataPtr, aPos );
+ WriteIfdL( exifDataPtr, EIfd0, aPos );
+ WriteIfdL( exifDataPtr, EIfdExif, aPos );
+ WriteIfdL( exifDataPtr, EIfdGps, aPos );
+ WriteIfdL( exifDataPtr, EIfdIntOp, aPos );
+ WriteIfdL( exifDataPtr, EIfd1, aPos );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::WriteJpegHeaderL
+// Writes the Jpeg header to the given descriptor starting from the specified
+// position/offset.
+// -----------------------------------------------------------------------------
+//
+void CExifCore::WriteJpegHeaderL( HBufC8*& aExifData, TUint& aPos )
+ {
+ if ( ( aExifData->Length() - aPos ) % 2 > 0 )
+ {
+ User::Leave( KErrGeneral );
+ }
+ TUint16* exifDataPtr = REINTERPRET_CAST( TUint16*,
+ CONST_CAST( TUint8*, aExifData->Ptr() ) + aPos );
+ *exifDataPtr = KSoiRev;
+ aPos+=2;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::Finalize
+// Finalizes the Exif data to ensure the validity, updates the internal offsets.
+// -----------------------------------------------------------------------------
+//
+TInt CExifCore::Finalize()
+ {
+ TInt error = 0;
+ TUint32 ifdOffset = FindIfdOffset( EIfdExif );
+ TRAP( error, SetTagDataL( KIdExifIfdPointer, ifdOffset ) );
+ if ( error )
+ {
+ return error;
+ }
+
+ ifdOffset = FindIfdOffset( EIfdGps );
+ if ( ifdOffset )
+ {
+ TRAP( error, SetTagDataL( KIdGpsIfdPointer, ifdOffset ) );
+ if ( error )
+ {
+ return error;
+ }
+ }
+ else
+ {
+ DeleteTag( EIfd0, KIdGpsIfdPointer );
+ }
+
+ ifdOffset = FindIfdOffset( EIfdIntOp );
+ if ( ifdOffset )
+ {
+ TRAP( error, SetTagDataL( KIdIntOpIfdPointer, ifdOffset ) );
+ if ( error )
+ {
+ return error;
+ }
+ }
+ else
+ {
+ DeleteTag( EIfdExif, KIdIntOpIfdPointer );
+ }
+
+ if ( iIfdArray[EIfd1] )
+ {
+ if ( !STATIC_CAST( CExifIfd1*, iIfdArray[EIfd1] )->ThumbnailSize() )
+ {
+ DeleteIfd( EIfd1 );
+ iIfdArray[EIfd0]->SetNextIfdOffset( 0 );
+ }
+ else
+ {
+ ifdOffset = FindIfdOffset( EIfd1 );
+ iIfdArray[EIfd0]->SetNextIfdOffset( ifdOffset );
+ TRAP( error, SetThumbnailTagDataL( KIdJpegInterchangeFormat,
+ STATIC_CAST( TUint32, ifdOffset + iIfdArray[EIfd1]->Size() ) ) );
+ if ( error )
+ {
+ return error;
+ }
+ TRAP( error, SetThumbnailTagDataL( KIdJpegInterchangeFormatLength,
+ STATIC_CAST( TUint32, STATIC_CAST( CExifIfd1*,
+ iIfdArray[EIfd1] )->ThumbnailSize() ) ) );
+ if ( error )
+ {
+ return error;
+ }
+ TRAP( error, SetThumbnailTagDataL( KIdCompression, KCompressed ) );
+ if ( error )
+ {
+ return error;
+ }
+ }
+ }
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::TotalSize
+// Returns the total size of the Exif file format in bytes.
+// -----------------------------------------------------------------------------
+//
+TUint CExifCore::TotalSize() const
+ {
+ return ( App1Size() + 4 + JpegSize() );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::JpegSize
+// Returns the size of the Jpeg image in the Exif file format, excluding SOI
+// and APP markers in bytes.
+// -----------------------------------------------------------------------------
+//
+TUint CExifCore::JpegSize() const
+ {
+ return iJpgEndOffset - iJpgStartOffset;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::App1Size
+// Returns the size of the APP1 marker, which includes the Exif-specific data
+// in bytes
+// -----------------------------------------------------------------------------
+//
+TUint16 CExifCore::App1Size() const
+ {
+ TUint16 app1Size = 0;
+ if ( iIfdArray[EIfd0] )
+ {
+ app1Size = STATIC_CAST( TUint16, app1Size + iIfdArray[EIfd0]->Size() );
+ }
+ if ( iIfdArray[EIfdExif] )
+ {
+ app1Size =
+ STATIC_CAST( TUint16, app1Size + iIfdArray[EIfdExif]->Size() );
+ }
+ if ( iIfdArray[EIfd1] )
+ {
+ app1Size = STATIC_CAST( TUint16, app1Size + iIfdArray[EIfd1]->Size() );
+ app1Size = STATIC_CAST( TUint16, app1Size + ( STATIC_CAST( CExifIfd1*,
+ iIfdArray[EIfd1] )->ThumbnailSize() ) );
+ }
+ if ( iIfdArray[EIfdGps] )
+ {
+ app1Size =
+ STATIC_CAST( TUint16, app1Size + iIfdArray[EIfdGps]->Size() );
+ }
+ if ( iIfdArray[EIfdIntOp] )
+ {
+ app1Size =
+ STATIC_CAST( TUint16, app1Size + iIfdArray[EIfdIntOp]->Size() );
+ }
+ return STATIC_CAST( TUint16, app1Size + 16 );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::IsValid
+// Checks if the Exif data is in valid Exif v2.2 format and contains all
+// mandatory information.
+// -----------------------------------------------------------------------------
+//
+TBool CExifCore::IsValid() const
+ {
+ if ( (!iIfdArray[EIfd0] ) || (!iIfdArray[EIfdExif] ) )
+ {
+ return EFalse;
+ }
+
+ if ( !iIfdArray[EIfd0]->IsValid() )
+ {
+ return EFalse;
+ }
+
+ if ( !iIfdArray[EIfdExif]->IsValid() )
+ {
+ return EFalse;
+ }
+
+ if ( iIfdArray[EIfd1] )
+ {
+ if ( !iIfdArray[EIfd1]->IsValid() )
+ {
+ return EFalse;
+ }
+ }
+ if ( iIfdArray[EIfdGps] )
+ {
+ if ( !iIfdArray[EIfdGps]->IsValid() )
+ {
+ return EFalse;
+ }
+ TRAPD( error, GetTagL( EIfd0, KIdGpsIfdPointer ) );
+ if ( error )
+ {
+ return EFalse;
+ }
+ }
+
+ if ( iIfdArray[EIfdIntOp] )
+ {
+ if ( !iIfdArray[EIfdIntOp]->IsValid() )
+ {
+ return EFalse;
+ }
+ TRAPD( error, GetTagL( EIfdExif, KIdIntOpIfdPointer ) );
+ if ( error )
+ {
+ return EFalse;
+ }
+ }
+
+ return ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::TagIsValid
+// Checks if the specified tag information conforms to the Full Validity
+// characteristics (Data count is correct, data type matches tag ID and data
+// value falls into the predefined range).
+// -----------------------------------------------------------------------------
+//
+TBool CExifCore::TagIsValid( TExifTagInfo aTagInfo, TExifIfdType aIfdType ) const
+ {
+ LOGTEXT3( _L( "ExifLib: CExifCore::TagIsValid() entering: aIfdType=0x%x, aTagInfo.iId=0x%x" ), aIfdType, aTagInfo.iId );
+ TInt noTags = 0;
+ const TReferenceTag* tags = NULL;
+ switch ( aIfdType )
+ {
+ case EIfd0:
+ noTags = KNoIfd0Tags;
+ tags = ifd0Tags;
+ break;
+ case EIfdExif:
+ noTags = KNoIfdExifTags;
+ tags = ifdExifTags;
+ break;
+ case EIfd1:
+ noTags = KNoIfd1Tags;
+ tags = ifd1Tags;
+ break;
+ case EIfdGps:
+ noTags = KNoIfdGpsTags;
+ tags = ifdGpsTags;
+ break;
+ case EIfdIntOp:
+ noTags = KNoIfdIntOpTags;
+ tags = ifdIntOpTags;
+ break;
+ default:
+ return EFalse;
+ }
+
+ TInt k = 0;
+ TBool found = EFalse;
+ for ( k = 0; ( k < noTags ) && ( !found ); ++k )
+ {
+ if ( tags[k].iId == aTagInfo.iId )
+ {
+ found = ETrue;
+ }
+ }
+
+ if ( !found )
+ {
+ LOGTEXT( _L( "ExifLib: CExifCore::TagIsValid() returning EFalse (tag not found)" ));
+ return EFalse;
+ }
+ // k locates the item next to the found item. Make it locate the found.
+ --k;
+
+ if ( tags[k].iDataType != TReferenceTag::ETagLongOrShort )
+ {
+ if ( tags[k].iDataType != aTagInfo.iDataType )
+ {
+ LOGTEXT2( _L( "ExifLib: CExifCore::TagIsValid() returning EFalse 1 aTagInfo.iDataType=0x%x" ), aTagInfo.iDataType );
+ return EFalse;
+ }
+ }
+ else if ( ( aTagInfo.iDataType != CExifTag::ETagShort ) &&
+ ( aTagInfo.iDataType != CExifTag::ETagLong ) )
+ {
+ LOGTEXT2( _L( "ExifLib: CExifCore::TagIsValid() returning EFalse 2 aTagInfo.iDataType=0x%x" ), aTagInfo.iDataType );
+ return EFalse;
+ }
+ else
+ {
+ // Nothing to check for this case!
+ }
+
+ if ( tags[k].iDataCount != KAny )
+ {
+ if ( tags[k].iDataCount != aTagInfo.iDataCount )
+ {
+ LOGTEXT2( _L( "ExifLib: CExifCore::TagIsValid() returning EFalse aTagInfo.iDataCount=0x%x" ), aTagInfo.iDataCount );
+ return EFalse;
+ }
+ }
+
+ LOGTEXT( _L( "ExifLib: CExifCore::TagIsValid() returning ETrue" ));
+ return ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::IfdExists
+// Checks if the specified IFD structure exists in the Exif data.
+// -----------------------------------------------------------------------------
+//
+TBool CExifCore::IfdExists( TExifIfdType aIfdType ) const
+ {
+ if ( iIfdArray[aIfdType] )
+ {
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::TagExists
+// Checks if the tag having the given tag ID exists in the specified IFD
+// structure
+// -----------------------------------------------------------------------------
+//
+TBool CExifCore::TagExists( TUint16 aTagId, TExifIfdType aIfdType ) const
+ {
+ if ( iIfdArray[aIfdType] )
+ {
+ return iIfdArray[aIfdType]->TagExists( aTagId );
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::SetJpgOffsets
+// Sets the given Jpeg data start and end offsets.
+// -----------------------------------------------------------------------------
+//
+void CExifCore::SetJpgOffsets( TUint32 aJpgStartOffset, TUint32 aJpgEndOffset )
+ {
+ iJpgStartOffset = aJpgStartOffset;
+ iJpgEndOffset = aJpgEndOffset;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::GetJpegData
+// Gets the pure Jpeg image data excluding the SOI and APP1 markers.
+// -----------------------------------------------------------------------------
+//
+TInt CExifCore::GetJpegData( TPtr8 aJpgPointer ) const
+ {
+ if ( !iJpgStartOffset )
+ {
+ return KErrGeneral;
+ }
+
+ TUint8* jpgStartPtr = CONST_CAST( TUint8*, iDataStartPtr + iJpgStartOffset );
+ if ( *jpgStartPtr != KMarkerStart )
+ {
+ return KErrGeneral;
+ }
+ aJpgPointer.Copy( jpgStartPtr, JpegSize() );
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::SetDataStartPtr
+// Sets the Exif data start pointer.
+// -----------------------------------------------------------------------------
+//
+void CExifCore::SetDataStartPtr( const TUint8* aPtr )
+ {
+ iDataStartPtr = aPtr;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::WriteExifHeaderL
+// Writes the Exif header to the location, which is defined by the given pointer
+// and the offset.
+// -----------------------------------------------------------------------------
+//
+void CExifCore::WriteExifHeaderL( TUint16*& aExifDataPtr, TUint& aPos )
+ {
+ if ( !aExifDataPtr )
+ {
+ User::Leave( KErrGeneral );
+ }
+ *aExifDataPtr++ = KApp1Rev;
+ TUint16 app1Size = App1Size();
+ *REINTERPRET_CAST( TUint8*, aExifDataPtr ) = STATIC_CAST( TUint8,
+ app1Size >> 8 );
+ *( REINTERPRET_CAST( TUint8*, aExifDataPtr ) + 1 ) = STATIC_CAST(
+ TUint8, app1Size );
+ ++aExifDataPtr;
+ TExifCommon::SetUint32( REINTERPRET_CAST( TUint8*, aExifDataPtr ),
+ KExifIdentifierRev );
+ aExifDataPtr+=2;
+ *aExifDataPtr++ = KExifPad;
+ *aExifDataPtr++ = KLittleEndian;
+ *aExifDataPtr++ = KExifDummyRev;
+ TExifCommon::SetUint32( REINTERPRET_CAST( TUint8*, aExifDataPtr ),
+ KHeaderOffset );
+ aExifDataPtr+=2;
+ aPos = 20;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::WriteIfdl
+// Writes the specified IFD data to the location, which is defined by the given
+// pointer and the offset.
+// -----------------------------------------------------------------------------
+//
+void CExifCore::WriteIfdL(
+ TUint16*& aExifDataPtr,
+ TExifIfdType aIfdType,
+ TUint& aPos )
+ {
+ if ( !aExifDataPtr )
+ {
+ User::Leave( KErrGeneral );
+ }
+ if ( iIfdArray[aIfdType] )
+ {
+ iIfdArray[aIfdType]->WriteTagsL( aExifDataPtr, aPos );
+ if ( aIfdType == EIfd1 )
+ {
+ (STATIC_CAST( CExifIfd1*, iIfdArray[aIfdType] ) )->WriteThumbnailL(
+ REINTERPRET_CAST( TUint8*&, aExifDataPtr ), aPos );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CExifCore::FindIfdOffset
+// Returns the offset of the specified IFD structure in the Exif data.
+// -----------------------------------------------------------------------------
+//
+TUint32 CExifCore::FindIfdOffset( TExifIfdType aIfdType ) const
+ {
+ if ( !iIfdArray[aIfdType] )
+ {
+ return 0;
+ }
+ TUint32 offset = 8;
+ switch ( aIfdType )
+ {
+ case EIfd0:
+ break;
+ case EIfdExif:
+ offset += ( iIfdArray[EIfd0]->Size() );
+ break;
+ case EIfd1:
+ offset += ( iIfdArray[EIfd0]->Size() + iIfdArray[EIfdExif]->Size() );
+ if ( iIfdArray[EIfdGps] )
+ {
+ offset += iIfdArray[EIfdGps]->Size();
+ }
+ if ( iIfdArray[EIfdIntOp] )
+ {
+ offset += iIfdArray[EIfdIntOp]->Size();
+ }
+ break;
+ case EIfdGps:
+ offset += ( iIfdArray[EIfd0]->Size() + iIfdArray[EIfdExif]->Size() );
+ break;
+ case EIfdIntOp:
+ offset += ( iIfdArray[EIfd0]->Size() + iIfdArray[EIfdExif]->Size() );
+ if ( iIfdArray[EIfdGps] )
+ {
+ offset += iIfdArray[EIfdGps]->Size();
+ }
+ break;
+ default:
+ return 0;
+ }
+ return offset;
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/src/ExifEndian.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,781 @@
+/*
+* Copyright (c) 2003, 2004 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: Exif data parser, that can parse both Little and Big endian
+* formats
+*
+*/
+
+
+// INCLUDE FILES
+#include "ExifEndian.h"
+#include "ExifCommon.h"
+
+// ============================ CLASS CExifEndianBase ==========================
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CExifEndianBase::CExifEndianBase
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CExifEndianBase::CExifEndianBase()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CExifEndianBase::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CExifEndianBase::ConstructL()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CExifEndianBase::NewBaseL
+// Two-phased constructor. Instantiates and returns relevant derived class.
+// -----------------------------------------------------------------------------
+//
+CExifEndianBase* CExifEndianBase::NewBaseL(
+ const TUint8* aExifDataPtr,
+ TUint aDataLength,
+ TBool aIsExif )
+ {
+ //
+ // Parse header.
+ // Find SOI (FFD8 )
+ // ptr = SOI pos.
+ // Then check the following 10 bytes:
+ // APP1 Marker (FFE1) + APP1 Length (no check) + Identifier ("Exif"00) +
+ // Pad (00) (no check)
+
+ //TUint8* dataStartPtr = CONST_CAST( TUint8*, aExifData.Ptr() );
+ if ( !aExifDataPtr )
+ {
+ User::Leave( KErrGeneral );
+ }
+ TUint8* ptr = CONST_CAST( TUint8*, aExifDataPtr ) - 1;
+ TUint8 *pE = CONST_CAST( TUint8*, aExifDataPtr ) + aDataLength;
+
+ // Locate the SOI marker.
+ do
+ {
+ if ( ptr == pE )
+ {
+ User::Leave( KErrCorrupt );
+ }
+ }
+ while ( *++ptr != KMarkerStart );
+
+ if ( *( ptr + 1 ) != KSoiEnd )
+ {
+ User::Leave( KErrCorrupt );
+ }
+ // ptr is now at SOI.
+
+ // If original is Exif, check whether it is Little- or Big-endian.
+ // Otherwise create Little-endian reader.
+ if ( aIsExif )
+ {
+ // Locate the APP1 marker
+ do
+ {
+ do
+ {
+ if ( ptr == pE )
+ {
+ User::Leave( KErrCorrupt );
+ }
+ }
+ while ( *++ptr != KMarkerStart );
+ }
+ while ( *( ptr + 1 ) != KApp1End );
+ // ptr is now at APP1
+ // Skip App1 length.
+ ptr += 4;
+
+ // Check the APP1 and Exif header.
+ if ( TExifCommon::Uint32L( ptr ) != KExifIdentifierRev )
+ {
+ User::Leave( KErrCorrupt );
+ }
+ ptr += 4;
+
+ // Padding 0 after 8 bytes of data. No need to check, skip.
+ //if ( ( *ptr ) != 0)
+ // {
+ // User::Leave( KErrCorrupt );
+ // }
+ ptr += 2;
+
+ // Check if little- or big- endian, and create the reader.
+ if ( TExifCommon::Uint16L( ptr ) == KLittleEndian )
+ {
+ return CExifLittleEndian::NewL( aExifDataPtr, ptr, pE, aIsExif );
+ }
+ else if ( TExifCommon::Uint16L( ptr ) == KBigEndian )
+ {
+ return CExifBigEndian::NewL( aExifDataPtr, ptr, pE, aIsExif );
+ }
+ else // None of the formats match!!
+ {
+ User::Leave( KErrCorrupt );
+ }
+ }
+ else
+ {
+ return CExifLittleEndian::NewL( aExifDataPtr, ptr, pE, aIsExif );
+ }
+
+ return NULL;
+ }
+
+// Destructor
+CExifEndianBase::~CExifEndianBase()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CExifEndianBase::CopyBufferL
+// Copies the data from the location, which starts and ends with the given
+// Jpeg Markers.
+// -----------------------------------------------------------------------------
+//
+void CExifEndianBase::CopyBufferL(
+ TUint16 aStartMarker,
+ TUint16 aEndMarker,
+ HBufC8*& aDestBuffer,
+ TBool aIncludeEnd )
+ {
+ TUint32 startOffset = 0;
+ if ( LocateJpegMarker( aStartMarker, startOffset ) )
+ {
+ User::Leave( KErrCorrupt );
+ }
+ TUint32 endOffset = 0;
+ if ( LocateJpegMarker( aEndMarker, endOffset ) )
+ {
+ User::Leave( KErrCorrupt );
+ }
+ TUint32 size = endOffset - startOffset;
+ if ( aIncludeEnd )
+ {
+ size += 2;
+ }
+ aDestBuffer = HBufC8::NewL( size );
+ CleanupStack::PushL( aDestBuffer );
+
+ iPosOffset = startOffset;
+
+ CopyBuffer( size, 1 , aDestBuffer );
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CExifEndianBase::ReadUint8
+// Gets the next 8-bit unsigned integer from the data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifEndianBase::ReadUint8( TUint8& aInt8 )
+ {
+ if ( iPosOffset + 1 >= iExifEndOffset )
+ {
+ return KErrCorrupt;
+ }
+ aInt8 = *( iDataStartPtr + iPosOffset );
+ ++iPosOffset;
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifEndianBase::MoveTo
+// Moves to the specified offset.
+// -----------------------------------------------------------------------------
+//
+TInt CExifEndianBase::MoveTo( TUint aOffset )
+ {
+ if ( iExifStartOffset + aOffset >= iExifEndOffset )
+ {
+ return KErrCorrupt;
+ }
+ iPosOffset = iExifStartOffset + aOffset;
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifEndianBase::Skip
+// Moves the current position forward by the given number of bytes.
+// -----------------------------------------------------------------------------
+//
+TInt CExifEndianBase::Skip( TUint aNoBytes )
+ {
+ if ( iPosOffset + aNoBytes >= iExifEndOffset )
+ {
+ return KErrCorrupt;
+ }
+ iPosOffset += aNoBytes;
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifEndianBase::Locate8
+// Locates the offset of the next specified 8-bit unsigned integer
+// -----------------------------------------------------------------------------
+//
+TInt CExifEndianBase::Locate8( TUint8 aSearch, TUint32& aOffset )
+ {
+ TUint8 *pBuf = iDataStartPtr + iPosOffset;
+ TUint8 *pB = pBuf - 1;
+ TUint8* pE = iDataStartPtr + iExifEndOffset;
+ do
+ {
+ if ( pB == pE )
+ {
+ return KErrCorrupt;
+ }
+ }
+ while ( *++pB != aSearch );
+ aOffset = pB - iDataStartPtr;
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifEndianBase::LocateJpegMarker
+// Locates the offset of the specified Jpeg Marker, which resides after the
+// given offset.
+// -----------------------------------------------------------------------------
+//
+TInt CExifEndianBase::LocateJpegMarker(
+ TUint16 aMarker,
+ TUint32& aOffset,
+ TUint32 aAfter,
+ TUint32 aBefore )
+ {
+ if ( aAfter < iPosOffset )
+ {
+ aAfter = iPosOffset;
+ }
+ TUint8* startPtr = iDataStartPtr + aAfter;
+ if ( !aBefore )
+ {
+ aBefore = iExifEndOffset;
+ }
+ TUint8* endPtr = iDataStartPtr + aBefore;
+ TUint8* pB = TExifCommon::LocateJpegMarkerPtr(
+ aMarker, startPtr, endPtr );
+ if ( !pB )
+ {
+ return KErrCorrupt;
+ }
+ aOffset = pB - iDataStartPtr;
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifEndianBase::LocateJpegMarkerFromEnd
+// Locates the offset of the last specified Jpeg Marker.
+// -----------------------------------------------------------------------------
+//
+TInt CExifEndianBase::LocateJpegMarkerFromEnd(
+ TUint16 aMarker,
+ TUint32& aOffset,
+ TUint32 aAfter,
+ TUint32 aBefore )
+ {
+ if ( aAfter < iPosOffset)
+ {
+ aAfter = iPosOffset;
+ }
+ TUint8* startPtr = iDataStartPtr + aAfter;
+ if ( !aBefore )
+ {
+ aBefore = iExifEndOffset;
+ }
+ TUint8* endPtr = iDataStartPtr + aBefore;
+ TUint8* pB = TExifCommon::LocateJpegMarkerPtrFromEnd( aMarker,
+ startPtr, endPtr );
+ if ( !pB )
+ {
+ return KErrCorrupt;
+ }
+ aOffset = pB - iDataStartPtr;
+ return KErrNone;
+ }
+
+
+// ============================ CLASS CExifLittleEndian ========================
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CExifLittleEndian::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CExifLittleEndian* CExifLittleEndian::NewL(
+ const TUint8* aDataStartPtr,
+ TUint8* aExifStartPtr,
+ TUint8* aExifEndPtr,
+ TBool aIsExif )
+ {
+ CExifLittleEndian* self = new( ELeave ) CExifLittleEndian();
+ CleanupStack::PushL( self );
+ self->ConstructL( CONST_CAST( TUint8*, aDataStartPtr ), aExifStartPtr,
+ aExifEndPtr, aIsExif );
+ CleanupStack::Pop();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifLittleEndian::CExifLittleEndian
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CExifLittleEndian::CExifLittleEndian()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CExifLittleEndian::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CExifLittleEndian::ConstructL(
+ TUint8* aDataStartPtr,
+ TUint8* aExifStartPtr,
+ TUint8* aExifEndPtr,
+ TBool aIsExif )
+ {
+ if ( !aDataStartPtr || !aExifStartPtr || !aExifEndPtr )
+ {
+ User::Leave( KErrGeneral );
+ }
+ iDataStartPtr = aDataStartPtr;
+ iExifEndOffset = aExifEndPtr - iDataStartPtr;
+ if ( aIsExif )
+ {
+ iExifStartOffset = aExifStartPtr - iDataStartPtr;
+ if ( TExifCommon::Uint16L( aExifStartPtr + 2 ) != KExifDummyRev )
+ {
+ User::Leave( KErrCorrupt );
+ }
+ TUint32 ifdOffset = TExifCommon::Uint32L( aExifStartPtr + 4 );
+ iPosOffset = iExifStartOffset + ifdOffset; //Locate 0th IFD position
+ if ( iPosOffset >= iExifEndOffset )
+ {
+ User::Leave( KErrCorrupt );
+ }
+ }
+ else
+ {
+ iPosOffset = aExifStartPtr - iDataStartPtr;
+ }
+ }
+
+// Destructor
+CExifLittleEndian::~CExifLittleEndian()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CExifLittleEndian::Locate16
+// Locates the offset of the next specified 16-bit unsigned integer.
+// -----------------------------------------------------------------------------
+//
+TInt CExifLittleEndian::Locate16( TUint16 aSearch, TUint32& aOffset )
+ {
+ TUint8* pB = iDataStartPtr + iPosOffset - 1;
+ TUint16 atHand = *pB;
+ TUint8* pE = iDataStartPtr + iExifEndOffset;
+ TInt error = KErrNone;
+ do
+ {
+ if ( pB >= pE )
+ {
+ return KErrCorrupt;
+ }
+ TRAP( error, atHand =TExifCommon::Uint16L( ++pB ) );
+ }
+ while ( ( atHand != aSearch ) && ( error == KErrNone ) );
+ if ( error )
+ {
+ return error;
+ }
+ aOffset = pB - iDataStartPtr;
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifLittleEndian::ReadUint16
+// Gets the next 16-bit unsigned integer from the data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifLittleEndian::ReadUInt16( TUint16& aInt16 )
+ {
+ if ( iPosOffset + 2 >= iExifEndOffset )
+ {
+ return KErrCorrupt;
+ }
+
+ TRAPD( error, aInt16 = TExifCommon::Uint16L( iDataStartPtr + iPosOffset ) );
+
+ if ( error )
+ {
+ return error;
+ }
+
+ iPosOffset += 2;
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifLittleEndian::ReadUint32
+// Gets the next 32-bit unsigned integer from the data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifLittleEndian::ReadUInt32( TUint32& aInt32 )
+ {
+ if ( iPosOffset + 4 >= iExifEndOffset )
+ {
+ return KErrCorrupt;
+ }
+
+ TRAPD( error, aInt32 = TExifCommon::Uint32L( iDataStartPtr + iPosOffset ) );
+ if ( error )
+ {
+ return error;
+ }
+
+ iPosOffset += 4;
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifLittleEndian::CopyBuffer
+// Copies the next specified amount of data to the given descriptor.
+// -----------------------------------------------------------------------------
+//
+TInt CExifLittleEndian::CopyBuffer(
+ TUint32 aCount,
+ TUint8 aWordSize,
+ HBufC8*& aBuffer )
+ {
+ if ( !aBuffer )
+ {
+ return KErrCorrupt;
+ }
+ TUint bufferSize = aCount * aWordSize;
+ if ( iPosOffset + bufferSize >= iExifEndOffset )
+ {
+ return KErrCorrupt;
+ }
+
+ aBuffer->Des().Copy( iDataStartPtr + iPosOffset, bufferSize );
+
+ iPosOffset += bufferSize;
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifLittleEndian::CopyBuffer
+// Copies the specified amount of data located in the given offset to the
+// given descriptor.
+// -----------------------------------------------------------------------------
+//
+TInt CExifLittleEndian::CopyBuffer(
+ TUint32 aOffset,
+ TUint32 aCount,
+ TUint8 aWordSize,
+ HBufC8*& aBuffer )
+ {
+ if ( !aBuffer )
+ {
+ return KErrCorrupt;
+ }
+ TUint bufferSize = aCount * aWordSize;
+ if ( ( aOffset + iExifStartOffset + bufferSize ) >= iExifEndOffset )
+ {
+ return KErrCorrupt;
+ }
+
+ TUint8* ptr = iDataStartPtr + iExifStartOffset + aOffset;
+ aBuffer->Des().Copy( ptr, bufferSize );
+
+ return KErrNone;
+ }
+
+
+// ============================ CLASS CExifBigEndian ===========================
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CExifBigEndian::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CExifBigEndian* CExifBigEndian::NewL(
+ const TUint8* aDataStartPtr,
+ TUint8* aExifStartPtr,
+ TUint8* aExifEndPtr,
+ TBool aIsExif )
+ {
+ CExifBigEndian* self = new( ELeave ) CExifBigEndian();
+ CleanupStack::PushL( self );
+ self->ConstructL( CONST_CAST( TUint8*, aDataStartPtr ), aExifStartPtr,
+ aExifEndPtr, aIsExif );
+ CleanupStack::Pop();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifBigEndian::CExifBigEndian
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CExifBigEndian::CExifBigEndian()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CExifBigEndian::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CExifBigEndian::ConstructL(
+ TUint8* aDataStartPtr,
+ TUint8* aExifStartPtr,
+ TUint8* aExifEndPtr,
+ TBool aIsExif )
+ {
+ if ( !aDataStartPtr || !aExifStartPtr || !aExifEndPtr )
+ {
+ User::Leave( KErrGeneral );
+ }
+ iDataStartPtr = aDataStartPtr;
+ iExifEndOffset = aExifEndPtr - iDataStartPtr;
+ if ( aIsExif )
+ {
+ iExifStartOffset = aExifStartPtr - iDataStartPtr;
+ if ( TExifCommon::Uint16L( aExifStartPtr + 2 ) != KExifDummy )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ TUint8* tmpPtr = aExifStartPtr + 4;
+ TUint32 ifdOffset = STATIC_CAST( TUint32, ( *tmpPtr << 24 )
+ + ( ( *( tmpPtr + 1 ) ) << 16 ) + ( ( *( tmpPtr + 2 ) ) << 8 )
+ + ( *( tmpPtr + 3 ) ) );
+ iPosOffset = ( iExifStartOffset + ifdOffset ); //Locate 0th IFD pos.
+ if ( iPosOffset >= iExifEndOffset )
+ {
+ User::Leave( KErrCorrupt );
+ }
+ }
+ else
+ {
+ iPosOffset = aExifStartPtr - iDataStartPtr;
+ }
+ }
+
+// Destructor
+CExifBigEndian::~CExifBigEndian()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CExifBigEndian::Locate16
+// Locates the offset of the next specified 16-bit unsigned integer.
+// -----------------------------------------------------------------------------
+//
+TInt CExifBigEndian::Locate16( TUint16 aSearch, TUint32& aOffset )
+ {
+ TUint8* pB = iDataStartPtr + iPosOffset;
+ TUint16 atHand = *pB;
+ TUint8* pE = iDataStartPtr + iExifEndOffset;
+ do
+ {
+ if ( pB >= pE )
+ {
+ return KErrCorrupt;
+ }
+ atHand = STATIC_CAST( TUint16, ( atHand << 8 ) + *++pB );
+ }
+ while ( atHand != aSearch );
+ aOffset = ( pB - 1 ) - iDataStartPtr;
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifBigEndian::ReadUInt16
+// Gets the next 16-bit unsigned integer from the data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifBigEndian::ReadUInt16( TUint16& aInt16 )
+ {
+ if ( iPosOffset + 2 >= iExifEndOffset )
+ {
+ return KErrCorrupt;
+ }
+
+ aInt16 = STATIC_CAST( TUint16, ( *( iDataStartPtr + iPosOffset ) << 8 )
+ + *( iDataStartPtr + iPosOffset + 1 ) );
+
+ iPosOffset += 2;
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifBigEndian::ReadUInt32
+// Gets the next 32-bit unsigned integer from the data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifBigEndian::ReadUInt32( TUint32& aInt32 )
+ {
+ if ( iPosOffset + 4 >= iExifEndOffset )
+ {
+ return KErrCorrupt;
+ }
+
+ aInt32 = STATIC_CAST( TUint32, ( *( iDataStartPtr + iPosOffset ) << 24 )
+ + ( *( iDataStartPtr + iPosOffset + 1 ) << 16 )
+ + ( *( iDataStartPtr + iPosOffset + 2 ) << 8 )
+ + *( iDataStartPtr + iPosOffset + 3 ) );
+
+ iPosOffset += 4;
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifBigEndian::CopyBuffer
+// Copies the next specified amount of data to the given descriptor.
+// -----------------------------------------------------------------------------
+//
+TInt CExifBigEndian::CopyBuffer(
+ TUint32 aCount,
+ TUint8 aWordSize,
+ HBufC8*& aBuffer )
+ {
+ if ( !aBuffer )
+ {
+ return KErrCorrupt;
+ }
+ TInt bufferSize = aCount * aWordSize;
+ if ( iPosOffset + bufferSize >= iExifEndOffset )
+ {
+ return KErrCorrupt;
+ }
+
+ TUint8* posPtr = iDataStartPtr + iPosOffset;
+ if ( aWordSize == 1 )
+ {
+ aBuffer->Des().Copy( posPtr, bufferSize );
+ iPosOffset += bufferSize;
+ }
+ else if ( aWordSize == 2 )
+ {
+ TUint8* destPtr = CONST_CAST( TUint8*, aBuffer->Ptr() );
+ for( TUint i = 0; i < aCount; ++i)
+ {
+ destPtr[0] = posPtr[1];
+ destPtr[1] = *posPtr;
+ posPtr += 2;
+ iPosOffset += 2;
+ destPtr += 2;
+ }
+ }
+ else
+ {
+ TUint8* destPtr = CONST_CAST( TUint8*, aBuffer->Ptr() );
+ for( TInt i = 0; i < bufferSize / 4; ++i)
+ {
+ destPtr[0] = posPtr[3];
+ destPtr[1] = posPtr[2];
+ destPtr[2] = posPtr[1];
+ destPtr[3] = *posPtr;
+ posPtr += 4;
+ iPosOffset += 4;
+ destPtr += 4;
+ }
+ }
+ aBuffer->Des().SetLength( bufferSize );
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifBigEndian::CopyBuffer
+// Copies the specified amount of data located in the given offset to the
+// given descriptor.
+// -----------------------------------------------------------------------------
+//
+TInt CExifBigEndian::CopyBuffer(
+ TUint32 aOffset,
+ TUint32 aCount,
+ TUint8 aWordSize,
+ HBufC8*& aBuffer )
+ {
+ if ( !aBuffer )
+ {
+ return KErrCorrupt;
+ }
+ TInt bufferSize = aCount * aWordSize;
+ if ( ( aOffset + iExifStartOffset + bufferSize ) >= iExifEndOffset )
+ {
+ return KErrCorrupt;
+ }
+
+ TUint8* ptr = iDataStartPtr + iExifStartOffset + aOffset;
+ if ( aWordSize == 1 )
+ {
+ aBuffer->Des().Copy( ptr, bufferSize );
+ }
+ else if ( aWordSize == 2 )
+ {
+ TUint8* destPtr = CONST_CAST( TUint8*, aBuffer->Ptr() );
+ for( TUint i = 0; i < aCount; ++i)
+ {
+ destPtr[0] = ptr[1];
+ destPtr[1] = *ptr;
+ destPtr += 2;
+ ptr += 2;
+ }
+ }
+ else
+ {
+ TUint8* destPtr = CONST_CAST( TUint8*, aBuffer->Ptr() );
+ for( TInt i = 0; i < bufferSize / 4; ++i)
+ {
+ destPtr[0] = ptr[3];
+ destPtr[1] = ptr[2];
+ destPtr[2] = ptr[1];
+ destPtr[3] = *ptr;
+ destPtr += 4;
+ ptr += 4;
+ }
+ }
+ aBuffer->Des().SetLength( bufferSize );
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifEndianBase::CurrentPosOffset
+// Returns the current position of decoded data
+// -----------------------------------------------------------------------------
+//
+void CExifEndianBase::CurrentPosOffset( TUint32& aOffset )
+ {
+ aOffset = iPosOffset;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/src/ExifIfd.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,926 @@
+/*
+* Copyright (c) 2003, 2004 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: Exif IFD structure handling classes.
+*
+*/
+
+
+// INCLUDE FILES
+#include "ExifRead.h"
+#include "ExifTagImpl.h"
+#include "ExifIfd.h"
+#include "ExifCommon.h"
+#include "ExifValueTable.h"
+
+// ============================ CLASS CExifIfd =================================
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CExifIfd::CExifIfd
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CExifIfd::CExifIfd() : iTagArray( sizeof( CExifTagImpl* ) )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CExifIfd::ConstructL()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd::NewBaseL
+// Two-phased constructor. Instantiates and returns the relevant derived class.
+// -----------------------------------------------------------------------------
+//
+CExifIfd* CExifIfd::NewBaseL( TExifIfdType aIfdType )
+ {
+ switch ( aIfdType )
+ {
+ case EIfd0:
+ return CExifIfd0::NewL();
+ case EIfdExif:
+ return CExifIfdExif::NewL();
+ case EIfd1:
+ return CExifIfd1::NewL();
+ case EIfdGps:
+ return CExifIfdGps::NewL();
+ case EIfdIntOp:
+ return CExifIfdIntOp::NewL();
+ default:
+ User::Leave( KErrGeneral );
+ }
+ return NULL;
+ }
+
+// Destructor
+CExifIfd::~CExifIfd()
+ {
+ iTagArray.ResetAndDestroy();
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd::IsValid
+// Checks if the IFD is in valid format, and contains all mandatory tags.
+// -----------------------------------------------------------------------------
+//
+TBool CExifIfd::IsValid() const
+ {
+ if ( iTagArray.Count() )
+ {
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd::TagExists
+// Checks if specified tag exists in the IFD.
+// -----------------------------------------------------------------------------
+//
+TBool CExifIfd::TagExists( TUint16 aTagId ) const
+ {
+ for ( TInt i = 0; i < iTagArray.Count(); ++i )
+ {
+ if ( aTagId == iTagArray[i]->Id() )
+ {
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd::Size
+// Returns the size of the IFD structure in bytes.
+// -----------------------------------------------------------------------------
+//
+TUint16 CExifIfd::Size() const
+ {
+ if ( !iTagArray.Count() )
+ {
+ return 0;
+ }
+ // Size of the tags + 6 bytes (the next ifd offset and number of tags info)
+ return STATIC_CAST( TUint16, iSize + 6 );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd::SetNextIfdOffset
+// Sets the next IFD offset.
+// -----------------------------------------------------------------------------
+//
+void CExifIfd::SetNextIfdOffset( TUint32 aIfdOffset )
+ {
+ iNextIfdOffset = aIfdOffset;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd::WriteTagsL
+// Writes the tag data in the IFD structure to the location defined by the
+// given pointer and the offset.
+// -----------------------------------------------------------------------------
+//
+void CExifIfd::WriteTagsL( TUint16*& aExifDataPtr, TUint& aPos ) const
+ {
+ if ( !iTagArray.Count() )
+ {
+ User::Leave( KErrNotReady );
+ }
+ *aExifDataPtr++ = STATIC_CAST( TUint16, iTagArray.Count() );
+ TUint16* ifdForwardPtr = aExifDataPtr + ( iTagArray.Count() * 6 ) + 2;
+ TUint32 fwdPos = ( ( iTagArray.Count() * 12 ) - 6 ) + aPos;
+ for ( TInt i = 0; i < iTagArray.Count(); ++i )
+ {
+ CExifTagImpl* tag = iTagArray[i];
+ *aExifDataPtr++ = tag->Id();
+ CExifTag::TExifTagDataType tagType = tag->DataType();
+ *aExifDataPtr++ = STATIC_CAST( TUint16, tagType );
+ TUint32 count = tag->DataCount();
+ TExifCommon::SetUint32( REINTERPRET_CAST( TUint8*, aExifDataPtr ),
+ count );
+ aExifDataPtr += 2;
+ TUint noBytes = 0;
+ if ( ( tagType == CExifTag::ETagByte ) ||
+ ( tagType == CExifTag::ETagAscii ) ||
+ ( tagType == CExifTag::ETagUndefined ) )
+ {
+ noBytes = 1;
+ }
+ else if ( ( tagType == CExifTag::ETagLong ) ||
+ ( tagType == CExifTag::ETagSlong ) )
+ {
+ noBytes = 4;
+ }
+ else if ( ( tagType == CExifTag::ETagRational ) ||
+ ( tagType == CExifTag::ETagSrational ) )
+ {
+ noBytes = 8;
+ }
+ else
+ {
+ noBytes = 2;
+ }
+ noBytes *= count;
+ TPtrC8 tagBuffer = tag->Data();
+ if ( noBytes < 5 )
+ {
+ TUint32 tagData = 0;
+ switch ( noBytes )
+ {
+ case 4:
+ tagData = TExifCommon::Uint32L(
+ CONST_CAST( TUint8*, tagBuffer.Ptr() ) );
+ break;
+ case 3:
+ tagData = TExifCommon::Uint32L( CONST_CAST(
+ TUint8*, tagBuffer.Ptr() ) ) & KThreeByteMask;
+ break;
+ case 2:
+ tagData = TExifCommon::Uint32L( CONST_CAST(
+ TUint8*, tagBuffer.Ptr() ) ) & KTwoByteMask;
+ break;
+ default:
+ tagData = TExifCommon::Uint32L( CONST_CAST(
+ TUint8*, tagBuffer.Ptr() ) ) & KOneByteMask;
+ }
+ TExifCommon::SetUint32(
+ REINTERPRET_CAST( TUint8*, aExifDataPtr ), tagData );
+ }
+ else
+ {
+ TPtr8 ptr( REINTERPRET_CAST( TUint8*, ifdForwardPtr ), noBytes );
+ ptr.Copy( tagBuffer.Ptr(), noBytes );
+ TExifCommon::SetUint32(
+ REINTERPRET_CAST( TUint8*, aExifDataPtr ), fwdPos );
+ if ( noBytes % 2 )
+ {
+ ++noBytes;
+ ifdForwardPtr += ( noBytes / 2 );
+ *( ( REINTERPRET_CAST( TUint8*, ifdForwardPtr ) ) - 1 ) = 0;
+ }
+ else
+ {
+ ifdForwardPtr += ( noBytes / 2 );
+ }
+ fwdPos += noBytes;
+ }
+ aExifDataPtr += 2;
+ }
+ TExifCommon::SetUint32(
+ REINTERPRET_CAST( TUint8*, aExifDataPtr ), iNextIfdOffset );
+ aExifDataPtr = ifdForwardPtr;
+ aPos = fwdPos + 12;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd::InsertTagL
+// Inserts/Replaces the given tag in the IFD structure.
+// -----------------------------------------------------------------------------
+//
+void CExifIfd::InsertTagL( CExifTagImpl* aExifTag, TBool aCheckValidity )
+ {
+ LOGTEXT( _L( "ExifLib: CExifIfd::InsertTagL entering" ));
+ if ( !aExifTag )
+ {
+ LOGTEXT( _L( "ExifLib: CExifIfd::InsertTagL Leaving KErrGeneral" ));
+ User::Leave( KErrGeneral );
+ }
+ TUint16 tagId = aExifTag->Id();
+
+ if ( aCheckValidity && ( !IsAcceptableTagId( tagId ) ) )
+ {
+ LOGTEXT2( _L( "ExifLib: CExifIfd::InsertTagL Leaving KErrNotSupported, tagId=0x%x" ), tagId);
+ User::Leave( KErrNotSupported );
+ }
+
+ TInt index = -1;
+ for ( TInt i = 0; ( i < iTagArray.Count() ) && ( index < 0 ); ++i )
+ {
+ if ( iTagArray[i]->Id() > tagId )
+ {
+ index = i;
+ }
+ else if ( iTagArray[i]->Id() == tagId )
+ {
+ iSize = STATIC_CAST( TUint16, iSize - iTagArray[i]->Size() );
+ delete iTagArray[i];
+ iTagArray[i] = aExifTag;
+ iSize = STATIC_CAST( TUint16, iSize + aExifTag->Size() );
+ LOGTEXT( _L( "ExifLib: CExifIfd::InsertTagL returning" ));
+ return;
+ }
+ else
+ {
+ }
+ }
+
+ if ( index < 0 )
+ {
+ iTagArray.AppendL( aExifTag );
+ }
+ else
+ {
+ iTagArray.InsertL( index, aExifTag );
+ }
+ iSize = STATIC_CAST( TUint16, iSize + aExifTag->Size() );
+ LOGTEXT( _L( "ExifLib: CExifIfd::InsertTagL returning" ));
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd::DeleteTag
+// Removes the specified tag from the IFD structure
+// -----------------------------------------------------------------------------
+//
+TInt CExifIfd::DeleteTag( TUint16 aTagId )
+ {
+ for ( TInt i = 0; i < iTagArray.Count(); ++i )
+ {
+ if ( iTagArray[i]->Id() == aTagId )
+ {
+ iSize = STATIC_CAST( TUint16, iSize - iTagArray[i]->Size() );
+ delete iTagArray[i];
+ iTagArray.Delete( i );
+ return KErrNone;
+ }
+ }
+ return KErrNotFound;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd::GetTagL
+// Gets the unmodifiable specified tag instance from the IFD structure.
+// -----------------------------------------------------------------------------
+//
+const CExifTagImpl* CExifIfd::GetTagL( TUint16 aTagId ) const
+ {
+ if ( !IsAcceptableTagId( aTagId ) )
+ {
+ User::Leave( KErrNotSupported );
+ }
+ for ( TInt i = 0; i < iTagArray.Count(); ++i )
+ {
+ if ( iTagArray[i]->Id() == aTagId )
+ {
+ return iTagArray[i];
+ }
+ }
+ User::Leave( KErrNotFound );
+ return NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd::GetTagIdsL
+// Gets the IDs and amount of the tags existing in the IFD structure.
+// -----------------------------------------------------------------------------
+//
+TUint16* CExifIfd::GetTagIdsL( TInt& aNoTags ) const
+ {
+ if ( !iTagArray.Count() )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ TUint16* tagIds = STATIC_CAST( TUint16*,
+ User::AllocL( sizeof( TUint16 ) * iTagArray.Count() ) );
+ for ( TInt i = 0; i < iTagArray.Count(); ++i )
+ {
+ tagIds[i] = iTagArray[i]->Id();
+ }
+
+ aNoTags = iTagArray.Count();
+ return tagIds;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd::IsAcceptableTagId
+// Checks if the given tag ID is one of the IDs that can be stored in the IFD
+// structure.
+// -----------------------------------------------------------------------------
+//
+TBool CExifIfd::IsAcceptableTagId( TUint16 aTagId ) const
+ {
+ TInt noTags = 0;
+ const TReferenceTag* tags = NULL;
+ switch ( iIfdType )
+ {
+ case EIfd0:
+ noTags = KNoIfd0Tags;
+ tags = ifd0Tags;
+ break;
+ case EIfdExif:
+ noTags = KNoIfdExifTags;
+ tags = ifdExifTags;
+ break;
+ case EIfd1:
+ noTags = KNoIfd1Tags;
+ tags = ifd1Tags;
+ break;
+ case EIfdGps:
+ noTags = KNoIfdGpsTags;
+ tags = ifdGpsTags;
+ break;
+ case EIfdIntOp:
+ noTags = KNoIfdIntOpTags;
+ tags = ifdIntOpTags;
+ break;
+ default:
+ return EFalse;
+ }
+
+ TInt k = 0;
+ for ( k = 0; k < noTags; ++k )
+ {
+ if ( tags[k].iId == aTagId )
+ {
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+
+// ============================ CLASS CExifIfd0 ================================
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CExifIfd0::CExifIfd0
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CExifIfd0::CExifIfd0()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd0::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CExifIfd0* CExifIfd0::NewL()
+ {
+ CExifIfd0* self = new( ELeave ) CExifIfd0();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd0::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CExifIfd0::ConstructL()
+ {
+ }
+
+// Destructor
+CExifIfd0::~CExifIfd0()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd0::IsValid
+// Checks if the IFD0 is in valid format, and contains all mandatory IFD0 tags.
+// -----------------------------------------------------------------------------
+//
+TBool CExifIfd0::IsValid() const
+ {
+ if ( !iTagArray.Count() )
+ {
+ return EFalse;
+ }
+ for ( TInt i = 0; i < KNoMandatoryIfd0Tags; ++i )
+ {
+ TBool found = EFalse;
+ TInt j = 0;
+ for ( j = 0; ( j < iTagArray.Count() ) && ( !found ); ++j )
+ {
+ if ( ifd0Tags[i].iId == iTagArray[j]->Id() )
+ {
+ found = ETrue;
+ }
+ }
+ if ( !found )
+ {
+ return EFalse;
+ }
+ }
+ return ETrue;
+ }
+
+
+// ============================ CLASS CExifIfdExif =============================
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CExifIfdExif::CExifIfdExif
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CExifIfdExif::CExifIfdExif ( )
+ {
+ iIfdType = EIfdExif;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfdExif::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CExifIfdExif* CExifIfdExif::NewL()
+ {
+ CExifIfdExif* self = new( ELeave ) CExifIfdExif();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfdExif::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CExifIfdExif::ConstructL()
+ {
+ }
+
+// Destructor
+CExifIfdExif::~CExifIfdExif ( )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfdExif::IsValid
+// Checks if the Exif IFD is in valid format, and contains all mandatory Exif
+// IFD tags.
+// -----------------------------------------------------------------------------
+//
+TBool CExifIfdExif::IsValid() const
+ {
+ if ( !iTagArray.Count() )
+ {
+ return EFalse;
+ }
+ for ( TInt i = 0; i < KNoMandatoryIfdExifTags; ++i )
+ {
+ TBool found = EFalse;
+ TInt j = 0;
+ for ( j = 0; ( j < iTagArray.Count() ) && ( !found ); ++j )
+ {
+ if ( ifdExifTags[i].iId == iTagArray[j]->Id() )
+ {
+ found = ETrue;
+ }
+ }
+ if ( !found )
+ {
+ return EFalse;
+ }
+ }
+ return ETrue;
+ }
+
+
+// ============================ CLASS CExifIfd1 ================================
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CExifIfd1::CExifIfd1
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CExifIfd1::CExifIfd1()
+ {
+ iIfdType = EIfd1;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd1::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CExifIfd1* CExifIfd1::NewL()
+ {
+ CExifIfd1* self = new( ELeave ) CExifIfd1();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd1::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CExifIfd1::ConstructL()
+ {
+ }
+
+// Destructor
+CExifIfd1::~CExifIfd1()
+ {
+ if ( iThumbnailBuffer )
+ {
+ delete iThumbnailBuffer;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd1::IsValid
+// Checks if the Exif IFD is in valid format, and contains all mandatory Exif
+// IFD tags.
+// -----------------------------------------------------------------------------
+//
+TBool CExifIfd1::IsValid() const
+ {
+ if ( !iTagArray.Count() )
+ {
+ return EFalse;
+ }
+ for ( TInt i = 0; i < KNoMandatoryIfd1Tags; ++i )
+ {
+ TBool found = EFalse;
+ TInt j = 0;
+ for ( j = 0; ( j < iTagArray.Count() ) && ( !found ); ++j )
+ {
+ if ( ifd1Tags[i].iId == iTagArray[j]->Id() )
+ {
+ found = ETrue;
+ }
+ }
+ if ( !found )
+ {
+ return EFalse;
+ }
+ }
+ if ( !iThumbnailBuffer )
+ {
+ return EFalse;
+ }
+ return ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd1::WriteThumbnailL
+// Writes the Exif thumbnail image to the location defined by the given pointer
+// and the offset.
+// -----------------------------------------------------------------------------
+//
+void CExifIfd1::WriteThumbnailL( TUint8*& aExifDataPtr, TUint& aPos ) const
+ {
+ if ( !iThumbnailBuffer )
+ {
+ User::Leave( KErrNotReady );
+ }
+ TPtr8 ptr( aExifDataPtr, iThumbnailBuffer->Length() );
+ ptr.Copy( iThumbnailBuffer->Ptr(), iThumbnailBuffer->Length() );
+ aExifDataPtr += iThumbnailBuffer->Length();
+ aPos += iThumbnailBuffer->Length();
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd1::ThumbnailSize
+// Returns the size of the Exif thumbnail image in bytes.
+// -----------------------------------------------------------------------------
+//
+TUint16 CExifIfd1::ThumbnailSize() const
+ {
+ if ( !iThumbnailBuffer )
+ {
+ return 0;
+ }
+ return STATIC_CAST( TUint16, iThumbnailBuffer->Length() );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd1::SetThumbnailData
+// Inserts/Updates the given Exif thumbnail image.
+// -----------------------------------------------------------------------------
+//
+TInt CExifIfd1::SetThumbnailData( TDesC8* aThumbnailData )
+ {
+ if ( !aThumbnailData )
+ {
+ return KErrGeneral;
+ }
+ if ( iThumbnailBuffer )
+ {
+ delete iThumbnailBuffer;
+ }
+ iThumbnailBuffer = aThumbnailData;
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd1::GetThumbnailData
+// Gets the Exif thumbnail image.
+// -----------------------------------------------------------------------------
+//
+TInt CExifIfd1::GetThumbnailData( TDesC8*& aThumbnailData ) const
+ {
+ if ( !iThumbnailBuffer )
+ {
+ return KErrNotFound;
+ }
+ aThumbnailData = iThumbnailBuffer;
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd1::RemoveThumbnailData
+// Removes the Exif thumbnail image.
+// -----------------------------------------------------------------------------
+//
+TInt CExifIfd1::RemoveThumbnailData()
+ {
+ if ( !iThumbnailBuffer )
+ {
+ return KErrNotFound;
+ }
+ delete iThumbnailBuffer;
+ iThumbnailBuffer = 0;
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfd1::InsertTagL
+// Inserts/Replaces the given tag in the IFD structure.
+// -----------------------------------------------------------------------------
+//
+void CExifIfd1::InsertTagL( CExifTagImpl* aExifTag, TBool aCheckValidity )
+ {
+ LOGTEXT( _L( "ExifLib: CExifIfd1::InsertTagL entering" ));
+ if ( !aExifTag )
+ {
+ LOGTEXT( _L( "ExifLib: CExifIfd1::InsertTagL Leaving KErrGeneral" ));
+ User::Leave( KErrGeneral );
+ }
+ TUint16 tagId = aExifTag->Id();
+ if ( tagId == KIdCompression )
+ {
+ if ( aExifTag->Data().Length() != 2 )
+ {
+ LOGTEXT2( _L( "ExifLib: CExifIfd1::InsertTagL Leaving KErrCorrupt, aExifTag->Data().Length()=0x%x" ), aExifTag->Data().Length());
+ User::Leave( KErrCorrupt );
+ }
+ TUint16* ptr = REINTERPRET_CAST( TUint16*, CONST_CAST( TUint8*,
+ aExifTag->Data().Ptr() ) );
+ if ( *ptr != 6 )
+ {
+ LOGTEXT2( _L( "ExifLib: CExifIfd1::InsertTagL Leaving KErrNotSupported, *ptr=0x%x" ), *ptr);
+ User::Leave( KErrNotSupported );
+ }
+ }
+
+ if ( aCheckValidity && ( !IsAcceptableTagId( tagId ) ) )
+ {
+ LOGTEXT2( _L( "ExifLib: CExifIfd1::InsertTagL Leaving KErrNotSupported, tagId=0x%x" ), tagId);
+ User::Leave( KErrNotSupported );
+ }
+
+ TInt index = -1;
+ for ( TInt i = 0; ( i < iTagArray.Count() ) && ( index < 0 ); ++i )
+ {
+ if ( iTagArray[i]->Id() > tagId )
+ {
+ index = i;
+ }
+ else if ( iTagArray[i]->Id() == tagId )
+ {
+ iSize = STATIC_CAST( TUint16, iSize - iTagArray[i]->Size() );
+ delete iTagArray[i];
+ iTagArray[i] = aExifTag;
+ iSize = STATIC_CAST( TUint16, iSize + aExifTag->Size() );
+ LOGTEXT( _L( "ExifLib: CExifIfd1::InsertTagL returning" ));
+ return;
+ }
+ else
+ {
+ }
+ }
+
+ if ( index < 0 )
+ {
+ iTagArray.AppendL( aExifTag );
+ }
+ else
+ {
+ iTagArray.InsertL( index, aExifTag );
+ }
+ iSize = STATIC_CAST( TUint16, iSize + aExifTag->Size() );
+ LOGTEXT( _L( "ExifLib: CExifIfd1::InsertTagL returning" ));
+ }
+
+
+// ============================ CLASS CExifIfdGps ==============================
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CExifIfdGps::CExifIfdGps
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CExifIfdGps::CExifIfdGps()
+ {
+ iIfdType = EIfdGps;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfdGps::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CExifIfdGps* CExifIfdGps::NewL()
+ {
+ CExifIfdGps* self = new( ELeave ) CExifIfdGps();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfdGps::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CExifIfdGps::ConstructL()
+ {
+ }
+
+// Destructor
+CExifIfdGps::~CExifIfdGps()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfdGps::IsValid
+// Checks if the Gps IFD is in valid format, and contains all Gps IFD mandatory
+// tags.
+// -----------------------------------------------------------------------------
+//
+TBool CExifIfdGps::IsValid() const
+ {
+ if ( !iTagArray.Count() )
+ {
+ return EFalse;
+ }
+ for ( TInt i = 0; i < KNoMandatoryIfdGpsTags; ++i )
+ {
+ TBool found = EFalse;
+ TInt j = 0;
+ for ( j = 0; ( j < iTagArray.Count() ) && ( !found ); ++j )
+ {
+ if ( ifdGpsTags[i].iId == iTagArray[j]->Id() )
+ {
+ found = ETrue;
+ }
+ }
+ if ( !found )
+ {
+ return EFalse;
+ }
+ }
+ return ETrue;
+ }
+
+
+// ============================ CLASS CExifIfdIntOp ============================
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CExifIfdIntOp::CExifIfdIntOp
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CExifIfdIntOp::CExifIfdIntOp()
+ {
+ iIfdType = EIfdIntOp;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfdIntOp::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CExifIfdIntOp* CExifIfdIntOp::NewL()
+ {
+ CExifIfdIntOp* self = new( ELeave ) CExifIfdIntOp();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfdIntOp::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CExifIfdIntOp::ConstructL()
+ {
+ }
+
+// Destructor
+CExifIfdIntOp::~CExifIfdIntOp()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CExifIfdIntOp::IsValid
+// Checks if the Interoperability IFD is in valid format, and contains all IOP
+// mandatory tags.
+// -----------------------------------------------------------------------------
+//
+TBool CExifIfdIntOp::IsValid() const
+ {
+ /* KNoMandatoryIfdIntOpTags is 0, no need for this checking loop.
+ if ( !iTagArray.Count() )
+ {
+ return EFalse;
+ }
+ for ( TUint i = 0; i < KNoMandatoryIfdIntOpTags; ++i )
+ {
+ TBool found = EFalse;
+ TUint j = 0;
+ for ( j = 0; ( j < iTagArray.Count() ) && ( !found ); ++j )
+ {
+ if ( ifdIntOpTags[i].iId == iTagArray[j]->Id() )
+ {
+ found = ETrue;
+ }
+ }
+ if ( !found )
+ {
+ return EFalse;
+ }
+ }
+ */
+ return ETrue;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/src/ExifModify.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,1166 @@
+/*
+* Copyright (c) 2003, 2004 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: Exif v2.2 file format modifier API implementation
+*
+*/
+
+
+// INCLUDE FILES
+#include "ExifModifyImpl.h"
+#include "ExifReadImpl.h"
+#include "ExifTagImpl.h"
+#include "ExifCore.h"
+#include "ExifCommon.h"
+
+// ============================ CLASS CExifModify ==============================
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CExifModify::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CExifModify* CExifModify::NewL(
+ const TDesC8& aExifData,
+ CExifModify::TOperationMode aOperationMode )
+ {
+ return CExifModifyImpl::NewL( aExifData, STATIC_CAST( TBool,
+ aOperationMode ), CExifModify::ENoOptions );
+ }
+
+EXPORT_C CExifModify* CExifModify::NewL(
+ const TDesC8& aExifData,
+ CExifModify::TOperationMode aOperationMode,
+ TUint aExifModifyOption )
+ {
+ return CExifModifyImpl::NewL( aExifData, STATIC_CAST( TBool,
+ aOperationMode ), aExifModifyOption );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModify::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CExifModify* CExifModify::NewL()
+ {
+ return CExifModifyImpl::NewL();
+ }
+
+// Destructor
+CExifModify::~CExifModify()
+ {
+ }
+
+
+// ============================ CLASS CExifModifyImpl ==========================
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::CExifModifyImpl
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CExifModifyImpl::CExifModifyImpl()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::ConstructL( const TDesC8& aInData, TBool aCreate, TUint aExifModifyOption )
+ {
+ iExifModifyOption = aExifModifyOption;
+ TUint readOption = CExifRead::ENoOptions;
+ if ( aExifModifyOption & CExifModify::ENoJpegParsing )
+ {
+ readOption |= CExifRead::EFastJpegParsing;
+ }
+ if ( aExifModifyOption & CExifModify::ENoTagChecking )
+ {
+ readOption |= CExifRead::ENoTagChecking;
+ }
+ iExifRead = CExifReadImpl::NewL( aInData, aCreate, readOption );
+ iExifCore = iExifRead->iExifCore;
+
+ if ( !aCreate )
+ {
+ if ( iExifCore->IfdExists( EIfdGps ) )
+ {
+ iExifCore->SetTagDataL( KIdGpsVersion, KGpsVersion );
+ }
+ }
+ iExifCore->SetTagDataL( KIdExifVersion, KExifVersion );
+ iExifCore->SetTagDataL( KIdFlashPixVersion, KFlashPixVersion );
+
+ // Keep some data from the beginning, middle and end for cross-checking.
+ iCrossCheckLength = aInData.Length();
+ iCrossCheckBegin = TExifCommon::Uint32L(
+ CONST_CAST( TUint8*, aInData.Ptr() ) );
+ iCrossCheckMiddle = TExifCommon::Uint32L(
+ CONST_CAST( TUint8*, aInData.Ptr() ) + aInData.Length() / 2 );
+ iCrossCheckEnd = TExifCommon::Uint32L(
+ CONST_CAST( TUint8*, aInData.Ptr() ) + aInData.Length() - 5 );
+
+ User::LeaveIfError( iExifCore->Finalize() );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::ConstructL()
+ {
+ iExifModifyOption = CExifModify::ENoOptions;
+ iExifRead = CExifReadImpl::NewL();
+ iExifCore = iExifRead->iExifCore;
+
+ iExifCore->SetTagDataL( KIdExifVersion, KExifVersion );
+ iExifCore->SetTagDataL( KIdFlashPixVersion, KFlashPixVersion );
+
+ // No cross-checking since there is no input data.
+ iCrossCheckLength = 0;
+
+ User::LeaveIfError( iExifCore->Finalize() );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CExifModifyImpl* CExifModifyImpl::NewL( const TDesC8& aExifData, TBool aCreate, TUint aExifModifyOption )
+ {
+ CExifModifyImpl* self = new( ELeave ) CExifModifyImpl();
+ CleanupStack::PushL( self );
+ self->ConstructL( aExifData, aCreate, aExifModifyOption );
+ CleanupStack::Pop();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CExifModifyImpl* CExifModifyImpl::NewL()
+ {
+ CExifModifyImpl* self = new( ELeave ) CExifModifyImpl();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+// Destructor
+CExifModifyImpl::~CExifModifyImpl()
+ {
+ if ( iExifRead )
+ {
+ delete iExifRead;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::Reader
+// Returns a constant pointer to a CExifRead instance that can be used to
+// parse the associated Exif image.
+// -----------------------------------------------------------------------------
+//
+const CExifRead* CExifModifyImpl::Reader() const
+ {
+ return iExifRead;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetTagL
+// Inserts/Updates the given tag in the specified IFD structure of the Exif data
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetTagL(
+ TExifIfdType aIfdType,
+ TExifTagInfo aExifTagInfo,
+ const TDesC8& aTagData )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ // Check if ASCII string terminates with NULL character.
+ // If not add NULL.
+ HBufC8* buffer = NULL;
+ if ( ( aExifTagInfo.iDataType == CExifTag::ETagAscii ) &&
+ ( aTagData.Ptr()[aTagData.Length() - 1] ) )
+ {
+ ++aExifTagInfo.iDataCount;
+ buffer = HBufC8::NewL( aTagData.Length() + 1 );
+ buffer->Des().Copy( aTagData );
+ *( CONST_CAST( TUint8*, buffer->Des().Ptr() ) +
+ aTagData.Length() ) = NULL;
+ buffer->Des().SetLength( aTagData.Length() + 1 );
+ }
+ else
+ {
+ buffer = aTagData.AllocL();
+ }
+ CleanupStack::PushL( buffer );
+ CExifTagImpl* tag = NULL;
+ if ( iExifModifyOption & CExifModify::ENoTagChecking )
+ {
+ tag = CExifTagImpl::NewL( aExifTagInfo, buffer, EFalse );
+ }
+ else
+ {
+ tag = CExifTagImpl::NewL( aExifTagInfo, buffer, ETrue );
+ }
+ CleanupStack::Pop( buffer );
+ CleanupStack::PushL( tag );
+
+ switch ( tag->TagInfo().iId )
+ {
+ case KIdExifIfdPointer:
+ case KIdGpsIfdPointer:
+ case KIdIntOpIfdPointer:
+ case KIdJpegInterchangeFormat:
+ case KIdJpegInterchangeFormatLength:
+ case KIdExifVersion:
+ case KIdGpsVersion:
+ case KIdFlashPixVersion:
+ case KIdCompression:
+ User::Leave( KErrNotSupported );
+ default:
+ break;
+ }
+
+ if ( iExifModifyOption & CExifModify::ENoTagChecking )
+ {
+ iExifCore->InsertTagL( aIfdType, tag, EFalse );
+ }
+ else
+ {
+ iExifCore->InsertTagL( aIfdType, tag, ETrue );
+ }
+ CleanupStack::Pop( tag );
+ if ( aIfdType == EIfdGps )
+ {
+ iExifCore->SetTagDataL( KIdGpsVersion, KGpsVersion );
+ }
+ TInt error = iExifCore->Finalize();
+ if ( error )
+ {
+ iExifCore->DeleteTag( aIfdType, aExifTagInfo.iId );
+ User::Leave( error );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::DeleteTag
+// Removes the tag with the given tag ID from the specified IFD structure in
+// the Exif data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifModifyImpl::DeleteTag( TExifIfdType aIfdType, TUint16 aTagId )
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ switch ( aTagId )
+ {
+ case KIdExifIfdPointer:
+ case KIdGpsIfdPointer:
+ case KIdIntOpIfdPointer:
+ case KIdJpegInterchangeFormat:
+ case KIdJpegInterchangeFormatLength:
+ case KIdExifVersion:
+ case KIdGpsVersion:
+ case KIdFlashPixVersion:
+ case KIdCompression:
+ return KErrNotSupported;
+ default:
+ if ( !TExifCommon::IsValidTagId( aTagId ) )
+ {
+ return KErrNotSupported;
+ }
+ }
+
+ TInt error = iExifCore->DeleteTag( aIfdType, aTagId );
+ if ( error )
+ {
+ return error;
+ }
+ return iExifCore->Finalize();
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::DeleteIfd
+// Removes the specified IFD structure and all its tags from the Exif data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifModifyImpl::DeleteIfd( TExifIfdType aIfdType )
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ if ( ( aIfdType == EIfd0 ) || ( aIfdType == EIfdExif ) )
+ {
+ return KErrArgument;
+ }
+
+ TInt error = iExifCore->DeleteIfd( aIfdType );
+ if ( error )
+ {
+ return error;
+ }
+ return iExifCore->Finalize();
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetThumbnailL
+// Inserts/Updates the given thumbnail Jpeg image data into the 1st IFD
+// structure in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetThumbnailL( const TDesC8& aThumbnailData )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+ TDesC8* data = aThumbnailData.AllocL();
+ CleanupStack::PushL( data );
+ iExifCore->InsertThumbnailL( data );
+ CleanupStack::Pop( data );
+ TInt error = iExifCore->Finalize();
+ if ( error )
+ {
+ iExifCore->RemoveThumbnail();
+ User::Leave( error );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::RemoveThumbnail
+// Removes the thumbnail Jpeg image data from the 1st IFD structure in the Exif
+// data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifModifyImpl::RemoveThumbnail()
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ TInt error = iExifCore->RemoveThumbnail();
+ if ( error )
+ {
+ return error;
+ }
+ return iExifCore->Finalize();
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::WriteDataL
+// Flushes the Exif data into the given data buffer, and releases the internal
+// structures.
+// -----------------------------------------------------------------------------
+//
+HBufC8* CExifModifyImpl::WriteDataL( const TDesC8& aInData )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ // Input Jpeg or Exif data is provided at instantiation (or not)
+ TBool inputProvidedEarly = iCrossCheckLength;
+
+ // Input Jpeg or Exif data is provided for this function (or not)
+ TBool inputProvidedLate = aInData.Length();
+
+ if ( inputProvidedEarly )
+ {
+ if ( inputProvidedLate )
+ {
+ // Cross-check. Check if content of aInData is identical with
+ // the descriptor provided during instantiation.
+ if ( aInData.Length() != iCrossCheckLength )
+ {
+ User::Leave(KErrArgument);
+ }
+ TUint32 crossCheck = TExifCommon::Uint32L(
+ CONST_CAST( TUint8*, aInData.Ptr() ) );
+ if ( crossCheck != iCrossCheckBegin )
+ {
+ User::Leave(KErrArgument);
+ }
+ crossCheck = TExifCommon::Uint32L(
+ CONST_CAST( TUint8*, aInData.Ptr() + aInData.Length() / 2 ) );
+ if ( crossCheck != iCrossCheckMiddle )
+ {
+ User::Leave(KErrArgument);
+ }
+ crossCheck = TExifCommon::Uint32L(
+ CONST_CAST( TUint8*, aInData.Ptr() + aInData.Length() - 5 ) );
+ if ( crossCheck != iCrossCheckEnd )
+ {
+ User::Leave(KErrArgument);
+ }
+ }
+ }
+ else
+ {
+ if ( inputProvidedLate )
+ {
+ iExifRead->ParseJpegDataL( aInData );
+ }
+ }
+
+ User::LeaveIfError( iExifCore->Finalize() );
+
+ if ( !iExifCore->IsValid() )
+ {
+ User::Leave( KErrNotReady );
+ }
+
+ TUint totalSize = 0;
+ if ( inputProvidedLate )
+ {
+ iExifCore->SetDataStartPtr( CONST_CAST( TUint8*, aInData.Ptr() ) );
+ totalSize = iExifCore->TotalSize();
+ }
+ else
+ {
+ totalSize = iExifCore->App1Size() + 2;
+ }
+ // Allocation amount is even for 2-byte alignment
+ HBufC8* exifData = HBufC8::NewLC( totalSize + ( totalSize % 2 ) );
+ exifData->Des().SetLength( totalSize + ( totalSize % 2 ) );
+ TUint pos = 0;
+ if ( inputProvidedLate )
+ {
+ iExifCore->WriteJpegHeaderL( exifData, pos );
+ iExifCore->WriteExifDataL( exifData, pos );
+ TPtr8 ptr( CONST_CAST( TUint8*, exifData->Ptr() ) + pos,
+ iExifCore->JpegSize() );
+ User::LeaveIfError( iExifCore->GetJpegData( ptr ) );
+ }
+ else
+ {
+ iExifCore->WriteExifDataL( exifData, pos );
+ }
+ exifData->Des().SetLength( totalSize );
+ CleanupStack::Pop();
+ return exifData;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetImageDescriptionL
+// Inserts/Updates given ImageDescription in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetImageDescriptionL( const TDesC8& aImageDescription )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdImageDescription, aImageDescription );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetMakeL
+// Inserts/Updates given Make in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetMakeL( const TDesC8& aMake )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdMake, aMake );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetModelL
+// Inserts/Updates given Model in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetModelL( const TDesC8& aModel )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdModel, aModel );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetOrientationL
+// Inserts/Updates given Orientation in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetOrientationL( TUint16 aOrientation )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdOrientation, aOrientation );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetXResolutionL
+// Inserts/Updates given X Resolution in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetXResolutionL(
+ TUint32 aXResolution1,
+ TUint32 aXResolution2 )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdXResolution, aXResolution1, aXResolution2 );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetYResolutionL
+// Inserts/Updates given Y Resolution in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetYResolutionL(
+ TUint32 aYResolution1,
+ TUint32 aYResolution2 )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdYResolution, aYResolution1, aYResolution2 );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetResolutionUnitL
+// Inserts/Updates given Resolution Unit in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetResolutionUnitL( TUint16 aResolutionUnit )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdResolutionUnit, aResolutionUnit );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetTransferFunctionL
+// Inserts/Updates given Transfer Function in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetTransferFunctionL( const TDesC8& aTransferFunction )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdTransferFunction, aTransferFunction );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetDateTimeL
+// Inserts/Updates given Date Time in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetDateTimeL( const TDesC8& aDateTime )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdDateTime, aDateTime );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetYCbCrPositioningL
+// Inserts/Updates given YCbCr Positioning in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetYCbCrPositioningL( TUint16 aYCbCrPositioning )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdYCbCrPositioning, aYCbCrPositioning );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetSoftwareL
+// Inserts/Updates given Software in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetSoftwareL( const TDesC8& aSoftware )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdSoftware, aSoftware );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetCopyrightL
+// Inserts/Updates given Copyright in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetCopyrightL( const TDesC8& aCopyright )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdCopyright, aCopyright );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetExposureTimeL
+// Inserts/Updates given Exposure Time in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetExposureTimeL(
+ TUint32 aExposureTime1,
+ TUint32 aExposureTime2 )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdExposureTime, aExposureTime1, aExposureTime2 );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetComponentsConfigurationL
+// Inserts/Updates given Components Configuration in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetComponentsConfigurationL(
+ TUint8 aFirstComponent, TUint8 aSecondComponent,
+ TUint8 aThirdComponent, TUint8 aFourthComponent )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ TUint32 componentsConfiguration = ( aFourthComponent << 24 ) +
+ ( aThirdComponent << 16 ) + ( aSecondComponent << 8 ) + aFirstComponent;
+ iExifCore->SetTagDataL( KIdComponentsConfiguration,
+ componentsConfiguration );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetFlashL
+// Inserts/Updates given Flash in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetFlashL( TUint16 aFlash )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdFlash, aFlash );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetColorSpaceL
+// Inserts/Updates given Color Space in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetColorSpaceL( TUint16 aColorSpace )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdColorSpace, aColorSpace );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetPixelXDimensionL
+// Inserts/Updates given Pixel X Dimension in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetPixelXDimensionL( TUint32 aPixelXDimension )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdPixelXDimension, aPixelXDimension );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetPixelYDimensionL
+// Inserts/Updates given Pixel Y Dimension in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetPixelYDimensionL( TUint32 aPixelYDimension )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdPixelYDimension, aPixelYDimension );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetExposureModeL
+// Inserts/Updates given Exposure Mode in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetExposureModeL( TUint16 aExposureMode )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdExposureMode, aExposureMode );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetWhiteBalanceL
+// Inserts/Updates given White Balance in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetWhiteBalanceL( TUint16 aWhiteBalance )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdWhiteBalance, aWhiteBalance );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetSceneCaptureTypeL
+// Inserts/Updates given Scene Capture Type in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetSceneCaptureTypeL( TUint16 aSceneCaptureType )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdSceneCaptureType, aSceneCaptureType );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetExposureProgramL
+// Inserts/Updates given Exposure Program in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetExposureProgramL( TUint16 aExposureProgram )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdExposureProgram, aExposureProgram );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetIsoSpeedRatingsL
+// Inserts/Updates given Iso Speed Ratings in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetIsoSpeedRatingsL( const TDesC8& aIsoSpeedRatings )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdIsoSpeedRatings, aIsoSpeedRatings );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetDateTimeOriginalL
+// Inserts/Updates given Date Time Original in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetDateTimeOriginalL( const TDesC8& aDateTimeOriginal )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdDateTimeOriginal, aDateTimeOriginal );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetDateTimeDigitizedL
+// Inserts/Updates given Date Time Digitized in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetDateTimeDigitizedL( const TDesC8& aDateTimeDigitized )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdDateTimeDigitized, aDateTimeDigitized );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetApertureValueL
+// Inserts/Updates given Aperture Value in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetApertureValueL(
+ TUint32 aApertureValue1,
+ TUint32 aApertureValue2 )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL(
+ KIdApertureValue, aApertureValue1, aApertureValue2 );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetExposureBiasValueL
+// Inserts/Updates given Exposure Bias Value in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetExposureBiasValueL(
+ TInt32 aExposureBiasValue1,
+ TInt32 aExposureBiasValue2 )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdExposureBiasValue,
+ aExposureBiasValue1, aExposureBiasValue2 );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetMeteringModeL
+// Inserts/Updates given Metering Mode in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetMeteringModeL( TUint16 aMeteringMode )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdMeteringMode, aMeteringMode );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetLightSourceL
+// Inserts/Updates given Light Source in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetLightSourceL( TUint16 aLightSource )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdLightSource, aLightSource );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetMakerNoteL
+// Inserts/Updates given Maker Note in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetMakerNoteL( const TDesC8& aMakerNote )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdMakerNote, aMakerNote );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetUserCommentL
+// Inserts/Updates given User Comment in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetUserCommentL( const TDesC8& aUserComment )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+ iExifCore->SetTagDataL( KIdUserComment, aUserComment );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetRelatedSoundFileL
+// Inserts/Updates given Related Sound File in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetRelatedSoundFileL( const TDesC8& aRelatedSoundFile )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdRelatedSoundFile, aRelatedSoundFile );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetFileSourceL
+// Inserts/Updates given FileSource in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetFileSourceL(TInt8 aFileSource )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdFileSource, aFileSource );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetDigitalZoomRatioL
+// Inserts/Updates given Digital Zoom Ratio in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetDigitalZoomRatioL(
+ TUint32 aDigitalZoomRatio1,
+ TUint32 aDigitalZoomRatio2 )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdDigitalZoomRatio,
+ aDigitalZoomRatio1, aDigitalZoomRatio2 );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetContrastL
+// Inserts/Updates given Contrast in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetContrastL( TUint16 aContrast )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdContrast, aContrast );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetSaturationL
+// Inserts/Updates given Saturation in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetSaturationL( TUint16 aSaturation )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdSaturation, aSaturation );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetSharpnessL
+// Inserts/Updates given Sharpness in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetSharpnessL( TUint16 aSharpness )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdSharpness, aSharpness );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetThumbnailXResolutionL
+// Inserts/Updates given Thumbnail X Resolution in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetThumbnailXResolutionL(
+ TUint32 aXResolution1,
+ TUint32 aXResolution2 )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetThumbnailTagDataL(KIdXResolution,
+ aXResolution1, aXResolution2 );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetThumbnailYResolutionL
+// Inserts/Updates given Thumbnail Y Resolution in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetThumbnailYResolutionL(
+ TUint32 aYResolution1,
+ TUint32 aYResolution2 )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetThumbnailTagDataL(KIdYResolution,
+ aYResolution1, aYResolution2 );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetThumbnailResolutionUnitL
+// Inserts/Updates given Thumbnail Resolution Unit in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetThumbnailResolutionUnitL( TUint16 aResolutionUnit )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetThumbnailTagDataL(KIdResolutionUnit, aResolutionUnit );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetShutterSpeedValueL
+// Inserts/Updates given Shutter Speed Value in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetShutterSpeedValueL(
+ TInt32 aShutterSpeedValue1,
+ TInt32 aShutterSpeedValue2 )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL(KIdShutterSpeedValue,
+ aShutterSpeedValue1, aShutterSpeedValue2 );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetBrightnessValueL
+// Inserts/Updates given Brightness Value in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetBrightnessValueL(
+ TInt32 aBrightnessValue1,
+ TInt32 aBrightnessValue2 )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL(KIdBrightnessValue,
+ aBrightnessValue1, aBrightnessValue2 );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetCustomRenderedL
+// Inserts/Updates given Custom Rendered in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetCustomRenderedL( TUint16 aCustomRendered )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdCustomRendered, aCustomRendered );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifModifyImpl::SetGainControlL
+// Inserts/Updates given Gain Control in the Exif data.
+// -----------------------------------------------------------------------------
+//
+void CExifModifyImpl::SetGainControlL( TUint16 aGainControl )
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ iExifCore->SetTagDataL( KIdGainControl, aGainControl );
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/src/ExifRead.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,1593 @@
+/*
+* Copyright (c) 2003, 2004 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: Exif v2.2 file format reader/parser API implementation
+*
+*/
+
+
+// INCLUDE FILES
+#include "ExifReadImpl.h"
+#include "ExifCore.h"
+#include "ExifEndian.h"
+#include "ExifCommon.h"
+#include "ExifTagImpl.h"
+
+// ============================ CLASS CExifRead ================================
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CExifRead::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CExifRead* CExifRead::NewL( const TDesC8& aExifData )
+ {
+ return CExifReadImpl::NewL( aExifData, EFalse, CExifRead::ENoOptions );
+ }
+
+EXPORT_C CExifRead* CExifRead::NewL( const TDesC8& aExifData, TUint aExifReadOption )
+ {
+ return CExifReadImpl::NewL( aExifData, EFalse, aExifReadOption );
+ }
+
+// Destructor
+CExifRead::~CExifRead()
+ {
+ }
+
+
+// ============================ CLASS CExifReadImpl ============================
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::CExifReadImpl
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CExifReadImpl::CExifReadImpl()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CExifReadImpl::ConstructL( const TDesC8& aExifData, TBool aCreate, TUint aExifReadOption )
+ {
+ LOGTEXT3( _L( "ExifLib: CExifReadImpl::ConstructL() entering: aCreate=%x, aExifReadOption=0x%x" ), aCreate, aExifReadOption );
+ iExifReadOption = aExifReadOption;
+ iExifCore = CExifCore::NewL();
+ iReader = CExifEndianBase::NewBaseL( aExifData.Ptr(), aExifData.Length(),
+ !aCreate );
+
+ if ( aCreate )
+ {
+ ParseJpegDataL();
+ }
+ else
+ {
+ ParseExifFormatL();
+ if ( !(iExifReadOption & CExifRead::ENoTagChecking ) &&
+ !iExifCore->IsValid() )
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ConstructL() Leaving KErrNotSupported" ));
+ User::Leave( KErrNotSupported );
+ }
+ }
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ConstructL() returning" ));
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CExifReadImpl::ConstructL()
+ {
+ iExifReadOption = CExifRead::ENoOptions;
+ iExifCore = CExifCore::NewL();
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CExifReadImpl* CExifReadImpl::NewL( const TDesC8& aExifData, TBool aCreate, TUint aExifReadOption )
+ {
+ CExifReadImpl* self = new( ELeave ) CExifReadImpl();
+ CleanupStack::PushL( self );
+ self->ConstructL( aExifData, aCreate, aExifReadOption );
+ CleanupStack::Pop();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CExifReadImpl* CExifReadImpl::NewL()
+ {
+ CExifReadImpl* self = new( ELeave ) CExifReadImpl();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+// Destructor
+CExifReadImpl::~CExifReadImpl()
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::~CExifReadImpl() entering" ) );
+ if ( iExifCore )
+ {
+ delete iExifCore;
+ }
+ if ( iReader )
+ {
+ delete iReader;
+ }
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::~CExifReadImpl() returning" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetTagL
+// Returns the Tag instance that has the specified tag ID from the requested IFD
+// -----------------------------------------------------------------------------
+//
+const CExifTag* CExifReadImpl::GetTagL(
+ const TExifIfdType aIfdType,
+ const TUint16 aTagId ) const
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ if ( !TExifCommon::IsValidTagId( aTagId ) )
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::GetTagL Leave( KErrNotSupported )" ) );
+ User::Leave( KErrNotSupported );
+ }
+ return iExifCore->GetTagL( aIfdType, aTagId );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetTagIdsL
+// Returns the IDs of all the tags that are stored in the Exif data.
+// -----------------------------------------------------------------------------
+//
+TUint16* CExifReadImpl::GetTagIdsL(
+ const TExifIfdType aIfdType,
+ TInt& aNoTags ) const
+ {
+ if ( !iExifCore )
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::GetTagIdsL Leave( KErrGeneral )" ) );
+ User::Leave( KErrGeneral );
+ }
+
+ return iExifCore->GetTagIdsL( aIfdType, aNoTags );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetIfdTypesL
+// Returns the types of the IFDs stored in the Exif data.
+// -----------------------------------------------------------------------------
+//
+TExifIfdType* CExifReadImpl::GetIfdTypesL( TInt& aNoIfd ) const
+ {
+ if ( !iExifCore )
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::GetIfdTypesL Leave( KErrGeneral )" ) );
+ User::Leave( KErrGeneral );
+ }
+
+ return iExifCore->GetIfdTypesL( aNoIfd );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetThumbnailL
+// Returns pointer to a copy of the thumbnail image data.
+// -----------------------------------------------------------------------------
+//
+HBufC8* CExifReadImpl::GetThumbnailL() const
+ {
+ if ( !iExifCore )
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::GetThumbnailL Leave( KErrGeneral )" ) );
+ User::Leave( KErrGeneral );
+ }
+
+ return iExifCore->GetThumbnailL();
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::IfdExists
+// Returns a boolean stating if the queried IFD structure exists in Exif data
+// -----------------------------------------------------------------------------
+//
+TBool CExifReadImpl::IfdExists( const TExifIfdType aIfdType ) const
+ {
+ if ( !iExifCore )
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::IfdExists return EFalse" ) );
+ return EFalse;
+ }
+
+ return iExifCore->IfdExists( aIfdType );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::TagExists
+// Returns a boolean stating if the queried tag exists in the specified IFD
+// structure
+// -----------------------------------------------------------------------------
+//
+TBool CExifReadImpl::TagExists(
+ const TUint16 aTagId,
+ const TExifIfdType aIfdType ) const
+ {
+ if ( !iExifCore )
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::TagExists return EFalse" ) );
+ return EFalse;
+ }
+
+ return iExifCore->TagExists( aTagId, aIfdType );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::ParseExifFormatL
+// Parses the IFD data according to the specified IFD type.
+// -----------------------------------------------------------------------------
+//
+void CExifReadImpl::ParseExifFormatL()
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ParseExifFormatL() entering" ) );
+ if ( ( !iExifCore ) || ( !iReader ) )
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ParseExifFormatL() Leaving KErrGeneral" ) );
+ User::Leave( KErrGeneral );
+ }
+
+ TUint32 ifd1Offset = 0;
+ ParseIfdL( EIfd0, ifd1Offset );
+
+ TUint32 ifdExifOffset = 0;
+ User::LeaveIfError( iExifCore->GetTagData( KIdExifIfdPointer,
+ ifdExifOffset ) );
+
+ User::LeaveIfError( iReader->MoveTo( ifdExifOffset ) );
+
+ TUint32 nextIfdOffset = 0;
+ ParseIfdL( EIfdExif, nextIfdOffset );
+
+ TUint32 ifdGpsOffset = 0 ;
+ if ( !iExifCore->GetTagData( KIdGpsIfdPointer, ifdGpsOffset ) )
+ {
+ User::LeaveIfError( iReader->MoveTo( ifdGpsOffset ) );
+ iExifCore->CreateIfdL( EIfdGps );
+ nextIfdOffset = 0;
+ ParseIfdL( EIfdGps, nextIfdOffset );
+ }
+
+ TUint32 ifdIntOpOffset = 0;
+ if ( !iExifCore->GetTagData( KIdIntOpIfdPointer, ifdIntOpOffset ) )
+ {
+ User::LeaveIfError( iReader->MoveTo( ifdIntOpOffset ) );
+ iExifCore->CreateIfdL( EIfdIntOp );
+ nextIfdOffset = 0;
+ ParseIfdL( EIfdIntOp, nextIfdOffset );
+ }
+
+ if ( ifd1Offset )
+ {
+ User::LeaveIfError( iReader->MoveTo( ifd1Offset ) );
+ TRAPD( error, ParseIfdL( EIfd1, nextIfdOffset ) );
+ if ( error == KErrNotSupported )
+ {
+ iExifCore->DeleteIfd( EIfd1 );
+ }
+ else if ( error == KErrCorrupt && ( iExifReadOption & CExifRead::ENoTagChecking ) )
+ {
+ iExifCore->DeleteIfd( EIfd1 );
+ }
+ else
+ {
+ LOGTEXT2( _L( "ExifLib: CExifReadImpl::ParseExifFormatL() ParseIfdL error=%d" ), error );
+ User::LeaveIfError( error );
+ }
+ }
+
+ // Parse jpeg data only if it is read to buffer
+ if ( !(iExifReadOption & (CExifRead::ENoJpeg)) )
+ {
+ ParseJpegDataL();
+ }
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ParseExifFormatL() returning" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::ParseIfdL
+// Parses the Jpeg primary image data and initializes the Jpeg primary image
+// structures.
+// -----------------------------------------------------------------------------
+//
+void CExifReadImpl::ParseIfdL(
+ const TExifIfdType aIfdType,
+ TUint32& aNextIfdOffset )
+ {
+ LOGTEXT3( _L( "ExifLib: CExifReadImpl::ParseIfdL() entering: aIfdType=0x%x, aNextIfdOffset=0x%x" ), aIfdType, aNextIfdOffset );
+ if ( ( !iExifCore ) || ( !iReader ) )
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ParseIfdL() Leaving KErrGeneral" ) );
+ User::Leave( KErrGeneral );
+ }
+
+ TUint16 noTagsInIfd = 0;
+ User::LeaveIfError( iReader->ReadUInt16( noTagsInIfd ) );
+ if ( !noTagsInIfd )
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ParseIfdL() Leaving KErrNotSupported" ) );
+ User::Leave( KErrNotSupported );
+ }
+ // Read and create each tag one by one
+ TUint32 tagsEndOffset = 0;
+ for ( TUint16 i = 0; i < noTagsInIfd; ++i )
+ {
+ TUint16 tagId = 0;
+ TUint16 tagType = 0;
+ TUint32 tagCount = 0;
+ User::LeaveIfError( ReadTagHeader( tagId, tagType, tagCount ) );
+ TUint noBytes = 0;
+ if ( ( tagType == CExifTag::ETagByte ) ||
+ ( tagType == CExifTag::ETagAscii ) ||
+ ( tagType == CExifTag::ETagUndefined ) )
+ {
+ noBytes = sizeof( TUint8 );
+ }
+ else if ( ( tagType == CExifTag::ETagLong ) ||
+ ( tagType == CExifTag::ETagSlong ) )
+ {
+ noBytes = sizeof( TUint32 );
+ }
+ else if ( ( tagType == CExifTag::ETagRational ) ||
+ ( tagType == CExifTag::ETagSrational ) )
+ {
+ noBytes = 2 * sizeof( TUint32 );
+ }
+ else if ( tagType == CExifTag::ETagShort )
+ {
+ noBytes = sizeof( TUint16 );
+ }
+ else
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ParseIfdL() Leaving KErrCorrupt" ) );
+ User::Leave( KErrCorrupt );
+ }
+ LOGTEXT2( _L( "ExifLib: CExifReadImpl::ParseIfdL() noBytes=%d" ), noBytes );
+
+ if ( tagCount > KMaxApp1Size )
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ParseIfdL() Leaving KErrCorrupt (>KMaxApp1Size)" ) );
+ User::Leave( KErrCorrupt );
+ }
+ LOGTEXT2( _L( "ExifLib: CExifReadImpl::ParseIfdL() tagCount=%d" ), tagCount );
+
+ if ( !tagCount )
+ {
+ if ( noBytes > 4)
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ParseIfdL() Leaving KErrCorrupt (noBytes > 4)" ) );
+ User::Leave( KErrCorrupt );
+ }
+ tagCount = 4 / noBytes;
+ }
+ noBytes *= tagCount;
+ HBufC8* valueBuffer = HBufC8::NewL( noBytes );
+ CleanupStack::PushL( valueBuffer );
+
+ // If real tag data size is smaller than 4 bytes, the data is at the
+ // current position. Otherwise 4-byte pointer to the real data location
+ // is kept. The pointer is at current location.
+ LOGTEXT2( _L( "ExifLib: CExifReadImpl::ParseIfdL() noBytes=%d" ), noBytes );
+ if ( noBytes < 5 )
+ {
+ iReader->CopyBuffer( tagCount,
+ STATIC_CAST( TUint8, ( noBytes / tagCount ) ), valueBuffer );
+ // Skip remaining bytes.
+ if ( 4 - noBytes )
+ {
+ LOGTEXT2( _L( "ExifLib: CExifReadImpl::ParseIfdL() skipping=%d" ), 4 - noBytes );
+ iReader->Skip( 4 - noBytes );
+ }
+ }
+ else
+ {
+ TUint32 valueOffset = 0;
+ User::LeaveIfError( iReader->ReadUInt32( valueOffset ) );
+ LOGTEXT2( _L( "ExifLib: CExifReadImpl::ParseIfdL() valueOffset=%d" ), valueOffset );
+ User::LeaveIfError( iReader->CopyBuffer( valueOffset, tagCount,
+ STATIC_CAST( TUint8, ( noBytes / tagCount ) ), valueBuffer ) );
+ LOGTEXT2( _L( "ExifLib: CExifReadImpl::ParseIfdL() tagCount=%d" ), tagsEndOffset );
+ if ( tagsEndOffset < ( valueOffset + noBytes ) )
+ {
+ tagsEndOffset = valueOffset + noBytes;
+ }
+ }
+
+ //
+ // Test if unknown tags should just be skipped and delete
+ //
+ LOGTEXT2( _L( "ExifLib: CExifReadImpl::ParseIfdL() iExifReadOption=%x" ), iExifReadOption );
+ if ( !(iExifReadOption & CExifRead::ENoTagChecking ) && !TExifCommon::IsValidTagId( tagId ) )
+ {
+ LOGTEXT2( _L( "ExifLib: CExifReadImpl::ParseIfdL() skipping tagId=%x" ), tagId );
+ CleanupStack::PopAndDestroy( valueBuffer );
+ }
+ else // Tag was known
+ {
+ LOGTEXT2( _L( "ExifLib: CExifReadImpl::ParseIfdL() create new tagId=%x" ), tagId );
+ CExifTagImpl* tag = NULL;
+ if ( iExifReadOption & CExifRead::ENoTagChecking )
+ {
+ tag = CExifTagImpl::NewL( tagId,
+ STATIC_CAST( CExifTag::TExifTagDataType, tagType ),
+ tagCount, valueBuffer, EFalse );
+ }
+ else
+ {
+ tag = CExifTagImpl::NewL( tagId,
+ STATIC_CAST( CExifTag::TExifTagDataType, tagType ),
+ tagCount, valueBuffer, ETrue );
+ }
+ CleanupStack::Pop( valueBuffer );
+ CleanupStack::PushL( tag );
+
+ // Ignore case when valid tag is in wrong IFD and ENoTagChecking is set
+ if ( !iExifCore->TagIsValid( tag->TagInfo(), aIfdType ) )
+ {
+ if ( iExifReadOption & CExifRead::ENoTagChecking )
+ {
+ LOGTEXT3( _L( "ExifLib: CExifReadImpl::ParseIfdL() keep tagId=0x%x in wrong aIfdType=0x%x" ), tagId, aIfdType );
+ iExifCore->InsertTagL( aIfdType, tag, EFalse );
+ CleanupStack::Pop( tag );
+ }
+ else
+ {
+ LOGTEXT3( _L( "ExifLib: CExifReadImpl::ParseIfdL() skipping tagId=0x%x in wrong aIfdType=0x%x" ), tagId, aIfdType );
+ CleanupStack::PopAndDestroy( tag );
+ }
+ }
+ else // Tag is in correct IFD
+ {
+ if ( iExifReadOption & CExifRead::ENoTagChecking )
+ {
+ iExifCore->InsertTagL( aIfdType, tag, EFalse );
+ }
+ else
+ {
+ iExifCore->InsertTagL( aIfdType, tag, ETrue );
+ }
+ CleanupStack::Pop( tag );
+ }
+ }
+
+ }
+ User::LeaveIfError( iReader->ReadUInt32( aNextIfdOffset ) );
+ if ( tagsEndOffset )
+ {
+ User::LeaveIfError( iReader->MoveTo( tagsEndOffset ) );
+ }
+ if ( aIfdType == EIfd1 )
+ {
+ ParseThumbnailL();
+ }
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ParseIfdL() returning" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::ParseJpegDataL
+// Parses the Jpeg primary image data and initializes the Jpeg primary image
+// structures.
+// -----------------------------------------------------------------------------
+//
+void CExifReadImpl::ParseJpegDataL()
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ParseIfdL() entering" ) );
+ if ( ( !iExifCore ) || ( !iReader ) )
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ParseIfdL() Leave( KErrGeneral )" ) );
+ User::Leave( KErrGeneral );
+ }
+
+ TUint32 jpgStartOffset = 0;
+ TUint32 jpgStartOffset2 = 0;
+ TUint32 jpgEndOffset = 0;
+ TUint32 jpgEndOffset2 = 0;
+ TUint32 jpgSofOffset = 0;
+
+ // 1. Find the last 2 EOI markers.
+ if ( iReader->LocateJpegMarkerFromEnd( KEoi, jpgEndOffset ) )
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ParseIfdL() Leave( KErrCorrupt )LocateJpegMarkerFromEnd" ) );
+ User::Leave( KErrCorrupt );
+ }
+
+ if ( iExifReadOption & CExifRead::EFastJpegParsing )
+ {
+ // Read current position after exif header parsing
+ iReader->CurrentPosOffset(jpgStartOffset);
+
+ // add start offset by 2 if exif header was not in image
+ // SOI is in 0 position
+ if ( !jpgStartOffset && jpgEndOffset )
+ {
+ jpgStartOffset += 2;
+ }
+ }
+ else
+ { // Scan the whole jpeg image data
+
+ iReader->LocateJpegMarkerFromEnd( KEoi, jpgEndOffset2, 0, jpgEndOffset );
+
+ // Assumption: There might be additional redundant EOI markers after the
+ // real EOI. Difference between two EOI marker is assumed to be 150 bytes.
+ while( jpgEndOffset - jpgEndOffset2 < 150 )
+ {
+ jpgEndOffset = jpgEndOffset2;
+ jpgEndOffset2 = 0;
+ iReader->LocateJpegMarkerFromEnd(
+ KEoi, jpgEndOffset2, 0, jpgEndOffset );
+ }
+
+ // 2. Find the SOF0 marker between the EOI markers.
+ if ( iReader->LocateJpegMarker(
+ KSof0, jpgSofOffset, jpgEndOffset2, jpgEndOffset ) )
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ParseIfdL() Leave( KErrNotSupported )LocateJpegMarker" ) );
+ User::Leave( KErrNotSupported );
+ }
+
+ jpgStartOffset = jpgSofOffset;
+
+ if ( (jpgStartOffset >= jpgEndOffset ) ||
+ ( jpgStartOffset < jpgEndOffset2 ) )
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ParseIfdL() Leave( KErrNotSupported )jpgStartOffset" ) );
+ User::Leave( KErrNotSupported );
+ }
+
+ // 3. Find other Jpeg markers between the 2nd last EOI and the last
+ // SOF0 marker.
+ if ( iReader->LocateJpegMarker(
+ KDqt, jpgStartOffset2, jpgEndOffset2, jpgStartOffset ) == KErrNone)
+ {
+ if ( jpgStartOffset2 < jpgStartOffset )
+ {
+ jpgStartOffset = jpgStartOffset2;
+ }
+ }
+
+ if ( iReader->LocateJpegMarker(
+ KDht, jpgStartOffset2, jpgEndOffset2, jpgStartOffset ) == KErrNone)
+ {
+ if ( jpgStartOffset2 < jpgStartOffset )
+ {
+ jpgStartOffset = jpgStartOffset2;
+ }
+ }
+
+ if ( iReader->LocateJpegMarker(
+ KDri, jpgStartOffset2, jpgEndOffset2, jpgStartOffset ) == KErrNone)
+ {
+ if ( jpgStartOffset2 < jpgStartOffset )
+ {
+ jpgStartOffset = jpgStartOffset2;
+ }
+ }
+ }
+ // Should include the EOI marker.
+ jpgEndOffset += 2;
+
+ iExifCore->SetJpgOffsets( jpgStartOffset, jpgEndOffset );
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ParseIfdL() returning" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::ParseThumbnailL
+// Parses the Jpeg thumbnail image data and initializes the Jpeg thumbnail
+// structures.
+// -----------------------------------------------------------------------------
+//
+void CExifReadImpl::ParseThumbnailL()
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ParseThumbnailL() entering" ) );
+ if ( ( !iExifCore ) || ( !iReader ) )
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ParseThumbnailL() Leave( KErrGeneral )" ) );
+ User::Leave( KErrGeneral );
+ }
+
+ TUint32 thumbnailStart = 0;
+ if ( iExifCore->GetThumbnailTagData( KIdJpegInterchangeFormat,
+ thumbnailStart ) )
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ParseThumbnailL() Leave( KErrCorrupt )GetThumbnailTagData1" ) );
+ User::Leave( KErrCorrupt );
+ }
+ TUint32 thumbnailSize = 0;
+ if ( iExifCore->GetThumbnailTagData( KIdJpegInterchangeFormatLength,
+ thumbnailSize ) )
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ParseThumbnailL() Leave( KErrCorrupt )GetThumbnailTagData2" ) );
+ User::Leave( KErrCorrupt );
+ }
+
+ LOGTEXT3( _L( "ExifLib: CExifReadImpl::ParseThumbnailL() thumbnailStart=%d, thumbnailSize=%d" ), thumbnailStart, thumbnailSize );
+ if ( thumbnailSize > KMaxApp1Size )
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ParseThumbnailL() Leave( KErrCorrupt ) thumbnailSize > KMaxApp1Size" ) );
+ User::Leave( KErrCorrupt );
+ }
+
+ iReader->MoveTo( thumbnailStart );
+ HBufC8* buffer = HBufC8::NewLC( thumbnailSize );
+ iReader->CopyBuffer( thumbnailSize, 1, buffer );
+ iExifCore->InsertThumbnailL( buffer );
+ CleanupStack::Pop();
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ParseThumbnailL() returning" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::ReadTagHeader
+// Reads the tag header, and returns the header information in the parameters.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::ReadTagHeader(
+ TUint16& aTagId,
+ TUint16& aTagType,
+ TUint32& aTagCount ) const
+ {
+ LOGTEXT4( _L( "ExifLib: CExifReadImpl::ReadTagHeader() entering: aTagId=0x%x, aTagType=0x%x, aTagCount=0x%x" ), aTagId, aTagType, aTagCount );
+ if ( !iReader )
+ {
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ReadTagHeader() returning KErrGeneral" ) );
+ return KErrGeneral;
+ }
+
+ TInt error = iReader->ReadUInt16( aTagId );
+ if ( error )
+ {
+ LOGTEXT2( _L( "ExifLib: CExifReadImpl::ReadTagHeader() returning aTagId error=%d" ),error );
+ return error;
+ }
+ error = iReader->ReadUInt16( aTagType );
+ if ( error )
+ {
+ LOGTEXT2( _L( "ExifLib: CExifReadImpl::ReadTagHeader() returning aTagType error=%d" ),error );
+ return error;
+ }
+ error = iReader->ReadUInt32( aTagCount );
+ if ( error )
+ {
+ LOGTEXT2( _L( "ExifLib: CExifReadImpl::ReadTagHeader() returning aTagCount error=%d" ),error );
+ return error;
+ }
+ LOGTEXT( _L( "ExifLib: CExifReadImpl::ReadTagHeader() returning" ) );
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetImageDescriptionL
+// Gets the Image Description tag data.
+// -----------------------------------------------------------------------------
+//
+HBufC8* CExifReadImpl::GetImageDescriptionL() const
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ return iExifCore->GetTagDataL( KIdImageDescription );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetMakeL
+// Gets the Make tag data.
+// -----------------------------------------------------------------------------
+//
+HBufC8* CExifReadImpl::GetMakeL() const
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ return iExifCore->GetTagDataL( KIdMake );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetModelL
+// Gets the Model tag data.
+// -----------------------------------------------------------------------------
+//
+HBufC8* CExifReadImpl::GetModelL() const
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ return iExifCore->GetTagDataL( KIdModel );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetOrientation
+// Gets the Orientation tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetOrientation( TUint16& aOrientation ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdOrientation, aOrientation );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetXResolution
+// Gets the X Resolution tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetXResolution(
+ TUint32& aXResolutionNumerator,
+ TUint32& aXResolutionDenumerator ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdXResolution,
+ aXResolutionNumerator, aXResolutionDenumerator );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetYResolution
+// Gets the Y Resolution tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetYResolution(
+ TUint32& aYResolutionNumerator,
+ TUint32& aYResolutionDenumerator ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdYResolution,
+ aYResolutionNumerator, aYResolutionDenumerator );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetResolutionUnit
+// Gets the Resolution Unit tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetResolutionUnit( TUint16& aResolutionUnit ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdResolutionUnit, aResolutionUnit );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetTransferFunctionL
+// Gets the Transfer Function tag data.
+// -----------------------------------------------------------------------------
+//
+HBufC8* CExifReadImpl::GetTransferFunctionL() const
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ return iExifCore->GetTagDataL( KIdTransferFunction );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetDateTimeL
+// Gets the Date Time tag data.
+// -----------------------------------------------------------------------------
+//
+HBufC8* CExifReadImpl::GetDateTimeL() const
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ return iExifCore->GetTagDataL( KIdDateTime );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetYCbCrPositioning
+// Gets the YCbCr Positioning tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetYCbCrPositioning( TUint16& aYCbCrPositioning ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdYCbCrPositioning, aYCbCrPositioning );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetSoftwareL
+// Gets the Software tag data.
+// -----------------------------------------------------------------------------
+//
+HBufC8* CExifReadImpl::GetSoftwareL() const
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ return iExifCore->GetTagDataL( KIdSoftware );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetCopyrightL
+// Gets the Copyright tag data.
+// -----------------------------------------------------------------------------
+//
+HBufC8* CExifReadImpl::GetCopyrightL() const
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ return iExifCore->GetTagDataL( KIdCopyright );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetExifIfdPointer
+// Gets the Exif Ifd Pointer tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetExifIfdPointer( TUint32& aExifIfdPointer ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdExifIfdPointer, aExifIfdPointer );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetGpsInfoIfdPointer
+// Gets the Gps Ifd Pointer tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetGpsInfoIfdPointer( TUint32& aGpsInfoIfdPointer ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdGpsIfdPointer, aGpsInfoIfdPointer );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetExposureTime
+// Gets the Exposure Time tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetExposureTime(
+ TUint32& aExposureTime1,
+ TUint32& aExposureTime2 ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdExposureTime,
+ aExposureTime1, aExposureTime2 );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetComponentsConfiguration
+// Gets the Components Configuration tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetComponentsConfiguration(
+ TUint8& aFirstComponent, TUint8& aSecondComponent,
+ TUint8& aThirdComponent, TUint8& aFourthComponent) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ TUint32 componentsConfiguration = 0;
+
+ TInt error = iExifCore->GetTagData( KIdComponentsConfiguration,
+ componentsConfiguration );
+ if ( error )
+ {
+ return error;
+ }
+ aFirstComponent = STATIC_CAST ( TUint8,
+ ( KOneByteMask & componentsConfiguration ) );
+ aSecondComponent = STATIC_CAST ( TUint8,
+ ( KOneByteMask & ( componentsConfiguration >> 8 ) ) );
+ aThirdComponent = STATIC_CAST ( TUint8,
+ ( KOneByteMask & ( componentsConfiguration >> 16 ) ) );
+ aFourthComponent = STATIC_CAST ( TUint8,
+ ( KOneByteMask & ( componentsConfiguration >> 24 ) ) );
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetFlash
+// Gets the Flash tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetFlash( TUint16& aFlash ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdFlash, aFlash );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetColorSpace
+// Gets the Color Space tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetColorSpace( TUint16& aColorSpace ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdColorSpace, aColorSpace );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetPixelXDimension
+// Gets the Pixel X Dimension tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetPixelXDimension( TUint32& aPixelXDimension ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdPixelXDimension, aPixelXDimension );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetPixelYDimension
+// Gets the Pixel Y Dimension tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetPixelYDimension( TUint32& aPixelYDimension ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdPixelYDimension, aPixelYDimension );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetExposureMode
+// Gets the Exposure Mode tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetExposureMode( TUint16& aExposureMode ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdExposureMode, aExposureMode );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetWhiteBalance
+// Gets the White Balance tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetWhiteBalance( TUint16& aWhiteBalance ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdWhiteBalance, aWhiteBalance );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetSceneCaptureType
+// Gets the Scene Capture Type tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetSceneCaptureType( TUint16& aSceneCaptureType ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdSceneCaptureType, aSceneCaptureType );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetExposureProgram
+// Gets the Exposure Program tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetExposureProgram( TUint16& aExposureProgram ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdExposureProgram, aExposureProgram );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetIsoSpeedRatingsL
+// Gets the Iso Speed Ratings tag data.
+// -----------------------------------------------------------------------------
+//
+HBufC8* CExifReadImpl::GetIsoSpeedRatingsL() const
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ return iExifCore->GetTagDataL( KIdIsoSpeedRatings );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetDateTimeOriginalL
+// Gets the Date Time Original tag data.
+// -----------------------------------------------------------------------------
+//
+HBufC8* CExifReadImpl::GetDateTimeOriginalL() const
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ return iExifCore->GetTagDataL( KIdDateTimeOriginal );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetDateTimeDigitizedL
+// Gets the Date Time Digitized tag data.
+// -----------------------------------------------------------------------------
+//
+HBufC8* CExifReadImpl::GetDateTimeDigitizedL() const
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ return iExifCore->GetTagDataL( KIdDateTimeDigitized );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetApertureValue
+// Gets the Aperture Value tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetApertureValue(
+ TUint32& aApertureValue1,
+ TUint32& aApertureValue2 ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdApertureValue,
+ aApertureValue1, aApertureValue2 );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetExposureBiasValue
+// Gets the Exposure Bias Value tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetExposureBiasValue(
+ TInt32& aExposureBiasValue1,
+ TInt32& aExposureBiasValue2 ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdExposureBiasValue,
+ aExposureBiasValue1, aExposureBiasValue2 );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetMeteringMode
+// Gets the Metering Mode tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetMeteringMode( TUint16& aMeteringMode ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdMeteringMode, aMeteringMode );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetLightSource
+// Gets the Light Source tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetLightSource( TUint16& aLightSource ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdLightSource, aLightSource );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetMakerNoteL
+// Gets the Maker Note tag data.
+// -----------------------------------------------------------------------------
+//
+HBufC8* CExifReadImpl::GetMakerNoteL() const
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ return iExifCore->GetTagDataL( KIdMakerNote );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetUserCommentL
+// Gets the User Comment tag data.
+// -----------------------------------------------------------------------------
+//
+HBufC8* CExifReadImpl::GetUserCommentL() const
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ return iExifCore->GetTagDataL( KIdUserComment );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetRelatedSoundFileL
+// Gets the Related Sound File tag data.
+// -----------------------------------------------------------------------------
+//
+HBufC8* CExifReadImpl::GetRelatedSoundFileL() const
+
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ return iExifCore->GetTagDataL( KIdRelatedSoundFile );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetFileSource
+// Gets the File Source tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetFileSource( TInt8& aFileSource ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdFileSource, aFileSource );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetDigitalZoomRatio
+// Gets the Digital Zoom Ratio tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetDigitalZoomRatio(
+ TUint32& aDigitalZoomRatio1,
+ TUint32& aDigitalZoomRatio2 ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdDigitalZoomRatio,
+ aDigitalZoomRatio1, aDigitalZoomRatio2 );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetContrast
+// Gets the Contrast tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetContrast( TUint16& aContrast ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdContrast, aContrast );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetSaturation
+// Gets the Saturation tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetSaturation( TUint16& aSaturation ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdSaturation, aSaturation );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetSharpness
+// Gets the Sharpness tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetSharpness( TUint16& aSharpness ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdSharpness, aSharpness );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetExifVersion
+// Gets the Exif Version tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetExifVersion( TUint32& aExifVersion ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdExifVersion, aExifVersion );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetFlashPixVersion
+// Gets the Flash Pix Version tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetFlashPixVersion( TUint32& aFlashPixVersion ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdFlashPixVersion, aFlashPixVersion );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetInteroperabilityIfdPointer
+// Gets the Interoperability Ifd Pointer tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetInteroperabilityIfdPointer(
+ TUint32& aInteroperabilityIfdPointer ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdIntOpIfdPointer,
+ aInteroperabilityIfdPointer );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetThumbnailXResolution
+// Gets the X Resolution tag data of thumbnail.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetThumbnailXResolution(
+ TUint32& aXResolution1,
+ TUint32& aXResolution2 ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetThumbnailTagData( KIdXResolution,
+ aXResolution1, aXResolution2 );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetThumbnailYResolution
+// Gets the Y Resolution tag data of thumbnail.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetThumbnailYResolution(
+ TUint32& aYResolution1,
+ TUint32& aYResolution2 ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetThumbnailTagData( KIdYResolution,
+ aYResolution1,
+ aYResolution2 );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetThumbnailResolutionUnit
+// Gets the ResolutionUnit tag data of thumbnail.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetThumbnailResolutionUnit( TUint16& aResolutionUnit ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetThumbnailTagData( KIdResolutionUnit, aResolutionUnit );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetThumbnailCompression
+// Gets the Compression tag data of thumbnail.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetThumbnailCompression( TUint16& aCompression ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetThumbnailTagData( KIdCompression, aCompression );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetJpegInterchangeFormat
+// Gets the Jpeg Interchange Format of thumbnail.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetJpegInterchangeFormat(
+ TUint32& aJpegInterchangeFormat ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetThumbnailTagData( KIdJpegInterchangeFormat,
+ aJpegInterchangeFormat );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetJpegInterchangeFormatLength
+// Gets the Jpeg Interchange Format Length of thumbnail.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetJpegInterchangeFormatLength(
+ TUint32& aJpegInterchangeFormatLength ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetThumbnailTagData( KIdJpegInterchangeFormatLength,
+ aJpegInterchangeFormatLength );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetExifAppSegmentL
+// Returns a copy of whole Exif APP1 segment in a descriptor.
+// -----------------------------------------------------------------------------
+HBufC8* CExifReadImpl::GetExifAppSegmentL() const
+ {
+ if ( !iExifCore )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ User::LeaveIfError( iExifCore->Finalize() );
+
+ if ( !iExifCore->IsValid() )
+ {
+ User::Leave( KErrNotReady );
+ }
+
+ TUint size = iExifCore->App1Size();
+ size+=2;
+ // Allocation amount is even for 2-byte alignment
+ HBufC8* exifData = HBufC8::NewLC( size + ( size % 2 ) );
+ exifData->Des().SetLength( size + ( size % 2 ) );
+ TUint pos = 0;
+ iExifCore->WriteExifDataL( exifData, pos );
+ exifData->Des().SetLength( size );
+ CleanupStack::Pop( exifData );
+ return exifData;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetShutterSpeedValue
+// Gets the Shutter Speed Value tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetShutterSpeedValue(
+ TInt32& aShutterSpeedValue1,
+ TInt32& aShutterSpeedValue2 ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdShutterSpeedValue, aShutterSpeedValue1,
+ aShutterSpeedValue2 );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetBrightnessSpeedValue
+// Gets the Brightness Value tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetBrightnessValue(
+ TInt32& aBrightnessValue1,
+ TInt32& aBrightnessValue2 ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdBrightnessValue, aBrightnessValue1,
+ aBrightnessValue2 );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetCustomRendered
+// Gets the Custom Rendered tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetCustomRendered( TUint16& aCustomRendered ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdCustomRendered, aCustomRendered );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetGainControl
+// Gets the Gain Control tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetGainControl( TUint16& aGainControl ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdGainControl, aGainControl );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::GetGpsVersion
+// Gets the Gps Version tag data.
+// -----------------------------------------------------------------------------
+//
+TInt CExifReadImpl::GetGpsVersion( TUint32& aGpsVersion ) const
+ {
+ if ( !iExifCore )
+ {
+ return KErrGeneral;
+ }
+
+ return iExifCore->GetTagData( KIdGpsVersion, aGpsVersion );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifReadImpl::ParseJpegDataL
+// Parses the Jpeg primary image data and initializes the Jpeg primary image
+// structures.
+// -----------------------------------------------------------------------------
+//
+void CExifReadImpl::ParseJpegDataL( const TDesC8& aJpegData )
+ {
+ if ( !iReader )
+ {
+ iReader = CExifEndianBase::NewBaseL( aJpegData.Ptr(), aJpegData.Length(),
+ EFalse );
+ }
+ ParseJpegDataL();
+ delete iReader;
+ iReader = NULL;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/exiflib/src/ExifTag.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,263 @@
+/*
+* Copyright (c) 2003-2006 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: Exif tag wrapper API implementation
+*
+*/
+
+
+// INCLUDE FILES
+#include "ExifTagImpl.h"
+#include "ExifCommon.h"
+
+// ============================ CLASS TExifTagInfo =============================
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// TExifTagInfo::TExifTagInfo
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TExifTagInfo::TExifTagInfo(
+ TUint16 aTagId,
+ CExifTag::TExifTagDataType aDataType,
+ TUint32 aDataCount ):
+ iId( aTagId ),
+ iDataType( aDataType ),
+ iDataCount( aDataCount )
+ {
+ }
+
+
+// ============================ CLASS CExifTag =================================
+// ============================ MEMBER FUNCTIONS ===============================
+
+// Destructor
+CExifTag::~CExifTag()
+ {
+ }
+
+
+// ============================ CLASS CExifTagImpl =============================
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CExifTagImpl::CExifTagImpl
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CExifTagImpl::CExifTagImpl( TExifTagInfo aTagInfo ): iTagInfo( aTagInfo )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CExifTagImpl::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CExifTagImpl::ConstructL( HBufC8* aDataBuffer, TBool aCheckValidity )
+ {
+ LOGTEXT2( _L( "ExifLib: CExifTagImpl::ConstructL entering aCheckValidity=%d" ), aCheckValidity);
+ if ( !aDataBuffer )
+ {
+ LOGTEXT( _L( "ExifLib: CExifTagImpl::ConstructL leaving KErrGeneral" ) );
+ User::Leave( KErrGeneral );
+ }
+ if ( aCheckValidity && !TExifCommon::IsValidTagId( iTagInfo.iId ) )
+ {
+ LOGTEXT( _L( "ExifLib: CExifTagImpl::ConstructL leaving KErrNotSupported" ) );
+ User::Leave( KErrNotSupported );
+ }
+
+ TInt wordLength = 1;
+ if ( iTagInfo.iDataType == ETagShort )
+ {
+ wordLength = 2;
+ }
+ else if ( ( iTagInfo.iDataType == ETagLong ) ||
+ ( iTagInfo.iDataType == ETagSlong ) )
+ {
+ wordLength = 4;
+ }
+ else if ( ( iTagInfo.iDataType == ETagRational ) ||
+ ( iTagInfo.iDataType == ETagSrational ) )
+ {
+ wordLength = 8;
+ }
+ else
+ {
+ // In practice, it never arrives here.
+ }
+ LOGTEXT2( _L( "ExifLib: CExifTagImpl::ConstructL wordLength=%d" ), wordLength );
+
+ if ( aDataBuffer->Length() !=
+ STATIC_CAST( TInt, wordLength * iTagInfo.iDataCount ) )
+ {
+ LOGTEXT3( _L( "ExifLib: CExifTagImpl::ConstructL leaving KErrArgument aDataBuffer->Length()=%d, iTagInfo.iDataCount=%d" ), aDataBuffer->Length(), iTagInfo.iDataCount);
+ User::Leave( KErrArgument );
+ }
+ iData = aDataBuffer;
+ LOGTEXT2( _L( "ExifLib: CExifTagImpl::ConstructL returning aDataBuffer->Length()=%d" ), aDataBuffer->Length() );
+ }
+
+// -----------------------------------------------------------------------------
+// CExifTagImpl::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CExifTagImpl* CExifTagImpl::NewL(
+ TUint16 aTagId,
+ CExifTag::TExifTagDataType aDataType,
+ TUint32 aDataCount,
+ HBufC8* aDataBuffer,
+ TBool aCheckValidity )
+ {
+ if ( !aDataBuffer->Length() )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ CExifTagImpl* self = new( ELeave ) CExifTagImpl( TExifTagInfo( aTagId,
+ aDataType, aDataCount ) );
+ CleanupStack::PushL( self );
+ self->ConstructL( aDataBuffer, aCheckValidity );
+ CleanupStack::Pop();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifTagImpl::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CExifTagImpl* CExifTagImpl::NewL( TExifTagInfo aTagInfo, HBufC8* aDataBuffer, TBool aCheckValidity )
+ {
+ if ( !aDataBuffer )
+ {
+ User::Leave( KErrGeneral );
+ }
+ if ( !aDataBuffer->Length() )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ CExifTagImpl* self = new( ELeave ) CExifTagImpl( aTagInfo );
+ CleanupStack::PushL( self );
+ self->ConstructL( aDataBuffer, aCheckValidity );
+ CleanupStack::Pop();
+ return self;
+ }
+
+// Destructor
+CExifTagImpl::~CExifTagImpl()
+ {
+ if ( iData )
+ {
+ delete iData;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CExifTagImpl::DuplicateL
+// Duplicate constructor. Creates an exact copy instance of the tag.
+// -----------------------------------------------------------------------------
+//
+CExifTag* CExifTagImpl::DuplicateL() const
+ {
+ HBufC8* buffer = iData->AllocL();
+ CleanupStack::PushL( buffer );
+ CExifTagImpl* tag = CExifTagImpl::NewL( iTagInfo.iId, iTagInfo.iDataType,
+ iTagInfo.iDataCount, buffer, ETrue );
+ CleanupStack::Pop( buffer );
+ return tag;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifTagImpl::TagInfo
+// Returns the informative fields of a tag.
+// -----------------------------------------------------------------------------
+//
+TExifTagInfo CExifTagImpl::TagInfo() const
+ {
+ return iTagInfo;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifTagImpl::Id
+// Returns the ID of the tag.
+// -----------------------------------------------------------------------------
+//
+TUint16 CExifTagImpl::Id() const
+ {
+ return iTagInfo.iId;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifTagImpl::DataType
+// Returns the data type of the tag.
+// -----------------------------------------------------------------------------
+//
+CExifTag::TExifTagDataType CExifTagImpl::DataType() const
+ {
+ return iTagInfo.iDataType;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifTagImpl::DataCount
+// Returns the data count of the tag.
+// -----------------------------------------------------------------------------
+//
+TUint32 CExifTagImpl::DataCount() const
+ {
+ return iTagInfo.iDataCount;
+ }
+
+// -----------------------------------------------------------------------------
+// CExifTagImpl::Data
+// Returns the data stored in the tag.
+// -----------------------------------------------------------------------------
+//
+TPtrC8 CExifTagImpl::Data() const
+ {
+ return iData->Des();
+ }
+
+// -----------------------------------------------------------------------------
+// CExifTagImpl::Size
+// Returns the total size of the tag in bytes
+// -----------------------------------------------------------------------------
+//
+TUint CExifTagImpl::Size() const
+ {
+ // If the real tag data size is smaller than 4 bytes, then total tag size is
+ // the default tag size (12). Otherwise, it is:
+ // Default tag size + real tag data size (+ 1 if tag data size is odd).
+ if ( iData->Length() < 5 )
+ {
+ return 12; // The default tag size
+ }
+ else
+ {
+ if ( iData->Length() % 2 )
+ {
+ return ( 12 + iData->Length() + 1 ); // Default tag size + ...
+ }
+ else
+ {
+ return ( 12 + iData->Length() ); // // Default tag size + ...
+ }
+ }
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/group/bld.inf Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,21 @@
+/*
+* Copyright (c) 2006 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 "../exiflib/group/bld.inf"
+#include "../jp2kcodec/Group/bld.inf"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Data/101F862D.rss Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,84 @@
+/*
+* Copyright (c) 2003-2006 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: Resource file for JPEG2000 codec.
+*
+*/
+
+
+// RESOURCE IDENTIFIER
+
+// INCLUDES
+#include <JP2KUids.hrh>
+#include <icl/icl_uids.hrh>
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <icl/icl_uids_def.hrh>
+#endif
+#include <ecom/registryinfo.rh>
+
+// CONSTANTS
+
+// MACROS
+
+// RESOURCE DEFINITIONS
+// -----------------------------------------------------------------------------
+//
+// theInfo
+// ICL codec registeration file for codec selection using ECom and ICL resolver.
+//
+// -----------------------------------------------------------------------------
+//
+RESOURCE REGISTRY_INFO theInfo
+ {
+ dll_uid = KJ2KCodecDllUidValue;
+ interfaces =
+ {
+ INTERFACE_INFO
+ {
+ interface_uid = KDecoderInterfaceUidValue;
+ implementations =
+ {
+ BINARY_IMPLEMENTATION_INFO
+ {
+ implementation_uid = KJ2KDecoderImplementationUid;
+ version_no = 1;
+ display_name = "JPEG2000";
+ default_data = {0x3F}; // "No match for main codec"
+ opaque_data = {1, 0x00, 0x00, 0x10, 0x1F, 0x86, 0x30, 0, 0, 0, 0, 2, 0x2E, 0x6A, 0x70, 0x32, 0x0D, 0x2E, 0x6A, 0x32, 0x6B, 0x0D, 2, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x2F, 0x6A, 0x70, 0x32, 0x0D, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x2F, 0x6A, 0x32, 0x6B, 0x0D};
+ // version 1, "main" codec 0x10 1F 86 30 0x00000000 2 . j p 2 . j 2 k 2 i m a g e / j p 2 i m a g e / j 2 k
+ },
+ BINARY_IMPLEMENTATION_INFO
+ {
+ implementation_uid = KJ2KDecoderImplementationUidValueFileFormat;
+ version_no = 1;
+ display_name = "JPEG2000 File Format";
+ default_data = {0, 0, 0, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A}; // "JP2 Signature"
+ opaque_data = {1, 0x00, 0x01, 0x10, 0x1F, 0x86, 0x30, 0, 0, 0, 0, 2, 0x2E, 0x6A, 0x70, 0x32, 0x0D, 0x2E, 0x6A, 0x32, 0x6B, 0x0D, 2, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x2F, 0x6A, 0x70, 0x32, 0x0D, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x2F, 0x6A, 0x32, 0x6B, 0x0D};
+ // version 1, "main" codec 0x10 1F 86 30 0x00000000 2 . j p 2 . j 2 k 2 i m a g e / j p 2 i m a g e / j 2 k
+ },
+ BINARY_IMPLEMENTATION_INFO
+ {
+ implementation_uid = KJ2KDecoderImplementationUidValueCodeStream;
+ version_no = 1;
+ display_name = "JPEG2000 Code Stream";
+ default_data = {0xFF, 0x4F, 0xFF, 0x51}; // SOC + SIZ
+ opaque_data = {1, 0x00, 0x01, 0x10, 0x1F, 0x86, 0x30, 0, 0, 0, 0, 2, 0x2E, 0x6A, 0x70, 0x32, 0x0D, 0x2E, 0x6A, 0x32, 0x6B, 0x0D, 2, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x2F, 0x6A, 0x70, 0x32, 0x0D, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x2F, 0x6A, 0x32, 0x6B, 0x0D};
+ // version 1, "main" codec 0x10 1F 86 30 0x00000000 2 . j p 2 . j 2 k 2 i m a g e / j p 2 i m a g e / j 2 k
+ }
+ };
+ }
+
+ };
+ }
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Data/101F862D_extra.rss Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,35 @@
+/*
+* Copyright (c) 2003, 2004 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: Extra resource file for JPEG2000 codec.
+*
+*/
+
+
+STRUCT DECODER_INFO
+ {
+ LTEXT decoder_name;
+ LTEXT image_format;
+ LTEXT image_dimensions;
+ LTEXT image_depth[];
+ LTEXT image_details[];
+ }
+
+RESOURCE DECODER_INFO theDecoderInfo
+ {
+ decoder_name = "Decoder: Jp2 decoder V1.0";
+ image_format = "Format: Jp2/J2k";
+ image_dimensions = "Dimensions: %dx%d pixels";
+ image_depth = {"Depth: %dbpp b&w", "Depth: %dbpp colour"};
+ image_details = {"Details: Profile 1", "Details: CClass 1"};
+ }
Binary file imagingmodules/jp2kcodec/Data/JP2KCodec.SIS has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Data/JP2KCodec.pkg Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,29 @@
+;
+; Copyright (c) 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: PKG file for creating JP2KCodec stub sis package
+;
+; Languages
+&EN
+
+; Header
+#{"JP2KCodec"}, (0x101F862D), 1, 0, 0, TYPE=SA
+
+; Localised Vendor name
+%{"Nokia"}
+
+; Unique Vendor name
+:"Nokia"
+
+;Files
+""-"z:\sys\bin\JP2KCodec.dll"
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Group/JP2KCodec.mmp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,80 @@
+/*
+* Copyright (c) 2003-2006 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: Project specification file for JPEG2000 plugin.
+*
+*/
+
+
+// To get the OS_LAYER_SYSTEMINCLUDE-definition
+#include <platform_paths.hrh>
+
+TARGET JP2KCodec.dll
+
+CAPABILITY CAP_ECOM_PLUGIN
+
+TARGETTYPE PLUGIN
+
+// MAGIC Dll recognition UID to support ECom.
+UID 0x10009D8D 0x101F862D
+
+VENDORID VID_DEFAULT
+
+SOURCEPATH ../Src
+SOURCE JP2KCodec.cpp
+SOURCE JP2KConvert.cpp
+SOURCE JP2KProxy.cpp
+SOURCE JP2KFormat.cpp
+SOURCE JP2KImageInfo.cpp
+SOURCE JP2KStreamReader.cpp
+SOURCE JP2KTileInfo.cpp
+SOURCE JP2KMarker.cpp
+SOURCE JP2KComponentInfo.cpp
+SOURCE JP2KSubband.cpp
+SOURCE JP2KPacket.cpp
+SOURCE JP2KCodeBlock.cpp
+SOURCE JP2KUtils.cpp
+SOURCE JP2KEntropyDecoder.cpp
+SOURCE JP2KSynthesis.cpp
+SOURCE JP2KImageWriter.cpp
+SOURCE JP2KImageData.cpp
+
+SOURCEPATH ../Data
+START RESOURCE 101F862D.rss
+TARGET JP2KCodec.rsc
+END
+
+START RESOURCE 101F862D_extra.rss
+TARGETPATH Resource/ICL
+HEADER
+END
+
+USERINCLUDE ../Inc
+USERINCLUDE ../../inc // subsystem level inc dir
+USERINCLUDE ../../../inc // ADo level inc dir
+
+// Default system include paths for middleware layer modules.
+OS_LAYER_SYSTEMINCLUDE
+
+LIBRARY euser.lib
+LIBRARY fbscli.lib
+LIBRARY bafl.lib
+LIBRARY ImageConversion.lib
+
+LANG SC
+
+START WINS
+BASEADDRESS 0x4F650000
+END
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Group/bld.inf Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,32 @@
+/*
+* Copyright (c) 2003-2008 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: Build information file for JPEG2000 decoder plugin.
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_EXPORTS
+// SIS stub
+../Data/JP2KCodec.SIS /epoc32/data/z/system/install/JP2KCodec.sis
+../rom/JP2KCodec.iby CORE_OS_LAYER_IBY_EXPORT_PATH(JP2KCodec.iby)
+
+PRJ_MMPFILES
+../Group/JP2KCodec.mmp
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KCodeBlock.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,222 @@
+/*
+* Copyright (c) 2003, 2004 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: JP2KCodeBlock class used to collect the codeblock
+* related information such as compressed data and data length.
+*
+*/
+
+
+#ifndef __JP2KCODEBLOCK_H__
+#define __JP2KCODEBLOCK_H__
+
+// INCLUDES
+#include <e32base.h>
+
+// CONSTANTS
+
+// MACROS
+
+// DATA TYPES
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+class CJ2kPacket;
+
+// CLASS DECLARATION
+
+/**
+ * JP2KCodeBlock class used to collect the code block
+ * related information such as compressed data, data
+ * length, and etc.
+ *
+ * JP2KCodec.dll
+ * @since 2.6
+ */
+class CJ2kCodeBlock : public CBase
+ {
+ public: // Constructors and destructor
+
+ /**
+ * C++ default constructor.
+ */
+ CJ2kCodeBlock();
+
+ /**
+ * Destructor.
+ */
+ virtual ~CJ2kCodeBlock();
+
+ public: // New functions
+
+ /**
+ * Set the canvas of the code block
+ * @since 2.6
+ * @param aX: x position of the codeblock.
+ * @param aY: y position of the codeblock.
+ * @param aWidth: width of the codeblock.
+ * @param aHeight: height of the codeblock.
+ */
+ void SetCodeBlockCanvas( TInt32 aX, TInt32 aY, TInt32 aWidth, TInt32 aHeight );
+
+ /**
+ * Initialize the number of segment
+ * @since 2.6
+ * @param aLayer: number of layer.
+ */
+ void InitializeL( TUint16 aLayer );
+
+ /**
+ * Get the data buffer descriptor
+ * @since 2.6
+ * @return HBufC8*: pointer to the descriptor of the data buffer.
+ */
+ HBufC8* DataL();
+
+ /**
+ * Get the pointer to the data portion
+ * @since 2.6
+ * @return TUint8*: pointer to the data buffer.
+ */
+ const TUint8* Data() const;
+
+ /**
+ * Get the last pass
+ * @since 2.6
+ * @return TInt8: the last pass.
+ */
+ TInt8 LastPass() const;
+
+ /**
+ * Get the pass index
+ * @since 2.6
+ * @return TInt8: the pass index.
+ */
+ TUint8 PassIndex() const;
+
+ /**
+ * Get the number of empty bit planes
+ * @since 2.6
+ * @return TInt8: the empty bit planes.
+ */
+ TUint8 EmptyBitplanes() const;
+
+ /**
+ * Get the canvas of the codeblock
+ * @since 2.6
+ * @return TRect&: reference to the canvas of the codeblock.
+ */
+ const TRect& CodeBlockCanvas() const;
+
+ /**
+ * Get the data length
+ * @since 2.6
+ * @return TInt32: the data length.
+ */
+ TUint32 DataLength() const;
+
+ /**
+ * Get the data size at specific segment
+ * @since 2.6
+ * @param aIndex: the specific segment.
+ * @return TInt16: the data size at specific segment.
+ */
+ TUint16 CblkLength( TUint16 aIndex ) const;
+
+ /**
+ * Get the pass per segment at specific segment
+ * @since 2.6
+ * @param aIndex: the specific segment.
+ * @return TInt16: the pass per segment at specific segment.
+ */
+ TUint16 PassesPerSegment( TUint16 aIndex ) const;
+
+ /**
+ * Reset the pass index to 0
+ * @since 2.6
+ */
+ void ResetPassIndex();
+
+ /**
+ * Increment the pass index
+ * @since 2.6
+ */
+ void IncrementPassIndex();
+
+ /**
+ * Set to indicate that the codeblock has been decoded
+ * @since 2.6
+ */
+ void SetCodeBlockDecoded();
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private:
+
+ public: // Data
+
+ protected: // Data
+
+ private: // Data
+
+ // Last pass
+ TInt8 iLastPass;
+
+ // Pass index
+ TUint8 iPassIndex;
+
+ // Empty bit plane
+ TUint8 iEmptyBitplane;
+
+ // Bits length
+ TUint8 iLengthBits;
+
+ // Data length
+ TUint32 iDataLength;
+
+ // Data size of each segment
+ HBufC16 *iDataSize;
+
+ // Number of pass per segment
+ HBufC16 *iPassesPerSegment;
+
+ // Number of segment
+ HBufC16 *iNumSegment;
+
+ // Canvas of the code block
+ TRect iCodeBlockCanvas;
+
+ // Compressed image data
+ HBufC8 *iData;
+
+ // True if codeblock has been decoded
+ TUint8 iIsDecoded;
+
+ public: // Friend classes
+ friend class CJ2kPacket;
+
+ protected: // Friend classes
+
+ private: // Friend classes
+ };
+
+// For inliners.
+#include "JP2KCodeBlock.inl"
+
+#endif // __JP2KCODEBLOCK_H__
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KCodeBlock.inl Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,135 @@
+/*
+* Copyright (c) 2003, 2004 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: JP2KCodeBlock class used to collect the codeblock
+* related information such as compressed data and data length.
+*
+*/
+
+
+#ifndef __JP2KCODEBLOCK_INL__
+#define __JP2KCODEBLOCK_INL__
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CJ2kCodeBlock::LastPass
+// Get the last pass.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TInt8 CJ2kCodeBlock::LastPass() const
+ {
+ return iLastPass;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kCodeBlock::PassIndex
+// Get the pass index.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kCodeBlock::PassIndex() const
+ {
+ return iPassIndex;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kCodeBlock::EmptyBitplanes
+// Get the number of empty bit planes.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kCodeBlock::EmptyBitplanes() const
+ {
+ return iEmptyBitplane;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kCodeBlock::CodeBlockCanvas
+// Get the canvas of the codeblock.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline const TRect& CJ2kCodeBlock::CodeBlockCanvas() const
+ {
+ return iCodeBlockCanvas;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kCodeBlock::DataLength
+// Get the data length.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint32 CJ2kCodeBlock::DataLength() const
+ {
+ return iDataLength;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kCodeBlock::CblkLength
+// Get the data size at specific segment.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint16 CJ2kCodeBlock::CblkLength(TUint16 aIndex) const
+ {
+ return (*iDataSize)[aIndex];
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kCodeBlock::PassesPerSegment
+// Get the pass per segment at specific segment.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint16 CJ2kCodeBlock::PassesPerSegment(TUint16 aIndex) const
+ {
+ return (*iPassesPerSegment)[aIndex];
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kCodeBlock::ResetPassIndex
+// Reset the pass index to 0.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kCodeBlock::ResetPassIndex()
+ {
+ iPassIndex = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kCodeBlock::IncrementPassIndex
+// Increment the pass index.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kCodeBlock::IncrementPassIndex()
+ {
+ ++iPassIndex;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kCodeBlock::SetCodeBlockDecoded
+// Set to indicate that the codeblock has been decoded
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kCodeBlock::SetCodeBlockDecoded()
+ {
+ iIsDecoded = (TUint8)1;
+ }
+
+#endif // __JP2KCODEBLOCK_INL__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KCodec.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,427 @@
+/*
+* Copyright (c) 2003, 2004 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: CJp2kReadCodec class implements the ICL read codec interface.
+*
+*/
+
+
+#ifndef __JP2KCODEC_H__
+#define __JP2KCODEC_H__
+
+// INCLUDES
+#include <icl/imageprocessor.h>
+#include <icl/imagecodec.h>
+#include <icl/imagecodecdata.h>
+
+// CONSTANTS
+
+// Delimiting marker segments
+const TUint16 KSOC = 0xFF4F; // Start of codestream
+const TUint16 KSOT = 0xFF90; // Start of tile-part
+const TUint16 KSOD = 0xFF93; // Start of data
+const TUint16 KEOC = 0xFFD9; // End of codestream
+
+// Fixed information marker segments
+const TUint16 KSIZ = 0xFF51; // Image and tile size
+
+// Functional marker segments
+const TUint16 KCOD = 0xFF52; // Coding style default
+const TUint16 KCOC = 0xFF53; // Coding style component
+const TUint16 KRGN = 0xFF5E; // Region of interest
+const TUint16 KQCD = 0xFF5C; // Quantization default
+const TUint16 KQCC = 0xFF5D; // Quantization component
+const TUint16 KPOC = 0xFF5F; // Progression order default
+
+// Pointer marker segments
+const TUint16 KTLM = 0xFF55; // Tile-part lengths, main header
+const TUint16 KPLM = 0xFF57; // Packet length, main header
+const TUint16 KPLT = 0xFF58; // Packet length, tile-part header
+const TUint16 KPPM = 0xFF60; // Packed packet headers, main header
+const TUint16 KPPT = 0xFF61; // Packed packet headers, tile-part header
+
+// Informational marker segments
+const TUint16 KCME = 0xFF64; // Comment and extension
+const TUint16 KCRG = 0xFF63; // Component registration
+
+// Packet information
+const TUint16 KSOP = 0xFF91; // Start of packet
+const TUint16 KEPH = 0xFF92; // End of packet header
+const TUint16 KSOP_LEN = 0x04; // Length of the SOP
+
+// Extensions marker segments
+const TUint16 KEXTS = 0xFF30; // Start of extensions
+const TUint16 KEXTE = 0xFF3F; // End Of extensions
+
+const TUint16 KMarkerSize = 2; // Size of a marker - 2 bytes
+const TUint16 KMarkerLength = 2; // Size of a length - 2 bytes
+const TUint16 KMarkerMinLength = KMarkerSize + KMarkerLength;
+
+// MACROS
+
+// DATA TYPES
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+class TJ2kInfo;
+class CJ2kImageInfo;
+class TJ2kStreamReader;
+class CJ2kEntropyDecoder;
+class CJ2kImageWriter;
+class CJ2kSynthesis;
+class CJ2kTileInfo;
+
+// CLASS DECLARATION
+
+/**
+ * CJp2kReadCodec JPEG2000 image read codec class.
+ * Implement the ICL read codec interface.
+ *
+ * JP2KCodec.dll
+ * @since 2.6
+ */
+class CJp2kReadCodec : public CImageProcessorReadCodec //lint !e768 Will be referenced by framework.
+{
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor.
+ */
+ static CJp2kReadCodec* NewL( const TJ2kInfo& aJ2kInfo );
+
+ /**
+ * Destructor.
+ */
+ virtual ~CJp2kReadCodec();
+
+ public: // New functions
+
+ /**
+ * Decoding the current tile-part.
+ * @since 2.6
+ * @return TFrameState: frame state after decoding the current tile-part.
+ */
+ TFrameState DecodeTileL();
+
+ /**
+ * Is codec in the decoding state.
+ * @since 2.6
+ * @return TBool: false if codec in the parsing state.
+ */
+ TBool IsDecodeTile() const;
+
+ public: // Functions from base classes
+
+ /**
+ * From CImageReadCodec
+ * @since 2.6
+ * @param aFrameInfo: Frame information.
+ * @param aFrameData: Frame data.
+ */
+ void InitFrameHeader( TFrameInfo& aFrameInfo, CFrameImageData& aFrameData );
+
+ /**
+ * From CImageReadCodec
+ * @since 2.6
+ * @param aData: Data to be processed.
+ */
+ TFrameState ProcessFrameHeaderL( TBufPtr8& aData );
+
+ /**
+ * From CImageReadCodec
+ * @since 2.6
+ * @param aFrameInfo: Frame information.
+ * @param aFrameData: Frame data.
+ * @param aDisableErrorDiffusion: Use error diffusion or not.
+ * @param aDestination: Destination bitmap.
+ * @param aDestinationMask: Destination bitmap mask.
+ */
+ void InitFrameL( TFrameInfo& aFrameInfo, CFrameImageData& aFrameData,
+ TBool aDisableErrorDiffusion, CFbsBitmap& aDestination,
+ CFbsBitmap *aDestinationMask );
+
+ /**
+ * From CImageReadCodec
+ * @since 2.6
+ * @param aSrc: Source data.
+ */
+ TFrameState ProcessFrameL( TBufPtr8& aSrc );
+
+ /**
+ * From CImageReadCodec
+ * @since 2.6
+ * @param aPosition: New position in data.
+ * @param aLength: Number of bytes to read.
+ */
+ void GetNewDataPosition(TInt& aPosition, TInt& aLength);
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private:
+
+ /**
+ * C++ default constructor.
+ */
+ CJp2kReadCodec( const TJ2kInfo& aJ2kInfo );
+
+ /**
+ * By default Symbian 2nd phase constructor is private.
+ */
+ void ConstructL();
+
+ /**
+ * Verify and process Start of Codestream (SOC marker)
+ * @since 2.6
+ */
+ TFrameState ReadSOCL();
+
+ /**
+ * Verify and process Image and Tile Size (SIZ marker)
+ * @since 2.6
+ */
+ TFrameState ReadSIZL();
+
+ /**
+ * Verify and process Coding Style Default (COD marker)
+ * @since 2.6
+ * @param aMain: true for Main Header, false for Tile Part Header.
+ */
+ TFrameState ReadCODL( TBool aMain = ETrue );
+
+ /**
+ * Verify and process Coding Style Component (COC marker)
+ * @since 2.6
+ * @param aMain: true for Main Header, false for Tile Part Header.
+ */
+ TFrameState ReadCOCL( TBool aMain = ETrue );
+
+ /**
+ * Verify and process Quantization Default (QCD marker)
+ * @since 2.6
+ * @param aMain: true for Main Header, false for Tile Part Header.
+ */
+ TFrameState ReadQCDL( TBool aMain = ETrue );
+
+ /**
+ * Verify and process Quantization Component (QCC marker)
+ * @since 2.6
+ * @param aMain: true for Main Header, false for Tile Part Header.
+ */
+ TFrameState ReadQCCL( TBool aMain = ETrue );
+
+ /**
+ * Verify and process Region of Interest (RGN marker)
+ * @since 2.6
+ * @param aMain: true for Main Header, false for Tile Part Header.
+ */
+ TFrameState ReadRGNL( TBool aMain = ETrue );
+
+ /**
+ * Verify and process Progression Order Change (POC marker)
+ * @since 2.6
+ * @param aMain: true for Main Header, false for Tile Part Header.
+ */
+ TFrameState ReadPOCL( TBool aMain = ETrue );
+
+ /**
+ * Verify and process Packed Packet Headers, Main Header (PPM marker)
+ * @since 2.6
+ */
+ TFrameState ReadPPML();
+
+ /**
+ * Verify and process Tile Part Lengths, Main Header (TLM marker)
+ * @since 2.6
+ */
+ TFrameState ReadTLML();
+
+ /**
+ * Verify and process Packet Length, Main Header (PLM marker)
+ * @since 2.6
+ */
+ TFrameState ReadPLML();
+
+ /**
+ * Verify and process Component Registration, Main Header (CRG marker)
+ * @since 2.6
+ */
+ TFrameState ReadCRGL();
+
+ /**
+ * Verify and process Comment (COM marker)
+ * @since 2.6
+ * @param aMain: true for Main Header, false for Tile Part Header.
+ */
+ TFrameState ReadCOML( TBool aMain = ETrue );
+
+ /**
+ * Verify and process Start of Tile Part (SOT marker)
+ * @since 2.6
+ */
+ TFrameState ReadSOTL();
+
+ /**
+ * Verify and process Start of Data (SOD marker)
+ * @since 2.6
+ */
+ TFrameState ReadSODL();
+
+ /**
+ * Verify and process BitStream Data
+ * @since 2.6
+ */
+ TFrameState ReadBitStreamL();
+
+ /**
+ * Verify and process Packed Packet Headers, Tile Part Header (PPT marker)
+ * @since 2.6
+ */
+ TFrameState ReadPPTL();
+
+ /**
+ * Verify and process Packet Length, Tile Part Header (PLT marker)
+ * @since 2.6
+ */
+ TFrameState ReadPLTL();
+
+ /**
+ * Ignore the content and advance the iterator to the next marker
+ * @since 2.6
+ */
+ TFrameState ReadSkipTileL();
+
+ /**
+ * Update the current state according to the marker type
+ * @since 2.6
+ */
+ TFrameState UpdateStateFromMarkerL();
+
+ /**
+ * Decode the tile and delete it after decoding
+ * @since 2.6
+ * @param aTile: a reference to the tile to decode.
+ */
+ void DecodeAndDeleteTileL( CJ2kTileInfo& aTile );
+
+ /**
+ * Convert metadata from file format to TImageDataBlock derived objects
+ * @since 2.6
+ */
+ void ConvertImageDataL();
+
+ public: // Data
+
+ // State machine represent the state when parsing of the JP2 codestream.
+ enum TFrameHeaderState
+ {
+ EStateInSOC,
+ EStateInSIZ,
+ EStateInCOD,
+ EStateInCOC,
+ EStateInQCD,
+ EStateInQCC,
+ EStateInRGN,
+ EStateInPOC,
+ EStateInPPM,
+ EStateInTLM,
+ EStateInPLM,
+ EStateInCRG,
+ EStateInCOM,
+ EStateInSOT,
+ EStateInPPT,
+ EStateInPLT,
+ EStateInSOD,
+ EStateInBITSTREAM,
+ EStateInEOC,
+ EStateInSkipTile,
+ EStateInUnknown
+ };
+
+ protected: // Data
+
+ private: // Data
+
+ // Decoding style.
+ enum TDecoderStyle
+ {
+ ETileBasedDecoder, // Tile-based decoding
+ EBlockBasedDecoder, // Block-based wavelet
+ EUnknownDecoder // Use some logic to choose the style to use
+ };
+
+ // JP2 file format information
+ const TJ2kInfo& iJ2kInfo;
+
+ // Frame information
+ TFrameInfo *iFrame;
+
+ // Frame data, owned by framework
+ CFrameImageData *iFrameData;
+
+ // Index of last tile processed
+ TUint16 iLastTileIndex;
+
+ // Current state
+ TFrameHeaderState iFHState;
+
+ // Indicate new tile to be processed
+ TUint8 iUseNewTile;
+
+ // Indicate next tile to be processed
+ TUint8 iUseNextTile;
+
+ // Tiles are in sequential order
+ TUint8 iSequential;
+
+ // Reference to stream reader
+ TJ2kStreamReader iReader;
+
+ // .jp2 image information
+ CJ2kImageInfo *iImageInfo;
+
+ // To handle the underflow PPM
+ TPPMMarker *iPreviousPPM;
+
+ // To handle the underflow COM
+ TCOMMarker *iPreviousCOM;
+
+ // The entropy decoder
+ CJ2kEntropyDecoder *iEntropy;
+
+ // The image write
+ CJ2kImageWriter *iImageWriter;
+
+ // The synthesis
+ CJ2kSynthesis *iSynthesis;
+
+ // The decoding mechanism used
+ TDecoderStyle iStyleUsed;
+
+ // Indicate a progression bar is needed for single tile image
+ TBool iProgressBar;
+
+ // Indicate the codec state
+ TBool iDecodeTile;
+
+ public: // Friend classes
+
+ protected: // Friend classes
+
+ private: // Friend classes
+ };
+
+#endif // __JP2KCODEC_H__
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KComponentInfo.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,312 @@
+/*
+* Copyright (c) 2003, 2004 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: CJ2kComponentInfo class used to collect component related
+* information such as precincts size at each resolution level and
+* list of subbands
+*
+*/
+
+
+#ifndef __JP2KCOMPONENTINFO_H__
+#define __JP2KCOMPONENTINFO_H__
+
+// INCLUDES
+#include <e32base.h>
+
+// CONSTANTS
+
+// MACROS
+
+// DATA TYPES
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+class CJ2kTileInfo;
+class CJ2kSubband;
+
+// CLASS DECLARATION
+
+/**
+ * JP2KComponentInfo class used to collect component related
+ * information such as precincts size at each resolution level,
+ * list of subbands, and etc. It contains the data to control
+ * where to resume the parsing of the bitstream.
+ *
+ * JP2KCodec.dll
+ * @since 2.6
+ */
+class CJ2kComponentInfo : public CBase
+{
+public:
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor.
+ */
+ static CJ2kComponentInfo* NewLC( CJ2kTileInfo& aTile, TUint16 aIndex );
+
+ /**
+ * Destructor.
+ */
+ virtual ~CJ2kComponentInfo();
+
+ public: // New functions
+
+ /**
+ * At each component, parse the bitstream with LRCP progression order
+ * @since 2.6
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @return TUint8: true if incomplete, false if completed.
+ */
+ TUint8 LRCPProgressionL( CJ2kTileInfo& aTile );
+
+ /**
+ * At each component, parse the bitstream with RPCL progression order
+ * @since 2.6
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @return TUint8: true if incomplete, false if completed.
+ */
+ TUint8 RPCLProgressionL( CJ2kTileInfo& aTile );
+
+ /**
+ * At each component, parse the bitstream with CPRL progression order
+ * @since 2.6
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @return TUint8: true if incomplete, false if completed.
+ */
+ TUint8 CPRLProgressionL( CJ2kTileInfo& aTile );
+
+ /**
+ * Get the subband at specific resolution level
+ * @since 2.6
+ * @param aResLevel: resolution level.
+ * @return CJ2kSubband*: pointer to CJ2kSubband object.
+ */
+ const CJ2kSubband* SubbandAt( TUint8 aResLevel ) const;
+
+ /**
+ * Get the number of packets at specific resolution level
+ * @since 2.6
+ * @param aResLevel: resolution level.
+ * @return TUint32: number of packets.
+ */
+ TUint32 NumOfPackets( TUint8 aResLevel ) const;
+
+ /**
+ * Get the quantization exponent value for transformation
+ * @since 2.6
+ * @param aIndex: subband index.
+ * @return TUint8: exponent value.
+ */
+ TUint8 Exponent( TUint16 aIndex ) const;
+
+ /**
+ * Get the quantization mantissa value for transformation
+ * @since 2.6
+ * @param aIndex: subband index.
+ * @return TUint16: mantissa value.
+ */
+ TUint16 Mantissa( TUint16 aIndex ) const;
+
+ /**
+ * Get the magnitude bits
+ * @since 2.6
+ * @param aIndex: subband index.
+ * @return TUint8: magnitude bits.
+ */
+ TUint8 MagnitudeBits( TUint16 aIndex ) const;
+
+ /**
+ * Reset the last packet processed for each subband
+ * @since 2.6
+ */
+ void ResetLastPacketProcessed();
+
+ /**
+ * Get the resolution level
+ * @since 2.6
+ * @return TUint8: resolution level.
+ */
+ TUint8 Levels() const;
+
+ /**
+ * Get the codeblock style
+ * @since 2.6
+ * @return TUint8: codeblock style.
+ */
+ TUint8 CodeBlockStyle() const;
+
+ /**
+ * Get the number of guard
+ * @since 2.6
+ * @return TUint8: number of guard.
+ */
+ TUint8 NumGuard() const;
+
+ /**
+ * Get the quantization style
+ * @since 2.6
+ * @return TUint8: quantization style.
+ */
+ TUint8 QuantizationStyle() const;
+
+ /**
+ * Get the region of interest shifting
+ * @since 2.6
+ * @return TUint8: region of interest shifting.
+ */
+ TUint8 RoiShift() const;
+
+ /**
+ * Get the codeblock size
+ * @since 2.6
+ * @return TSize&: a reference to the codeblock size.
+ */
+ const TSize& CodeBlockSize() const;
+
+ /**
+ * Get the canvas of the component
+ * @since 2.6
+ * @return TRect&: a reference to the component's canvas.
+ */
+ const TRect& ComponentCanvas() const;
+
+ /**
+ * Get the precinct size at specific resolution level
+ * @since 2.6
+ * @param aResLevel: resolution level.
+ * @return TSize&: a reference to the precinct size.
+ */
+ const TSize& PrecinctSizeAt( TUint8 aResLevel ) const;
+
+ /**
+ * Get the minimum grid size
+ * @since 2.6
+ * @return TSize&: a reference to the minimum grid.
+ */
+ const TSize& MinGrid() const;
+
+ /**
+ * Is coding style shows SOP marker may exists in codestream
+ * @since 2.6
+ * @return TUInt8: true if SOP marker used.
+ */
+ TUint8 IsSOPMarkerUsed() const;
+
+ /**
+ * Is coding style shows EPH marker may exists in codestream
+ * @since 2.6
+ * @return TUint8: true if EPH marker used.
+ */
+ TUint8 IsEPHMarkerUsed() const;
+
+ /**
+ * Is codeblock style shows AC bypass
+ * @since 2.6
+ * @return TUint8: true if AC bypass.
+ */
+ TUint8 IsACByPass() const;
+
+ /**
+ * Is codeblock style shows termination
+ * @since 2.6
+ * @return TUint8: true if termination.
+ */
+ TUint8 IsTermination() const;
+
+ /**
+ * Is transformation reversible
+ * @since 2.6
+ * @return TUint8: true if reversible.
+ */
+ TUint8 IsReversible() const;
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private:
+
+ /**
+ * C++ default constructor.
+ */
+ CJ2kComponentInfo();
+
+ /**
+ * By default Symbian 2nd phase constructor is private.
+ */
+ void ConstructL( CJ2kTileInfo& aTile, TUint16 aIndex );
+
+ public: // Data
+
+ protected: // Data
+
+ private: // Data
+
+ // Canvas of the component
+ TRect iComponentCanvas;
+
+ // Root of the subbands
+ CJ2kSubband *iRootSubband;
+
+ // Precincts at each resolution level
+ RArray<TSize> iPrecinctSizeList;
+
+ // List of grid
+ RArray<TSize> iGridList;
+
+ // Minimum grid size
+ TSize iMinGrid;
+
+ // Size of codeblock
+ TSize iCodeBlockSiz;
+
+ // Number of resolution level
+ TUint8 iNumOfLevels;
+
+ // Codeblock style
+ TUint8 iCodeBlockStyle;
+
+ // DWT transformation
+ TUint8 iWaveletTransformation;
+
+ // Coding style
+ TUint8 iCod;
+
+ // Quantization
+ TUint8 iQc;
+
+ // Region of interest
+ TUint8 iRoiShift;
+
+ // Quantization values for transformation
+ HBufC8 *iExponentList;
+
+ // Quantization values for transformation
+ HBufC16 *iMantissaList;
+
+ public: // Friend classes
+
+ protected: // Friend classes
+
+ private: // Friend classes
+};
+
+// For inliners.
+#include "JP2KComponentInfo.inl"
+
+#endif // __JP2KCOMPONENTINFO_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KComponentInfo.inl Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,180 @@
+/*
+* Copyright (c) 2003, 2004 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: J2kComponentInfo class used to collect component related
+* information such as precincts size at each resolution level and
+* list of subbands.
+*
+*/
+
+
+#ifndef __JP2KCOMPONENTINFO_INL__
+#define __JP2KCOMPONENTINFO_INL__
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::Levels
+// Get the resolution level
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kComponentInfo::Levels() const
+ {
+ return iNumOfLevels;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::CodeBlockStyle
+// Get the codeblock style
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kComponentInfo::CodeBlockStyle() const
+ {
+ return iCodeBlockStyle;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::NumGuard
+// Get the number of guard
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kComponentInfo::NumGuard() const
+ {
+ return (TUint8)( ( iQc & 0xe0 ) >> 5 );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::QuantizationStyle
+// Get the quantization style
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kComponentInfo::QuantizationStyle() const
+ {
+ return (TUint8)( iQc & 0x1f );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::RoiShift
+// Get the region of interest shifting
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kComponentInfo::RoiShift() const
+ {
+ return iRoiShift;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::CodeBlockSize
+// Get the codeblock size
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline const TSize& CJ2kComponentInfo::CodeBlockSize() const
+ {
+ return iCodeBlockSiz;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::ComponentCanvas
+// Get the canvas of the component
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline const TRect& CJ2kComponentInfo::ComponentCanvas() const
+ {
+ return iComponentCanvas;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::PrecinctSizeAt
+// Get the precinct size at specific resolution level
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline const TSize& CJ2kComponentInfo::PrecinctSizeAt( TUint8 aResLevel ) const
+ {
+ return iPrecinctSizeList[aResLevel];
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::MinGrid
+// Get the minimum grid size
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline const TSize& CJ2kComponentInfo::MinGrid() const
+ {
+ return iMinGrid;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::IsSOPMarkerUsed
+// Is coding style shows SOP marker may exists in codestream
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kComponentInfo::IsSOPMarkerUsed() const
+ {
+ return (TUint8)( iCod & 0x02 );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::IsEPHMarkerUsed
+// Is coding style shows EPH marker may exists in codestream
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kComponentInfo::IsEPHMarkerUsed() const
+ {
+ return (TUint8)( iCod & 0x04 );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::IsACByPass
+// Is codeblock style shows AC bypass
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kComponentInfo::IsACByPass() const
+ {
+ return (TUint8)( iCodeBlockStyle & 0x01 );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::IsTermination
+// Is codeblock style shows termination
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kComponentInfo::IsTermination() const
+ {
+ return (TUint8)( iCodeBlockStyle & 0x04 );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::IsReversible
+// Is transformation reversible
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kComponentInfo::IsReversible() const
+ {
+ return (TUint8)( iWaveletTransformation & 0x01 );
+ }
+
+#endif // __JP2KCOMPONENTINFO_INL__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KConvert.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,312 @@
+/*
+* Copyright (c) 2003, 2004 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: JPEG2000 image encoder/decoder plugin class
+*
+*/
+
+
+#ifndef __JP2KCONVERT_H__
+#define __JP2KCONVERT_H__
+
+// INCLUDES
+#include <icl/imageplugin.h>
+#include <icl/imagedata.h>
+
+// CONSTANTS
+
+// MACROS
+
+// DATA TYPES
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+class TJ2kInfo;
+class CJp2kReadCodec;
+
+// CLASS DECLARATION
+
+/**
+ * CJp2kDecoder JPEG2000 image decoder plugin class.
+ * Implement the ICL decoder plugin interface.
+ *
+ * JP2KCodec.dll
+ * @since 2.6
+ */
+class CJp2kDecoder : public CImageDecoderPlugin
+{
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor.
+ */
+ static CJp2kDecoder* NewL();
+
+ /**
+ * Destructor.
+ */
+ virtual ~CJp2kDecoder();
+
+ public: // New functions
+
+ public: // Functions from base classes
+
+ /**
+ * From CImageDecoderPlugin
+ * @since 2.6
+ * @param aFrameNumber: Number of frame whose type is needed.
+ * @param aImageType: Return image type UID.
+ * @param aImageSubType: Returned image sub type UID.
+ */
+ void ImageType( TInt aFrameNumber, TUid& aImageType, TUid& aImageSubType ) const;
+
+ /**
+ * From CImageDecoderPlugin
+ * @since 2.6
+ */
+ TInt NumberOfImageComments() const;
+
+ /**
+ * From CImageDecoderPlugin
+ * @since 2.6
+ * @param aCommentNumber: Number of comment whose comment is needed.
+ */
+ HBufC* ImageCommentL( TInt aCommentNumber ) const;
+
+ /**
+ * From CImageDecoderPlugin
+ * @since 2.6
+ * @param aFrameNumber: Number of frame whose comment is needed.
+ */
+ TInt NumberOfFrameComments( TInt aFrameNumber ) const;
+
+ /**
+ * From CImageDecoderPlugin
+ * @since 2.6
+ * @param aFrameNumber: Number of frame whose comment is needed.
+ * @param aCommentNumber: Number of comment whose comment is needed.
+ */
+ HBufC* FrameCommentL( TInt aFrameNumber, TInt aCommentNumber ) const;
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ /**
+ * From CImageDecoderPlugin
+ */
+ CFrameInfoStrings* FrameInfoStringsL( RFs& aFs, TInt aFrameNumber );
+
+ /**
+ * From CImageDecoderPlugin
+ */
+ TInt FrameHeaderBlockSize( TInt aFrameNumber ) const;
+
+ /**
+ * From CImageDecoderPlugin
+ */
+ TInt FrameBlockSize( TInt aFrameNumber ) const;
+
+ /**
+ * From CImageDecoderPlugin
+ */
+ void DoConvert();
+
+ private:
+
+ /**
+ * C++ default constructor.
+ */
+ CJp2kDecoder();
+
+ /**
+ * Main state machine
+ * Verify and start parsing the JP2 file format
+ * or JP2 codestream.
+ * @since 2.6
+ */
+ void ReadFormatL();
+
+ /**
+ * Verify and process JP2 Signature box
+ * @since 2.6
+ */
+ void ReadSignatureBoxL();
+ /**
+ * Verify and process JP2 File Type box
+ * @since 2.6
+ */
+ void ReadFileTypeBoxL();
+
+ /**
+ * Verify and process JP2 Header box (superbox)
+ * @since 2.6
+ */
+ void ReadJp2HeaderBoxL();
+
+ /**
+ * Verify and process Image Header box (in JP2 Header box)
+ * @since 2.6
+ */
+ void ReadImageHeaderBoxL();
+
+ /**
+ * Verify and process Colour Specification box (in JP2 Header box)
+ * @since 2.6
+ * @param aBoxLength: the length of the Colour Specification box
+ */
+ void ReadColorSpecBoxL( const TUint32 aBoxLength );
+
+ /**
+ * Verify and process Bits Per Component box (in JP2 Header box)
+ * @since 2.6
+ * @param aBoxLength: the length of the Bits Per Component box
+ */
+ void ReadBitsPerCompBoxL( TUint32 aBoxLength );
+
+ /**
+ * Verify and process Resolution box (in JP2 Header box, which itself is superbox)
+ * @since 2.6
+ * @param aPtrLimit: the boundary of the data to be read
+ * @param aBoxLength: the length of the Resolution box
+ */
+ void ReadResolutionBoxL( const TUint8 *aPtrLimit, TUint32 aBoxLength );
+
+ /**
+ * Verify and process Default Display Resolution box (in Resolution box)
+ * @since 2.6
+ */
+ void ReadDisplayResBoxL();
+
+ /**
+ * Verify and process Capture Resolution box (in Resolution box)
+ * @since 2.6
+ * @param aBoxLength: the length of the Capture Resolution box
+ */
+ void ReadCaptureResBoxL( TUint32 aBoxLength );
+
+ /**
+ * Verify and process Palette box (in JP2 Header box)
+ * @since 2.6
+ */
+ void ReadPaletteBoxL();
+
+ /**
+ * Verify and process Component Mapping box (in JP2 Header box)
+ * @since 2.6
+ * @param aBoxLength: the length of the Component Mapping box
+ */
+ void ReadComponentMapBoxL( TUint32 aBoxLength );
+
+ /**
+ * Verify and process Channel Definition box (in JP2 Header box)
+ * @since 2.6
+ * @param aBoxLength: the length of the Channel Definition box
+ */
+ void ReadChannelDefBoxL( TUint32 aBoxLength );
+
+ /**
+ * Verify and process IPR box
+ * @since 2.6
+ */
+ void ReadIPRBoxL();
+
+ /**
+ * Verify and process XML box
+ * @since 2.6
+ */
+ void ReadXMLBoxL();
+
+ /**
+ * Verify and process UUID box
+ * @since 2.6
+ */
+ void ReadUUIDBoxL();
+
+ /**
+ * Verify and process UUID Info box (superbox)
+ * @since 2.6
+ */
+ void ReadUUIDInfoBoxL();
+
+ /**
+ * Ignore the content and advance the iterator to the next box
+ * @since 2.6
+ */
+ void IgnoreBoxL();
+
+ /**
+ * Update the current state according to the box type
+ * @since 2.6
+ */
+ void UpdateStateFromBoxTypeL();
+
+ /**
+ * Read frame headers and instantiate decoder for application.
+ * @since 2.6
+ */
+ void ScanDataL();
+
+ public: // Data
+
+ // State machine represent the state when parsing the JP2 file format.
+ enum TDecoderState
+ {
+ EStateInUnknown,
+ EStateInSignatureBox,
+ EStateInFileTypeBox,
+ EStateInJP2SuperBox,
+ EStateInIPRBox,
+ EStateInXMLBox,
+ EStateInUUIDBox,
+ EStateInUUIDInfoBox,
+ EStateInCodestreamBox
+ };
+
+ protected: // Data
+
+ private: // Data
+
+ // JP2 file format information
+ TJ2kInfo iJ2kInfo;
+
+ // Descriptor of the buffer
+ TPtrC8 iBufferDes;
+
+ // Length of box read
+ TUint32 iBoxLength;
+
+ // Type of box read
+ TUint32 iBoxType;
+
+ // Position of last ReadDataL() used
+ TUint32 iLastRead;
+
+ // Enter the method from ICL framework
+ TBool iCallFromFramework;
+
+ // Pointer into the data represented by iBufferDes
+ const TUint8 *iPtr;
+
+ // Current state of the parsing of file or data
+ TDecoderState iState;
+
+ public: // Friend classes
+
+ protected: // Friend classes
+
+ private: // Friend classes
+};
+
+#endif // __JP2KCONVERT_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KEntropyDecoder.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,701 @@
+/*
+* Copyright (c) 2003, 2004 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: CJ2kEntropyDecoder class used to perform entropy decoding
+* on the codebloc.
+*
+*/
+
+
+#ifndef __JP2KENTROPYDECODER_H__
+#define __JP2KENTROPYDECODER_H__
+
+// INCLUDES
+#include <e32base.h>
+#include "JP2KUtils.h"
+
+// CONSTANTS
+const TUint8 KSignShift = (TUint8)( KImplementationPrecision - 1 );
+
+// Flags for positions of the contexts of the state of a pixel
+const TUint8 KPositionSignificant = 14;
+const TUint8 KPositionVisited = 13;
+const TUint8 KPositionHorNeg = 12;
+const TUint8 KPositionHorPos = 11;
+const TUint8 KPositionVerNeg = 10;
+const TUint8 KPositionVerPos = 9;
+const TUint8 KPositionMR = 8;
+const TUint8 KPositionLeft = 7;
+const TUint8 KPositionRight = 6;
+const TUint8 KPositionUp = 5;
+const TUint8 KPositionDown = 4;
+const TUint8 KPositionUpperLeft = 3;
+const TUint8 KPositionUpperRight = 2;
+const TUint8 KPositionLowerLeft = 1;
+const TUint8 KPositionLowerRight = 0;
+
+// Flags for the values of the contexts of the state of a pixel
+const TInt16 KStateSignificant = (TInt16)( 1 << KPositionSignificant );
+const TInt16 KStateVisited = (TInt16)( 1 << KPositionVisited );
+const TInt16 KStateHorNegative = (TInt16)( 1 << KPositionHorNeg );
+const TInt16 KStateHorPositive = (TInt16)( 1 << KPositionHorPos );
+const TInt16 KStateVerNegative = (TInt16)( 1 << KPositionVerNeg );
+const TInt16 KStateVerPositive = (TInt16)( 1 << KPositionVerPos );
+const TInt16 KStatePreviousMR = (TInt16)( 1 << KPositionMR );
+const TInt16 KStateLeft = (TInt16)( 1 << KPositionLeft );
+const TInt16 KStateRight = (TInt16)( 1 << KPositionRight );
+const TInt16 KStateUp = (TInt16)( 1 << KPositionUp );
+const TInt16 KStateDown = (TInt16)( 1 << KPositionDown );
+const TInt16 KStateUpperLeft = (TInt16)( 1 << KPositionUpperLeft );
+const TInt16 KStateUpperRight = (TInt16)( 1 << KPositionUpperRight );
+const TInt16 KStateLowerLeft = (TInt16)( 1 << KPositionLowerLeft );
+const TInt16 KStateLowerRight = (TInt16)( 1 << KPositionLowerRight );
+
+const TInt16 KZcMask = (TInt16)( ( 1 << 8 ) - 1 ); // First eight bits of states
+const TUint8 KPredictionBit = 6;
+const TUint8 KScShift = 9;
+const TUint8 KScLutMask = (TUint8)( ( 1 << 4 ) - 1 ); // First four bits of states
+const TUint8 KZcLutBits = 8;
+const TUint8 KLutSize = 16;
+const TUint8 KUniformContext = 0;
+const TUint8 KRlcContext = 1;
+const TUint8 KSegmentationMarker = 10; // Segmentation markers with one int
+const TUint8 KErrorResilienceTermination = 0x55; // Error resilience prediction termination.
+const TUint8 KStripeHeight = 4;
+
+// MQ related parameters
+const TUint8 KNumberContexts = 19;
+const TUint8 KNumberOriginalMQEntries = 47;
+
+// Coding pass related parameters
+const TUint8 KFirstLazyPassIndex = 9;
+const TUint8 KFirstBypassTermIndex = 10; // Pass which is terminated first if AC bypass and no termination
+
+// MACROS
+
+// DATA TYPES
+
+// Entropy coding parameters: flags for arithmetic bypass, context
+// resetting, termination, vertical stripes, prediction termination
+// and segment symbols.
+enum TEntropyErrorState
+ {
+ ENoError = 0,
+ EEntropyCodingError,
+ };
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+class J2KMQCoder;
+class CJ2kEntropyDecoder;
+class CJ2kImageInfo;
+class CJ2kCodeBlock;
+class CJ2kSynthesis;
+
+// CLASS DECLARATION
+
+/**
+ * J2KEntropyStream class is used to handle
+ * the buffer of encoded bytes as well as
+ * reading bits and bytes from it.
+ *
+ * JP2KCodec.dll
+ * @since 2.6
+ */
+class J2KEntropyStream
+{
+
+ public: // Constructors and destructor
+
+ public: // New functions
+
+ /**
+ * Read a byte from the input stream
+ * @since 2.6
+ * @return TUint8: a byte from the input stream.
+ */
+ TUint8 ReadByteFromStream();
+
+ /**
+ * Read a bit from the input stream
+ * @since 2.6
+ * @return TUint8: a bit from the input stream.
+ */
+ TUint8 ReadBitFromStream();
+
+ /**
+ * Check a prediction termination for raw coding
+ * @since 2.6
+ * @return TEntropyErrorState: ENoError if success.
+ */
+ TEntropyErrorState CheckPrediction();
+
+ /**
+ * Reset the input stream
+ * @since 2.6
+ */
+ void ResetInputStream();
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private:
+
+ public: // Data
+
+ protected: // Data
+
+ private: // Data
+
+ // The size of the buffer
+ TInt32 iNumBytes;
+
+ // Position of the next byte in the buffer
+ TInt32 iPosition;
+
+ // Buffer for bytes
+ TUint8* iBuffer;
+
+ // Buffer for bit-output
+ TUint8 iTinyBuffer;
+
+ // Flag for delaying the input of 0xFF byte
+ TUint8 iDelayedFF;
+
+ // Position of the next bit in the the tiny_buffer
+ TInt8 iTinyBufferPos;
+
+ public: // Friend classes
+
+ friend class J2KMQCoder;
+ friend class CJ2kEntropyDecoder;
+
+ protected: // Friend classes
+
+ private: // Friend classes
+};
+
+/**
+ * J2KEntropyStates class is used to handle
+ * the states and state transition information
+ * for the MQ entropy decoding.
+ *
+ * JP2KCodec.dll
+ * @since 2.6
+ */
+class J2KEntropyStates : public CBase
+ {
+ public: // Constructors and destructor
+
+ public: // New functions
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private:
+
+ public: // Data
+
+ protected: // Data
+
+ private: // Data
+
+ // Pointer to the next mps state
+ J2KEntropyStates* iNextMPS;
+
+ // Pointer to the next lps state
+ J2KEntropyStates* iNextLPS;
+
+ // Current estimate for lps symbol probability
+ TUint32 iQe;
+
+ // Flag for switching the mps (0->1 or 1->0)
+ TInt32 iSwitchFlag;
+
+ public: // Friend classes
+ friend class J2KMQCoder;
+ protected: // Friend classes
+
+ private: // Friend classes
+
+ };
+
+/**
+ * J2KEntropyContexts class is used to handle
+ * the context information for the MQ entropy
+ * decoding.
+ *
+ * JP2KCodec.dll
+ * @since 2.6
+ */
+class J2KEntropyContexts : public CBase
+ {
+ public: // Constructors and destructor
+
+ public: // New functions
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private:
+
+ public: // Data
+
+ protected: // Data
+
+ private: // Data
+
+ // Entropy state.
+ J2KEntropyStates* iState;
+
+ // Most probable symbol
+ TInt32 iMPS;
+
+ public: // Friend classes
+ friend class J2KMQCoder;
+ protected: // Friend classes
+
+ private: // Friend classes
+
+ };
+
+/**
+ * J2KMQCoder class is used to perform
+ * the actual MQ entropy decoding.
+ *
+ * JP2KCodec.dll
+ * @since 2.6
+ */
+class J2KMQCoder : public CBase
+ {
+ public: // Constructors and destructor
+
+ /**
+ * Destructor.
+ */
+ virtual ~J2KMQCoder();
+
+ public: // New functions
+
+ /**
+ * Read a byte from the input stream
+ * @since 2.6
+ */
+ void MqByteIn();
+
+ /**
+ * Decode the symbol
+ * @since 2.6
+ * @param aContextIndex: the context index.
+ * @return TUint8: a decision.
+ */
+ TUint8 MqDecodeSymbol( TInt32 aContextIndex );
+
+ /**
+ * Initialize the MQCoder
+ * @since 2.6
+ */
+ void MqInitDecoder();
+
+ /**
+ * Check the prediction termination
+ * @since 2.6
+ * @return TEntropyErrorState: ENoError if success.
+ */
+ TEntropyErrorState MqCheckPrediction();
+
+ /**
+ * Reset the MQCoder context list to the original state
+ * @since 2.6
+ */
+ void ResetMqContexts();
+
+ /**
+ * Initialze MQCoder and reset the context
+ * @since 2.6
+ * @param aSegmentLength: the segment length.
+ */
+ void ResetMQDecoder( TInt32 aSegmentLength );
+
+ /**
+ * Initialize MQCoder original states table
+ * @since 2.6
+ */
+ void InitializeOrigMqTable();
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private:
+
+ /**
+ * Renormalize
+ * @since 2.6
+ */
+ void ReNormalize();
+
+ /**
+ * MPS exchange
+ * @since 2.6
+ * @param aD: a reference to TInt32.
+ */
+ void MpsExchange( TInt32& aD );
+ /**
+ * LPS exchange
+ * @since 2.6
+ * @param aD: a reference to TInt32.
+ */
+ void LpsExchange( TInt32& aD );
+
+ public: // Data
+
+ protected: // Data
+
+ private: // Data
+
+ // Original states table
+ RPointerArray<J2KEntropyStates> iOriginalStates;
+
+ // An array of contexts
+ RPointerArray<J2KEntropyContexts> iContextList;
+
+ // Context corresponding to the current context index
+ J2KEntropyContexts* iCurrentContext;
+
+ // State of the current context
+ J2KEntropyStates* iCurrentState;
+
+ // Input stream
+ J2KEntropyStream iInputStream;
+
+ // The C register, i.e. the code register
+ TUint32 iC;
+
+ // The A register, i.e. the interval register
+ TUint32 iA;
+
+ // The counter
+ TUint32 iCT;
+
+ // Buffer for the output byte
+ TUint8 iB;
+
+ // Current marker
+ TUint8 iMarker;
+
+ public: // Friend classes
+ friend class CJ2kEntropyDecoder;
+
+ protected: // Friend classes
+
+ private: // Friend classes
+ };
+
+/**
+ * CJ2kEntropyDecoder class is used to perform
+ * the initializations and coding passes of
+ * the entropy decoding process.
+ *
+ * JP2KCodec.dll
+ * @since 2.6
+ */
+class CJ2kEntropyDecoder : public CBase
+ {
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor.
+ */
+ static CJ2kEntropyDecoder* NewL( CJ2kImageInfo& aImageInfo );
+
+ /**
+ * Destructor.
+ */
+ virtual ~CJ2kEntropyDecoder();
+
+ public: // New functions
+
+ /**
+ * Set the size of internal buffer and other control data
+ * @since 2.6
+ * @param aSize: the size of the internal buffer.
+ */
+ void SetNewSizeL( const TSize& aSize );
+
+ /**
+ * Set the current pointer to point to the right LUT
+ * depending on the current subband
+ * @since 2.6
+ * @param aBandIndex: the subband index.
+ */
+ void SetCurrentZCLUT( TUint8 aBandIndex );
+
+ /**
+ * Decode the coded codeblock
+ * @since 2.6
+ * @param aCodeblock: a reference to CJ2kCodeBlock object.
+ * @param aCblkStyle: the codeblock style.
+ * @param aMagBits: the magniture bits.
+ */
+ void DecodeCodeblock( CJ2kCodeBlock& aCodeblock, TUint8 aCblkStyle, TUint8 aMagBits );
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private:
+
+ /**
+ * By default Symbian 2nd phase constructor is private.
+ */
+ void ConstructL( CJ2kImageInfo& aImageInfo );
+
+ /**
+ * Initialize ZC lookup table
+ * @since 2.6
+ */
+ void InitializeZCLut();
+
+ /**
+ * Initialize SC/MR lookup table
+ * @since 2.6
+ */
+ void InitializeScMrLut();
+
+ /**
+ * Get the casual
+ * @since 2.6
+ * @param aDataCol: a reference to the pointer of data column.
+ * @param aStateCol: a reference to the pointer of state column.
+ */
+ void GetCausal( TPrecInt*& aDataCol, TInt16*& aStateCol );
+
+ /**
+ * Decode the significance bit
+ * @since 2.6
+ * @param aDataValue: a reference to the pointer of data value.
+ * @param aStateValue: a reference to the pointer of state value.
+ * @param aMask: the mask.
+ */
+ void DecodeSignificance( TPrecInt*& aDataValue, TInt16*& aStateValue, TPrecInt aMask );
+
+ /**
+ * Decode the lazy significance bit
+ * @since 2.6
+ * @param aDataValue: a reference to the pointer of data value.
+ * @param aStateValue: a reference to the pointer of state value.
+ * @param aMask: the mask.
+ */
+ void DecodeRawSignificance( TPrecInt*& aDataValue, TInt16*& aStateValue, TPrecInt aMask );
+
+ /**
+ * Decode the refinement bit
+ * @since 2.6
+ * @param aDataValue: a reference to the pointer of data value.
+ * @param aStateValue: a reference to the pointer of state value.
+ * @param aMask: the mask.
+ * @param aResetMask: the reset mask.
+ */
+ void DecodeRefinement( TPrecInt*& aDataValue, TInt16*& aStateValue, TPrecInt aMask, TInt32 aResetMask );
+
+ /**
+ * Decode the lazy refinement bit
+ * @since 2.6
+ * @param aDataValue: a reference to the pointer of data value.
+ * @param aStateValue: a reference to the pointer of state value.
+ * @param aMask: the mask.
+ * @param aResetMask: the reset mask.
+ */
+ void DecodeRawRefinement( TPrecInt*& aDataValue, TInt16*& aStateValue, TPrecInt aMask, TInt32 aResetMask );
+
+ /**
+ * Perform the normalization
+ * @since 2.6
+ * @param aDataValue: a reference to the pointer of data value.
+ * @param aStateValue: a reference to the pointer of state value.
+ * @param aMask: the mask.
+ * @param aZCValue: a reference to ZC value.
+ */
+ void DecodeNormalization( TPrecInt*& aDataValue, TInt16*& aStateValue, TPrecInt aMask, TInt32& aZCValue );
+
+ /**
+ * Update the significance
+ * @since 2.6
+ * @param aStateValue: a reference to the pointer of state value.
+ * @param aSymbol: the symbol.
+ */
+ void UpdateSignificance( TInt16*& aStateValue, TInt32 aSymbol );
+
+ /**
+ * Perform the significance pass
+ * @since 2.6
+ */
+ void SignificancePass();
+
+ /**
+ * Perform the lazy significance pass
+ * @since 2.6
+ */
+ void LazySignificancePass();
+
+ /**
+ * Perform the refinement pass
+ * @since 2.6
+ */
+ void RefinementPass();
+
+ /**
+ * Perform the lszy refinement pass
+ * @since 2.6
+ */
+ void LazyRefinementPass();
+
+ /**
+ * Perform the cleanup pass
+ * @since 2.6
+ * @param aSegSymbols: segmentation symbols at the end of coding pass.
+ */
+ void CleanupPass( TUint8 aSegSymbols );
+
+ /**
+ * Get the first state row
+ * @since 2.6
+ * @return TInt16*: a pointer to the first state row.
+ */
+ const TInt16* GetFirstStateRow() const;
+
+ public: // Data
+
+ protected: // Data
+
+ private: // Data
+
+ // Coding flags
+ enum TCodingFlags
+ {
+ EArithmeticBypass = 1,
+ EResetContext = 1 << 1,
+ ETermination = 1 << 2,
+ EVerticalStripe = 1 << 3,
+ EPredictableTermination = 1 << 4,
+ ESegmentationSymbols = 1 << 5
+ };
+
+ // MQCoder
+ J2KMQCoder iMQDecoder;
+
+ // States.
+ TInt16* iStates;
+
+ // SC lut buffer
+ HBufC8* iSCLutBuf;
+
+ // Pointer to SC lut buffer
+ TUint8* iSCLut;
+
+ // MR lut buffer
+ HBufC8* iMRLutBuf;
+
+ // Pointer to MR lut buffer
+ TUint8* iMRLut;
+
+ // ZC lut for LL/LH band
+ HBufC8* iZcLutLL;
+
+ // ZC lut for HL band
+ HBufC8* iZcLutHL;
+
+ // ZC lut for HH band
+ HBufC8* iZcLutHH;
+
+ // Pointer to one of the ZC lut
+ TUint8* iCurrentZcLutPtr;
+
+ // Image max block size
+ TSize iCurrentSize;
+
+ // Number of stripes in the current codeblock
+ TUint16 iNumStripes;
+
+ // Image max block width
+ TUint16 iMaxBlockWidth;
+
+ // Width of data samples in the codeblock
+ TInt32 iBlockDataWidth;
+
+ // Width of state samples in the codeblock
+ TInt32 iStateWidth;
+
+ // Size of the iStates array
+ TInt32 iStateSize;
+
+ // Number of data samples in one full stripe
+ TInt32 iDataSamplesPerStripe;
+
+ // Number of state samples in one full stripe
+ TInt32 iStateSamplesPerStripe;
+
+ // Height of the last stripe in the codeblock
+ TInt32 iLastStripeHeight;
+
+ // Width of the current codeblock
+ TInt32 iBlockWidth;
+
+ // Max bit depth of the image
+ TInt32 iMaxBitDepth;
+
+ // Error state of the Entropy decoder
+ TEntropyErrorState iErrorState;
+
+ // Code block style has Reset Context Probabilities
+ TUint8 iResetContexts;
+
+ // Code block style has Vertical Context Casual
+ TUint8 iVerticalCausalContextUsed;
+
+ // Code block style has Predictable Termination
+ TUint8 iPredictableTerminationUsed;
+
+ // Current bitplane
+ TUint8 iCurrentBitplane;
+
+ // Code block style has Termination on each coding pass
+ TUint8 iTerminateThisPass;
+
+ // Internal two dimensional data array
+ TPrecInt** iData;
+
+ public: // Friend classes
+ friend class CJ2kSynthesis;
+
+ protected: // Friend classes
+
+ private: // Friend classes
+ };
+
+#endif // __JP2KENTROPYDECODER_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KFormat.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,295 @@
+/*
+* Copyright (c) 2003, 2004 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: Collection of structs used to store and represent
+* the metadata in the JP2 file format.
+*
+*/
+
+
+#ifndef __JP2KFORMAT_H__
+#define __JP2KFORMAT_H__
+
+// INCLUDES
+#include <icl/imageprocessor.h>
+
+// CONSTANTS
+
+// BlockSizeInBytes returns this value.
+const TInt KJ2kInputBufferSize = 8192;
+
+// JPEG 2000 signature box information
+const TUint32 KJ2kSigBoxLength = ( (TUint32) 0x0000000c );
+const TUint32 KJ2kSigBoxType = ( (TUint32) 0x6a502020 );
+const TUint32 KJ2kSigBoxContent = ( (TUint32) 0x0d0a870a );
+
+// Length for both box length and type fields together
+const TUint32 KJ2kBoxTypeLength = ( (TUint32)8 );
+
+// JPEG 2000 signaturebox length + next box type and length fields
+const TInt KJ2kFileInformationSize = KJ2kSigBoxLength + KJ2kBoxTypeLength;
+
+// File type box
+const TUint32 KJ2kFileTypeBox = ( (TUint32) 0x66747970 );
+const TUint32 KJ2kFileTypeBrand = ( (TUint32) 0x6a703220 );
+const TUint32 KJ2kFileTypeMinV = ( (TUint32) 0x00000000 );
+const TUint32 KJ2kFileTypeProfile0 = ( (TUint32) 0x4a325030 );
+const TUint32 KJ2kFileTypeProfile1 = ( (TUint32) 0x4a325031 );
+// Restrict the file type box's length to be 1024, this is more than enough
+// and helps detect corrupted codestreams
+const TUint32 KJ2kFileTypeBoxMaxLength = ( (TUint32) 1024);
+
+// JP2 Header Box
+const TUint32 KJ2kJP2HeaderBoxType = ( (TUint32) 0x6a703268 );
+
+// Image Header Box(JP2 Header Box's sub-box) type and length in bytes
+const TUint32 KJ2kImageHeaderBoxType = ( (TUint32) 0x69686472 );
+const TUint32 KJ2kImageHeaderBoxLength = ( (TUint32) 22 );
+const TUint8 KJ2kImageHeaderCompressionType = ( (TUint8)7 );
+
+// Bits Per Component Box(JP2 Header Box's sub-box) type and length
+const TUint32 KJ2kBitsPerCompBoxType = ( (TUint32) 0x62706363 );
+const TUint8 KJ2kIsBPCBoxExist = ( (TUint8) 0xff );
+
+// Colour Specification Box(JP2 Header Box's sub-box) type and length
+const TUint32 KJ2kColourSpecBoxType = ( (TUint32) 0x636f6c72 );
+const TUint32 KJ2kColourSpecGrayScale = ( (TUint32) 17 );
+
+// Palette Box(JP2 Header Box's sub-box) type and length
+const TUint32 KJ2kPaletterBoxType = ( (TUint32) 0x70636c72 );
+
+// Component Mapping Box(JP2 Header Box's sub-box) type and length
+const TUint32 KJ2kComponentMapBoxType = ( (TUint32) 0x636d6170 );
+
+// Channel Definition Box(JP2 Header Box's sub-box) type and length
+const TUint32 KJ2kChannelDefBoxType = ( (TUint32) 0x63646566 );
+
+// Resolution Box(JP2 Header Box's sub-box) type and length
+const TUint32 KJ2kResolutionBoxType = ( (TUint32) 0x72657320 );
+const TUint32 KJ2kCaptureResBoxType = ( (TUint32) 0x72657363 );
+const TUint32 KJ2kDisplayResBoxType = ( (TUint32) 0x72657364 );
+const TUint32 KJ2kResSubBoxLength = ( (TUint32)18 );
+
+// Contiguous Codestream Box type
+const TUint32 KJ2kCodestreamBoxType = ( (TUint32) 0x6a703263 );
+const TUint32 KJ2kIPRBoxType = ( (TUint32) 0x6a703269 );
+const TUint32 KJ2kXMLBoxType = ( (TUint32) 0x786d6c20 );
+const TUint32 KJ2kUUIDBoxType = ( (TUint32) 0x75756964 );
+const TUint32 KJ2kUUIDInfoBoxType = ( (TUint32) 0x75696e66 );
+const TUint32 KJ2kUUIDListBoxType = ( (TUint32) 0x756c7374 );
+const TUint32 KJ2kUUIDUrlBoxType = ( (TUint32) 0x75726c20 );
+
+// Reader Requirements Box
+const TUint32 KJ2kReaderReqBox = ( (TUint32) 0x72726571 );
+
+// JP2 Codestream only - SOC + SIZ marker
+const TUint32 KJ2kSOCType = ( (TUint32) 0xff4fff51 );
+
+// Twip = 1/1440inch. 1/1440*0,0254 meters
+const TReal KJ2kTwipM = 0.000017638; //( (TReal)( 1 / 1440.0 ) * 0.0254 );
+
+// Maximum number of palette entries
+const TInt KMaxPaletteEntries = 1024;
+
+// Maximum number of components possible
+const TInt KMaxComponents = 16384;
+
+// Maximum bitdepth supported
+const TInt KMaxBitdepth = 32;
+
+
+// MACROS
+
+// DATA TYPES
+
+/**
+ * Collection of structs used to store and represent
+ * the metadata in the JP2 file format.
+ *
+ * JP2KCodec.dll
+ * @since 7.0
+ */
+struct TPalette
+ {
+ /**
+ * Destructor
+ * @since 7.0
+ */
+ ~TPalette();
+
+ // Bi list
+ RArray<TUint> iBList;
+
+ // Cij matrix
+ RPointerArray<RArray<TUint> > iC2DArray;
+ };
+
+struct TComponentMap
+ {
+ /**
+ * Constructor
+ * @since 7.0
+ * @param aCmp: the CMP field.
+ * @param aMtyp: the MTYP field.
+ * @param aPcol: the PCOL field.
+ */
+ TComponentMap( TUint16 aCmp, TUint8 aMtyp, TUint8 aPcol );
+
+ // CMP field
+ TUint16 iCmp;
+
+ // MTYP field
+ TUint8 iMtyp;
+
+ // PCOL field
+ TUint8 iPcol;
+ };
+
+struct TChannelDefinition
+ {
+ /**
+ * Constructor
+ * @since 7.0
+ * @param aCn: the Cn field.
+ * @param aTyp: the Typ field.
+ * @param aAsoc: the Asoc field.
+ */
+ TChannelDefinition( TUint16 aCn, TUint16 aTyp, TUint16 aAsoc );
+
+ // Cn field
+ TUint16 iCn;
+
+ // Typ field
+ TUint16 iTyp;
+
+ // Asoc field
+ TUint16 iAsoc;
+ };
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// CLASS DECLARATION
+
+/**
+ * TJ2kInfo class is used to gather and store the
+ * JP2 file format information
+ *
+ * JP2KCodec.dll
+ * @since 2.6
+ */
+class TJ2kInfo
+ {
+ public: // Constructors and destructor
+
+ /**
+ * C++ default constructor.
+ */
+ TJ2kInfo();
+
+ /**
+ * Destructor.
+ */
+ ~TJ2kInfo();
+
+ public: // New functions
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private:
+
+ public: // Data
+
+ // Flags to indicate the existance of some parameters
+ enum TOption
+ {
+ EIPR = 0x01, // To indicate that IPR Box exists //lint !e769 will be referenced in next release.
+ EProfile0 = 0x02, // To indicate the JP2 is restricted to Profile 0
+ EProfile1 = 0x04, // To indicate the JP2 is restricted to Profile 1
+ EJP2file = 0x08, // To indicate that JP2 file format exists
+ EJP2Header= 0x10, // To indicate that JP2 Header processed
+ EColorSpec= 0x20 // To indicate that Colour Spec Box exists
+ };
+
+ // Image size
+ TSize iImageSize;
+
+ // Number of components
+ TUint16 iNC;
+
+ // Bits per component
+ TUint8 iBPC;
+
+ // Bit vector of flags
+ TUint8 iOption;
+
+ // Length of the first codestream box
+ TUint32 iCSBoxLength;
+
+ // Colour spec
+ TUint32 iEnumCS;
+
+ // Start position of codestream in file
+ TUint32 iCSOffset;
+
+ // Display resolution
+ TSize iImageSizeInTwips;
+
+ // Bits per component list
+ RArray<TUint> iBPCList;
+
+ // ICC Profile
+ HBufC8 *iICCProfile;
+
+ // Component Mapping list
+ RArray<TComponentMap> iCMPList;
+
+ // Channel Definition list
+ RArray<TChannelDefinition> iCNList;
+
+ // Palette
+ TPalette iPalette;
+
+ // Intellectual Property box
+ RPointerArray<HBufC8> iIPRList;
+
+ // XML box
+ RPointerArray<HBufC8> iXMLList;
+
+ // UUID box
+ RPointerArray<HBufC8> iUUIDList;
+
+ // UUIDInfo List box
+ RPointerArray<HBufC8> iUUIDInfoListList;
+
+ // UUIDInfo Data Entry Url box
+ RPointerArray<HBufC8> iUUIDInfoUrlList;
+
+ protected: // Data
+
+ private: // Data
+
+ public: // Friend classes
+
+ protected: // Friend classes
+
+ private: // Friend classes
+ };
+
+#endif // __JP2KFORMAT_H__
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KImageClientMain.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,55 @@
+/*
+* Copyright (c) 2003, 2004 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: All used panics are defined in this header file.
+*
+*/
+
+
+#ifndef __JP2IMAGECLIENTMAIN_H__
+#define __JP2IMAGECLIENTMAIN_H__
+
+// INCLUDES
+#include <e32std.h>
+
+// CONSTANTS
+
+// MACROS
+
+// DATA TYPES
+
+// To keep analogy between ICL panics and JPEG 2000 plug-in
+// panics, we use same enumerations and same panics if needed.
+enum TIclPanic
+ {
+ EFrameNumberOutOfRange = 14, //lint !e769 Referenced in ASSER ALWAYS macro
+ EHeaderProcessingNotComplete = 17, //lint !e769 Referenced in ASSER ALWAYS macro
+ ECommentNumberOutOfRange = 18, //lint !e769 Referenced in ASSER ALWAYS macro
+ EInvalidState = 28 //lint !e769 Referenced in ASSER ALWAYS macro
+ };
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// CLASS DECLARATION
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+
+// -----------------------------------------------------------------------------
+// Global panic function
+// -----------------------------------------------------------------------------
+//
+GLDEF_C void Panic( TIclPanic aError );
+
+#endif // __JP2IMAGECLIENTMAIN_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KImageInfo.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,463 @@
+/*
+* Copyright (c) 2003, 2004 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: CJ2kImageInfo class used to collect image related
+* information such as Main Header, SIZ marker and
+* list of tiles.
+*
+*/
+
+
+#ifndef __JP2KIMAGEINFO_H__
+#define __JP2KIMAGEINFO_H__
+
+// INCLUDES
+#include "JP2KMarker.h"
+#include "JP2KUtils.h"
+
+// CONSTANTS
+
+// MACROS
+
+// DATA TYPES
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+class CJ2kTileInfo;
+
+// CLASS DECLARATION
+/**
+ * CJ2kImageInfo class used to collect image related
+ * information such as Main Header, SIZ marker,
+ * List of tiles, and etc. It's also implement the
+ * MJ2kPacketHeaderReader interface for reading the
+ * packet header from PPM marker.
+ *
+ * JP2KCodec.dll
+ * @since 2.6
+ */
+class CJ2kImageInfo : public CBase, public MJ2kPacketHeaderReader
+{
+ public: // Constructors and destructor
+
+ /**
+ * C++ default constructor.
+ */
+ CJ2kImageInfo();
+
+ /**
+ * Destructor.
+ */
+ virtual ~CJ2kImageInfo();
+
+ public: // New functions
+
+ /**
+ * Verify and append COC to the main header
+ * @since 2.6
+ * @param aMarker: pointer to TCOCMarker.
+ */
+ void AppendCOCL( TCOCMarker *aMarker );
+
+ /**
+ * Verify and append QCC to the main header
+ * @since 2.6
+ * @param aMarker: pointer to TQCCMarker.
+ */
+ void AppendQCCL( TQCCMarker *aMarker );
+
+ /**
+ * Verify and append RGN to the main header
+ * @since 2.6
+ * @param aMarker: pointer to TRGNMarker.
+ */
+ void AppendRGNL( TRGNMarker *aMarker );
+
+ /**
+ * Verify and append POC to the main header
+ * @since 2.6
+ * @param aMarker: pointer to TPOCMarker.
+ */
+ void AppendPOCL( TPOCMarker *aMarker );
+
+ /**
+ * Verify and append CRG to the main header
+ * @since 2.6
+ * @param aMarker: pointer to TCRGMarker.
+ */
+ void AppendCRGL( TCRGMarker *aMarker );
+
+ /**
+ * Verify and append COM to the main header
+ * @since 2.6
+ * @param aMarker: pointer to TCOMMarker.
+ */
+ void AppendCOML( const TCOMMarker *aMarker );
+
+ /**
+ * Retrieve the right Coding Style Marker
+ * @since 2.6
+ * @param aCod: a reference to TCODMarker pointer.
+ * @param aCoc: a reference to TCOCMarker pointer.
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @param aComponentIndex: the index of component.
+ */
+ void GetCodingStyle( TCODMarker*& aCod, TCOCMarker*& aCoc,
+ const CJ2kTileInfo& aTile, TUint16 aComponentIndex );
+
+ /**
+ * Retrieve the right Quantization Marker
+ * @since 2.6
+ * @param aQcd: a reference to TQCDMarker pointer.
+ * @param aQcc: a reference to TQCCMarker pointer.
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @param aComponentIndex: the index of component.
+ */
+ void GetQuantization( TQCDMarker*& aQcd, TQCCMarker*& aQcc,
+ const CJ2kTileInfo& aTile, TUint16 aComponentIndex );
+
+ /**
+ * Retrieve the right Region of Interest Marker
+ * @since 2.6
+ * @param aRgn: a reference to TRGNMarker pointer.
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @param aComponentIndex: the index of component.
+ */
+ void GetRegion( TRGNMarker*& aRgn, const CJ2kTileInfo& aTile, TUint16 aComponentIndex ) const;
+
+ /**
+ * Retrieve the tile length field from TLM marker
+ * @since 2.6
+ * @param aSotMarker: a reference to TSotMarker.
+ */
+ void GetFromTLM( TSotMarker& aSotMarker ) const;
+
+ /**
+ * Set up to read the packet header from the PPM marker
+ * @since 2.6
+ * @param aTile: a reference to CJ2kTileInfo object.
+ */
+ void UsePPM( CJ2kTileInfo& aTile );
+
+ /**
+ * Re-arrange the PPM and PLM buffers
+ * @since 2.6
+ */
+ void DoCompactMainHeaderL();
+
+ /**
+ * Get total number of tiles in horizontal position
+ * @since 2.6
+ * @return TUint16: number of tiles in horizontal position.
+ */
+ TUint16 NumOfHorizTiles() const;
+
+ /**
+ * Get total number of tiles in vertical position
+ * @since 2.6
+ * @return TUint16: number of tiles in vertical position.
+ */
+ TUint16 NumOfVertTiles() const;
+
+ /**
+ * Get total number of components
+ * @since 2.6
+ * @return TUint16: number of components.
+ */
+ TUint16 NumOfComponents() const;
+
+ /**
+ * Get the bit depth of a component
+ * @since 2.6
+ * @param aIndex: the component index.
+ * @return TUint8: bit depth of a component.
+ */
+ TUint8 DepthOfComponent( TUint16 aIndex ) const;
+
+ /**
+ * Get the sign bit of a component
+ * @since 2.6
+ * @param aIndex: the component index.
+ * @return TUint8: sign bit of a component.
+ */
+ TUint8 SignOfComponent( TUint16 aIndex ) const;
+
+ /**
+ * Get the SIZ marker
+ * @since 2.6
+ * @return TSizMarker&: a reference to TSizMarker object.
+ */
+ const TSizMarker& SizMarker() const;
+
+ /**
+ * Get the Main Header marker
+ * @since 2.6
+ * @return TMainMarker&: a reference to TMainMarker object.
+ */
+ const TMainMarker& MainMarker() const;
+
+ /**
+ * Get the maximum block size
+ * @since 2.6
+ * @return TSize&: a reference to the maximum size.
+ */
+ const TSize& MaxBlockSize() const;
+
+ /**
+ * Get the cropped area
+ * @since 2.6
+ * @return TRect&: a reference to the cropped area.
+ */
+ const TRect& CropArea() const;
+
+ /**
+ * Get the total number of tiles in the tile list
+ * @since 2.6
+ * @return TUint16: number of tiles in the tile list.
+ */
+ TUint16 TileCount() const;
+
+ /**
+ * Get the tile at specific location
+ * @since 2.6
+ * @param aIndex: the location.
+ * @return CJ2kTileInfo&: a reference to CJ2kTileInfo object.
+ */
+ const CJ2kTileInfo& TileAt( TUint16 aIndex ) const;
+
+ /**
+ * Append tile into the tile list
+ * @since 2.6
+ * @param aTile: the pointer to CJ2kTileInfo object.
+ */
+ void Append( CJ2kTileInfo *aTile );
+
+ /**
+ * Remove a tile at specific location
+ * @since 2.6
+ * @param aIndex: the location.
+ */
+ void Remove( TUint16 aIndex );
+
+ /**
+ * Get the mask of a tile at specific location
+ * @since 2.6
+ * @param aIndex: the location.
+ * @return TUint8: the mask of the tile.
+ */
+ TUint8 TileMaskAt( TUint16 aIndex ) const;
+
+ /**
+ * Set the mask of a tile at specific location
+ * @since 2.6
+ * @param aIndex: the location.
+ * @param aTileMask: the mask.
+ */
+ void SetTileMask( TUint16 aIndex, TUint8 aTileMask );
+
+ /**
+ * Set the resolution level to drop
+ * @since 2.6
+ * @param aDrop: the resolution level to drop.
+ */
+ void SetLevelDrop( TUint8 aDrop );
+
+ /**
+ * Set the extra resolution level to drop
+ * @since 2.6
+ * @param aDrop: the extra levels to drop.
+ */
+ void SetExtraLevelDrop( TUint8 aDrop );
+
+ /**
+ * Get the component to drop
+ * @since 2.6
+ * @return TUint8: the component to drop.
+ */
+ TUint8 ComponentDrop() const;
+
+ /**
+ * Get the resolution level to drop
+ * @since 2.6
+ * @return TUint8: the resolution level to drop.
+ */
+ TUint8 LevelDrop() const;
+
+ /**
+ * Get the extra resolution level to drop
+ * @since 2.6
+ * @return TUint8: the extra resolution level to drop.
+ */
+ TUint8 ExtraLevelDrop() const;
+
+ /**
+ * Get the crop
+ * @since 2.6
+ * @return TUint8: the crop flag.
+ */
+ TUint8 Crop() const;
+
+ /**
+ * Set the last tile part processed
+ * @since 2.6
+ * @param aLastTilePart: the last tile part processed.
+ */
+ void SetLastTilePartProcessed( TUint16 aLastTilePart );
+
+ /**
+ * Increment the counter for tracking the last tile part processed
+ * @since 2.6
+ */
+ void IncrementLastTilePartProcessed();
+
+ /**
+ * Is packet header should be read from PPM marker
+ * @since 2.6
+ * @return TUint8: true if PPM marker exists.
+ */
+ TUint8 IsPPM() const;
+
+ /**
+ * Reset packet header pointer to the end of the PPM marker
+ * @since 2.6
+ */
+ void ResetPPM();
+
+ public: // Functions from base classes
+
+ /**
+ * From MJ2kPacketHeaderReader
+ * Try to consume the EPH marker if there is one
+ * @since 2.6
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 ReadEPHMarker();
+
+ /**
+ * From MJ2kPacketHeaderReader
+ * Read a bit from the packet header stream
+ * @since 2.6
+ * @param aBit: get a bit from the packet header bitstream.
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 ReadBit( TUint8& aBit );
+
+ /**
+ * From MJ2kPacketHeaderReader
+ * Read some bits from the packet header stream
+ * @since 2.6
+ * @param aBit: get some bits from the packet header bitstream.
+ * @param aBitLen: how many bits to read.
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 ReadBits( TUint8& aBit, TUint8 aBitLen );
+
+ /**
+ * From MJ2kPacketHeaderReader
+ * Read some bits from the packet header stream
+ * @since 2.6
+ * @param aBit: get some bits from the packet header bitstream.
+ * @param aBitLen: how many bits to read.
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 ReadBits( TUint32& aBit, TUint8 aBitLen );
+
+ /**
+ * From MJ2kPacketHeaderReader
+ * Start reading from packet header stream
+ * @since 2.6
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 StartReadBit();
+
+ /**
+ * From MJ2kPacketHeaderReader
+ * Align the stream to the next byte boundary if necessary
+ * @since 2.6
+ */
+ void AlignReader();
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private:
+
+ public: // Data
+
+ protected: // Data
+
+ // Structure to hold the information on reading packet header
+ struct TPPMStream
+ {
+ TUint32 iPtr; // Current byte position in buffer
+ TUint32 iPtrEnd; // End of byte position in buffer
+ TUint8 iData; // Current data in 8 bits
+ TUint8 iPos; // Current bit position
+ TUint8 iNextPos; // Bit position of next byte
+ };
+
+ private: // Data
+
+ // SIZ marker
+ TSizMarker iSizMarker;
+
+ // Main Header
+ TMainMarker iMainMarker;
+
+ // Current tile in progress
+ CJ2kTileInfo *iTile;
+
+ // Current tile mask
+ TUint8 iTileMask;
+
+ // Max block size
+ TSize iMaxBlockSize;
+
+ // Cropped area
+ TRect iCropArea;
+
+ // Component to drop
+ TUint8 iComponentDrop;
+
+ // Resolution level to drop
+ TUint8 iLevelDrop;
+
+ // Resolution drop
+ TUint8 iExtraLevelDrop;
+
+ // Is cropped
+ TUint8 iCrop;
+
+ // Last tile part processed
+ TInt16 iLastTilePartProcessed;
+
+ // Control the reading of packet header
+ TPPMStream *iPpm;
+
+ // Pointer to PPM in Main Header
+ HBufC8 *iPpmBuffer;
+
+ public: // Friend classes
+
+ protected: // Friend classes
+
+ private: // Friend classes
+ };
+
+// For inliners.
+#include "JP2KImageInfo.inl"
+
+#endif // __JP2KIMAGEINFO_H__
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KImageInfo.inl Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,301 @@
+/*
+* Copyright (c) 2003, 2004 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: CJ2kImageInfo class used to collect image related
+* information such as Main Header, SIZ marker and
+* list of tiles.
+*
+*/
+
+
+#ifndef __JP2KIMAGEINFO_INL__
+#define __JP2KIMAGEINFO_INL__
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::NumOfHorizTiles
+// Get total number of tiles in horizontal position
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint16 CJ2kImageInfo::NumOfHorizTiles() const
+ {
+ return (TUint16)( TJ2kUtils::Ceil( iSizMarker.iXsiz - iSizMarker.iXTOsiz,
+ iSizMarker.iXTsiz ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::NumOfVertTiles
+// Get total number of tiles in vertical position
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint16 CJ2kImageInfo::NumOfVertTiles() const
+ {
+ return (TUint16)( TJ2kUtils::Ceil( iSizMarker.iYsiz - iSizMarker.iYTOsiz,
+ iSizMarker.iYTsiz ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::NumOfComponents
+// Get total number of components
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint16 CJ2kImageInfo::NumOfComponents() const
+ {
+ return iSizMarker.iCsiz;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::DepthOfComponent
+// Get the bit depth of a component
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kImageInfo::DepthOfComponent( TUint16 aIndex ) const
+ {
+ return ( aIndex < iSizMarker.iCsiz ) ?
+ (TUint8)( ( iSizMarker.iSsiz[aIndex] & 0x7f ) + 1 ) :
+ (TUint8)0;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::SignOfComponent
+// Get the sign bit of a component
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kImageInfo::SignOfComponent( TUint16 aIndex ) const
+ {
+ return ( aIndex < iSizMarker.iCsiz ) ?
+ (TUint8)( iSizMarker.iSsiz[aIndex] & 0x80 ) :
+ (TUint8)0;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::SizMarker
+// Get the SIZ marker
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline const TSizMarker& CJ2kImageInfo::SizMarker() const
+ {
+ return iSizMarker;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::MainMarker
+// Get the Main Header marker
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline const TMainMarker& CJ2kImageInfo::MainMarker() const
+ {
+ return iMainMarker;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::MaxBlockSize
+// Get the maximum block size
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline const TSize& CJ2kImageInfo::MaxBlockSize() const
+ {
+ return iMaxBlockSize;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::CropArea
+// Get the cropped area
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline const TRect& CJ2kImageInfo::CropArea() const
+ {
+ return iCropArea;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::TileCount
+// Get the total number of tiles in the tile list
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint16 CJ2kImageInfo::TileCount() const
+ {
+ return (TUint16)( iTile ? 1 : 0 );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::TileAt
+// Get the tile at specific location
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline const CJ2kTileInfo& CJ2kImageInfo::TileAt( TUint16 /*aIndex*/ ) const
+ {
+ return *iTile;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::Append
+// Append tile into the tile list
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kImageInfo::Append( CJ2kTileInfo *aTile )
+ {
+ iTile = aTile;
+ iTileMask = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::Remove
+// Remove a tile at specific location
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kImageInfo::Remove( TUint16 /*aIndex*/ )
+ {
+ delete iTile;
+ iTile = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::TileMaskAt
+// Get the mask of a tile at specific location
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kImageInfo::TileMaskAt( TUint16 /*aIndex*/ ) const
+ {
+ return iTileMask;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::SetTileMask
+// Set the mask of a tile at specific location
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kImageInfo::SetTileMask( TUint16 /*aIndex*/, TUint8 aTileMask )
+ {
+ iTileMask = aTileMask;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::SetLevelDrop
+// Set the resolution level to drop
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kImageInfo::SetLevelDrop( TUint8 aDrop )
+ {
+ iLevelDrop = aDrop;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::SetExtraLevelDrop
+// Set the extra resolution level to drop
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kImageInfo::SetExtraLevelDrop( TUint8 aDrop )
+ {
+ iExtraLevelDrop = aDrop;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::ComponentDrop
+// Get the component to drop
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kImageInfo::ComponentDrop() const
+ {
+ return iComponentDrop;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::LevelDrop
+// Get the resolution level to drop
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kImageInfo::LevelDrop() const
+ {
+ return iLevelDrop;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::ExtraLevelDrop
+// Get the extra resolution level to drop
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kImageInfo::ExtraLevelDrop() const
+ {
+ return iExtraLevelDrop;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::Crop
+// Get the crop
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kImageInfo::Crop() const
+ {
+ return iCrop;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::SetLastTilePartProcessed
+// Set the last tile part processed
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kImageInfo::SetLastTilePartProcessed( TUint16 aLastTilePart )
+ {
+ iLastTilePartProcessed = aLastTilePart;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::IncrementLastTilePartProcessed
+// Increment the counter for tracking the last tile part processed
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kImageInfo::IncrementLastTilePartProcessed()
+ {
+ ++iLastTilePartProcessed;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::ResetPPM
+// Reset packet header pointer to the end of the PPM marker
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kImageInfo::ResetPPM()
+ {
+ if ( iPpm )
+ {
+ iPpm->iPtr = iPpm->iPtrEnd;
+ }
+ }
+
+#endif // __JP2KIMAGEINFO_INL__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KImageUtils.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,111 @@
+/*
+* Copyright (c) 2003, 2004 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: Basic utilities to handle conversion and object safe deletion.
+*
+*/
+
+
+#ifndef __JP2KIMAGEUTILS_H__
+#define __JP2KIMAGEUTILS_H__
+
+// INCLUDES
+#include <e32std.h>
+#include <e32base.h>
+
+// CONSTANTS
+
+// MACROS
+
+// DATA TYPES
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// TEMPLATE DECLARATION
+
+/**
+* Basic reading utility class.
+* Utility class with methods for standard
+* reading stuff from a TUint8* string.
+*
+ * JP2KCodec.dll
+ * @since 2.6
+*/
+class PtrReadUtil
+ {
+ public: // Constructors and destructor
+
+ public: // New functions
+
+ /**
+ * Reads big endian value from given buffer.
+ * @since 2.6
+ * @param aPtr: Pointer to buffer
+ * @TUint16: Read value.
+ */
+ static TUint16 ReadBigEndianUint16( const TUint8* aPtr );
+
+ /**
+ * Reads big endian value from given buffer.
+ * @since 2.6
+ * @param aPtr: Pointer to buffer
+ * @TUint32: Read value.
+ */
+ static TUint32 ReadBigEndianUint32( const TUint8* aPtr );
+
+ /**
+ * Reads big endian value from given buffer and increments pointer.
+ * @since 2.6
+ * @param aPtr: Pointer to buffer
+ * @TUint16: Read value.
+ */
+ static TUint16 ReadBigEndianUint16Inc( const TUint8*& aPtr );
+
+ /**
+ * Reads big endian value from given buffer and increments pointer.
+ * @since 2.6
+ * @param aPtr: Pointer to buffer
+ * @TUint32: Read value.
+ */
+ static TUint32 ReadBigEndianUint32Inc( const TUint8*& aPtr );
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private:
+
+ public: // Data
+
+ protected: // Data
+
+ private: // Data
+
+ public: // Friend classes
+
+ protected: // Friend classes
+
+ private: // Friend classes
+
+ };
+
+#include "JP2KImageUtils.inl"
+
+#endif // __JP2KIMAGEUTILS_H__
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KImageUtils.inl Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,72 @@
+/*
+* Copyright (c) 2003, 2004 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: Basic utilities to handle conversion and object safe deletion.
+*
+*/
+
+
+#ifndef __JP2KIMAGEUTILS_INL__
+#define __JP2KIMAGEUTILS_INL__
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// PtrReadUtil::ReadBigEndianUint16
+// Reads big endian value from given buffer.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint16 PtrReadUtil::ReadBigEndianUint16( const TUint8* aPtr )
+ {
+ return TUint16( ( aPtr[0] << 8 ) | aPtr[1] );
+ }
+
+// -----------------------------------------------------------------------------
+// PtrReadUtil::ReadBigEndianUint32
+// Reads big endian value from given buffer.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint32 PtrReadUtil::ReadBigEndianUint32( const TUint8* aPtr )
+ {
+ return TUint32( ( aPtr[0] << 24 ) | ( aPtr[1] << 16 ) | ( aPtr[2] << 8 ) | aPtr[3] );
+ }
+
+// -----------------------------------------------------------------------------
+// PtrReadUtil::ReadBigEndianUint16Inc
+// Reads big endian value from given buffer and increments pointer.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint16 PtrReadUtil::ReadBigEndianUint16Inc( const TUint8*& aPtr )
+ {
+ TUint16 result = ReadBigEndianUint16( aPtr );
+ aPtr += 2;
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+// PtrReadUtil::ReadBigEndianUint32Inc
+// Reads big endian value from given buffer and increments pointer.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint32 PtrReadUtil::ReadBigEndianUint32Inc( const TUint8*& aPtr )
+ {
+ TUint32 result = ReadBigEndianUint32( aPtr );
+ aPtr += 4;
+ return result;
+ }
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KImageWriter.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,515 @@
+/*
+* Copyright (c) 2003, 2004 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: CJ2kImageWriter class used to perform inverse transformation and
+* writing decoded image data to bitmap.
+*
+*/
+
+
+#ifndef __JP2KIMAGEWRITER_H__
+#define __JP2KIMAGEWRITER_H__
+
+// INCLUDES
+#include <icl/imageprocessor.h>
+
+// CONSTANTS
+const TUint8 KByteBits = 8; // Number of bits in byte
+const TUint8 KFractionBits = 12;
+const TUint16 KOffset = (1 << ( KFractionBits - 1 ) );
+
+// Inverse color transform shifted(by 12 bits) coefficients
+const TInt32 KIctCoefficient11 = 5743;
+const TInt32 KIctCoefficient21 = -1409;
+const TInt32 KIctCoefficient22 = -2925;
+const TInt32 KIctCoefficient31 = 7258;
+
+// The ICC profile Tag definitions
+const TUint8 KICCSkipBytes = 128; // Bytes to skip before reading the ICC profile
+const TUint32 KRedMatrixTag = 0x7258595A; // Tag indicating the place (in ICC profile) of conversion matrix coefficients for red
+const TUint32 KGreenMatrixTag = 0x6758595A; // Tag indicating the place of conversion matrix coefficients for green
+const TUint32 KBlueMatrixTag = 0x6258595A; // Tag indicating the place of conversion matrix coefficients for blue
+const TUint32 KRedTrcTag = 0x72545243; // Tag indicating the place of Tone Reproduction Curve value for red
+const TUint32 KGreenTrcTag = 0x67545243; // Tag indicating the place of Tone Reproduction Curve value for green
+const TUint32 KBlueTrcTag = 0x62545243; // Tag indicating the place of Tone Reproduction Curve value for blue
+const TUint32 KGrayTrcTag = 0x6B545243; // Tag indicating the place of Tone Reproduction Curve value for gray
+const TUint32 KPixelsBlock = 256; // The max number of pixel in a block
+
+// Define the XYZ to linear sRGB matrix coefficients
+const TReal KSRGB00 = 3.1337;
+const TReal KSRGB01 = -1.6173;
+const TReal KSRGB02 = -0.4907;
+const TReal KSRGB10 = -0.9785;
+const TReal KSRGB11 = 1.9162;
+const TReal KSRGB12 = 0.0334;
+const TReal KSRGB20 = 0.0720;
+const TReal KSRGB21 = -0.2290;
+const TReal KSRGB22 = 1.4056;
+const TReal KSRGBMax = (TReal)4095;
+const TInt32 KSRGBMaxInt = (TInt32)4095;
+const TInt32 KSRGBShift = 4; // The shift for the sRGB maximum value
+const TInt32 KSRGBMaxIntShifted = (TInt32)( ( 1 << KSRGBShift ) * (TReal)4095 );// The sRGB maximum value shifted by 4
+const TInt32 KTRCShift = 12; // The shift used for TRC LUT values for integer computation
+const TInt32 KTRCShiftMultiplier = (TInt32)( 1 << KTRCShift ); // The shift used for TRC LUT values for integer computation
+const TUint32 KICCDownshift = KTRCShift + KSRGBShift; // The total shift used for computing the ICC conversion with integers (12 for TRC LUT and 4 for the matrix coefficients)
+
+const TReal KDivisor = (TReal)65536;
+const TReal KGamma = (TReal)256;
+
+// Define values for performing the linear RGB -> sRGB (non linear) conversion
+const TReal KSRGB_CUTOFF = 0.0031308;
+const TReal KSRGB_SLOPE = 12.92;
+const TReal KSRGB_EXPONENT = 0.4166666; // ( 1.0 / 2.4 );
+const TReal KSRGB_MULTIPLIER = 1.055;
+const TReal KSRGB_SUBTRACT = 0.055;
+
+// DATA TYPES
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+class CJ2kImageWriter;
+class CJ2kImageInfo;
+class CJ2kTileInfo;
+class TJ2kInfo;
+
+// CLASS DECLARATION
+
+/**
+ * CJ2kWriterComponentInfo class is used to store
+ * information about tiles' coordinates for outputting
+ * samples and also to store the output data.
+ *
+ * JP2KCodec.dll
+ * @since 2.6
+ */
+class CJ2kWriterComponentInfo : public CBase
+ {
+ public: // Constructors and destructor
+
+ /**
+ * Destructor.
+ */
+ virtual ~CJ2kWriterComponentInfo();
+
+ public: // New functions
+
+ /**
+ * Allocate the 2-D data array with a size
+ * @since 2.6
+ * @param aSize: the size to allocate.
+ */
+ void AllocDataL( const TSize& aSize );
+
+ /**
+ * Free the 2-D data array
+ * @since 2.6
+ */
+ void FreeData();
+
+ /**
+ * Get the 2-D data arry
+ * @since 2.6
+ * @return TPrecInt**: the pointer to pointer.
+ */
+ TPrecInt** Data();
+
+ /**
+ * Get the starting point of a tile
+ * @since 2.6
+ * @param aTileIndex: the tile index.
+ * @return TPoint&: a reference to the start point of the tile.
+ */
+ TPoint& TileStartAt( TUint16 aTileIndex );
+
+ /**
+ * Update the starting point of next tile
+ * @since 2.6
+ * @param aTileIndex: the tile index.
+ * @param aSize: the size of the tile.
+ * @param aImageInfo: a reference to CJ2kImageInfo object.
+ */
+ void UpdateNextTileStartAt(TUint16 aTileIndex, const TSize& aSize, CJ2kImageInfo& aImageInfo );
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private:
+
+ public: // Data
+
+ protected: // Data
+
+ private: // Data
+
+ // Internal 2-D data array
+ TPrecInt **iData;
+
+ // Start position of each tile
+ RArray<TPoint> iTileStartList;
+
+ public: // Friend classes
+ friend class CJ2kImageWriter;
+
+ protected: // Friend classes
+
+ private: // Friend classes
+ };
+
+/**
+ * CJ2kImageWriter class has methods to perform
+ * color, bitdepth and ICC profile conversions to
+ * produce 8-bit output data.
+ *
+ * JP2KCodec.dll
+ * @since 2.6
+ */
+class CJ2kImageWriter : public CBase
+ {
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor.
+ */
+ static CJ2kImageWriter* NewL( CImageProcessor* aImageProcessor, CJ2kImageInfo& aImageInfo,
+ TJ2kInfo& aJ2kInfo );
+
+ /**
+ * Destructor.
+ */
+ virtual ~CJ2kImageWriter();
+
+ public: // New functions
+
+ /**
+ * Get the component of the image writer
+ * @since 2.6
+ * @param aIndex: the component index.
+ * @return CJ2kWriterComponentInfo&: a reference to CJ2kWriterComponentInfo.
+ */
+ const CJ2kWriterComponentInfo& WriterComponentAt( TUint16 aIndex ) const;
+
+ /**
+ * Output the image related to the component of the tile
+ * @since 2.6
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @param aComponentIndex: the component index.
+ */
+ void OutputImageL( CJ2kTileInfo& aTile, TUint16 aComponentIndex );
+
+ /**
+ * Output the image related to the component of the tile
+ * @since 2.6
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @param aComponentIndex: the component index.
+ * @param aSize: the size to output.
+ */
+ void OutputImageL( CJ2kTileInfo& aTile, TUint16 aComponentIndex,
+ const TSize& aSize );
+ /**
+ * Output the image related to the component of the tile
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @param aComponentIndex: the component index.
+ * @param aBlockXCoord: the block X coordinate.
+ * @param aBlockYCoord: the block Y coordinate.
+ * @param aFirstCompSize: the size of first component.
+ * @param aThisCompSize: the size of this component.
+ */
+ void OutputBlockL( CJ2kTileInfo& aTile, TUint16 aComponentIndex,
+ TInt32 aBlockXCoord, TInt32 aBlockYCoord,
+ TSize aFirstCompSize, TSize aThisCompSize );
+ /**
+ * Set the image processor of the image write
+ * @since 2.6
+ * @param aImageProcessor: a pointer to CImageProcessor object.
+ */
+ void SetNewImageProcessor( CImageProcessor* aImageProcessor );
+
+ /**
+ * Get the single output file
+ * @since 2.6
+ * @return TUint8: true if single file output.
+ */
+ TUint8 SingleFileOutput() const;
+
+ /**
+ * Get the EnumCS
+ * @since 2.6
+ * @return TUint8: the CS code.
+ */
+ TUint8 CSCode() const;
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private:
+
+ /**
+ * C++ default constructor.
+ */
+ CJ2kImageWriter( CImageProcessor* aImageProcessor, CJ2kImageInfo& aImageInfo, TJ2kInfo& aJ2kInfo );
+
+ /**
+ * By default Symbian 2nd phase constructor is private.
+ */
+ void ConstructL();
+
+ /**
+ * Perform the inverse reversible color transformation
+ * @since 2.6
+ * @param aSize: the size.
+ */
+ void PerformInverseRCT( const TSize& aSize );
+
+ /**
+ * Perform the inverse irreversible color transformation
+ * @since 2.6
+ * @param aSize: the size.
+ */
+ void PerformInverseICT( const TSize& aSize );
+
+ /**
+ * Inverse irreversible color transformation
+ * @since 2.6
+ * @param aY: the Y value.
+ * @param aU: the U value.
+ * @param aV: the V value.
+ * @param aR: a reference to red value.
+ * @param aG: a reference to green value.
+ * @param aB: a reference to blue value.
+ */
+ void InverseICTTransform( TPrecInt aY, TPrecInt aU, TPrecInt aV,
+ TPrecInt& aR, TPrecInt& aG, TPrecInt& aB );
+
+ /**
+ * Inverse irreversible color transformation
+ * @since 2.6
+ * @param aY1: the Y value of the even sample.
+ * @param aY2: the Y value of the odd sample.
+ * @param aU: the U value.
+ * @param aV: the V value.
+ * @param aR1: a reference to even red value.
+ * @param aG1: a reference to even green value.
+ * @param aB1: a reference to even blue value.
+ * @param aR2: a reference to odd red value.
+ * @param aG2: a reference to odd green value.
+ * @param aB2: a reference to odd blue value.
+ */
+ void InverseICTTransform( TPrecInt aY1, TPrecInt aY2, TPrecInt aU, TPrecInt aV,
+ TPrecInt& aR1, TPrecInt& aG1, TPrecInt& aB1,
+ TPrecInt& aR2, TPrecInt& aG2, TPrecInt& aB2 );
+
+ /**
+ * Inverse irreversible color transformation
+ * @since 2.6
+ * @param aY1: the Y value of the even sample on even row.
+ * @param aY2: the Y value of the odd sample on even row.
+ * @param aY3: the Y value of the even sample on odd row.
+ * @param aY4: the Y value of the odd sample on odd row.
+ * @param aU: the U value.
+ * @param aV: the V value.
+ * @param aR1: a reference to even red value on even row.
+ * @param aG1: a reference to even green value on even row.
+ * @param aB1: a reference to even blue value on even row.
+ * @param aR2: a reference to odd red value on even row.
+ * @param aG2: a reference to odd green value on even row.
+ * @param aB2: a reference to odd blue value on even row.
+ * @param aR3: a reference to even red value on odd row.
+ * @param aG3: a reference to even green value on odd row.
+ * @param aB3: a reference to even blue value on odd row.
+ * @param aR4: a reference to odd red value on odd row.
+ * @param aG4: a reference to odd green value on odd row.
+ * @param aB4: a reference to odd blue value on odd row.
+ */
+ void InverseICTTransform( TPrecInt aY1, TPrecInt aY2, TPrecInt aY3, TPrecInt aY4,
+ TPrecInt aU, TPrecInt aV,
+ TPrecInt& aR1, TPrecInt& aG1, TPrecInt& aB1,
+ TPrecInt& aR2, TPrecInt& aG2, TPrecInt& aB2,
+ TPrecInt& aR3, TPrecInt& aG3, TPrecInt& aB3,
+ TPrecInt& aR4, TPrecInt& aG4, TPrecInt& aB4 );
+
+ /**
+ * Initialize the ICC profile from JP2 file format (iJ2kInfo)
+ * @since 2.6
+ */
+ void InitializeICCProfileL();
+
+ /**
+ * Initialize the output parameters
+ * @since 2.6
+ */
+ void InitializeOutputParametersL();
+
+ /**
+ * Perform the XYZ to sRGB conversion using ICC profile.
+ * @since 2.6
+ * @param aX: sample x to be converted.
+ * @param aY: sample y to be converted.
+ * @param aZ: sample z to be converted.
+ * @param aR: a reference to red value.
+ * @param aG: a reference to green value.
+ * @param aB: a reference to blue value.
+ */
+ void DoICCConversion( TInt32 aX, TInt32 aY, TInt32 aZ,
+ TPrecInt& aR, TPrecInt& aG, TPrecInt& aB );
+ /**
+ * Map data less than 8 bits to 8 bits data
+ * @since 2.6
+ * @param aComponent: a reference to CJ2kWriterComponentInfo object.
+ * @param aSize: the size of component.
+ * @param aBitDepth: the bit depth.
+ */
+ void MapToEightBits( CJ2kWriterComponentInfo& aComponent,
+ const TSize& aSize, TUint16 aBitDepth );
+
+ /**
+ * Map data using the component mapping box from JP2 file format
+ * @since 2.6
+ * @param aNumCSComp: number of CS component.
+ * @param aReducedLevels: the reduced resolution level.
+ * @param aSize: the size to output.
+ * @param aTile: a reference to CJ2kTileInfo object.
+ */
+ void MapComponentsL( TUint16 aNumCSComp,TUint16 aReducedLevels,
+ const TSize& aSize, CJ2kTileInfo& aTile );
+
+ /**
+ * Write the component to the single output file
+ * @since 2.6
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @param aCompIndex: the component index.
+ * @param aSize: the size of component.
+ * @param aBitDepth: the bit depth.
+ */
+ void WriteOutputFile( CJ2kTileInfo& aTile, TUint16 aCompIndex, const TSize& aSize,
+ TUint16 aBitDepth );
+
+ /**
+ * Write all components of the tile to the single output file
+ * @since 2.6
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @param aSize: the size to output.
+ */
+ void CombineOutputFile( CJ2kTileInfo& aTile, const TSize& aSize );
+
+ /**
+ * Write out a color pixel
+ * @since 2.6
+ * @param aR: the red value.
+ * @param aG: the green value.
+ * @param aB: the blue value.
+ */
+ void WritePixel( TUint8 aR, TUint8 aG, TUint8 aB );
+
+ /**
+ * Write out a grayscale pixel
+ * @since 2.6
+ * @param aGray256: the gray scale value.
+ */
+ void WritePixel( TUint8 aGray256 );
+
+ /**
+ * Set the position of the pixel
+ * @since 2.6
+ * @param aPosition: the position of next pixel.
+ */
+ void SetPixelPos( const TPoint& aPosition );
+
+ /**
+ * Set the position of the pixel
+ * @since 2.6
+ * @param aX: the X position of next pixel.
+ * @param aY: the Y position of next pixel.
+ */
+ void SetPixelPos( const TInt aX, const TInt aY );
+
+ public: // Data
+
+ protected: // Data
+
+ private: // Data
+
+ // File type
+ enum TFileType
+ {
+ KOurRGB, //lint !e769 keep here for later use
+ KRGB,
+ KYUV422,
+ KYUV420
+ };
+
+ // Number of components
+ TUint16 iNumComponents;
+
+ // File type
+ TFileType iFileType;
+
+ // Is single file output?
+ TUint8 iSingleFileOutput;
+
+ // Is ICC Profile used?
+ TUint8 iICCProfile;
+
+ // An array of component infos
+ RPointerArray<CJ2kWriterComponentInfo> iComponents;
+
+ // Reference to the image processor
+ CImageProcessor* iImageProcessor;
+
+ // Reference to the image info
+ CJ2kImageInfo& iImageInfo;
+
+ // Reference to the file format into
+ TJ2kInfo& iJ2kInfo;
+
+ // ** For ICC Profile **
+
+ // Conversion matrix to perform the RGBin->XYZ->sRGB conversion
+ TInt32 iMatrix[9];
+
+ // Linear sRGB lookup table for sRGB(lin)->sRGB(non-lin) conversion
+ HBufC8 *iLinearsRGBLut;
+
+ // Tone reproduction curve LUT for linearizing Gray input sample
+ TInt32 *iGrayTRCLut;
+
+ // Tone reproduction curve LUT for linearizing Red input sample
+ TInt32 *iRedTRCLut;
+
+ // Tone reproduction curve LUT for linearizing Green input sample
+ TInt32 *iGreenTRCLut;
+
+ // Tone reproduction curve LUT for linearizing Blue input sample
+ TInt32 *iBlueTRCLut;
+
+ // Block containing grayscale pixels
+ TUint32 *iMonoPixelBlock;
+
+ // Block containing color pixels
+ TRgb *iColorPixelBlock;
+
+ public: // Friend classes
+
+ protected: // Friend classes
+
+ private: // Friend classes
+
+ };
+
+#endif // __JP2KIMAGEWRITER_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KMarker.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,552 @@
+/*
+* Copyright (c) 2003, 2004 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: Collection of structs used to gather the various
+* marker related information in the JP2 image file.
+* TxxxMarker must not exist on the stack, it must
+* be the data member of the classes derived from CBase.
+*
+*/
+
+
+#ifndef __JP2KMARKER_H__
+#define __JP2KMARKER_H__
+
+// INCLUDES
+#include <e32base.h>
+
+// CONSTANTS
+
+// MACROS
+
+// DATA TYPES
+
+/**
+ * struct TSizMarker
+ * Image and tile size (SIZ)
+ * @since 2.6
+ */
+struct TSizMarker
+ {
+
+ /**
+ * Constructor
+ * @since 2.6
+ */
+ TSizMarker();
+
+ /**
+ * Destructor
+ * @since 2.6
+ */
+ ~TSizMarker();
+
+ TUint32 iXsiz;
+ TUint32 iYsiz;
+ TUint32 iXOsiz;
+ TUint32 iYOsiz;
+ TUint32 iXTsiz;
+ TUint32 iYTsiz;
+ TUint32 iXTOsiz;
+ TUint32 iYTOsiz;
+ TUint16 iRsiz;
+ TUint16 iCsiz;
+ RArray<TUint> iSsiz;
+ RArray<TUint> iXRsiz;
+ RArray<TUint> iYRsiz;
+ };
+
+/**
+ * struct TSotMarker
+ * Start of tile-part (SOT)
+ * @since 2.6
+ */
+struct TSotMarker
+ {
+ TUint32 iPsot;
+ TUint16 iIsot;
+ TUint8 iTPsot;
+ TUint8 iTNsot;
+ };
+
+/**
+ * struct TCODMarker
+ * Coding style default (COD)
+ * @since 2.6
+ */
+struct TCODMarker
+ {
+ /**
+ * Constructor
+ * @since 2.6
+ */
+ TCODMarker();
+
+ /**
+ * Destructor
+ * @since 2.6
+ */
+ ~TCODMarker();
+
+ TUint8 iScod;
+ TUint8 iProgressionOrder;
+ TUint8 iColorTransformation;
+ TUint8 iNumOfLevels;
+ TUint8 iCodeBlockStyle;
+ TUint8 iWaveletTransformation;
+ TUint16 iNumOfLayers;
+ TSize iCodeBlockSiz;
+ HBufC8 *iPrecinctSiz;
+ };
+
+/**
+ * struct TCOCMarker
+ * Coding style component (COC)
+ * @since 2.6
+ */
+struct TCOCMarker
+ {
+
+ /**
+ * Constructor
+ * @since 2.6
+ */
+ TCOCMarker();
+
+ /**
+ * Destructor
+ * @since 2.6
+ */
+ ~TCOCMarker();
+
+ TUint16 iCcoc;
+ TUint8 iScoc;
+ TUint8 iNumOfLevels;
+ TUint8 iCodeBlockStyle;
+ TUint8 iWaveletTransformation;
+ TSize iCodeBlockSiz;
+ HBufC8 *iPrecinctSiz;
+ };
+
+/**
+ * struct TQCDMarker
+ * Quantization default (QCD)
+ * @since 2.6
+ */
+struct TQCDMarker
+ {
+
+ /**
+ * Constructor
+ * @since 2.6
+ */
+ TQCDMarker();
+
+ /**
+ * Destructor
+ * @since 2.6
+ */
+ ~TQCDMarker();
+
+ TUint8 iSqcd;
+ HBufC8 *iExponent;
+ HBufC16 *iMantissa;
+ };
+
+/**
+ * struct TQCCMarker
+ * Quantization component (QCC)
+ * @since 2.6
+ */
+struct TQCCMarker
+ {
+
+ /**
+ * Constructor
+ * @since 2.6
+ */
+ TQCCMarker();
+
+ /**
+ * Destructor
+ * @since 2.6
+ */
+ ~TQCCMarker();
+
+ TUint16 iCqcc;
+ TUint8 iSqcc;
+ HBufC8 *iExponent;
+ HBufC16 *iMantissa;
+ };
+
+/**
+ * struct TRGNMarker
+ * Region of interest (RGN)
+ * @since 2.6
+ */
+struct TRGNMarker
+ {
+ TUint16 iCrgn;
+ TUint8 iSrgn;
+ TUint8 iSPrgn;
+ };
+
+/**
+ * struct TPOCMarker
+ * Progression order change (POC)
+ * @since 2.6
+ */
+struct TPOCMarker
+ {
+
+ /**
+ * Constructor
+ * @since 2.6
+ */
+ TPOCMarker();
+
+ /**
+ * Destructor
+ * @since 2.6
+ */
+ ~TPOCMarker();
+
+ RArray<TUint> iRSpoc;
+ RArray<TUint> iCSpoc;
+ RArray<TUint> iLYEpoc;
+ RArray<TUint> iREpoc;
+ RArray<TUint> iCEpoc;
+ RArray<TUint> iPpoc;
+ };
+
+/**
+ * struct TPPMMarker
+ * Packed packet headers, main header (PPM)
+ * @since 2.6
+ */
+struct TPPMMarker
+ {
+
+ /**
+ * Constructor
+ * @since 2.6
+ */
+ TPPMMarker();
+
+ /**
+ * Destructor
+ * @since 2.6
+ */
+ ~TPPMMarker();
+
+ TUint8 iZppm;
+ TUint32 iRemainder;
+ TUint32 iNppm;
+ HBufC8 *iIppm;
+ };
+
+/**
+ * struct TTLMMarker
+ * Tile-part lengths (TLM)
+ * @since 2.6
+ */
+struct TTLMMarker
+ {
+
+ /**
+ * Constructor
+ * @since 2.6
+ */
+ TTLMMarker();
+
+ /**
+ * Destructor
+ * @since 2.6
+ */
+ ~TTLMMarker();
+
+ TUint8 iZtlm;
+ TUint8 iStlm;
+ RArray<TUint> iTtlm;
+ RArray<TUint> iPtlm;
+ };
+
+/**
+ * struct TPLMMarker
+ * Packet length, main header (PLM)
+ * @since 2.6
+ */
+struct TPLMMarker
+ {
+ /**
+ * Constructor
+ * @since 2.6
+ */
+ TPLMMarker();
+
+ /**
+ * Destructor
+ * @since 2.6
+ */
+ ~TPLMMarker();
+
+ TUint8 iZplm;
+ TUint8 iNplm;
+ HBufC8 *iIplm;
+ };
+
+/**
+ * struct TPPTMarker
+ * Packed packet headers, tile-part header (PPT)
+ * @since 2.6
+ */
+struct TPPTMarker
+ {
+
+ /**
+ * Constructor
+ * @since 2.6
+ */
+ TPPTMarker();
+
+ /**
+ * Destructor
+ * @since 2.6
+ */
+ ~TPPTMarker();
+
+ TUint8 iZppt;
+ HBufC8 *iIppt;
+ };
+
+/**
+ * struct TPLTMarker
+ * Packet length, tile-part header (PLT)
+ * @since 2.6
+ */
+struct TPLTMarker
+ {
+
+ /**
+ * Constructor
+ * @since 2.6
+ */
+ TPLTMarker();
+
+ /**
+ * Destructor
+ * @since 2.6
+ */
+ ~TPLTMarker();
+
+ TUint8 iZplt;
+ RArray<TUint> iIplt;
+ };
+
+/**
+ * struct TCRGMarker
+ * Component registration (CRG)
+ * @since 2.6
+ */
+struct TCRGMarker
+ {
+
+ /**
+ * Constructor
+ * @since 2.6
+ */
+ TCRGMarker();
+
+ /**
+ * Destructor
+ * @since 2.6
+ */
+ ~TCRGMarker();
+
+ RArray<TPoint> iXYcrg;
+ };
+
+/**
+ * struct TCOMMarker
+ * Comment (COM)
+ * @since 2.6
+ */
+struct TCOMMarker
+ {
+
+ /**
+ * Constructor
+ * @since 2.6
+ */
+ TCOMMarker();
+ /**
+ * Destructor
+ * @since 2.6
+ */
+ ~TCOMMarker();
+
+ TUint16 iRemainder;
+ TUint16 iRcom;
+ HBufC8 *iCcom;
+ };
+
+/**
+ * struct TMainMarker
+ * Main header
+ * @since 2.6
+ */
+struct TMainMarker
+ {
+
+ /**
+ * Constructor
+ * @since 2.6
+ */
+ TMainMarker();
+
+ /**
+ * Destructor
+ * @since 2.6
+ */
+ ~TMainMarker();
+
+ TCODMarker iCod;
+ TQCDMarker iQcd;
+ RPointerArray<TCOCMarker> iCoc;
+ RPointerArray<TQCCMarker> iQcc;
+ RPointerArray<TRGNMarker> iRgn;
+ TPOCMarker *iPoc;
+ RPointerArray<TPPMMarker> iPpm;
+ RPointerArray<TTLMMarker> iTlm;
+ RPointerArray<TPLMMarker> iPlm;
+ TCRGMarker *iCrg;
+ RPointerArray<TCOMMarker> iCom;
+ };
+
+/**
+ * struct TTileMarker
+ * Tile-part header
+ * @since 2.6
+ */
+struct TTileMarker
+ {
+ /**
+ * Constructor
+ * @since 2.6
+ */
+ TTileMarker();
+
+ /**
+ * Destructor
+ * @since 2.6
+ */
+ ~TTileMarker();
+
+ TCODMarker *iCod;
+ TQCDMarker *iQcd;
+ RPointerArray<TCOCMarker> iCoc;
+ RPointerArray<TQCCMarker> iQcc;
+ RPointerArray<TRGNMarker> iRgn;
+ TPOCMarker *iPoc;
+ RPointerArray<TPPTMarker> iPpt;
+ RPointerArray<TPLTMarker> iPlt;
+ RPointerArray<TCOMMarker> iCom;
+ };
+
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// CLASS DECLARATION
+
+/**
+ * MJ2kPacketHeaderReader defines the interface
+ * for reading the packet header from streams.
+ * @since 2.6
+ */
+class MJ2kPacketHeaderReader
+ {
+ public: // Constructors and destructor
+
+ public: // New functions
+
+ /**
+ * Try to consume the EPH marker if there is one
+ * @since 2.6
+ * @return TUint8: true if end of buffer.
+ */
+ virtual TUint8 ReadEPHMarker() = 0;
+
+ /**
+ * Read a bit from the packet header stream
+ * @since 2.6
+ * @param aBit: get a bit from the packet header bitstream.
+ * @return TUint8: true if end of buffer.
+ */
+ virtual TUint8 ReadBit( TUint8& aBit ) = 0;
+
+ /**
+ * Read some bits from the packet header stream
+ * @since 2.6
+ * @param aBit: get some bits from the packet header bitstream.
+ * @param aBitLen: how many bits to read.
+ * @return TUint8: true if end of buffer.
+ */
+ virtual TUint8 ReadBits( TUint8& aBit, TUint8 aBitLen ) = 0;
+
+ /**
+ * Read some bits from the packet header stream
+ * @since 2.6
+ * @param aBit: get some bits from the packet header bitstream.
+ * @param aBitLen: how many bits to read.
+ * @return TUint8: true if end of buffer.
+ */
+ virtual TUint8 ReadBits( TUint32& aBit, TUint8 aBitLen ) = 0;
+
+ /**
+ * Start reading from packet header stream
+ * @since 2.6
+ * @return TUint8: true if end of buffer.
+ */
+ virtual TUint8 StartReadBit() = 0;
+
+ /**
+ * Align the stream to the next byte boundary if necessary
+ * @since 2.6
+ */
+ virtual void AlignReader() = 0;
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private:
+
+ public: // Data
+
+ protected: // Data
+
+ private: // Data
+
+ public: // Friend classes
+
+ protected: // Friend classes
+
+ private: // Friend classes
+
+ };
+
+#endif // __JP2KMARKER_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KPacket.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,602 @@
+/*
+* Copyright (c) 2003, 2004 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: JP2KPacket class used to collect packet related
+* information such as tag tree and list of codeblocks.
+*
+*/
+
+
+#ifndef __JP2KPACKET_H__
+#define __JP2KPACKET_H__
+
+// INCLUDES
+#include <e32base.h>
+#include "JP2KEntropyDecoder.h"
+
+// CONSTANTS
+
+// MACROS
+
+// DATA TYPES
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+class CJ2kSubband;
+class CJ2kTileInfo;
+class CJ2kComponentInfo;
+class CJ2kCodeBlock;
+
+// CLASS DECLARATION
+
+/**
+ * JP2KPacket class used to collect packet related
+ * information such as tag tree, list of codeblocks,
+ * and data used to control where to resume the parsing
+ * of the bitstream.
+ *
+ * JP2KCodec.dll
+ * @since 2.6
+ */
+class CJ2kPacket : public CBase
+{
+ public: // Constructors and destructor
+
+ /**
+ * C++ default constructor.
+ */
+ CJ2kPacket( TUint16 aLayer );
+
+ /**
+ * Destructor.
+ */
+ virtual ~CJ2kPacket();
+
+ public: // New functions
+
+ /**
+ * Set the canvas of the packet
+ * @since 2.6
+ * @param aX: the x position.
+ * @param aY: the y position.
+ * @param aWidth the width.
+ * @param aHeight: the height.
+ */
+ void SetPacketCanvas( TInt32 aX, TInt32 aY, TInt32 aWidth, TInt32 aHeight );
+
+ /**
+ * Set the number of blocks
+ * @since 2.6
+ * @param aCodeBlock: the size of the codeblock.
+ */
+ void SetNumOfBlocks( TSize& aCodeBlock );
+
+ /**
+ * Build the inclusive informaiton of the packet
+ * @since 2.6
+ */
+ void BuildInclusiveInfoL();
+
+ /**
+ * Build the codeblocks in the packet
+ * @since 2.6
+ * @param aX: the x position.
+ * @param aY: the y position.
+ * @param aCodeBlock: the size of the codeblock.
+ */
+ void BuildCodeBlocksL( TInt32 aX, TInt32 aY, TSize& aCodeBlock );
+
+ /**
+ * Read the packet header
+ * @since 2.6
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @param aComponent: a reference to CJ2kComponentInfo object.
+ * @param aSubband: a reference to CJ2kSubband object.
+ * @return TUint8: true if incomplete.
+ */
+ TUint8 ReadPacketHeaderL( CJ2kTileInfo& aTile, CJ2kComponentInfo& aComponent, CJ2kSubband& aSubband );
+
+ /**
+ * Read the packet body
+ * @since 2.6
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @param aComponent: a reference to CJ2kComponentInfo object.
+ * @param aSubband: a reference to CJ2kSubband object.
+ * @return TUint8: true if incomplete.
+ */
+ TUint8 ReadPacketBodyL( CJ2kTileInfo& aTile, CJ2kComponentInfo& aComponent, CJ2kSubband& aSubband );
+
+ /**
+ * Reset the internal flags
+ * @since 2.6
+ */
+ void ResetInternalFlags();
+
+ /**
+ * Get the last codeblock processed
+ * @since 2.6
+ * @return TUint16: the last codeblock processed.
+ */
+ TUint16 LastCodeBlockProcessed() const;
+
+ /**
+ * Set the last codeblock processed
+ * @since 2.6
+ * @param aLastCodeBlock: the last codeblock processed.
+ */
+ void SetLastCodeBlockProcessed( TUint16 aLastCodeBlock );
+
+ /**
+ * Get number of blocks
+ * @since 2.6
+ * @return TUint16: number of codeblocks.
+ */
+ TUint16 NumOfBlocks() const;
+
+ /**
+ * Get number of blocks in horizontal direction
+ * @since 2.6
+ * @return TUint16: number of codeblock in X direction.
+ */
+ TUint16 NumOfBlocksX() const;
+
+ /**
+ * Get number of blocks in vertical direction
+ * @since 2.6
+ * @return TUint16: number of codeblock in Y direction.
+ */
+ TUint16 NumOfBlocksY() const;
+
+ /**
+ * Get the canvas of the packet
+ * @since 2.6
+ * @return TRect&: a reference to the packet's canvas.
+ */
+ const CJ2kCodeBlock& CodeBlockAt( TUint16 aIndex ) const;
+
+ /**
+ * Is packet body read underflow
+ * @since 2.6
+ * @return TUint8: true if packet body incomplete.
+ */
+ TUint8 IsBodyIncomplete() const;
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private:
+
+ /**
+ * Build the tag trees
+ * @since 2.6
+ */
+ void BuildTagtreeL();
+
+ /**
+ * Decode the included tag tree
+ * @since 2.6
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @param aWidth: the width.
+ * @param aHeight: the height.
+ * @param aValue: a reference to the TUint16.
+ * @return TUint8: true if incomplete.
+ */
+ TUint8 DecodeIncTagtree( CJ2kTileInfo& aTile, TUint32 aWidth, TUint32 aHeight, TUint16& aValue );
+
+ /**
+ * Decode the msb tag tree
+ * @since 2.6
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @param aWidth: the width.
+ * @param aHeight: the height.
+ * @param aValue: a reference to the TUint16.
+ * @return TUint8: true if incomplete.
+ */
+ TUint8 DecodeMsbTagtree( CJ2kTileInfo& aTile, TUint32 aWidth, TUint32 aHeight, TUint16& aValue );
+
+ /**
+ * Backup the included tag tree
+ * @since 2.6
+ * @param aTagValue: a reference to the value descriptor pointer.
+ * @param aTagState: a reference to the state descriptor pointer.
+ */
+ void BackupIncTagtreeL( HBufC16*& aTagValue, HBufC16*& aTagState );
+
+ /**
+ * Backup the msb tag tree
+ * @since 2.6
+ * @param aTagValue: a reference to the value descriptor pointer.
+ * @param aTagState: a reference to the state descriptor pointer.
+ */
+ void BackupMsbTagtreeL( HBufC16*& aTagValue, HBufC16*& aTagState );
+
+ /**
+ * Restore the included tag tree
+ * @since 2.6
+ * @param aTagValue: a pointer to the value descriptor.
+ * @param aTagState: a pointer to the state descriptor.
+ */
+ void RestoreIncTagtree( HBufC16 *aTagValue, HBufC16 *aTagState );
+
+ /**
+ * Restore the msb tag tree
+ * @since 2.6
+ * @param a
+ * @param aTagValue: a pointer to the value descriptor.
+ * @param aTagState: a pointer to the state descriptor.
+ */
+ void RestoreMsbTagtree( HBufC16 *aTagValue, HBufC16 *aTagState );
+
+ /**
+ * Release the temporary backup memory
+ * @since 2.6
+ * @param aTagValue: a reference to the include value descriptor pointer.
+ * @param aTagState: a reference to the include state descriptor pointer.
+ * @param aTagValue: a reference to the msb value descriptor pointer.
+ * @param aTagState: a reference to the msb state descriptor pointer.
+ */
+ void FreeBackupTagtree( HBufC16*& aIncTagValue, HBufC16*& aIncTagState,
+ HBufC16*& aMsbTagValue, HBufC16*& aMsbTagState );
+
+ /**
+ * Is the layer has been included in the previous packet
+ * @since 2.6
+ * @param aLayer: the layer
+ * @return TUint8: true if layer has been included.
+ */
+ TUint8 IsIncludedL( TUint16 aLayer );
+
+ /**
+ * Get the inclusive information at specific layer
+ * @since 2.6
+ * @param aLayer: the layer.
+ * @return TUint8: inclusive information.
+ */
+ TUint8 IncludedAt( TUint16 aLayer ) const;
+
+ /**
+ * Set the inclusive information at specific layer
+ * @since 2.6
+ * @param aLayer: the layer.
+ */
+ void SetIncluded( TUint16 aLayer );
+
+ /**
+ * Is tag tree backup is required for underflow recovery
+ * @since 2.6
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @return TUint8: true if backup is needed.
+ */
+ TUint8 IsBackupNeeded( CJ2kTileInfo& aTile );
+
+ /**
+ * Start reading from packet header stream
+ * @since 2.6
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 StartReadBit( CJ2kTileInfo& aTile );
+
+ /**
+ * Read a bit from the packet header stream
+ * @since 2.6
+ * @param aBit: get a bit from the packet header bitstream.
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 ReadBit( TUint8& aBit, CJ2kTileInfo& aTile );
+
+ /**
+ * Read some bits from the packet header stream
+ * @since 2.6
+ * @param aBit: get some bits from the packet header bitstream.
+ * @param aBitLen: how many bits to read.
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 ReadBits( TUint8& aBit, TUint8 aBitLen, CJ2kTileInfo& aTile );
+
+ /**
+ * Read some bits from the packet header stream
+ * @since 2.6
+ * @param aBit: get some bits from the packet header bitstream.
+ * @param aBitLen: how many bits to read.
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 ReadBits( TUint32& aBit, TUint8 aBitLen, CJ2kTileInfo& aTile );
+
+ /**
+ * Align the stream to the next byte boundary if necessary
+ * @since 2.6
+ * @param aTile: a reference to CJ2kTileInfo object.
+ */
+ void AlignReader( CJ2kTileInfo& aTile );
+
+ /**
+ * Try to consume the SOP marker if there is one
+ * @since 2.6
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 ReadSOPMarker( CJ2kTileInfo& aTile );
+
+ /**
+ * Try to consume the EPH marker if there is one
+ * @since 2.6
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 ReadEPHMarker( CJ2kTileInfo& aTile );
+
+ /**
+ * Try to re-align stream to next byte boundary if necessary,
+ * Try to consume the previous leftover EPH marker if there is one,
+ * Try to consume the SOP marker if there is one
+ * @since 2.6
+ * @param aComponent: a reference to CJ2kComponentInfo object.
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @param aSOP: true if to try SOP marker.
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 ReadSOP_EPHMarker( CJ2kComponentInfo& aComponent, CJ2kTileInfo& aTile, TBool aSOP = ETrue );
+
+ /**
+ * Get the included tag tree value at specific level and width
+ * @since 2.6
+ * @param aLevel: the layer.
+ * @param aWidth: the width.
+ * @return TUint16: the include tag value.
+ */
+ TUint16 IncTagValue( TUint16 aLevel, TUint16 aWidth ) const;
+
+ /**
+ * Get the included tag tree state at specific level and width
+ * @since 2.6
+ * @param aLevel: the layer.
+ * @param aWidth: the width.
+ * @return TUint16: the include tag state.
+ */
+ TUint16 IncTagState( TUint16 aLevel, TUint16 aWidth ) const;
+
+ /**
+ * Get the msb tag tree value at specific level and width
+ * @since 2.6
+ * @param aLevel: the layer.
+ * @param aWidth: the width.
+ * @return TUint16: the msb tag value.
+ */
+ TUint16 MsbTagValue( TUint16 aLevel, TUint16 aWidth ) const;
+
+ /**
+ * Get the msb tag tree state at specific level and width
+ * @since 2.6
+ * @param aLevel: the layer.
+ * @param aWidth: the width.
+ * @return TUint16: the msb tag state.
+ */
+ TUint16 MsbTagState( TUint16 aLevel, TUint16 aWidth ) const;
+
+ /**
+ * Set the included tag tree value at specific level and width
+ * @since 2.6
+ * @param aLevel: the layer.
+ * @param aWidth: the width.
+ * @param aValue: the value.
+ */
+ void SetIncTagValue( TUint16 aLevel, TUint16 aWidth, TUint16 aValue );
+
+ /**
+ * Set the included tag tree state at specific level and width
+ * @since 2.6
+ * @param aLevel: the layer.
+ * @param aWidth: the width.
+ * @param aState: the state.
+ */
+ void SetIncTagState( TUint16 aLevel, TUint16 aWidth, TUint16 aState );
+
+ /**
+ * Increment the included tag tree state at specific level and width
+ * @since 2.6
+ * @param aLevel: the layer.
+ * @param aWidth: the width.
+ */
+ void IncrementIncTagState( TUint16 aLevel, TUint16 aWidth );
+
+ /**
+ * Set the msb tag tree value at specific level and width
+ * @since 2.6
+ * @param aLevel: the layer.
+ * @param aWidth: the width.
+ * @param aValue: the value.
+ */
+ void SetMsbTagValue( TUint16 aLevel, TUint16 aWidth, TUint16 aValue );
+
+ /**
+ * Set the msb tag tree state at specific level and width
+ * @since 2.6
+ * @param aLevel: the layer.
+ * @param aWidth: the width.
+ * @param aState: the state.
+ */
+ void SetMsbTagState( TUint16 aLevel, TUint16 aWidth, TUint16 aState );
+
+ /**
+ * Increment the msb tag tree state at specific level and width
+ * @since 2.6
+ * @param aLevel: the layer.
+ * @param aWidth: the width.
+ */
+ void IncrementMsbTagState( TUint16 aLevel, TUint16 aWidth );
+
+ /**
+ * Is packet header has been read
+ * @since 2.6
+ * @return TUint8: true if packet header has been read.
+ */
+ TUint8 IsHeader() const;
+
+ /**
+ * Set the flag to indicate that packet header has been read
+ * @since 2.6
+ */
+ void SetHeader();
+
+ /**
+ * Reset the flag to indicate that packet header has not been read
+ * @since 2.6
+ */
+ void ResetHeader();
+
+ /**
+ * Is packet body has been read
+ * @since 2.6
+ * @return TUint8: true if packet body has been read.
+ */
+ TUint8 IsBody() const;
+
+ /**
+ * Set the flag to indicate that packet body has been read
+ * @since 2.6
+ */
+ void SetBody();
+
+ /**
+ * Reset the flag to indicate that packet body has not been read
+ * @since 2.6
+ */
+ void ResetBody();
+
+ /**
+ * Set the flag to indicate that packet body read underflow
+ * @since 2.6
+ */
+ void SetBodyIncomplete();
+
+ /**
+ * Reset the flag to indicate that packet body read is not underflow
+ * @since 2.6
+ */
+ void ResetBodyIncomplete();
+
+ /**
+ * Is the read recover from previous underflow
+ * @since 2.6
+ * @return TUint8: true if recover from previous underflow.
+ */
+ TUint8 IsRecoverFromIncomplete() const;
+
+ /**
+ * Set the flag to indicate that the next read is recover from underflow
+ * @since 2.6
+ */
+ void SetRecoverFromIncomplete();
+
+ /**
+ * Reset the flag to indicate that the next read is not recover from underflow
+ * @since 2.6
+ */
+ void ResetRecoverFromIncomplete();
+
+ /**
+ * Is codeblock number should iLastCodeBlock
+ * @since 2.6
+ * @return TUint8: true if codeblock number should match with iLastCodeBlock.
+ */
+ TUint8 IsMatch() const;
+
+ /**
+ * Set the flag to indicate that the next codeblock should match iLastCodeBlock
+ * @since 2.6
+ */
+ void ResetMatch();
+
+ /**
+ * Reset the flag to indicate that the next codeblock should be greater than
+ * iLastCodeBlock
+ * @since 2.6
+ */
+ void SetMatch();
+
+ public: // Data
+
+ protected: // Data
+
+ private: // Data
+
+ // Flags to control the parsing of bitstream
+ enum TReadPacket
+ {
+ EReadHeader = 0x01,
+ EReadBody = 0x02,
+ EReadBodyIncomplete = 0x04,
+ EReadRecoverFromIncomplete = 0x08,
+ EReadMatchLastCodeBlock = 0x10
+ };
+
+ // Canvas of the packet
+ TRect iPacketCanvas;
+
+ // Codeblock size
+ TSize iCodeBlockSize;
+
+ // Tag tree level
+ TUint8 iTagTreeLevel;
+
+ // Control flags
+ TUint8 iReadControl;
+
+ // Inclusive layer number
+ TUint16 iLayer;
+
+ // Last codeblock processed
+ TUint16 iLastCodeBlock;
+
+ // Inclusive information
+ HBufC8 *iIncluded;
+
+ // Tagtree information
+ HBufC16 *iTagTreeInfo;
+
+ // Included tag tree value
+ HBufC16 *iIncTagTreeValue;
+
+ // Included tag tree state
+ HBufC16 *iIncTagTreeState;
+
+ // MSB tag tree value
+ HBufC16 *iMsbTagTreeValue;
+
+ // MSB tag tree state
+ HBufC16 *iMsbTagTreeState;
+
+ // List of codeblocks
+ RPointerArray<CJ2kCodeBlock> iCodeBlockList;
+
+ public: // Friend classes
+
+ protected: // Friend classes
+
+ private: // Friend classes
+
+ };
+
+// For inliners.
+#include "JP2KPacket.inl"
+
+#endif // __JP2KPACKET_H__
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KPacket.inl Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,374 @@
+/*
+* Copyright (c) 2003, 2004 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: JP2KPacket class used to collect packet related
+* information such as tag tree and list of codeblocks.
+*
+*/
+
+
+#ifndef __JP2KPACKET_INL__
+#define __JP2KPACKET_INL__
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::LastCodeBlockProcessed
+// Get the last codeblock processed
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint16 CJ2kPacket::LastCodeBlockProcessed() const
+ {
+ return iLastCodeBlock;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::SetLastCodeBlockProcessed
+// Set the last codeblock processed
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kPacket::SetLastCodeBlockProcessed( TUint16 aLastCodeBlock )
+ {
+ iLastCodeBlock = aLastCodeBlock;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::NumOfBlocks
+// Get number of blocks
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint16 CJ2kPacket::NumOfBlocks() const
+ {
+ return (TUint16)( iCodeBlockSize.iWidth * iCodeBlockSize.iHeight );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::NumOfBlocksX
+// Get number of blocks in horizontal direction
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint16 CJ2kPacket::NumOfBlocksX() const
+ {
+ return (TUint16)iCodeBlockSize.iWidth;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::NumOfBlocksY
+// Get number of blocks in vertical direction
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint16 CJ2kPacket::NumOfBlocksY() const
+ {
+ return (TUint16)iCodeBlockSize.iHeight;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::CodeBlockAt
+// Get the codeblock at specific location
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline const CJ2kCodeBlock& CJ2kPacket::CodeBlockAt( TUint16 aIndex ) const
+ {
+ return *iCodeBlockList[aIndex];
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::IsBodyIncomplete
+// Is packet body read underflow
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kPacket::IsBodyIncomplete() const
+ {
+ return (TUint8)( iReadControl & EReadBodyIncomplete );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::IncTagValue
+// Get the included tag tree value at specific level and width
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint16 CJ2kPacket::IncTagValue( TUint16 aLevel, TUint16 aWidth ) const
+ {
+ return ( iIncTagTreeValue->Des() )[( iTagTreeInfo->Des() )[aLevel] + aWidth];
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::IncTagState
+// Get the included tag tree state at specific level and width
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint16 CJ2kPacket::IncTagState( TUint16 aLevel, TUint16 aWidth ) const
+ {
+ return ( iIncTagTreeState->Des() )[( iTagTreeInfo->Des() )[aLevel] + aWidth];
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::MsbTagValue
+// Get the msb tag tree value at specific level and width
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint16 CJ2kPacket::MsbTagValue( TUint16 aLevel, TUint16 aWidth ) const
+ {
+ return ( iMsbTagTreeValue->Des() )[( iTagTreeInfo->Des() )[aLevel] + aWidth];
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::MsbTagState
+// Get the msb tag tree state at specific level and width
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint16 CJ2kPacket::MsbTagState( TUint16 aLevel, TUint16 aWidth ) const
+ {
+ return ( iMsbTagTreeState->Des() )[( iTagTreeInfo->Des() )[aLevel] + aWidth];
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::SetIncTagValue
+// Set the included tag tree value at specific level and width
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kPacket::SetIncTagValue( TUint16 aLevel, TUint16 aWidth, TUint16 aValue )
+ {
+ TPtr16 tmpPtr = ( iIncTagTreeValue->Des() );
+ tmpPtr[( iTagTreeInfo->Des() )[aLevel] + aWidth] = aValue;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::SetIncTagState
+// Set the included tag tree state at specific level and width
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kPacket::SetIncTagState( TUint16 aLevel, TUint16 aWidth, TUint16 aState )
+ {
+ TPtr16 tmpPtr = ( iIncTagTreeState->Des() );
+ tmpPtr[( iTagTreeInfo->Des() )[aLevel] + aWidth] = aState;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::IncrementIncTagState
+// Increment the included tag tree state at specific level and width
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kPacket::IncrementIncTagState( TUint16 aLevel, TUint16 aWidth )
+ {
+ TPtr16 tmpPtr = ( iIncTagTreeState->Des() );
+ tmpPtr[( iTagTreeInfo->Des() )[aLevel] + aWidth]++;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::SetMsbTagValue
+// Set the msb tag tree value at specific level and width
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kPacket::SetMsbTagValue( TUint16 aLevel, TUint16 aWidth, TUint16 aValue )
+ {
+ TPtr16 tmpPtr = ( iMsbTagTreeValue->Des() );
+ tmpPtr[( iTagTreeInfo->Des() )[aLevel] + aWidth] = aValue;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::SetMsbTagState
+// Set the msb tag tree state at specific level and width
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kPacket::SetMsbTagState( TUint16 aLevel, TUint16 aWidth, TUint16 aState )
+ {
+ TPtr16 tmpPtr = ( iMsbTagTreeState->Des() );
+ tmpPtr[( iTagTreeInfo->Des() )[aLevel] + aWidth] = aState;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::IncrementMsbTagState
+// Increment the msb tag tree state at specific level and width
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kPacket::IncrementMsbTagState( TUint16 aLevel, TUint16 aWidth )
+ {
+ TPtr16 tmpPtr = ( iMsbTagTreeState->Des() );
+ tmpPtr[( iTagTreeInfo->Des() )[aLevel] + aWidth]++;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::IsHeader
+// Is packet header has been read
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kPacket::IsHeader() const
+ {
+ return (TUint8)( iReadControl & EReadHeader );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::SetHeader
+// Set the flag to indicate that packet header has been read
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kPacket::SetHeader()
+ {
+ iReadControl |= EReadHeader;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ResetHeader
+// Reset the flag to indicate that packet header has not been read
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kPacket::ResetHeader()
+ {
+ iReadControl &= ~EReadHeader;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::IsBody
+// Is packet body has been read
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kPacket::IsBody() const
+ {
+ return (TUint8)( iReadControl & EReadBody );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::SetBody
+// Set the flag to indicate that packet body has been read
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kPacket::SetBody()
+ {
+ iReadControl |= EReadBody;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ResetBody
+// Reset the flag to indicate that packet body has not been read
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kPacket::ResetBody()
+ {
+ iReadControl &= ~EReadBody;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::SetBodyIncomplete
+// Set the flag to indicate that packet body read underflow
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kPacket::SetBodyIncomplete()
+ {
+ iReadControl |= EReadBodyIncomplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ResetBodyIncomplete
+// Reset the flag to indicate that packet body read is not underflow
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kPacket::ResetBodyIncomplete()
+ {
+ iReadControl &= ~EReadBodyIncomplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::IsRecoverFromIncomplete
+// Is the read recover from previous underflow
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kPacket::IsRecoverFromIncomplete() const
+ {
+ return (TUint8)( iReadControl & EReadRecoverFromIncomplete );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::SetRecoverFromIncomplete
+// Set the flag to indicate that the next read is recover from underflow
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kPacket::SetRecoverFromIncomplete()
+ {
+ iReadControl |= EReadRecoverFromIncomplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ResetRecoverFromIncomplete
+// Reset the flag to indicate that the next read is not recover from underflow
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kPacket::ResetRecoverFromIncomplete()
+ {
+ iReadControl &= ~EReadRecoverFromIncomplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::IsMatch
+// Is codeblock number should iLastCodeBlock
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kPacket::IsMatch() const
+ {
+ return (TUint8)( iReadControl & EReadMatchLastCodeBlock );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ResetMatch
+// Reset the flag to indicate that the next codeblock should be greater than
+// iLastCodeBlock
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kPacket::ResetMatch()
+ {
+ iReadControl &= ~EReadMatchLastCodeBlock;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::SetMatch
+// Set the flag to indicate that the next codeblock should match iLastCodeBlock
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kPacket::SetMatch()
+ {
+ iReadControl |= EReadMatchLastCodeBlock;
+ }
+
+#endif // __JP2KPACKET_INL__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KStreamReader.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,206 @@
+/*
+* Copyright (c) 2003, 2004 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: TJ2kStreamReader class is to implement the
+* MJ2kPacketHeaderReader interface for reading the
+* packet header and packet body from the stream
+* buffer provided by ICL framework.
+*
+*/
+
+
+#ifndef __JP2KSTREAMREADER_H__
+#define __JP2KSTREAMREADER_H__
+
+// INCLUDES
+#include <e32base.h>
+#include "JP2KMarker.h"
+
+// CONSTANTS
+
+// MACROS
+
+// DATA TYPES
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// CLASS DECLARATION
+
+/**
+* TJ2kStreamReader class is to implement the
+* MJ2kPacketHeaderReader interface for reading the
+* packet header and packet body from the stream
+* buffer provided by ICL framework.
+*
+* JP2KCodec.dll
+* @since 2.6
+*/
+class TJ2kStreamReader : public MJ2kPacketHeaderReader
+ {
+ public: // Constructors and destructor
+
+ public: // New functions
+
+ /**
+ * Update the codestream length read and offset of SOT marker
+ * @since 2.6
+ */
+ void UpdateMainHeader();
+
+ /**
+ * Update the codestream length read and length of data consumed
+ * @since 2.6
+ */
+ void UpdateTileHeader();
+
+ /**
+ * From MJ2kPacketHeaderReader
+ * Try to consume the EPH marker if there is one
+ * @since 2.6
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 ReadEPHMarker();
+
+ /**
+ * From MJ2kPacketHeaderReader
+ * Read a bit from the packet header stream
+ * @since 2.6
+ * @param aBit: get a bit from the packet header bitstream.
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 ReadBit( TUint8& aBit );
+
+ /**
+ * From MJ2kPacketHeaderReader
+ * Read some bits from the packet header stream
+ * @since 2.6
+ * @param aBit: get some bits from the packet header bitstream.
+ * @param aBitLen: how many bits to read.
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 ReadBits( TUint8& aBit, TUint8 aBitLen );
+
+ /**
+ * From MJ2kPacketHeaderReader
+ * Read some bits from the packet header stream
+ * @since 2.6
+ * @param aBit: get some bits from the packet header bitstream.
+ * @param aBitLen: how many bits to read.
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 ReadBits( TUint32& aBit, TUint8 aBitLen );
+
+ /**
+ * From MJ2kPacketHeaderReader
+ * Start reading from packet header stream
+ * @since 2.6
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 StartReadBit();
+
+ /**
+ * From MJ2kPacketHeaderReader
+ * Align the stream to the next byte boundary if necessary
+ * @since 2.6
+ */
+ void AlignReader();
+
+ /**
+ * Try to consume the SOP marker if there is one
+ * @since 2.6
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 ReadSOPMarker();
+
+ /**
+ * Try to consume the EPH marker after failure on previous try
+ * @since 2.6
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 TryReadEPHMarker();
+
+ /**
+ * Try to align to byte boundary after failure on previous try
+ * @since 2.6
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 TryReAlignReader();
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private:
+
+ public: // Data
+
+ // Iterator pointed to current position in the buffer
+ const TUint8 *iPtr;
+
+ // Iterator pointed to the start of buffer
+ TUint8 *iPtrStart;
+
+ // Iterator pointed to the end of buffer
+ TUint8 *iPtrEnd;
+
+ // Iterator pointed to the start of marker
+ TUint8 *iPtrStartMarker;
+
+ // Data consumed during decoding
+ TUint32 iDataUsed;
+
+ // Length of codestream left to be read
+ TUint32 iCSLength;
+
+ // Offset position of first SOT
+ TUint32 iStartSOT;
+
+ // Offset position of next tile to be processed
+ TUint32 iNewDataStart;
+
+ // Length of data to skip
+ TUint32 iSkipLength;
+
+ // Current data in 8 bits
+ TUint8 iData;
+
+ // Current bit position
+ TUint8 iPos;
+
+ // Bit position of next byte
+ TUint8 iNextPos;
+
+ // To indicate byte alignment is required
+ TUint8 iAlign;
+
+ // To indicate EPH marker should be tried
+ TUint8 iTryEPHMarker;
+
+ protected: // Data
+
+ private: // Data
+
+ public: // Friend classes
+
+ protected: // Friend classes
+
+ private: // Friend classes
+
+ };
+
+#endif // __JP2KSTREAMREADER_H__
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KSubband.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,460 @@
+/*
+* Copyright (c) 2003, 2004 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: JP2KSubband class used to collect the subband related
+* information such as list of packets and list of subbands.
+*
+*/
+
+
+#ifndef __JP2KSUBBAND_H__
+#define __JP2KSUBBAND_H__
+
+// INCLUDES
+#include <e32base.h>
+
+// CONSTANTS
+
+// MACROS
+
+// DATA TYPES
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+class CJ2kPacket;
+class CJ2kTileInfo;
+class CJ2kComponentInfo;
+
+// CLASS DECLARATION
+
+/**
+* JP2KSubband class used to collect the subband related
+* information such as list of packets, list of subbands
+* if it is EBandLL, and etc. It contains the data to control
+* where to resume the parsing of the bitstream. It is
+* implemented in Composite pattern.
+*
+* JP2KCodec.dll
+* @since 2.6
+*/
+class CJ2kSubband : public CBase
+ {
+ public: // Constructors and destructor
+
+ /**
+ * Destructor.
+ */
+ virtual ~CJ2kSubband();
+
+ public: // New functions
+
+ // Subband type
+ enum TSubbandType
+ {
+ EBandLL, // LL subband, which may further subdivided into subband
+ EBandHL, // HL Subband
+ EBandLH, // LH Subband
+ EBandHH // HH Subband
+ };
+
+ /**
+ * Static method to set up the tree structure of the DWT subbands
+ * @since 2.6
+ * @param aMaxLevel: maximum level of DWT subbands.
+ * @param aComponent: a reference to CJ2kComponentInfo object.
+ * @return CJ2kSubband*: pointer to root CJ2kSubband object.
+ */
+ static CJ2kSubband* BuildSubbandTreeL( TUint8 aMaxLevel, CJ2kComponentInfo& aComponent );
+
+ /**
+ * Build the possible packets that may be in the subband
+ * @since 2.6
+ * @param aComponent: a reference to CJ2kComponentInfo object.
+ * @param aPrecinctSize: a pointer to descriptor of precinct size.
+ * @param aLayer: the layer.
+ */
+ void BuildPacketsL( CJ2kComponentInfo& aComponent, HBufC8 *aPrecinctSiz, TUint16 aLayer );
+
+ /**
+ * At each subband, parse the bitstream with LRCP progression order
+ * @since 2.6
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @param aComponent: a reference to CJ2kComponentInfo object.
+ * @return TUint8: true if incomplete, false if completed.
+ */
+ TUint8 LRCPProgressionL( CJ2kTileInfo& aTile, CJ2kComponentInfo& aComponent );
+
+ /**
+ * At each subband, parse the bitstream with RPCL progression order
+ * @since 2.6
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @param aComponent: a reference to CJ2kComponentInfo object.
+ * @return TUint8: true if incomplete, false if completed.
+ */
+ TUint8 RPCLProgressionL( CJ2kTileInfo& aTile, CJ2kComponentInfo& aComponent );
+
+ /**
+ * At each subband, parse the bitstream with CPRL progression order
+ * @since 2.6
+ * @param aTile: a reference to CJ2kTileInfo object.
+ * @param aComponent: a reference to CJ2kComponentInfo object.
+ * @return TUint8: true if incomplete, false if completed.
+ */
+ TUint8 CPRLProgressionL( CJ2kTileInfo& aTile, CJ2kComponentInfo& aComponent );
+
+ /**
+ * Get the child subband at specific band
+ * @since 2.6
+ * @param aBand: the band index.
+ * @return CJ2kSubband*: the child at specific band.
+ */
+ virtual CJ2kSubband* ChildAt( TInt aBand );
+
+ /**
+ * Get the sibling subband
+ * @since 2.6
+ * @return CJ2kSubband*: pointer to the sibling subband.
+ */
+ virtual CJ2kSubband* NextSubbandRaster();
+
+ /**
+ * Get the subband at specific resolution level
+ * @since 2.6
+ * @param aResLevel: the resolution level.
+ * @return CJ2kSubband*: pointer to the subband at specific resolution level.
+ */
+ virtual CJ2kSubband* SubbandAt( TUint8 aResLevel );
+
+ /**
+ * Add the child subband into the list of child subbands
+ * @since 2.6
+ * @param aChild: add the child subband.
+ */
+ virtual void AddChildL( CJ2kSubband* aChild );
+
+ /**
+ * Get the subband tree index
+ * @since 2.6
+ * @return TUint16: the subband tree index.
+ */
+ TUint16 SubbandTreeIndex() const;
+
+ /**
+ * Get the parent subband of the current subband
+ * @since 2.6
+ * @return CJ2kSubband*: a pointer to the parent.
+ */
+ CJ2kSubband* Parent();
+
+ /**
+ * Set the parent subband of the current subband
+ * @since 2.6
+ * @param aParent: the parent of current subband.
+ */
+ void SetParent(CJ2kSubband* aParent);
+
+ /**
+ * Set the subband level
+ * @since 2.6
+ * @param aLevel: the level.
+ */
+ void SetSubbandLevel( TUint8 aLevel );
+
+ /**
+ * Get the subband type
+ * @since 2.6
+ * @return CJ2kSubband::TSubbandType: the subband's type.
+ */
+ CJ2kSubband::TSubbandType SubbandType() const;
+
+ /**
+ * Get the subband level
+ * @since 2.6
+ * @return TUint8: the subband's level.
+ */
+ TUint8 SubbandLevel() const;
+
+ /**
+ * Get the subband resolution level
+ * @since 2.6
+ * @return TUint8: the subband's resolution level.
+ */
+ TUint8 SubbandResLevel() const;
+
+ /**
+ * Get the subband gain
+ * @since 2.6
+ * @return TUint8: the subband gain.
+ */
+ TUint8 SubbandGain() const;
+
+ /**
+ * Get the subband high pass first
+ * @since 2.6
+ * @return TPoint&: a reference to the subband's high pass first.
+ */
+ const TPoint& HighPassFirst() const;
+
+ /**
+ * Get the subband origin
+ * @since 2.6
+ * @return TPoint&: a reference ot the subband's origin point.
+ */
+ const TPoint& SubbandOrigin() const;
+
+ /**
+ * Get the subband canvas
+ * @since 2.6
+ * @return TRect&: a reference to the subband's canvas.
+ */
+ const TRect& SubbandCanvas() const;
+
+ /**
+ * Get the subband canvas size
+ * @since 2.6
+ * @return TSize: the subband's canvas size.
+ */
+ TSize SubbandCanvasSize() const;
+
+ /**
+ * Get the list of packets
+ * @since 2.6
+ * @return RPointerArray<CJ2kPacket>&: a reference to the packet list.
+ */
+ const RPointerArray<CJ2kPacket>& PacketList() const;
+
+ /**
+ * Get the last packet processed
+ * @since 2.6
+ * @return TUint16: the last packet processed.
+ */
+ TUint16 LastPacketProcessed() const;
+
+ /**
+ * Reset the last packet processed to 0
+ * @since 2.6
+ */
+ void ResetLastPacketProcessed();
+
+ /**
+ * Set the last subband processed
+ * @since 2.6
+ * @param aSubbandType: the subband type.
+ */
+ void SetLastSubbandProcessed( TUint8 aSubbandType );
+
+ /**
+ * Get the last subband processed
+ * @since 2.6
+ * @return TUint8: the last subband processed.
+ */
+ TUint8 LastSubbandProcessed() const;
+
+ /**
+ * Get the packet at specific location
+ * @since 2.6
+ * @param aIndex: the index.
+ * @return CJ2kPacket&: a reference to the CJ2kPacket object.
+ */
+ const CJ2kPacket& PacketAt( TUint16 aIndex ) const;
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ /**
+ * C++ default constructor.
+ */
+ CJ2kSubband();
+
+ protected: // Functions from base classes
+
+ private:
+
+ public: // Data
+
+ protected: // Data
+
+ // Parent of the Subband
+ CJ2kSubband *iParent;
+
+ // Canvas of the Subband
+ TRect iSubbandCanvas;
+
+ // Origin of the baSubbandnd
+ TPoint iSubbandOrigin;
+
+ // High pass first
+ TPoint iHighPassFirst;
+
+ // Last packet processed
+ TUint16 iLastPacket;
+
+ // Type of the Subband
+ TSubbandType iType;
+
+ // Gain of the Subband
+ TUint8 iGain;
+
+ // Level of the Subband
+ TUint8 iLevel;
+
+ // Resolution level of the Subband
+ TUint8 iResLevel;
+
+ // Last Subband processed
+ TUint8 iLastSubband;
+
+ // List of packets
+ RPointerArray<CJ2kPacket> iPacketList;
+
+ private: // Data
+
+ public: // Friend classes
+
+ protected: // Friend classes
+
+ private: // Friend classes
+
+ };
+
+
+/**
+* CJ2kSubbandLL class is a subband class that can
+* have children, i.e. can be divided into new subbands.
+*
+* JP2KCodec.dll
+* @since 2.6
+*/
+class CJ2kSubbandLL : public CJ2kSubband
+ {
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor.
+ */
+ static CJ2kSubbandLL * NewLC();
+
+ /**
+ * Destructor.
+ */
+ virtual ~CJ2kSubbandLL();
+
+ public: // New functions
+
+ /**
+ * Get the child subband at specific band
+ * @since 2.6
+ * @param aBand: the band index.
+ * @return CJ2kSubband*: the child at specific band.
+ */
+ CJ2kSubband* ChildAt( TInt aBand );
+
+ /**
+ * Get the subband at specific resolution level
+ * @since 2.6
+ * @param aResLevel: the resolution level.
+ * @return CJ2kSubband*: pointer to the subband at specific resolution level.
+ */
+ CJ2kSubband* SubbandAt( TUint8 aResLevel );
+
+ /**
+ * Add the child subband into the list of child subbands
+ * @since 2.6
+ * @param aChild: add the child subband.
+ */
+ void AddChildL( CJ2kSubband* aChild );
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private:
+
+ public: // Data
+
+ protected: // Data
+
+ private: // Data
+
+ // List of child subbands
+ RPointerArray<CJ2kSubband> iChildList;
+
+ public: // Friend classes
+
+ protected: // Friend classes
+
+ private: // Friend classes
+
+ };
+
+/**
+* CJ2kSubbandNLL class is a subband class that can not
+* have children.
+*
+* JP2KCodec.dll
+* @since 2.6
+*/
+class CJ2kSubbandNLL : public CJ2kSubband
+ {
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor.
+ */
+ static CJ2kSubbandNLL * NewLC();
+
+ /**
+ * Destructor.
+ */
+ virtual ~CJ2kSubbandNLL();
+
+ public: // New functions
+
+ /**
+ * Get the sibling subband
+ * @since 2.6
+ * @return CJ2kSubband*: pointer to the sibling subband.
+ */
+ CJ2kSubband* NextSubbandRaster();
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private:
+
+ public: // Data
+
+ protected: // Data
+
+ private: // Data
+
+ public: // Friend classes
+
+ protected: // Friend classes
+
+ private: // Friend classes
+
+
+ };
+
+// For inliners.
+#include "JP2KSubband.inl"
+
+#endif // __JP2KSUBBAND_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KSubband.inl Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,214 @@
+/*
+* Copyright (c) 2003, 2004 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: JP2KSubband class used to collect the subband related
+* information such as list of packets and list of subbands.
+*
+*/
+
+
+
+#ifndef __JP2KSUBBAND_INL__
+#define __JP2KSUBBAND_INL__
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::Parent
+// Get the parent subband of the current subband
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline CJ2kSubband* CJ2kSubband::Parent()
+ {
+ return iParent;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::SetParent
+// Set the parent subband of the current subband
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kSubband::SetParent( CJ2kSubband* aParent )
+ {
+ iParent = aParent;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::SetSubbandLevel
+// Set the subband level
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kSubband::SetSubbandLevel( TUint8 aLevel )
+ {
+ iLevel = aLevel;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::SubbandType
+// Get the subband type
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline CJ2kSubband::TSubbandType CJ2kSubband::SubbandType() const
+ {
+ return iType;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::SubbandLevel
+// Get the subband level
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kSubband::SubbandLevel() const
+ {
+ return iLevel;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::SubbandResLevel
+// Get the subband resolution level
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kSubband::SubbandResLevel() const
+ {
+ return iResLevel;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::SubbandGain
+// Get the subband gain
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kSubband::SubbandGain() const
+ {
+ return iGain;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::HighPassFirst
+// Get the subband high pass first
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline const TPoint& CJ2kSubband::HighPassFirst() const
+ {
+ return iHighPassFirst;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::SubbandOrigin
+// Get the subband origin
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline const TPoint& CJ2kSubband::SubbandOrigin() const
+ {
+ return iSubbandOrigin;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::SubbandCanvas
+// Get the subband canvas
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline const TRect& CJ2kSubband::SubbandCanvas() const
+ {
+ return iSubbandCanvas;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::SubbandCanvasSize
+// Get the subband canvas size
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TSize CJ2kSubband::SubbandCanvasSize() const
+ {
+ return iSubbandCanvas.Size();
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::PacketList
+// Get the list of packets
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline const RPointerArray<CJ2kPacket>& CJ2kSubband::PacketList() const
+ {
+ return iPacketList;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::LastPacketProcessed
+// Get the last packet processed
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint16 CJ2kSubband::LastPacketProcessed() const
+ {
+ return iLastPacket;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::ResetLastPacketProcessed
+// Reset the last packet processed to 0
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kSubband::ResetLastPacketProcessed()
+ {
+ iLastPacket = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::SetLastSubbandProcessed
+// Set the last subband processed
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kSubband::SetLastSubbandProcessed( TUint8 aSubbandType )
+ {
+ iLastSubband = aSubbandType;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::LastSubbandProcessed
+// Get the last subband processed
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kSubband::LastSubbandProcessed() const
+ {
+ return iLastSubband;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::PacketAt
+// Get the packet at specific location
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+inline const CJ2kPacket& CJ2kSubband::PacketAt( TUint16 aIndex ) const
+ {
+ return *iPacketList[aIndex];
+ }
+
+#endif // __JP2KSUBBAND_INL__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KSynthesis.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,379 @@
+/*
+* Copyright (c) 2003, 2004 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: CJ2kSynthesis class used to perform inverse quantization
+* and inverse DWT
+*
+*/
+
+
+#ifndef __JP2KSYNTHESIS_H__
+#define __JP2KSYNTHESIS_H__
+
+// INCLUDES
+#include <e32base.h>
+#include "JP2KUtils.h"
+
+// CONSTANTS
+
+const TUint8 KFilterShift = 14; // Filter shift for the 9x7 filter taps
+const TUint8 KWaveletShift = 4; // Shift for the fractional part of wavelet coefficients
+
+// The synthesis taps:
+// 9x7 High-pass synthesis shifted by 14
+const TPrecInt KFixedHigh9x70 = 9879;
+const TPrecInt KFixedHigh9x71 = -4372;
+const TPrecInt KFixedHigh9x72 = -1282;
+const TPrecInt KFixedHigh9x73 = 276;
+const TPrecInt KFixedHigh9x74 = 438;
+
+// 9x7 Low-pass synthesis filter
+const TPrecInt KFixedLow9x70 = 18270;
+const TPrecInt KFixedLow9x71 = 9687;
+const TPrecInt KFixedLow9x72 = -943;
+const TPrecInt KFixedLow9x73 = -1495;
+
+const TUint8 KStepBits = 11;
+const TUint8 KFilterExtension = 4;
+const TPrecInt KMinimumPrecisionInteger = (TPrecInt)( -1 << ( KImplementationPrecision - 1 ) );
+const TPrecInt KMaximumPrecisionInteger = (TPrecInt)( ~KMinimumPrecisionInteger );
+
+// The coefficients we need to perform an inverse wavelet for 256 samples is at most (9x7 filter, first sample is odd) 132.
+// Thus we allocate 264 sized block to perform the inverse wavelet transform.
+const TInt32 KMaxBlockSupportSize = 264;
+const TInt32 KWaveletBlockSize = 256;
+const TInt32 KWaveletBlockMidPoint = 132;
+
+// MACROS
+
+// DATA TYPES
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+class CJ2kImageWriter;
+class CJ2kEntropyDecoder;
+class CJ2kImageInfo;
+class CJ2kTileInfo;
+class CJ2kSubband;
+class CJ2kCodeBlock;
+class CJ2kComponentInfo;
+
+// CLASS DECLARATION
+
+
+/**
+* CJ2kSynthesis class is used to decode a tile by
+* perform inverse quantization, inverse DWT, and
+* send the data to the component mixer.
+*
+* JP2KCodec.dll
+* @since 2.6
+*/
+class CJ2kSynthesis : public CBase
+ {
+ public: // Constructors and destructor
+
+ /**
+ * C++ default constructor.
+ */
+ CJ2kSynthesis();
+
+ /**
+ * Destructor.
+ */
+ virtual ~CJ2kSynthesis();
+
+ public: // New functions
+
+ /**
+ * Decode a single tile
+ * @since 2.6
+ * @param aImageWriter: a reference to CJ2kImageWriter object.
+ * @param aEntropyDecoder: a reference to CJ2kEntropyDecoder object.
+ * @param aImageInfo: a reference to CJ2kImageInfo object.
+ * @param aTile: a reference to CJ2kTileInfo object.
+ */
+ void DecodeTileL( CJ2kImageWriter& aImageWriter, CJ2kEntropyDecoder& aEntropyDecoder,
+ CJ2kImageInfo& aImageInfo, CJ2kTileInfo& aTile );
+
+ /**
+ * Decode a single tile with block-based wavelet transformation
+ * @since 2.6
+ * @param aImageWriter: a reference to CJ2kImageWriter object.
+ * @param aEntropyDecoder: a reference to CJ2kEntropyDecoder object.
+ * @param aImageInfo: a reference to CJ2kImageInfo object.
+ * @param aTile: a reference to CJ2kTileInfo object.
+ */
+ void DecodeTileBlockL( CJ2kImageWriter& aImageWriter, CJ2kEntropyDecoder& aEntropyDecoder,
+ CJ2kImageInfo& aImageInfo, CJ2kTileInfo& aTile );
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private:
+
+ /**
+ * Perform one dimensional synthesis using reversible 5/3 filter
+ * @since 2.6
+ * @param aStartPos: the start position.
+ * @param aEndPos: the end position.
+ */
+ void OneDimReversibleFilter( TInt32 aStartPos, TInt32 aEndPos );
+
+ /**
+ * Performs one dimensional symmetric extension of the line of pixels
+ * @since 2.6
+ * @param aStartPos: the start position.
+ * @param aEndPos: the end position.
+ */
+ void PerformExtension( TInt32 aStartPos, TInt32 aEndPos );
+
+ /**
+ * Perform one dimensional synthesis using irreversible 9/7 filter
+ * @since 2.6
+ * @param aStartPos: the start position.
+ * @param aEndPos: the end position.
+ * @param aLevel: the resolution level.
+ * @param aVertical: flag for the vertical filtering.
+ */
+ void OneDimIrrevFilter( TInt32 aStartPos, TInt32 aEndPos, TUint8 aLevel, TUint8 aVertical );
+
+ /**
+ * Perform one dimensional filtering
+ * @since 2.6
+ * @param aStartPos: the start position.
+ * @param aEndPos: the end position.
+ * @param aLevel: the resolution level.
+ * @param aVertical: flag for the vertical filtering.
+ */
+ void OneDimFiltering( TInt32 aStartPos, TInt32 aEndPos, TUint8 aLevel, TUint8 aVertical );
+
+ /**
+ * Perform one dimensional horizontal filtering
+ * @since 2.6
+ * @param aImage: the 2-D image.
+ * @param aRow: the index of row.
+ * @param aXtcSiz: the length of row.
+ * @param aSubband: pointer to CJ2kSubband object.
+ */
+ void HorizontalFilter( TPrecInt** aImage, TInt32 aRow, TUint32 aXtcSiz, CJ2kSubband* aSubband );
+
+ /**
+ * Perform one dimensional vertical filtering
+ * @since 2.6
+ * @param aImage: the 2-D image.
+ * @param aColumn: the index of column.
+ * @param aYtcSiz: the length of column.
+ * @param aSubband: pointer to CJ2kSubband object.
+ */
+ void VerticalFilter( TPrecInt** aImage, TInt32 aColumn, TUint32 aYtcSiz, CJ2kSubband* aSubband );
+
+ /**
+ * Perform two dimensional inverse wavelet transformation
+ * @since 2.6
+ * @param aImage: the 2-D image.
+ * @param aXtcSiz: the length of row.
+ * @param aYtcSiz: the length of column.
+ * @param aSubband: pointer to CJ2kSubband object.
+ */
+ void TwoDimFiltering( TPrecInt** aImage, TInt32 aXtcSiz, TInt32 aYtcSiz, CJ2kSubband* aSubband );
+
+ /**
+ * Perform a full inverse wavelet transformation
+ * @since 2.6
+ * @param aImage: the 2-D image.
+ * @param aSubband: pointer to CJ2kSubband object.
+ */
+ void FullWaveletInverse( TPrecInt** aImage, CJ2kSubband* aSubband );
+
+ /**
+ * Compute the quantization parameters for a particular subband
+ * in the component
+ * @since 2.6
+ * @param aComponentInfo: a reference to CJ2kComponentInfo object.
+ * @param aBandIndex: the band index.
+ * @param aBandGain: the band gain.
+ * @param aBitdepth: the bit depth.
+ */
+ void ComputeQuantizationParameters( const CJ2kComponentInfo& aComponentInfo, TInt16 aBandIndex,
+ TUint8 aBandGain, TUint8 aBitDepth );
+
+ /**
+ * Apply inverse quantization and ROI shifting on the decoded
+ * codeblock and copy to the image writer
+ * @since 2.6
+ * @param aEntropyDecoder: a reference to CJ2kEntropyDecoder object.
+ * @param aImageBlock: the 2-D image block.
+ * @param aSubband: a reference to CJ2kSubband object.
+ * @param aCodeblock: a reference to CJ2kCodeBlock object.
+ * @param aQuantizationStyle: the quantization style.
+ */
+ void CopyDataToImage( CJ2kEntropyDecoder& aEntropyDecoder,TPrecInt** aImageBlock,
+ CJ2kSubband& aSubband, CJ2kCodeBlock& aCodeblock, TUint8 aQuantizationStyle );
+
+ /**
+ * Allocate internal buffer based on the requested size
+ * @since 2.6
+ * @param aSize: the size of buffer to allocate.
+ */
+ void AllocBufferL( TInt32 aSize );
+
+ /**
+ * Perform one dimensional horizontal filtering (block-based)
+ * @since 2.6
+ * @param aImage: the 2-D image.
+ * @param aRow: the index of row.
+ * @param aXtcSiz: the length of row.
+ * @param aSubband: pointer to CJ2kSubband object.
+ * @param aXOffset: the offset in X position.
+ * @param aCurrentLevel: the current resolution level.
+ */
+ void HorizontalBlockFilter( TPrecInt** aImage, TInt32 aRow, TUint32 aXtcSiz, CJ2kSubband* aSubband,
+ TInt32 aXOffset, TUint8 aCurrentLevel );
+
+ /**
+ * Perform one dimensional vertical filtering (block-based)
+ * @since 2.6
+ * @param aImage: the 2-D image.
+ * @param aColumn: the index of column.
+ * @param aYtcSiz: the length of column.
+ * @param aSubband: pointer to CJ2kSubband object.
+ * @param aYOffset: the offset in Y position.
+ * @param aCurrentLevel: the current resolution level.
+ */
+ void VerticalBlockFilter( TPrecInt** aImage, TInt32 aColumn, TUint32 aYtcSiz, CJ2kSubband* aSubband,
+ TInt32 aYOffset, TUint8 aCurrentLevel );
+
+ /**
+ * Perform two dimensional inverse wavelet transformation (block-based)
+ * @since 2.6
+ * @param aImage: the 2-D image.
+ * @param aXtcSiz: the length of row.
+ * @param aYtcSiz: the length of column.
+ * @param aSubband: pointer to CJ2kSubband object.
+ * @param aOffset: the offset in both position.
+ * @param aCurrentLevel: the current resolution level.
+ */
+ void TwoDimBlockFiltering( TPrecInt** aImage, TSize aRegion, CJ2kSubband* aSubband,
+ TPoint aOffset, TUint8 aCurrentLevel );
+
+ /**
+ * Perform a full inverse wavelet transformation (block-based)
+ * @since 2.6
+ * @param aImage: the 2-D image.
+ * @param aSubband: pointer to CJ2kSubband object.
+ * @param aOffset: the offset in both position.
+ * @param aRegion; the region.
+ * @param aCurrentLevel: the current resolution level.
+ */
+ void SingleLevelWaveletInverse( TPrecInt** aImage, CJ2kSubband* aSubband, TPoint aOffset,
+ TSize aRegion, TUint8 aCurrentLevel );
+
+ /**
+ * Apply inverse quantization and ROI shifting on the decoded
+ * codeblock and copy to the image writer
+ * @since 2.6
+ * @param aEntropyDecoder: a reference to CJ2kEntropyDecoder object.
+ * @param aImageBlock: the 2-D image block.
+ * @param aSubband: a reference to CJ2kSubband object.
+ * @param aQuantizationStyle: the quantization style.
+ * @param aStartRowCblk: the starting row of codeblock.
+ * @param aStartColCblk: the starting column of codeblock.
+ * @param aStartRowImage: the starting row of image.
+ * @param aStartColImage: the starting column of image.
+ * @param aCblkHeight: the codeblock height.
+ * @param aCblkWidth: the codeblock width.
+ */
+ void CopyDataToBlock( CJ2kEntropyDecoder& aEntropyDecoder,TPrecInt** aImageBlock, CJ2kSubband& aSubband,
+ TUint8 aQuantizationStyle, TInt32 aStartRowCblk, TInt32 aStartColCblk,
+ TInt32 aStartRowImage, TInt32 aStartColImage, TInt32 aCblkHeight,TInt32 aCblkWidth );
+
+ /**
+ * Fill a block in image writer with zeros (corresponding to an
+ * empty block)
+ * @since 2.6
+ * @param aImageBlock: the 2-D image block.
+ * @param aSubband: a reference to CJ2kSubband object.
+ * @param aStartRowImage: the starting row of image.
+ * @param aStartColImage: the starting column of image.
+ * @param aCblkHeight: the codeblock height.
+ * @param aCblkWidth: the codeblock width.
+ */
+ void FillDataWithZeros( TPrecInt** aImageBlock, CJ2kSubband& aSubband, TInt32 aStartRowImage,
+ TInt32 aStartColImage, TInt32 aCblkHeight, TInt32 aCblkWidth );
+
+ public: // Data
+
+ protected: // Data
+
+ private: // Data
+
+ // Number of filters tap for low-pass and high-pass
+ enum TFilterTap
+ {
+ ELowTap = 4,
+ EHighTap
+ };
+
+ // Is transformation reversible?
+ TUint8 iReversible;
+
+ // Magnitude bits for this band
+ TUint8 iMagnitudeBitsHere;
+
+ // Resolution level for DWT
+ TInt16 iWaveletLevels;
+
+ // Amount of shift for ROI
+ TInt32 iROIShift;
+
+ // Downshift for ROI data samples
+ TInt32 iROIDataShift;
+
+ // Downshift for data samples
+ TInt32 iDataShift;
+
+ // Quantization step value
+ TInt32 iStepValue;
+
+ // Quantization step's exponent
+ TInt32 iStepExponent;
+
+ // Internal buffer size
+ TInt32 iIOBufferSize;
+
+ // Internal input buffer
+ TInt32* iInputBuffer;
+
+ // Internal output buffer
+ TInt32* iOutputBuffer;
+
+ // Filter taps for irreversible low-pass filtering
+ TPrecInt iTapsLow[ELowTap];
+
+ // Filter taps for irreversible high-pass filtering
+ TPrecInt iTapsHigh[EHighTap];
+
+ public: // Friend classes
+
+ protected: // Friend classes
+
+ private: // Friend classes
+
+ };
+
+#endif // __JP2KSYNTHESIS_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KTileInfo.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,608 @@
+/*
+* Copyright (c) 2003, 2004 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: CJ2kTileInfo class used to collect tile related
+* information such as Tile Part Header, SOT marker and
+* list of components.
+*
+*/
+
+
+#ifndef __JP2KTILEINFO_H__
+#define __JP2KTILEINFO_H__
+
+// INCLUDES
+#include <e32std.h>
+#include <e32base.h>
+#include "JP2KMarker.h"
+
+// CONSTANTS
+
+// MACROS
+
+// DATA TYPES
+struct TPOCMarker;
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+class CJ2kImageInfo;
+class TJ2kStreamReader;
+class CJ2kComponentInfo;
+
+// CLASS DECLARATION
+
+/**
+* CJ2kTileInfo class used to collect tile related
+* information such as Tile Part Header, SOT marker,
+* List of components, and etc. It's also implement the
+* MJ2kPacketHeaderReader interface for reading the
+* packet header from PPT marker. It contains the data
+* to control where to resume the parsing of the bitstream.
+*
+* JP2KCodec.dll
+* @since 2.6
+*/
+class CJ2kTileInfo : public CBase, public MJ2kPacketHeaderReader
+ {
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor.
+ */
+ static CJ2kTileInfo* NewLC( CJ2kImageInfo& aImageInfo, TJ2kStreamReader& aReader );
+
+ /**
+ * Destructor.
+ */
+ virtual ~CJ2kTileInfo();
+
+ public: // New functions
+
+ /**
+ * Initialize the components in the tile
+ * @since 2.6
+ */
+ void InitializeL();
+
+ /**
+ * Verify and append COD to the tile part header
+ * @since 2.6
+ * @param aMarker: pointer to TCODMarker.
+ * @param aLength: the marker length.
+ */
+ void AppendCOD( TCODMarker *aMarker, TUint32 aLength );
+
+ /**
+ * Verify and append COC to the tile part header
+ * @since 2.6
+ * @param aMarker: pointer to TCOCMarker.
+ * @param aLength: the marker length.
+ */
+ void AppendCOCL( TCOCMarker *aMarker, TUint32 aLength );
+
+ /**
+ * Verify and append QCD to the tile part header
+ * @since 2.6
+ * @param aMarker: pointer to TQCDMarker.
+ * @param aLength: the marker length.
+ */
+ void AppendQCD( TQCDMarker *aMarker, TUint32 aLength );
+
+ /**
+ * Verify and append QCC to the tile part header
+ * @since 2.6
+ * @param aMarker: pointer to TQCCMarker.
+ * @param aLength: the marker length.
+ */
+ void AppendQCCL( TQCCMarker *aMarker, TUint32 aLength );
+
+ /**
+ * Verify and append RGN to the tile part header
+ * @since 2.6
+ * @param aMarker: pointer to TRGNMarker.
+ * @param aLength: the marker length.
+ */
+ void AppendRGNL( TRGNMarker *aMarker, TUint32 aLength );
+
+ /**
+ * Verify and append POC to the tile part header
+ * @since 2.6
+ * @param aMarker: pointer to TPOCMarker.
+ * @param aLength: the marker length.
+ */
+ void AppendPOCL( TPOCMarker *aMarker, TUint32 aLength );
+
+ /**
+ * Verify and append COM to the tile part header
+ * @since 2.6
+ * @param aMarker: pointer to TCOMMarker.
+ * @param aLength: the marker length.
+ */
+ void AppendCOML( TCOMMarker *aMarker, TUint32 aLength );
+
+ /**
+ * Verify and append PPT to the tile part header
+ * @since 2.6
+ * @param aMarker: pointer to TPPTMarker.
+ * @param aLength: the marker length.
+ */
+ void AppendPPTL( TPPTMarker *aMarker, TUint32 aLength );
+
+ /**
+ * Verify and append PLT to the tile part header
+ * @since 2.6
+ * @param aMarker: pointer to TPLTMarker.
+ * @param aLength: the marker length.
+ */
+ void AppendPLTL( TPLTMarker *aMarker, TUint32 aLength );
+
+ /**
+ * Parsing the bitstream data based on progression order
+ * @since 2.6
+ * @param aBool: to check next SOT/EOC marker if true.
+ */
+ void ReadBitStreamL( TUint8 aBool = EFalse );
+
+ /**
+ * Get the color transformation
+ * @since 2.6
+ * @return TUint8: color transformation from tile COD or main COD.
+ */
+ TUint8 ColorTransformation() const;
+
+ /**
+ * Get the progression order
+ * @since 2.6
+ * @return TUint8: progression order from tile COD or main COD.
+ */
+ TUint8 ProgressionOrder() const;
+
+ /**
+ * Get the number of layers
+ * @since 2.6
+ * @return TUint16: number of layers from tile COD or main COD.
+ */
+ TUint16 NumOfLayers() const;
+
+ /**
+ * Get the number of resolution level
+ * @since 2.6
+ * @return TUint8: max number of resolution level from each component.
+ */
+ TUint8 NumOfLevels() const;
+
+ /**
+ * Get the minimum grid among the components in the tile
+ * @since 2.6
+ * @param aGrid: get the minimum grid size.
+ */
+ void GetMinGrid( TSize &aGrid ) const;
+
+ /**
+ * Set up to read the packet header from the PPT marker
+ * @since 2.6
+ */
+ void UsePPTL();
+
+ /**
+ * From MJ2kPacketHeaderReader
+ * Try to consume the EPH marker if there is one
+ * @since 2.6
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 ReadEPHMarker();
+
+ /**
+ * From MJ2kPacketHeaderReader
+ * Read a bit from the packet header stream
+ * @since 2.6
+ * @param aBit: get a bit from the packet header bitstream.
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 ReadBit( TUint8& aBit );
+
+ /**
+ * From MJ2kPacketHeaderReader
+ * Read some bits from the packet header stream
+ * @since 2.6
+ * @param aBit: get some bits from the packet header bitstream.
+ * @param aBitLen: how many bits to read.
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 ReadBits( TUint8& aBit, TUint8 aBitLen );
+
+ /**
+ * From MJ2kPacketHeaderReader
+ * Read some bits from the packet header stream
+ * @since 2.6
+ * @param aBit: get some bits from the packet header bitstream.
+ * @param aBitLen: how many bits to read.
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 ReadBits( TUint32& aBit, TUint8 aBitLen );
+
+ /**
+ * From MJ2kPacketHeaderReader
+ * Start reading from packet header stream
+ * @since 2.6
+ * @return TUint8: true if end of buffer.
+ */
+ TUint8 StartReadBit();
+
+ /**
+ * From MJ2kPacketHeaderReader
+ * Align the stream to the next byte boundary if necessary
+ * @since 2.6
+ */
+ void AlignReader();
+
+ /**
+ * Release unused markers in tile part header
+ * @since 2.6
+ */
+ void DoReleaseUnusedMarkers();
+
+ /**
+ * Set the tile length
+ * @since 2.6
+ * @param aLength: the tile length to set.
+ */
+ void SetTileLength( TUint32 aLength );
+
+ /**
+ * Get the tile length
+ * @since 2.6
+ * @return TUint32&: reference to the tile length.
+ */
+ TUint32& TileLength();
+
+ /**
+ * Get the tile canvas
+ * @since 2.6
+ * @return TRect&: reference to the canvas of the tile.
+ */
+ const TRect& TileCanvas() const;
+
+ /**
+ * Get the number of components
+ * @since 2.6
+ * @return TUint16: the number of components.
+ */
+ TUint16 NumOfComponents() const;
+
+ /**
+ * Get the end of layer to process
+ * @since 2.6
+ * @return TUint16: the last layer to process.
+ */
+ TUint16 NumOfLayersPOC() const;
+
+ /**
+ * Get the end of level to process
+ * @since 2.6
+ * @return TUint8: the last level to process.
+ */
+ TUint8 NumOfLevelsPOC() const;
+
+ /**
+ * Get the component at specific location
+ * @since 2.6
+ * @param aIndex: component index.
+ * @return CJ2kComponentInfo&: a specific component.
+ */
+ const CJ2kComponentInfo& ComponentAt( TUint16 aIndex ) const;
+
+ /**
+ * Get the last layer processed
+ * @since 2.6
+ * @return TUint16: the last layer processed.
+ */
+ TUint16 LastLayerProcessed() const;
+
+ /**
+ * Get the last resolution level processed
+ * @since 2.6
+ * @return TUint8: the last resolution level processed.
+ */
+ TUint8 LastLevelProcessed() const;
+
+ /**
+ * Get the last component processed
+ * @since 2.6
+ * @return TUint16: the last component processed.
+ */
+ TUint16 LastComponentProcessed() const;
+
+ /**
+ * Get the last position processed in vertical direction
+ * @since 2.6
+ * @return TInt: the last vertical position processed.
+ */
+ TInt LastN1Processed() const;
+
+ /**
+ * Get the last position processed in horizontal direction
+ * @since 2.6
+ * @return TInt: the last horizontal position processed.
+ */
+ TInt LastN2Processed() const;
+
+ /**
+ * Increment the last layer processed
+ * @since 2.6
+ */
+ void IncrementLastLayerProcessed();
+
+ /**
+ * Reset the last layer processed to 0
+ * @since 2.6
+ */
+ void ResetLastLayerProcessed();
+
+ /**
+ *
+ * @since 2.6Get the reference to the image info
+ * @return CJ2kImageInfo&: a reference to CJ2kImageInfo object.
+ */
+ const CJ2kImageInfo& ImageInfo() const;
+
+ /**
+ * Get the reference to the stream reader
+ * @since 2.6
+ * @return TJ2kStreamReader&: a reference to TJ2kStreamReader object.
+ */
+ const TJ2kStreamReader& StreamReader() const;
+
+ /**
+ * Set the SOT marker
+ * @since 2.6
+ * @param aSotMarker: the TSotMarker to set.
+ */
+ void SetSotMarker( const TSotMarker &aSotMarker );
+
+ /**
+ * Get the SOT marker
+ * @since 2.6
+ * @return TSotMarker&: a reference to TSotMarker object.
+ */
+ const TSotMarker& SotMarker() const;
+
+ /**
+ * Get the Tile Part Header
+ * @since 2.6
+ * @return TTileMarker&: a reference to TTileMarker object.
+ */
+ const TTileMarker& TileMarker() const;
+
+ /**
+ * Set the SOT/EOC check indicator
+ * @since 2.6
+ * @param aCheckMarker: true if SOT/EOC need to be checked.
+ */
+ void SetCheckMarker( TUint8 aCheckMarker );
+
+ /**
+ * Get the packet header reader
+ * @since 2.6
+ * @return MJ2kPacketHeaderReader&: a reference to MJ2kPacketHeaderReader object.
+ */
+ MJ2kPacketHeaderReader& PacketHeaderReader();
+
+ /**
+ * Set the packet header reader
+ * @since 2.6
+ * @param aReader: set the packet header reader to aReader.
+ */
+ void SetPacketHeaderReader( MJ2kPacketHeaderReader* aReader );
+
+ /**
+ * Is this the first tile part
+ * @since 2.6
+ * @return TUint8: true if this is the first tile part.
+ */
+ TUint8 IsFirstTilePart() const;
+
+ /**
+ * Is packet header should be read from PPT marker
+ * @since 2.6
+ * @return TUint8: true if tile contains PPT.
+ */
+ TUint8 IsPPT() const;
+
+ /**
+ * Is POC marker should be used for progression order
+ * @since 2.6
+ * @return TUint8: true if tile contains POC.
+ */
+ TUint8 IsPOC() const;
+
+ /**
+ * Is this the last tile part
+ * @since 2.6
+ * @return TUint8: true if this is the last tile part.
+ */
+ TUint8 IsLastTilePart() const;
+
+ /**
+ * Is SOT/EOC marker should be checked during progression
+ * @since 2.6
+ * @return TUint8: true if SOT/EOC should be checked.
+ */
+ TUint8 IsCheckMarker() const;
+
+ /**
+ * Is RLCP/RPCL progression order used
+ * @since 2.6
+ * @return TUint8: true if RLCP/RPCL progression order used.
+ */
+ TUint8 IsSpeedup() const;
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private:
+
+ /**
+ * C++ default constructor.
+ */
+ CJ2kTileInfo( CJ2kImageInfo& aImageInfo, TJ2kStreamReader& aReader );
+
+ /**
+ * Parse the bitstream with LRCP progression order
+ * @since 2.6
+ * @return TUint8: true if next SOT or EOC marker is found.
+ */
+ TUint8 LRCPProgressionL();
+
+ /**
+ * Parse the bitstream with RLCP progression order
+ * @since 2.6
+ * @return TUint8: true if next SOT or EOC marker is found.
+ */
+ TUint8 RLCPProgressionL();
+
+ /**
+ * Parse the bitstream with RPCL progression order
+ * @since 2.6
+ * @return TUint8: true if next SOT or EOC marker is found.
+ */
+ TUint8 RPCLProgressionL();
+
+ /**
+ * Parse the bitstream with PCRL progression order
+ * @since 2.6
+ * @return TUint8: true if next SOT or EOC marker is found.
+ */
+ TUint8 PCRLProgressionL();
+
+ /**
+ * Parse the bitstream with CPRL progression order
+ * @since 2.6
+ * @return TUint8: true if next SOT or EOC marker is found.
+ */
+ TUint8 CPRLProgressionL();
+
+ public: // Data
+
+ protected: // Data
+
+ // Progression order
+ enum TProgression
+ {
+ EProgression_L_R_C_P = 0,
+ EProgression_R_L_C_P = 1,
+ EProgression_R_P_C_L = 2,
+ EProgression_P_C_R_L = 3,
+ EProgression_C_P_R_L = 4
+ };
+
+ // Structure to hold the information on reading packet header
+ struct TPPTStream
+ {
+ TUint32 iPtr; // Current byte position in buffer
+ TUint32 iPtrEnd; // End of byte position in buffer
+ TUint8 iData; // Current data in 8 bits
+ TUint8 iPos; // Current bit position
+ TUint8 iNextPos; // Bit position of next byte
+ };
+
+ private: // Data
+
+ // SOT marker
+ TSotMarker iSot;
+
+ // Tile Part Header
+ TTileMarker iTileMarker;
+
+ // List of components
+ RPointerArray<CJ2kComponentInfo> iComponentList;
+
+ // Canvas of the tile
+ TRect iTileCanvas;
+
+ // Remaining tile length
+ TUint32 iTileLength;
+
+ // Last layer processed
+ TUint16 iLastLayer;
+
+ // Last component processed
+ TUint16 iLastComponent;
+
+ // Original starting component
+ TUint16 iLastComponentOrig;
+
+ // End of layer to process
+ TUint16 iNumOfLayersPOC;
+
+ // End of component to process
+ TUint16 iNumOfComponentsPOC;
+
+ // Last resolution level processed
+ TUint8 iLastLevel;
+
+ // Original starting resolution level
+ TUint8 iLastLevelOrig;
+
+ // End of resolution level to process
+ TUint8 iNumOfLevelsPOC;
+
+ // Last POC processed
+ TUint8 iLastPOC;
+
+ // To indicate not to load from iPOC
+ TUint8 iDoLoadPOC;
+
+ // To indicate whether to check SOT/EOC marker
+ TUint8 iCheckMarker;
+
+ // Pointer to the POC in Tile Part Header or Main Header
+ TPOCMarker *iPOC;
+
+ // Last position processed in vertical direction
+ TInt iLastN1;
+
+ // Last position processed in horizontal direction
+ TInt iLastN2;
+
+ // Reference to the image info
+ CJ2kImageInfo &iImageInfo;
+
+ // Reference to the stream reader (buffer provided by ICL framework)
+ TJ2kStreamReader &iReader;
+
+ // Control the reading of packet header
+ TPPTStream *iPpt;
+
+ // Pointed to PPT in Tile Part Header
+ HBufC8 *iPptBuffer;
+
+ // Packet header reader
+ MJ2kPacketHeaderReader *iPacketHeaderReader;
+
+ public: // Friend classes
+
+ protected: // Friend classes
+
+ private: // Friend classes
+
+ };
+
+// For inliners.
+#include "JP2KTileInfo.inl"
+
+#endif // __JP2KTILEINFO_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KTileInfo.inl Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,335 @@
+/*
+* Copyright (c) 2003, 2004 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: CJ2kTileInfo class used to collect tile related
+* information such as Tile Part Header, SOT marker and
+* list of components.
+*
+*/
+
+
+#ifndef __JP2KTILEINFO_INL__
+#define __JP2KTILEINFO_INL__
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::SetTileLength
+// Set the tile length.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kTileInfo::SetTileLength( TUint32 aLength )
+ {
+ iTileLength = aLength;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::TileLength
+// Get the tile length.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline TUint32& CJ2kTileInfo::TileLength()
+ {
+ return iTileLength;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::TileCanvas
+// Get the canvas of the tile.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline const TRect& CJ2kTileInfo::TileCanvas() const
+ {
+ return iTileCanvas;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::NumOfComponents
+// Get the number of componnets.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline TUint16 CJ2kTileInfo::NumOfComponents() const
+ {
+ return (TUint16)iComponentList.Count();
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::NumOfLayersPOC
+// Get the end of layer to process.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline TUint16 CJ2kTileInfo::NumOfLayersPOC() const
+ {
+ return iNumOfLayersPOC;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::NumOfLevelsPOC
+// Get the end of level to process.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kTileInfo::NumOfLevelsPOC() const
+ {
+ return iNumOfLevelsPOC;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::ComponentAt
+// Get the component at specific location.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline const CJ2kComponentInfo& CJ2kTileInfo::ComponentAt( TUint16 aIndex ) const
+ {
+ return *iComponentList[aIndex];
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::LastLayerProcessed
+// Get the last layer processed.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline TUint16 CJ2kTileInfo::LastLayerProcessed() const
+ {
+ return iLastLayer;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::LastLevelProcessed
+// Get the last resolution level processed.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kTileInfo::LastLevelProcessed() const
+ {
+ return iLastLevel;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::LastComponentProcessed
+// Get the last component processed.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline TUint16 CJ2kTileInfo::LastComponentProcessed() const
+ {
+ return iLastComponent;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::LastN1Processed
+// Get the last position processed in vertical direction.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline TInt CJ2kTileInfo::LastN1Processed() const
+ {
+ return iLastN1;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::LastN2Processed
+// Get the last position processed in horizontal direction.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline TInt CJ2kTileInfo::LastN2Processed() const
+ {
+ return iLastN2;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::IncrementLastLayerProcessed
+// Increment the last layer processed.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kTileInfo::IncrementLastLayerProcessed()
+ {
+ ++iLastLayer;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::ResetLastLayerProcessed
+// Reset the last layer processed to 0.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kTileInfo::ResetLastLayerProcessed()
+ {
+ iLastLayer = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::ImageInfo
+// Get the reference to the image info.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline const CJ2kImageInfo& CJ2kTileInfo::ImageInfo() const
+ {
+ return iImageInfo;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::StreamReader
+// Get the reference to the stream reader.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline const TJ2kStreamReader& CJ2kTileInfo::StreamReader() const
+ {
+ return iReader;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::SetSotMarker
+// Set the SOT marker.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kTileInfo::SetSotMarker( const TSotMarker &aSotMarker )
+ {
+ iSot = aSotMarker;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::SotMarker
+// Get the SOT marker.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline const TSotMarker& CJ2kTileInfo::SotMarker() const
+ {
+ return iSot;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::TileMarker
+// Get the Tile Part Header.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline const TTileMarker& CJ2kTileInfo::TileMarker() const
+ {
+ return iTileMarker;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::SetCheckMarker
+// Set the SOT/EOC check indicator.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kTileInfo::SetCheckMarker( TUint8 aCheckMarker )
+ {
+ iCheckMarker = aCheckMarker;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::SetPacketHeaderReader
+// Set the packet header reader.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline void CJ2kTileInfo::SetPacketHeaderReader( MJ2kPacketHeaderReader* aReader )
+ {
+ iPacketHeaderReader = aReader;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::PacketHeaderReader
+// Get the packet header reader.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline MJ2kPacketHeaderReader& CJ2kTileInfo::PacketHeaderReader()
+ {
+ return *iPacketHeaderReader;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::IsFirstTilePart
+// Is this the first tile part.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kTileInfo::IsFirstTilePart() const
+ {
+ return ( iSot.iTPsot == 0 );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::IsPPT
+// Is packet header should be read from PPT marker.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kTileInfo::IsPPT() const
+ {
+ return ( iPptBuffer != 0 || iTileMarker.iPpt.Count() != 0 );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::IsPOC
+// Is POC marker should be used for progression order.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kTileInfo::IsPOC() const
+ {
+ return ( iPOC != 0 );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::IsLastTilePart
+// Is this the last tile part.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kTileInfo::IsLastTilePart() const
+ {
+ return ( iSot.iTNsot != 0 && iSot.iTNsot == ( iSot.iTPsot + 1 ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::IsCheckMarker
+// Is SOT/EOC marker should be checked during progression.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kTileInfo::IsCheckMarker() const
+ {
+ return iCheckMarker;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::IsSpeedup
+// Is RLCP/RPCL progression order used.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+inline TUint8 CJ2kTileInfo::IsSpeedup() const
+ {
+ return ( ProgressionOrder() == EProgression_R_L_C_P ||
+ ProgressionOrder() == EProgression_R_P_C_L );
+ }
+
+#endif // __JP2KTILEINFO_INL__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Inc/JP2KUtils.h Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,140 @@
+/*
+* Copyright (c) 2003, 2004 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: TJ2kUtils class used to provide common public static
+* functions used by all classes in JP2KCodec.
+*
+*/
+
+
+#ifndef __JP2KUTILS_H__
+#define __JP2KUTILS_H__
+
+// INCLUDES
+#include <e32base.h>
+
+// CONSTANTS
+const TInt KImplementationPrecision = 32;
+
+// MACROS
+
+// DATA TYPES
+
+typedef TInt32 TPrecInt;
+
+struct TDiv
+ {
+ TInt quot; // Quotient
+ TInt rem; // Remainder
+ };
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// CLASS DECLARATION
+
+/**
+* TJ2kUtils class used to provide common public static
+* methods used by all classes
+*
+* JP2KCodec.dll
+* @since 2.6
+*/
+class TJ2kUtils
+ {
+ public: // Constructors and destructor
+
+ public: // New functions
+
+ /**
+ * Get the ceiling between two integers
+ * @since 2.6
+ * @param aL: first integer to compute.
+ * @param aR: second integer to compute.
+ * @return TInt32: the ceiling between two integers aL and aR.
+ */
+ static TInt32 Ceil( TInt32 aL, TInt32 aR );
+
+ /**
+ * Get the floor between two integers
+ * @since 2.6
+ * @param aL: first integer to compute.
+ * @param aR: second integer to compute.
+ * @return TInt32: the floor between two integers aL and aR.
+ */
+ static TInt32 Floor( TInt32 aL, TInt32 aR );
+
+ /**
+ * Get the quotient and remainder
+ * @since 2.6
+ * @param aNum: first integer to compute.
+ * @param aDenom: divisor integer.
+ * @return TDiv: the structure contains the quotient and remainder.
+ */
+ static TDiv Div( TInt aNum, TInt aDenom );
+
+ /**
+ * Get the log2 value of an integer
+ * @since 2.6
+ * @param aI: an integer to compute.
+ * @return TInt32: the log2 value of the integer aI.
+ */
+ static TInt32 Log2( TUint32 aI );
+
+ /**
+ * Allocate 2-D array
+ * @since 2.6
+ * @param aRowSize: row size of the 2-D array.
+ * @param aColSize: column size of the 2-D array.
+ * @return TPrecInt**: a pointer of pointer to TPrecInt.
+ */
+ static TPrecInt** Alloc2DArrayL( TInt aRowSize, TInt aColSize );
+
+ /**
+ * Free 2-D array
+ * @since 2.6
+ * @param aPtr: a pointer of pointer to TPrecInt to be freed.
+ */
+ static void Free2DArray( TPrecInt **aPtr );
+
+ /**
+ * Wrapper to free 2-D array when put into TCleanupItem
+ * @since 2.6
+ * @param aPtr: a pointer of pointer to TAny to be freed.
+ */
+ static void Free2DArray( TAny *aPtr );
+
+ public: // Functions from base classes
+
+ protected: // New functions
+
+ protected: // Functions from base classes
+
+ private:
+
+ public: // Data
+
+ protected: // Data
+
+ private: // Data
+
+ public: // Friend classes
+
+ protected: // Friend classes
+
+ private: // Friend classes
+
+ };
+
+#endif // __JP2KUTILS_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Src/JP2KCodeBlock.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,135 @@
+/*
+* Copyright (c) 2003, 2004 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: JP2KCodeBlock class used to collect the codeblock
+* related information such as compressed data and data length.
+*
+*/
+
+
+// INCLUDE FILES
+#include "JP2KCodeBlock.h"
+#include "JP2KUtils.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CJ2kCodeBlock::CJ2kCodeBlock
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CJ2kCodeBlock::CJ2kCodeBlock() :
+ iLastPass(-1),
+ iLengthBits(3)
+ {
+ }
+
+// Destructor
+CJ2kCodeBlock::~CJ2kCodeBlock()
+ {
+ delete iDataSize;
+ iDataSize = 0;
+
+ delete iPassesPerSegment;
+ iPassesPerSegment = 0;
+
+ delete iNumSegment;
+ iNumSegment = 0;
+
+ delete iData;
+ iData = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kCodeBlock::SetCodeBlockCanvas
+// Set the canvas of the code block.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kCodeBlock::SetCodeBlockCanvas( TInt32 aX, TInt32 aY, TInt32 aWidth, TInt32 aHeight )
+ {
+ iCodeBlockCanvas.iTl = TPoint( aX, aY );
+ iCodeBlockCanvas.SetWidth( aWidth );
+ iCodeBlockCanvas.SetHeight( aHeight );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kCodeBlock::InitializeL
+// Initialize the number of segment.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kCodeBlock::InitializeL( TUint16 aLayer )
+ {
+ iNumSegment = HBufC16::NewMaxL( aLayer );
+ iNumSegment->Des().FillZ();
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kCodeBlock::DataL
+// Get the data buffer descriptor.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+HBufC8* CJ2kCodeBlock::DataL()
+ {
+ if ( iData )
+ {
+ if ( iData->Des().MaxLength() < (TInt)iDataLength )
+ {
+ iData = iData->ReAllocL( iDataLength );
+ }
+ }
+ else
+ {
+ iData = HBufC8::NewL( iDataLength );
+ }
+
+ return iData;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kCodeBlock::Data
+// Get the pointer to the data portion.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+const TUint8* CJ2kCodeBlock::Data() const
+ {
+ if ( iData )
+ {
+ return iData->Ptr();
+ }
+
+ return 0;
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Src/JP2KCodec.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,2751 @@
+/*
+* Copyright (c) 2003-2006 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: CJp2kReadCodec class implements the ICL read codec interface.
+*
+*/
+
+
+// INCLUDE FILES
+#include <fbs.h>
+#include <JP2KImageData.h>
+#include "JP2KImageUtils.h"
+#include "JP2KFormat.h"
+#include "JP2KStreamReader.h"
+#include "JP2KTileInfo.h"
+#include "JP2KImageInfo.h"
+#include "JP2KCodec.h"
+#include "JP2KEntropyDecoder.h"
+#include "JP2KImageWriter.h"
+#include "JP2KSynthesis.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CJp2kReadCodec* CJp2kReadCodec::NewL( const TJ2kInfo& aJ2kInfo )
+ {
+ CJp2kReadCodec* self = new ( ELeave ) CJp2kReadCodec( aJ2kInfo );
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+// Destructor
+CJp2kReadCodec::~CJp2kReadCodec()
+ {
+ delete iImageInfo;
+ iImageInfo = 0;
+
+ delete iEntropy;
+ iEntropy = 0;
+
+ delete iImageWriter;
+ iImageWriter = 0;
+
+ delete iSynthesis;
+ iSynthesis = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::DecodeTileL
+// Decoding the current tile-part
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::DecodeTileL()
+ {
+ CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
+
+ // Decode and delete the tile
+ DecodeAndDeleteTileL( tile );
+
+ // reset the codec back to the parsing state
+ iDecodeTile = EFalse;
+ TFrameState retCode = EFrameIncomplete;
+
+ // Start with new tile
+ iUseNewTile = ETrue;
+ if ( !iUseNextTile )
+ {
+ iFHState = EStateInUnknown;
+ retCode = EFrameIncompleteRepositionRequest;
+ }
+ else
+ {
+ if ( !iSequential )
+ {
+ // Must be End of Codestream EOC
+ iFHState = EStateInEOC;
+ retCode = EFrameComplete;
+ }
+ else if ( iFHState == EStateInEOC )
+ {
+ retCode = EFrameComplete;
+ }
+ else
+ {
+ iFHState = EStateInUnknown;
+ }
+ }
+ return retCode;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::IsDecodeTile
+// Is codec in the decoding state
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool CJp2kReadCodec::IsDecodeTile() const
+ {
+ return iDecodeTile;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::InitFrameHeader
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kReadCodec::InitFrameHeader( TFrameInfo& aFrameInfo, CFrameImageData& aFrameData )
+ {
+ // Initialize internal data structure for holding frame header
+ ASSERT( aFrameInfo.CurrentFrameState() == TFrameInfo::EFrameInfoUninitialised );
+
+ iFrame = &aFrameInfo;
+ iFrameData = &aFrameData;
+ aFrameInfo.SetCurrentFrameState( TFrameInfo::EFrameInfoProcessingFrameHeader );
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ProcessFrameHeaderL
+// Collect the JP2 codestream Main Header information.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::ProcessFrameHeaderL( TBufPtr8& aData )
+ {
+ // Read frame header and fill up internal data structure
+ TFrameState retCode = EFrameIncomplete;
+
+ iReader.iPtr = aData.Ptr();
+ iReader.iPtrStart = CONST_CAST( TUint8*, iReader.iPtr );
+ iReader.iPtrEnd = iReader.iPtrStart + aData.Length();
+
+ while ( iFHState != EStateInSOT )
+ {
+ iReader.iPtrStartMarker = CONST_CAST( TUint8*, iReader.iPtr );
+ switch ( iFHState )
+ {
+ case EStateInSOC:
+ {
+ retCode = ReadSOCL();
+ break;
+ }
+ case EStateInSIZ:
+ {
+ retCode = ReadSIZL();
+ break;
+ }
+ case EStateInCOD:
+ {
+ retCode = ReadCODL();
+ break;
+ }
+ case EStateInCOC:
+ {
+ retCode = ReadCOCL();
+ break;
+ }
+ case EStateInQCD:
+ {
+ retCode = ReadQCDL();
+ break;
+ }
+ case EStateInQCC:
+ {
+ retCode = ReadQCCL();
+ break;
+ }
+ case EStateInRGN:
+ {
+ retCode = ReadRGNL();
+ break;
+ }
+ case EStateInPOC:
+ {
+ retCode = ReadPOCL();
+ break;
+ }
+ case EStateInPPM:
+ {
+ retCode = ReadPPML();
+ break;
+ }
+ case EStateInTLM:
+ {
+ retCode = ReadTLML();
+ break;
+ }
+ case EStateInPLM:
+ {
+ retCode = ReadPLML();
+ break;
+ }
+ case EStateInCRG:
+ {
+ retCode = ReadCRGL();
+ break;
+ }
+ case EStateInCOM:
+ {
+ retCode = ReadCOML();
+ break;
+ }
+ case EStateInUnknown:
+ {
+ // Update the internal state based on the Marker
+ retCode = UpdateStateFromMarkerL();
+ break;
+ }
+ default:
+ {
+ // Unrecognized marker
+ User::Leave( KErrCorrupt );
+ break;
+ }
+ }
+ // Check for underflow
+ if ( retCode != EFrameComplete )
+ {
+ aData.Shift( iReader.iPtr - iReader.iPtrStart );
+ return retCode;
+ }
+
+ // Update the internal counter for data processed
+ iReader.UpdateMainHeader();
+ }
+
+ // Convert the MainHeader's COM marker to TJp2kComment
+ // and let the framework managing the buffer.
+ TMainMarker& mainMarker = CONST_CAST( TMainMarker&, iImageInfo->MainMarker() );
+ for ( TInt index = 0; index < mainMarker.iCom.Count(); ++index )
+ {
+ TJp2kComment* jp2kComment = new ( ELeave ) TJp2kComment;
+ CleanupDeletePushL( jp2kComment );
+
+ jp2kComment->iComment = mainMarker.iCom[index]->iCcom;
+
+ User::LeaveIfError( iFrameData->AppendImageData( jp2kComment ) );
+ CleanupStack::Pop();
+
+ // Transfer the ownership of the buffer from TMainMarker to framework
+ User::LeaveIfError( iFrameData->AppendImageBuffer( jp2kComment->iComment ) );
+ mainMarker.iCom[index]->iCcom = 0;
+ }
+
+ // Convert some metadata from file format to TImageDataBlock derived objects
+ ConvertImageDataL();
+
+ // Try to sort PPM and PLM if there is one
+ iImageInfo->DoCompactMainHeaderL();
+
+ aData.Shift( iReader.iPtr - iReader.iPtrStart );
+
+ // Fill up the image related information if it is not
+ // JP2 file format
+ if ( !( iJ2kInfo.iOption & TJ2kInfo::EJP2file ) )
+ {
+ const TSizMarker &sizMarker = iImageInfo->SizMarker();
+
+ // To get the right output image size, we must compute the size tile by tile.
+ // Compute the width of the output image
+ TInt32 tileCompCanvasWidth = 0;
+ TInt32 numHorTiles = iImageInfo->NumOfHorizTiles();
+ TInt32 tileStartCanvas;
+ TInt32 tileEndCanvas;
+ TInt32 tileCompStartCanvas;
+ for(TUint16 indexX = 0; indexX < numHorTiles; ++indexX )
+ {
+ tileStartCanvas = Max( ( sizMarker.iXTOsiz + indexX * sizMarker.iXTsiz ), sizMarker.iXOsiz );
+ tileEndCanvas = Min( ( sizMarker.iXTOsiz + ( indexX + 1 ) * sizMarker.iXTsiz ), sizMarker.iXsiz );
+
+ // Add this tile's contribution to the total size
+ tileCompStartCanvas = TJ2kUtils::Ceil( tileStartCanvas, sizMarker.iXRsiz[0] );
+ tileCompCanvasWidth += TJ2kUtils::Ceil( tileEndCanvas, sizMarker.iXRsiz[0] ) - tileCompStartCanvas;
+ }
+
+ // Compute the height of the output image
+ TInt32 tileCompCanvasHeight = 0;
+ TInt32 numVerTiles = iImageInfo->NumOfVertTiles();
+ for(TUint16 indexY = 0; indexY < numVerTiles; ++indexY )
+ {
+ tileStartCanvas = Max( ( sizMarker.iYTOsiz + indexY * sizMarker.iYTsiz ), sizMarker.iYOsiz );
+ tileEndCanvas = Min( ( sizMarker.iYTOsiz + ( indexY + 1 ) * sizMarker.iYTsiz ), sizMarker.iYsiz );
+
+ // Add this tile's contribution to the total size
+ tileCompStartCanvas = TJ2kUtils::Ceil( tileStartCanvas, sizMarker.iYRsiz[0] );
+ tileCompCanvasHeight += TJ2kUtils::Ceil( tileEndCanvas, sizMarker.iYRsiz[0] ) - tileCompStartCanvas;
+ }
+
+ iFrame->iOverallSizeInPixels = TSize( tileCompCanvasWidth, tileCompCanvasHeight );
+
+ iFrame->iFrameCoordsInPixels.SetRect( TPoint( 0, 0 ), iFrame->iOverallSizeInPixels );
+ iFrame->iFrameSizeInTwips.SetSize( 0, 0 );
+
+ for ( TUint16 index = 0; index < sizMarker.iCsiz; ++index )
+ {
+ iFrame->iBitsPerPixel += ( ( sizMarker.iSsiz[index] & 0x7f ) + 1 );
+ }
+
+ // We can dither.
+ iFrame->iFlags |= TFrameInfo::ECanDither;
+
+ // Decoder is able to handle scaleable resolution
+ iFrame->iFlags |= TFrameInfo::EConstantAspectRatio;
+
+ if ( sizMarker.iCsiz > 1 )
+ {
+ iFrame->iFlags |= TFrameInfo::EColor;
+ }
+
+ // Animation is not allowed
+ iFrame->iDelay = 0;
+
+ switch ( iFrame->iBitsPerPixel )
+ {
+ case 1:
+ {
+ iFrame->iFrameDisplayMode = EGray2;
+ break;
+ }
+ case 2:
+ {
+ iFrame->iFrameDisplayMode = EGray4;
+ break;
+ }
+ case 4:
+ {
+ iFrame->iFrameDisplayMode = ( iFrame->iFlags & TFrameInfo::EColor ) ? EColor16 : EGray16;
+ break;
+ }
+ case 8:
+ {
+ iFrame->iFrameDisplayMode = ( iFrame->iFlags & TFrameInfo::EColor ) ? EColor16M : EGray256;
+ break;
+ }
+ case 12:
+ {
+ iFrame->iFrameDisplayMode = ( iFrame->iFlags & TFrameInfo::EColor ) ? EColor4K : EGray256;
+ break;
+ }
+ case 16:
+ {
+ iFrame->iFrameDisplayMode = EColor64K;
+ break;
+ }
+ case 24:
+ {
+ iFrame->iFrameDisplayMode = EColor16M;
+ break;
+ }
+ default:
+ {
+ iFrame->iFrameDisplayMode = EColor64K;
+ break;
+ }
+ }
+ }
+
+ // It is the offset that ICL framework used to read in
+ // more data from the image file.
+ iFrame->SetFrameDataOffset( iReader.iStartSOT );
+
+ // Frame header has been processed without error
+ // the flag is used by the ICL framework to determine
+ // whether it should continue processing or halt with error
+ iFrame->SetCurrentFrameState( TFrameInfo::EFrameInfoProcessingComplete );
+
+ return retCode;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::InitFrameL
+// Called from ICL framework to initialise frame.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kReadCodec::InitFrameL( TFrameInfo& /*aFrameInfo*/, CFrameImageData& /*aFrameData*/,
+ TBool aDisableErrorDiffusion, CFbsBitmap& aDestination,
+ CFbsBitmap* /*aDestinationMask*/ )
+ {
+ // Always use ERgb mode unless specified in the JP2 file format
+ TDisplayMode mode = ERgb;
+
+ TInt reductionFactor = ImageProcessorUtility::ReductionFactor( iFrame->iOverallSizeInPixels,
+ aDestination.SizeInPixels() );
+
+ iImageInfo->SetLevelDrop( (TUint8)reductionFactor );
+
+ // If the codestream doesn't contain enough wavelet levels to do the resolution
+ // reduction required by the framework / calling application, "extraLevels" are
+ // assigned to perform the resolution reduction. The "extra" resolution drop is
+ // performed at the output stage, i.e. all the samples are decoded, but only
+ // 1/4, 1/16, etc. are written to output.
+ if(reductionFactor > iImageInfo->MainMarker().iCod.iNumOfLevels)
+ {
+ iImageInfo->SetExtraLevelDrop( (TUint8)(reductionFactor - iImageInfo->MainMarker().iCod.iNumOfLevels) );
+ }
+ else
+ {
+ iImageInfo->SetExtraLevelDrop( 0 );
+ }
+
+ CImageProcessor* imageProc = ImageProcessorUtility::NewImageProcessorL( aDestination,
+ 0,
+ mode,
+ aDisableErrorDiffusion );
+ TPoint startAt( iFrame->iFrameCoordsInPixels.iTl.iX,
+ iFrame->iFrameCoordsInPixels.iTl.iY );
+
+ TRect imageSize( startAt, aDestination.SizeInPixels() );
+
+ // Prepare the bitmap using the image size
+ SetImageProcessor( imageProc );
+ imageProc->PrepareL( aDestination, imageSize );
+
+ // Clear bitmap so sensibly draw partial decodes
+ ClearBitmapL(aDestination, KRgbWhite);
+
+ iUseNewTile = ETrue;
+ iReader.iNewDataStart = iFrame->FrameDataOffset();
+ iStyleUsed = EUnknownDecoder;
+
+ iProgressBar = EFalse;
+ if ( ( iImageInfo->NumOfHorizTiles() == 1 ) &&
+ ( iImageInfo->NumOfVertTiles() == 1 ) )
+ {
+ // To force a return immediately from ProcessFrameL()
+ // on first entry to stimulate the occurrance of
+ // the progress bar
+ iProgressBar = ETrue;
+ }
+
+ if ( iFHState != EStateInSOT )
+ {
+ // We are in zoom in mode
+ iUseNextTile = iSequential = EFalse;
+ iFHState = EStateInSOT;
+ iLastTileIndex = 0;
+ iImageInfo->SetLastTilePartProcessed( (TUint16)0xffff );
+ iImageWriter->SetNewImageProcessor( imageProc );
+
+ if ( iJ2kInfo.iOption & TJ2kInfo::EJP2file )
+ {
+ iReader.iCSLength = iJ2kInfo.iCSBoxLength;
+
+ // We have read in all header information, so skip it
+ if ( iReader.iCSLength > iReader.iStartSOT )
+ {
+ iReader.iCSLength -= iReader.iStartSOT;
+ }
+ iReader.iDataUsed = 0;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ProcessFrameL
+// Collect the JP2 codestream Tile Part information.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::ProcessFrameL(TBufPtr8& aSrc)
+ {
+ // Start decoding the compressed data stream
+ TFrameState retCode = EFrameIncomplete;
+
+ iReader.iPtr = aSrc.Ptr();
+
+ iReader.iPtrStart = CONST_CAST( TUint8*, iReader.iPtr );
+ iReader.iPtrEnd = iReader.iPtrStart + aSrc.Length();
+
+ while ( iFHState != EStateInEOC )
+ {
+ iReader.iPtrStartMarker = CONST_CAST( TUint8*, iReader.iPtr );
+ switch ( iFHState )
+ {
+ case EStateInSOT:
+ {
+ retCode = ReadSOTL();
+ break;
+ }
+ case EStateInSOD:
+ {
+ retCode = ReadSODL();
+ break;
+ }
+ case EStateInBITSTREAM:
+ {
+ retCode = ReadBitStreamL();
+ break;
+ }
+ case EStateInCOD:
+ {
+ retCode = ReadCODL( EFalse );
+ break;
+ }
+ case EStateInCOC:
+ {
+ retCode = ReadCOCL( EFalse );
+ break;
+ }
+ case EStateInQCD:
+ {
+ retCode = ReadQCDL( EFalse );
+ break;
+ }
+ case EStateInQCC:
+ {
+ retCode = ReadQCCL( EFalse );
+ break;
+ }
+ case EStateInRGN:
+ {
+ retCode = ReadRGNL( EFalse );
+ break;
+ }
+ case EStateInPOC:
+ {
+ retCode = ReadPOCL( EFalse );
+ break;
+ }
+ case EStateInPPT:
+ {
+ retCode = ReadPPTL();
+ break;
+ }
+ case EStateInPLT:
+ {
+ retCode = ReadPLTL();
+ break;
+ }
+ case EStateInCOM:
+ {
+ retCode = ReadCOML( EFalse );
+ break;
+ }
+ case EStateInUnknown:
+ {
+ // Update the internal state based on the Marker
+ retCode = UpdateStateFromMarkerL();
+ break;
+ }
+ case EStateInSkipTile:
+ {
+ retCode = ReadSkipTileL();
+ break;
+ }
+ default:
+ {
+ // Unrecognized marker
+ User::Leave( KErrCorrupt );
+ break;
+ }
+ }
+ // Check for underflow
+ if ( retCode != EFrameComplete )
+ {
+ // Request to jump to another section of the image file
+ if ( retCode == EFrameIncompleteRepositionRequest )
+ {
+ // Update the internal counter for data processed
+ iReader.UpdateTileHeader();
+ }
+
+ aSrc.Shift( iReader.iPtr - iReader.iPtrStart );
+ return retCode;
+ }
+
+ if ( iFHState != EStateInSkipTile && iFHState != EStateInSOT )
+ {
+ // Update the internal counter for data processed
+ // only for the current tile
+ iReader.UpdateTileHeader();
+ }
+
+ if ( ( iProgressBar && iFHState != EStateInEOC ) || iDecodeTile )
+ {
+ iProgressBar = EFalse;
+ aSrc.Shift( iReader.iPtr - iReader.iPtrStart );
+ return EFrameIncomplete;
+ }
+ }
+
+ if ( iDecodeTile == EFalse )
+ {
+ ImageProcessor()->FlushPixels();
+ }
+
+ return EFrameComplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::GetNewDataPosition
+// Get the new offset where data should be read from.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kReadCodec::GetNewDataPosition( TInt& aPosition, TInt& /*aLength*/ )
+ {
+ // Set new offset position so that
+ // ICL framework will read in more image data for processing
+ aPosition = iReader.iNewDataStart + iJ2kInfo.iCSOffset;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::CJp2kReadCodec
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CJp2kReadCodec::CJp2kReadCodec( const TJ2kInfo& aJ2kInfo ) :
+ iJ2kInfo( aJ2kInfo )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CJp2kReadCodec::ConstructL()
+ {
+ iImageInfo = new ( ELeave ) CJ2kImageInfo;
+
+ // Invoke base class 2nd phase constructor.
+ CImageProcessorReadCodec::ConstructL();
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ReadSOCL
+// Verify and process Start of Codestream (SOC marker).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::ReadSOCL()
+ {
+ const TUint8* dataPtr = iReader.iPtr;
+
+ if ( iJ2kInfo.iOption & TJ2kInfo::EJP2file )
+ {
+ // Codestream box in JP2 file format
+ iReader.iCSLength = iJ2kInfo.iCSBoxLength;
+ iReader.iPtr += KJ2kBoxTypeLength;
+
+ if ( iReader.iCSLength == 1 )
+ {
+ // The XLBox shall exist and contains the actual length of the box
+ // XLBox is 8 bytes width
+ iReader.iCSLength = PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
+ iReader.iCSLength += PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
+
+ // Populate back to the iJ2kInfo
+ CONST_CAST( TJ2kInfo&, iJ2kInfo ).iCSBoxLength = iReader.iCSLength;
+ }
+ }
+
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerSize )
+ {
+ // Underflow, backup the pointer to the beginning
+ iReader.iPtr = dataPtr;
+ return EFrameIncomplete;
+ }
+
+ if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KSOC )
+ {
+ // Unrecognized SOC marker
+ User::Leave( KErrCorrupt );
+ }
+
+ // SIZ marker shall immediately follow the SOC marker
+ iFHState = EStateInSIZ;
+
+ return EFrameComplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ReadSIZL
+// Verify and process Image and Tile Size (SIZ marker).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::ReadSIZL()
+ {
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
+ {
+ // Underflow
+ return EFrameIncomplete;
+ }
+
+ if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KSIZ )
+ {
+ // Unrecognized SIZ marker
+ User::Leave( KErrCorrupt );
+ }
+
+ TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
+ {
+ // Underflow, backup the iterator to the beginning of the marker
+ iReader.iPtr -= KMarkerMinLength;
+ return EFrameIncomplete;
+ }
+
+ TSizMarker& sizMarker = CONST_CAST( TSizMarker&, iImageInfo->SizMarker() );
+
+ sizMarker.iRsiz = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ sizMarker.iXsiz = PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
+ sizMarker.iYsiz = PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
+ sizMarker.iXOsiz = PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
+ sizMarker.iYOsiz = PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
+ sizMarker.iXTsiz = PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
+ sizMarker.iYTsiz = PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
+ sizMarker.iXTOsiz = PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
+ sizMarker.iYTOsiz = PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
+ sizMarker.iCsiz = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+
+ if(sizMarker.iXOsiz > sizMarker.iXsiz || sizMarker.iYOsiz > sizMarker.iYsiz)
+ {
+ // Image offset is larger than image size, exit
+ User::Leave( KErrCorrupt );
+ }
+
+ if(sizMarker.iXTOsiz > sizMarker.iXsiz || sizMarker.iYTOsiz > sizMarker.iYsiz)
+ {
+ // Tile offset is larger than image size, exit
+ User::Leave( KErrCorrupt );
+ }
+
+ for ( TUint16 index = 0; index < sizMarker.iCsiz; ++index )
+ {
+ // Component's information
+ User::LeaveIfError( sizMarker.iSsiz.Append( *iReader.iPtr++ ) );
+ User::LeaveIfError( sizMarker.iXRsiz.Append( *iReader.iPtr++ ) );
+ User::LeaveIfError( sizMarker.iYRsiz.Append( *iReader.iPtr++ ) );
+
+ if((( sizMarker.iSsiz[index] & 0x7f ) + 1) > KMaxBitdepth )
+ {
+ // Invalid bitdepth for this component, exit
+ User::Leave( KErrCorrupt );
+ }
+ }
+
+ if ( iJ2kInfo.iCMPList.Count() > sizMarker.iCsiz )
+ {
+ // Populate the remaining component Rsiz using component 0's Rsiz
+ TUint16 indexi = (TUint16)( iJ2kInfo.iCMPList.Count() - sizMarker.iCsiz );
+ while ( indexi )
+ {
+ User::LeaveIfError( sizMarker.iXRsiz.Append( sizMarker.iXRsiz[0] ) );
+ User::LeaveIfError( sizMarker.iYRsiz.Append( sizMarker.iYRsiz[0] ) );
+ --indexi;
+ }
+ }
+
+ // Make sure we read all the data
+ if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
+ {
+ // We must be missing some data in the marker
+ User::Leave( KErrCorrupt );
+ }
+
+ // Any valid marker may come after SIZ marker
+ iFHState = EStateInUnknown;
+
+ return EFrameComplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ReadCODL
+// Verify and process Coding Style Default (COD marker).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::ReadCODL( TBool aMain )
+ {
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
+ {
+ // Underflow
+ return EFrameIncomplete;
+ }
+
+ if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KCOD )
+ {
+ // Unrecognized COD marker
+ User::Leave(KErrCorrupt);
+ }
+
+ TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
+ {
+ // Underflow, backup the iterator to the beginning of the marker
+ iReader.iPtr -= KMarkerMinLength;
+ return EFrameIncomplete;
+ }
+
+ TCODMarker *codMarker = NULL;
+
+ if ( aMain )
+ {
+ TMainMarker& mainMarker = CONST_CAST( TMainMarker&, iImageInfo->MainMarker() );
+ codMarker = &mainMarker.iCod;
+ }
+ else
+ {
+ // COD in Tile Part Header
+ codMarker = new ( ELeave ) TCODMarker;
+ CleanupDeletePushL( codMarker );
+ }
+
+ codMarker->iScod = *iReader.iPtr++;
+ codMarker->iProgressionOrder = *iReader.iPtr++;
+ codMarker->iNumOfLayers = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ codMarker->iColorTransformation = *iReader.iPtr++;
+ codMarker->iNumOfLevels = *iReader.iPtr++;
+
+ TUint8 tmp = (TUint8)( ( *iReader.iPtr++ ) + 2 );
+ codMarker->iCodeBlockSiz.iWidth = 1 << tmp;
+
+ tmp = (TUint8)( ( *iReader.iPtr++ ) + 2 );
+ codMarker->iCodeBlockSiz.iHeight = 1 << tmp;
+
+ codMarker->iCodeBlockStyle = *iReader.iPtr++;
+ codMarker->iWaveletTransformation = *iReader.iPtr++;
+
+ if ( codMarker->iScod & 0x01 )
+ {
+ // Entropy coder with precincts defined below
+ codMarker->iPrecinctSiz = HBufC8::NewL( codMarker->iNumOfLevels + 1 );
+ for ( TUint8 index = 0; index < codMarker->iNumOfLevels + 1; ++index )
+ {
+ codMarker->iPrecinctSiz->Des().Append( *iReader.iPtr++ );
+ }
+ }
+
+ // Make sure we read all the data
+ if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
+ {
+ // We must be missing some data in the marker
+ User::Leave( KErrCorrupt );
+ }
+
+ if ( !aMain )
+ {
+ CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
+
+ // Append COD to the current tile and decrement the tile length
+ tile.AppendCOD( codMarker, markerLength + KMarkerSize );
+ CleanupStack::Pop();
+ }
+
+ // Any valid marker may come after COD marker
+ iFHState = EStateInUnknown;
+ return EFrameComplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ReadCOCL
+// Verify and process Coding Style Component (COC marker).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::ReadCOCL( TBool aMain )
+ {
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
+ {
+ // Underflow
+ return EFrameIncomplete;
+ }
+
+ if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KCOC )
+ {
+ // Unrecognized COC marker
+ User::Leave( KErrCorrupt );
+ }
+
+ TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
+ {
+ // Underflow, backup the iterator to the beginning of the marker
+ iReader.iPtr -= KMarkerMinLength;
+ return EFrameIncomplete;
+ }
+
+ const TSizMarker& sizMarker = iImageInfo->SizMarker();
+
+ TCOCMarker *cocMarker = new ( ELeave ) TCOCMarker;
+ CleanupDeletePushL(cocMarker);
+
+ if ( sizMarker.iCsiz < 257 )
+ {
+ // 8 bits component
+ cocMarker->iCcoc = *iReader.iPtr++;
+ }
+ else
+ {
+ // 16 bits component
+ cocMarker->iCcoc = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ }
+
+ cocMarker->iScoc = *iReader.iPtr++;
+ cocMarker->iNumOfLevels = *iReader.iPtr++;
+
+ TUint8 tmp = (TUint8)( ( *iReader.iPtr++ ) + 2 );
+ cocMarker->iCodeBlockSiz.iWidth = 1 << tmp;
+
+ tmp = (TUint8)( ( *iReader.iPtr++ ) + 2 );
+ cocMarker->iCodeBlockSiz.iHeight = 1 << tmp;
+
+ cocMarker->iCodeBlockStyle = *iReader.iPtr++;
+ cocMarker->iWaveletTransformation = *iReader.iPtr++;
+
+ if ( cocMarker->iScoc & 0x01 )
+ {
+ // Entropy coder with precincts defined below
+ cocMarker->iPrecinctSiz = HBufC8::NewL( cocMarker->iNumOfLevels + 1 );
+ for ( TUint8 index = 0; index < cocMarker->iNumOfLevels + 1; ++index )
+ {
+ cocMarker->iPrecinctSiz->Des().Append( *iReader.iPtr++ );
+ }
+ }
+
+ // Make sure we read all the data
+ if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
+ {
+ // We must be missing some data in the marker
+ User::Leave( KErrCorrupt );
+ }
+
+ if ( aMain )
+ {
+ iImageInfo->AppendCOCL( cocMarker );
+ }
+ else
+ {
+ CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
+
+ // Append COC to the current tile and decrement the tile length
+ tile.AppendCOCL( cocMarker, markerLength + KMarkerSize );
+ }
+ CleanupStack::Pop();
+
+ // Any valid marker may come after COC marker
+ iFHState = EStateInUnknown;
+
+ return EFrameComplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ReadQCDL
+// Verify and process Quantization Default (QCD marker).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::ReadQCDL( TBool aMain )
+ {
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
+ {
+ // Underflow
+ return EFrameIncomplete;
+ }
+
+ if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KQCD )
+ {
+ // Unrecognized QCD marker
+ User::Leave( KErrCorrupt );
+ }
+
+ TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
+ {
+ // Underflow, backup the iterator to the beginning of the marker
+ iReader.iPtr -= KMarkerMinLength;
+ return EFrameIncomplete;
+ }
+
+ TQCDMarker *qcdMarker = NULL;
+
+ if ( aMain )
+ {
+ TMainMarker& mainMarker = CONST_CAST( TMainMarker&, iImageInfo->MainMarker() );
+ qcdMarker = &mainMarker.iQcd;
+ }
+ else
+ {
+ // QCD in Tile Part Header
+ qcdMarker = new ( ELeave ) TQCDMarker;
+
+ CleanupDeletePushL( qcdMarker );
+ }
+
+ qcdMarker->iSqcd = *iReader.iPtr++;
+
+ if ( qcdMarker->iSqcd & 0x01 )
+ {
+ // Scalar derived (values signalled for NLL subband only)
+ TUint16 tmp = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ qcdMarker->iExponent = HBufC8::NewL(1);
+ qcdMarker->iExponent->Des().Append( (TUint8)( (tmp >> 11) & 0x1f ) );
+ qcdMarker->iMantissa = HBufC16::NewL(1);
+ qcdMarker->iMantissa->Des().Append( (TUint16)( tmp & 0x07ff ) );
+ }
+ else
+ {
+ TInt entries = markerLength - ( iReader.iPtr - iReader.iPtrStartMarker ) + KMarkerSize;
+ if ( qcdMarker->iSqcd & 0x1f )
+ {
+ // Word oriented
+ TUint16 tmp;
+ qcdMarker->iExponent = HBufC8::NewL( entries / 2 );
+ qcdMarker->iMantissa = HBufC16::NewL( entries / 2 );
+
+ while ( entries >= 2 )
+ {
+ tmp = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ qcdMarker->iExponent->Des().Append((TUint8)( ( tmp >> 11) & 0x1f ) );
+ qcdMarker->iMantissa->Des().Append((TUint16)( tmp & 0x07ff ) );
+ entries -= 2;
+ }
+ }
+ else
+ {
+ // No quantization
+ qcdMarker->iExponent = HBufC8::NewL( entries );
+ while ( entries )
+ {
+ qcdMarker->iExponent->Des().Append( (TUint8)( ( *iReader.iPtr++ >> 3 ) & 0x1f ) );
+ --entries;
+ }
+ }
+ }
+
+ // Make sure we read all the data
+ if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
+ {
+ // We must be missing some data in the marker
+ User::Leave( KErrCorrupt );
+ }
+
+ if ( !aMain )
+ {
+ CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
+
+ // Append QCD to the current tile and decrement the tile length
+ tile.AppendQCD( qcdMarker, markerLength + KMarkerSize );
+ CleanupStack::Pop();
+ }
+
+ // Any valid marker may come after QCD marker
+ iFHState = EStateInUnknown;
+
+ return EFrameComplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ReadQCCL
+// Verify and process Quantization Component (QCC marker).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::ReadQCCL(TBool aMain)
+ {
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
+ {
+ // Underflow
+ return EFrameIncomplete;
+ }
+
+ if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KQCC )
+ {
+ // Unrecognized QCC marker
+ User::Leave( KErrCorrupt );
+ }
+
+ TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < (markerLength - KMarkerLength ) )
+ {
+ // Underflow, backup the iterator to the beginning of the marker
+ iReader.iPtr -= KMarkerMinLength;
+ return EFrameIncomplete;
+ }
+
+ const TSizMarker& sizMarker = iImageInfo->SizMarker();
+
+ TQCCMarker *qccMarker = new (ELeave) TQCCMarker;
+
+ CleanupDeletePushL( qccMarker );
+
+ if ( sizMarker.iCsiz < 257 )
+ {
+ // 8 bits component
+ qccMarker->iCqcc = *iReader.iPtr++;
+ }
+ else
+ {
+ // 16 bit component
+ qccMarker->iCqcc = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ }
+
+ qccMarker->iSqcc = *iReader.iPtr++;
+
+ if ( qccMarker->iSqcc & 0x01 )
+ {
+ // Scalar derived (values signalled for NLL subband only)
+ TUint16 tmp = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ qccMarker->iExponent = HBufC8::NewL(1);
+ qccMarker->iExponent->Des().Append( (TUint8)( ( tmp >> 11 ) & 0x1f ) );
+ qccMarker->iMantissa = HBufC16::NewL(1);
+ qccMarker->iMantissa->Des().Append( (TUint16)( tmp & 0x07ff ) );
+ }
+ else
+ {
+ TInt entries = markerLength - ( iReader.iPtr - iReader.iPtrStartMarker ) + KMarkerSize;
+ if ( qccMarker->iSqcc & 0x1f )
+ {
+ // Word oriented
+ TUint16 tmp;
+ qccMarker->iExponent = HBufC8::NewL( entries / 2 );
+ qccMarker->iMantissa = HBufC16::NewL( entries / 2 );
+
+ while ( entries >= 2 )
+ {
+ tmp = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ qccMarker->iExponent->Des().Append( (TUint8)( ( tmp >> 11 ) & 0x1f ) );
+ qccMarker->iMantissa->Des().Append( (TUint16)( tmp & 0x07ff ) );
+ entries -= 2;
+ }
+ }
+ else
+ {
+ // No quantization
+ qccMarker->iExponent = HBufC8::NewL( entries );
+ while ( entries )
+ {
+ qccMarker->iExponent->Des().Append( (TUint8)( ( *iReader.iPtr++ >> 3 ) & 0x1f ) );
+ --entries;
+ }
+ }
+ }
+
+ // Make sure we read all the data
+ if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
+ {
+ // We must be missing some data in the marker
+ User::Leave( KErrCorrupt );
+ }
+
+ if ( aMain )
+ {
+ iImageInfo->AppendQCCL( qccMarker );
+ }
+ else
+ {
+ CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
+
+ // Append QCC to the current tile and decrement the tile length
+ tile.AppendQCCL( qccMarker, markerLength + KMarkerSize );
+ }
+ CleanupStack::Pop();
+
+ // Any valid marker may come after QCC marker
+ iFHState = EStateInUnknown;
+
+ return EFrameComplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ReadRGNL
+// Verify and process Region of Interest (RGN marker).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::ReadRGNL( TBool aMain )
+ {
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
+ {
+ // Underflow
+ return EFrameIncomplete;
+ }
+
+ if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KRGN )
+ {
+ // Unrecognized RGN marker
+ User::Leave( KErrCorrupt );
+ }
+
+ TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
+ {
+ // Underflow, backup the iterator to the beginning of the marker
+ iReader.iPtr -= KMarkerMinLength;
+ return EFrameIncomplete;
+ }
+
+ const TSizMarker& sizMarker = iImageInfo->SizMarker();
+
+ TRGNMarker *rgnMarker = new ( ELeave ) TRGNMarker;
+ CleanupDeletePushL( rgnMarker );
+
+ if ( sizMarker.iCsiz < 257 )
+ {
+ // 8 bits component
+ rgnMarker->iCrgn = *iReader.iPtr++;
+ }
+ else
+ {
+ // 16 bits component
+ rgnMarker->iCrgn = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ }
+
+ rgnMarker->iSrgn = *iReader.iPtr++;
+ rgnMarker->iSPrgn = *iReader.iPtr++;
+
+ // Make sure we read all the data
+ if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
+ {
+ // We must be missing some data in the marker
+ User::Leave( KErrCorrupt );
+ }
+
+ if ( aMain )
+ {
+ iImageInfo->AppendRGNL( rgnMarker );
+ }
+ else
+ {
+ CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
+
+ // Append RGN to the current tile and decrement the tile length
+ tile.AppendRGNL( rgnMarker, markerLength + KMarkerSize );
+ }
+ CleanupStack::Pop();
+
+ // Any valid marker may come after RGN marker
+ iFHState = EStateInUnknown;
+
+ return EFrameComplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ReadPOCL
+// Verify and process Progression Order Change ( POC marker ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::ReadPOCL( TBool aMain )
+ {
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
+ {
+ // Underflow
+ return EFrameIncomplete;
+ }
+
+ if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KPOC )
+ {
+ // Unrecognized COC marker
+ User::Leave( KErrCorrupt );
+ }
+
+ TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
+ {
+ // Underflow, backup the iterator to the beginning of the marker
+ iReader.iPtr -= KMarkerMinLength;
+ return EFrameIncomplete;
+ }
+
+ const TSizMarker& sizMarker = iImageInfo->SizMarker();
+
+ TPOCMarker *pocMarker = new ( ELeave ) TPOCMarker;
+ CleanupDeletePushL( pocMarker );
+
+ TInt entries = markerLength - KMarkerSize;
+ TInt sizEntry = ( sizMarker.iCsiz < 257 ) ? 7 : 9;
+
+ while ( entries >= sizEntry )
+ {
+ User::LeaveIfError( pocMarker->iRSpoc.Append( *iReader.iPtr++ ) );
+
+ if ( sizMarker.iCsiz < 257 )
+ {
+ // 8 bits component
+ User::LeaveIfError( pocMarker->iCSpoc.Append( *iReader.iPtr++ ) );
+ }
+ else
+ {
+ // 16 bits component
+ User::LeaveIfError( pocMarker->iCSpoc.Append( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) ) );
+ }
+ User::LeaveIfError( pocMarker->iLYEpoc.Append( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) ) );
+ User::LeaveIfError( pocMarker->iREpoc.Append( *iReader.iPtr++ ) );
+ if ( sizMarker.iCsiz < 257 )
+ {
+ // 8 bits component
+ User::LeaveIfError( pocMarker->iCEpoc.Append( *iReader.iPtr++ ) );
+ }
+ else
+ {
+ // 16 bits component
+ User::LeaveIfError( pocMarker->iCEpoc.Append( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) ) );
+ }
+ User::LeaveIfError( pocMarker->iPpoc.Append( *iReader.iPtr++ ) );
+
+ entries -= sizEntry;
+ }
+
+ // Make sure we read all the data
+ if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
+ {
+ // We must be missing some data in the marker
+ User::Leave( KErrCorrupt );
+ }
+
+ if ( aMain )
+ {
+ iImageInfo->AppendPOCL( pocMarker );
+ }
+ else
+ {
+ CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
+
+ // Append POC to the current tile and decrement the tile length
+ tile.AppendPOCL( pocMarker, markerLength + KMarkerSize );
+ }
+ CleanupStack::Pop( );
+
+ // Any valid marker may come after POC marker
+ iFHState = EStateInUnknown;
+
+ return EFrameComplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ReadPPML
+// Verify and process Packed Packet Headers, Main Header ( PPM marker ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::ReadPPML()
+ {
+ TUint8 isUnderflow = EFalse;
+ if ( !iPreviousPPM )
+ {
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
+ {
+ // Underflow
+ return EFrameIncomplete;
+ }
+
+ if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KPPM )
+ {
+ // Unrecognized PPM marker
+ User::Leave( KErrCorrupt );
+ }
+
+ TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( KMarkerLength + 1 ) )
+ {
+ // Underflow, we need Zppm and Nppm to be in the buffer
+ // backup the iterator to the beginning of the marker
+ iReader.iPtr -= KMarkerMinLength;
+ return EFrameIncomplete;
+ }
+
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
+ {
+ // Underflow, will keep reading
+ isUnderflow = ETrue;
+ }
+
+ TPPMMarker *ppmMarker = new ( ELeave ) TPPMMarker;
+ CleanupDeletePushL( ppmMarker );
+
+ ppmMarker->iZppm = *iReader.iPtr++;
+ TUint32 entries = (TUint32)( markerLength - KMarkerSize - 1 );
+
+ ppmMarker->iNppm = entries;
+ ppmMarker->iIppm = HBufC8::NewL( entries );
+
+ if ( !isUnderflow )
+ {
+ ppmMarker->iIppm->Des( ).Append( iReader.iPtr, entries );
+ iReader.iPtr += entries;
+ iPreviousPPM = 0;
+
+ // Make sure we read all the data
+ if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
+ {
+ // We must be missing some data in the marker
+ User::Leave( KErrCorrupt );
+ }
+ }
+ else
+ {
+ ppmMarker->iIppm->Des().Append( iReader.iPtr, ( iReader.iPtrEnd - iReader.iPtr ) );
+ ppmMarker->iRemainder = (TUint32)( entries - ( iReader.iPtrEnd - iReader.iPtr ) );
+ iReader.iPtr = iReader.iPtrEnd;
+ iPreviousPPM = ppmMarker;
+ }
+
+ // Insert the new PPM marker into the right order
+ TMainMarker& mainMarker = CONST_CAST( TMainMarker&, iImageInfo->MainMarker() );
+ TUint8 tmp = ETrue;
+ if ( mainMarker.iPpm.Count() > 0 &&
+ mainMarker.iPpm[mainMarker.iPpm.Count() - 1]->iZppm > ppmMarker->iZppm )
+ {
+ for ( entries = 0; entries < (TUint32)mainMarker.iPpm.Count(); ++entries )
+ {
+ // Order by iZppm of the PPM marker
+ if ( mainMarker.iPpm[entries]->iZppm > ppmMarker->iZppm )
+ {
+ User::LeaveIfError( mainMarker.iPpm.Insert( ppmMarker, entries ) );
+
+ tmp = EFalse;
+ entries = (TUint32)mainMarker.iPpm.Count();
+ }
+ }
+ }
+
+ if ( tmp )
+ {
+ User::LeaveIfError( mainMarker.iPpm.Append( ppmMarker ) );
+ }
+ CleanupStack::Pop();
+ }
+ else
+ {
+ if ( (TUint32)( iReader.iPtrEnd - iReader.iPtr ) < iPreviousPPM->iRemainder )
+ {
+ // Continue reading incomplete COM marker
+ iPreviousPPM->iIppm->Des().Append( iReader.iPtr, ( iReader.iPtrEnd - iReader.iPtr ) );
+ iPreviousPPM->iRemainder = (TUint32)( iPreviousPPM->iRemainder - ( iReader.iPtrEnd - iReader.iPtr ) );
+ iReader.iPtr = iReader.iPtrEnd;
+ isUnderflow = ETrue;
+ }
+ else
+ {
+ // We have the complete COM marker now
+ iPreviousPPM->iIppm->Des().Append( iReader.iPtr, iPreviousPPM->iRemainder );
+ iReader.iPtr += iPreviousPPM->iRemainder;
+ iPreviousPPM->iRemainder = 0;
+ iPreviousPPM = 0;
+ }
+ }
+
+ if ( !isUnderflow )
+ {
+ // Any valid marker may come after PPM marker
+ iFHState = EStateInUnknown;
+ return EFrameComplete;
+ }
+ else
+ {
+ // Underflow, stay in the same state
+ iReader.UpdateMainHeader();
+ return EFrameIncomplete;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ReadTLML
+// Verify and process Tile Part Lengths, Main Header ( TLM marker ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::ReadTLML()
+ {
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
+ {
+ // Underflow
+ return EFrameIncomplete;
+ }
+
+ if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KTLM )
+ {
+ // Unrecognized TLM marker
+ User::Leave( KErrCorrupt );
+ }
+
+ TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
+ {
+ // Underflow, backup the iterator to the beginning of the marker
+ iReader.iPtr -= KMarkerMinLength;
+ return EFrameIncomplete;
+ }
+
+ TTLMMarker *tlmMarker = new ( ELeave ) TTLMMarker;
+ CleanupDeletePushL( tlmMarker );
+
+ tlmMarker->iZtlm = *iReader.iPtr++;
+ tlmMarker->iStlm = *iReader.iPtr++;
+
+ TInt entries = markerLength - ( 2 * KMarkerSize );
+ TUint8 st = (TUint8)( ( tlmMarker->iStlm >> 4 ) & 0x03 );
+ TUint8 sp = (TUint8)( ( tlmMarker->iStlm >> 6 ) & 0x01 );
+ TInt sizEntry = st;
+ sizEntry += ( sp ? 4 : 2 );
+
+ while ( entries >= sizEntry )
+ {
+ if ( st == 1 )
+ {
+ // 8 bits tile index
+ User::LeaveIfError( tlmMarker->iTtlm.Append( *iReader.iPtr++ ) );
+ }
+ else if ( st == 2 )
+ {
+ // 16 bits tile index
+ User::LeaveIfError( tlmMarker->iTtlm.Append( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) ) );
+ }
+ if ( sp ) //lint !e961 no else is needed here at the end of if...else if
+ {
+ // 32 bits length
+ User::LeaveIfError( tlmMarker->iPtlm.Append( PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr ) ) );
+ }
+ else
+ {
+ // 16 bits length
+ User::LeaveIfError( tlmMarker->iPtlm.Append( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) ) );
+ }
+ entries -= sizEntry;
+ }
+
+ // Make sure we read all the data
+ if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
+ {
+ // We must be missing some data in the marker
+ User::Leave( KErrCorrupt );
+ }
+
+ // Insert the new TLM marker into the right order
+ TMainMarker& mainMarker = CONST_CAST( TMainMarker&, iImageInfo->MainMarker() );
+ sp = 1;
+ for ( entries = 0; entries < mainMarker.iTlm.Count(); ++entries )
+ {
+ // Order by iZtlm of the TLM marker
+ if ( mainMarker.iTlm[entries]->iZtlm > tlmMarker->iZtlm )
+ {
+ User::LeaveIfError( mainMarker.iTlm.Insert( tlmMarker, entries ) );
+ sp = 0;
+ entries = mainMarker.iTlm.Count();
+ }
+ }
+
+ if ( sp )
+ {
+ User::LeaveIfError( mainMarker.iTlm.Append( tlmMarker ) );
+ }
+ CleanupStack::Pop();
+
+ // Any valid marker may come after TLM marker
+ iFHState = EStateInUnknown;
+
+ return EFrameComplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ReadPLML
+// Verify and process Packet Length, Main Header ( PLM marker ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::ReadPLML()
+ {
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
+ {
+ // Underflow
+ return EFrameIncomplete;
+ }
+
+ if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KPLM )
+ {
+ // Unrecognized PLM marker
+ User::Leave( KErrCorrupt );
+ }
+
+ TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
+ {
+ // Underflow, backup the iterator to the beginning of the marker
+ iReader.iPtr -= KMarkerMinLength;
+ return EFrameIncomplete;
+ }
+
+ TPLMMarker *plmMarker = new ( ELeave ) TPLMMarker;
+ CleanupDeletePushL( plmMarker );
+
+ plmMarker->iZplm = *iReader.iPtr++;
+ TUint32 entries = (TUint32)( markerLength - KMarkerSize - 1 );
+
+ plmMarker->iNplm = (TUint8)entries;
+ plmMarker->iIplm = HBufC8::NewL( entries );
+ plmMarker->iIplm->Des().Append( iReader.iPtr, entries );
+ iReader.iPtr += entries;
+
+ // Make sure we read all the data
+ if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
+ {
+ // We must be missing some data in the marker
+ User::Leave( KErrCorrupt );
+ }
+
+ // Insert the new PLM marker into the right order
+ TMainMarker& mainMarker = CONST_CAST( TMainMarker&, iImageInfo->MainMarker() );
+ TUint8 tmp = ETrue;
+
+ if ( mainMarker.iPlm.Count() > 0 &&
+ mainMarker.iPlm[mainMarker.iPlm.Count() - 1]->iZplm > plmMarker->iZplm )
+ {
+ for ( entries = 0; entries < (TUint32)mainMarker.iPlm.Count(); ++entries )
+ {
+ // Order by iZplm of the PLM marker
+ if ( mainMarker.iPlm[entries]->iZplm > plmMarker->iZplm )
+ {
+ User::LeaveIfError( mainMarker.iPlm.Insert( plmMarker, entries ) );
+ tmp = EFalse;
+ entries = (TUint32)mainMarker.iPlm.Count();
+ }
+ }
+ }
+
+ if ( tmp )
+ {
+ User::LeaveIfError( mainMarker.iPlm.Append( plmMarker ) );
+ }
+ CleanupStack::Pop();
+
+ // Any valid marker may come after PLM marker
+ iFHState = EStateInUnknown;
+
+ return EFrameComplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ReadCRGL
+// Verify and process Component Registration, Main Header ( CRG marker ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::ReadCRGL()
+ {
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
+ {
+ // Underflow
+ return EFrameIncomplete;
+ }
+
+ if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KCRG )
+ {
+ // Unrecognized CRG marker
+ User::Leave( KErrCorrupt );
+ }
+
+ TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
+ {
+ // Underflow, backup the iterator to the beginning of the marker
+ iReader.iPtr -= KMarkerMinLength;
+ return EFrameIncomplete;
+ }
+
+ TCRGMarker *crgMarker = new ( ELeave ) TCRGMarker;
+ CleanupDeletePushL( crgMarker );
+
+ TInt entries = markerLength - KMarkerSize;
+ TUint16 xCrg;
+ TUint16 yCrg;
+ while ( entries )
+ {
+ xCrg = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ yCrg = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ User::LeaveIfError( crgMarker->iXYcrg.Append( TPoint( xCrg, yCrg ) ) );
+ entries -= 4;
+ }
+
+ // Make sure we read all the data
+ if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
+ {
+ // We must be missing some data in the marker
+ User::Leave( KErrCorrupt );
+ }
+
+ iImageInfo->AppendCRGL( crgMarker );
+
+ CleanupStack::Pop( );
+
+ // Any valid marker may come after CRG marker
+ iFHState = EStateInUnknown;
+
+ return EFrameComplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ReadCOML
+// Verify and process Comment ( COM marker ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::ReadCOML( TBool aMain )
+ {
+ TUint8 isUnderflow = EFalse;
+ if ( !iPreviousCOM )
+ {
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
+ {
+ // Underflow
+ return EFrameIncomplete;
+ }
+
+ if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KCME )
+ {
+ // Unrecognized COM marker
+ User::Leave( KErrCorrupt );
+ }
+
+ TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerLength )
+ {
+ // Underflow, we need Rcom to be in the buffer
+ // backup the iterator to the beginning of the marker
+ iReader.iPtr -= KMarkerMinLength;
+ return EFrameIncomplete;
+ }
+
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
+ {
+ // Underflow, will keep reading
+ isUnderflow = ETrue;
+ }
+
+ TCOMMarker* comMarker = new ( ELeave ) TCOMMarker;
+ CleanupDeletePushL( comMarker );
+
+ comMarker->iRcom = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ TInt entries = markerLength - ( 2 * KMarkerSize );
+
+ comMarker->iCcom = HBufC8::NewL( entries );
+ if ( !isUnderflow )
+ {
+ comMarker->iCcom->Des().Append( iReader.iPtr, entries );
+ iReader.iPtr += entries;
+ iPreviousCOM = 0;
+
+ // Make sure we read all the data
+ if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
+ {
+ // We must be missing some data in the marker
+ User::Leave( KErrCorrupt );
+ }
+ }
+ else
+ {
+ comMarker->iCcom->Des().Append( iReader.iPtr, ( iReader.iPtrEnd - iReader.iPtr ) );
+ comMarker->iRemainder = (TUint16)( entries - ( iReader.iPtrEnd - iReader.iPtr ) );
+ iReader.iPtr = iReader.iPtrEnd;
+ iPreviousCOM = comMarker;
+ }
+
+ if ( aMain )
+ {
+ iImageInfo->AppendCOML( comMarker );
+ }
+ else
+ {
+ CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
+
+ // Append COM to the current tile and decrement the tile length
+ tile.AppendCOML( comMarker, markerLength + KMarkerSize );
+ }
+ CleanupStack::Pop();
+ }
+ else
+ {
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < iPreviousCOM->iRemainder )
+ {
+ // Continue reading incomplete COM marker
+ iPreviousCOM->iCcom->Des().Append( iReader.iPtr, ( iReader.iPtrEnd - iReader.iPtr ) );
+ iPreviousCOM->iRemainder = (TUint16)( iPreviousCOM->iRemainder - ( iReader.iPtrEnd - iReader.iPtr ) );
+ iReader.iPtr = iReader.iPtrEnd;
+ isUnderflow = ETrue;
+ }
+ else
+ {
+ // We have the complete COM marker now
+ iPreviousCOM->iCcom->Des( ).Append( iReader.iPtr, iPreviousCOM->iRemainder );
+ iReader.iPtr += iPreviousCOM->iRemainder;
+ iPreviousCOM->iRemainder = 0;
+ iPreviousCOM = 0;
+ }
+ }
+
+ if ( !isUnderflow )
+ {
+ // Any valid marker may come after COM marker
+ iFHState = EStateInUnknown;
+ return EFrameComplete;
+ }
+ else
+ {
+ // Underflow, stay in the same state
+ if ( aMain )
+ {
+ iReader.UpdateMainHeader( );
+ }
+ return EFrameIncomplete;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ReadSOTL
+// Verify and process Start of Tile Part ( SOT marker ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::ReadSOTL()
+ {
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
+ {
+ // Underflow
+ return EFrameIncomplete;
+ }
+
+ if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KSOT )
+ {
+ // Unrecognized SOT marker
+ User::Leave( KErrCorrupt );
+ }
+
+ TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
+ {
+ // Underflow, backup the iterator to the beginning of the marker
+ iReader.iPtr -= KMarkerMinLength;
+ return EFrameIncomplete;
+ }
+
+ TSotMarker sotMarker;
+ sotMarker.iIsot = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+ sotMarker.iPsot = PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
+ sotMarker.iTPsot = *iReader.iPtr++;
+ sotMarker.iTNsot = *iReader.iPtr++;
+
+ if(sotMarker.iIsot >= ( iImageInfo->NumOfHorizTiles() * iImageInfo->NumOfVertTiles() ))
+ {
+ // Invalid tile index, exceeds the number of tiles, exit
+ User::Leave( KErrCorrupt );
+ }
+
+ if ( sotMarker.iPsot == 0 )
+ {
+ // Try to look for tile part length information
+ // from the TLM in the main header - if there is one
+ iImageInfo->GetFromTLM( sotMarker );
+ }
+
+ iImageInfo->IncrementLastTilePartProcessed();
+
+ if ( iUseNewTile )
+ {
+ if ( sotMarker.iIsot < iLastTileIndex )
+ {
+ // Skip all tiles with iIsot smaller than the iLastTileIndex
+ iReader.iSkipLength = sotMarker.iPsot - markerLength - KMarkerSize;
+ iUseNewTile = EFalse;
+ iFHState = EStateInSkipTile;
+ return EFrameComplete;
+ }
+
+ if(sotMarker.iTPsot >= sotMarker.iTNsot)
+ {
+ // Skip the tiles where tile part index is larger than
+ // the number of tile parts
+ iReader.iSkipLength = sotMarker.iPsot - markerLength - KMarkerSize;
+ iUseNewTile = EFalse;
+ iFHState = EStateInSkipTile;
+ return EFrameComplete;
+ }
+
+ // Start using this tile as the current tile
+ iLastTileIndex = sotMarker.iIsot;
+
+ // Save the next tile offset
+ iReader.iNewDataStart += sotMarker.iPsot;
+ iUseNextTile = iSequential = ETrue;
+ }
+ else
+ {
+ if ( sotMarker.iIsot != iLastTileIndex )
+ {
+ if ( iUseNextTile )
+ {
+ if ( sotMarker.iIsot > iLastTileIndex )
+ {
+ iUseNextTile = EFalse;
+ }
+ }
+ iSequential = EFalse;
+
+ // Skip all tiles that are not equal to current tile
+ iReader.iSkipLength = sotMarker.iPsot - markerLength - KMarkerSize;
+ iFHState = EStateInSkipTile;
+ return EFrameComplete;
+ }
+ else
+ {
+ // Tiles are in sequential order
+ if ( iUseNextTile && iSequential )
+ {
+ // Save the next tile offset
+ iReader.iNewDataStart += sotMarker.iPsot;
+ }
+ }
+ }
+
+ CJ2kTileInfo *tile = 0;
+ if ( iUseNewTile )
+ {
+ tile = CJ2kTileInfo::NewLC( *iImageInfo, iReader );
+ }
+ else
+ {
+ tile = CONST_CAST( CJ2kTileInfo*, &iImageInfo->TileAt( iLastTileIndex ) );
+ }
+
+ // Set the SOT marker
+ tile->SetSotMarker( sotMarker );
+
+ if ( sotMarker.iPsot )
+ {
+ // Decrement the tile length
+ tile->SetTileLength( sotMarker.iPsot - markerLength - KMarkerSize );
+ }
+
+ // Make sure we read all the data
+ if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
+ {
+ // We must be missing some data in the marker
+ User::Leave( KErrCorrupt );
+ }
+
+ if ( iUseNewTile )
+ {
+ iImageInfo->Append( tile );
+ CleanupStack::Pop();
+ iUseNewTile = EFalse;
+ }
+
+ // Any valid marker may come after SOT marker
+ iFHState = EStateInUnknown;
+ return EFrameComplete;
+
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ReadSODL
+// Verify and process Start of Data ( SOD marker ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::ReadSODL()
+ {
+ if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KSOD )
+ {
+ // Unrecognized SOD marker
+ User::Leave( KErrCorrupt );
+ }
+
+ CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
+
+ TUint32& length = tile.TileLength();
+ if ( length )
+ {
+ // Decrement the tile length
+ length -= KMarkerSize;
+ }
+
+ // Initialize the tile only for tile part 0
+ if ( tile.IsFirstTilePart() )
+ {
+ tile.InitializeL();
+ iImageInfo->SetLastTilePartProcessed( tile.SotMarker().iIsot );
+ }
+
+ if ( tile.IsPPT() )
+ {
+ // Use packet header information from PPT
+ tile.UsePPTL();
+ }
+ else if ( iImageInfo->IsPPM() )
+ {
+ // Use packet header information from PPM
+ iImageInfo->UsePPM( tile );
+ }
+ else
+ {
+ tile.SetPacketHeaderReader( &iReader );
+ }
+
+ if ( ( iImageInfo->NumOfHorizTiles() == 1 ) &&
+ ( iImageInfo->NumOfVertTiles() == 1 ) )
+ {
+ // To force a return immediately from ProcessFrameL()
+ // on first entry to stimulate the occurrance of
+ // the progress bar
+ iProgressBar = ETrue;
+ }
+
+ // We know that bitstream will follow SOD marker
+ iFHState = EStateInBITSTREAM;
+
+ return EFrameComplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ReadBitStreamL
+// Verify and process BitStream Data.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::ReadBitStreamL()
+ {
+ CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
+ TUint32& length = tile.TileLength( );
+
+ if ( length )
+ {
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( TInt32 )length )
+ {
+ // Larger bitstream will not fit into the internal
+ // buffer size, so process a chunk at a time
+ // we have to add some kind of state information
+ // so that we know where to continue and process
+ if ( tile.IsSpeedup() )
+ {
+ // For RLCP/RPCL progression order
+ if ( tile.LastLevelProcessed() <= tile.NumOfLevelsPOC() )
+ {
+ tile.ReadBitStreamL();
+ }
+ else
+ {
+ // discard any data that beyond the required resolution level
+ if ( !tile.IsPPT() )
+ {
+ if ( iImageInfo->IsPPM() )
+ {
+ // discard current packet header in PPM marker
+ iImageInfo->ResetPPM();
+ }
+ }
+ iReader.iPtr = iReader.iPtrEnd;
+ }
+ }
+ else
+ {
+ tile.ReadBitStreamL();
+ }
+
+ length -= ( iReader.iPtr - iReader.iPtrStartMarker );
+ iReader.UpdateTileHeader();
+
+ // stay in the current state
+ return EFrameIncomplete;
+ }
+
+ // We are sure that all tile part data fit into the buffer
+ // so just go ahead and process it
+ if ( tile.IsSpeedup() )
+ {
+ // For RLCP/RPCL progression order
+ if ( tile.LastLevelProcessed() <= tile.NumOfLevelsPOC() )
+ {
+ tile.ReadBitStreamL( ETrue );
+ iReader.TryReAlignReader();
+ }
+ else
+ {
+ // discard any data that beyond the required resolution level
+ if ( !tile.IsPPT() )
+ {
+ if ( iImageInfo->IsPPM() )
+ {
+ // discard current packet header in PPM marker
+ iImageInfo->ResetPPM();
+ }
+ }
+ iReader.iPtr += length;
+ }
+ }
+ else
+ {
+ tile.ReadBitStreamL( ETrue );
+ iReader.TryReAlignReader();
+ }
+
+ length -= ( iReader.iPtr - iReader.iPtrStartMarker );
+
+ if ( tile.IsSpeedup() )
+ {
+ // discard any data that beyond the required resolution level
+ if ( !tile.IsPPT() )
+ {
+ if ( iImageInfo->IsPPM() )
+ {
+ // discard current packet header in PPM marker
+ iImageInfo->ResetPPM();
+ }
+ }
+ iReader.iPtr += length;
+ length = 0;
+ }
+
+ // Sanity check
+ if ( length != 0 )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ if ( tile.IsLastTilePart() )
+ {
+ tile.DoReleaseUnusedMarkers();
+
+ // proceed to the decoding state
+ iDecodeTile = ETrue;
+
+ // Start with new tile
+ iUseNewTile = ETrue;
+ if ( !iUseNextTile )
+ {
+ iFHState = EStateInUnknown;
+ return EFrameIncompleteRepositionRequest;
+ }
+ else
+ {
+ if ( !iSequential )
+ {
+ // Must be End of Codestream EOC
+ iFHState = EStateInEOC;
+ iReader.iPtr += KMarkerSize;
+ return EFrameComplete;
+ }
+ }
+ }
+
+ // We do not know what is the next marker
+ // either next SOT or EOC
+ iFHState = EStateInUnknown;
+ }
+ else
+ {
+ if ( iReader.iPtrEnd == iReader.iPtr )
+ {
+ // Assume that we have done with the image
+ iFHState = EStateInEOC;
+ }
+ else
+ {
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) >= 2 )
+ {
+ TUint16 marker = PtrReadUtil::ReadBigEndianUint16( iReader.iPtr );
+ if ( marker == KSOT )
+ {
+ // Next SOT marker is found
+ iFHState = EStateInSOT;
+ }
+ else if ( marker == EStateInEOC )
+ {
+ // End of Codestream is found
+ iFHState = EStateInEOC;
+ iReader.iPtr += KMarkerSize;
+ }
+ else
+ {
+ tile.ReadBitStreamL();
+ marker = PtrReadUtil::ReadBigEndianUint16( iReader.iPtr );
+
+ if ( marker == KSOT || marker == KEOC )
+ {
+ iFHState = EStateInUnknown;
+
+ if ( tile.IsLastTilePart() )
+ {
+ tile.DoReleaseUnusedMarkers();
+
+ // proceed to the decoding state
+ iDecodeTile = ETrue;
+
+ // Start with new tile
+ iUseNewTile = ETrue;
+ if ( !iUseNextTile )
+ {
+ return EFrameIncompleteRepositionRequest;
+ }
+ else
+ {
+ if ( !iSequential )
+ {
+ // Must be End of Codestream EOC
+ iFHState = EStateInEOC;
+ iReader.iPtr += KMarkerSize;
+ }
+ }
+ }
+ }
+ else
+ {
+ iReader.UpdateTileHeader();
+
+ // Stay in the current state
+ return EFrameIncomplete;
+ }
+ }
+ }
+ else
+ {
+ iReader.UpdateTileHeader();
+
+ // Stay in the current state
+ return EFrameIncomplete;
+ }
+ }
+ }
+
+ if ( ( iImageInfo->NumOfHorizTiles() == 1 ) &&
+ ( iImageInfo->NumOfVertTiles() == 1 ) )
+ {
+ // To force a return immediately from ProcessFrameL()
+ // on first entry to stimulate the occurrance of
+ // the progress bar
+ iProgressBar = ETrue;
+ }
+
+ return EFrameComplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ReadPPTL
+// Verify and process Packed Packet Headers, Tile Part Header ( PPT marker ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::ReadPPTL()
+ {
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
+ {
+ // Underflow
+ return EFrameIncomplete;
+ }
+
+ if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KPPT )
+ {
+ // Unrecognized PPT marker
+ User::Leave( KErrCorrupt );
+ }
+
+ TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
+ {
+ // Underflow, backup the iterator to the beginning of the marker
+ iReader.iPtr -= KMarkerMinLength;
+ return EFrameIncomplete;
+ }
+
+ TPPTMarker *pptMarker = new ( ELeave ) TPPTMarker;
+ CleanupDeletePushL( pptMarker );
+
+ TInt entries = markerLength - KMarkerSize - 1;
+ pptMarker->iZppt = *iReader.iPtr++;
+ pptMarker->iIppt = HBufC8::NewL( entries );
+ pptMarker->iIppt->Des( ).Append( iReader.iPtr, entries );
+ iReader.iPtr += entries;
+
+ // Make sure we read all the data
+ if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
+ {
+ // We must be missing some data in the marker
+ User::Leave( KErrCorrupt );
+ }
+
+ CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
+
+ // Append PPT to the current tile and decrement the tile length
+ tile.AppendPPTL( pptMarker, markerLength + KMarkerSize );
+ CleanupStack::Pop();
+
+ // Any valid marker may come after PPT marker
+ iFHState = EStateInUnknown;
+
+ return EFrameComplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ReadPLTL
+// Verify and process Packet Length, Tile Part Header ( PLT marker ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::ReadPLTL()
+ {
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
+ {
+ // Underflow
+ return EFrameIncomplete;
+ }
+
+ if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KPLT )
+ {
+ // Unrecognized PLT marker
+ User::Leave( KErrCorrupt );
+ }
+
+ TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
+
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
+ {
+ // Underflow, backup the iterator to the beginning of the marker
+ iReader.iPtr -= KMarkerMinLength;
+ return EFrameIncomplete;
+ }
+
+ TPLTMarker *pltMarker = new ( ELeave ) TPLTMarker;
+ //CleanupStack::PushL( pltMarker );
+ CleanupDeletePushL( pltMarker );
+
+ pltMarker->iZplt = *iReader.iPtr++;
+
+ TInt entries = markerLength - KMarkerSize - 1;
+ while ( entries )
+ {
+ User::LeaveIfError( pltMarker->iIplt.Append( *iReader.iPtr++ ) );
+ --entries;
+ }
+
+ // Make sure we read all the data
+ if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
+ {
+ // We must be missing some data in the marker
+ User::Leave( KErrCorrupt );
+ }
+
+ CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
+
+ // Append PLT to the current tile and decrement the tile length
+ tile.AppendPLTL( pltMarker, markerLength + KMarkerSize );
+ CleanupStack::Pop();
+
+ // Any valid marker may come after PLT marker
+ iFHState = EStateInUnknown;
+
+ return EFrameComplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ReadSkipTileL
+// Ignore the content and advance the iterator to the next marker.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::ReadSkipTileL()
+ {
+ if ( (TUint32)( iReader.iPtrEnd - iReader.iPtr ) < iReader.iSkipLength )
+ {
+ iReader.iSkipLength -= ( iReader.iPtrEnd - iReader.iPtr );
+ iReader.iPtr = iReader.iPtrEnd;
+
+ // Stay in the current state
+ return EFrameIncomplete;
+ }
+ else
+ {
+ if ( iReader.iSkipLength )
+ {
+ iReader.iPtr += iReader.iSkipLength;
+ iReader.iSkipLength = 0;
+ }
+ else
+ {
+ iFHState = EStateInUnknown;
+ }
+ return EFrameComplete;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::UpdateStateFromMarkerL
+// Update the current state according to the marker type.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TFrameState CJp2kReadCodec::UpdateStateFromMarkerL()
+ {
+ if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerSize )
+ {
+ // Underflow
+ return EFrameIncomplete;
+ }
+
+ TUint16 marker = PtrReadUtil::ReadBigEndianUint16( iReader.iPtr );
+ switch ( marker )
+ {
+ case KCOD:
+ {
+ iFHState = EStateInCOD;
+ break;
+ }
+ case KCOC:
+ {
+ iFHState = EStateInCOC;
+ break;
+ }
+ case KQCD:
+ {
+ iFHState = EStateInQCD;
+ break;
+ }
+ case KQCC:
+ {
+ iFHState = EStateInQCC;
+ break;
+ }
+ case KRGN:
+ {
+ iFHState = EStateInRGN;
+ break;
+ }
+ case KPOC:
+ {
+ iFHState = EStateInPOC;
+ break;
+ }
+ case KPPM:
+ {
+ iFHState = EStateInPPM;
+ break;
+ }
+ case KTLM:
+ {
+ iFHState = EStateInTLM;
+ break;
+ }
+ case KPLM:
+ {
+ iFHState = EStateInPLM;
+ break;
+ }
+ case KCRG:
+ {
+ iFHState = EStateInCRG;
+ break;
+ }
+ case KCME:
+ {
+ iFHState = EStateInCOM;
+ break;
+ }
+ case KSOT:
+ {
+ iFHState = EStateInSOT;
+ break;
+ }
+ case KPPT:
+ {
+ iFHState = EStateInPPT;
+ break;
+ }
+ case KPLT:
+ {
+ iFHState = EStateInPLT;
+ break;
+ }
+ case KSOD:
+ {
+ iFHState = EStateInSOD;
+ break;
+ }
+ case KEOC:
+ {
+ if ( !iUseNewTile && iImageInfo->TileCount() )
+ {
+ // There is a tile which has not been decoded yet
+ CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
+
+ tile.DoReleaseUnusedMarkers();
+
+ // Decode and delete the tile
+ DecodeAndDeleteTileL( tile );
+
+ // Start with new tile
+ iUseNewTile = ETrue;
+ if ( !iUseNextTile )
+ {
+ iFHState = EStateInUnknown;
+ return EFrameIncompleteRepositionRequest;
+ }
+ else
+ {
+ if ( !iSequential )
+ {
+ // Must be End of Codestream EOC
+ iFHState = EStateInEOC;
+ iReader.iPtr += KMarkerSize;
+ return EFrameComplete;
+ }
+ }
+ }
+ else
+ {
+ iFHState = EStateInEOC;
+
+ // Have to increment the iterator
+ iReader.iPtr += KMarkerSize;
+ }
+ break;
+ }
+ default:
+ {
+ if ( marker < KEXTS || marker > KEXTE )
+ {
+ // Unrecognized marker
+ User::Leave( KErrCorrupt );
+ }
+ else
+ {
+ // Ignore the extension marker
+ iReader.iPtr += KMarkerSize;
+ }
+ break;
+ }
+ }
+ return EFrameComplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::DecodeAndDeleteTileL
+// Decode the tile, write to image processor and delete the tile.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kReadCodec::DecodeAndDeleteTileL( CJ2kTileInfo& aTile )
+ {
+ if ( !iEntropy )
+ {
+ iEntropy = CJ2kEntropyDecoder::NewL( *iImageInfo );
+ }
+
+ if ( !iImageWriter )
+ {
+ iImageWriter = CJ2kImageWriter::NewL( ImageProcessor( ), *iImageInfo, CONST_CAST( TJ2kInfo&,iJ2kInfo ) );
+ }
+
+ if ( !iSynthesis )
+ {
+ iSynthesis = new ( ELeave ) CJ2kSynthesis;
+ }
+
+ if ( iStyleUsed == EUnknownDecoder )
+ {
+ // Use tile-based as the default
+ iStyleUsed = ETileBasedDecoder;
+
+ // If extra levels are dropped, the resolution of the decoded image is larger than
+ // the resolution of the output image. levelsDropped here gives the resolution of
+ // the decoded image (and thus relates to the amount of memory required for decoding).
+ TUint8 levelsDropped = (TUint8)(iImageInfo->LevelDrop() - iImageInfo->ExtraLevelDrop());
+
+ TSizMarker& sizMarker = CONST_CAST( TSizMarker&, iImageInfo->SizMarker() );
+ if ( ( sizMarker.iXTsiz >> levelsDropped ) > (TUint32) KWaveletBlockSize ||
+ ( sizMarker.iYTsiz >> levelsDropped ) > (TUint32) KWaveletBlockSize )
+ {
+ iStyleUsed = EBlockBasedDecoder;
+ }
+ }
+
+ if ( iStyleUsed == ETileBasedDecoder )
+ {
+ iSynthesis->DecodeTileL( *iImageWriter, *iEntropy, *iImageInfo, aTile );
+ }
+ else
+ {
+ iSynthesis->DecodeTileBlockL( *iImageWriter, *iEntropy, *iImageInfo, aTile );
+ }
+
+ iImageInfo->Remove( 0 );
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kReadCodec::ConvertImageDataL
+// Convert some metadata from file format to TImageDataBlock derived objects
+// and let the framework managing the buffer
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kReadCodec::ConvertImageDataL()
+ {
+ TJ2kInfo& info = CONST_CAST( TJ2kInfo&, iJ2kInfo );
+
+ TInt index;
+ // Convert each IPR box to TJp2kIprBox image data
+ for ( index = 0; index < info.iIPRList.Count(); ++index )
+ {
+ TJp2kIprBox* jp2kIPR = new (ELeave) TJp2kIprBox;
+ CleanupDeletePushL( jp2kIPR );
+
+ jp2kIPR->iIprData = info.iIPRList[index];
+
+ User::LeaveIfError( iFrameData->AppendImageData( jp2kIPR ) );
+ CleanupStack::Pop(); // jp2kIPR
+
+ // Transfer the ownership of the buffer to the framework
+ User::LeaveIfError( iFrameData->AppendImageBuffer( jp2kIPR->iIprData ) );
+ info.iIPRList[index] = 0;
+ }
+ info.iIPRList.Reset();
+
+ // Convert each XML box to TJp2kXmlBox image data
+ for ( index = 0; index < info.iXMLList.Count(); ++index )
+ {
+ TJp2kXmlBox* jp2kXML = new (ELeave) TJp2kXmlBox;
+ CleanupDeletePushL( jp2kXML );
+
+ jp2kXML->iXmlData = info.iXMLList[index];
+
+ User::LeaveIfError( iFrameData->AppendImageData( jp2kXML ) );
+ CleanupStack::Pop(); // jp2kXML
+
+ // Transfer the ownership of the buffer to the framework
+ User::LeaveIfError( iFrameData->AppendImageBuffer( jp2kXML->iXmlData ) );
+ info.iXMLList[index] = 0;
+ }
+ info.iXMLList.Reset();
+
+ TInt length;
+ const TUint8 *ptr = 0;
+ // Convert each UUID box to TJp2kUuidBox image data
+ for ( index = 0; index < info.iUUIDList.Count(); ++index )
+ {
+ TJp2kUuidBox* jp2kUUID = new (ELeave) TJp2kUuidBox;
+ CleanupDeletePushL( jp2kUUID );
+
+ ptr = info.iUUIDList[index]->Ptr();
+ jp2kUUID->iUuidId.Copy( ptr, KJ2KUuidIDSize );
+
+ // Advance the pointer
+ ptr += KJ2KUuidIDSize;
+
+ length = info.iUUIDList[index]->Length() - KJ2KUuidIDSize;
+ jp2kUUID->iUuidData = HBufC8::NewLC( length );
+ jp2kUUID->iUuidData->Des().Append( ptr, length );
+
+ // Transfer the ownership of the buffer to the framework
+ User::LeaveIfError( iFrameData->AppendImageBuffer( jp2kUUID->iUuidData ) );
+ CleanupStack::Pop( 1 ); // jp2kUUID->iUuidData
+
+ User::LeaveIfError( iFrameData->AppendImageData( jp2kUUID ) );
+ CleanupStack::Pop( 1 ); // jp2kUUID
+ }
+ info.iUUIDList.ResetAndDestroy();
+
+ // Convert each UUIDInfo box to TJp2kUuidInfoBox image data
+ for ( index = 0; index < info.iUUIDInfoListList.Count(); ++index )
+ {
+ TJp2kUuidInfoBox* jp2kUUIDInfo = new (ELeave) TJp2kUuidInfoBox;
+ CleanupDeletePushL( jp2kUUIDInfo );
+
+ if ( info.iUUIDInfoListList[index]->Length() )
+ {
+ ptr = info.iUUIDInfoListList[index]->Ptr();
+ jp2kUUIDInfo->iUuidInfoNu = PtrReadUtil::ReadBigEndianUint16Inc( ptr );
+
+ length = jp2kUUIDInfo->iUuidInfoNu * KJ2KUuidIDSize;
+ jp2kUUIDInfo->iUuidInfoId = HBufC8::NewLC( length );
+ jp2kUUIDInfo->iUuidInfoId->Des().Append( ptr, length );
+ }
+
+ if ( info.iUUIDInfoUrlList[index]->Length() )
+ {
+ ptr = info.iUUIDInfoUrlList[index]->Ptr();
+
+ // 1 byte unsigned integer
+ jp2kUUIDInfo->iUuidInfoVersion = *ptr++;
+
+ // 3 bytes unsigned integer (in little endian)
+ jp2kUUIDInfo->iUuidInfoFlag = *ptr++;
+ jp2kUUIDInfo->iUuidInfoFlag |= ( *ptr++ << 8 );
+ jp2kUUIDInfo->iUuidInfoFlag |= ( *ptr++ << 16 );
+
+ length = info.iUUIDInfoUrlList[index]->Length() - 4;
+ jp2kUUIDInfo->iUuidInfoData = HBufC8::NewLC( length );
+ jp2kUUIDInfo->iUuidInfoData->Des().Append( ptr, length );
+ }
+
+ // Transfer the ownership of the buffer to the framework
+ if ( jp2kUUIDInfo->iUuidInfoData )
+ {
+ User::LeaveIfError( iFrameData->AppendImageBuffer( jp2kUUIDInfo->iUuidInfoData ) );
+ CleanupStack::Pop( 1 ); // jp2kUUIDInfo->iUUidInfoData
+ }
+
+ // Transfer the ownership of the buffer to the framework
+ if ( jp2kUUIDInfo->iUuidInfoId )
+ {
+ User::LeaveIfError( iFrameData->AppendImageBuffer( jp2kUUIDInfo->iUuidInfoId ) );
+ CleanupStack::Pop( 1 ); // jp2kUUIDInfo->iUuidInfoId
+ }
+
+ User::LeaveIfError( iFrameData->AppendImageData( jp2kUUIDInfo ) );
+ CleanupStack::Pop( 1 ); // jp2kUUIDInfo
+ }
+ info.iUUIDInfoListList.ResetAndDestroy();
+ info.iUUIDInfoUrlList.ResetAndDestroy();
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Src/JP2KComponentInfo.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,393 @@
+/*
+* Copyright (c) 2003, 2004 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: CJ2kComponentInfo class used to collect component related
+* information such as precincts size at each resolution level and
+* list of subbands.
+*
+*/
+
+
+
+// INCLUDE FILES
+#include "JP2KTileInfo.h"
+#include "JP2KImageInfo.h"
+#include "JP2KSubband.h"
+#include "JP2KComponentInfo.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::NewLC
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CJ2kComponentInfo* CJ2kComponentInfo::NewLC( CJ2kTileInfo& aTile, TUint16 aIndex )
+ {
+ CJ2kComponentInfo* self = new ( ELeave ) CJ2kComponentInfo;
+
+ CleanupStack::PushL(self);
+ self->ConstructL( aTile, aIndex );
+
+ return self;
+ }
+
+// Destructor
+CJ2kComponentInfo::~CJ2kComponentInfo()
+ {
+ delete iRootSubband;
+ iRootSubband = 0;
+
+ iPrecinctSizeList.Close();
+ iGridList.Close();
+
+ // iExponentList and iMantissaList are not owned by this object
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::LRCPProgressionL
+// At each component, parse the bitstream with LRCP progression order
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kComponentInfo::LRCPProgressionL( CJ2kTileInfo& aTile )
+ {
+ TUint8 incomplete = 0;
+ if ( aTile.LastLevelProcessed() <= iNumOfLevels )
+ {
+ incomplete = iRootSubband->SubbandAt( aTile.LastLevelProcessed() )->LRCPProgressionL( aTile, *this );
+ }
+ return incomplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::RPCLProgressionL
+// At each component, parse the bitstream with RPCL progression order
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kComponentInfo::RPCLProgressionL( CJ2kTileInfo& aTile )
+ {
+ TUint8 incomplete = 0;
+ TUint8 level = aTile.LastLevelProcessed();
+ TUint8 diff = (TUint8)( iNumOfLevels - level );
+ if ( level <= iNumOfLevels )
+ {
+ TInt trx0 = TJ2kUtils::Ceil( iComponentCanvas.iTl.iX, 1 << diff );
+ TInt try0 = TJ2kUtils::Ceil( iComponentCanvas.iTl.iY, 1 << diff );
+ const TSizMarker& sizMarker = aTile.ImageInfo().SizMarker();
+
+ if ( ( ( aTile.LastN1Processed() % (TInt)( sizMarker.iYRsiz[aTile.LastComponentProcessed()] * iGridList[level].iHeight ) == 0) ||
+ ( ( aTile.LastN1Processed() == aTile.TileCanvas().iTl.iY ) &&
+ ( ( try0 << diff) % iGridList[level].iHeight ) ) ) &&
+ ( ( aTile.LastN2Processed() % (TInt)( sizMarker.iXRsiz[aTile.LastComponentProcessed()] * iGridList[level].iWidth ) == 0) ||
+ ( ( aTile.LastN2Processed() == aTile.TileCanvas().iTl.iX ) &&
+ ( ( trx0 << diff ) % iGridList[level].iWidth ) ) ) )
+ {
+ incomplete = iRootSubband->SubbandAt( level )->RPCLProgressionL( aTile, *this );
+ }
+ }
+ return incomplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::CPRLProgressionL
+// At each component, parse the bitstream with CPRL progression order
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kComponentInfo::CPRLProgressionL( CJ2kTileInfo& aTile )
+ {
+ TUint8 incomplete = 0;
+ TUint8 level = aTile.LastLevelProcessed();
+ TUint8 diff = (TUint8)( iNumOfLevels - level );
+
+ if (level <= iNumOfLevels)
+ {
+ TInt trx0 = TJ2kUtils::Ceil( iComponentCanvas.iTl.iX, 1 << diff );
+ TInt try0 = TJ2kUtils::Ceil( iComponentCanvas.iTl.iY, 1 << diff );
+ const TSizMarker& sizMarker = aTile.ImageInfo().SizMarker();
+
+ if ( ( ( aTile.LastN1Processed() % (TInt)( sizMarker.iYRsiz[aTile.LastComponentProcessed()] * iGridList[level].iHeight ) == 0 ) ||
+ ( ( aTile.LastN1Processed() == aTile.TileCanvas().iTl.iY ) &&
+ ( ( try0 << diff) % iGridList[level].iHeight ) ) ) &&
+ ( ( aTile.LastN2Processed() % (TInt)( sizMarker.iXRsiz[aTile.LastComponentProcessed()] * iGridList[level].iWidth ) == 0 ) ||
+ ( ( aTile.LastN2Processed() == aTile.TileCanvas().iTl.iX ) &&
+ ( ( trx0 << diff) % iGridList[level].iWidth ) ) ) )
+ {
+ incomplete = iRootSubband->SubbandAt( level )->CPRLProgressionL( aTile, *this );
+ }
+ }
+ return incomplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::SubbandAt
+// Get the subband at specific resolution level
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+const CJ2kSubband* CJ2kComponentInfo::SubbandAt( TUint8 aResLevel ) const
+ {
+ return ( iRootSubband ) ? iRootSubband->SubbandAt( aResLevel ) : 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::NumOfPackets
+// Get the number of packets at specific resolution level
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint32 CJ2kComponentInfo::NumOfPackets( TUint8 aResLevel ) const
+ {
+ return (TUint32)( iPrecinctSizeList[aResLevel].iWidth *
+ iPrecinctSizeList[aResLevel].iHeight );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::Exponent
+// Get the quantization exponnet value for transformation
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kComponentInfo::Exponent( TUint16 aIndex ) const
+ {
+ if ( iQc & 0x01 )
+ {
+ if ( aIndex > 0 )
+ {
+ return (TUint8)( ( *iExponentList)[0] - ( ( aIndex - 1 ) / 3 ) );
+ }
+ }
+ return ( *iExponentList )[aIndex];
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::Mantissa
+// Get the quantization mantissa value for transformation
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint16 CJ2kComponentInfo::Mantissa( TUint16 aIndex ) const
+ {
+ if ( iQc & 0x01 )
+ {
+ if ( aIndex > 0 )
+ {
+ return ( *iMantissaList )[0];
+ }
+ }
+ return ( *iMantissaList )[aIndex];
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::MagnitudeBits
+// Get the magnitude bits
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kComponentInfo::MagnitudeBits( TUint16 aIndex ) const
+ {
+ return (TUint8)( NumGuard() + Exponent( aIndex ) - 1 );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::ResetLastPacketProcessed
+// Reset the last packet processed
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kComponentInfo::ResetLastPacketProcessed()
+ {
+ for ( TUint8 index = 0; index <= iNumOfLevels; ++index )
+ {
+ iRootSubband->SubbandAt( index )->ResetLastPacketProcessed();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::CJ2kComponentInfo
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CJ2kComponentInfo::CJ2kComponentInfo() :
+ iPrecinctSizeList(4),
+ iGridList(4)
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kComponentInfo::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CJ2kComponentInfo::ConstructL( CJ2kTileInfo& aTile, TUint16 aIndex )
+ {
+ CJ2kImageInfo& imageInfo = CONST_CAST( CJ2kImageInfo&, aTile.ImageInfo() );
+ const TSizMarker& sizMarker = imageInfo.SizMarker();
+ const TRect& tileCanvas = aTile.TileCanvas();
+
+ iComponentCanvas.iTl = TPoint( TJ2kUtils::Ceil( tileCanvas.iTl.iX, sizMarker.iXRsiz[aIndex] ),
+ TJ2kUtils::Ceil( tileCanvas.iTl.iY, sizMarker.iYRsiz[aIndex] ) );
+ iComponentCanvas.iBr = TPoint( TJ2kUtils::Ceil( tileCanvas.iBr.iX, sizMarker.iXRsiz[aIndex] ),
+ TJ2kUtils::Ceil( tileCanvas.iBr.iY, sizMarker.iYRsiz[aIndex] ) );
+
+ if ( iComponentCanvas.Width( ) <= 0 || iComponentCanvas.Height( ) <= 0 )
+ {
+ // Empty may be caused by subsampled
+ return;
+ }
+
+ // Tile part COD > main header COD
+ TCODMarker *codMarker = aTile.TileMarker().iCod;
+ if ( !codMarker )
+ {
+ codMarker = CONST_CAST( TCODMarker*, &imageInfo.MainMarker().iCod );
+ }
+
+ TCODMarker *cod = 0;
+ TCOCMarker *coc = 0;
+
+ // Tile part COC > tile part COD > main header COC > main header COD
+ imageInfo.GetCodingStyle( cod, coc, aTile, aIndex );
+
+ iNumOfLevels = ( coc ) ? coc->iNumOfLevels : cod->iNumOfLevels;
+ iCodeBlockSiz = ( coc ) ? coc->iCodeBlockSiz : cod->iCodeBlockSiz;
+ iCodeBlockStyle = ( coc ) ? coc->iCodeBlockStyle : cod->iCodeBlockStyle;
+ iWaveletTransformation = ( coc ) ? coc->iWaveletTransformation : cod->iWaveletTransformation;
+
+ HBufC8 *precinctSiz = ( coc ) ? coc->iPrecinctSiz : cod->iPrecinctSiz;
+ iCod = ( coc ) ? (TUint8)( ( codMarker->iScod & 0xfe ) | ( coc->iScoc & 0x01 ) ): cod->iScod;
+
+ TQCDMarker *qcd = 0;
+ TQCCMarker *qcc = 0;
+
+ // Tile part QCC > tile part QCD > main header QCC > main header QCD
+ imageInfo.GetQuantization( qcd, qcc, aTile, aIndex );
+
+ iQc = ( qcc ) ? qcc->iSqcc : qcd->iSqcd;
+ iExponentList = ( qcc ) ? qcc->iExponent : qcd->iExponent;
+ iMantissaList = ( qcc ) ? qcc->iMantissa : qcd->iMantissa;
+
+ TRGNMarker *rgn = 0;
+
+ // Tile part RGN > main header RGN
+ imageInfo.GetRegion( rgn, aTile, aIndex );
+ iRoiShift = ( rgn ) ? rgn->iSPrgn : (TUint8)0;
+
+ TSize& maxBlock = CONST_CAST( TSize&, imageInfo.MaxBlockSize() );
+ maxBlock.iWidth = Max( maxBlock.iWidth, iCodeBlockSiz.iWidth );
+ maxBlock.iHeight = Max( maxBlock.iHeight, iCodeBlockSiz.iHeight );
+
+ TSize precinct( 0,0 );
+ TInt trx0 = 0;
+ TInt trx1 = 0;
+ TInt try0 = 0;
+ TInt try1 = 0;
+ TInt denom = 0;
+ TInt ppx = 15;
+ TInt ppy = 15;
+
+ for ( TUint8 index = 0; index <= iNumOfLevels; ++index )
+ {
+ // Resolution level at r = index
+ if ( precinctSiz )
+ {
+ ppx = ( *precinctSiz )[index] & 0x0f;
+ ppy = ( ( *precinctSiz )[index] & 0xf0 ) >> 4;
+ }
+ denom = 1 << ( iNumOfLevels - index );
+
+ trx0 = TJ2kUtils::Ceil( iComponentCanvas.iTl.iX, denom );
+ try0 = TJ2kUtils::Ceil( iComponentCanvas.iTl.iY, denom );
+ trx1 = TJ2kUtils::Ceil( iComponentCanvas.iBr.iX, denom );
+ try1 = TJ2kUtils::Ceil( iComponentCanvas.iBr.iY, denom );
+
+ if ( trx1 > trx0 )
+ {
+ precinct.iWidth = TJ2kUtils::Ceil( trx1, 1 << ppx ) - TJ2kUtils::Floor( trx0, 1 << ppx );
+ }
+ else
+ {
+ precinct.iWidth = 0;
+ }
+
+ if ( try1 > try0 )
+ {
+ precinct.iHeight = TJ2kUtils::Ceil( try1, 1 << ppy ) - TJ2kUtils::Floor( try0, 1 << ppy );
+ }
+ else
+ {
+ precinct.iHeight = 0;
+ }
+
+ User::LeaveIfError( iPrecinctSizeList.Append( precinct ) );
+
+ precinct.iWidth = 1 << ( ppx + iNumOfLevels - index );
+ precinct.iHeight = 1 << ( ppy + iNumOfLevels - index );
+ User::LeaveIfError( iGridList.Append( precinct ) );
+
+ // Calculate the minimum grid
+ if ( iMinGrid.iWidth == 0 || iMinGrid.iWidth > precinct.iWidth )
+ {
+ iMinGrid.iWidth = precinct.iWidth;
+ }
+ if ( iMinGrid.iHeight == 0 || iMinGrid.iHeight > precinct.iHeight )
+ {
+ iMinGrid.iHeight = precinct.iHeight;
+ }
+ }
+
+ if ( imageInfo.Crop() )
+ {
+ const TRect& crop = imageInfo.CropArea();
+
+ if ( !( crop.iTl.iX >= ( tileCanvas.iBr.iX - ( TInt )sizMarker.iXOsiz ) ||
+ crop.iBr.iX < ( tileCanvas.iTl.iX - ( TInt )sizMarker.iXOsiz ) ||
+ crop.iTl.iY >= ( tileCanvas.iBr.iY - ( TInt )sizMarker.iYOsiz ) ||
+ crop.iBr.iY < ( tileCanvas.iTl.iY - ( TInt )sizMarker.iYOsiz ) ) )
+ {
+ imageInfo.SetTileMask( aTile.SotMarker().iIsot, ETrue );
+ }
+ else
+ {
+ // Current tile is not in the cropping area,
+ // just skip setting up the subbands and packets
+ return;
+ }
+ }
+
+ // Build the associated Subband root
+ iRootSubband = CJ2kSubband::BuildSubbandTreeL( iNumOfLevels, *this );
+
+ // Build the associated Packet classes
+ iRootSubband->BuildPacketsL( *this, precinctSiz, codMarker->iNumOfLayers );
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Src/JP2KConvert.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,2196 @@
+/*
+* Copyright (c) 2003-2006 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: JPEG2000 image encoder/decoder plugin class.
+*
+*/
+
+
+// INCLUDE FILES
+#include "JP2KImageUtils.h"
+#include "JP2KFormat.h"
+#include "JP2KConvert.h"
+#include "JP2KStreamReader.h"
+#include "JP2KImageClientMain.h"
+#include "JP2KCodec.h"
+#include <barsc.h>
+#include <imageconversion.h>
+#include <barsread.h>
+#include <bautils.h>
+#include <e32math.h>
+#include <101F862D_extra.rsg>
+#include <icl/icl_uids.hrh>
+#include "JP2KUids.hrh"
+#include <JP2KImageData.h>
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+_LIT( KJ2KPanicCategory, "J2KConvertPlugin" );
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CJp2kDecoder* CJp2kDecoder::NewL()
+ {
+ return new ( ELeave ) CJp2kDecoder;
+ }
+
+// Destructor
+CJp2kDecoder::~CJp2kDecoder()
+ {
+ // Call base class Cleanup(), else there is a possibility
+ // of memory leak
+ CImageDecoderPlugin::Cleanup();
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ImageType
+// Get the image type uid of this plugin.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ImageType( TInt aFrameNumber, TUid& aImageType, TUid& aImageSubType ) const
+ {
+ __ASSERT_ALWAYS( aFrameNumber == 0, Panic( EFrameNumberOutOfRange ) );
+
+ TUid uid = {KImageTypeJ2KUid};
+ aImageType = uid;
+ aImageSubType = KNullUid;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::NumberOfImageComments
+// Get the number of image comment.
+// -----------------------------------------------------------------------------
+//
+TInt CJp2kDecoder::NumberOfImageComments() const
+ {
+ __ASSERT_ALWAYS( IsImageHeaderProcessingComplete(), Panic( EHeaderProcessingNotComplete ) );
+
+ const TUid commentUid = { KJ2KCommentUid };
+ const CFrameImageData& frameImageData = FrameData( 0 );
+ const TInt imageDataCount = frameImageData.ImageDataCount();
+ const TImageDataBlock *imageData = 0;
+ TInt imageCommentCount = 0;
+ for ( TInt index = 0; index < imageDataCount; ++index )
+ {
+ imageData = frameImageData.GetImageData( index );
+ if ( imageData->DataType() == commentUid )
+ {
+ imageCommentCount++;
+ }
+ }
+ return imageCommentCount;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ImageCommentL
+// Get the image comment.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+HBufC* CJp2kDecoder::ImageCommentL( TInt aCommentNumber ) const
+ {
+ __ASSERT_ALWAYS( IsImageHeaderProcessingComplete(), Panic( EHeaderProcessingNotComplete ) );
+ __ASSERT_ALWAYS( ( aCommentNumber >= 0 ) && ( aCommentNumber < NumberOfImageComments() ),
+ Panic( ECommentNumberOutOfRange ) );
+
+ HBufC *comment = 0;
+
+ if( FrameData( 0 ).ImageDataCount() > 0 )
+ {
+ const TUid commentUid = { KJ2KCommentUid };
+ const CFrameImageData& frameImageData = FrameData( 0 );
+ const TInt imageDataCount = frameImageData.ImageDataCount();
+ const TImageDataBlock *imageData = 0;
+ TInt commentCount = 0;
+ for ( TInt index = 0; index < imageDataCount; ++index )
+ {
+ imageData = frameImageData.GetImageData( index );
+ if ( imageData->DataType() == commentUid )
+ {
+ if ( commentCount == aCommentNumber )
+ {
+ index = imageDataCount; // Break from the for loop
+ }
+ else
+ {
+ commentCount++;
+ }
+ }
+ }
+
+ if( imageData != 0 )
+ {
+ const TJp2kComment *jp2kComment = STATIC_CAST( const TJp2kComment*, imageData );
+ comment = HBufC::NewL( jp2kComment->iComment->Length() );
+
+ // Create 16 bit copy of the 8 bit original
+ comment->Des().Copy( *( jp2kComment->iComment ) );
+ }
+ }
+ return comment;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::NumberOfFrameComments
+// Get the number of frame comment.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CJp2kDecoder::NumberOfFrameComments( TInt aFrameNumber ) const
+ {
+ __ASSERT_ALWAYS( IsImageHeaderProcessingComplete(), Panic( EHeaderProcessingNotComplete ) );
+ __ASSERT_ALWAYS( aFrameNumber == 0, Panic( EFrameNumberOutOfRange ) );
+
+ return NumberOfImageComments();
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::FrameCommentL
+// Get the frame comment.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+HBufC* CJp2kDecoder::FrameCommentL( TInt aFrameNumber, TInt aCommentNumber ) const
+ {
+ __ASSERT_ALWAYS( IsImageHeaderProcessingComplete(), Panic( EHeaderProcessingNotComplete ) );
+ __ASSERT_ALWAYS( aFrameNumber == 0, Panic( EFrameNumberOutOfRange ) );
+
+ return ImageCommentL( aCommentNumber );
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::FrameInfoStringsL
+// Retrieve frame information and format it according to info stored in .rss file.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CFrameInfoStrings* CJp2kDecoder::FrameInfoStringsL( RFs& aFs, TInt aFrameNumber )
+ {
+ const TUid KJp2kCodecDllUid = { KJ2KCodecDllUidValue };
+
+ RResourceFile resourceFile;
+ OpenExtraResourceFileLC( aFs, KJp2kCodecDllUid, resourceFile );
+
+ HBufC8* resourceInfo = resourceFile.AllocReadLC( THEDECODERINFO );
+ TResourceReader resourceReader;
+ resourceReader.SetBuffer( resourceInfo );
+
+ TBuf<KCodecResourceStringMax> info;
+ TBuf<KCodecResourceStringMax> templte;
+
+ const TFrameInfo& frameInfo = FrameInfo( aFrameNumber );
+ CFrameInfoStrings* frameInfoStrings = CFrameInfoStrings::NewLC();
+
+ info = resourceReader.ReadTPtrC();
+ frameInfoStrings->SetDecoderL( info );
+
+ info = resourceReader.ReadTPtrC();
+ frameInfoStrings->SetFormatL( info );
+
+ TInt width = frameInfo.iOverallSizeInPixels.iWidth;
+ TInt height = frameInfo.iOverallSizeInPixels.iHeight;
+ TInt depth = frameInfo.iBitsPerPixel;
+
+ templte = resourceReader.ReadTPtrC();
+ info.Format( templte, width, height );
+ frameInfoStrings->SetDimensionsL( info );
+
+ CDesCArrayFlat* resourceArray = resourceReader.ReadDesCArrayL();
+ CleanupStack::PushL( resourceArray );
+ TUint formatIndex = ( frameInfo.iFlags & TFrameInfo::EColor ) ? 1 : 0;
+ templte = ( *resourceArray )[formatIndex];
+ CleanupStack::PopAndDestroy( resourceArray );
+ info.Format( templte, depth );
+ frameInfoStrings->SetDepthL( info );
+
+ resourceArray = resourceReader.ReadDesCArrayL();
+ CleanupStack::PushL( resourceArray );
+ formatIndex = 0;
+ info = ( *resourceArray )[formatIndex];
+ CleanupStack::PopAndDestroy( resourceArray );
+ frameInfoStrings->SetDetailsL( info );
+
+ CleanupStack::Pop( frameInfoStrings );
+ CleanupStack::PopAndDestroy( 2 ); // resourceInfo + resourceFile
+ return frameInfoStrings;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::FrameHeaderBlockSize
+// Returns the frame header block size.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CJp2kDecoder::FrameHeaderBlockSize( TInt aFrameNumber ) const
+ {
+ __ASSERT_ALWAYS( aFrameNumber == 0, Panic( EFrameNumberOutOfRange ) );
+
+ return KJ2kInputBufferSize;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::FrameBlockSize
+// Returns the frame block size.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CJp2kDecoder::FrameBlockSize(TInt aFrameNumber) const
+ {
+ __ASSERT_ALWAYS( aFrameNumber == 0, Panic( EFrameNumberOutOfRange ) );
+
+ return KJ2kInputBufferSize;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::DoConvert
+// Override the default DoConvert to split out the parsing and decoding
+// process into multiple steps.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::DoConvert()
+ {
+ TFrameState codecState = EFrameIncomplete;
+ TInt errCode = KErrNone;
+
+ CJp2kReadCodec *j2kCodec = static_cast<CJp2kReadCodec*>( ImageReadCodec() );
+
+ if ( !j2kCodec->IsDecodeTile() )
+ {
+ // parsing of a tile-part
+ TRAP( errCode, PrepareForProcessFrameL() );
+ if ( errCode != KErrNone )
+ {
+ RequestComplete( errCode );
+ return;
+ }
+
+ TBufPtr8& sourceData = SourceData();
+ TInt sourceLength = sourceData.Length();
+ if ( sourceLength != 0 )
+ {
+ TRAP( errCode, codecState = j2kCodec->ProcessFrameL( sourceData ) );
+
+ if ( j2kCodec->IsDecodeTile() )
+ {
+ // tile-part contains all compressed data
+ // and proceed to the decoding
+ SelfComplete( KErrNone );
+ return;
+ }
+ }
+ // continue on parsing the tile-part
+ HandleProcessFrameResult( errCode, codecState );
+ }
+ else
+ {
+ // decoding of the tile-part
+ TRAP( errCode, codecState = j2kCodec->DecodeTileL() );
+
+ if ( errCode == KErrNone )
+ {
+ if ( j2kCodec->IsDecodeTile() )
+ {
+ // continue on decoding the tile-part
+ // if we split the decoding into multiple steps
+ SelfComplete( KErrNone );
+ return;
+ }
+ }
+ // either continue on parsing the next tile-part
+ // or done with the whole image
+ HandleProcessFrameResult( errCode, codecState );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::CJp2kDecoder
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CJp2kDecoder::CJp2kDecoder()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadFormatL
+// JP2 File Format detection state machine.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadFormatL()
+ {
+ // Verify the JP2 file format if it exist
+ iCallFromFramework = ETrue;
+
+ while ( iState != EStateInCodestreamBox )
+ {
+ switch ( iState )
+ {
+ case EStateInSignatureBox:
+ {
+ ReadSignatureBoxL();
+ break;
+ }
+ case EStateInFileTypeBox:
+ {
+ ReadFileTypeBoxL();
+ break;
+ }
+ case EStateInJP2SuperBox:
+ {
+ ReadJp2HeaderBoxL();
+ break;
+ }
+ case EStateInIPRBox:
+ {
+ ReadIPRBoxL();
+ break;
+ }
+ case EStateInXMLBox:
+ {
+ ReadXMLBoxL();
+ break;
+ }
+ case EStateInUUIDBox:
+ {
+ ReadUUIDBoxL();
+ break;
+ }
+ case EStateInUUIDInfoBox:
+ {
+ ReadUUIDInfoBoxL();
+ break;
+ }
+ case EStateInUnknown:
+ {
+ if ( iCallFromFramework )
+ {
+ // Always read the length and type of the box
+ ReadDataL( iLastRead, iBufferDes, KJ2kBoxTypeLength );
+
+ if ( (TUint32)iBufferDes.Length() < KJ2kBoxTypeLength )
+ {
+ if ( ( iJ2kInfo.iCSOffset != 0 ) &&
+ ( (TUint32)iBufferDes.Length() == 0 ) )
+ {
+ // We have reach the end of file/stream and
+ // CodeStream box has been recognized
+ iState = EStateInCodestreamBox;
+ }
+ else
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+ }
+ iPtr = iBufferDes.Ptr();
+ }
+
+ if ( iState != EStateInCodestreamBox )
+ {
+ // Length and Type of next box
+ iBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ iBoxType = PtrReadUtil::ReadBigEndianUint32( iPtr );
+
+ // Update the internal state based on the iBoxType
+ UpdateStateFromBoxTypeL();
+
+ if ( iState != EStateInCodestreamBox )
+ {
+ // Corrupted box length
+ if ( ( (TInt32)iBoxLength ) < 0 )
+ {
+ User::Leave( KErrCorrupt );
+ }
+ }
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ iCallFromFramework = EFalse;
+ }
+
+ // When the code reach here, it means that we have found the
+ // codestream box in JP2 file format or the codestream SOC itself
+ // in case of the JP2 file format, all the boxes after the
+ // codestream box will not be read and parsed.
+
+ // In JP2 file format, iLastRead points to codestream box
+ // in JP2 codestream, iLastRead points to SOC marker
+ // it is the offset that ICL framework used to read
+ // in more data from the image file.
+ SetStartPosition( iJ2kInfo.iCSOffset );
+
+ // Always set the image data length to KMaxTInt32
+ SetDataLength( KMaxTInt );
+
+ // Fill up the image related information, if it is
+ // in JP2 file format, else defer the setting of the
+ // image info til SIZ marker in the codestream has
+ // been processed.
+ if ( iJ2kInfo.iOption & TJ2kInfo::EJP2file )
+ {
+ TFrameInfo& imageInfo = CONST_CAST( TFrameInfo&, ImageInfo() );
+ imageInfo.iOverallSizeInPixels = iJ2kInfo.iImageSize;
+ imageInfo.iFrameCoordsInPixels.SetRect( TPoint( 0, 0 ), iJ2kInfo.iImageSize );
+ imageInfo.iFrameSizeInTwips = iJ2kInfo.iImageSizeInTwips;
+
+ if ( iJ2kInfo.iBPCList.Count() > 0 )
+ {
+ // Calculate based on the bitdepth per component
+ for ( TUint16 index = 0; index < iJ2kInfo.iNC; ++index )
+ {
+ imageInfo.iBitsPerPixel += ( ( 0x7f & iJ2kInfo.iBPCList[index] ) + 1 );
+ }
+ }
+ else
+ {
+ if ( iJ2kInfo.iBPC == KJ2kIsBPCBoxExist )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ // Has the same bitdepth on each component
+ imageInfo.iBitsPerPixel = ( ( 0x7f & iJ2kInfo.iBPC ) + 1 ) * iJ2kInfo.iNC;
+ }
+ imageInfo.iFlags |= TFrameInfo::ECanDither;
+
+ // Decoder is able to handle scaleable resolution
+ imageInfo.iFlags |= TFrameInfo::EConstantAspectRatio;
+
+ if ( iJ2kInfo.iEnumCS != KJ2kColourSpecGrayScale )
+ {
+ imageInfo.iFlags |= TFrameInfo::EColor;
+ }
+
+ // No animation.
+ imageInfo.iDelay = 0;
+
+ switch ( imageInfo.iBitsPerPixel )
+ {
+ case 1:
+ {
+ imageInfo.iFrameDisplayMode = EGray2;
+ break;
+ }
+ case 2:
+ {
+ imageInfo.iFrameDisplayMode = EGray4;
+ break;
+ }
+ case 4:
+ {
+ imageInfo.iFrameDisplayMode = ( imageInfo.iFlags & TFrameInfo::EColor ) ? EColor16 : EGray16;
+ break;
+ }
+ case 8:
+ {
+ imageInfo.iFrameDisplayMode = ( imageInfo.iFlags & TFrameInfo::EColor ) ? EColor16M : EGray256;
+ break;
+ }
+ case 12:
+ {
+ imageInfo.iFrameDisplayMode = ( imageInfo.iFlags & TFrameInfo::EColor ) ? EColor4K : EGray256;
+ break;
+ }
+ case 16:
+ {
+ imageInfo.iFrameDisplayMode = EColor64K;
+ break;
+ }
+ case 24:
+ {
+ imageInfo.iFrameDisplayMode = EColor16M;
+ break;
+ }
+ default:
+ {
+ imageInfo.iFrameDisplayMode = EColor64K;
+ break;
+ }
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadSignatureBoxL
+// Verify and process the Signature box.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadSignatureBoxL( )
+ {
+ // Validate the Signature Box
+ __ASSERT_ALWAYS( iLastRead == 0, Panic( EInvalidState ) );
+
+ // Read the Signature box + the next box's Length and Type
+ ReadDataL( iLastRead, iBufferDes, KJ2kFileInformationSize );
+
+ if ( (TUint32)iBufferDes.Length() < KJ2kSigBoxLength )
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+
+ iPtr = iBufferDes.Ptr();
+
+ if ( ( PtrReadUtil::ReadBigEndianUint32Inc( iPtr ) != KJ2kSigBoxLength ) ||
+ ( PtrReadUtil::ReadBigEndianUint32Inc( iPtr ) != KJ2kSigBoxType ) ||
+ ( PtrReadUtil::ReadBigEndianUint32Inc( iPtr ) != KJ2kSigBoxContent ) )
+ {
+ // Unrecognized signature box
+ User::Leave( KErrCorrupt );
+ }
+
+ // File Type box shall immediately follow the Signature box
+ iLastRead = KJ2kSigBoxLength;
+ iState = EStateInFileTypeBox;
+
+ // JP2 file format
+ iJ2kInfo.iOption |= TJ2kInfo::EJP2file;
+
+ if ( iBufferDes.Length() < KJ2kFileInformationSize )
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadFileTypeBoxL
+// Verify and process the File Type box.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadFileTypeBoxL()
+ {
+ // Validate the File Type Box's Length and Type
+ if ( iCallFromFramework )
+ {
+ __ASSERT_ALWAYS( iLastRead == KJ2kSigBoxLength, Panic( EInvalidState ) );
+
+ ReadDataL( iLastRead, iBufferDes, KJ2kBoxTypeLength );
+
+ if ( (TUint32)iBufferDes.Length() < KJ2kBoxTypeLength )
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+
+ iPtr = iBufferDes.Ptr();
+ }
+
+ iBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ iBoxType = PtrReadUtil::ReadBigEndianUint32( iPtr );
+
+ if ( ( (TInt32)iBoxLength ) <= 0 || iBoxType != KJ2kFileTypeBox || iBoxLength > KJ2kFileTypeBoxMaxLength )
+ {
+ // Unrecognized file type box or corrupted box length
+ User::Leave( KErrCorrupt );
+ }
+
+ TUint8 xlBoxExist = 0;
+ if ( iBoxLength == 1 )
+ {
+ // The XLBox shall exist and contains the actual length of the box
+ // XLBox is 8 bytes width
+ ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, KJ2kBoxTypeLength );
+
+ if ( (TUint32)iBufferDes.Length() < KJ2kBoxTypeLength )
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+
+ iPtr = iBufferDes.Ptr();
+ iBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ iBoxLength += PtrReadUtil::ReadBigEndianUint32( iPtr );
+ xlBoxExist = 1;
+ }
+
+ if ( ( (TInt32)iBoxLength ) <= 0 || ( ( (TInt32)iBoxLength - 16 ) / 4 ) <= 0 )
+ {
+ // Must include at least one CL field in the Compatibility list
+ User::Leave( KErrCorrupt );
+ }
+
+ // Read the File Type box + the next box's Length and Type
+ ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, iBoxLength );
+
+ if ( (TUint32)iBufferDes.Length() < iBoxLength - KJ2kBoxTypeLength )
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+
+ iPtr = iBufferDes.Ptr();
+
+ // Substract next box's KJ2kBoxTypeLength
+ const TUint8 *ptrLimit = iPtr + iBoxLength - KJ2kBoxTypeLength;
+
+ // Advance the pointer by 8 bytes if XLBox exists
+ iPtr += ( xlBoxExist * KJ2kBoxTypeLength );
+
+ // Check Brand ( BR ) or Major Version
+ if ( PtrReadUtil::ReadBigEndianUint32Inc( iPtr ) != KJ2kFileTypeBrand )
+ {
+ // It is ok at this point if Major Version does not match
+ iPtr += 0;
+ }
+
+ // Check Minor Version ( MinV )
+ if ( PtrReadUtil::ReadBigEndianUint32Inc( iPtr ) != KJ2kFileTypeMinV )
+ {
+ // It is ok at this point if Minor Version does not match
+ iPtr += 0;
+ }
+
+ // Check Compatibility List ( CL )
+ TBool clFound = EFalse;
+ TUint32 clField = 0;
+ while ( ( iPtr + 4 ) <= ptrLimit )
+ {
+ clField = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ if ( clField == KJ2kFileTypeBrand )
+ {
+ clFound = ETrue;
+ }
+ else if ( clField == KJ2kFileTypeProfile0 )
+ {
+ iJ2kInfo.iOption |= TJ2kInfo::EProfile0;
+ }
+ else if ( clField == KJ2kFileTypeProfile1 )
+ {
+ iJ2kInfo.iOption |= TJ2kInfo::EProfile1;
+ }
+ else
+ {
+ // other file types require no action
+ }
+ }
+
+ if ( !clFound || iPtr != ptrLimit )
+ {
+ // Unrecognized compatibility list or data misaligned
+ User::Leave( KErrCorrupt );
+ }
+
+ iLastRead += iBoxLength;
+ iState = EStateInUnknown;
+
+ if ( (TUint32)iBufferDes.Length() < iBoxLength )
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadJp2HeaderBoxL
+// Verify and process the JP2 Header box ( superbox ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadJp2HeaderBoxL()
+ {
+ // Since we are getting data from ICL framework
+ // we have no control of when will be the EOF
+ if ( iBoxLength == 0 )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ TUint8 xlBoxExist = 0;
+ if ( iBoxLength == 1 )
+ {
+ // The XLBox shall exist and contains the actual length of the box
+ // XLBox is 8 bytes width
+ ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, KJ2kBoxTypeLength );
+
+ if ( (TUint32)iBufferDes.Length() < KJ2kBoxTypeLength )
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+
+ iPtr = iBufferDes.Ptr();
+ iBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ iBoxLength += PtrReadUtil::ReadBigEndianUint32( iPtr );
+ xlBoxExist = 1;
+ }
+
+ // Corrupted box length
+ if ( ( (TInt32)iBoxLength ) <= 0 )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ // Validate the JP2 Header Super Box
+ // Read the JP2 box + the next box's Length and Type
+ ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, iBoxLength );
+
+ if ( (TUint32)iBufferDes.Length() < iBoxLength - KJ2kBoxTypeLength )
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+
+ // Make sure that JP2 Header box contains enough data
+ // for Image Header box
+ if ( iBoxLength - KJ2kBoxTypeLength < KJ2kImageHeaderBoxLength )
+ {
+ // Missing Image Header box
+ User::Leave( KErrCorrupt );
+ }
+
+ iPtr = iBufferDes.Ptr();
+
+ // Advance the pointer by 8 bytes if XLBox exists
+ iPtr += ( xlBoxExist * KJ2kBoxTypeLength );
+
+ // Image Header box shall be the first box within JP2 Header box
+ ReadImageHeaderBoxL();
+
+ TUint32 subBoxLength = 0;
+ TUint32 subBoxType = 0;
+
+ // Substract next box's Length and Type
+ const TUint8 *ptrLimit = iPtr + iBoxLength - KJ2kBoxTypeLength - KJ2kImageHeaderBoxLength;
+ TInt32 length = ptrLimit - iPtr;
+ TBool csFound = EFalse;
+
+ while ( length > 0 )
+ {
+ if ( ( ptrLimit - iPtr ) < 8 )
+ {
+ // Not enough room for box data
+ User::Leave( KErrCorrupt );
+ }
+
+ subBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ subBoxType = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+
+ if ( subBoxLength == 1 )
+ {
+ // The XLBox shall exist and contains the actual length of the box
+ // XLBox is 8 bytes width
+ subBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ subBoxLength += PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ length -= KJ2kBoxTypeLength;
+ subBoxLength -= KJ2kBoxTypeLength;
+ }
+
+ if ( ( (TInt32)subBoxLength ) < 0 || ( subBoxLength <= 8 ) || ( ( iPtr + subBoxLength - KJ2kBoxTypeLength ) > ptrLimit ) )
+ {
+ // Not enough room for subbox data or corrupted subbox length
+ User::Leave( KErrCorrupt );
+ }
+
+ switch ( subBoxType )
+ {
+ case KJ2kColourSpecBoxType:
+ {
+ if ( !csFound )
+ {
+ // Colour Spec Box
+ ReadColorSpecBoxL( subBoxLength );
+ csFound = ETrue;
+ }
+ else
+ {
+ // Ignore the second Colour Spec Box,
+ // just advance the iterator pointer
+ iPtr += subBoxLength - KJ2kBoxTypeLength;
+ }
+ break;
+ }
+ case KJ2kResolutionBoxType:
+ {
+ // Resolution box ( superbox )
+ ReadResolutionBoxL( ptrLimit, subBoxLength );
+ break;
+ }
+ case KJ2kBitsPerCompBoxType:
+ {
+ // Bits Per Component Box
+ ReadBitsPerCompBoxL( subBoxLength );
+ break;
+ }
+ case KJ2kPaletterBoxType:
+ {
+ // Palette Box
+ ReadPaletteBoxL();
+ break;
+ }
+ case KJ2kComponentMapBoxType:
+ {
+ // Component Mapping Box
+ ReadComponentMapBoxL( subBoxLength );
+ break;
+ }
+ case KJ2kChannelDefBoxType:
+ {
+ // Channel Definition Box
+ ReadChannelDefBoxL( subBoxLength );
+ break;
+ }
+ default:
+ {
+ // Unrecognized Box
+ User::Leave( KErrCorrupt );
+ break;
+ }
+ }
+ length -= subBoxLength;
+ }
+
+ iLastRead += iBoxLength;
+ iState = EStateInUnknown;
+
+ // JP2 Header processed
+ iJ2kInfo.iOption |= TJ2kInfo::EJP2Header;
+
+ if ( (TUint32)iBufferDes.Length() < iBoxLength )
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadImageHeaderBoxL
+// Verify and process the Image Header box ( in JP2 Header box ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadImageHeaderBoxL()
+ {
+ // Validate the Image Header Box
+ if ( ( PtrReadUtil::ReadBigEndianUint32Inc( iPtr ) != KJ2kImageHeaderBoxLength ) ||
+ ( PtrReadUtil::ReadBigEndianUint32Inc( iPtr ) != KJ2kImageHeaderBoxType ) )
+ {
+ // Unrecognized Image Header box
+ User::Leave( KErrCorrupt );
+ }
+
+ iJ2kInfo.iImageSize.iHeight = (TInt)PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ iJ2kInfo.iImageSize.iWidth = (TInt)PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ iJ2kInfo.iNC = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+ iJ2kInfo.iBPC = *iPtr++;
+
+ if ( (iJ2kInfo.iImageSize.iHeight <= 0) || (iJ2kInfo.iImageSize.iWidth <= 0) ||
+ (iJ2kInfo.iNC == 0) || (iJ2kInfo.iBPC == 0) )
+ {
+ // Corrupted image parameters
+ User::Leave( KErrCorrupt );
+ }
+
+ if ( *iPtr++ != KJ2kImageHeaderCompressionType )
+ {
+ // Unrecognized compression type
+ User::Leave( KErrCorrupt );
+ }
+
+ // Check color space - UnkC
+ TUint8 value = *iPtr++;
+ if ( value == 0 || value == 1 )
+ {
+ iJ2kInfo.iOption |= ( value == 0 ) ? TJ2kInfo::EColorSpec : 0;
+ }
+ else
+ {
+ // Unrecognized color space
+ User::Leave( KErrCorrupt );
+ }
+
+ // Check intellectual property - IPR
+ value = *iPtr++;
+ if ( value == 0 || value == 1 )
+ {
+ iJ2kInfo.iOption |= value;
+ }
+ else
+ {
+ // Unrecognized intellectual property
+ User::Leave( KErrCorrupt );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadColorSpecBoxL
+// Verify and process the Colour Specification box ( in JP2 Header box ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadColorSpecBoxL( const TUint32 aBoxLength )
+ {
+ // Validate the Color Specification Box
+ TUint8 method = *iPtr++;
+
+ if ( method != 1 && method != 2 )
+ {
+ // Unrecognized method
+ User::Leave( KErrCorrupt );
+ }
+
+ // Ignore the precedence
+ iPtr++;
+
+ // Ignore the approximation
+ iPtr++;
+
+ if ( method == 1 )
+ {
+ // Method must be 1 if we reach this point
+ iJ2kInfo.iEnumCS = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ switch ( iJ2kInfo.iEnumCS )
+ {
+ case 16:
+ case 17:
+ case 18:
+ case 21:
+ case 22:
+ {
+ break;
+ }
+ default:
+ {
+ // Unrecognized colour specification
+ User::Leave( KErrNotSupported );
+ break;
+ }
+ }
+ }
+ else
+ {
+ // ICC profile
+ TUint32 length = (TUint32)( aBoxLength - KJ2kBoxTypeLength - 3 );
+ iJ2kInfo.iICCProfile = HBufC8::NewL( length );
+ iJ2kInfo.iICCProfile->Des().Append( iPtr, length );
+ iPtr += length;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadBitsPerCompBoxL
+// Verify and process the Bits Per Component box ( in JP2 Header box ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadBitsPerCompBoxL( TUint32 aBoxLength )
+ {
+ if ( iJ2kInfo.iBPC != KJ2kIsBPCBoxExist )
+ {
+ // Should not happen but we just advance
+ // the iterator and ignore the whole box
+ iPtr += aBoxLength - KJ2kBoxTypeLength;
+ return;
+ }
+
+ // Validate the Bits Per Component Box
+ if ( ( aBoxLength - KJ2kBoxTypeLength ) != iJ2kInfo.iNC )
+ {
+ // Unrecognized number of components
+ User::Leave( KErrCorrupt );
+ }
+
+ while ( aBoxLength > KJ2kBoxTypeLength )
+ {
+ User::LeaveIfError( iJ2kInfo.iBPCList.Append( *iPtr++ ) );
+
+ --aBoxLength;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadResolutionBoxL
+// Verify and process the Resolution box ( in JP2 Header box,
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadResolutionBoxL( const TUint8 *aPtrLimit, TUint32 aBoxLength )
+ {
+ TUint32 subBoxLength = 0;
+ TUint32 subBoxType = 0;
+
+ aBoxLength -= KJ2kBoxTypeLength;
+ while ( aBoxLength > 0 )
+ {
+ if ( (TUint32)( aPtrLimit - iPtr ) < KJ2kResSubBoxLength )
+ {
+ // Not enough room for subbox data
+ User::Leave( KErrCorrupt );
+ }
+
+ subBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ subBoxType = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+
+ if ( subBoxLength == 1 )
+ {
+ // The XLBox shall exist and contains the actual length of the box
+ // XLBox is 8 bytes width
+ subBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ subBoxLength += PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ aBoxLength -= KJ2kBoxTypeLength;
+ subBoxLength -= KJ2kBoxTypeLength;
+ }
+
+ if ( subBoxLength != KJ2kResSubBoxLength )
+ {
+ // Corrupted resolution box length, both sub boxes have length of 18
+ User::Leave( KErrCorrupt );
+ }
+
+ if ( subBoxType == KJ2kCaptureResBoxType )
+ {
+ ReadCaptureResBoxL( subBoxLength );
+ }
+ else if ( subBoxType == KJ2kDisplayResBoxType )
+ {
+ ReadDisplayResBoxL( );
+ }
+ else
+ {
+ // Unrecognized box in Resolution super box
+ User::Leave( KErrCorrupt );
+ }
+ aBoxLength -= subBoxLength;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadDisplayResBoxL
+// Verify and process the Default Display Resolution box ( in Resolution box ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadDisplayResBoxL()
+ {
+ // Store default display resolution
+ TUint16 verNum = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+ TUint16 verDen = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+ TUint16 horNum = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+ TUint16 horDen = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+ TUint8 verExp = *iPtr++;
+ TUint8 horExp = *iPtr++;
+ TReal tenPow = 0.0;
+
+ // Check the validity of the parameters
+ if((verNum == 0) || (verDen == 0) || (horNum == 0) || (horDen == 0))
+ {
+ // Values corrupted, do not try to compute the SizeInTwips
+ return;
+ }
+
+ User::LeaveIfError( Math::Pow10( tenPow, verExp ) );
+
+ TReal result = ( iJ2kInfo.iImageSize.iWidth / ( ( (TReal)verNum / verDen ) * tenPow ) ) / KJ2kTwipM;
+ iJ2kInfo.iImageSizeInTwips.iWidth = (TInt)result;
+
+ User::LeaveIfError( Math::Pow10( tenPow,horExp ) );
+
+ result = ( iJ2kInfo.iImageSize.iHeight / ( ( (TReal)horNum / horDen ) * tenPow ) ) / KJ2kTwipM;
+ iJ2kInfo.iImageSizeInTwips.iHeight = (TInt)result;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadCaptureResBoxL
+// Verify and process the Capture Resolution box ( in Resolution box ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadCaptureResBoxL( const TUint32 aBoxLength )
+ {
+ // Ignore the capture resolution
+ iPtr += aBoxLength - KJ2kBoxTypeLength;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadPaletteBoxL
+// Verify and process the Palette box ( in JP2 Header box ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadPaletteBoxL()
+ {
+ // Validate the Palette Box
+ TUint16 entries = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+ TUint8 npc = *iPtr++;
+
+ if((entries > KMaxPaletteEntries) || (entries == 0))
+ {
+ // Number of entries must be between 1 and 1024
+ User::Leave( KErrCorrupt );
+ }
+
+ TInt rowIndex = 0;
+ TInt columnIndex = 0;
+ RArray<TUint> bpcInBytes;
+ TUint8 bpc = 0;
+
+ for ( rowIndex = 0; rowIndex < npc; ++rowIndex )
+ {
+ bpc = *iPtr++;
+ User::LeaveIfError( iJ2kInfo.iPalette.iBList.Append( bpc ) );
+
+ bpc = (TUint8)( ( 0x7f & bpc ) + 1 );
+ User::LeaveIfError( bpcInBytes.Append( (TUint)( ( bpc % 8 ) ? bpc / 8 + 1 : bpc / 8 ) ) );
+ }
+
+ RArray<TUint> *cList;
+ CleanupClosePushL( bpcInBytes );
+
+ for ( rowIndex = 0; rowIndex < entries; ++rowIndex )
+ {
+ cList = new ( ELeave ) RArray<TUint>( npc );
+ CleanupStack::PushL( cList );
+ CleanupClosePushL( *cList );
+
+ for ( columnIndex = 0; columnIndex < npc; ++columnIndex )
+ {
+ switch ( bpcInBytes[columnIndex] )
+ {
+ case 1:
+ {
+ User::LeaveIfError( cList->Append( (TUint)*iPtr++ ) );
+ break;
+ }
+ case 2:
+ {
+ User::LeaveIfError( cList->Append( (TUint)PtrReadUtil::ReadBigEndianUint16Inc( iPtr ) ) );
+ break;
+ }
+ case 3:
+ {
+ bpc = *iPtr++;
+ User::LeaveIfError( cList->Append( ( (TUint)bpc << 16 ) | PtrReadUtil::ReadBigEndianUint16Inc( iPtr ) ) );
+ break;
+ }
+ case 4:
+ {
+ User::LeaveIfError( cList->Append( PtrReadUtil::ReadBigEndianUint32Inc( iPtr ) ) );
+ break;
+ }
+ default:
+ {
+ // Unrecognized index
+ User::Leave( KErrCorrupt );
+ break;
+ }
+ }
+ }
+ User::LeaveIfError( iJ2kInfo.iPalette.iC2DArray.Append( cList ) );
+ CleanupStack::Pop(2);
+ }
+ CleanupStack::PopAndDestroy();
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadComponentMapBoxL
+// Verify and process the Component Mapping box ( in JP2 Header box ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadComponentMapBoxL( TUint32 aBoxLength )
+ {
+ // Validate the Component Mapping Box
+ if ( ( aBoxLength - KJ2kBoxTypeLength ) % 4 != 0 )
+ {
+ // Misaligned Component Mapping box
+ User::Leave( KErrCorrupt );
+ }
+
+ TUint16 cmp = 0;
+ TUint8 mtyp = 0;
+ TUint8 pcol = 0;
+
+ while ( aBoxLength > KJ2kBoxTypeLength )
+ {
+ cmp = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+
+ if(cmp > KMaxComponents)
+ {
+ // Illegal component index
+ User::Leave( KErrCorrupt );
+ }
+
+ mtyp = *iPtr++;
+ pcol = *iPtr++;
+ if ( mtyp == 0 || mtyp == 1 )
+ {
+ if ( mtyp == 0 && pcol != 0 )
+ {
+ // Unrecognized matching between MTYP and PCOL
+ User::Leave( KErrCorrupt );
+ }
+ }
+ else
+ {
+ // Unrecognized MTYP
+ User::Leave( KErrCorrupt );
+ }
+
+ User::LeaveIfError( iJ2kInfo.iCMPList.Append( TComponentMap( cmp, mtyp, pcol ) ) );
+ aBoxLength -= 4;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadChannelDefBoxL
+// Verify and process the Channel Definition box ( in JP2 Header box ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadChannelDefBoxL( TUint32 aBoxLength )
+ {
+ // Validate the Channel Definition Box
+ TUint16 entries = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+ if ( ( aBoxLength - KJ2kBoxTypeLength - 2 ) / 6 != entries )
+ {
+ // Misaligned Channel Definition box
+ User::Leave( KErrCorrupt );
+ }
+
+ TUint16 cn = 0;
+ TUint16 typ = 0;
+ TUint16 asoc = 0;
+
+ while ( entries != 0 )
+ {
+ cn = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+ typ = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+ asoc = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+ User::LeaveIfError( iJ2kInfo.iCNList.Append( TChannelDefinition( cn, typ, asoc ) ) );
+ --entries;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadIPRBoxL
+// Verify and process the IPR box .
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadIPRBoxL()
+ {
+ // Check whether this IPR box is the last box in the file
+ if ( iBoxLength == 0 )
+ {
+ // This IPR box is the last box in the file
+ if ( iJ2kInfo.iCSOffset != 0 )
+ {
+ // CodeStream box has been recognized
+ // Since we are not able to read til the
+ // end of file/stream, we will skip this
+ // IPR box
+ iState = EStateInCodestreamBox;
+ return;
+ }
+ else
+ {
+ // The CodeStream box is missing from the file
+ // and nothing can be decoded
+ User::Leave( KErrCorrupt );
+ }
+ }
+
+ TUint xlBoxExist = 0;
+ if ( iBoxLength == 1 )
+ {
+ // The XLBox shall exist and contains the actual length of the box
+ // XLBox is 8 bytes width
+ ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, KJ2kBoxTypeLength );
+
+ if ( (TUint32)iBufferDes.Length() < KJ2kBoxTypeLength )
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+
+ iPtr = iBufferDes.Ptr();
+ iBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ iBoxLength += PtrReadUtil::ReadBigEndianUint32( iPtr );
+ xlBoxExist = 1;
+ }
+
+ // Corrupted box length
+ if ( ( (TInt32)iBoxLength ) < 0 )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ // Check whether this IPR box is the last box in the file
+ if ( iBoxLength == 0 )
+ {
+ // This IPR box is the last box in the file
+ if ( iJ2kInfo.iCSOffset != 0 )
+ {
+ // CodeStream box has been recognized
+ // Since we are not able to read til the
+ // end of file/stream, we will skip this
+ // IPR box
+ iState = EStateInCodestreamBox;
+ return;
+ }
+ else
+ {
+ // The CodeStream box is missing from the file
+ // and nothing can be decoded
+ User::Leave( KErrCorrupt );
+ }
+ }
+
+ // Validate the IPR Box
+ // Read the IPR box + the next box's Length and Type
+ ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, iBoxLength );
+
+ if ( (TUint32)iBufferDes.Length() < iBoxLength - KJ2kBoxTypeLength )
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+
+ iPtr = iBufferDes.Ptr();
+
+ // Advance the pointer by 8 bytes if XLBox exists
+ iPtr += ( xlBoxExist * KJ2kBoxTypeLength );
+
+ TInt length = iBoxLength - ( ( 1 + xlBoxExist ) * KJ2kBoxTypeLength );
+
+ HBufC8 *iprBuffer = HBufC8::NewLC( length );
+ iprBuffer->Des().Append( iPtr, length );
+ iPtr += length;
+
+ User::LeaveIfError( iJ2kInfo.iIPRList.Append( iprBuffer ) );
+ CleanupStack::Pop(); // iprBuffer
+
+ iLastRead += iBoxLength;
+ iState = EStateInUnknown;
+
+ if ( (TUint32)iBufferDes.Length() < iBoxLength )
+ {
+ // Test the end of file/stream
+ ReadDataL( iLastRead, iBufferDes, 1 );
+ if ( ( (TUint32)iBufferDes.Length() == 0 ) &&
+ ( iJ2kInfo.iCSOffset != 0 ) )
+ {
+ // CodeStream box has been recognized
+ iState = EStateInCodestreamBox;
+ }
+ else
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadXMLBoxL
+// Verify and process the XML box.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadXMLBoxL()
+ {
+ // Check whether this XML box is the last box in the file
+ if ( iBoxLength == 0 )
+ {
+ // This XML box is the last box in the file
+ if ( iJ2kInfo.iCSOffset != 0 )
+ {
+ // CodeStream box has been recognized
+ // Since we are not able to read til the
+ // end of file/stream, we will skip this
+ // XML box
+ iState = EStateInCodestreamBox;
+ return;
+ }
+ else
+ {
+ // The CodeStream box is missing from the file
+ // and nothing can be decoded
+ User::Leave( KErrCorrupt );
+ }
+ }
+
+ TUint xlBoxExist = 0;
+ if ( iBoxLength == 1 )
+ {
+ // The XLBox shall exist and contains the actual length of the box
+ // XLBox is 8 bytes width
+ ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, KJ2kBoxTypeLength );
+
+ if ( (TUint32)iBufferDes.Length() < KJ2kBoxTypeLength )
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+
+ iPtr = iBufferDes.Ptr();
+ iBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ iBoxLength += PtrReadUtil::ReadBigEndianUint32( iPtr );
+ xlBoxExist = 1;
+ }
+
+ // Corrupted box length
+ if ( ( (TInt32)iBoxLength ) < 0 )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ // Check whether this XML box is the last box in the file
+ if ( iBoxLength == 0 )
+ {
+ // This XML box is the last box in the file
+ if ( iJ2kInfo.iCSOffset != 0 )
+ {
+ // CodeStream box has been recognized
+ // Since we are not able to read til the
+ // end of file/stream, we will skip this
+ // XML box
+ iState = EStateInCodestreamBox;
+ return;
+ }
+ else
+ {
+ // The CodeStream box is missing from the file
+ // and nothing can be decoded
+ User::Leave( KErrCorrupt );
+ }
+ }
+
+ // Validate the XML Box
+ // Read the XML box + the next box's Length and Type
+ ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, iBoxLength );
+
+ if ( (TUint32)iBufferDes.Length() < iBoxLength - KJ2kBoxTypeLength )
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+
+ iPtr = iBufferDes.Ptr();
+
+ // Advance the pointer by 8 bytes if XLBox exists
+ iPtr += ( xlBoxExist * KJ2kBoxTypeLength );
+
+ TInt length = iBoxLength - ( ( 1 + xlBoxExist ) * KJ2kBoxTypeLength );
+
+ HBufC8 *xmlBuffer = HBufC8::NewLC( length );
+ xmlBuffer->Des().Append( iPtr, length );
+ iPtr += length;
+
+ User::LeaveIfError( iJ2kInfo.iXMLList.Append( xmlBuffer ) );
+ CleanupStack::Pop(); // xmlBuffer
+
+ iLastRead += iBoxLength;
+ iState = EStateInUnknown;
+
+ if ( (TUint32)iBufferDes.Length() < iBoxLength )
+ {
+ // Test the end of file
+ ReadDataL( iLastRead, iBufferDes, 1 );
+ if ( ( (TUint32)iBufferDes.Length() == 0 ) &&
+ ( iJ2kInfo.iCSOffset != 0 ) )
+ {
+ // CodeStream box has been recognized
+ iState = EStateInCodestreamBox;
+ }
+ else
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadUUIDBoxL
+// Verify and process UUID box.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadUUIDBoxL()
+ {
+ // Check whether this UUID box is the last box in the file
+ if ( iBoxLength == 0 )
+ {
+ // This UUID box is the last box in the file
+ if ( iJ2kInfo.iCSOffset != 0 )
+ {
+ // CodeStream box has been recognized
+ // Since we are not able to read til the
+ // end of file/stream, we will skip this
+ // UUID box
+ iState = EStateInCodestreamBox;
+ return;
+ }
+ else
+ {
+ // The CodeStream box is missing from the file
+ // and nothing can be decoded
+ User::Leave( KErrCorrupt );
+ }
+ }
+
+ TUint xlBoxExist = 0;
+ if ( iBoxLength == 1 )
+ {
+ // The XLBox shall exist and contains the actual length of the box
+ // XLBox is 8 bytes width
+ ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, KJ2kBoxTypeLength );
+
+ if ( (TUint32)iBufferDes.Length() < KJ2kBoxTypeLength )
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+
+ iPtr = iBufferDes.Ptr();
+ iBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ iBoxLength += PtrReadUtil::ReadBigEndianUint32( iPtr );
+ xlBoxExist = 1;
+ }
+
+ // Corrupted box length
+ if ( ( (TInt32)iBoxLength ) < 0 )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ // Check whether this UUID box is the last box in the file
+ if ( iBoxLength == 0 )
+ {
+ // This UUID box is the last box in the file
+ if ( iJ2kInfo.iCSOffset != 0 )
+ {
+ // CodeStream box has been recognized
+ // Since we are not able to read til the
+ // end of file/stream, we will skip this
+ // UUID box
+ iState = EStateInCodestreamBox;
+ return;
+ }
+ else
+ {
+ // The CodeStream box is missing from the file
+ // and nothing can be decoded
+ User::Leave( KErrCorrupt );
+ }
+ }
+
+ // Validate the UUID Box
+ // Read the UUID box + the next box's Length and Type
+ ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, iBoxLength );
+
+ if ( (TUint32)iBufferDes.Length() < iBoxLength - KJ2kBoxTypeLength )
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+
+ iPtr = iBufferDes.Ptr();
+
+ // Advance the pointer by 8 bytes if XLBox exists
+ iPtr += ( xlBoxExist * KJ2kBoxTypeLength );
+
+ TInt length = iBoxLength - ( ( 1 + xlBoxExist ) * KJ2kBoxTypeLength );
+
+ HBufC8 *uuidBuffer = HBufC8::NewLC( length );
+ uuidBuffer->Des().Append( iPtr, length );
+ iPtr += length;
+
+ User::LeaveIfError( iJ2kInfo.iUUIDList.Append( uuidBuffer ) );
+ CleanupStack::Pop(); // uuidBuffer
+
+ iLastRead += iBoxLength;
+ iState = EStateInUnknown;
+
+ if ( (TUint32)iBufferDes.Length() < iBoxLength )
+ {
+ // Test the end of file
+ ReadDataL( iLastRead, iBufferDes, 1 );
+ if ( ( (TUint32)iBufferDes.Length() == 0 ) &&
+ ( iJ2kInfo.iCSOffset != 0 ) )
+ {
+ // CodeStream box has been recognized
+ iState = EStateInCodestreamBox;
+ }
+ else
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadUUIDInfoBoxL
+// Verify and process the UUID Info box ( superbox ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadUUIDInfoBoxL()
+ {
+ // Check whether this UUIDInfo box is the last box in the file
+ if ( iBoxLength == 0 )
+ {
+ // This UUIDInfo box is the last box in the file
+ if ( iJ2kInfo.iCSOffset != 0 )
+ {
+ // CodeStream box has been recognized
+ // Since we are not able to read til the
+ // end of file/stream, we will skip this
+ // UUIDInfo box
+ iState = EStateInCodestreamBox;
+ return;
+ }
+ else
+ {
+ // The CodeStream box is missing from the file
+ // and nothing can be decoded
+ User::Leave( KErrCorrupt );
+ }
+ }
+
+ TUint xlBoxExist = 0;
+ if ( iBoxLength == 1 )
+ {
+ // The XLBox shall exist and contains the actual length of the box
+ // XLBox is 8 bytes width
+ ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, KJ2kBoxTypeLength );
+
+ if ( (TUint32)iBufferDes.Length() < KJ2kBoxTypeLength )
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+
+ iPtr = iBufferDes.Ptr();
+ iBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ iBoxLength += PtrReadUtil::ReadBigEndianUint32( iPtr );
+ xlBoxExist = 1;
+ }
+
+ // Corrupted box length
+ if ( ( (TInt32)iBoxLength ) < 0 )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ // Check whether this UUIDInfo box is the last box in the file
+ if ( iBoxLength == 0 )
+ {
+ // This UUIDInfo box is the last box in the file
+ if ( iJ2kInfo.iCSOffset != 0 )
+ {
+ // CodeStream box has been recognized
+ // Since we are not able to read til the
+ // end of file/stream, we will skip this
+ // UUIDInfo box
+ iState = EStateInCodestreamBox;
+ return;
+ }
+ else
+ {
+ // The CodeStream box is missing from the file
+ // and nothing can be decoded
+ User::Leave( KErrCorrupt );
+ }
+ }
+
+ // Validate the UUIDInfo Box
+ // Read the UUIDInfo box + the next box's Length and Type
+ ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, iBoxLength );
+
+ if ( (TUint32)iBufferDes.Length() < iBoxLength - KJ2kBoxTypeLength )
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+
+ iPtr = iBufferDes.Ptr();
+
+ // Substract next box's Length and Type
+ const TUint8 *ptrLimit = iPtr + iBoxLength - KJ2kBoxTypeLength;
+
+ // Advance the pointer by 8 bytes if XLBox exists
+ iPtr += ( xlBoxExist * KJ2kBoxTypeLength );
+
+ TUint32 subBoxLength = 0;
+ TUint32 subBoxType = 0;
+
+ TInt32 length = ptrLimit - iPtr;
+ TInt32 dataLength = 0;
+ TInt32 order = 0;
+
+ HBufC8 *listBuffer = 0;
+ HBufC8 *urlBuffer = 0;
+
+ while ( length > 0 )
+ {
+ if ( ( ptrLimit - iPtr ) < 8 )
+ {
+ // Not enough room for box data
+ User::Leave( KErrCorrupt );
+ }
+
+ subBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ subBoxType = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+
+ if ( subBoxLength == 1 )
+ {
+ // The XLBox shall exist and contains the actual length of the box
+ // XLBox is 8 bytes width
+ subBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ subBoxLength += PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ length -= KJ2kBoxTypeLength;
+ subBoxLength -= KJ2kBoxTypeLength;
+ }
+
+ if ( ( (TInt32)subBoxLength < 0 ) || ( subBoxLength <= 8 ) || ( ( iPtr + subBoxLength - KJ2kBoxTypeLength ) > ptrLimit ) )
+ {
+ // Not enough room for subbox data or corrupted subbox length
+ User::Leave( KErrCorrupt );
+ }
+
+ switch ( subBoxType )
+ {
+ case KJ2kUUIDListBoxType:
+ {
+ // Validate the UUIDInfo List box
+ // NU | ID-0 | ... | ID-n
+ // where NU is 2 bytes unsigned specifying the number of IDs
+ // ID is 16 bytes UUID
+ TUint16 nuField = PtrReadUtil::ReadBigEndianUint16( iPtr );
+ if ( ( subBoxLength - ( 2 + KJ2kBoxTypeLength ) ) !=
+ ( (TUint32)( nuField * KJ2KUuidIDSize ) ) )
+ {
+ // UUIDInfo List box does not confirm to standard format
+ User::Leave( KErrCorrupt );
+ }
+
+ if ( listBuffer )
+ {
+ // There should be one UUIDInfo List box
+ User::Leave( KErrCorrupt );
+ }
+
+ dataLength = subBoxLength - KJ2kBoxTypeLength;
+ listBuffer = HBufC8::NewLC( dataLength );
+ listBuffer->Des().Append( iPtr, dataLength );
+ iPtr += ( dataLength );
+
+ if ( order == 0 )
+ {
+ // Increment the order if UUIDInfo List box come first
+ ++order;
+ }
+ break;
+ }
+ case KJ2kUUIDUrlBoxType:
+ {
+ // Validate the UUIDInfo Data Entry Url box
+ if ( urlBuffer )
+ {
+ // There should be one UUIDInfo Data Entry Url box
+ User::Leave( KErrCorrupt );
+ }
+
+ dataLength = subBoxLength - KJ2kBoxTypeLength;
+ urlBuffer = HBufC8::NewLC( dataLength );
+ urlBuffer->Des().Append( iPtr, dataLength );
+ iPtr += ( dataLength );
+
+ if ( order == 0 )
+ {
+ // Decrement the order if UUIDInfo Data Entry Url box come first
+ --order;
+ }
+ break;
+ }
+ default:
+ {
+ // Unrecognized Box
+ User::Leave( KErrCorrupt );
+ break;
+ }
+ }
+ length -= subBoxLength;
+ }
+
+ if ( listBuffer || urlBuffer )
+ {
+ if ( !( listBuffer ) )
+ {
+ // Create a dummy place holder
+ listBuffer = HBufC8::NewLC( 1 );
+ }
+
+ if ( !( urlBuffer ) )
+ {
+ // Create a dummy place holder
+ urlBuffer = HBufC8::NewLC( 1 );
+ }
+
+ if ( order < 0 )
+ {
+ // UUIDInfo Data Entry Url box come first
+ User::LeaveIfError( iJ2kInfo.iUUIDInfoListList.Append( listBuffer ) );
+ CleanupStack::Pop( 1 ); // listBuffer
+
+ User::LeaveIfError( iJ2kInfo.iUUIDInfoUrlList.Append( urlBuffer ) );
+ CleanupStack::Pop( 1 ); // urlBuffer
+ }
+ else
+ {
+ // UUIDInfo List box come first
+ User::LeaveIfError( iJ2kInfo.iUUIDInfoUrlList.Append( urlBuffer ) );
+ CleanupStack::Pop( 1 ); // urlBuffer
+
+ User::LeaveIfError( iJ2kInfo.iUUIDInfoListList.Append( listBuffer ) );
+ CleanupStack::Pop( 1 ); // listBuffer
+ }
+ }
+ else
+ {
+ // UUIDInfo box does not containing any
+ // UUIDInfo List box or UUIDInfo Data Entry Url box
+ User::Leave( KErrCorrupt );
+ }
+
+ iLastRead += iBoxLength;
+ iState = EStateInUnknown;
+
+ if ( (TUint32)iBufferDes.Length() < iBoxLength )
+ {
+ // Test the end of file
+ ReadDataL( iLastRead, iBufferDes, 1 );
+ if ( ( (TUint32)iBufferDes.Length() == 0 ) &&
+ ( iJ2kInfo.iCSOffset != 0 ) )
+ {
+ // CodeStream box has been recognized
+ iState = EStateInCodestreamBox;
+ }
+ else
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::IgnoreBoxL
+// Ignore the content of the box and advance the iterator to the next box.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::IgnoreBoxL()
+ {
+ // Check whether this box is the last box in the file
+ if ( iBoxLength == 0 )
+ {
+ // This box is the last box in the file
+ if ( iJ2kInfo.iCSOffset != 0 )
+ {
+ // CodeStream box has been recognized
+ // Since we are not able to read til the
+ // end of file/stream, we will skip this
+ // box
+ iState = EStateInCodestreamBox;
+ return;
+ }
+ else
+ {
+ // The CodeStream box is missing from the file
+ // and nothing can be decoded
+ User::Leave( KErrCorrupt );
+ }
+ }
+
+ if ( iBoxLength == 1 )
+ {
+ // The XLBox shall exist and contains the actual length of the box
+ // XLBox is 8 bytes width
+ ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, KJ2kBoxTypeLength );
+
+ if ( (TUint32)iBufferDes.Length() < KJ2kBoxTypeLength )
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+
+ iPtr = iBufferDes.Ptr();
+ iBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ iBoxLength += PtrReadUtil::ReadBigEndianUint32( iPtr );
+ }
+
+ // Corrupted box length
+ if ( ( (TInt32)iBoxLength ) < 0 )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ // Check whether this box is the last box in the file
+ if ( iBoxLength == 0 )
+ {
+ // This box is the last box in the file
+ if ( iJ2kInfo.iCSOffset != 0 )
+ {
+ // CodeStream box has been recognized
+ // Since we are not able to read til the
+ // end of file/stream, we will skip this
+ // box
+ iState = EStateInCodestreamBox;
+ return;
+ }
+ else
+ {
+ // The CodeStream box is missing from the file
+ // and nothing can be decoded
+ User::Leave( KErrCorrupt );
+ }
+ }
+
+ // Read and ignore the validation of the box
+ ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, iBoxLength );
+
+ if ( (TUint32)iBufferDes.Length() < iBoxLength - KJ2kBoxTypeLength )
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+
+ iPtr = iBufferDes.Ptr();
+
+ iLastRead += iBoxLength;
+ iState = EStateInUnknown;
+
+ iPtr += iBoxLength - KJ2kBoxTypeLength;
+ if ( (TUint32)iBufferDes.Length() < iBoxLength )
+ {
+ // Test the end of file
+ ReadDataL( iLastRead, iBufferDes, 1 );
+ if ( ( (TUint32)iBufferDes.Length() == 0 ) &&
+ ( iJ2kInfo.iCSOffset != 0 ) )
+ {
+ // CodeStream box has been recognized
+ iState = EStateInCodestreamBox;
+ }
+ else
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::UpdateStateFromBoxTypeL
+// Update the current state according to the box type
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::UpdateStateFromBoxTypeL()
+ {
+ switch ( iBoxType )
+ {
+ case KJ2kSigBoxType:
+ {
+ iState = EStateInSignatureBox;
+ break;
+ }
+ case KJ2kJP2HeaderBoxType:
+ {
+ iState = EStateInJP2SuperBox;
+ break;
+ }
+ case KJ2kCodestreamBoxType:
+ {
+ if ( iJ2kInfo.iOption & TJ2kInfo::EJP2file )
+ {
+ if ( !( iJ2kInfo.iOption & TJ2kInfo::EJP2Header ) )
+ {
+ // In JP2 file format, CodeStream box
+ // can not come before JP2 Header box
+ User::Leave( KErrCorrupt );
+ }
+
+ // Save the CodeStream box's length
+ iJ2kInfo.iCSBoxLength = iBoxLength;
+ iJ2kInfo.iCSOffset = iLastRead;
+
+ if ( iBoxLength == 0 )
+ {
+ // CodeStream box is the last box in the file
+ iState = EStateInCodestreamBox;
+ }
+ else
+ {
+ // Continue checking any boxes after the CodeStream box
+ if ( iBoxLength == 1 )
+ {
+ // The XLBox shall exist and contains the actual length of the box
+ // XLBox is 8 bytes width
+ ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, KJ2kBoxTypeLength );
+
+ if ( (TUint32)iBufferDes.Length() < KJ2kBoxTypeLength )
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+
+ iPtr = iBufferDes.Ptr();
+ iBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+ iBoxLength += PtrReadUtil::ReadBigEndianUint32( iPtr );
+ }
+
+ // Corrupted box length
+ if ( ( (TInt32)iBoxLength ) < 0 )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ iLastRead += iBoxLength;
+ // Test the end of file
+ ReadDataL( iLastRead, iBufferDes, KJ2kBoxTypeLength );
+ if ( (TUint32)iBufferDes.Length() == 0 )
+ {
+ // CodeStream box is the last box in the file
+ iState = EStateInCodestreamBox;
+ }
+ else if ( (TUint32)iBufferDes.Length() == KJ2kBoxTypeLength )
+ {
+ iPtr = iBufferDes.Ptr();
+ }
+ else
+ {
+ // Need more data from the ICL framework
+ User::Leave( KErrUnderflow );
+ }
+ }
+ }
+ else
+ {
+ // CodeStream box must exist in file format only
+ User::Leave( KErrCorrupt );
+ }
+ break;
+ }
+ case KJ2kIPRBoxType:
+ {
+ iState = EStateInIPRBox;
+ break;
+ }
+ case KJ2kXMLBoxType:
+ {
+ iState = EStateInXMLBox;
+ break;
+ }
+ case KJ2kUUIDBoxType:
+ {
+ iState = EStateInUUIDBox;
+ break;
+ }
+ case KJ2kUUIDInfoBoxType:
+ {
+ iState = EStateInUUIDInfoBox;
+ break;
+ }
+ default:
+ {
+ // Check if the first 4 bytes read
+ // is SOC + SIZ
+ if ( iBoxLength == KJ2kSOCType )
+ {
+ if ( iJ2kInfo.iOption & TJ2kInfo::EJP2file )
+ {
+ // JP2 codestream shouldn't in JP2 file format
+ User::Leave( KErrCorrupt );
+ }
+
+ // SOC + SIZ marker - JP2 Codestream
+ iState = EStateInCodestreamBox;
+ iJ2kInfo.iCSOffset = iLastRead;
+ }
+ else
+ {
+ // Unrecognized box type
+ // there are two ways of handling this
+ // 1. stop parsing and Leave with an KErrCorrupt error
+ // User::Leave( KErrCorrupt );
+ // 2. just ignore the box and continue on parsing the
+ // next box.
+ IgnoreBoxL();
+ }
+ break;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ScanDataL
+// Called from ICL framework to instantiate decoder and parse header.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ScanDataL()
+ {
+ ReadFormatL();
+
+ ASSERT( ImageReadCodec() == NULL );
+
+ CJp2kReadCodec* imageReadCodec = CJp2kReadCodec::NewL( iJ2kInfo );
+ SetImageReadCodec( imageReadCodec );
+
+ ReadFrameHeadersL();
+ }
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+
+// -----------------------------------------------------------------------------
+// Global panic function, From JP2KImageClientMain.h
+// -----------------------------------------------------------------------------
+//
+GLDEF_C void Panic( TIclPanic aError ) //lint !e759 already in module
+ {
+ User::Panic( KJ2KPanicCategory, aError );
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Src/JP2KEntropyDecoder.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,1857 @@
+/*
+* Copyright (c) 2003, 2004 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: Entropy decoder functionality..
+*
+*/
+
+
+// INCLUDE FILES
+#include "JP2KCodeBlock.h"
+#include "JP2KTileInfo.h"
+#include "JP2KImageInfo.h"
+#include "JP2KEntropyDecoder.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// Mq decoder state information, all of the 47 states contain
+// the probability estimate of LPS in hexadecimal, the next
+// mps state index, the next lps state index and the flag
+// indicating a mps switch.
+const TUint32 KMqQeStates[KNumberOriginalMQEntries] = {0x5601,0x3401,0x1801,0x0ac1,0x0521,0x0221,0x5601,
+ 0x5401,0x4801,0x3801,0x3001,0x2401,0x1c01,0x1601,
+ 0x5601,0x5401,0x5101,0x4801,0x3801,0x3401,0x3001,
+ 0x2801,0x2401,0x2201,0x1c01,0x1801,0x1601,0x1401,
+ 0x1201,0x1101,0x0ac1,0x09c1,0x08a1,0x0521,0x0441,
+ 0x02a1,0x0221,0x0141,0x0111,0x0085,0x0049,0x0025,
+ 0x0015,0x0009,0x0005,0x0001,0x5601};
+
+const TInt32 KMqMpsStates[KNumberOriginalMQEntries] = {1,2,3,4,5,38,7,8,9,10,11,12,13,29,15,16,17,18,19,
+ 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,
+ 36,37,38,39,40,41,42,43,44,45,45,46};
+
+const TInt32 KMqLpsStates[KNumberOriginalMQEntries] = {1,6,9,12,29,33,6,14,14,14,17,18,20,21,14,14,15,16,
+ 17,18,19,19,20,21,22,23,24,25,26,27,28,29,30,31,
+ 32,33,34,35,36,37,38,39,40,41,42,43,46};
+
+const TInt32 KMqSwitchFlagStates[KNumberOriginalMQEntries] = {1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0};
+
+// MQCoder initial states
+const TInt32 KMqInitStates[KNumberContexts] = {46,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// J2KEntropyStream::ReadByteFromStream
+// Read a byte from the input stream
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+TUint8 J2KEntropyStream::ReadByteFromStream()
+ {
+ if ( iPosition < iNumBytes )
+ {
+ return ( TUint8 )iBuffer[iPosition++];
+ }
+ else
+ {
+ // 0xFF to represent EOF
+ return ( 0xFF );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// J2KEntropyStream::ReadBitFromStream
+// Read a bit from the input stream
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+TUint8 J2KEntropyStream::ReadBitFromStream()
+ {
+ if ( iTinyBufferPos == 0 )
+ {
+ // Input the byte buffer
+ iTinyBuffer = ReadByteFromStream();
+
+ if ( iDelayedFF )
+ {
+ iTinyBufferPos = 7;
+ }
+ else
+ {
+ iTinyBufferPos = 8;
+ }
+
+ if ( iTinyBuffer != 0xFF ) // No bit-stuffing needed
+ {
+ iDelayedFF = 0;
+ }
+ else // We need to do bit stuffing on next byte
+ {
+ iDelayedFF = 1;
+ }
+ }
+
+ return (TUint8)( ( iTinyBuffer >> ( --iTinyBufferPos ) ) & 0x01 );
+ }
+
+// -----------------------------------------------------------------------------
+// J2KEntropyStream::CheckPrediction
+// Check a prediction termination for raw coding
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+TEntropyErrorState J2KEntropyStream::CheckPrediction()
+ {
+ // Error resilient sequence in last byte
+ TInt32 errorResSeq = 0;
+
+ // If tiny buffer is empty and equal to 0xFF,
+ // get the next byte for error resilience marker
+ if ( iTinyBufferPos == 0 && iTinyBuffer == 0xFF )
+ {
+ iTinyBuffer = ReadByteFromStream();
+ iTinyBufferPos = 7;
+ }
+
+ // Search for the error resilience marker
+ if ( iTinyBufferPos > 0 )
+ {
+ // Get the error resilience sequence
+ errorResSeq = iTinyBuffer & ( ( 1 << iTinyBufferPos ) - 1 );
+
+ // Compare the read error resilience marker to the constant 01010101 byte
+ if ( errorResSeq != ( KErrorResilienceTermination >> ( 8 - iTinyBufferPos ) ) )
+ {
+ return EEntropyCodingError;
+ }
+ }
+
+ // If we are not at the end of this stream,
+ // next byte should be smaller than 0x80.
+ if ( iPosition < iNumBytes )
+ {
+ if ( iTinyBuffer == 0xFF && iTinyBufferPos == 1 )
+ {
+ if ( ReadByteFromStream() >= 0x80 )
+ {
+ return EEntropyCodingError;
+ }
+ }
+ else
+ {
+ if ( ReadByteFromStream() != 0xFF )
+ {
+ return EEntropyCodingError;
+ }
+ }
+ }
+
+ // No error detected
+ return ENoError;
+ }
+
+// -----------------------------------------------------------------------------
+// J2KEntropyStream::ResetInputStream
+// Reset the input stream
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+void J2KEntropyStream::ResetInputStream()
+ {
+ // Initialize the stream parameters. Note that stream->position is not reset here,
+ // it is reset only when the stream is created for the first time.
+ iTinyBuffer = 0;
+ iTinyBufferPos = 0;
+ iDelayedFF = 0;
+ }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// Destructor
+J2KMQCoder::~J2KMQCoder()
+ {
+ iOriginalStates.ResetAndDestroy();
+ iContextList.ResetAndDestroy();
+ }
+
+// -----------------------------------------------------------------------------
+// J2KMQCoder::MqByteIn
+// Read a byte from the input stream
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+void J2KMQCoder::MqByteIn()
+ {
+ if ( !iMarker )
+ {
+ if ( iB == 0xff )
+ {
+ iB = iInputStream.ReadByteFromStream();
+
+ if ( iB > 0x8f )
+ {
+ iMarker = 1;
+ iCT = 8;
+ }
+ else
+ {
+ iC += 0xFE00 - ( iB << 9 );
+ iCT = 7;
+ }
+ }
+ else
+ {
+ iB = iInputStream.ReadByteFromStream();
+ iC += 0xFF00 - ( iB << 8 );
+ iCT = 8;
+ }
+ }
+ else
+ {
+ iCT = 8;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// J2KMQCoder::MqDecodeSymbol
+// Decode the symbol
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+TUint8 J2KMQCoder::MqDecodeSymbol( TInt32 aContextIndex )
+ {
+ // Set the current context to point to the right place in the context list
+ iCurrentContext = iContextList[aContextIndex];
+ iCurrentState = iCurrentContext->iState;
+
+ iA -= iCurrentState->iQe;
+
+ // Decision returned ( i.e. decoded symbol )
+ TInt32 decision = 0;
+ if ( ( iC >> 16 ) < iA ) // Chigh >= A
+ {
+ MpsExchange( decision );
+ }
+ else // lps exchange
+ {
+ LpsExchange( decision );
+ }
+
+ // Return decision
+ return (TUint8)decision;
+ }
+
+// -----------------------------------------------------------------------------
+// J2KMQCoder::MqInitDecoder
+// Initialize the MQCoder
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+void J2KMQCoder::MqInitDecoder()
+ {
+ iMarker = 0;
+ iB = iInputStream.ReadByteFromStream();
+
+ // Software conventions decoder initialization
+ iC = ( iB ^ 0xFF ) << 16;
+ MqByteIn();
+
+ iC <<= 7;
+ iCT -= 7;
+ iA = 0x8000;
+ }
+
+// -----------------------------------------------------------------------------
+// J2KMQCoder::MqCheckPrediction
+// Check the prediction termination
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+TEntropyErrorState J2KMQCoder::MqCheckPrediction()
+ {
+ // If no marker was found, B should be == 0xFF and counter zero,
+ // otherwise there is an error
+ if ( !iMarker && ( iCT != 0 || iB != 0xFF ) )
+ {
+ return EEntropyCodingError;
+ }
+
+ // If counter CT is 1, no need to check any further
+ if ( iCT == 1 )
+ {
+ return ENoError;
+ }
+
+ // If counter CT is zero, then next byte must be larger than 0x8F, if the terminating
+ // marker has not been reached yet
+ if ( iCT == 0 )
+ {
+ if ( !iMarker )
+ {
+ // Get next byte and check that it is larger than 0x8F
+ iB = iInputStream.ReadByteFromStream();
+ if ( iB <= 0x8F )
+ {
+ return EEntropyCodingError;
+ }
+ }
+ // Set the counter back to 8
+ iCT = 8;
+ }
+
+ // Number of bits that where added in the termination process
+ // Compute the number of bits, k for error resilience information
+ TUint32 k = (TUint32)( iCT - 1 );
+
+ // Check for a coded LPS.
+ TUint32 q = 0x8000 >> k;
+
+ // Check that we can decode an LPS interval of probability 'q'
+ iA -= q;
+ if ( ( iC >> 16 ) < iA ) // software convention
+ {
+ // MPS interval was decoded, thus error occured
+ return EEntropyCodingError;
+ }
+
+ // Check for coded LPS interval.
+ iA = q;
+
+ do // Renormalization
+ {
+ if ( iCT == 0 )
+ {
+ MqByteIn();
+ }
+
+ iA <<= 1;
+ iC <<= 1;
+ iCT--;
+
+ } while ( iA < 0x8000 );
+
+ // No error was found
+ return ENoError;
+ }
+
+// -----------------------------------------------------------------------------
+// J2KMQCoder::ResetMqContexts
+// Reset the MQCoder context list to the original state
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+void J2KMQCoder::ResetMqContexts()
+ {
+ // Reset all context states to initial states and set the mps
+ // of every context to 0.
+ for ( TInt32 i = KNumberContexts - 1; i >= 0; i-- )
+ {
+ iContextList[i]->iState = iOriginalStates[KMqInitStates[i]];
+ iContextList[i]->iMPS = 0;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// J2KMQCoder::ResetMQDecoder
+// Initialze MQCoder and reset the context
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+void J2KMQCoder::ResetMQDecoder( TInt32 aSegmentLength )
+ {
+ // Reset all contexts ( states and mps )
+ ResetMqContexts();
+ iInputStream.ResetInputStream();
+ iInputStream.iPosition = 0;
+ iInputStream.iNumBytes = aSegmentLength;
+ MqInitDecoder();
+ }
+
+// -----------------------------------------------------------------------------
+// J2KMQCoder::InitializeOrigMqTable
+// Initialize MQCoder original states table
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+void J2KMQCoder::InitializeOrigMqTable()
+ {
+ for ( TUint8 i = 0; i < KNumberOriginalMQEntries; i++ )
+ {
+ iOriginalStates[i]->iQe = KMqQeStates[i];
+ iOriginalStates[i]->iNextMPS = iOriginalStates[KMqMpsStates[i]];
+ iOriginalStates[i]->iNextLPS = iOriginalStates[KMqLpsStates[i]];
+ iOriginalStates[i]->iSwitchFlag = KMqSwitchFlagStates[i];
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// J2KMQCoder::ReNormalize
+// Renormalize
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+void J2KMQCoder::ReNormalize()
+ {
+ do
+ {
+ if ( iCT == 0 )
+ {
+ MqByteIn();
+ }
+
+ iA <<= 1;
+ iC <<= 1;
+ --iCT;
+ } while ( !( iA & 0x8000 ) );
+ }
+
+// -----------------------------------------------------------------------------
+// J2KMQCoder::MpsExchange
+// MPS exchange
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+void J2KMQCoder::MpsExchange( TInt32& aD )
+ {
+ aD = iCurrentContext->iMPS;
+ if ( !( iA & 0x8000 ) )
+ {
+ if ( iA < iCurrentState->iQe )
+ {
+ aD ^= 1;
+ if ( iCurrentState->iSwitchFlag )
+ {
+ iCurrentContext->iMPS ^= 1;
+ }
+
+ iCurrentContext->iState = iCurrentState->iNextLPS;
+ }
+ else
+ {
+ iCurrentContext->iState = iCurrentState->iNextMPS;
+ }
+
+ ReNormalize();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// J2KMQCoder::LpsExchange
+// LPS exchange
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+void J2KMQCoder::LpsExchange( TInt32& aD )
+ {
+ iC -= iA << 16;
+ aD = iCurrentContext->iMPS;
+ if ( iA < iCurrentState->iQe )
+ {
+ iCurrentContext->iState = iCurrentState->iNextMPS;
+ }
+ else
+ {
+ aD ^= 1;
+ if ( iCurrentState->iSwitchFlag )
+ {
+ iCurrentContext->iMPS ^= 1;
+ }
+
+ iCurrentContext->iState = iCurrentState->iNextLPS;
+ }
+ iA = iCurrentState->iQe;
+ ReNormalize( );
+ }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CJ2kEntropyDecoder* CJ2kEntropyDecoder::NewL( CJ2kImageInfo& aImageInfo )
+ {
+ CJ2kEntropyDecoder *self = new ( ELeave ) CJ2kEntropyDecoder;
+
+ CleanupStack::PushL( self );
+ self->ConstructL( aImageInfo );
+ CleanupStack::Pop();
+
+ return self;
+ }
+
+// Destructor
+CJ2kEntropyDecoder::~CJ2kEntropyDecoder()
+ {
+ delete iMRLutBuf;
+ iMRLutBuf = 0;
+
+ delete iSCLutBuf;
+ iSCLutBuf = 0;
+
+ delete iZcLutLL;
+ iZcLutLL = 0;
+
+ delete iZcLutHL;
+ iZcLutHL = 0;
+
+ delete iZcLutHH;
+ iZcLutHH = 0;
+
+ TJ2kUtils::Free2DArray( iData );
+ User::Free( iStates );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::SetNewSizeL
+// Set the size of internal buffer and other control data
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::SetNewSizeL( const TSize& aSize )
+ {
+ if ( aSize.iWidth <= iCurrentSize.iWidth &&
+ aSize.iHeight <= iCurrentSize.iHeight )
+ {
+ return;
+ }
+ else
+ {
+ iCurrentSize = aSize;
+
+ TJ2kUtils::Free2DArray( iData );
+ iData = 0;
+ iData = TJ2kUtils::Alloc2DArrayL( iCurrentSize.iHeight, iCurrentSize.iWidth );
+
+ iMaxBlockWidth = (TUint8)( iCurrentSize.iWidth );
+
+ // We can compute some parameters for entropy decoding here not to compute them for every pass!!!
+ iBlockDataWidth = iMaxBlockWidth;
+ iStateWidth = iMaxBlockWidth + 2;
+ iStateSize = ( iCurrentSize.iHeight + 2 ) * ( iCurrentSize.iWidth + 2 );
+ iDataSamplesPerStripe = iBlockDataWidth * KStripeHeight;
+ iStateSamplesPerStripe = iStateWidth * KStripeHeight;
+
+ TInt16* ptrTemp = STATIC_CAST( TInt16*, User::ReAlloc( iStates, iStateSize * sizeof( TInt16 ) ) );
+ if ( !ptrTemp )
+ {
+ User::Leave( KErrNoMemory );
+ }
+ iStates = ptrTemp;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::SetCurrentZCLUT
+// Set the current pointer to point to the right LUT depending on the current subband
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::SetCurrentZCLUT( TUint8 aBandIndex )
+ {
+ if ( aBandIndex == 1 )
+ {
+ // For HL band
+ iCurrentZcLutPtr = (TUint8*)iZcLutHL->Des().Ptr();
+ }
+ else if ( aBandIndex == 3 )
+ {
+ // For HH band
+ iCurrentZcLutPtr = (TUint8*)iZcLutHH->Des().Ptr();
+ }
+ else
+ {
+ // For LL and LH band
+ iCurrentZcLutPtr = (TUint8*)iZcLutLL->Des().Ptr();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::DecodeCodeblock
+// Decode the coded codeblock
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::DecodeCodeblock( CJ2kCodeBlock& aCodeblock, TUint8 aCblkStyle,
+ TUint8 aMagBits )
+ {
+ TInt32 startBitplane = 0; // The bitplane where coding starts
+ TInt32 endBitplane = 0; // The last coded bitplane
+ TInt32 terminationLength = 0;
+ TUint8 tempPassIndex = 0;
+ TUint8 passIndex = 0;
+
+ iMQDecoder.iInputStream.iBuffer = CONST_CAST( TUint8*, aCodeblock.Data() );
+ TSize codeBlockSize = aCodeblock.CodeBlockCanvas().Size();
+
+ iVerticalCausalContextUsed = ( ( aCblkStyle & EVerticalStripe ) != 0 );
+ iResetContexts = ( ( aCblkStyle & EResetContext ) != 0 );
+ iPredictableTerminationUsed = ( ( aCblkStyle & EPredictableTermination ) != 0 );
+ TUint8 terminateEachPass = ( ( aCblkStyle & ETermination ) != 0 );
+ TUint8 segmentationSymbolsUsed = ( ( aCblkStyle & ESegmentationSymbols ) != 0 );
+ TUint8 arithmeticBypass = ( ( aCblkStyle & EArithmeticBypass ) != 0 );
+ aCodeblock.ResetPassIndex();
+
+
+ // Initialize the stream and the mq coder for this code block:
+ // also set mq coder's stream to point to aCodeblock's stream
+ if ( !arithmeticBypass && !terminateEachPass ) // No termination
+ {
+ iMQDecoder.ResetMQDecoder( aCodeblock.DataLength() );
+ }
+ else
+ {
+ // Compute the length of the first terminated segment. If we are
+ // terminating on each pass, terminated lengths are equal to
+ // codeblock lengths. On the other hand if we are using arithmetic
+ // bypass ( without terminating each pass ), the first termination length
+ // is the codeblock lengths summed up to the point where we have last AC
+ // pass before first raw coding pass.
+
+ if ( terminateEachPass )
+ {
+ terminationLength = aCodeblock.CblkLength( (TUint16)passIndex++ );
+ }
+ else // AC bypass without termination on each pass
+ {
+ // Loop adding codeblock lengths until enough passes have been consumed
+ while ( ( tempPassIndex < KFirstBypassTermIndex ) && ( passIndex <= aCodeblock.LastPass() ) )
+ {
+ tempPassIndex = (TUint8)( tempPassIndex + aCodeblock.PassesPerSegment( passIndex ) );
+ terminationLength = (TUint32)( terminationLength + aCodeblock.CblkLength( passIndex++ ) );
+ }
+ }
+
+ // Now initialize the iMQDecoder with the right terminated length
+ iMQDecoder.ResetMQDecoder( terminationLength );
+ }
+
+ // Initialize data array
+ for ( TInt i = codeBlockSize.iHeight - 1; i >= 0; i-- )
+ {
+ Mem::FillZ( iData[i], codeBlockSize.iWidth * sizeof( TPrecInt ) );
+ }
+
+ // Initialize iStates array
+ Mem::FillZ( iStates, iStateSize * sizeof( TInt16 ) );
+
+ // Compute different bitplanes; empty bitplanes tells how many bitplanes are
+ // empty in this codeblock compared to the whole subband, iStartBitplane gives
+ // the index of the first bitplane to be coded for this block and iEndBitplane
+ // is the index of the last bitplane coded for this codeblock.
+
+ // Compute coded block's magnitude bits
+ aMagBits = (TUint8)( aMagBits - aCodeblock.EmptyBitplanes() );
+ startBitplane = ( KImplementationPrecision - 2 ) - aCodeblock.EmptyBitplanes();
+ endBitplane = startBitplane - aMagBits;
+
+ // Compute the number of stripes for this codeblock
+ iNumStripes = (TUint16)( ( codeBlockSize.iHeight + KStripeHeight - 1 ) / KStripeHeight );
+ iBlockWidth = codeBlockSize.iWidth;
+
+ // Compute the last stripe's height once,
+ // so that we don't have to compute it for all passes!
+ iLastStripeHeight = codeBlockSize.iHeight - ( iNumStripes - 1 ) * KStripeHeight;
+
+ iCurrentBitplane = (TUint8)( startBitplane );
+
+ // First do only the normalization pass
+ iTerminateThisPass = ( terminateEachPass || ( iCurrentBitplane == endBitplane ) );
+
+ CleanupPass( segmentationSymbolsUsed );
+
+ aCodeblock.IncrementPassIndex();
+
+ iCurrentBitplane--;
+
+ // Then repeat the three passes: significance, refinement and normalization
+ // for the remaining bitplanes.
+ while ( aCodeblock.PassIndex() <= aCodeblock.LastPass() )
+ {
+ // Significance pass, terminate only if terminating after each pass
+ iTerminateThisPass = terminateEachPass;
+
+ if ( ( arithmeticBypass == 0 ) || ( aCodeblock.PassIndex() < KFirstLazyPassIndex ) )
+ {
+ if ( terminateEachPass ) // if last pass was terminated, initialize MQ-coder
+ {
+ // Update the number of available TUint8s for this terminated sequence
+ iMQDecoder.iInputStream.iNumBytes += aCodeblock.CblkLength( passIndex++ );
+ iMQDecoder.MqInitDecoder();
+ }
+
+ SignificancePass();
+ }
+ else
+ {
+ // if we are here, then the previous pass was terminated
+ if ( terminateEachPass )
+ {
+ // Update the number of available bytes for this terminated sequence
+ iMQDecoder.iInputStream.iNumBytes += aCodeblock.CblkLength( passIndex++ );
+ }
+ else // AC bypass without termination on each pass
+ {
+ // Here we have two cases:
+ // 1. If this codeblock length is for this pass only, then for the terminated length
+ // we have to add the next pass codeblock length also.
+ // 2. This codeblock length is for both this pass ( significance ) and the next pass
+ // ( refinement ). Terminated length is equal to the CblkLength[iPassIndex].
+ if ( aCodeblock.PassesPerSegment( passIndex ) == 2 )
+ {
+ iMQDecoder.iInputStream.iNumBytes += aCodeblock.CblkLength( passIndex++ );
+ }
+ else
+ {
+ iMQDecoder.iInputStream.iNumBytes += aCodeblock.CblkLength( passIndex ) +
+ aCodeblock.CblkLength( (TUint16)( passIndex + 1 ) );
+ passIndex += 2;
+ }
+ }
+ iMQDecoder.iInputStream.ResetInputStream();
+ LazySignificancePass();
+ }
+
+ aCodeblock.IncrementPassIndex();
+ if ( aCodeblock.PassIndex() > aCodeblock.LastPass() )
+ {
+ // We have fully decoded this codeblock
+ return;
+ }
+
+ // Magnitude refinement pass, terminate if raw coding or termination after each pass
+ iTerminateThisPass = ( terminateEachPass || ( arithmeticBypass && ( aCodeblock.PassIndex() >
+ KFirstLazyPassIndex ) ) );
+
+ if ( arithmeticBypass == 0 || ( aCodeblock.PassIndex() < KFirstLazyPassIndex ) )
+ {
+ if ( terminateEachPass ) // if previous pass was terminated, initialize MQ-coder
+ {
+ // Update the number of available bytes for this terminated sequence
+ iMQDecoder.iInputStream.iNumBytes += aCodeblock.CblkLength( passIndex++ );
+ iMQDecoder.MqInitDecoder();
+ }
+
+ RefinementPass();
+ }
+ else
+ {
+ if ( terminateEachPass ) // if previous pass was terminated
+ {
+ // Update the number of available bytes for this terminated sequence
+ iMQDecoder.iInputStream.iNumBytes += aCodeblock.CblkLength( passIndex++ );
+ iMQDecoder.iInputStream.ResetInputStream();
+ }
+
+ LazyRefinementPass();
+ }
+
+ aCodeblock.IncrementPassIndex();
+ if ( aCodeblock.PassIndex() > aCodeblock.LastPass() )
+ {
+ // We have fully decoded this codeblock
+ return;
+ }
+
+ // Cleanup pass, terminate if coding raw, termination after each pass, last bitplane
+ // before starting raw coding or last bitplane in this codeblock.
+ iTerminateThisPass = ( terminateEachPass || ( iCurrentBitplane == endBitplane ) ||
+ ( arithmeticBypass && ( aCodeblock.PassIndex() >= KFirstLazyPassIndex ) ) );
+
+ // If last ( AC ) pass was terminated, initialize MQ-coder
+ if ( terminateEachPass || ( arithmeticBypass && ( aCodeblock.PassIndex() > KFirstLazyPassIndex ) ) )
+ {
+ // Update the number of available bytes for this terminated sequence
+ iMQDecoder.iInputStream.iNumBytes += aCodeblock.CblkLength( passIndex++ );
+ iMQDecoder.MqInitDecoder();
+ }
+
+ CleanupPass( segmentationSymbolsUsed );
+
+ aCodeblock.IncrementPassIndex();
+ if ( aCodeblock.PassIndex() > aCodeblock.LastPass() )
+ {
+ // We have fully decoded this codeblock
+ return;
+ }
+
+ // move onto next bitplane
+ if ( iCurrentBitplane == 0 ) // This might happen with 16-bit and ROI
+ {
+ // We have fully decoded this codeblock
+ return;
+ }
+
+ iCurrentBitplane--;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::ConstructL( CJ2kImageInfo& aImageInfo )
+ {
+ iCurrentSize = aImageInfo.MaxBlockSize();
+
+ for ( TUint16 i = 0; i < KNumberContexts; i++ )
+ {
+ J2KEntropyContexts *context = new ( ELeave ) J2KEntropyContexts;
+ CleanupStack::PushL( context );
+ User::LeaveIfError( iMQDecoder.iContextList.Append( context ) );
+ CleanupStack::Pop(1);
+ }
+
+ for ( TUint16 ii = 0; ii < KNumberOriginalMQEntries; ii++ )
+ {
+ J2KEntropyStates *state = new ( ELeave ) J2KEntropyStates;
+ CleanupStack::PushL( state );
+ User::LeaveIfError( iMQDecoder.iOriginalStates.Append( state ) );
+ CleanupStack::Pop(1);
+ }
+
+ // Allocate memory for the SC Look up table
+ iSCLutBuf = HBufC8::NewL( KLutSize );
+ iSCLut = CONST_CAST( TUint8*, iSCLutBuf->Des().Ptr() );
+
+ // Allocate memory for the MR Look up table
+ iMRLutBuf = HBufC8::NewL( KLutSize );
+ iMRLut = CONST_CAST( TUint8*, iMRLutBuf->Des().Ptr() );
+
+ // Allocate memory for the Zero coding Look up table
+ iZcLutLL = HBufC8::NewL( ( 1 << KZcLutBits ) );
+ iZcLutHL = HBufC8::NewL( ( 1 << KZcLutBits ) );
+ iZcLutHH = HBufC8::NewL( ( 1 << KZcLutBits ) );
+
+ iData = TJ2kUtils::Alloc2DArrayL( iCurrentSize.iHeight, iCurrentSize.iWidth );
+
+ iMaxBlockWidth = (TUint16)( iCurrentSize.iWidth );
+
+ // We can compute some parameters for entropy decoding here not to compute them for every pass!!!
+ iBlockDataWidth = iMaxBlockWidth;
+ iStateWidth = iMaxBlockWidth + 2;
+ iStateSize = ( iCurrentSize.iHeight + 2 ) * ( iCurrentSize.iWidth + 2 );
+ iDataSamplesPerStripe = iBlockDataWidth * KStripeHeight;
+ iStateSamplesPerStripe = iStateWidth * KStripeHeight;
+
+ iStates = STATIC_CAST( TInt16*, User::AllocL( iStateSize * sizeof( TInt16 ) ) );
+
+ // Initialization of the MQ tables needed since
+ // the original table could not be used as it was constant!
+ iMQDecoder.InitializeOrigMqTable();
+
+ iMaxBitDepth = 0;
+ for ( TUint16 iii = 0; iii < aImageInfo.NumOfComponents(); ++iii )
+ {
+ iMaxBitDepth = Max( iMaxBitDepth, aImageInfo.DepthOfComponent( iii ) );
+ }
+
+ // Initialize ZC lookup table
+ InitializeZCLut();
+
+ // Initialize SC/MR lookup table
+ InitializeScMrLut();
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::InitializeZCLut
+// Initialize ZC lookup table
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::InitializeZCLut()
+ {
+ // Create pointers for all the ZC LUT's
+ TUint8* iZcLutLLPtr = CONST_CAST( TUint8*, iZcLutLL->Des().Ptr() );
+ TUint8* iZcLutHLPtr = CONST_CAST( TUint8*, iZcLutHL->Des().Ptr() );
+ TUint8* iZcLutHHPtr = CONST_CAST( TUint8*, iZcLutHH->Des().Ptr() );
+
+ TInt32 ctxt = 0;
+ TUint16 sh = 0; // horizontal sum
+ TUint16 sv = 0; // vertical sum
+ TUint16 sd = 0; // diagonal sum
+
+ for ( TUint16 i = 0; i <= KZcMask; i++ )
+ {
+ sh = (TUint16)( ( ( i >> KPositionRight ) & 1 ) + ( ( i >> KPositionLeft ) & 1 ) );
+ sv = (TUint16)( ( ( i >> KPositionDown ) & 1 ) + ( ( i >> KPositionUp ) & 1 ) );
+ sd = (TUint16)( ( ( i >> KPositionUpperLeft ) & 1 ) + ( ( i >> KPositionUpperRight ) & 1 ) +
+ ( ( i >> KPositionLowerLeft ) & 1 ) + ( ( i >> KPositionLowerRight ) & 1 ) );
+
+ if ( sh == 2 )
+ {
+ ctxt = 10;
+ }
+ else if ( sh == 1 )
+ {
+ if ( sv )
+ {
+ ctxt = 9;
+ }
+ else if ( sd )
+ {
+ ctxt = 8;
+ }
+ else
+ {
+ ctxt = 7;
+ }
+ }
+ else
+ {
+ if ( sv )
+ {
+ ctxt = 4 + sv;
+ }
+ else
+ {
+ ctxt = 2 + ( ( sd > 2 ) ? 2 : sd );
+ }
+ }
+
+ iZcLutLLPtr[i] = (TUint8) ctxt;
+
+
+ if ( sv == 2 )
+ {
+ ctxt = 10;
+ }
+ else if ( sv == 1 )
+ {
+ if ( sh )
+ {
+ ctxt = 9;
+ }
+ else if ( sd )
+ {
+ ctxt = 8;
+ }
+ else
+ {
+ ctxt = 7;
+ }
+ }
+ else
+ {
+ if ( sh )
+ {
+ ctxt = 4 + sh;
+ }
+ else
+ {
+ ctxt = 2 + ( ( sd > 2 ) ? 2 : sd );
+ }
+ }
+
+ iZcLutHLPtr[i] = (TUint8) ctxt;
+
+ if ( sd >= 3 )
+ {
+ ctxt = 10;
+ }
+ else if ( sd == 2 )
+ {
+ if ( ( sv + sh ) >= 1 )
+ {
+ ctxt = 9;
+ }
+ else
+ {
+ ctxt = 8;
+ }
+ }
+ else if ( sd == 1 )
+ {
+ ctxt = 5 + ( ( ( sv + sh ) > 2 ) ? 2 : ( sv + sh ) );
+ }
+ else
+ {
+ ctxt = 2 + ( ( ( sv + sh ) > 2 ) ? 2 : ( sv + sh ) );
+ }
+
+ iZcLutHHPtr[i] = (TUint8) ctxt;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::InitializeScMrLut
+// Initialize SC/MR lookup table
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::InitializeScMrLut()
+ {
+ TInt32 ctxt = 0;
+ TInt32 vpos = 0; // vert +
+ TInt32 vneg = 0; // vert -
+ TInt32 hpos = 0; // hor +
+ TInt32 hneg = 0; // hor -
+ TInt32 hc = 0; // horizontal contribution
+ TInt32 vc = 0; // vertical contribution
+ TInt16 predict = 0; // the xor bit for differentiating states. ( positioned at the 6th bit )
+
+ for ( TUint8 i = 0; i < 16; i++ )
+ {
+ vpos = i & 1;
+ vneg = ( i >> 1 ) & 1;
+ hpos = ( i >> 2 ) & 1;
+ hneg = ( i >> 3 ) & 1;
+ hc = hpos - hneg;
+ vc = vpos - vneg;
+ predict = 0;
+ if ( hc < 0 )
+ {
+ predict = 1;
+ hc = -hc;
+ vc = -vc;
+ }
+ if ( hc == 0 )
+ {
+ if ( vc < 0 )
+ {
+ predict = 1;
+ vc = -vc;
+ }
+ ctxt = 11 + vc;
+ }
+ else
+ {
+ ctxt = 14 + vc;
+ }
+
+ iSCLut[i] = (TUint8) ( ctxt | ( predict << KPredictionBit ) );
+ }
+ iMRLut[0] = 16;
+ iMRLut[1] = 17;
+ iMRLut[2] = 18;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::GetCausal
+// Get the casual
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::GetCausal( TPrecInt*& aDataCol, TInt16*& aStateCol )
+ {
+ TInt32 vpos = 0;
+ TInt32 vneg = 0;
+ TUint16 state = 0;
+ TInt16 causalityMask = 0;
+
+ aDataCol--;
+ for ( TInt32 col = iStateWidth; col > 0; col-- )
+ {
+ state = *aStateCol;
+ vpos = 0;
+ vneg = 0;
+ if ( ( ( state >> KPositionDown ) & 1 ) == 1 )
+ {
+ if ( ( ( state >> KPositionUp ) & 1 ) == 1 )
+ {
+ if ( col < iStateWidth )
+ {
+ if ( *aDataCol >= 0 )
+ {
+ vneg = 1;
+ }
+ else
+ {
+ vpos = 1;
+ }
+ }
+ }
+ else
+ {
+ vpos = 1;
+ vneg = 1;
+ }
+ }
+ causalityMask = (TInt16)( ~( ( KStateDown| KStateLowerLeft | KStateLowerRight ) |
+ ( vneg << KPositionVerNeg ) | ( vpos << KPositionVerPos ) ) );
+
+ ( *aStateCol ) &= causalityMask;
+ aDataCol++;
+ aStateCol++;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::DecodeSignificance
+// Decode the significance bit
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::DecodeSignificance( TPrecInt*& aDataValue, TInt16*& aStateValue, TPrecInt aMask )
+ {
+ TUint32 state = *aStateValue;
+ TInt32 context = state & KZcMask;
+ if ( ( state & KStateSignificant ) == 0 && context > 0 )
+ {
+ if ( iMQDecoder.MqDecodeSymbol( iCurrentZcLutPtr[context] ) != 0 )
+ {
+ TUint32 ctxt = iSCLut[( state >> KScShift ) & KScLutMask];
+ TInt32 symbol = iMQDecoder.MqDecodeSymbol( ( ctxt & KScLutMask ) ) ^ ( ( ctxt >> KPredictionBit ) & 1 );
+ *aDataValue = ( symbol << KSignShift ) | aMask;
+ *aStateValue |= KStateSignificant | KStateVisited;
+ UpdateSignificance( aStateValue, symbol );
+ }
+ else
+ {
+ ( *aStateValue ) |= KStateVisited;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::DecodeRawSignificance
+// Decode the lazy significance bit
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::DecodeRawSignificance( TPrecInt*& aDataValue, TInt16*& aStateValue, TPrecInt aMask )
+ {
+ TInt32 state = *aStateValue;
+ if ( ( state & KStateSignificant ) == 0 && ( state & KZcMask ) > 0 )
+ {
+ if ( iMQDecoder.iInputStream.ReadBitFromStream() )
+ {
+ TInt32 symbol = iMQDecoder.iInputStream.ReadBitFromStream();
+ *aDataValue = ( symbol << KSignShift ) | aMask;
+ *aStateValue |= KStateSignificant | KStateVisited;
+ UpdateSignificance( aStateValue, symbol );
+ }
+ else
+ {
+ ( *aStateValue ) |= KStateVisited;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::DecodeRefinement
+// Decode the refinement bit
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::DecodeRefinement( TPrecInt*& aDataValue, TInt16*& aStateValue,
+ TPrecInt aMask, TInt32 aResetMask )
+ {
+ TInt32 state = *aStateValue;
+ if ( ( state & ( KStateSignificant | KStateVisited ) ) == KStateSignificant )
+ {
+ TInt16 mrContext = (TInt16)( state & KStatePreviousMR );
+ TInt32 ctxt = 0;
+ if ( mrContext )
+ {
+ ctxt = 2;
+ }
+ else
+ {
+ if ( ( state & KZcMask ) == 0 )
+ {
+ ctxt = 0;
+ }
+ else
+ {
+ ctxt = 1;
+ }
+ }
+ TInt32 symbol = iMQDecoder.MqDecodeSymbol( iMRLut[ctxt] );
+ ( *aDataValue ) &= aResetMask;
+ ( *aDataValue ) |= ( symbol << iCurrentBitplane ) | aMask;
+ ( *aStateValue ) |= KStatePreviousMR;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::DecodeRawRefinement
+// Decode the lazy refinement bit
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::DecodeRawRefinement( TPrecInt*& aDataValue, TInt16*& aStateValue,
+ TPrecInt aMask, TInt32 aResetMask )
+ {
+ if ( ( ( *aStateValue ) & ( KStateSignificant | KStateVisited ) ) == KStateSignificant )
+ {
+ TInt32 symbol = iMQDecoder.iInputStream.ReadBitFromStream();
+ ( *aDataValue ) &= aResetMask;
+ ( *aDataValue ) |= ( symbol << iCurrentBitplane ) | aMask;
+ ( *aStateValue ) |= KStatePreviousMR;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::DecodeNormalization
+// Perform the normalization
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::DecodeNormalization( TPrecInt*& aDataValue, TInt16*& aStateValue,
+ TPrecInt aMask, TInt32& aZCValue )
+ {
+ TUint32 state = *aStateValue;
+ if ( state < (TUint32)KStateVisited )
+ {
+ TInt32 symbol = 0;
+ TUint32 ctxt = 0;
+ if ( aZCValue == 1 )
+ {
+ ( *aStateValue ) &= ~KStateVisited;
+ if ( iMQDecoder.MqDecodeSymbol( iCurrentZcLutPtr[state & KZcMask] ) != 0 )
+ {
+ ctxt = iSCLut[( state >> KScShift ) & KScLutMask];
+ symbol = iMQDecoder.MqDecodeSymbol( ( ctxt & KScLutMask ) ) ^( ( ctxt >> KPredictionBit ) & 1 );
+ ( *aDataValue ) = ( symbol << KSignShift ) | aMask;
+ ( *aStateValue ) |= KStateSignificant;
+ UpdateSignificance( aStateValue, symbol );
+ aZCValue = 1;
+ }
+ }
+ else
+ {
+ ctxt = iSCLut[( state >> KScShift ) & KScLutMask];
+ symbol = iMQDecoder.MqDecodeSymbol( ( ctxt & KScLutMask ) ) ^ ( ( ctxt >> KPredictionBit ) & 1 );
+ ( *aDataValue ) = ( symbol << KSignShift ) | aMask;
+ ( *aStateValue ) |= KStateSignificant; \
+ UpdateSignificance( aStateValue, symbol );
+ aZCValue = 1;
+ }
+ }
+ else
+ {
+ ( *aStateValue ) &= ( ~KStateVisited );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::UpdateSignificance
+// Update the significance
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::UpdateSignificance( TInt16*& aStateValue, TInt32 aSymbol )
+ {
+ TInt16* u = ( aStateValue ) - ( iStateWidth );
+ TInt16* d = ( aStateValue ) + ( iStateWidth );
+ u[-1] |= KStateLowerRight;
+ u[1] |= KStateLowerLeft;
+ d[-1] |= KStateUpperRight;
+ d[1] |= KStateUpperLeft;
+
+ if ( aSymbol != 0 )
+ {
+ aStateValue[-1] |= KStateRight | KStateHorNegative;
+ aStateValue[1] |= KStateLeft | KStateHorNegative;
+ *d |= KStateUp | KStateVerNegative;
+ *u |= KStateDown | KStateVerNegative;
+ }
+ else
+ {
+ aStateValue[-1] |= KStateRight | KStateHorPositive;
+ aStateValue[1] |= KStateLeft | KStateHorPositive;
+ *d |= KStateUp | KStateVerPositive;
+ *u |= KStateDown | KStateVerPositive;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::SignificancePass
+// Perform the significance pass
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::SignificancePass()
+ {
+ // Mask for the current bitplane is actually also an approximation of the
+ // lower bitplanes, i.e. mask might be 00001100 for the fourth bitplane instead
+ // of 00001000, thus the data will be increased by the current bitplane and
+ // half of the sum of the lower bitplanes.
+ TPrecInt mask = ( 1 << iCurrentBitplane ) | ( 1 << ( iCurrentBitplane - 1 ) );
+
+ TPrecInt* dataRow = &( iData[0][0] );
+ TInt16* stateRow = CONST_CAST( TInt16*, GetFirstStateRow( ) );
+
+ TPrecInt* dataCol = 0;
+ TPrecInt* dataValue = 0;
+ TInt16* stateCol = 0;
+ TInt16* stateValue = 0;
+
+ // Column index in the stripe
+ TInt32 col = 0;
+ TInt32 row = 0;
+
+ // Code stripe by stripe
+ for ( TInt32 s = iNumStripes - 1; s > 0; s-- )
+ {
+ // If using stripe causal context formation, reset necessary bits
+ // in state of first line in next stripe ( not on last
+ // stripe ).
+ if ( iVerticalCausalContextUsed )
+ {
+ dataCol = dataRow + 2 * iBlockDataWidth;
+ stateCol = stateRow + iStateSamplesPerStripe - iStateWidth - 1;
+ GetCausal( dataCol, stateCol );
+ }
+
+ dataCol = dataRow;
+ stateCol = stateRow;
+
+ // Scan column by column in each stripe
+ for ( col = iBlockWidth; col > 0; col--, dataCol++, stateCol++ )
+ {
+ stateValue = stateCol;
+ dataValue = dataCol;
+
+ for ( row = KStripeHeight; row > 0; row-- )
+ {
+ DecodeSignificance( dataValue, stateValue, mask );
+ dataValue += iBlockDataWidth;
+ stateValue += iStateWidth;
+ }
+ }
+
+ dataRow += iDataSamplesPerStripe;
+ stateRow += iStateSamplesPerStripe;
+ }
+
+ // Deal with the last stripe separately
+ dataCol = dataRow;
+ stateCol = stateRow;
+
+ // Scan column by column in each stripe
+ for ( col = iBlockWidth; col > 0; col--, dataCol++, stateCol++ )
+ {
+ stateValue = stateCol;
+ dataValue = dataCol;
+
+ for ( row = iLastStripeHeight; row > 0; row-- )
+ {
+ DecodeSignificance( dataValue, stateValue, mask );
+ if ( row > 1 )
+ {
+ dataValue += iBlockDataWidth;
+ }
+ stateValue += iStateWidth;
+ }
+ }
+
+ // If there is predictable termination, check for errors
+ if ( iTerminateThisPass && iPredictableTerminationUsed )
+ {
+ iErrorState = iMQDecoder.MqCheckPrediction();
+ }
+
+ // Reset the MQ context states if we need to
+ if ( iResetContexts )
+ {
+ iMQDecoder.ResetMqContexts();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::LazySignificancePass
+// Perform the lazy significance pass
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::LazySignificancePass()
+ {
+ // Mask for the current bitplane
+ TPrecInt mask = ( 1 << iCurrentBitplane ) | ( 1 << ( iCurrentBitplane - 1 ) );
+
+ TPrecInt* dataRow = &( iData[0][0] );
+ TInt16* stateRow = CONST_CAST( TInt16*, GetFirstStateRow() );
+ TPrecInt* dataCol = 0;
+ TPrecInt* dataValue = 0;
+ TInt16* stateCol = 0;
+ TInt16* stateValue = 0;
+
+ // Column index in the stripe
+ TInt32 col = 0;
+ TInt32 row = 0;
+
+ for ( TInt32 s = iNumStripes - 1; s > 0; s-- )
+ {
+ // If using stripe causal context formation, reset necessary bits
+ // in state of first line in next stripe ( not on last
+ // stripe ).
+ if ( iVerticalCausalContextUsed )
+ {
+ dataCol = dataRow + 2 * iBlockDataWidth;
+ stateCol = stateRow + iStateSamplesPerStripe - iStateWidth - 1;
+ GetCausal( dataCol, stateCol );
+ }
+
+ // Scan column by column in each stripe
+ dataCol = dataRow;
+ stateCol = stateRow;
+
+ // Scan column by column in each stripe
+ for ( col = iBlockWidth; col > 0; col--, dataCol++, stateCol++ )
+ {
+ stateValue = stateCol;
+ dataValue = dataCol;
+
+ for ( row = KStripeHeight; row > 0; row-- )
+ {
+ DecodeRawSignificance( dataValue, stateValue, mask );
+ dataValue += iBlockDataWidth;
+ stateValue += iStateWidth;
+ }
+ }
+ dataRow += iDataSamplesPerStripe;
+ stateRow += iStateSamplesPerStripe;
+ }
+
+ // Deal with the last stripe separately
+ // Scan column by column in each stripe
+ dataCol = dataRow;
+ stateCol = stateRow;
+
+ // Line index
+ TInt32 l = 0;
+
+ // Scan column by column in each stripe
+ for ( col = iBlockWidth; col > 0; col--, dataCol++, stateCol++ )
+ {
+ stateValue = stateCol;
+ dataValue = dataCol;
+
+ l = iLastStripeHeight;
+ DecodeRawSignificance( dataValue, stateValue, mask );
+ if ( --l <= 0 )
+ {
+ continue; //lint !e960 Continue is OK, no need to go end of for.
+ }
+
+ dataValue += iBlockDataWidth;
+ stateValue += iStateWidth;
+ DecodeRawSignificance( dataValue, stateValue, mask );
+ if ( --l <= 0 )
+ {
+ continue; //lint !e960 Continue is OK, no need to go end of for.
+ }
+
+ dataValue += iBlockDataWidth;
+ stateValue += iStateWidth;
+ DecodeRawSignificance( dataValue, stateValue, mask );
+ if ( --l <= 0 )
+ {
+ continue; //lint !e960 Continue is OK, no need to go end of for.
+ }
+
+ dataValue += iBlockDataWidth;
+ stateValue += iStateWidth;
+ DecodeRawSignificance( dataValue, stateValue, mask );
+
+ }
+
+ // If there is predictable termination, check for errors
+ if ( iTerminateThisPass && iPredictableTerminationUsed )
+ {
+ iErrorState = iMQDecoder.iInputStream.CheckPrediction();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::RefinementPass
+// Perform the refinement pass
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::RefinementPass()
+ {
+ // To reset the effects of the approximation done in significance and
+ // normalization passes we have the resetmask.
+ TInt32 resetMask = ( -1 ) << ( iCurrentBitplane + 1 );
+ TUint32 mask = ( ( TUint32 )( 1 << iCurrentBitplane ) ) >> 1;
+
+ TPrecInt* dataRow = &( iData[0][0] );
+ TInt16* stateRow = CONST_CAST( TInt16*, GetFirstStateRow() );
+
+ TPrecInt* dataCol = 0;
+ TPrecInt* dataValue = 0;
+ TInt16* stateCol = 0;
+ TInt16* stateValue = 0;
+
+ // Column index in the stripe
+ TInt32 col = 0;
+ TInt32 row = 0;
+
+ // Code stripe by stripe
+ for ( TInt32 s = iNumStripes - 1; s > 0; s-- )
+ {
+ // If using stripe causal context formation, reset necessary bits
+ // in state of first line in next stripe ( not on last
+ // stripe ).
+ if ( iVerticalCausalContextUsed )
+ {
+ dataCol = dataRow + 2 * iBlockDataWidth;
+ stateCol = stateRow + iStateSamplesPerStripe - iStateWidth - 1;
+ GetCausal( dataCol, stateCol );
+ }
+
+ // Scan column by column in each stripe
+ dataCol = dataRow;
+ stateCol = stateRow;
+
+ // Scan column by column in each stripe
+ for ( col = iBlockWidth; col > 0; col--, dataCol++, stateCol++ )
+ {
+ dataValue = dataCol;
+ stateValue = stateCol;
+
+ for ( row = KStripeHeight; row > 0; row-- )
+ {
+ DecodeRefinement( dataValue, stateValue, mask, resetMask );
+ dataValue += iBlockDataWidth;
+ stateValue += iStateWidth;
+ }
+ }
+ dataRow += iDataSamplesPerStripe;
+ stateRow += iStateSamplesPerStripe;
+ }
+
+ // Deal with the last stripe separately
+ // Scan column by column in each stripe
+ dataCol = dataRow;
+ stateCol = stateRow;
+
+ // Scan column by column in the last stripe
+ for ( col = iBlockWidth; col > 0; col--, dataCol++, stateCol++ )
+ {
+ dataValue = dataCol;
+ stateValue = stateCol;
+
+ for ( row = iLastStripeHeight; row > 0; row-- )
+ {
+ DecodeRefinement( dataValue, stateValue, mask, resetMask );
+ if ( row > 1 )
+ {
+ dataValue += iBlockDataWidth;
+ }
+ stateValue += iStateWidth;
+ }
+ }
+
+ // If there is predictable termination, check for errors
+ if ( iTerminateThisPass && iPredictableTerminationUsed )
+ {
+ iErrorState = iMQDecoder.MqCheckPrediction();
+ }
+
+ // Reset the MQ context states if we need to
+ if ( iResetContexts )
+ {
+ iMQDecoder.ResetMqContexts();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::LazyRefinementPass
+// Perform the lazy refinement pass
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::LazyRefinementPass()
+ {
+ TInt32 resetMask = ( -1 ) << ( iCurrentBitplane + 1 );
+ TUint32 mask = ( ( TUint32 )( 1 << iCurrentBitplane ) ) >> 1;
+ TPrecInt* dataRow = &( iData[0][0] );
+ TInt16* stateRow = CONST_CAST( TInt16*, GetFirstStateRow() );
+ TPrecInt* dataCol = 0;
+ TPrecInt* dataValue = 0;
+ TInt16* stateCol = 0;
+ TInt16* stateValue = 0;
+
+ // Column index in the stripe
+ TInt32 col = 0;
+ TInt32 row = 0;
+
+ // Code stripe by stripe
+ for ( TInt32 s = iNumStripes - 1; s > 0; s-- )
+ {
+ // If using stripe causal context formation, reset necessary bits
+ // in state of first line in next stripe ( not on last
+ // stripe ).
+ if ( iVerticalCausalContextUsed )
+ {
+ dataCol = dataRow + 2 * iBlockDataWidth;
+ stateCol = stateRow + iStateSamplesPerStripe - iStateWidth - 1;
+ GetCausal( dataCol, stateCol );
+ }
+
+ // Scan column by column in each stripe
+ dataCol = dataRow;
+ stateCol = stateRow;
+
+ // Scan column by column in each stripe
+ for ( col = iBlockWidth; col > 0; col--, dataCol++, stateCol++ )
+ {
+ dataValue = dataCol;
+ stateValue = stateCol;
+ for ( row = KStripeHeight; row > 0; row-- )
+ {
+ DecodeRawRefinement( dataValue, stateValue, mask, resetMask );
+ dataValue += iBlockDataWidth;
+ stateValue += iStateWidth;
+ }
+ }
+ dataRow += iDataSamplesPerStripe;
+ stateRow += iStateSamplesPerStripe;
+ }
+
+ // Deal with the last stripe separately
+ // Scan column by column in each stripe
+ dataCol = dataRow;
+ stateCol = stateRow;
+
+ // Scan column by column in each stripe
+ for ( col = iBlockWidth; col > 0; col--, dataCol++, stateCol++ )
+ {
+ dataValue = dataCol;
+ stateValue = stateCol;
+
+ for ( row = iLastStripeHeight; row > 0; row-- )
+ {
+ DecodeRawRefinement( dataValue, stateValue, mask, resetMask );
+ dataValue += iBlockDataWidth;
+ stateValue += iStateWidth;
+ }
+ stateValue = stateCol;
+ dataValue = dataCol;
+ }
+
+ // If there is predictable termination, check for errors
+ if ( iTerminateThisPass && iPredictableTerminationUsed )
+ {
+ iErrorState = iMQDecoder.iInputStream.CheckPrediction();
+ }
+
+ // Because this is always terminated, reset stream
+ iMQDecoder.iInputStream.ResetInputStream();
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::CleanupPass
+// Perform the cleanup pass
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::CleanupPass( TUint8 aSegSymbols )
+ {
+ TInt32 zcCoding = 0;
+
+ // Symbol to be coded
+ TInt32 symbol = 0;
+
+ TPrecInt mask = ( 1 << iCurrentBitplane ) | ( 1 << ( iCurrentBitplane - 1 ) );
+
+ TPrecInt* dataRow = &( iData[0][0] );
+ TInt16* stateRow = CONST_CAST( TInt16*, GetFirstStateRow() );
+ TPrecInt* dataCol = 0;
+ TPrecInt* dataValue = 0;
+ TInt16* stateCol = 0;
+ TInt16* stateValue = 0;
+
+ // Column index in the stripe
+ TInt32 col = 0;
+ TInt32 row = 0;
+
+ // Code stripe by stripe
+ for ( TInt32 s = iNumStripes - 1; s > 0; s-- )
+ {
+ // If using stripe causal context formation, reset necessary bits
+ // in state of first line in next stripe
+ if ( iVerticalCausalContextUsed )
+ {
+ dataCol = dataRow + 2 * iBlockDataWidth;
+ stateCol = stateRow + iStateSamplesPerStripe - iStateWidth - 1;
+ GetCausal( dataCol, stateCol );
+ }
+
+ // Scan column by column in each stripe
+ dataCol = dataRow;
+ stateCol = stateRow;
+
+ for ( col = iBlockWidth; col > 0; col--, dataCol++, stateCol++ )
+ {
+ stateValue = stateCol;
+ dataValue = dataCol;
+
+ // If sample is insignificant and not yet visited in the
+ // current bitplane, then apply the normalization pass
+ if ( ( *stateValue == 0 ) &&
+ ( stateValue += iStateWidth, ( *stateValue ) == 0 ) && //lint !e960 Comma is OK.
+ ( stateValue += iStateWidth, ( *stateValue ) == 0 ) && //lint !e960 Comma is OK.
+ ( stateValue += iStateWidth, ( *stateValue ) == 0 ) ) //lint !e960 Comma is OK.
+ {
+ // Use RLC
+ if ( iMQDecoder.MqDecodeSymbol( KRlcContext ) != 0 ) //some sample( s ) not zero
+ {
+ // Decode the symbol most significant bit first
+ symbol = (TUint8)( iMQDecoder.MqDecodeSymbol( KUniformContext ) << 1 ); // MSB
+ symbol |= (TUint8)( iMQDecoder.MqDecodeSymbol( KUniformContext ) & 0x01 ); // LSB
+
+ // Update data and state pointers
+ stateValue = stateCol + symbol * iStateWidth;
+ dataValue = dataCol + symbol * iBlockDataWidth;
+
+ // Set zcCoding flag to zero
+ zcCoding = 0;
+ row = KStripeHeight - symbol;
+ }
+ else // All samples zero
+ {
+ // Move to next column
+ continue; //lint !e960 Continue is OK, no need to go end of for.
+ }
+ }
+ else // No RLC used
+ {
+ stateValue = stateCol;
+
+ // Set zcCoding flag to one
+ zcCoding = 1;
+ row = KStripeHeight;
+ }
+
+ for ( ; row > 0; row-- )
+ {
+ DecodeNormalization( dataValue, stateValue, mask, zcCoding );
+ dataValue += iBlockDataWidth;
+ stateValue += iStateWidth;
+ }
+ }
+ dataRow += iDataSamplesPerStripe;
+ stateRow += iStateSamplesPerStripe;
+ }
+
+ // Deal with last stripe separately
+ // Scan column by column in each stripe
+ dataCol = dataRow;
+ stateCol = stateRow;
+
+ // Scan column by column in each stripe
+ for ( col = iBlockWidth; col > 0; col--, stateCol++, dataCol++ )
+ {
+ stateValue = stateCol;
+ dataValue = dataCol;
+
+ // If sample is insignificant and not yet visited in the
+ // current bitplane, then apply the normalization pass
+ if( ( iLastStripeHeight == KStripeHeight ) && ( *stateValue ==0 ) &&
+ ( stateValue += iStateWidth, ( *stateValue ) == 0 ) && //lint !e960 Comma is OK.
+ ( stateValue += iStateWidth, ( *stateValue ) == 0 ) && //lint !e960 Comma is OK.
+ ( stateValue += iStateWidth, ( *stateValue ) == 0 ) ) //lint !e960 Comma is OK.
+ {
+ // Use RLC:
+ if ( iMQDecoder.MqDecodeSymbol( KRlcContext ) != 0 ) //some sample( s ) not zero
+ {
+ // Decode the symbol most significant bit first
+ symbol = ( TUint8 )( iMQDecoder.MqDecodeSymbol( KUniformContext ) << 1 ); // MSB
+ symbol |= ( TUint8 )( iMQDecoder.MqDecodeSymbol( KUniformContext ) & 0x01 ); // LSB
+
+ // Update data and state pointers
+ stateValue = stateCol + symbol * iStateWidth;
+ dataValue = dataCol + symbol * iBlockDataWidth;
+
+ // Set zcCoding flag to zero
+ zcCoding = 0;
+ row = KStripeHeight - symbol;
+ }
+ else // All samples zero
+ {
+ // Move to next column
+ continue; //lint !e960 Continue is OK, no need to go end of for.
+ }
+ }
+ else // No RLC used
+ {
+ row = iLastStripeHeight;
+ stateValue = stateCol;
+
+ // Set zcCoding flag to one
+ zcCoding = 1;
+ }
+
+ for ( ; row > 0; row-- )
+ {
+ DecodeNormalization( dataValue, stateValue, mask, zcCoding );
+ if ( row > 1 )
+ {
+ dataValue += iBlockDataWidth;
+ }
+ stateValue += iStateWidth;
+ }
+ }
+
+ // Decode a segment marker if we need to
+ if ( aSegSymbols )
+ {
+ symbol = (TUint8)( iMQDecoder.MqDecodeSymbol( KUniformContext ) << 3 );
+ symbol |= (TUint8)( iMQDecoder.MqDecodeSymbol( KUniformContext ) << 2 );
+ symbol |= (TUint8)( iMQDecoder.MqDecodeSymbol( KUniformContext ) << 1 );
+ symbol |= (TUint8)( iMQDecoder.MqDecodeSymbol( KUniformContext ) );
+
+ if ( symbol != KSegmentationMarker )
+ {
+ iErrorState = EEntropyCodingError;
+ }
+ }
+
+ // If there is predictable termination, check for errors
+ if ( iTerminateThisPass && iPredictableTerminationUsed )
+ {
+ iErrorState = iMQDecoder.MqCheckPrediction();
+ }
+
+ // Reset the MQ context states if we need to
+ if ( iResetContexts )
+ {
+ iMQDecoder.ResetMqContexts();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::GetFirstStateRow
+// Get the first state row
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+const TInt16* CJ2kEntropyDecoder::GetFirstStateRow() const
+ {
+ return iStates + ( iStateWidth + 1 );
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Src/JP2KFormat.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,123 @@
+/*
+* Copyright (c) 2003, 2004 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: Collection of structs used to store and represent
+* the metadata in the JP2 file format.
+*
+*/
+
+
+// INCLUDE FILES
+#include "JP2KFormat.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// Destructor
+TPalette::~TPalette()
+ {
+ iBList.Close();
+ TInt entries = iC2DArray.Count();
+ for (TInt index = 0; index < entries; ++index)
+ {
+ iC2DArray[index]->Close();
+ }
+ iC2DArray.ResetAndDestroy();
+ }
+
+// -----------------------------------------------------------------------------
+// TComponentMap::TComponentMap
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TComponentMap::TComponentMap( TUint16 aCmp, TUint8 aMtyp, TUint8 aPcol ) :
+ iCmp( aCmp ),
+ iMtyp( aMtyp ),
+ iPcol( aPcol )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// TChannelDefinition::TChannelDefinition
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TChannelDefinition::TChannelDefinition( TUint16 aCn, TUint16 aTyp, TUint16 aAsoc ):
+ iCn( aCn ),
+ iTyp( aTyp ),
+ iAsoc( aAsoc )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// TJ2kInfo::TJ2kInfo
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TJ2kInfo::TJ2kInfo() :
+ iImageSize( 1, 1 ),
+ iNC( 1 ),
+ iBPC( 8 ),
+ iOption( 0 ),
+ iCSBoxLength( 0 ),
+ iEnumCS( 0 ),
+ iCSOffset( 0 ),
+ iImageSizeInTwips( 0, 0 ),
+ iBPCList( 1 ),
+ iICCProfile( 0 ),
+ iCMPList( 1 ),
+ iCNList( 1 ),
+ iPalette(),
+ iIPRList( 1 ),
+ iXMLList( 1 ),
+ iUUIDList( 1 ),
+ iUUIDInfoListList( 1 ),
+ iUUIDInfoUrlList( 1 )
+ {
+ }
+
+// Destructor
+TJ2kInfo::~TJ2kInfo()
+ {
+ iBPCList.Close();
+
+ delete iICCProfile;
+ iICCProfile = 0;
+
+ iCMPList.Close();
+ iCNList.Close();
+
+ iIPRList.ResetAndDestroy();
+ iXMLList.ResetAndDestroy();
+ iUUIDList.ResetAndDestroy();
+ iUUIDInfoListList.ResetAndDestroy();
+ iUUIDInfoUrlList.ResetAndDestroy();
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Src/JP2KImageData.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,202 @@
+/*
+* Copyright (c) 2003-2006 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: Collection of classes derived from TImageDataBlock used
+* to store and represent the Image data.
+*
+*/
+
+
+// INCLUDE FILES
+#include <JP2KImageData.h>
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+const TUid KJP2KCommentUid = { KJ2KCommentUid };
+const TUid KJP2KIprBoxUid = { KJ2KIprBoxUid };
+const TUid KJP2KXmlBoxUid = { KJ2KXmlBoxUid };
+const TUid KJP2KUuidBoxUid = { KJ2KUuidBoxUid };
+const TUid KJP2KUuidInfoBoxUid = { KJ2KUuidInfoBoxUid };
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// TJp2kComment::TJp2kComment
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TJp2kComment::TJp2kComment() :
+ TImageDataBlock( KJP2KCommentUid ),
+ iComment( 0 )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// TJp2kComment::DuplicateL
+// To duplicate the image data.
+// -----------------------------------------------------------------------------
+//
+TImageDataBlock* TJp2kComment::DuplicateL( CFrameImageData& aFrameImageData ) const
+ {
+ TJp2kComment *jp2kComment = new ( ELeave ) TJp2kComment( *this );
+ CleanupDeletePushL( jp2kComment );
+
+ jp2kComment->iComment = jp2kComment->iComment->AllocLC();
+
+ User::LeaveIfError( aFrameImageData.AppendImageBuffer( jp2kComment->iComment ) );
+ CleanupStack::Pop( 2 ); // jp2kComment and jp2kComment->iComment
+
+ return jp2kComment;
+ }
+
+// -----------------------------------------------------------------------------
+// TJp2kIprBox::TJp2kIprBox
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TJp2kIprBox::TJp2kIprBox() :
+ TImageDataBlock( KJP2KIprBoxUid ),
+ iIprData( 0 )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// TJp2kIprBox::DuplicateL
+// To duplicate the image data.
+// -----------------------------------------------------------------------------
+//
+TImageDataBlock* TJp2kIprBox::DuplicateL( CFrameImageData& aFrameImageData ) const
+ {
+ TJp2kIprBox *jp2kIprBox = new ( ELeave ) TJp2kIprBox( *this );
+ CleanupDeletePushL( jp2kIprBox );
+
+ jp2kIprBox->iIprData = jp2kIprBox->iIprData->AllocLC();
+
+ User::LeaveIfError( aFrameImageData.AppendImageBuffer( jp2kIprBox->iIprData ) );
+ CleanupStack::Pop( 2 ); // jp2kIprBox and jp2kIprBox->iIprData
+
+ return jp2kIprBox;
+ }
+
+// -----------------------------------------------------------------------------
+// TJp2kXmlBox::TJp2kXmlBox
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TJp2kXmlBox::TJp2kXmlBox() :
+ TImageDataBlock( KJP2KXmlBoxUid ),
+ iXmlData( 0 )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// TJp2kComment::DuplicateL
+// To duplicate the image data.
+// -----------------------------------------------------------------------------
+//
+TImageDataBlock* TJp2kXmlBox::DuplicateL( CFrameImageData& aFrameImageData ) const
+ {
+ TJp2kXmlBox *jp2kXmlBox = new ( ELeave ) TJp2kXmlBox( *this );
+ CleanupDeletePushL( jp2kXmlBox );
+
+ jp2kXmlBox->iXmlData = jp2kXmlBox->iXmlData->AllocLC();
+
+ User::LeaveIfError( aFrameImageData.AppendImageBuffer( jp2kXmlBox->iXmlData ) );
+ CleanupStack::Pop( 2 ); // jp2kXmlBox and jp2kXmlBox->iXmlData
+
+ return jp2kXmlBox;
+ }
+
+// -----------------------------------------------------------------------------
+// TJp2kUuidBox::TJp2kUuidBox
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TJp2kUuidBox::TJp2kUuidBox() :
+ TImageDataBlock( KJP2KUuidBoxUid ),
+ iUuidId( KJ2KUuidIDSize ),
+ iUuidData( 0 )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// TJp2kComment::DuplicateL
+// To duplicate the image data.
+// -----------------------------------------------------------------------------
+//
+TImageDataBlock* TJp2kUuidBox::DuplicateL( CFrameImageData& aFrameImageData ) const
+ {
+ TJp2kUuidBox *jp2kUuidBox = new ( ELeave ) TJp2kUuidBox( *this );
+ CleanupDeletePushL( jp2kUuidBox );
+
+ jp2kUuidBox->iUuidData = jp2kUuidBox->iUuidData->AllocLC();
+
+ User::LeaveIfError( aFrameImageData.AppendImageBuffer( jp2kUuidBox->iUuidData ) );
+ CleanupStack::Pop( 2 ); // jp2kUuidBox and jp2kUuidBox->iUuidData
+
+ return jp2kUuidBox;
+ }
+
+// -----------------------------------------------------------------------------
+// TJp2kUuidInfoBox::TJp2kUuidInfoBox
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TJp2kUuidInfoBox::TJp2kUuidInfoBox() :
+ TImageDataBlock( KJP2KUuidInfoBoxUid ),
+ iUuidInfoNu( 0 ),
+ iUuidInfoId( 0 ),
+ iUuidInfoVersion( 0 ),
+ iUuidInfoFlag( 0 ),
+ iUuidInfoData( 0 )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// TJp2kComment::DuplicateL
+// To duplicate the image data.
+// -----------------------------------------------------------------------------
+//
+TImageDataBlock* TJp2kUuidInfoBox::DuplicateL( CFrameImageData& aFrameImageData ) const
+ {
+ TJp2kUuidInfoBox *jp2kUuidInfoBox = new ( ELeave ) TJp2kUuidInfoBox( *this );
+ CleanupDeletePushL( jp2kUuidInfoBox );
+
+ jp2kUuidInfoBox->iUuidInfoId = jp2kUuidInfoBox->iUuidInfoId->AllocLC();
+ User::LeaveIfError( aFrameImageData.AppendImageBuffer( jp2kUuidInfoBox->iUuidInfoId ) );
+ CleanupStack::Pop( 1 ); // jp2kUuidInfoBox->iUuidInfoId
+
+ jp2kUuidInfoBox->iUuidInfoData = jp2kUuidInfoBox->iUuidInfoData->AllocLC();
+ User::LeaveIfError( aFrameImageData.AppendImageBuffer( jp2kUuidInfoBox->iUuidInfoData ) );
+ CleanupStack::Pop( 2 ); // jp2kUuidInfoBox and jp2kUuidInfoBox->iUuidInfoData
+
+ return jp2kUuidInfoBox;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Src/JP2KImageInfo.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,848 @@
+/*
+* Copyright (c) 2003, 2004 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: CJ2kImageInfo class used to collect image related
+* information such as Main Header, SIZ marker and
+* list of tiles. It's also implement the
+* MJ2kPacketHeaderReader interface for reading the
+* packet header from PPM marker.
+*
+*/
+
+
+// INCLUDE FILES
+#include <icl/imagecodec.h>
+#include "JP2KImageUtils.h"
+#include "JP2KFormat.h"
+#include "JP2KStreamReader.h"
+#include "JP2KTileInfo.h"
+#include "JP2KImageInfo.h"
+#include "JP2KCodec.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::CJ2kImageInfo
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CJ2kImageInfo::CJ2kImageInfo() :
+ iLastTilePartProcessed( -1 )
+ {
+ }
+
+// Destructor
+CJ2kImageInfo::~CJ2kImageInfo()
+ {
+ delete iTile;
+ iTile= 0;
+
+ delete iPpm;
+ iPpm = 0;
+
+ // iPpmBuffer not owned.
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::AppendCOCL
+// Verify and append COC to the main header
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageInfo::AppendCOCL( TCOCMarker *aMarker )
+ {
+ for ( TUint16 index = 0; index < iMainMarker.iCoc.Count(); ++index )
+ {
+ if ( iMainMarker.iCoc[index]->iCcoc == aMarker->iCcoc )
+ {
+ // No more than one COC per component
+ delete aMarker;
+ aMarker = 0;
+
+ return;
+ }
+ }
+ User::LeaveIfError( iMainMarker.iCoc.Append( aMarker ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::AppendQCCL
+// Verify and append QCC to the main header
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageInfo::AppendQCCL( TQCCMarker *aMarker )
+ {
+ for ( TUint16 index = 0; index < iMainMarker.iQcc.Count(); ++index )
+ {
+ if ( iMainMarker.iQcc[index]->iCqcc == aMarker->iCqcc )
+ {
+ // No more than one QCC per component
+ delete aMarker;
+ aMarker = 0;
+
+ return;
+ }
+ }
+ User::LeaveIfError( iMainMarker.iQcc.Append( aMarker ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::AppendRGNL
+// Verify and append RGN to the main header
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageInfo::AppendRGNL( TRGNMarker *aMarker )
+ {
+ for ( TUint16 index = 0; index < iMainMarker.iRgn.Count(); ++index )
+ {
+ if ( iMainMarker.iRgn[index]->iCrgn == aMarker->iCrgn )
+ {
+ // no more than one RGN per component
+ delete aMarker;
+ aMarker = 0;
+
+ return;
+ }
+ }
+ User::LeaveIfError( iMainMarker.iRgn.Append( aMarker ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::AppendPOCL
+// Verify and append POC to the main header
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageInfo::AppendPOCL( TPOCMarker *aMarker )
+ {
+ if ( iMainMarker.iPoc == 0 )
+ {
+ iMainMarker.iPoc = aMarker;
+ }
+ else
+ {
+ // Appending the content of the POC to the
+ // existing main header POC
+ for ( TInt index = 0; index < aMarker->iPpoc.Count(); ++index )
+ {
+ User::LeaveIfError( iMainMarker.iPoc->iRSpoc.Append( aMarker->iRSpoc[index] ) );
+ User::LeaveIfError( iMainMarker.iPoc->iCSpoc.Append( aMarker->iCSpoc[index] ) );
+ User::LeaveIfError( iMainMarker.iPoc->iLYEpoc.Append( aMarker->iLYEpoc[index] ) );
+ User::LeaveIfError( iMainMarker.iPoc->iREpoc.Append( aMarker->iREpoc[index] ) );
+ User::LeaveIfError( iMainMarker.iPoc->iCEpoc.Append( aMarker->iCEpoc[index] ) );
+ User::LeaveIfError( iMainMarker.iPoc->iPpoc.Append( aMarker->iPpoc[index] ) );
+ }
+ // At most one POC may exist in main header
+ delete aMarker;
+ aMarker = 0;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::AppendCRGL
+// Verify and append CRG to the main header
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageInfo::AppendCRGL( TCRGMarker *aMarker )
+ {
+ if ( iMainMarker.iCrg == 0 )
+ {
+ iMainMarker.iCrg = aMarker;
+ }
+ else
+ {
+ // Appending the content of the CRG to the
+ // existing main header CRG
+ for ( TInt index = 0; index < aMarker->iXYcrg.Count(); ++index )
+ {
+ User::LeaveIfError( iMainMarker.iCrg->iXYcrg.Append( aMarker->iXYcrg[index] ) );
+ }
+ // At most one CRG may exist in main header
+ delete aMarker;
+ aMarker = 0;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::AppendCOML
+// Verify and append COM to the main header
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageInfo::AppendCOML( const TCOMMarker *aMarker )
+ {
+ User::LeaveIfError( iMainMarker.iCom.Append( aMarker ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::GetCodingStyle
+// Retrieve the right Coding Style Marker
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageInfo::GetCodingStyle( TCODMarker*& aCod, TCOCMarker*& aCoc,
+ const CJ2kTileInfo& aTile, TUint16 aComponentIndex )
+ {
+ // Tile part COC > tile part COD > main header COC > main header COD
+ aCod = 0;
+ aCoc = 0;
+ TUint16 index = 0;
+ TUint16 cocCount = 0;
+ const TTileMarker &tileMarker = aTile.TileMarker();
+
+ cocCount = (TUint16)tileMarker.iCoc.Count();
+ if ( cocCount )
+ {
+ for ( index = 0; index < cocCount; ++index )
+ {
+ if ( tileMarker.iCoc[index]->iCcoc == aComponentIndex )
+ {
+ aCoc = tileMarker.iCoc[index];
+ return;
+ }
+ }
+ }
+ if ( tileMarker.iCod )
+ {
+ aCod = tileMarker.iCod;
+ return;
+ }
+
+ cocCount = (TUint16)iMainMarker.iCoc.Count();
+ if ( cocCount )
+ {
+ for ( index = 0; index < cocCount; ++index )
+ {
+ if ( iMainMarker.iCoc[index]->iCcoc == aComponentIndex )
+ {
+ aCoc = iMainMarker.iCoc[index];
+ return;
+ }
+ }
+ }
+ aCod = &iMainMarker.iCod;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::GetQuantization
+// Retrieve the right Quantization Marker
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageInfo::GetQuantization( TQCDMarker*& aQcd, TQCCMarker*& aQcc,
+ const CJ2kTileInfo& aTile, TUint16 aComponentIndex )
+ {
+ // Tile part QCC > tile part QCD > main header QCC > main header QCD
+ aQcd = 0;
+ aQcc = 0;
+ TUint16 index = 0;
+ TUint16 qccCount = 0;
+ const TTileMarker &tileMarker = aTile.TileMarker();
+
+ qccCount = (TUint16)tileMarker.iQcc.Count();
+ if ( qccCount )
+ {
+ for ( index = 0; index < qccCount; ++index )
+ {
+ if ( tileMarker.iQcc[index]->iCqcc == aComponentIndex )
+ {
+ aQcc = tileMarker.iQcc[index];
+ return;
+ }
+ }
+ }
+ if ( tileMarker.iQcd )
+ {
+ aQcd = tileMarker.iQcd;
+ return;
+ }
+
+ qccCount = (TUint16)iMainMarker.iQcc.Count();
+ if ( qccCount )
+ {
+ for ( index = 0; index < qccCount; ++index )
+ {
+ if ( iMainMarker.iQcc[index]->iCqcc == aComponentIndex )
+ {
+ aQcc = iMainMarker.iQcc[index];
+ return;
+ }
+ }
+ }
+ aQcd = &iMainMarker.iQcd;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::GetRegion
+// Retrieve the right Region of Interest Marker
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageInfo::GetRegion( TRGNMarker*& aRgn, const CJ2kTileInfo& aTile, TUint16 aComponentIndex ) const
+ {
+ // Tile part RGN > main header RGN
+ aRgn = 0;
+ TUint16 index = 0;
+ TUint16 rgnCount = 0;
+ const TTileMarker &tileMarker = aTile.TileMarker();
+
+ rgnCount = (TUint16)tileMarker.iRgn.Count();
+ if ( rgnCount )
+ {
+ for ( index = 0; index < rgnCount; ++index )
+ {
+ if ( tileMarker.iRgn[index]->iCrgn == aComponentIndex )
+ {
+ aRgn = tileMarker.iRgn[index];
+ return;
+ }
+ }
+ }
+
+ rgnCount = (TUint16)iMainMarker.iRgn.Count();
+ if ( rgnCount )
+ {
+ for ( index = 0; index < rgnCount; ++index )
+ {
+ if ( iMainMarker.iRgn[index]->iCrgn == aComponentIndex )
+ {
+ aRgn = iMainMarker.iRgn[index];
+ return;
+ }
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::GetFromTLM
+// Retrieve the tile length field from TLM marker
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageInfo::GetFromTLM( TSotMarker& aSotMarker ) const
+ {
+ TTLMMarker* tlm = 0;
+ TUint16 tileIndex = 0;
+ TUint16 dIndex = 0;
+
+ for ( TInt index = 0; index < iMainMarker.iTlm.Count(); ++index )
+ {
+ tlm = iMainMarker.iTlm[index];
+ dIndex = 0;
+ if ( tlm->iTtlm.Count() == 0 )
+ {
+ // One tile-part per tile and the tiles are
+ // in index order without omission or repetition
+ while ( dIndex < tlm->iPtlm.Count() )
+ {
+ if ( dIndex == aSotMarker.iIsot )
+ {
+ aSotMarker.iPsot = tlm->iPtlm[dIndex];
+ return;
+ }
+ ++dIndex;
+ }
+ }
+ else
+ {
+ while ( dIndex < tlm->iTtlm.Count() )
+ {
+ // Looking for the right tile
+ if ( tlm->iTtlm[dIndex] == aSotMarker.iIsot )
+ {
+ // Looking for the right tile-part
+ if ( tileIndex == aSotMarker.iTPsot )
+ {
+ aSotMarker.iPsot = tlm->iPtlm[dIndex];
+ return;
+ }
+ ++tileIndex;
+ }
+ ++dIndex;
+ }
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::UsePPM
+// Set up to read the packet header from the PPM marker
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageInfo::UsePPM( CJ2kTileInfo& aTile )
+ {
+ if ( iPpm->iPtr == iPpm->iPtrEnd )
+ {
+ iPpm->iPtr = 4;
+ iPpm->iPtrEnd = iPpm->iPtr + iMainMarker.iPpm[iLastTilePartProcessed]->iNppm;
+ iPpmBuffer = iMainMarker.iPpm[iLastTilePartProcessed]->iIppm;
+ }
+ aTile.SetPacketHeaderReader( this );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::DoCompactMainHeaderL
+// Re-arrange the PPM and PLM buffers
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageInfo::DoCompactMainHeaderL()
+ {
+ RPointerArray<TPLMMarker>& plmList = iMainMarker.iPlm;
+ if ( plmList.Count() )
+ {
+ TPLMMarker *plmMarker = 0;
+ TPLMMarker *prevMarker = 0;
+ TUint8 checkNplm = ETrue;
+ TUint8 continuation = EFalse;
+ TUint8 length = 0;
+ const TUint8 *ptr = 0;
+ TUint32 remainder = 0;
+ TInt index = 0;
+
+ for ( index = 0; index < plmList.Count(); ++index )
+ {
+ plmMarker = plmList[index];
+ if ( checkNplm )
+ {
+ ptr = plmMarker->iIplm->Ptr();
+ length = *ptr;
+ if ( length != ( TUint8 )( plmMarker->iNplm - 1 ) )
+ {
+ // Incomplete PLM marker
+ // there is a continuation of data in the next PLM marker
+ // and concatenation is needed
+ plmMarker->iIplm = plmMarker->iIplm->ReAllocL( length + 1 );
+ remainder = (TUint32)( length - ( plmMarker->iNplm - 1 ) );
+ plmMarker->iNplm = length;
+ prevMarker = plmMarker;
+ checkNplm = EFalse;
+ }
+ else
+ {
+ // It is a complete PLM marker
+ plmMarker->iNplm = length;
+ }
+ }
+ else
+ {
+ // Concatenate with the previous PLM marker
+ continuation = ETrue;
+ TPtr8 previous = prevMarker->iIplm->Des();
+ previous.Append( plmMarker->iIplm->Ptr(), plmMarker->iNplm );
+ remainder = (TUint32)( remainder - plmMarker->iNplm );
+ plmMarker->iNplm = 0;
+ if ( remainder == 0 )
+ {
+ checkNplm = ETrue;
+ }
+ }
+ }
+ if ( continuation )
+ {
+ index = 0;
+ while ( index < plmList.Count() )
+ {
+ plmMarker = plmList[index];
+ if ( plmMarker->iNplm )
+ {
+ ++index;
+ }
+ else
+ {
+ // Remove PPM marker which has been concatenated
+ plmList.Remove( index );
+ delete plmMarker;
+ }
+ }
+ }
+ // Do not use PLM segment.
+ plmList.ResetAndDestroy();
+ }
+
+ RPointerArray<TPPMMarker>& ppmList = iMainMarker.iPpm;
+ if ( ppmList.Count() > 0 )
+ {
+ iPpm = new ( ELeave ) TPPMStream;
+ Mem::FillZ( iPpm, sizeof( TPPMStream ) );
+
+ TPPMMarker *ppmMarker = 0;
+ TPPMMarker *prevMarker = 0;
+ TUint8 checkNppm = ETrue;
+ TUint8 continuation = EFalse;
+ const TUint8 *ptr = 0;
+ TUint32 length = 0;
+ TUint32 remainder = 0;
+ TInt index = 0;
+ TUint8 zppm = 0;
+
+ for ( index = 0; index < ppmList.Count(); ++index )
+ {
+ ppmMarker = ppmList[index];
+ if ( checkNppm )
+ {
+ ptr = ppmMarker->iIppm->Ptr();
+ length = PtrReadUtil::ReadBigEndianUint32( ptr );
+ if ( length != (TUint32)( ppmMarker->iNppm - 4 ) )
+ {
+ if ( length > (TUint32)( ppmMarker->iNppm - 4 ) )
+ {
+ // Incomplete PPM marker
+ // there is a continuation of data in the next PPM marker
+ // and concatenation is needed
+ ppmMarker->iZppm = zppm++;
+ ppmMarker->iIppm = ppmMarker->iIppm->ReAllocL( length + 4 );
+ remainder = (TUint32)( length - ( ppmMarker->iNppm - 4 ) );
+ ppmMarker->iNppm = length;
+ prevMarker = ppmMarker;
+ checkNppm = EFalse;
+ }
+ else
+ {
+ // We should split the PPM marker into smaller PPM marker
+ TInt location = 0;
+ ppmList.Remove( index );
+ remainder = ppmMarker->iNppm;
+ while ( remainder >= ( length + 4 ) )
+ {
+ prevMarker = new ( ELeave ) TPPMMarker;
+ CleanupStack::PushL( prevMarker );
+
+ prevMarker->iZppm = ( location ? (TUint8)0 : zppm++ );
+ prevMarker->iNppm = length + ( location ? 4 : 0 );
+ prevMarker->iIppm = HBufC8::NewL( length + 4 );
+ prevMarker->iIppm->Des().Append( ptr, length + 4 );
+ User::LeaveIfError( ppmList.Insert( prevMarker, index + location ) );
+ CleanupStack::Pop();
+ ++location;
+ ptr += ( length + 4 );
+ remainder -= ( length + 4 );
+ if ( remainder > 4 )
+ {
+ length = PtrReadUtil::ReadBigEndianUint32( ptr );
+ }
+ else
+ {
+ length = 0;
+ }
+ }
+ if ( remainder )
+ {
+ // Incomplete PPM marker
+ prevMarker = new ( ELeave ) TPPMMarker;
+ CleanupStack::PushL( prevMarker );
+
+ prevMarker->iNppm = remainder;
+ prevMarker->iIppm = HBufC8::NewL( remainder );
+ prevMarker->iIppm->Des().Append( ptr, remainder );
+ User::LeaveIfError( ppmList.Insert( prevMarker, index + location ) );
+ CleanupStack::Pop();
+ }
+ delete ppmMarker;
+ ppmMarker = 0;
+ }
+ }
+ else
+ {
+ // It is a complete PPM marker, adjust the Nppm to length
+ ppmMarker->iZppm = zppm++;
+ ppmMarker->iNppm = length;
+ }
+ }
+ else
+ {
+ continuation = ETrue;
+ if ( ppmMarker->iNppm <= remainder )
+ {
+ // Concatenate with the previous PPM marker
+ TPtr8 previous = prevMarker->iIppm->Des();
+ previous.Append( ppmMarker->iIppm->Ptr(), ppmMarker->iNppm );
+ remainder = ( TUint32 )( remainder - ppmMarker->iNppm );
+ ppmMarker->iNppm = 0;
+ if ( remainder == 0 )
+ {
+ checkNppm = ETrue;
+ }
+ }
+ else
+ {
+ checkNppm = ETrue;
+ // Partially concatenate with the previous PPM marker
+ TPtr8 previous = prevMarker->iIppm->Des();
+ previous.Append( ppmMarker->iIppm->Ptr(), remainder );
+
+ // We should split the PPM marker into smaller PPM marker
+ TInt location = 0;
+ ppmList.Remove( index );
+ ptr = ppmMarker->iIppm->Ptr() + remainder;
+ length = PtrReadUtil::ReadBigEndianUint32( ptr );
+ remainder = ( TUint32 )( ppmMarker->iNppm - remainder );
+ while ( remainder >= ( length + 4 ) )
+ {
+ prevMarker = new ( ELeave ) TPPMMarker;
+ CleanupStack::PushL( prevMarker );
+
+ prevMarker->iZppm = ( location ? (TUint8)0 : zppm++ );
+ prevMarker->iNppm = length + ( location ? 4 : 0 );
+ prevMarker->iIppm = HBufC8::NewL( length + 4 );
+ prevMarker->iIppm->Des().Append( ptr, length + 4 );
+ User::LeaveIfError( ppmList.Insert( prevMarker, index + location ) );
+ CleanupStack::Pop();
+ ++location;
+ ptr += ( length + 4 );
+ remainder -= ( length + 4 );
+ if ( remainder > 4 )
+ {
+ length = PtrReadUtil::ReadBigEndianUint32( ptr );
+ }
+ else
+ {
+ length = 0;
+ }
+ }
+ if ( remainder )
+ {
+ // Incomplete PPM marker
+ prevMarker = new ( ELeave ) TPPMMarker;
+ CleanupStack::PushL( prevMarker );
+
+ prevMarker->iNppm = remainder;
+ prevMarker->iIppm = HBufC8::NewL( remainder );
+ prevMarker->iIppm->Des().Append( ptr, remainder );
+ User::LeaveIfError( ppmList.Insert( prevMarker, index + location ) );
+ CleanupStack::Pop();
+ }
+ delete ppmMarker;
+ ppmMarker = 0;
+ }
+ }
+ }
+ if ( continuation )
+ {
+ index = 0;
+ while ( index < ppmList.Count() )
+ {
+ ppmMarker = ppmList[index];
+ if ( ppmMarker->iNppm )
+ {
+ ++index;
+ }
+ else
+ {
+ // Remove PPM marker which has been concatenated
+ ppmList.Remove( index );
+ delete ppmMarker;
+ ppmMarker = 0;
+ }
+ }
+ }
+ }
+
+ // Do not use the COM segment at this release
+ if ( iMainMarker.iCom.Count() )
+ {
+ iMainMarker.iCom.ResetAndDestroy();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::IsPPM
+// Is packet header should be read from PPM marker
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kImageInfo::IsPPM() const
+ {
+ if ( iPpm )
+ {
+ if ( iPpm->iPtr < iPpm->iPtrEnd )
+ {
+ return ETrue;
+ }
+ else if ( iLastTilePartProcessed < iMainMarker.iPpm.Count() )
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::ReadEPHMarker
+// Try to consume the EPH marker if there is one.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kImageInfo::ReadEPHMarker()
+ {
+ if ( iPpm && ( iPpm->iPtrEnd - iPpm->iPtr ) >= 2 )
+ {
+ const TUint8 *ptr = iPpmBuffer->Ptr();
+ ptr += iPpm->iPtr;
+ if ( PtrReadUtil::ReadBigEndianUint16( ptr ) == KEPH )
+ {
+ iPpm->iPtr += 2;
+ }
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::ReadBit
+// Read a bit from the packet header stream.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kImageInfo::ReadBit( TUint8& aBit )
+ {
+ if ( iPpm->iPos == 0 )
+ {
+ if ( iPpm->iPtr < iPpm->iPtrEnd )
+ {
+ // Stream contains some packet header data
+ iPpm->iData = ( *iPpmBuffer )[iPpm->iPtr++];
+ iPpm->iPos = iPpm->iNextPos;
+ if ( iPpm->iNextPos == 0x08 && iPpm->iData == 0xff )
+ {
+ iPpm->iNextPos = 0x07;
+ }
+ else
+ {
+ iPpm->iNextPos = 0x08;
+ }
+ }
+ else
+ {
+ // No more data
+ return ETrue;
+ }
+ }
+ aBit = (TUint8)( ( iPpm->iData >> ( --iPpm->iPos ) ) & 0x01 );
+
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::ReadBits
+// Read some bits from the packet header stream.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kImageInfo::ReadBits( TUint8& aBit, TUint8 aBitLen )
+ {
+ aBit = (TUint8)0;
+ TUint8 bit;
+ for ( TInt8 index = (TInt8)( aBitLen - 1 ); index >= 0; --index )
+ {
+ if ( !ReadBit( bit ) )
+ {
+ aBit |= ( bit << index );
+ }
+ else
+ {
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::ReadBits
+// Read some bits from the packet header stream.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kImageInfo::ReadBits( TUint32& aBit, TUint8 aBitLen )
+ {
+ aBit = (TUint32)0;
+ TUint8 bit = 0;
+ for ( TInt8 index = (TInt8)( aBitLen - 1 ); index >= 0; --index )
+ {
+ if ( !ReadBit( bit ) )
+ {
+ aBit |= ( bit << index );
+ }
+ else
+ {
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::StartReadBit
+// Start reading from packet header stream.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kImageInfo::StartReadBit()
+ {
+ if ( iPpm && iPpm->iPtr < iPpm->iPtrEnd )
+ {
+ // Stream contains some packet header data
+ iPpm->iData = ( *iPpmBuffer )[iPpm->iPtr++];
+ iPpm->iPos = iPpm->iNextPos = 0x08;
+ if ( iPpm->iData == 0xff )
+ {
+ iPpm->iNextPos = 0x07;
+ }
+
+ return EFalse;
+ }
+ return ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageInfo::AlignReader
+// Align the stream to the next byte boundary if necessary.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageInfo::AlignReader()
+ {
+ if ( iPpm->iNextPos == 0x07 )
+ {
+ if ( iPpm->iPtr < iPpm->iPtrEnd )
+ {
+ ++iPpm->iPtr;
+ }
+ }
+ iPpm->iData = iPpm->iPos = iPpm->iNextPos = 0;
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Src/JP2KImageWriter.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,2187 @@
+/*
+* Copyright (c) 2003, 2004 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: CJ2kImageWriter class used to perform inverse transformation and
+* writing decoded image data to bitmap.
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32math.h>
+#include <fbs.h>
+#include "JP2KImageUtils.h"
+#include "JP2KFormat.h"
+#include "JP2KTileInfo.h"
+#include "JP2KImageInfo.h"
+#include "JP2KSubband.h"
+#include "JP2KComponentInfo.h"
+#include "JP2KImageWriter.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// MACROS
+#define INT2BYTE( n ) ( ( n ) < 0 ? (TUint8)0 : ( ( n ) > 255 ? (TUint8)255 : (TUint8)( n ) ) )
+#define CLIPINT( n,bitdepth ) ( ( n >= ( 1 << bitdepth ) ) ? ( ( 1<<bitdepth ) - 1 ) : ( n < 0 ) ? 0 : n )
+#define CLIP2BITDEPTH( n, maxValue ) ( ( n > maxValue ) ? ( maxValue ) : ( n < 0 ) ? 0 : n )
+#define CLIP2RANGE( n, minValue, maxValue ) ( ( n > maxValue ) ? ( maxValue ) : ( n < minValue ) ? minValue : n )
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// LOCAL CONSTANTS AND MACROS
+
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// Destructor
+CJ2kWriterComponentInfo::~CJ2kWriterComponentInfo()
+ {
+ iTileStartList.Close();
+ FreeData();
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kWriterComponentInfo::AllocDataL
+// Allocate 2-D data array with a size
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kWriterComponentInfo::AllocDataL( const TSize& aSize )
+ {
+ FreeData();
+ iData = TJ2kUtils::Alloc2DArrayL( aSize.iHeight, aSize.iWidth );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kWriterComponentInfo::FreeData
+// Free the 2-D data array
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kWriterComponentInfo::FreeData()
+ {
+ if ( iData )
+ {
+ TJ2kUtils::Free2DArray( iData );
+ iData = 0;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kWriterComponentInfo::Data
+// Get the 2-D data array
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TPrecInt** CJ2kWriterComponentInfo::Data()
+ {
+ return iData;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kWriterComponentInfo::TileStartAt
+// Get the starting point of a tile
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TPoint& CJ2kWriterComponentInfo::TileStartAt( TUint16 aTileIndex )
+ {
+ return iTileStartList[aTileIndex];
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kWriterComponentInfo::UpdateNextTileStartAt
+// Update the starting point of next tile
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kWriterComponentInfo::UpdateNextTileStartAt( TUint16 aTileIndex,
+ const TSize& aSize,
+ CJ2kImageInfo& aImageInfo )
+ {
+ TUint16 numOfHorizTiles = aImageInfo.NumOfHorizTiles();
+ TUint16 numOfVertTiles = aImageInfo.NumOfVertTiles();
+
+ // Calculate the p and q of a tile
+ TDiv tDiv = TJ2kUtils::Div( aTileIndex, numOfHorizTiles );
+ if ( tDiv.rem != ( numOfHorizTiles - 1 ) )
+ {
+ iTileStartList[aTileIndex + 1].iX = iTileStartList[aTileIndex].iX + aSize.iWidth;
+ }
+
+ if ( tDiv.quot != ( numOfVertTiles - 1 ) )
+ {
+ iTileStartList[aTileIndex + numOfHorizTiles].iY = iTileStartList[aTileIndex].iY + aSize.iHeight;
+ }
+ }
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CJ2kImageWriter* CJ2kImageWriter::NewL( CImageProcessor* aImageProcessor,
+ CJ2kImageInfo& aImageInfo,
+ TJ2kInfo& aJ2kInfo )
+ {
+ CJ2kImageWriter *self = new ( ELeave ) CJ2kImageWriter( aImageProcessor, aImageInfo, aJ2kInfo );
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+
+ return self;
+ }
+
+// Destructor
+CJ2kImageWriter::~CJ2kImageWriter()
+ {
+ iComponents.ResetAndDestroy();
+
+ delete iLinearsRGBLut;
+ iLinearsRGBLut = 0;
+
+ User::Free( iGrayTRCLut );
+ User::Free( iRedTRCLut );
+ User::Free( iGreenTRCLut );
+ User::Free( iBlueTRCLut );
+ User::Free( iMonoPixelBlock );
+ User::Free( iColorPixelBlock );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::WriterComponentAt
+// Get the component of the image writer
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+const CJ2kWriterComponentInfo& CJ2kImageWriter::WriterComponentAt( TUint16 aIndex ) const
+ {
+ return *iComponents[aIndex];
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::OutputImageL
+// Output the image related to the component of the tile
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageWriter::OutputImageL( CJ2kTileInfo& aTile, TUint16 aComponentIndex )
+ {
+ TUint8 bitdepth = 0;
+ TUint16 c = 0;
+ CJ2kComponentInfo& componentInfo = CONST_CAST( CJ2kComponentInfo&, aTile.ComponentAt( aComponentIndex ) );
+
+ TInt16 reducedLevels = (TInt16)( componentInfo.Levels() - iImageInfo.LevelDrop() );
+ if ( reducedLevels < 0 )
+ {
+ reducedLevels = 0;
+ }
+
+ CJ2kSubband* subband = CONST_CAST( CJ2kSubband*, componentInfo.SubbandAt( (TUint8)reducedLevels ) );
+
+ if ( subband->SubbandResLevel() != 0 )
+ {
+ subband = subband->Parent();
+ }
+
+ TSize subbandSize = subband->SubbandCanvasSize();
+
+ // Note that in case of component truncation color transform is not performed
+ if ( iImageInfo.ComponentDrop() )
+ {
+ iNumComponents = 1;
+ }
+ else // Only perform color transform if we don't drop components
+ {
+ // Perform the color transfrom
+ if ( aComponentIndex == 2 && aTile.ColorTransformation() )
+ {
+ // Perform the inverse color transform
+ if ( aTile.ComponentAt( 0 ).IsReversible() ) // If RCT is used
+ {
+ PerformInverseRCT( subbandSize );
+ }
+ else
+ {
+ PerformInverseICT( subbandSize );
+ }
+ }
+ }
+
+ // Check if palettes are used. If so, get the number of output channels
+ if ( iJ2kInfo.iCMPList.Count() )
+ {
+ TUint16 numCSComp = iImageInfo.NumOfComponents();
+
+ // Allocate more memory for data if needed
+ if ( iNumComponents > numCSComp )
+ {
+ for ( c = numCSComp; c < iNumComponents; c++ )
+ {
+ // Allocate memory for component data
+ iComponents[c]->AllocDataL( subbandSize );
+ }
+ }
+ // Check if we have all the necessary channels for component mapping
+ if ( aComponentIndex == ( numCSComp - 1 ) )
+ {
+ MapComponentsL( numCSComp, reducedLevels, subbandSize, aTile );
+ }
+ }
+
+ // We start the output of files:
+ if ( iSingleFileOutput )
+ {
+ if ( iNumComponents == 3 ) // 3 comp to combine
+ {
+ // Compute the subbandSize from the first component since others might be downsampled.
+ TInt16 tempNumLevels = (TUint16)( aTile.ComponentAt( 0 ).Levels() - iImageInfo.LevelDrop() );
+
+ if ( tempNumLevels < 0 )
+ {
+ tempNumLevels = 0;
+ }
+
+ CJ2kSubband* tempSubband = CONST_CAST( CJ2kSubband*, aTile.ComponentAt( 0 ).SubbandAt( (TUint8)tempNumLevels ) );
+
+ if ( tempSubband->SubbandResLevel() != 0 )
+ {
+ tempSubband = tempSubband->Parent();
+ }
+
+ subbandSize = tempSubband->SubbandCanvasSize();
+
+ if( !iColorPixelBlock )
+ {
+ // Allocate memory for block of color pixels
+ iColorPixelBlock = STATIC_CAST( TRgb*, User::AllocL( 2 * KPixelsBlock * sizeof( TRgb ) ) );
+ }
+
+ CombineOutputFile( aTile, subbandSize );
+ for ( c = 0; c < iNumComponents; c++ )
+ {
+ iComponents[c]->FreeData();
+ }
+ }
+ else // 1 comp to output
+ {
+ if ( iImageInfo.ComponentDrop() )
+ {
+ c = ( TUint16 )( iImageInfo.ComponentDrop() - 1 );
+ }
+ else
+ {
+ c = aComponentIndex;
+ }
+
+ bitdepth = iImageInfo.DepthOfComponent( c );
+
+ if( !iMonoPixelBlock )
+ {
+ // Allocate memory for block of grayscale pixels
+ iMonoPixelBlock = STATIC_CAST( TUint32*, User::AllocL( KPixelsBlock * sizeof( TUint32 ) ) );
+ }
+
+ // Output a single component
+ WriteOutputFile( aTile, c, subbandSize, bitdepth );
+ iComponents[c]->FreeData();
+ }
+ }
+ else
+ {
+ // Write out three independent output files
+ if( !iMonoPixelBlock )
+ {
+ // Allocate memory for block of grayscale pixels
+ iMonoPixelBlock = STATIC_CAST( TUint32*, User::AllocL( KPixelsBlock * sizeof( TUint32 ) ) );
+ }
+
+ if ( aComponentIndex == 2 && aTile.ColorTransformation() )
+ {
+ for ( c = 0; c < 3; c++ )
+ {
+ bitdepth = iImageInfo.DepthOfComponent( c );
+
+ // Output single files
+ WriteOutputFile( aTile, c, subbandSize, bitdepth );
+ iComponents[c]->FreeData();
+ }
+ }
+ else if ( iJ2kInfo.iCMPList.Count() )
+ {
+ for ( c = 0; c < iNumComponents; c++ )
+ {
+ // Bitdepth is the lowest seven bits plus one for palettes
+ bitdepth = ( TUint8 )( ( iJ2kInfo.iPalette.iBList[0] & 0x7f )+1 );
+
+ // Output single files
+ WriteOutputFile( aTile, c, subbandSize, bitdepth );
+ iComponents[c]->FreeData();
+ }
+ }
+ else
+ {
+ bitdepth = iImageInfo.DepthOfComponent( aComponentIndex );
+
+ // Output only the first component to screen
+ if( aComponentIndex == 0 )
+ {
+ WriteOutputFile( aTile, aComponentIndex, subbandSize, bitdepth );
+ }
+ iComponents[aComponentIndex]->FreeData();
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::OutputImageL
+// Output the image related to the component of the tile
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageWriter::OutputImageL( CJ2kTileInfo& aTile, TUint16 aComponentIndex,
+ const TSize& aSize )
+ {
+ TUint8 bitdepth = 0;
+ TUint16 c = 0;
+ CJ2kComponentInfo& componentInfo = CONST_CAST( CJ2kComponentInfo&, aTile.ComponentAt( aComponentIndex ) );
+
+ TInt16 reducedLevels = (TInt16)( componentInfo.Levels() - iImageInfo.LevelDrop() );
+ if ( reducedLevels < 0 )
+ {
+ reducedLevels = 0;
+ }
+
+ CJ2kSubband* subband = CONST_CAST( CJ2kSubband*, componentInfo.SubbandAt( (TUint8)reducedLevels ) );
+ if ( subband->SubbandResLevel() != 0 )
+ {
+ subband = subband->Parent();
+ }
+
+ TSize subbandSize = aSize;
+
+ // Note that in case of component truncation color transform is not performed
+ if ( iImageInfo.ComponentDrop() )
+ {
+ iNumComponents = 1;
+ }
+ else // Only perform color transform if we don't drop components
+ {
+ // Perform the color transfrom
+ if ( aComponentIndex == 2 && aTile.ColorTransformation() )
+ {
+ // Perform the inverse color transform
+ if ( aTile.ComponentAt( 0 ).IsReversible() ) // If RCT is used
+ {
+ PerformInverseRCT( subbandSize );
+ }
+ else
+ {
+ PerformInverseICT( subbandSize );
+ }
+ }
+ }
+
+ // Check if palettes are used. If so, get the number of output channels
+ if ( iJ2kInfo.iCMPList.Count() )
+ {
+ TUint16 numCSComp = iImageInfo.NumOfComponents();
+
+ // Allocate more memory for data if needed
+ if ( iNumComponents > numCSComp )
+ {
+ for ( c = numCSComp; c < iNumComponents; c++ )
+ {
+ // Allocate memory for component data
+ iComponents[c]->AllocDataL( subbandSize );
+ }
+ }
+ // Check if we have all the necessary channels for component mapping
+ if ( aComponentIndex == ( numCSComp - 1 ) )
+ {
+ MapComponentsL( numCSComp, reducedLevels, subbandSize, aTile );
+ }
+ }
+
+ // We start the output of files:
+ if ( iSingleFileOutput )
+ {
+ if ( iNumComponents == 3 ) // 3 comp to combine
+ {
+ if( !iColorPixelBlock )
+ {
+ // Allocate memory for block of color pixels
+ iColorPixelBlock = STATIC_CAST( TRgb*, User::AllocL( 2 * KPixelsBlock * sizeof( TRgb ) ) );
+ }
+
+ CombineOutputFile( aTile, subbandSize );
+ for ( c = 0; c < iNumComponents; c++ )
+ {
+ iComponents[c]->FreeData();
+ }
+ }
+ else // 1 comp to output
+ {
+ if ( iImageInfo.ComponentDrop() )
+ {
+ c = (TUint16)( iImageInfo.ComponentDrop() - 1 );
+ }
+ else
+ {
+ c = aComponentIndex;
+ }
+
+ bitdepth = iImageInfo.DepthOfComponent( c );
+
+ if( !iMonoPixelBlock )
+ {
+ // Allocate memory for block of grayscale pixels
+ iMonoPixelBlock = STATIC_CAST( TUint32*, User::AllocL( KPixelsBlock * sizeof( TUint32 ) ) );
+ }
+
+ // Output a single component
+ WriteOutputFile( aTile, c, subbandSize, bitdepth );
+ iComponents[c]->FreeData();
+ }
+ }
+ else
+ {
+ // Write out three independent output files
+ if( !iMonoPixelBlock )
+ {
+ // Allocate memory for block of grayscale pixels
+ iMonoPixelBlock = STATIC_CAST( TUint32*, User::AllocL( KPixelsBlock * sizeof( TUint32 ) ) );
+ }
+
+ if ( aComponentIndex == 2 && aTile.ColorTransformation() )
+ {
+ for ( c = 0; c < 3; c++ )
+ {
+ bitdepth = iImageInfo.DepthOfComponent( c );
+
+ // Output single files
+ WriteOutputFile( aTile, c, subbandSize, bitdepth );
+ iComponents[c]->FreeData();
+ }
+ }
+ else if ( iJ2kInfo.iCMPList.Count() )
+ {
+ for ( c = 0; c < iNumComponents; c++ )
+ {
+ // Bitdepth is the lowest seven bits plus one for palettes
+ bitdepth = (TUint8)( ( iJ2kInfo.iPalette.iBList[0] & 0x7f )+1 );
+
+ // Output single files
+ WriteOutputFile( aTile, c, subbandSize, bitdepth );
+ iComponents[c]->FreeData();
+ }
+ }
+ else
+ {
+ bitdepth = iImageInfo.DepthOfComponent( aComponentIndex );
+
+ // Output only the first component to screen
+ if( aComponentIndex == 0 )
+ {
+ WriteOutputFile( aTile, aComponentIndex, subbandSize, bitdepth );
+ }
+
+ iComponents[aComponentIndex]->FreeData();
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::OutputBlockL
+// Output the image related to the component of the tile
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageWriter::OutputBlockL( CJ2kTileInfo& aTile, TUint16 aComponentIndex,
+ TInt32 aBlockXCoord, TInt32 aBlockYCoord,
+ TSize aFirstCompSize, TSize aThisCompSize )
+ {
+ TUint32 tileIndex = 0;
+ CJ2kWriterComponentInfo* currentComponent = iComponents[aComponentIndex];
+ TPoint tmpTileStart( 0, 0 );
+ TPoint tmpTileStart1( 0, 0 );
+ TPoint tmpTileStart2( 0, 0 );
+
+ CJ2kComponentInfo& componentInfo = CONST_CAST( CJ2kComponentInfo&, aTile.ComponentAt( aComponentIndex ) );
+ TSize outputSize( 0, 0 );
+
+ tileIndex = aTile.SotMarker().iIsot;
+
+ // Update the subband size ( which will be used to compute output size )
+ TInt16 reducedLevels = (TInt16)( componentInfo.Levels() - iImageInfo.LevelDrop() );
+ if ( reducedLevels < 0 )
+ {
+
+ TInt32 i;
+ TInt32 stepSize = 1;
+
+ // Compute the output step size, the stepSize indicates how much more
+ // resolution has to be dropped if the image didn't have enough wavelet
+ // levels to begin with. One indicates no extra resolution drop (write
+ // each sample) and for each extra drop skip half of the samples, i.e.
+ // stepSize is 2^extraLevels in case extra drop is needed.
+
+ // Compute the stepSize
+ for ( i = 0; i < (-reducedLevels); i++ )
+ {
+ // Double the step size for every extra level dropped.
+ stepSize *= 2;
+ }
+
+ // Adjust the block coordinates, so that next block is drawn to the right coordinates
+ aBlockXCoord /= stepSize;
+ aBlockYCoord /= stepSize;
+
+ reducedLevels = 0;
+ }
+
+ CJ2kSubband* subband = CONST_CAST( CJ2kSubband*, componentInfo.SubbandAt( (TUint8)reducedLevels ) );
+ if ( subband->SubbandResLevel() != 0 )
+ {
+ subband = subband->Parent();
+ }
+
+ // If we are going to combine the output into a single file we must use the first components size and
+ // tile-start values ( other components might be sub sampled ).
+ if( iSingleFileOutput && iNumComponents == 3 )
+ {
+ // Update the tileStartCoordinates
+ tmpTileStart = iComponents[0]->TileStartAt( aTile.SotMarker().iIsot );
+ iComponents[0]->iTileStartList[tileIndex].iX += aBlockXCoord;
+ iComponents[0]->iTileStartList[tileIndex].iY += aBlockYCoord;
+
+ // Also store and update the tileStartCoordinates of the other two components, as they may be output to file
+ tmpTileStart1 = iComponents[1]->TileStartAt( aTile.SotMarker().iIsot );
+ iComponents[1]->iTileStartList[tileIndex].iX += aBlockXCoord;
+ iComponents[1]->iTileStartList[tileIndex].iY += aBlockYCoord;
+ tmpTileStart2 = iComponents[2]->TileStartAt( aTile.SotMarker().iIsot );
+ iComponents[2]->iTileStartList[tileIndex].iX += aBlockXCoord;
+ iComponents[2]->iTileStartList[tileIndex].iY += aBlockYCoord;
+
+ outputSize = aFirstCompSize;
+ }
+ else
+ {
+ // Update the tileStartCoordinates
+ tmpTileStart = currentComponent->TileStartAt( aTile.SotMarker().iIsot );
+ currentComponent->iTileStartList[tileIndex].iX += aBlockXCoord;
+ currentComponent->iTileStartList[tileIndex].iY += aBlockYCoord;
+
+ outputSize = aThisCompSize;
+ }
+
+ // Call OutputImageL with the changed parameters
+ OutputImageL( aTile, aComponentIndex, outputSize );
+
+ // Restore the original values
+ if( iSingleFileOutput && iNumComponents == 3 )
+ {
+ iComponents[0]->iTileStartList[tileIndex] = tmpTileStart;
+ iComponents[1]->iTileStartList[tileIndex] = tmpTileStart1;
+ iComponents[2]->iTileStartList[tileIndex] = tmpTileStart2;
+ }
+ else
+ {
+ currentComponent->iTileStartList[tileIndex] = tmpTileStart;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::SetNewImageProcessor
+// Set the image processor of the image write
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageWriter::SetNewImageProcessor( CImageProcessor* aImageProcessor )
+ {
+ iImageProcessor = aImageProcessor;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::SingleFileOutput
+// Get the single output file
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kImageWriter::SingleFileOutput() const
+ {
+ return iSingleFileOutput;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::CSCode
+// Get the EnumCS
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kImageWriter::CSCode() const
+ {
+ return (TUint8)iJ2kInfo.iEnumCS;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::CJ2kImageWriter
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CJ2kImageWriter::CJ2kImageWriter( CImageProcessor* aImageProcessor,
+ CJ2kImageInfo& aImageInfo,
+ TJ2kInfo& aJ2kInfo ) :
+ iImageProcessor( aImageProcessor ),
+ iImageInfo( aImageInfo ),
+ iJ2kInfo( aJ2kInfo )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageWriter::ConstructL()
+ {
+ TInt32 i = 0;
+
+ TSizMarker& sizMarker = CONST_CAST( TSizMarker&, iImageInfo.SizMarker() );
+
+ iNumComponents = iImageInfo.NumOfComponents();
+
+ if ( iJ2kInfo.iCMPList.Count() )
+ {
+ iNumComponents = (TUint16)( iJ2kInfo.iCMPList.Count() );
+
+ if(iNumComponents < iImageInfo.NumOfComponents())
+ {
+ // Every component in the codestream must have a mapping defined
+ User::Leave( KErrCorrupt );
+ }
+ }
+
+ for ( i = 0; i < iNumComponents; i++ )
+ {
+ CJ2kWriterComponentInfo *info = new ( ELeave ) CJ2kWriterComponentInfo;
+ CleanupStack::PushL( info );
+ User::LeaveIfError( iComponents.Append( info ) );
+ CleanupStack::Pop(1);
+ }
+
+ if ( iNumComponents == 3 )
+ {
+ iSingleFileOutput = 1;
+ if ( sizMarker.iXRsiz[1] == 2 * sizMarker.iXRsiz[0] &&
+ sizMarker.iXRsiz[2] == 2 * sizMarker.iXRsiz[0] )
+ {
+ if ( sizMarker.iYRsiz[1] == 2 * sizMarker.iYRsiz[0] &&
+ sizMarker.iYRsiz[2] == 2 * sizMarker.iYRsiz[0] )
+ {
+ iFileType = KYUV420;
+ }
+ else
+ {
+ iFileType = KYUV422;
+ }
+ }
+ }
+ else if ( iNumComponents == 1 )
+ {
+ iFileType = KRGB;
+ }
+
+ if ( iImageInfo.ComponentDrop() ) //lint !e961 no else is needed here at the end of if...else if
+ {
+ iFileType = KRGB;
+ }
+
+ if ( iJ2kInfo.iICCProfile )
+ {
+ iICCProfile = ETrue;
+ InitializeICCProfileL();
+ }
+
+ // Initialize the output parameters
+ if ( iImageInfo.Crop() )
+ {
+ // Currently do nothing.
+ }
+ else
+ {
+ InitializeOutputParametersL();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::PerformInverseRCT
+// Perform the inverse reversible color transformation
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageWriter::PerformInverseRCT( const TSize& aSize )
+ {
+ TInt32 col = 0;
+ TPrecInt red = 0;
+ TPrecInt green = 0;
+ TPrecInt blue = 0;
+ TPrecInt** block1 = iComponents[0]->iData;
+ TPrecInt** block2 = iComponents[1]->iData;
+ TPrecInt** block3 = iComponents[2]->iData;
+
+ for ( TInt32 row = 0; row < aSize.iHeight; row++ )
+ {
+ for ( col = 0; col < aSize.iWidth; col++ )
+ {
+ red = block1[row][col];
+ green = block2[row][col];
+ blue = block3[row][col];
+
+ block2[row][col] = red - ( ( blue + green ) >> 2 ); //lint !e704 shifting is OK.
+ block1[row][col] = blue + block2[row][col];
+ block3[row][col] = green + block2[row][col];
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::PerformInverseICT
+// Perform the inverse irreversible color transformation
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageWriter::PerformInverseICT( const TSize& aSize )
+ {
+ TInt32 col = 0;
+ TPrecInt red = 0;
+ TPrecInt green = 0;
+ TPrecInt blue = 0;
+ TPrecInt** block1 = iComponents[0]->iData;
+ TPrecInt** block2 = iComponents[1]->iData;
+ TPrecInt** block3 = iComponents[2]->iData;
+
+ for ( TInt32 row = 0; row < aSize.iHeight; row++ )
+ {
+ for ( col = 0; col < aSize.iWidth; col++ )
+ {
+ red = block1[row][col];
+ green = block2[row][col];
+ blue = block3[row][col];
+ InverseICTTransform( red, green, blue, block1[row][col], block2[row][col], block3[row][col] );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::InverseICTTransform
+// Inverse irreversible color transformation
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageWriter::InverseICTTransform( TPrecInt aY, TPrecInt aU, TPrecInt aV,
+ TPrecInt& aR, TPrecInt& aG, TPrecInt& aB )
+ {
+ aR = ( TPrecInt )( ( ( ( aY << KFractionBits ) +
+ ( KIctCoefficient11 * aV ) ) + KOffset ) >> KFractionBits ); //lint !e704 shifting is OK.
+ aG = ( TPrecInt )( ( ( ( aY << KFractionBits ) +
+ ( KIctCoefficient21 * aU ) + ( KIctCoefficient22 * aV ) ) + KOffset ) >> KFractionBits ); //lint !e704 shifting is OK.
+ aB = ( TPrecInt )( ( ( ( aY << KFractionBits ) +
+ ( KIctCoefficient31 * aU ) ) + KOffset ) >> KFractionBits ); //lint !e704 shifting is OK.
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::InverseICTTransform
+// Inverse irreversible color transformation.
+// Performs fast transform and outputs even and odd samples at the same time
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageWriter::InverseICTTransform( TPrecInt aY1, TPrecInt aY2, TPrecInt aU, TPrecInt aV,
+ TPrecInt& aR1, TPrecInt& aG1, TPrecInt& aB1,
+ TPrecInt& aR2, TPrecInt& aG2, TPrecInt& aB2)
+ {
+ TInt32 y1Shifted;
+ TInt32 y2Shifted;
+ TInt32 rTempValue;
+ TInt32 gTempValue;
+ TInt32 bTempValue;
+
+ y1Shifted = ( aY1 << KFractionBits );
+ y2Shifted = ( aY2 << KFractionBits );
+ rTempValue = ( KIctCoefficient11 * aV ) + KOffset;
+ gTempValue = ( KIctCoefficient21 * aU ) + ( KIctCoefficient22 * aV ) + KOffset;
+ bTempValue = ( KIctCoefficient31 * aU ) + KOffset;
+
+ aR1 = ( TPrecInt )( ( y1Shifted + rTempValue ) >> KFractionBits ); //lint !e704 shifting is OK.
+ aG1 = ( TPrecInt )( ( y1Shifted + gTempValue ) >> KFractionBits ); //lint !e704 shifting is OK.
+ aB1 = ( TPrecInt )( ( y1Shifted + bTempValue ) >> KFractionBits ); //lint !e704 shifting is OK.
+ aR2 = ( TPrecInt )( ( y2Shifted + rTempValue ) >> KFractionBits ); //lint !e704 shifting is OK.
+ aG2 = ( TPrecInt )( ( y2Shifted + gTempValue ) >> KFractionBits ); //lint !e704 shifting is OK.
+ aB2 = ( TPrecInt )( ( y2Shifted + bTempValue ) >> KFractionBits ); //lint !e704 shifting is OK.
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::InverseICTFastYUV420Transform
+// Inverse irreversible color transformation
+// Performs fast transform and outputs even and odd samples on even and odd
+// rows (four samples) at the same time.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageWriter::InverseICTTransform( TPrecInt aY1, TPrecInt aY2, TPrecInt aY3, TPrecInt aY4,
+ TPrecInt aU, TPrecInt aV,
+ TPrecInt& aR1, TPrecInt& aG1, TPrecInt& aB1,
+ TPrecInt& aR2, TPrecInt& aG2, TPrecInt& aB2,
+ TPrecInt& aR3, TPrecInt& aG3, TPrecInt& aB3,
+ TPrecInt& aR4, TPrecInt& aG4, TPrecInt& aB4)
+ {
+ TInt32 y1Shifted;
+ TInt32 y2Shifted;
+ TInt32 y3Shifted;
+ TInt32 y4Shifted;
+ TInt32 rTempValue;
+ TInt32 gTempValue;
+ TInt32 bTempValue;
+
+ y1Shifted = ( aY1 << KFractionBits );
+ y2Shifted = ( aY2 << KFractionBits );
+ y3Shifted = ( aY3 << KFractionBits );
+ y4Shifted = ( aY4 << KFractionBits );
+ rTempValue = ( KIctCoefficient11 * aV ) + KOffset;
+ gTempValue = ( KIctCoefficient21 * aU ) + ( KIctCoefficient22 * aV ) + KOffset;
+ bTempValue = ( KIctCoefficient31 * aU ) + KOffset;
+
+ aR1 = ( TPrecInt )( ( y1Shifted + rTempValue ) >> KFractionBits ); //lint !e704 shifting is OK.
+ aG1 = ( TPrecInt )( ( y1Shifted + gTempValue ) >> KFractionBits ); //lint !e704 shifting is OK.
+ aB1 = ( TPrecInt )( ( y1Shifted + bTempValue ) >> KFractionBits ); //lint !e704 shifting is OK.
+ aR2 = ( TPrecInt )( ( y2Shifted + rTempValue ) >> KFractionBits ); //lint !e704 shifting is OK.
+ aG2 = ( TPrecInt )( ( y2Shifted + gTempValue ) >> KFractionBits ); //lint !e704 shifting is OK.
+ aB2 = ( TPrecInt )( ( y2Shifted + bTempValue ) >> KFractionBits ); //lint !e704 shifting is OK.
+ aR3 = ( TPrecInt )( ( y3Shifted + rTempValue ) >> KFractionBits ); //lint !e704 shifting is OK.
+ aG3 = ( TPrecInt )( ( y3Shifted + gTempValue ) >> KFractionBits ); //lint !e704 shifting is OK.
+ aB3 = ( TPrecInt )( ( y3Shifted + bTempValue ) >> KFractionBits ); //lint !e704 shifting is OK.
+ aR4 = ( TPrecInt )( ( y4Shifted + rTempValue ) >> KFractionBits ); //lint !e704 shifting is OK.
+ aG4 = ( TPrecInt )( ( y4Shifted + gTempValue ) >> KFractionBits ); //lint !e704 shifting is OK.
+ aB4 = ( TPrecInt )( ( y4Shifted + bTempValue ) >> KFractionBits ); //lint !e704 shifting is OK.
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::InitializeICCProfileL
+// Initialize the ICC profile from JP2 file format ( iJ2kInfo )
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageWriter::InitializeICCProfileL()
+ {
+ const TUint8* iterator = iJ2kInfo.iICCProfile->Ptr();
+ TUint8* origin = CONST_CAST( TUint8*, iJ2kInfo.iICCProfile->Ptr() );
+
+ // Skip the first 128 bytes
+ iterator += KICCSkipBytes;
+
+ // Get the tag count
+ TUint32 tagCount = PtrReadUtil::ReadBigEndianUint32Inc( iterator );
+
+ TUint32 tagSignature = 0;
+ TUint32 tagSize = 0;
+ TUint32 redXYZOffset = 0;
+ TUint32 greenXYZOffset = 0;
+ TUint32 blueXYZOffset = 0;
+ TUint32 trcOffset = 0;
+ TUint32 index = 0;
+ TInt32 i = 0;
+ TInt entries = 0;
+ HBufC16* redTRC = 0;
+ HBufC16* greenTRC = 0;
+ HBufC16* blueTRC = 0;
+ HBufC16* grayTRC = 0;
+ TUint8 isColor = EFalse;
+ TReal value = 0.0;
+
+ for ( index = 0; index < tagCount; ++index )
+ {
+ tagSignature = PtrReadUtil::ReadBigEndianUint32Inc( iterator );
+ switch ( tagSignature )
+ {
+ case KRedMatrixTag:
+ {
+ redXYZOffset = PtrReadUtil::ReadBigEndianUint32Inc( iterator ) + 8;
+ iterator += 4;
+ break;
+ }
+ case KGreenMatrixTag:
+ {
+ greenXYZOffset = PtrReadUtil::ReadBigEndianUint32Inc( iterator ) + 8;
+ iterator += 4;
+ break;
+ }
+ case KBlueMatrixTag:
+ {
+ blueXYZOffset = PtrReadUtil::ReadBigEndianUint32Inc( iterator ) + 8;
+ iterator += 4;
+ break;
+ }
+ case KRedTrcTag:
+ {
+ isColor = ETrue;
+ trcOffset = PtrReadUtil::ReadBigEndianUint32Inc( iterator ) + 12;
+ tagSize = PtrReadUtil::ReadBigEndianUint32Inc( iterator ) - 12;
+ entries = tagSize >> 1;
+ redTRC = HBufC16::NewLC( entries );
+ TPtr16 tmpPtr = ( redTRC->Des() );
+
+ // Read bytes into the TRC values array
+ for( i = 0; i < entries; i++ )
+ {
+ tmpPtr.Append( (TUint16)( ( origin[trcOffset + 2 * i] << 8 ) |
+ origin[trcOffset + 2 * i + 1] ) );
+ }
+
+ break;
+ }
+ case KGreenTrcTag:
+ {
+ isColor = ETrue;
+ trcOffset = PtrReadUtil::ReadBigEndianUint32Inc( iterator ) + 12;
+ tagSize = PtrReadUtil::ReadBigEndianUint32Inc( iterator ) - 12;
+ entries = tagSize >> 1;
+ greenTRC = HBufC16::NewLC( entries );
+ TPtr16 tmpPtr = ( greenTRC->Des() );
+
+ // Read bytes into the TRC values array
+ for( i = 0; i < entries; i++ )
+ {
+ tmpPtr.Append( (TUint16)( ( origin[trcOffset + 2 * i] << 8 ) |
+ origin[trcOffset + 2 * i + 1] ) );
+ }
+
+ break;
+ }
+ case KBlueTrcTag:
+ {
+ isColor = ETrue;
+ trcOffset = PtrReadUtil::ReadBigEndianUint32Inc( iterator ) + 12;
+ tagSize = PtrReadUtil::ReadBigEndianUint32Inc( iterator ) - 12;
+ entries = tagSize >> 1;
+ blueTRC = HBufC16::NewLC( entries );
+ TPtr16 tmpPtr = ( blueTRC->Des() );
+
+ // Read bytes into the TRC values array
+ for( i = 0; i < entries; i++ )
+ {
+ tmpPtr.Append( (TUint16)( ( origin[trcOffset+2*i] << 8 ) |
+ origin[trcOffset+2*i+1] ) );
+ }
+
+ break;
+ }
+ case KGrayTrcTag:
+ {
+ trcOffset = PtrReadUtil::ReadBigEndianUint32Inc( iterator ) + 12;
+ tagSize = PtrReadUtil::ReadBigEndianUint32Inc( iterator ) - 12;
+ entries = tagSize >> 1;
+ grayTRC = HBufC16::NewLC( entries );
+ TPtr16 tmpPtr = ( grayTRC->Des() );
+
+ // Read bytes into the TRC values array
+ for( i = 0; i < entries; i++ )
+ {
+ tmpPtr.Append( (TUint16)( ( origin[trcOffset + 2 * i] << 8 ) |
+ origin[trcOffset + 2 * i + 1] ) );
+ }
+
+ break;
+ }
+ default:
+ {
+ iterator += 8;
+ break;
+ }
+ }
+ }
+
+ TReal gamma = 0.0;
+ TReal maxInput = 0.0;
+ TReal src = 0.0;
+ TUint32 numPerSample = 0;
+ TUint32 lutSize = 0;
+ if ( iJ2kInfo.iBPCList.Count() )
+ {
+ lutSize = 1 << ( iJ2kInfo.iBPCList[0] & 0x7f + 1 );
+ }
+ else
+ {
+ lutSize = 1 << iImageInfo.DepthOfComponent( 0 );
+ }
+
+ if ( isColor )
+ {
+ // Read the RGB( lin. ) -> XYZ conversion matrix coefficients
+ // The matrix is the following:
+ // _ _
+ // | redX greenX blueX |
+ // | redY greenY blueY |
+ // | redZ greenZ blueZ |
+ // |_ _|
+ //
+ TReal redX = ( TReal )PtrReadUtil::ReadBigEndianUint32( origin + redXYZOffset ) / KDivisor;
+ TReal redY = ( TReal )PtrReadUtil::ReadBigEndianUint32( origin + redXYZOffset + 4 ) / KDivisor;
+ TReal redZ = ( TReal )PtrReadUtil::ReadBigEndianUint32( origin + redXYZOffset + 8 ) / KDivisor;
+
+ TReal greenX = ( TReal )PtrReadUtil::ReadBigEndianUint32( origin + greenXYZOffset ) / KDivisor;
+ TReal greenY = ( TReal )PtrReadUtil::ReadBigEndianUint32( origin + greenXYZOffset + 4 ) / KDivisor;
+ TReal greenZ = ( TReal )PtrReadUtil::ReadBigEndianUint32( origin + greenXYZOffset + 8 ) / KDivisor;
+
+ TReal blueX = ( TReal )PtrReadUtil::ReadBigEndianUint32( origin + blueXYZOffset ) / KDivisor;
+ TReal blueY = ( TReal )PtrReadUtil::ReadBigEndianUint32( origin + blueXYZOffset + 4 ) / KDivisor;
+ TReal blueZ = ( TReal )PtrReadUtil::ReadBigEndianUint32( origin + blueXYZOffset + 8 ) / KDivisor;
+
+ // Combine the RGB( lin. ) -> XYZ and the XYZ -> sRGB( lin. ) conversions, i.e.
+ // perform the matrix multiplication. Store the result in "iMatrix".
+ iMatrix[0] = ( TInt32 )( KSRGBMaxIntShifted * ( KSRGB00 * redX + KSRGB01 * redY + KSRGB02 * redZ ) );
+ iMatrix[1] = ( TInt32 )( KSRGBMaxIntShifted * ( KSRGB00 * greenX + KSRGB01 * greenY + KSRGB02 * greenZ ) );
+ iMatrix[2] = ( TInt32 )( KSRGBMaxIntShifted * ( KSRGB00 * blueX + KSRGB01 * blueY + KSRGB02 * blueZ ) );
+
+ iMatrix[3] = ( TInt32 )( KSRGBMaxIntShifted * ( KSRGB10 * redX + KSRGB11 * redY + KSRGB12 * redZ ) );
+ iMatrix[4] = ( TInt32 )( KSRGBMaxIntShifted * ( KSRGB10 * greenX + KSRGB11 * greenY + KSRGB12 * greenZ ) );
+ iMatrix[5] = ( TInt32 )( KSRGBMaxIntShifted * ( KSRGB10 * blueX + KSRGB11 * blueY + KSRGB12 * blueZ ) );
+
+ iMatrix[6] = ( TInt32 )( KSRGBMaxIntShifted * ( KSRGB20 * redX + KSRGB21 * redY + KSRGB22 * redZ ) );
+ iMatrix[7] = ( TInt32 )( KSRGBMaxIntShifted * ( KSRGB20 * greenX + KSRGB21 * greenY + KSRGB22 * greenZ ) );
+ iMatrix[8] = ( TInt32 )( KSRGBMaxIntShifted * ( KSRGB20 * blueX + KSRGB21 * blueY + KSRGB22 * blueZ ) );
+
+ iRedTRCLut = STATIC_CAST( TInt32*, User::AllocL( lutSize * sizeof( TInt32 ) ) );
+ if ( redTRC->Length() == 1 )
+ {
+ gamma = (TReal)( *redTRC )[0] / KGamma;
+ maxInput = (TReal)( lutSize - 1 );
+ for ( index = 0; index < lutSize; ++index )
+ {
+ src = index / maxInput;
+ Math::Pow( value, src, gamma );
+ iRedTRCLut[index] = (TInt32)( value * KTRCShiftMultiplier + 0.5 );
+ }
+ }
+ else
+ {
+ numPerSample = lutSize / (TUint32)( redTRC->Length() );
+ if ( numPerSample )
+ {
+ for ( index = 0; index < lutSize; ++index )
+ {
+ value = ( *redTRC )[index / numPerSample] / KDivisor;
+ iRedTRCLut[index] = (TInt32)( value * KTRCShiftMultiplier + 0.5 );
+ }
+ }
+ }
+
+ if ( iJ2kInfo.iBPCList.Count() )
+ {
+ lutSize = 1 << ( iJ2kInfo.iBPCList[1] & 0x7f + 1 );
+ }
+ else
+ {
+ lutSize = 1 << iImageInfo.DepthOfComponent( 1 );
+ }
+
+ iGreenTRCLut = STATIC_CAST( TInt32*, User::AllocL( lutSize * sizeof( TInt32 ) ) );
+ if ( greenTRC->Length() == 1 )
+ {
+ gamma = (TReal)( *greenTRC )[0] / KGamma;
+ maxInput = (TReal)( lutSize - 1 );
+ for ( index = 0; index < lutSize; ++index )
+ {
+ src = index / maxInput;
+ Math::Pow( value, src, gamma );
+ iGreenTRCLut[index] = (TInt32)( value * KTRCShiftMultiplier + 0.5 );
+ }
+ }
+ else
+ {
+ numPerSample = lutSize / (TUint32)( greenTRC->Length() );
+ if ( numPerSample )
+ {
+ for ( index = 0; index < lutSize; ++index )
+ {
+ value = ( *greenTRC )[index / numPerSample] / KDivisor;
+ iGreenTRCLut[index] = (TInt32)( value * KTRCShiftMultiplier + 0.5 );
+ }
+ }
+ }
+
+ if ( iJ2kInfo.iBPCList.Count() )
+ {
+ lutSize = 1 << ( iJ2kInfo.iBPCList[2] & 0x7f + 1 );
+ }
+ else
+ {
+ lutSize = 1 << iImageInfo.DepthOfComponent( 2 );
+ }
+
+ iBlueTRCLut = STATIC_CAST( TInt32*, User::AllocL( lutSize * sizeof( TInt32 ) ) );
+ if ( blueTRC->Length() == 1 )
+ {
+ gamma = (TReal)( *blueTRC )[0] / KGamma;
+ maxInput = (TReal)( lutSize - 1 );
+ for ( index = 0; index < lutSize; ++index )
+ {
+ src = index / maxInput;
+ Math::Pow( value, src, gamma );
+ iBlueTRCLut[index] = (TInt32)( value * KTRCShiftMultiplier + 0.5 );
+ }
+ }
+ else
+ {
+ numPerSample = lutSize / (TUint32)( blueTRC->Length() );
+ if ( numPerSample )
+ {
+ for ( index = 0; index < lutSize; ++index )
+ {
+ value = ( *blueTRC )[index / numPerSample] / KDivisor;
+ iBlueTRCLut[index] = (TInt32)( value * KTRCShiftMultiplier + 0.5 );
+ }
+ }
+ }
+ }
+ else
+ {
+
+ iGrayTRCLut = STATIC_CAST( TInt32*, User::AllocL( lutSize * sizeof( TInt32 ) ) );
+ if ( grayTRC->Length() == 1 )
+ {
+
+ gamma = (TReal)( *grayTRC )[0] / KGamma;
+ maxInput = (TReal)( lutSize - 1 );
+ for ( index = 0; index < lutSize; ++index )
+ {
+ src = index / maxInput;
+ Math::Pow( value, src, gamma );
+ iGrayTRCLut[index] = (TInt32)( value*KSRGBMax+0.5 );
+ }
+ }
+ else
+ {
+ numPerSample = lutSize / (TUint32)( grayTRC->Length() );
+ if ( numPerSample )
+ {
+ for ( index = 0; index < lutSize; ++index )
+ {
+ value = ( *grayTRC )[index / numPerSample] / KDivisor;
+ iGrayTRCLut[index] = (TInt32)( value*KSRGBMax + 0.5 );
+ }
+ }
+ }
+ }
+
+ TUint16 cutoffIdx = 0; // Cutoff index for linear portion of output LUT
+ TReal linearSlope = 0.0; // Slope of output LUT in the linear region
+ TReal normalisation = 0.0; // Scale factor to normalize sRGB linear value to [0,1]
+
+ // Generate the final output LUT for converting linear sRGB to non-linear sRGB.
+ // Input values are in the range [0,KSRGBMax] and output will be 8-bit [0,255].
+ // Conversation values can be obtained in e.g. "JPEG2000 - Image compression
+ // fundamentals, standards and practice" book by Taubman and Marcellin.
+ cutoffIdx = (TUint16)( KSRGB_CUTOFF * KSRGBMax );
+ linearSlope = 255.0 * KSRGB_SLOPE / KSRGBMax;
+ normalisation = 1.0 / KSRGBMax;
+
+ iLinearsRGBLut = HBufC8::NewL( KSRGBMaxInt + 1 );
+
+ // Generate the output lin.sRGB -> non-lin.sRGB LUT
+ // Linear part
+ for ( index = 0; index <= cutoffIdx; ++index )
+ {
+ iLinearsRGBLut->Des().Append( (TUint8)( linearSlope * index ) );
+ }
+
+ // Non-linear part
+ for ( ; index <= (TUint32)KSRGBMaxInt; ++index )
+ {
+ gamma = index * normalisation;
+ Math::Pow( src, gamma , KSRGB_EXPONENT );
+ iLinearsRGBLut->Des().Append( (TUint8)( 255 * ( KSRGB_MULTIPLIER * src - KSRGB_SUBTRACT ) ) );
+ }
+
+ // We do not need iJ2kInfo.iICCProfile data anymore
+ delete iJ2kInfo.iICCProfile;
+ iJ2kInfo.iICCProfile = 0;
+
+ if ( isColor )
+ {
+ CleanupStack::PopAndDestroy( 3 );
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy( 1 );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::InitializeOutputParametersL
+// Initialize the output parameters
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageWriter::InitializeOutputParametersL()
+ {
+ CJ2kWriterComponentInfo* component = 0;
+ TUint16 l = 0;
+ TUint16 m = 0;
+ TUint16 tileIndex = 0;
+ TUint16 tileYIndex = 0;
+ TPoint tileStart( 0, 0 );
+ TUint16 numOfHorizTiles = iImageInfo.NumOfHorizTiles();
+ TUint16 numOfVertTiles = iImageInfo.NumOfVertTiles();
+ TRect tileCanvas( 0, 0, 0, 0 );
+ TRect componentCanvas( 0, 0, 0, 0 );
+ const TSizMarker &sizMarker = iImageInfo.SizMarker();
+ TInt useHeight = 0;
+ TInt useWidth = 0;
+
+ // Prepare the tile coordinates for output image
+ for ( TUint16 compIndex = 0; compIndex < iNumComponents; compIndex++ )
+ {
+ component = iComponents[compIndex];
+
+ for ( l = 0; l < numOfVertTiles; l++ )
+ {
+ tileYIndex = (TUint16)( l * numOfHorizTiles );
+
+ for ( m = 0; m < numOfHorizTiles; m++ )
+ {
+ // Tile index
+ tileIndex = (TUint16)( tileYIndex + m );
+
+ // Tile canvas
+ tileCanvas.iTl = TPoint( Max( sizMarker.iXTOsiz + m * sizMarker.iXTsiz, sizMarker.iXOsiz ),
+ Max( sizMarker.iYTOsiz + l * sizMarker.iYTsiz, sizMarker.iYOsiz ) );
+
+ tileCanvas.iBr = TPoint( Min( sizMarker.iXTOsiz + ( m + 1 ) * sizMarker.iXTsiz, sizMarker.iXsiz ),
+ Min( sizMarker.iYTOsiz + ( l + 1 ) * sizMarker.iYTsiz, sizMarker.iYsiz ) );
+ // Component canvas
+ componentCanvas.iTl = TPoint( TJ2kUtils::Ceil( tileCanvas.iTl.iX, sizMarker.iXRsiz[compIndex] ),
+ TJ2kUtils::Ceil( tileCanvas.iTl.iY, sizMarker.iYRsiz[compIndex] ) );
+
+ componentCanvas.iBr = TPoint( TJ2kUtils::Ceil( tileCanvas.iBr.iX, sizMarker.iXRsiz[compIndex] ),
+ TJ2kUtils::Ceil( tileCanvas.iBr.iY, sizMarker.iYRsiz[compIndex] ) );
+
+ if ( m )
+ {
+ tileStart.iX = component->iTileStartList[tileIndex - 1].iX + useWidth;
+ }
+ else
+ {
+ tileStart.iX = 0;
+ }
+
+ // Width to be used on the next horizontal tile
+ useWidth = componentCanvas.Width();
+
+ if ( l )
+ {
+ tileStart.iY = component->iTileStartList[tileIndex - 1].iY + useHeight;
+ useHeight = 0;
+ }
+ else
+ {
+ tileStart.iY = 0;
+ }
+
+ User::LeaveIfError( component->iTileStartList.Append( tileStart ) );
+ }
+ // Height to be used on the next vertical tile
+ useHeight = componentCanvas.Height();
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::DoICCConversion
+// Perform XYZ to sRGB conversion with the ICC profile.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageWriter::DoICCConversion( TInt32 aX,
+ TInt32 aY,
+ TInt32 aZ,
+ TPrecInt& aR,
+ TPrecInt& aG,
+ TPrecInt& aB )
+ {
+ TInt32 tmpX = 0;
+ TInt32 tmpY = 0;
+ TInt32 tmpZ = 0;
+ TInt32 tmpR = 0;
+ TInt32 tmpG = 0;
+ TInt32 tmpB = 0;
+
+ // First perform the input linearization
+ tmpX = iRedTRCLut[aX];
+ tmpY = iGreenTRCLut[aY];
+ tmpZ = iBlueTRCLut[aZ];
+
+ // Then perform the matrix multiplication to obtain the nonlinear RGB
+ tmpR = ( iMatrix[0] * tmpX + iMatrix[1] * tmpY + iMatrix[2] * tmpZ ) >> KICCDownshift; //lint !e704 shifting is OK.
+ tmpG = ( iMatrix[3] * tmpX + iMatrix[4] * tmpY + iMatrix[5] * tmpZ ) >> KICCDownshift; //lint !e704 shifting is OK.
+ tmpB = ( iMatrix[6] * tmpX + iMatrix[7] * tmpY + iMatrix[8] * tmpZ ) >> KICCDownshift; //lint !e704 shifting is OK.
+
+ // Get rid of values outside the range of legal values
+ tmpR = CLIP2RANGE( tmpR, 0, KSRGBMaxInt );
+ tmpG = CLIP2RANGE( tmpG, 0, KSRGBMaxInt );
+ tmpB = CLIP2RANGE( tmpB, 0, KSRGBMaxInt );
+
+ // De-linearize the output RGB values
+ aR = ( *iLinearsRGBLut )[tmpR];
+ aG = ( *iLinearsRGBLut )[tmpG];
+ aB = ( *iLinearsRGBLut )[tmpB];
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::MapToEightBits
+// Map data less than 8 bits to 8 bits data
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageWriter::MapToEightBits( CJ2kWriterComponentInfo& aComponent,
+ const TSize& aSize,
+ TUint16 aBitDepth )
+ {
+ TPrecInt* imageRow;
+ TInt32 i = 0;
+ TInt32 j = 0;
+
+ // DC-shift is always non zero, since we map signed data to unsigned
+ if ( aBitDepth < 8 )
+ {
+ TPrecInt upshift = KByteBits - aBitDepth;
+ TPrecInt dcShiftUp = 1 << ( KByteBits - 1 );
+
+ for ( i = aSize.iHeight - 1; i >= 0; i-- )
+ {
+ imageRow = aComponent.Data()[i];
+ for ( j = aSize.iWidth - 1; j >= 0; j-- )
+ {
+ imageRow[j] = ( imageRow[j] * ( 1 << upshift ) ) + dcShiftUp;
+ }
+ }
+ }
+ else // The original bitdepth is more than eight
+ {
+ TPrecInt dcShift = 1 << ( aBitDepth - 1 );
+ TPrecInt downshift = aBitDepth - KByteBits;
+ for ( i = aSize.iHeight - 1; i >= 0; --i )
+ {
+ imageRow = aComponent.Data()[i];
+ for ( j = aSize.iWidth - 1; j >= 0; j-- )
+ {
+ imageRow[j] = ( imageRow[j] + dcShift ) >> downshift; //lint !e704 shifting is OK.
+ }
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::MapComponentsL
+// Map data using the component mapping box from JP2 file format
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageWriter::MapComponentsL( TUint16 aNumCSComp,
+ TUint16 aReducedLevels,
+ const TSize& aSize,
+ CJ2kTileInfo& aTile )
+ {
+ TInt32 i = 0;
+ TInt32 j = 0;
+ TInt32 k = 0; // Indices
+ TInt32 compIndex = 0; // Index of the component in the codestream
+ TInt32 paletteIndex = 0; // Index of the component in the palette
+ TInt32 value = 0;
+ TInt32 dcShift = 0;
+ TPrecInt*** tempData = 0; // temporary storage for codestream data
+ TUint8 bitdepth = 0;
+
+ CJ2kWriterComponentInfo* componentFrom = 0;
+ CJ2kWriterComponentInfo* componentTo = 0;
+ CJ2kSubband* subband = 0;
+
+ TSize subbandSize( 0, 0 );
+
+ // First allocate the temporary storage
+ tempData = STATIC_CAST( TPrecInt***, User::Alloc( aNumCSComp * sizeof( TPrecInt** ) ) );
+ if ( !tempData )
+ {
+ User::Leave( KErrNoMemory );
+ }
+ CleanupStack::PushL( tempData );
+ for ( i = 0; i < aNumCSComp; i++ )
+ {
+ subband = CONST_CAST( CJ2kSubband*, aTile.ComponentAt( (TUint16)i ).SubbandAt( (TUint8)aReducedLevels ) );
+
+ if( subband->SubbandResLevel() != 0 )
+ {
+ subband = subband->Parent();
+ }
+ subbandSize = subband->SubbandCanvasSize();
+
+ // Check that this component's size doesn't exceed the output size
+ if( subbandSize.iWidth > aSize.iWidth )
+ {
+ subbandSize.iWidth = aSize.iWidth;
+ }
+ if( subbandSize.iHeight > aSize.iHeight )
+ {
+ subbandSize.iHeight = aSize.iHeight;
+ }
+
+ // Allocate the temporary storage
+ tempData[i] = TJ2kUtils::Alloc2DArrayL( subbandSize.iHeight, subbandSize.iWidth );
+ CleanupStack::PushL( TCleanupItem( ( TCleanupOperation )&( TJ2kUtils::Free2DArray ), ( TAny* )tempData[i] ) );
+ componentFrom = iComponents[i];
+
+ for ( j = subbandSize.iHeight - 1; j >= 0; j-- )
+ {
+ Mem::Copy( tempData[i][j], componentFrom->Data()[j], subbandSize.iWidth * sizeof( TPrecInt ) );
+ }
+ }
+
+ for ( k = 0; k < iNumComponents; k++ )
+ {
+ // Get the channel in the codestream from which to map
+ compIndex = iJ2kInfo.iCMPList[k].iCmp;
+ componentFrom = iComponents[compIndex];
+
+ subband = CONST_CAST( CJ2kSubband*, aTile.ComponentAt( (TUint16)compIndex ).SubbandAt( (TUint8)aReducedLevels ) );
+
+ if( subband->SubbandResLevel() != 0 )
+ {
+ subband = subband->Parent();
+ }
+
+ subbandSize = subband->SubbandCanvasSize();
+
+ // Check that this component's size doesn't exceed the output size
+ if( subbandSize.iWidth > aSize.iWidth )
+ {
+ subbandSize.iWidth = aSize.iWidth;
+ }
+ if( subbandSize.iHeight > aSize.iHeight )
+ {
+ subbandSize.iHeight = aSize.iHeight;
+ }
+
+ // Get the output channel
+ componentTo = iComponents[k];
+
+ // Check if palette is used for mapping
+ if ( iJ2kInfo.iCMPList[k].iMtyp == 1 )
+ {
+ // Get the right palette channel for mapping
+ paletteIndex = iJ2kInfo.iCMPList[k].iPcol;
+
+ // Bitdepth is the lowest seven bits plus one for palettes
+ bitdepth = (TUint8)( ( iJ2kInfo.iPalette.iBList[paletteIndex] & 0x7f ) + 1 );
+ dcShift = 1 << ( bitdepth - 1 );
+
+ for ( i = 0; i < subbandSize.iHeight; i++ )
+ {
+ for ( j = 0; j < subbandSize.iWidth; j++ )
+ {
+ // Map the input codestream channel into the output component
+ // using the palette value.
+ value = tempData[compIndex][i][j] + dcShift;
+ if ( value < 0 )
+ {
+ value = 0;
+ }
+ if ( value >= iJ2kInfo.iPalette.iC2DArray.Count() )
+ {
+ value = iJ2kInfo.iPalette.iC2DArray.Count() - 1;
+ }
+
+ componentTo->iData[i][j] = ( *iJ2kInfo.iPalette.iC2DArray[value] )[paletteIndex] - dcShift;
+ }
+ }
+ }
+ else // Direct mapping
+ {
+ for ( i = subbandSize.iHeight - 1; i >= 0; --i )
+ {
+ for ( j = subbandSize.iWidth - 1; j >= 0; --j )
+ {
+ // Map the input codestream channel into the output component directly.
+ componentTo->iData[i][j] = componentFrom->iData[i][j];
+ }
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy( aNumCSComp + 1 );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::WriteOutputFile
+// Write the component to the single output file
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageWriter::WriteOutputFile( CJ2kTileInfo& aTile,
+ TUint16 aCompIndex,
+ const TSize& aSize,
+ TUint16 aBitDepth )
+ {
+ TPrecInt* imageRow = 0;
+ CJ2kWriterComponentInfo* currentComponent = iComponents[aCompIndex];
+ TSize outputSize = aSize;
+
+ TUint16 numLevels = aTile.ComponentAt( aCompIndex ).Levels();
+ TInt16 tempNumLevels = (TUint16)( numLevels - iImageInfo.LevelDrop() );
+
+ TPoint tileStartCoord = currentComponent->TileStartAt( aTile.SotMarker().iIsot );
+ currentComponent->UpdateNextTileStartAt( aTile.SotMarker().iIsot, aSize, iImageInfo );
+
+ if ( tempNumLevels < 0 )
+ {
+
+ TInt32 i;
+ TInt32 stepSize = 1;
+
+ // Compute the output step size, the stepSize indicates how much more
+ // resolution has to be dropped if the image didn't have enough wavelet
+ // levels to begin with. One indicates no extra resolution drop (write
+ // each sample) and for each extra drop skip half of the samples, i.e.
+ // stepSize is 2^extraLevels in case extra drop is needed.
+
+ // Adjust the tile starting points and the stepSize
+ for ( i = 0; i < (-tempNumLevels); i++ )
+ {
+ // Double the step size for every extra level dropped.
+ stepSize *= 2;
+ }
+
+ // Also take care of next tile's starting position
+ outputSize.iHeight /= stepSize;
+ outputSize.iWidth /= stepSize;
+ iComponents[0]->UpdateNextTileStartAt( aTile.SotMarker().iIsot, outputSize, iImageInfo );
+ }
+
+ TInt32 dcShift = 0;
+ TInt32 j = 0;
+ if ( aBitDepth == 8 )
+ {
+ if ( !( iImageInfo.SignOfComponent( aCompIndex ) ) )
+ {
+ dcShift = 1 << ( aBitDepth - 1 );
+ }
+ }
+
+ // Convert with an ICC profile if necessary
+ if( iICCProfile )
+ {
+ TInt32 value = 0;
+ TInt32 outputValue = 0;
+
+ // Compute the dcShift again, we must have dcShift != 0 for other than 8-bit input.
+ dcShift = 1 << ( iImageInfo.DepthOfComponent( 0 )-1 );
+
+ for ( TInt32 i = 0; i < outputSize.iHeight; i++ )
+ {
+ imageRow = currentComponent->Data()[i];
+
+ SetPixelPos( tileStartCoord.iX, tileStartCoord.iY + i );
+ for ( j = 0; j < outputSize.iWidth; j++ )
+ {
+ // Use a clipped value of input sample for an index to the grayscale TRC LUT.
+ value = iGrayTRCLut[CLIPINT( ( imageRow[j]+dcShift ), aBitDepth )];
+
+ // Get rid of values outside the range of legal values.
+ value = CLIP2RANGE( value, 0, KSRGBMaxInt );
+
+ // De-linearize the output values.
+ outputValue = ( *iLinearsRGBLut )[value];
+
+ iMonoPixelBlock[j] = (TUint32)( INT2BYTE( outputValue ) );
+ }
+
+ // Flush the row of grayscale pixels to image processor
+ iImageProcessor->SetMonoPixels( iMonoPixelBlock, outputSize.iWidth );
+ }
+
+ SetPixelPos( tileStartCoord );
+ }
+ else // No ICC profile was used.
+ {
+
+ // Take care of bitdepths != 8
+ if ( aBitDepth != 8 )
+ {
+ MapToEightBits( *currentComponent, outputSize, aBitDepth );
+ }
+
+ SetPixelPos( tileStartCoord );
+
+ for ( TInt32 i = 0; i < outputSize.iHeight; i++ )
+ {
+ imageRow = currentComponent->Data()[i];
+
+
+ SetPixelPos( tileStartCoord.iX, tileStartCoord.iY + i );
+
+ for ( j = 0; j < outputSize.iWidth; j++ )
+ {
+ // Store the value in the RGB "block"
+ iMonoPixelBlock[j] = (TUint32)( INT2BYTE( ( imageRow[j] + dcShift ) ) );
+ }
+
+ // Flush the row of grayscale pixels to image processor
+ iImageProcessor->SetMonoPixels( iMonoPixelBlock, outputSize.iWidth );
+ }
+
+ SetPixelPos( tileStartCoord );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::CombineOutputFile
+// Write all components of the tile to the single output file
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageWriter::CombineOutputFile( CJ2kTileInfo& aTile, const TSize& aSize )
+ {
+ TInt32 i = 0;
+ TInt32 j = 0;
+ TUint16 numLevels = aTile.ComponentAt( 0 ).Levels();
+ TInt16 tempNumLevels = (TUint16)( numLevels - iImageInfo.LevelDrop() );
+
+ TSize outputSize = aSize;
+ TPoint& tileStartCoord = iComponents[0]->TileStartAt( aTile.SotMarker().iIsot );
+ iComponents[0]->UpdateNextTileStartAt( aTile.SotMarker().iIsot, outputSize, iImageInfo );
+
+ if ( tempNumLevels < 0 )
+ {
+ TInt32 stepSize = 1;
+
+ // Compute the output step size, the stepSize indicates how much more
+ // resolution has to be dropped if the image didn't have enough wavelet
+ // levels to begin with. One indicates no extra resolution drop (write
+ // each sample) and for each extra drop skip half of the samples, i.e.
+ // stepSize is 2^extraLevels in case extra drop is needed.
+
+ // Adjust the tile starting points and the stepSize
+ for ( i = 0; i < (-tempNumLevels); i++ )
+ {
+ // Double the step size for every extra level dropped.
+ stepSize *= 2;
+ }
+
+ // Also take care of next tile's starting position
+ outputSize.iHeight /= stepSize;
+ outputSize.iWidth /= stepSize;
+ iComponents[0]->UpdateNextTileStartAt( aTile.SotMarker().iIsot, outputSize, iImageInfo );
+
+ tempNumLevels = 0;
+ }
+
+ TInt32 dcShift = 0;
+ if ( iImageInfo.DepthOfComponent( 0 ) == 8 )
+ {
+ if ( !( iImageInfo.SignOfComponent( 0 ) ) )
+ {
+ dcShift = 1 << ( iImageInfo.DepthOfComponent( 0 ) - 1 );
+ }
+ }
+
+ TSize subSamplingSize( 0, 0 );
+
+ // Due to subsampling we might have one more sample than the result of
+ // height/2 or width/2 will give thus we have to check whether we an
+ // extra row/column .
+ //
+ if ( iImageInfo.NumOfComponents() == 3 && iJ2kInfo.iEnumCS == 18 )
+ {
+ CJ2kSubband* subband = CONST_CAST( CJ2kSubband*, aTile.ComponentAt( 1 ).SubbandAt( (TUint8)tempNumLevels ) );
+
+ if ( subband->SubbandResLevel() != 0 )
+ {
+ subband = subband->Parent();
+ }
+
+ subSamplingSize = subband->SubbandCanvasSize();
+
+ if ( subSamplingSize.iWidth )
+ {
+ --subSamplingSize.iWidth;
+ }
+
+ if ( subSamplingSize.iHeight )
+ {
+ --subSamplingSize.iHeight;
+ }
+ }
+
+ TPrecInt** c1 = iComponents[0]->Data();
+ TPrecInt** c2 = iComponents[1]->Data();
+ TPrecInt** c3 = iComponents[2]->Data();
+
+ TPrecInt* c1Row = c1[0];
+ TPrecInt* c2Row = c2[0];
+ TPrecInt* c3Row = c3[0];
+
+ // For taking care of channel definition box order
+ if ( iJ2kInfo.iCNList.Count() > 0 )
+ {
+ for ( i = 0; i < 3; i++ )
+ {
+ if ( iJ2kInfo.iCNList[i].iAsoc == 1 )
+ {
+ c1 = iComponents[i]->Data();
+ }
+ else if ( iJ2kInfo.iCNList[i].iAsoc == 2 )
+ {
+ c2 = iComponents[i]->Data();
+ }
+ else if( iJ2kInfo.iCNList[i].iAsoc == 3 )
+ {
+ c3 = iComponents[i]->Data();
+ }
+ } //lint !e961 no else is needed here at the end of if...else if
+ }
+
+ // If dithering is needed the following lines should be used:
+ // TInt32 A = KDitherCoeffcient11 + dcShift;
+ // TInt32 B = KDitherCoeffcient12 + dcShift;
+ // TInt32 C = KDitherCoeffcient21 + dcShift;
+ // TInt32 D = KDitherCoeffcient22 + dcShift;
+ // Without dithering, use dcShift only.
+ //
+ TInt32 ditherA = dcShift;
+ TInt32 ditherB = dcShift;
+ TInt32 ditherC = dcShift;
+ TInt32 ditherD = dcShift;
+
+ TUint8 values[6];
+
+ // Convert with the ICC profile values if necessary.
+ if( iICCProfile )
+ {
+ TInt32 x = 0;
+ TInt32 y = 0;
+ TInt32 z = 0;
+ TPrecInt sR = 0;
+ TPrecInt sG = 0;
+ TPrecInt sB = 0;
+ TInt32 maxValue = 0;
+
+ // Compute the dcShift again, we must have dcShift != 0 for other than 8-bit input.
+ dcShift = 1 << ( iImageInfo.DepthOfComponent( 0 ) - 1 );
+ maxValue = ( 1 << iImageInfo.DepthOfComponent( 0 ) ) - 1; // Maximum value for this bitdepth
+
+ for( i = 0; i < outputSize.iHeight; i++ )
+ {
+
+ // Set the current coordinate in the output image
+ SetPixelPos( tileStartCoord.iX, tileStartCoord.iY + i );
+
+ for( j = 0; j < outputSize.iWidth; j++ )
+ {
+ x = CLIP2BITDEPTH( ( c1[i][j] + dcShift ),maxValue );
+ y = CLIP2BITDEPTH( ( c2[i][j] + dcShift ),maxValue );
+ z = CLIP2BITDEPTH( ( c3[i][j] + dcShift ),maxValue );
+
+ DoICCConversion( x,y,z,sR,sG,sB );
+
+ values[0] = INT2BYTE( sB );
+ values[1] = INT2BYTE( sG );
+ values[2]= INT2BYTE( sR );
+
+ WritePixel( values[2], values[1], values[0] );
+ }
+ }
+
+ // Set the current coordinate in the output image
+ SetPixelPos( tileStartCoord );
+ }
+ else
+ {
+
+ // To speed up output writing (for subsampled samples), compute the number of half the samples
+ TInt32 halfOfWidth = outputSize.iWidth / 2;
+
+ // If the bitdepth is not eight, shift values so that output is unsigned eight bit
+ for ( i = 0; i < iImageInfo.NumOfComponents(); i++ )
+ {
+ if ( iImageInfo.DepthOfComponent( ( TUint16 )i ) != 8 )
+ {
+ MapToEightBits( *iComponents[i], outputSize, iImageInfo.DepthOfComponent( (TUint16)i ) );
+ }
+ }
+
+ // Do the YUV to RGB conversion if needed
+ if ( iJ2kInfo.iEnumCS == 18 )
+ {
+ TPrecInt y1 = 0;
+ TPrecInt y2 = 0;
+ TPrecInt u = 0;
+ TPrecInt v = 0;
+ TPrecInt r = 0;
+ TPrecInt g = 0;
+ TPrecInt b = 0;
+ TPrecInt r1 = 0;
+ TPrecInt g1 = 0;
+ TPrecInt b1 = 0;
+ TPrecInt r2 = 0;
+ TPrecInt g2 = 0;
+ TPrecInt b2 = 0;
+
+ if ( iFileType == KYUV420 ) // YUV 4:2:0
+ {
+
+ TPrecInt* c1EvenRow = c1[0];
+ TPrecInt* c1OddRow = c1[0];
+ TPrecInt y3 = 0;
+ TPrecInt y4 = 0;
+ TPrecInt r3 = 0;
+ TPrecInt g3 = 0;
+ TPrecInt b3 = 0;
+ TPrecInt r4 = 0;
+ TPrecInt g4 = 0;
+ TPrecInt b4 = 0;
+
+ for ( i = 0; i < outputSize.iHeight / 2; i++ )
+ {
+ SetPixelPos( tileStartCoord.iX, ( tileStartCoord.iY + 2 * i ) );
+
+ c1EvenRow = c1[2 * i];
+ c1OddRow = c1[2 * i + 1];
+ c2Row = c2[i];
+ c3Row = c3[i];
+
+ for ( j = 0; j < halfOfWidth; j++ )
+ {
+ y1 = *c1EvenRow++;
+ y2 = *c1EvenRow++;
+ y3 = *c1OddRow++;
+ y4 = *c1OddRow++;
+ u = *c2Row++;
+ v = *c3Row++;
+
+ InverseICTTransform(y1,y2,y3,y4,u,v,r1,g1,b1,r2,g2,b2,r3,g3,b3,r4,g4,b4);
+
+ // Even rows, even columns
+ values[0] = INT2BYTE( ( r1 + ditherA ) );
+ values[1] = INT2BYTE( ( g1 + ditherA ) );
+ values[2] = INT2BYTE( ( b1 + ditherA ) );
+
+ // Even rows, odd columns:
+ values[3] = INT2BYTE( ( r2 + ditherB ) );
+ values[4] = INT2BYTE( ( g2 + ditherB ) );
+ values[5] = INT2BYTE( ( b2 + ditherB ) );
+
+ // Store the values in the RGB "block"
+ iColorPixelBlock[2 * j] = TRgb( values[0], values[1], values[2] );
+ iColorPixelBlock[2 * j + 1] = TRgb( values[3], values[4], values[5] );
+
+ // Now the odd row:
+ // Odd rows, even column
+ values[0] = INT2BYTE( ( r3 + ditherC ) );
+ values[1] = INT2BYTE( ( g3 + ditherC ) );
+ values[2] = INT2BYTE( ( b3 + ditherC ) );
+
+ // Odd rows, odd columns:
+ values[3] = INT2BYTE( ( r4 + ditherD ) );
+ values[4] = INT2BYTE( ( g4 + ditherD ) );
+ values[5] = INT2BYTE( ( b4 + ditherD ) );
+
+ // Store the values in the RGB "block"
+ iColorPixelBlock[KPixelsBlock + 2 * j] = TRgb( values[0], values[1], values[2] );
+ iColorPixelBlock[KPixelsBlock + 2 * j + 1] = TRgb( values[3], values[4], values[5] );
+ }
+
+ if ( outputSize.iWidth & 1 ) // If the width is odd:
+ {
+ // The even row:
+ y1 = c1[2 * i][outputSize.iWidth - 1];
+ // And the odd row:
+ y2 = c1[2 * i + 1][outputSize.iWidth - 1];
+ u = c2[i][subSamplingSize.iWidth];
+ v = c3[i][subSamplingSize.iWidth];
+
+ InverseICTTransform(y1,y2,u,v,r1,g1,b1,r2,g2,b2);
+
+ values[0] = INT2BYTE( ( r1 + ditherA ) );
+ values[1] = INT2BYTE( ( g1 + ditherA ) );
+ values[2] = INT2BYTE( ( b1 + ditherA ) );
+
+ // Store the value in the RGB "block"
+ iColorPixelBlock[outputSize.iWidth - 1] = TRgb( values[0], values[1], values[2] );
+
+ values[0] = INT2BYTE( ( r2 + ditherC ) );
+ values[1] = INT2BYTE( ( g2 + ditherC ) );
+ values[2] = INT2BYTE( ( b2 + ditherC ) );
+
+ // Store the value in the RGB "block"
+ iColorPixelBlock[KPixelsBlock + outputSize.iWidth - 1] = TRgb( values[0], values[1], values[2] );
+ }
+
+ // Flush the row of color pixels to image processor
+ iImageProcessor->SetPixels( iColorPixelBlock, outputSize.iWidth );
+
+ // Duplicated processing for the odd rows
+ SetPixelPos( tileStartCoord.iX, ( tileStartCoord.iY + 2 * i + 1 ) );
+
+ // Flush the row of color pixels to image processor
+ iImageProcessor->SetPixels( (iColorPixelBlock + KPixelsBlock), outputSize.iWidth );
+
+ } // End of loop on rows
+
+ if ( outputSize.iHeight & 1 ) // If the height is odd:
+ {
+ SetPixelPos( tileStartCoord.iX, ( tileStartCoord.iY + outputSize.iHeight - 1 ) );
+
+ c1Row = c1[outputSize.iHeight - 1];
+ c2Row = c2[subSamplingSize.iHeight];
+ c3Row = c3[subSamplingSize.iHeight];
+
+ for ( i = 0; i < halfOfWidth; i++ )
+ {
+ y1 = *c1Row++;
+ y2 = *c1Row++;
+ u = *c2Row++;
+ v = *c3Row++;
+
+ InverseICTTransform(y1,y2,u,v,r1,g1,b1,r2,g2,b2);
+
+ values[0] = INT2BYTE( ( r1 + ditherA ) );
+ values[1] = INT2BYTE( ( g1 + ditherA ) );
+ values[2] = INT2BYTE( ( b1 + ditherA ) );
+
+ values[3] = INT2BYTE( ( r2 + ditherB ) );
+ values[4] = INT2BYTE( ( g2 + ditherB ) );
+ values[5] = INT2BYTE( ( b2 + ditherB ) );
+
+ // Store the value in the RGB "block"
+ iColorPixelBlock[2 * i] = TRgb( values[0], values[1], values[2] );
+ iColorPixelBlock[2 * i + 1] = TRgb( values[3], values[4], values[5] );
+ }
+
+ if ( outputSize.iWidth & 1 ) // if the width is odd:
+ {
+ y1 = c1[outputSize.iHeight - 1][outputSize.iWidth - 1];
+ u = c2[subSamplingSize.iHeight][subSamplingSize.iWidth];
+ v = c3[subSamplingSize.iHeight][subSamplingSize.iWidth];
+
+ InverseICTTransform( y1, u, v, r, g, b );
+ values[0] = INT2BYTE( ( r + ditherA ) );
+ values[1] = INT2BYTE( ( g + ditherA ) );
+ values[2] = INT2BYTE( ( b + ditherA ) );
+
+ // Store the value in the RGB "block"
+ iColorPixelBlock[outputSize.iWidth - 1] = TRgb( values[0], values[1], values[2] );
+ }
+
+ // Flush the row of color pixels to image processor
+ iImageProcessor->SetPixels( iColorPixelBlock, outputSize.iWidth );
+
+ }
+
+ SetPixelPos( tileStartCoord );
+ }
+ else if ( iFileType == KYUV422 )
+ {
+
+ for ( i = 0; i < outputSize.iHeight; i++ )
+ {
+ SetPixelPos( tileStartCoord.iX, ( tileStartCoord.iY + 2 * i ) );
+
+ c1Row = c1[i];
+ c2Row = c2[i];
+ c3Row = c3[i];
+
+ for ( j = 0; j < halfOfWidth; j++ )
+ {
+ y1 = *c1Row++;
+ y2 = *c1Row++;
+ u = c2Row[j];
+ v = c3Row[j];
+
+ InverseICTTransform(y1,y2,u,v,r1,g1,b1,r2,g2,b2);
+
+ values[0] = INT2BYTE( ( r1 + dcShift ) );
+ values[1] = INT2BYTE( ( g1 + dcShift ) );
+ values[2] = INT2BYTE( ( b1 + dcShift ) );
+
+ values[3] = INT2BYTE( ( r2 + dcShift ) );
+ values[4] = INT2BYTE( ( g2 + dcShift ) );
+ values[5] = INT2BYTE( ( b2 + dcShift ) );
+
+ // Store the value in the RGB "block"
+ iColorPixelBlock[j] = TRgb( values[0], values[1], values[2] );
+ iColorPixelBlock[j+1] = TRgb( values[3], values[4], values[5] );
+ }
+
+ if ( outputSize.iWidth & 1 ) // if the width is odd:
+ {
+ y1 = c1Row[outputSize.iWidth - 1];
+ u = c2Row[subSamplingSize.iWidth];
+ v = c3Row[subSamplingSize.iWidth];
+
+ InverseICTTransform( y1, u, v, r, g, b );
+
+ values[0] = INT2BYTE( ( r + dcShift ) );
+ values[1] = INT2BYTE( ( g + dcShift ) );
+ values[2] = INT2BYTE( ( b + dcShift ) );
+
+ // Store the value in the RGB "block"
+ iColorPixelBlock[outputSize.iWidth-1] = TRgb( values[0], values[1], values[2] );
+ }
+
+ // Flush the row of color pixels to image processor
+ iImageProcessor->SetPixels( iColorPixelBlock, outputSize.iWidth );
+ }
+
+ SetPixelPos( tileStartCoord );
+ }
+ else // To take care of YUV 4:4:4
+ {
+
+ for ( i = 0; i < outputSize.iHeight; i++ )
+ {
+ SetPixelPos( tileStartCoord.iX, ( tileStartCoord.iY + i ) );
+
+ c1Row = c1[i];
+ c2Row = c2[i];
+ c3Row = c3[i];
+
+ for ( j = 0; j < outputSize.iWidth; j++ )
+ {
+ y1 = *c1Row++;
+ u = *c2Row++;
+ v = *c3Row++;
+
+ InverseICTTransform( y1, u, v, r, g, b );
+
+ values[0] = INT2BYTE( ( r + dcShift ) );
+ values[1] = INT2BYTE( ( g + dcShift ) );
+ values[2] = INT2BYTE( ( b + dcShift ) );
+
+ // Store the value in the RGB "block"
+ iColorPixelBlock[j] = TRgb( values[0], values[1], values[2] );
+ }
+
+ // Flush the row of color pixels to image processor
+ iImageProcessor->SetPixels( iColorPixelBlock, outputSize.iWidth );
+ }
+
+ SetPixelPos( tileStartCoord );
+ }
+ }
+ else // RGB
+ {
+ TInt32 r = 0;
+ TInt32 g = 0;
+ TInt32 b = 0;
+
+ for ( i = 0; i < outputSize.iHeight; i++ )
+ {
+
+ SetPixelPos( tileStartCoord.iX, tileStartCoord.iY + i );
+
+ c1Row = c1[i];
+ c2Row = c2[i];
+ c3Row = c3[i];
+
+ for ( j = 0; j < outputSize.iWidth; j++ )
+ {
+ r = *c1Row++;
+ g = *c2Row++;
+ b = *c3Row++;
+
+ values[0] = INT2BYTE( r + dcShift );
+ values[1] = INT2BYTE( g + dcShift );
+ values[2] = INT2BYTE( b + dcShift );
+
+ // Store the value in the RGB "block"
+ iColorPixelBlock[j] = TRgb( values[0], values[1], values[2] );
+ }
+
+ // Flush the row of color pixels to image processor
+ iImageProcessor->SetPixels( iColorPixelBlock, outputSize.iWidth );
+ }
+
+ SetPixelPos( tileStartCoord );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::WritePixel
+// Write out a color pixel
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageWriter::WritePixel( TUint8 aR, TUint8 aG, TUint8 aB )
+ {
+ iImageProcessor->SetPixel( TRgb( aR, aG, aB ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::WritePixel
+// Write out a grayscale pixel
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageWriter::WritePixel( TUint8 aGray256 )
+ {
+ iImageProcessor->SetMonoPixel( aGray256 );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::SetPixelPos
+// Set the position of the pixel
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageWriter::SetPixelPos( const TPoint& aPosition )
+ {
+ iImageProcessor->SetPos( aPosition );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kImageWriter::SetPixelPos
+// Set the position of the pixel
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kImageWriter::SetPixelPos( const TInt aX, const TInt aY )
+ {
+ iImageProcessor->SetPos( TPoint( aX, aY ) );
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Src/JP2KMarker.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,410 @@
+/*
+* Copyright (c) 2003, 2004 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: Collection of structs used to gather the various
+* marker related information in the JP2 image file.
+*
+*/
+
+
+// INCLUDE FILES
+#include "JP2KMarker.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// TSizMarker::TSizMarker
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TSizMarker::TSizMarker() :
+ iXsiz(1),
+ iYsiz(1),
+ iXOsiz(0),
+ iYOsiz(0),
+ iXTsiz(1),
+ iYTsiz(1),
+ iXTOsiz(0),
+ iYTOsiz(0),
+ iRsiz(0),
+ iCsiz(1),
+ iSsiz(3),
+ iXRsiz(3),
+ iYRsiz(3)
+ {
+ }
+
+// Destructor
+TSizMarker::~TSizMarker()
+ {
+ iSsiz.Close();
+ iXRsiz.Close();
+ iYRsiz.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// TCODMarker::TCODMarker
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TCODMarker::TCODMarker() :
+ iScod(0),
+ iProgressionOrder(0),
+ iColorTransformation(0),
+ iNumOfLevels(0),
+ iCodeBlockStyle(0),
+ iWaveletTransformation(0),
+ iNumOfLayers(1),
+ iCodeBlockSiz(32,32),
+ iPrecinctSiz(0)
+ {
+ }
+
+// Destructor
+TCODMarker::~TCODMarker()
+ {
+ delete iPrecinctSiz;
+ iPrecinctSiz = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// TCOCMarker::TCOCMarker
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TCOCMarker::TCOCMarker() :
+ iCcoc(0),
+ iScoc(0),
+ iNumOfLevels(0),
+ iCodeBlockStyle(0),
+ iWaveletTransformation(0),
+ iCodeBlockSiz(32,32),
+ iPrecinctSiz(0)
+ {
+ }
+
+// Destructor
+TCOCMarker::~TCOCMarker()
+ {
+ delete iPrecinctSiz;
+ iPrecinctSiz = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// TQCDMarker::TQCDMarker
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TQCDMarker::TQCDMarker():
+ iSqcd(0),
+ iExponent(0),
+ iMantissa(0)
+ {
+ }
+
+// Destructor
+TQCDMarker::~TQCDMarker()
+ {
+ delete iExponent;
+ iExponent = 0;
+ delete iMantissa;
+ iMantissa = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// TQCCMarker::TQCCMarker
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TQCCMarker::TQCCMarker() :
+ iCqcc(0),
+ iSqcc(0),
+ iExponent(0),
+ iMantissa(0)
+ {
+ }
+
+// Destructor
+TQCCMarker::~TQCCMarker()
+ {
+ delete iExponent;
+ iExponent = 0;
+ delete iMantissa;
+ iMantissa = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// TPOCMarker::TPOCMarker
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TPOCMarker::TPOCMarker():
+ iRSpoc(1),
+ iCSpoc(1),
+ iLYEpoc(1),
+ iREpoc(1),
+ iCEpoc(1),
+ iPpoc(1)
+ {
+ }
+
+// Destructor
+TPOCMarker::~TPOCMarker()
+ {
+ iRSpoc.Close();
+ iCSpoc.Close();
+ iLYEpoc.Close();
+ iREpoc.Close();
+ iCEpoc.Close();
+ iPpoc.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// TPPMMarker::TPPMMarker
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TPPMMarker::TPPMMarker():
+ iZppm(0),
+ iRemainder(0),
+ iNppm(1),
+ iIppm(0)
+ {
+ }
+
+// Destructor
+TPPMMarker::~TPPMMarker()
+ {
+ delete iIppm;
+ iIppm = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// TTLMMarker::TTLMMarker
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TTLMMarker::TTLMMarker() :
+ iZtlm(0),
+ iStlm(0),
+ iTtlm(1),
+ iPtlm(1)
+ {
+ }
+
+// Destructor
+TTLMMarker::~TTLMMarker()
+ {
+ iTtlm.Close();
+ iPtlm.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// TPLMMarker::TPLMMarker
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TPLMMarker::TPLMMarker() :
+ iZplm(0),
+ iNplm(1),
+ iIplm(0)
+ {
+ }
+
+// Destructor
+TPLMMarker::~TPLMMarker()
+ {
+ delete iIplm;
+ iIplm = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// TPPTMarker::TPPTMarker
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TPPTMarker::TPPTMarker():
+ iZppt(0),
+ iIppt(0)
+ {
+ }
+
+// Destructor
+TPPTMarker::~TPPTMarker()
+ {
+ delete iIppt;
+ iIppt = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// TPLTMarker::TPLTMarker
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TPLTMarker::TPLTMarker() :
+ iZplt(0),
+ iIplt(1)
+ {
+ }
+
+// Destructor
+TPLTMarker::~TPLTMarker()
+ {
+ iIplt.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// TCRGMarker::TCRGMarker
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TCRGMarker::TCRGMarker() :
+ iXYcrg(1)
+ {
+ }
+
+// Destructor
+TCRGMarker::~TCRGMarker()
+ {
+ iXYcrg.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// TCOMMarker::TCOMMarker
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TCOMMarker::TCOMMarker() :
+ iRemainder(0),
+ iRcom(0),
+ iCcom(0)
+ {
+ }
+
+// Destructor
+TCOMMarker::~TCOMMarker()
+ {
+ delete iCcom;
+ iCcom = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// TMainMarker::TMainMarker
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TMainMarker::TMainMarker():
+ iCod(),
+ iQcd(),
+ iCoc(3),
+ iQcc(3),
+ iRgn(1),
+ iPoc(0),
+ iPpm(1),
+ iTlm(1),
+ iPlm(1),
+ iCrg(0),
+ iCom(1)
+ {
+ }
+
+// Destructor
+TMainMarker::~TMainMarker()
+ {
+ iCoc.ResetAndDestroy();
+ iQcc.ResetAndDestroy();
+ iRgn.ResetAndDestroy();
+
+ delete iPoc;
+ iPoc = 0;
+
+ iPpm.ResetAndDestroy();
+ iTlm.ResetAndDestroy();
+ iPlm.ResetAndDestroy();
+
+ delete iCrg;
+ iCrg = 0;
+
+ iCom.ResetAndDestroy();
+ }
+
+// -----------------------------------------------------------------------------
+// TTileMarker::TTileMarker
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+TTileMarker::TTileMarker():
+ iCod(0),
+ iQcd(0),
+ iCoc(3),
+ iQcc(3),
+ iRgn(1),
+ iPoc(0),
+ iPpt(1),
+ iPlt(1),
+ iCom(1)
+ {
+ }
+
+// Destructor
+TTileMarker::~TTileMarker()
+ {
+ delete iCod;
+ iCod = 0;
+
+ delete iQcd;
+ iQcd = 0;
+
+ iCoc.ResetAndDestroy();
+ iQcc.ResetAndDestroy();
+ iRgn.ResetAndDestroy();
+
+ delete iPoc;
+ iPoc =0;
+
+ iPpt.ResetAndDestroy();
+ iPlt.ResetAndDestroy();
+ iCom.ResetAndDestroy();
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Src/JP2KPacket.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,1430 @@
+/*
+* Copyright (c) 2003, 2004 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: JP2KPacket class used to collect packet related
+* information such as tag tree and list of codeblocks.
+*
+*/
+
+
+// INCLUDE FILES
+#include <icl/imagecodec.h>
+#include "JP2KImageUtils.h"
+#include "JP2KStreamReader.h"
+#include "JP2KTileInfo.h"
+#include "JP2KImageInfo.h"
+#include "JP2KCodeBlock.h"
+#include "JP2KPacket.h"
+#include "JP2KSubband.h"
+#include "JP2KComponentInfo.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::CJ2kPacket
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CJ2kPacket::CJ2kPacket( TUint16 aLayer ) :
+ iTagTreeLevel(1),
+ iLayer(aLayer),
+ iCodeBlockList(1)
+ {
+ }
+
+// Destructor
+CJ2kPacket::~CJ2kPacket()
+ {
+ delete iIncluded;
+ iIncluded = 0;
+
+ delete iTagTreeInfo;
+ iTagTreeInfo = 0;
+
+ delete iIncTagTreeValue;
+ iIncTagTreeValue = 0;
+
+ delete iIncTagTreeState;
+ iIncTagTreeState = 0;
+
+ delete iMsbTagTreeValue;
+ iMsbTagTreeValue = 0;
+
+ delete iMsbTagTreeState;
+ iMsbTagTreeState = 0;
+
+ iCodeBlockList.ResetAndDestroy();
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::SetPacketCanvas
+// Set the canvas of the packet
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::SetPacketCanvas( TInt32 aX, TInt32 aY, TInt32 aWidth, TInt32 aHeight )
+ {
+ iPacketCanvas.iTl = TPoint( aX, aY );
+ iPacketCanvas.SetWidth( aWidth );
+ iPacketCanvas.SetHeight( aHeight );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::SetNumOfBlocks
+// Set the number of blocks
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::SetNumOfBlocks( TSize& aCodeBlock )
+ {
+ TInt32 x0 = TJ2kUtils::Floor( iPacketCanvas.iTl.iX, aCodeBlock.iWidth ) * aCodeBlock.iWidth;
+ TInt32 y0 = TJ2kUtils::Floor( iPacketCanvas.iTl.iY, aCodeBlock.iHeight ) * aCodeBlock.iHeight;
+ TInt32 x1 = TJ2kUtils::Ceil( iPacketCanvas.iTl.iX + iPacketCanvas.Width(), aCodeBlock.iWidth ) * aCodeBlock.iWidth;
+ TInt32 y1 = TJ2kUtils::Ceil( iPacketCanvas.iTl.iY + iPacketCanvas.Height(), aCodeBlock.iHeight ) * aCodeBlock.iHeight;
+ iCodeBlockSize.iWidth = ( x1 - x0 ) / aCodeBlock.iWidth;
+ iCodeBlockSize.iHeight = ( y1 - y0 ) / aCodeBlock.iHeight;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::BuildInclusiveInfoL
+// Build the inclusive information of the packet
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::BuildInclusiveInfoL()
+ {
+ TInt entries = ( iLayer % 8 ) ? ( ( iLayer / 8 ) + 1 ) : ( iLayer / 8 );
+ iIncluded = HBufC8::NewMaxL( entries );
+ iIncluded->Des().FillZ();
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::BuildCodeBlocksL
+// Build the codeblocks in the packet
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::BuildCodeBlocksL( TInt32 aX, TInt32 aY, TSize& aCodeBlock )
+ {
+ TUint16 numOfBlocks = NumOfBlocks();
+
+ if ( numOfBlocks )
+ {
+ BuildTagtreeL();
+
+ TInt32 x0 = 0;
+ TInt32 y0 = 0;
+ TInt32 x1 = 0;
+ TInt32 y1 = 0;
+ TInt32 origX = aX;
+ TUint16 index = 0;
+
+ while ( index < numOfBlocks )
+ {
+ x0 = Max( aX, iPacketCanvas.iTl.iX );
+ y0 = Max( aY, iPacketCanvas.iTl.iY );
+ x1 = Min( aX + aCodeBlock.iWidth, iPacketCanvas.iTl.iX + iPacketCanvas.Width() ) - x0;
+ y1 = Min( aY + aCodeBlock.iHeight, iPacketCanvas.iTl.iY + iPacketCanvas.Height() ) - y0;
+ if ( x1 > 0 && y1 > 0 )
+ {
+ CJ2kCodeBlock *block = new ( ELeave ) CJ2kCodeBlock;
+ CleanupStack::PushL( block );
+ User::LeaveIfError( iCodeBlockList.Append( block ) );
+ CleanupStack::Pop( 1 );
+ iCodeBlockList[index]->SetCodeBlockCanvas( x0, y0, x1, y1 );
+
+ // Initialize the codeblock
+ iCodeBlockList[index]->InitializeL( iLayer );
+ ++index;
+ }
+
+ aX += aCodeBlock.iWidth;
+ if ( aX >= iPacketCanvas.iTl.iX + iPacketCanvas.Width() )
+ {
+ aX = origX;
+ aY += aCodeBlock.iHeight;
+ }
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ReadPacketHeaderL
+// Read the packet header
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::ReadPacketHeaderL( CJ2kTileInfo& aTile, CJ2kComponentInfo& aComponent, CJ2kSubband& aSubband )
+ {
+ if ( IsIncludedL( aTile.LastLayerProcessed() ) )
+ {
+ return EFalse;
+ }
+
+ TUint8 incomplete = ETrue;
+ if ( LastCodeBlockProcessed() == 0 )
+ {
+ if ( ReadSOP_EPHMarker( aComponent, aTile ) )
+ {
+ return incomplete;
+ }
+ }
+
+ TJ2kStreamReader& reader = CONST_CAST( TJ2kStreamReader&, aTile.StreamReader() );
+ TUint8 *rollbackPtr = CONST_CAST( TUint8*, reader.iPtr );
+
+ if ( !StartReadBit( aTile ) )
+ {
+ TUint8 bit = 0;
+
+ if ( LastCodeBlockProcessed() == 0 )
+ {
+ if ( !IsRecoverFromIncomplete() )
+ {
+ ReadBit( bit, aTile );
+ if ( bit == 0 )
+ {
+ // Empty packet
+ incomplete = EFalse;
+ }
+ }
+ }
+
+ if ( incomplete )
+ {
+ // Packet header has not been processed yet
+ if ( !IsHeader() )
+ {
+ TUint8 isBackup = IsBackupNeeded( aTile );
+
+ CJ2kSubband *subband = &aSubband;
+ if ( subband->SubbandResLevel() > 0 )
+ {
+ if ( subband->LastSubbandProcessed() == CJ2kSubband::EBandLL )
+ {
+ subband->SetLastSubbandProcessed( CJ2kSubband::EBandHL );
+ }
+ else
+ {
+ // Move to last subband processed
+ while ( subband->SubbandType() != aSubband.LastSubbandProcessed() )
+ {
+ subband = subband->NextSubbandRaster();
+ }
+ }
+ }
+
+ TUint16 bandIndex = 0;
+ TUint16 cbIndex = 0;
+ TUint16 cbYIndex = 0;
+ TUint16 xIndex = 0;
+ TUint16 yIndex = 0;
+ TUint16 incValue = 0;
+ TUint16 msbValue = 0;
+ TUint16 index = 0;
+ TUint16 layer = aTile.LastLayerProcessed();
+ TUint16 numPass = 0;
+ TUint16 codePass = 0;
+ TUint16 numSegment = 0;
+ TUint8 recoverIncTag = 0;
+ TUint8 recoverMsbTag = 0;
+ TUint8 firstRecovery = ETrue;
+ TUint8 recoverData = 0;
+ TUint8 recoverPos = 0;
+ TUint8 recoverNextPos = 0;
+ TUint8 origPassIndex = 0;
+ TUint8 origLengthBits = 0;
+ TInt8 origLastPass = 0;
+ TUint32 origDataLength = 0;
+
+ HBufC16 *recoverIncTagTreeValue = 0;
+ HBufC16 *recoverIncTagTreeState = 0;
+ HBufC16 *recoverMsbTagTreeValue = 0;
+ HBufC16 *recoverMsbTagTreeState = 0;
+
+ if ( IsRecoverFromIncomplete() )
+ {
+ recoverData = reader.iData;
+ recoverPos = reader.iPos;
+ recoverNextPos = reader.iNextPos;
+ }
+
+ CJ2kPacket *packet = CONST_CAST( CJ2kPacket*, &subband->PacketAt( aSubband.LastPacketProcessed() ) );
+ CJ2kCodeBlock *codeBlock;
+ incomplete = EFalse;
+ do
+ {
+ if ( aComponent.QuantizationStyle() != 1 )
+ {
+ bandIndex = subband->SubbandTreeIndex();
+ }
+
+ for ( yIndex = 0; yIndex < packet->NumOfBlocksY(); ++yIndex )
+ {
+ cbYIndex = (TUint16)( yIndex * packet->NumOfBlocksX() );
+ for ( xIndex = 0; xIndex < packet->NumOfBlocksX(); ++xIndex )
+ {
+ cbIndex = (TUint16)( cbYIndex + xIndex );
+ if ( cbIndex < packet->LastCodeBlockProcessed() ||
+ ( packet->IsMatch() && cbIndex == packet->LastCodeBlockProcessed() ) )
+ {
+ // Has been processed, skip to the next codeblock
+ continue; //lint !e960 Using continue saves a lot of code here.
+ }
+ else
+ {
+ packet->ResetMatch();
+ recoverIncTag = recoverMsbTag = EFalse;
+ codeBlock = CONST_CAST( CJ2kCodeBlock*, &packet->CodeBlockAt( cbIndex ) );
+
+ TPtr16 numSegPtr = codeBlock->iNumSegment->Des();
+
+ origPassIndex = codeBlock->iPassIndex;
+ origLastPass = codeBlock->iLastPass;
+ if ( codeBlock->iLastPass < 0 && codeBlock->iPassIndex == 0 )
+ {
+ if ( isBackup )
+ {
+ packet->BackupIncTagtreeL( recoverIncTagTreeValue, recoverIncTagTreeState );
+ recoverIncTag = ETrue;
+ }
+ msbValue = (TUint16)0;
+ incomplete = packet->DecodeIncTagtree( aTile, xIndex, yIndex, incValue );
+ if ( !incomplete )
+ {
+ if ( incValue <= layer )
+ {
+ if ( isBackup )
+ {
+ packet->BackupMsbTagtreeL( recoverMsbTagTreeValue, recoverMsbTagTreeState );
+ recoverMsbTag = ETrue;
+ }
+ incomplete = packet->DecodeMsbTagtree( aTile, xIndex, yIndex, msbValue );
+ }
+ else
+ {
+ packet->SetLastCodeBlockProcessed( cbIndex );
+ firstRecovery = EFalse;
+ recoverData = reader.iData;
+ recoverPos = reader.iPos;
+ recoverNextPos = reader.iNextPos;
+ recoverIncTag = recoverMsbTag = EFalse;
+ rollbackPtr = CONST_CAST( TUint8*, reader.iPtr );
+
+ // Move on to the next codeblock
+ continue; //lint !e960 Using continue saves a lot of code here.
+ }
+ }
+
+ if ( incomplete )
+ {
+ // Underflow, should backup the iterator position
+ if ( cbIndex > packet->LastCodeBlockProcessed() )
+ {
+ // Next read should match the codeblock index
+ packet->SetMatch();
+ }
+
+ if ( !firstRecovery )
+ {
+ SetRecoverFromIncomplete();
+ reader.iData = recoverData;
+ reader.iPos = recoverPos;
+ reader.iNextPos = recoverNextPos;
+ }
+ else
+ {
+ if ( IsRecoverFromIncomplete() )
+ {
+ reader.iData = recoverData;
+ reader.iPos = recoverPos;
+ reader.iNextPos = recoverNextPos;
+ }
+ }
+
+ if ( isBackup )
+ {
+ if ( recoverIncTag )
+ {
+ packet->RestoreIncTagtree( recoverIncTagTreeValue, recoverIncTagTreeState );
+ }
+ if ( recoverMsbTag )
+ {
+ packet->RestoreMsbTagtree( recoverMsbTagTreeValue, recoverMsbTagTreeState );
+ }
+ // Release memory
+ packet->FreeBackupTagtree( recoverIncTagTreeValue, recoverIncTagTreeState,
+ recoverMsbTagTreeValue, recoverMsbTagTreeState );
+ }
+ reader.iPtr = rollbackPtr;
+
+ // Return from the packet header decoding
+ return incomplete;
+ }
+
+ codeBlock->iLastPass = 0;
+ numSegPtr[layer] = 1;
+
+ codeBlock->iEmptyBitplane = (TUint8)msbValue;
+
+ if ( aComponent.RoiShift() > 0 )
+ {
+ numPass = (TUint16)( ( aComponent.MagnitudeBits( bandIndex ) + aComponent.RoiShift() ) * 3 + 1 );
+ }
+ else
+ {
+ numPass = (TUint16)( ( aComponent.MagnitudeBits( bandIndex ) - msbValue ) * 3 + 1 );
+ }
+
+ if ( codeBlock->iDataSize == 0 || codeBlock->iDataSize->Length() < numPass )
+ {
+ if ( codeBlock->iDataSize == 0 )
+ {
+ codeBlock->iDataSize = HBufC16::NewMaxL( numPass );
+ codeBlock->iDataSize->Des().FillZ();
+ codeBlock->iPassesPerSegment = HBufC16::NewMaxL( numPass );
+ codeBlock->iPassesPerSegment->Des().FillZ();
+ }
+ else
+ {
+ incValue = ( TUint16 )( numPass - codeBlock->iDataSize->Length() );
+ codeBlock->iDataSize = codeBlock->iDataSize->ReAllocL( numPass );
+ codeBlock->iPassesPerSegment = codeBlock->iPassesPerSegment->ReAllocL( numPass );
+ while ( incValue-- )
+ {
+ codeBlock->iDataSize->Des().Append( 0 );
+ codeBlock->iPassesPerSegment->Des().Append( 0 );
+ }
+ }
+ }
+ }
+ else
+ {
+ incomplete = ReadBit( bit, aTile );
+ if ( incomplete )
+ {
+ // Underflow, should backup the iterator position
+ if ( cbIndex > packet->LastCodeBlockProcessed() )
+ {
+ // Next read should match the codeblock index
+ packet->SetMatch();
+ }
+
+ if ( !firstRecovery )
+ {
+ SetRecoverFromIncomplete();
+ reader.iData = recoverData;
+ reader.iPos = recoverPos;
+ reader.iNextPos = recoverNextPos;
+ }
+ else
+ {
+ if ( IsRecoverFromIncomplete() )
+ {
+ reader.iData = recoverData;
+ reader.iPos = recoverPos;
+ reader.iNextPos = recoverNextPos;
+ }
+ }
+
+ if ( isBackup )
+ {
+ // Release memory
+ packet->FreeBackupTagtree( recoverIncTagTreeValue, recoverIncTagTreeState,
+ recoverMsbTagTreeValue, recoverMsbTagTreeState );
+ }
+ reader.iPtr = rollbackPtr;
+
+ // Return from the packet header decoding
+ return incomplete;
+ }
+
+ numSegPtr[layer] = bit;
+
+ if ( bit == 0 )
+ {
+ packet->SetLastCodeBlockProcessed( cbIndex );
+ firstRecovery = EFalse;
+ recoverData = reader.iData;
+ recoverPos = reader.iPos;
+ recoverNextPos = reader.iNextPos;
+ recoverIncTag = recoverMsbTag = EFalse;
+ rollbackPtr = CONST_CAST( TUint8*, reader.iPtr );
+
+ // Move on to the next codeblock
+ continue; //lint !e960 Using continue saves a lot of code here.
+ }
+ }
+
+ incomplete = ReadBit( bit, aTile );
+ codePass = (TUint16)0;
+ if ( !incomplete )
+ {
+ if ( bit ) // 1
+ {
+ incomplete = ReadBit( bit, aTile );
+ if ( !incomplete )
+ {
+ if ( bit ) // 11
+ {
+ incomplete = ReadBits( bit, 2, aTile );
+ if ( !incomplete )
+ {
+ if ( bit == 0x03 ) // 1111
+ {
+ incomplete = ReadBits( bit, 5, aTile );
+ if ( !incomplete )
+ {
+ if ( bit == 0x1f ) // 1111 11111
+ {
+ incomplete = ReadBits( bit, 7, aTile );
+ if ( !incomplete )
+ {
+ codePass = (TUint16)( 0x25 + bit );
+ }
+ }
+ else
+ {
+ // 1111 XXXXX, at least one of them is not 1
+ codePass = (TUint16)( 6 + bit );
+ }
+ }
+ }
+ else
+ {
+ // 11XX
+ codePass = (TUint16)( 3 + bit );
+ }
+ }
+ }
+ else
+ {
+ // 10
+ codePass = 2;
+ }
+ }
+ }
+ else
+ {
+ // 0
+ codePass = 1;
+ }
+ }
+
+ if ( incomplete )
+ {
+ // Underflow, restore the original codeblock information
+ codeBlock->iPassIndex = origPassIndex;
+ codeBlock->iLastPass = origLastPass;
+
+ // Underflow, should backup the iterator position
+ if ( cbIndex > packet->LastCodeBlockProcessed() )
+ {
+ // Next read should match the codeblock index
+ packet->SetMatch();
+ }
+
+ if ( !firstRecovery )
+ {
+ SetRecoverFromIncomplete();
+ reader.iData = recoverData;
+ reader.iPos = recoverPos;
+ reader.iNextPos = recoverNextPos;
+ }
+ else
+ {
+ if ( IsRecoverFromIncomplete() )
+ {
+ reader.iData = recoverData;
+ reader.iPos = recoverPos;
+ reader.iNextPos = recoverNextPos;
+ }
+ }
+
+ if ( isBackup )
+ {
+ if ( recoverIncTag )
+ {
+ packet->RestoreIncTagtree( recoverIncTagTreeValue,
+ recoverIncTagTreeState );
+ }
+ if ( recoverMsbTag )
+ {
+ packet->RestoreMsbTagtree( recoverMsbTagTreeValue,
+ recoverMsbTagTreeState );
+ }
+ // Release memory
+ packet->FreeBackupTagtree( recoverIncTagTreeValue, recoverIncTagTreeState,
+ recoverMsbTagTreeValue, recoverMsbTagTreeState );
+ }
+ reader.iPtr = rollbackPtr;
+
+ // Return from the packet header decoding
+ return incomplete;
+ }
+
+ if ( codeBlock->iPassIndex == 0 )
+ {
+ codeBlock->iLastPass = -1;
+ }
+
+ numSegment = 1;
+
+ if ( aComponent.IsTermination() )
+ {
+ numSegment = codePass;
+ }
+ else if ( aComponent.IsACByPass() )
+ {
+ if ( ( codeBlock->iLastPass + codePass ) >= KFirstLazyPassIndex )
+ {
+ for ( index = 1; index < codePass; ++index )
+ {
+ if ( ( index + codeBlock->iLastPass ) >= KFirstLazyPassIndex )
+ {
+ if ( ( ( index + codeBlock->iLastPass ) % 3 ) != 1 )
+ {
+ ++numSegment;
+ }
+ }
+ }
+ }
+ }
+
+ numSegPtr[layer] = numSegment; //lint !e961 no else is needed here at the end of if...else if
+
+ origLengthBits = codeBlock->iLengthBits;
+ origDataLength = codeBlock->iDataLength;
+ incomplete = ReadBit( bit, aTile );
+ if ( !incomplete )
+ {
+ // Skip all 1 bits
+ while ( bit )
+ {
+ ++codeBlock->iLengthBits;
+ incomplete = ReadBit( bit, aTile );
+ if ( incomplete )
+ {
+ // Underflow
+ // Set bit to zero to break from the while-loop
+ bit = 0;
+ }
+ }
+ }
+
+ if ( !incomplete )
+ {
+ TUint8 bits = 0;
+ TUint32 tmpBits = 0;
+ TPtr16 numPassesPerSegPtr = codeBlock->iPassesPerSegment->Des();
+ TPtr16 numDataSizePtr = codeBlock->iDataSize->Des();
+
+ if ( numSegment == 1 )
+ {
+ bits = (TUint8)( codeBlock->iLengthBits + TJ2kUtils::Log2( codePass ) );
+
+ incomplete = ReadBits( tmpBits, bits, aTile );
+ if ( !incomplete )
+ {
+ numPassesPerSegPtr[codeBlock->iPassIndex] = codePass;
+ numDataSizePtr[codeBlock->iPassIndex++] = (TUint16)tmpBits;
+
+ codeBlock->iDataLength += tmpBits;
+ codeBlock->iLastPass = (TUint8)( codeBlock->iLastPass + codePass );
+ if ( tmpBits > 0 )
+ {
+ SetBodyIncomplete();
+ }
+ }
+ }
+ else
+ {
+ TUint16 totalCodePass = codePass;
+ TUint16 tmpCodePass;
+ for ( index = 0; index < numSegment; ++index )
+ {
+ if ( aComponent.IsTermination() )
+ {
+ tmpCodePass = 1;
+ }
+ else
+ {
+ if ( codeBlock->iLastPass < KFirstLazyPassIndex )
+ {
+ tmpCodePass = (TUint16)( KFirstLazyPassIndex - ( TInt )codeBlock->iLastPass );
+ }
+ else
+ {
+ tmpCodePass = (TUint16)( ( codeBlock->iLastPass % 3 ) ? 1 : ( ( totalCodePass > 1 ) ? 2 : 1 ) );
+ }
+ }
+ bits = (TUint8)( codeBlock->iLengthBits + TJ2kUtils::Log2( tmpCodePass ) );
+ incomplete = ReadBits( tmpBits, bits, aTile );
+ if ( !incomplete )
+ {
+ numPassesPerSegPtr[codeBlock->iPassIndex] = tmpCodePass;
+ numDataSizePtr[codeBlock->iPassIndex++] = (TUint16)tmpBits;
+
+ codeBlock->iDataLength += tmpBits;
+ codeBlock->iLastPass = (TUint8)( codeBlock->iLastPass + tmpCodePass );
+ totalCodePass = (TUint16)( totalCodePass - tmpCodePass );
+ if ( tmpBits > 0 )
+ {
+ SetBodyIncomplete();
+ }
+ }
+ else
+ {
+ index = numSegment; // break from the for-loop
+ }
+ }
+ }
+ }
+
+ if ( incomplete )
+ {
+ // Underflow, restore the original codeblock information
+ codeBlock->iPassIndex = origPassIndex;
+ codeBlock->iLastPass = origLastPass;
+ codeBlock->iLengthBits = origLengthBits;
+ codeBlock->iDataLength = origDataLength;
+
+ // Underflow, should backup the iterator position
+ if ( cbIndex > packet->LastCodeBlockProcessed() )
+ {
+ // Next read should match the codeblock index
+ packet->SetMatch();
+ }
+
+ if ( !firstRecovery )
+ {
+ SetRecoverFromIncomplete();
+ reader.iData = recoverData;
+ reader.iPos = recoverPos;
+ reader.iNextPos = recoverNextPos;
+ }
+ else
+ {
+ if ( IsRecoverFromIncomplete() )
+ {
+ reader.iData = recoverData;
+ reader.iPos = recoverPos;
+ reader.iNextPos = recoverNextPos;
+ }
+ }
+
+ if ( isBackup )
+ {
+ if ( recoverIncTag )
+ {
+ packet->RestoreIncTagtree( recoverIncTagTreeValue,
+ recoverIncTagTreeState );
+ }
+ if ( recoverMsbTag )
+ {
+ packet->RestoreMsbTagtree( recoverMsbTagTreeValue,
+ recoverMsbTagTreeState );
+ }
+
+ // Release memory
+ packet->FreeBackupTagtree( recoverIncTagTreeValue,
+ recoverIncTagTreeState,
+ recoverMsbTagTreeValue,
+ recoverMsbTagTreeState );
+ }
+ reader.iPtr = rollbackPtr;
+
+ // Return from the packet header decoding
+ return incomplete;
+ }
+
+ }
+
+ packet->SetLastCodeBlockProcessed( cbIndex );
+ firstRecovery = EFalse;
+ recoverData = reader.iData;
+ recoverPos = reader.iPos;
+ recoverNextPos = reader.iNextPos;
+ recoverIncTag = recoverMsbTag = EFalse;
+ rollbackPtr = CONST_CAST( TUint8*, reader.iPtr );
+ } // end of xIndex
+ } // end of yIndex
+
+ packet->SetLastCodeBlockProcessed( 0 );
+ packet->ResetMatch();
+ ResetRecoverFromIncomplete();
+ subband = subband->NextSubbandRaster();
+ if ( subband )
+ {
+ if ( isBackup )
+ {
+ // Sibling may have different tag tree level, so release memory here
+ packet->FreeBackupTagtree( recoverIncTagTreeValue, recoverIncTagTreeState,
+ recoverMsbTagTreeValue, recoverMsbTagTreeState );
+ }
+ packet = CONST_CAST( CJ2kPacket*, &subband->PacketAt( aSubband.LastPacketProcessed() ) );
+ aSubband.SetLastSubbandProcessed( (TUint8)subband->SubbandType() );
+ }
+
+ } while ( subband );
+
+ if ( !incomplete )
+ {
+ // Packet header has been completely processed
+ SetHeader();
+ SetIncluded( aTile.LastLayerProcessed() );
+ AlignReader( aTile );
+ aSubband.SetLastSubbandProcessed( CJ2kSubband::EBandLL );
+ }
+ if ( isBackup )
+ {
+ // Release memory
+ packet->FreeBackupTagtree( recoverIncTagTreeValue, recoverIncTagTreeState,
+ recoverMsbTagTreeValue, recoverMsbTagTreeState );
+ }
+ }
+ else
+ {
+ // Packet has been processed
+ reader.iPtr = rollbackPtr;
+ }
+ }
+
+ if ( !incomplete )
+ {
+ if ( aComponent.IsEPHMarkerUsed() )
+ {
+ ReadEPHMarker( aTile );
+ }
+ }
+ }
+ return incomplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ReadPacketBodyL
+// Read the packet body
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::ReadPacketBodyL( CJ2kTileInfo& aTile, CJ2kComponentInfo& aComponent, CJ2kSubband& aSubband )
+ {
+ TUint8 incomplete = EFalse;
+ if ( LastCodeBlockProcessed() == 0 )
+ {
+ if ( ReadSOP_EPHMarker( aComponent, aTile, EFalse ) )
+ {
+ return ETrue;
+ }
+ }
+
+ TJ2kStreamReader& reader = CONST_CAST( TJ2kStreamReader&, aTile.StreamReader() );
+
+ // Packet body has not been processed yet
+ if ( !IsBody() )
+ {
+ SetBodyIncomplete();
+
+ CJ2kSubband *subband = &aSubband;
+ if ( subband->SubbandResLevel() > 0 )
+ {
+ if ( subband->LastSubbandProcessed() == CJ2kSubband::EBandLL )
+ {
+ subband->SetLastSubbandProcessed( CJ2kSubband::EBandHL );
+ }
+ else
+ {
+ // Move to last subband processed
+ while ( subband->SubbandType() != aSubband.LastSubbandProcessed() )
+ {
+ subband = subband->NextSubbandRaster();
+ }
+ }
+ }
+ TUint16 xIndex = 0;
+ TUint16 yIndex = 0;
+ TUint16 cbIndex = 0;
+ TUint16 cbYIndex = 0;
+ TUint16 index = 0;
+ TUint16 cblkLength = 0;
+ TUint16 layer = aTile.LastLayerProcessed();
+ TInt32 totalLength = 0;
+ TUint8 *rollbackPtr = CONST_CAST( TUint8*, reader.iPtr );
+
+ CJ2kPacket *packet = CONST_CAST( CJ2kPacket*, &subband->PacketAt( aSubband.LastPacketProcessed() ) );
+ CJ2kCodeBlock *codeBlock = 0;
+ do
+ {
+
+ for ( yIndex = 0; yIndex < packet->NumOfBlocksY(); ++yIndex )
+ {
+ cbYIndex = (TUint16)( yIndex * packet->NumOfBlocksX() );
+ for ( xIndex = 0; xIndex < packet->NumOfBlocksX(); ++xIndex )
+ {
+ cbIndex = (TUint16)( cbYIndex + xIndex );
+ if ( cbIndex < packet->LastCodeBlockProcessed() ||
+ ( packet->IsMatch() && cbIndex == packet->LastCodeBlockProcessed() ) )
+ {
+ // Has been processed, skip to the next codeblock
+ continue; //lint !e960 Using continue saves a lot of code here.
+ }
+ else
+ {
+ packet->ResetMatch();
+ codeBlock = CONST_CAST( CJ2kCodeBlock*, &packet->CodeBlockAt( cbIndex ) );
+
+ if ( ( *codeBlock->iNumSegment )[layer] > 0 )
+ {
+ TUint tempLength = 0;
+ TUint8 skip = 0;
+
+ if ( !aTile.IsSpeedup() )
+ {
+ // If this resolution level is not required in decoding, skip storing the data to save memory
+ if ( aTile.LastLevelProcessed() > (TUint8)( aTile.NumOfLevelsPOC() - aTile.ImageInfo().LevelDrop() ) )
+ skip = 1;
+ }
+
+ tempLength = codeBlock->iDataLength;
+
+ if ( tempLength )
+ {
+ // Find out which segment has been processed
+ totalLength = codeBlock->iDataLength - tempLength;
+ {
+ for ( index = 1; index <= ( *codeBlock->iNumSegment )[layer]; ++index )
+ {
+ totalLength -= ( *codeBlock->iDataSize )[codeBlock->iPassIndex - index];
+ if ( totalLength <= 0 )
+ {
+ break; //lint !e960 break usage saves code here.
+ }
+ }
+ }
+ }
+ else
+ {
+ index = ( *codeBlock->iNumSegment )[layer];
+ }
+
+ for ( ; index > 0; --index )
+ {
+ cblkLength = ( *codeBlock->iDataSize )[codeBlock->iPassIndex - index];
+ if ( ( reader.iPtrEnd - reader.iPtr ) < cblkLength )
+ {
+ // Underflow, rollback the iterator position
+ reader.iPtr = rollbackPtr;
+ incomplete = ETrue;
+ if ( cbIndex > packet->LastCodeBlockProcessed() )
+ {
+ // Next read should match the codeblock index
+ packet->SetMatch();
+ }
+
+ return incomplete;
+ }
+ else
+ {
+
+ // Store data only if the resolution level is not skipped
+ if( !skip )
+ {
+ TPtr8 data = codeBlock->DataL()->Des();
+ data.Append( reader.iPtr, cblkLength );
+ }
+
+ reader.iPtr += cblkLength;
+ }
+ // Save the iterator position
+ rollbackPtr = CONST_CAST( TUint8*, reader.iPtr );
+ }
+ }
+ }
+ packet->SetLastCodeBlockProcessed( cbIndex );
+
+ // Save the iterator position
+ rollbackPtr = CONST_CAST( TUint8*, reader.iPtr );
+ } // end of xIndex
+ } // end of yIndex
+
+ packet->SetLastCodeBlockProcessed( 0 );
+ packet->ResetMatch();
+ subband = subband->NextSubbandRaster();
+ if ( subband )
+ {
+ packet = CONST_CAST( CJ2kPacket*, &subband->PacketAt( aSubband.LastPacketProcessed() ) );
+ aSubband.SetLastSubbandProcessed( (TUint8)subband->SubbandType() );
+ }
+
+ } while ( subband );
+
+ SetBody();
+ ResetBodyIncomplete();
+ aSubband.SetLastSubbandProcessed( CJ2kSubband::EBandLL );
+ }
+
+ return incomplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ResetInternalFlags
+// Reset the internal flags
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::ResetInternalFlags()
+ {
+ ResetHeader();
+ ResetBody();
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::BuildTagtreeL
+// Build the tag tree
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::BuildTagtreeL()
+ {
+ TUint32 width = iCodeBlockSize.iWidth;
+ TUint32 height = iCodeBlockSize.iHeight;
+
+ while ( width != 1 || height != 1 )
+ {
+ width = ( width + 1 ) >> 1;
+ height = ( height + 1 ) >> 1;
+ ++iTagTreeLevel;
+ }
+
+ TInt size = 0;
+ TInt sizeIndex = 0;
+ width = iCodeBlockSize.iWidth;
+ height = iCodeBlockSize.iHeight;
+
+ iTagTreeInfo = HBufC16::NewMaxL( iTagTreeLevel + 1 );
+ TPtr16 tmpPtr = ( iTagTreeInfo->Des() );
+ tmpPtr[0] = (TUint16)sizeIndex;
+
+ for ( TUint8 index = 0; index < iTagTreeLevel; ++index )
+ {
+ size = width * height;
+ sizeIndex += size;
+ tmpPtr[index + 1] = (TUint16)sizeIndex;
+ }
+
+ TChar fillChar( 0xffff );
+
+ iIncTagTreeValue = HBufC16::NewMaxL( sizeIndex );
+ iIncTagTreeValue->Des().Fill( fillChar, iIncTagTreeValue->Length() );
+ iIncTagTreeState = HBufC16::NewMaxL( sizeIndex );
+ iIncTagTreeState->Des().FillZ();
+
+ iMsbTagTreeValue = HBufC16::NewMaxL( sizeIndex );
+ iMsbTagTreeValue->Des().Fill( fillChar, iIncTagTreeValue->Length() );
+ iMsbTagTreeState = HBufC16::NewMaxL( sizeIndex );
+ iMsbTagTreeState->Des().FillZ();
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::DecodeIncTagtree
+// Decode the included tag tree
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::DecodeIncTagtree( CJ2kTileInfo& aTile, TUint32 aWidth, TUint32 aHeight, TUint16& aValue )
+ {
+ TUint8 bit = 2;
+ TInt16 parentState = 0;
+ TUint8 contCoding = 1;
+ TUint16 idx = 0;
+ TUint16 layer = (TUint16)( aTile.LastLayerProcessed() + 1 );
+
+ for ( TInt16 index = TInt16( iTagTreeLevel - 1 ); index >= 0; --index )
+ {
+ idx = (TUint16)( ( aHeight >> index ) * ( (TUint32)( iCodeBlockSize.iWidth + ( 1 << index ) - 1 ) >> index ) + ( aWidth >> index ) );
+ if ( ( IncTagState( index, idx ) < parentState ) && IncTagValue( index, idx ) == 0xffff )
+ {
+ SetIncTagState( index, idx, (TUint16)( parentState - contCoding ) );
+ }
+
+ while ( contCoding && IncTagState( index, idx ) < layer && IncTagValue( index, idx ) == 0xffff )
+ {
+ if ( ReadBit( bit, aTile ) )
+ {
+ return ETrue;
+ }
+
+ if ( bit == 1 )
+ {
+ SetIncTagValue( index, idx, IncTagState( index, idx ) );
+ }
+ IncrementIncTagState( index, idx );
+ }
+ parentState = IncTagState( index, idx );
+ if ( bit == 0 || IncTagValue( index, idx ) == 0xffff )
+ {
+ contCoding = 0;
+ }
+ }
+ aValue = IncTagValue( 0, idx );
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::DecodeMsbTagtree
+// Decode the msb tag tree
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::DecodeMsbTagtree( CJ2kTileInfo& aTile, TUint32 aWidth, TUint32 aHeight, TUint16& aValue )
+ {
+ TUint8 bit = 2;
+ TInt16 parentState = 0;
+ TUint8 contCoding = 1;
+ TUint16 idx = 0;
+ TUint16 layer = 0xffff;
+
+ for ( TInt16 index = (TUint16)( iTagTreeLevel - 1 ); index >= 0; --index )
+ {
+ idx = (TUint16)( ( aHeight >> index ) * ( (TUint32)( iCodeBlockSize.iWidth + ( 1 << index ) - 1 ) >> index ) + ( aWidth >> index ) );
+
+ if ( ( MsbTagState( index, idx ) < parentState ) && MsbTagValue( index, idx ) == 0xffff )
+ {
+ SetMsbTagState( index, idx, (TUint16)( ( parentState - contCoding ) ) );
+ }
+
+ while ( contCoding && MsbTagState( index, idx ) < layer && MsbTagValue( index, idx ) == 0xffff )
+ {
+ if ( ReadBit( bit, aTile ) )
+ {
+ return ETrue;
+ }
+
+ if ( bit == 1 )
+ {
+ SetMsbTagValue( index, idx, MsbTagState( index, idx ) );
+ }
+ IncrementMsbTagState( index, idx );
+ }
+ parentState = MsbTagState( index, idx );
+ if ( bit == 0 || MsbTagValue( index, idx ) == 0xffff )
+ {
+ contCoding = 0;
+ }
+ }
+ aValue = MsbTagValue( 0, idx );
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::BackupIncTagtreeL
+// Backup the included tag tree
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::BackupIncTagtreeL( HBufC16*& aTagValue, HBufC16*& aTagState )
+ {
+ if ( aTagValue && aTagState )
+ {
+ if ( aTagValue->Des().MaxLength() < iIncTagTreeValue->Length() )
+ {
+ aTagValue = aTagValue->ReAllocL( iIncTagTreeValue->Length() );
+ }
+ if ( aTagState->Des().MaxLength() < iIncTagTreeState->Length() )
+ {
+ aTagState = aTagState->ReAllocL( iIncTagTreeState->Length() );
+ }
+ }
+ else
+ {
+ aTagValue = HBufC16::NewMaxLC( iIncTagTreeValue->Length() );
+ aTagState = HBufC16::NewMaxLC( iIncTagTreeState->Length() );
+ }
+ *aTagValue = *iIncTagTreeValue;
+ *aTagState = *iIncTagTreeState;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::BackupMsbTagtreeL
+// Backup the msb tag tree
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::BackupMsbTagtreeL( HBufC16*& aTagValue, HBufC16*& aTagState )
+ {
+ if ( aTagValue && aTagState )
+ {
+ if ( aTagValue->Des().MaxLength() < iMsbTagTreeValue->Length() )
+ {
+ aTagValue = aTagValue->ReAllocL( iMsbTagTreeValue->Length() );
+ }
+ if ( aTagState->Des().MaxLength() < iMsbTagTreeState->Length() )
+ {
+ aTagState = aTagState->ReAllocL( iMsbTagTreeState->Length() );
+ }
+ }
+ else
+ {
+ aTagValue = HBufC16::NewMaxLC( iMsbTagTreeValue->Length() );
+ aTagState = HBufC16::NewMaxLC( iMsbTagTreeState->Length() );
+ }
+ *aTagValue = *iMsbTagTreeValue;
+ *aTagState = *iMsbTagTreeState;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::RestoreIncTagtree
+// Restore the included tag tree
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::RestoreIncTagtree( HBufC16 *aTagValue, HBufC16 *aTagState )
+ {
+ *iIncTagTreeValue = *aTagValue;
+ *iIncTagTreeState = *aTagState;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::RestoreMsbTagtree
+// Restore the msb tag tree
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::RestoreMsbTagtree( HBufC16 *aTagValue, HBufC16 *aTagState )
+ {
+ *iMsbTagTreeValue = *aTagValue;
+ *iMsbTagTreeState = *aTagState;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::FreeBackupTagtree
+// Release the temporary backup memory
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::FreeBackupTagtree( HBufC16*& aIncTagValue, HBufC16*& aIncTagState,
+ HBufC16*& aMsbTagValue, HBufC16*& aMsbTagState )
+ {
+ TInt count = 0;
+ if ( aIncTagValue )
+ {
+ delete aIncTagValue;
+ aIncTagValue = 0;
+ ++count;
+ }
+ if ( aIncTagState )
+ {
+ delete aIncTagState;
+ aIncTagState = 0;
+ ++count;
+ }
+ if ( aMsbTagValue )
+ {
+ delete aMsbTagValue;
+ aMsbTagValue = 0;
+ ++count;
+ }
+ if ( aMsbTagState )
+ {
+ delete aMsbTagState;
+ aMsbTagState = 0;
+ ++count;
+ }
+ CleanupStack::Pop( count );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::IsIncludedL
+// Is the layer has been included in previous packet
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::IsIncludedL( TUint16 aLayer )
+ {
+ TInt entries = ( iLayer % 8 ) ? ( ( iLayer / 8 ) + 1 ) : ( iLayer / 8 );
+ if ( iIncluded == 0 || iIncluded->Des().MaxLength() < entries )
+ {
+ if ( iIncluded )
+ {
+ TInt diff = entries - iIncluded->Length();
+ iIncluded = iIncluded->ReAllocL( entries );
+ while ( diff-- )
+ {
+ iIncluded->Des().Append( (TUint8)0 );
+ }
+ }
+ else
+ {
+ iIncluded = HBufC8::NewMaxL( entries );
+ iIncluded->Des().FillZ();
+ }
+ }
+ return IncludedAt( aLayer );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::IncludedAt
+// Get the inclusive information at specific layer
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::IncludedAt( TUint16 aLayer ) const
+ {
+ TInt entry = aLayer / 8;
+ TInt bit = aLayer % 8;
+ return (TUint8)( ( iIncluded->Des() )[entry] & ( 0x01 << bit ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::SetIncluded
+// Set the inclusive information at specific layer
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::SetIncluded( TUint16 aLayer )
+ {
+ TInt entry = aLayer / 8;
+ TInt bit = aLayer % 8;
+ TPtr8 tmpPtr = iIncluded->Des();
+ tmpPtr[entry] |= ( 0x01 << bit );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::IsBackupNeeded
+// Is tag tree backup is required for underflow recovery
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::IsBackupNeeded( CJ2kTileInfo& aTile )
+ {
+ return !( aTile.IsPPT() || aTile.ImageInfo().IsPPM() );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::StartReadBit
+// Read a bit from the packet header stream
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::StartReadBit( CJ2kTileInfo& aTile )
+ {
+ return ( !IsRecoverFromIncomplete() ) ?
+ aTile.PacketHeaderReader().StartReadBit() :
+ (TUint8)EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ReadBit
+// Read a bit from the packet header stream
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::ReadBit( TUint8& aBit, CJ2kTileInfo& aTile )
+ {
+ return aTile.PacketHeaderReader().ReadBit( aBit );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ReadBits
+// Read some bits from the packet header stream
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::ReadBits( TUint8& aBit, TUint8 aBitLen, CJ2kTileInfo& aTile )
+ {
+ return aTile.PacketHeaderReader().ReadBits( aBit, aBitLen );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ReadBits
+// Read some bits from the packet header stream
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::ReadBits( TUint32& aBit, TUint8 aBitLen, CJ2kTileInfo& aTile )
+ {
+ return aTile.PacketHeaderReader().ReadBits( aBit, aBitLen );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::AlignReader
+// Align the stream to the next byte boundary if necessary
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::AlignReader( CJ2kTileInfo& aTile )
+ {
+ aTile.PacketHeaderReader().AlignReader();
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ReadSOPMarker
+// Try to consume the SOP marker if there is one
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::ReadSOPMarker( CJ2kTileInfo& aTile )
+ {
+ // SOP may be inside the CodeStream only
+ return CONST_CAST( TJ2kStreamReader&, aTile.StreamReader() ).ReadSOPMarker();
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ReadEPHMarker
+// Try to consume the EPH marker if there is one
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::ReadEPHMarker( CJ2kTileInfo& aTile )
+ {
+ // EPH may be inside PPT or PPM or CodeStream
+ return aTile.PacketHeaderReader().ReadEPHMarker();
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ReadSOP_EPHMarker
+// Try to re-align stream to next byte boundary if necessary,
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::ReadSOP_EPHMarker( CJ2kComponentInfo& aComponent, CJ2kTileInfo& aTile, TBool aSOP )
+ {
+ TJ2kStreamReader& reader = CONST_CAST( TJ2kStreamReader&, aTile.StreamReader() );
+
+ TUint8 incomplete = reader.TryReAlignReader();
+ incomplete = reader.TryReadEPHMarker();
+
+ if ( !incomplete && aSOP && aComponent.IsSOPMarkerUsed() && ( !IsHeader() || !IsBody() ) )
+ {
+ incomplete = ReadSOPMarker( aTile );
+ }
+
+ return incomplete;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Src/JP2KProxy.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,136 @@
+/*
+* Copyright (c) 2003-2006 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: JPEG2000 image encoder/decoder plugin entry point.
+*
+*/
+
+
+// INCLUDE FILES
+#include <ecom/ecom.h>
+#include <ecom/implementationproxy.h>
+#include <icl/imageconstruct.h>
+#include <icl/icl_uids.hrh>
+#include <JP2KUids.hrh>
+#include "JP2KFormat.h"
+#include "JP2KConvert.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// MACROS
+#ifdef __EABI__
+#ifndef IMPLEMENTATION_PROXY_ENTRY
+typedef TAny* TProxyNewLPtr;
+#define IMPLEMENTATION_PROXY_ENTRY(aUid, aFuncPtr) {{aUid},(TProxyNewLPtr)(aFuncPtr)}
+#endif
+#endif
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+/**
+* CJp2kDecodeConstruct class.
+* Implement the entry point for creating JPEG2000 decoder.
+*
+* @lib ?library
+* @since 2.6
+*/
+class CJp2kDecodeConstruct : public CImageDecodeConstruct
+{
+ public:
+
+ /**
+ * Two-phased constructor.
+ */
+ static CJp2kDecodeConstruct* NewL();
+
+ public:
+
+ /**
+ * Instantiates JPEG 2000 plug-in.
+ * @since 2.6
+ * @param None.
+ * @return Pointer to instantiated plug-in.
+ */
+ CImageDecoderPlugin* NewPluginL() const;
+};
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CJp2kDecodeConstruct::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CJp2kDecodeConstruct* CJp2kDecodeConstruct::NewL()
+ {
+ CJp2kDecodeConstruct* self = new ( ELeave ) CJp2kDecodeConstruct;
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecodeConstruct::NewPluginL
+// Creating a new CJp2kDecodeConstruct object.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CImageDecoderPlugin* CJp2kDecodeConstruct::NewPluginL() const
+ {
+ return CJp2kDecoder::NewL();
+ }
+
+// -----------------------------------------------------------------------------
+// Global implementation uid array
+// Define the Implementation UIDs for JP2K decoder.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+const TImplementationProxy ImplementationTable[] =
+{
+ // Decoder recognize two different formats
+ // JP2 file format and JP2 codestream
+ IMPLEMENTATION_PROXY_ENTRY( KJ2KDecoderImplementationUidValueFileFormat,
+ CJp2kDecodeConstruct::NewL ),
+ IMPLEMENTATION_PROXY_ENTRY( KJ2KDecoderImplementationUidValueCodeStream,
+ CJp2kDecodeConstruct::NewL ),
+ IMPLEMENTATION_PROXY_ENTRY( KJ2KDecoderImplementationUid,
+ CJp2kDecodeConstruct::NewL )
+};
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+
+// -----------------------------------------------------------------------------
+// ImplementationGroupProxy Implements proxy interface for ECom
+// Exported proxy for instantiation method resolution.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy( //lint !e714 Used by ECom
+ TInt& aTableCount ) // Number of tables
+ {
+ aTableCount = sizeof( ImplementationTable ) / sizeof( TImplementationProxy );
+ return ImplementationTable;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Src/JP2KStreamReader.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,323 @@
+/*
+* Copyright (c) 2003, 2004 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: TJ2kStreamReader class is to implement the
+* MJ2kPacketHeaderReader interface for reading the
+* packet header and packet body from the stream
+* buffer provided by ICL framework.
+*
+*/
+
+
+// INCLUDE FILES
+#include <icl/imageprocessor.h>
+#include <icl/imagecodec.h>
+#include <icl/imagecodecdata.h>
+#include "JP2KImageUtils.h"
+#include "JP2KFormat.h"
+#include "JP2KStreamReader.h"
+#include "JP2KCodec.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// TJ2kStreamReader::UpdateMainHeader
+// Update the codestream length read and offset of SOT marker
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void TJ2kStreamReader::UpdateMainHeader()
+ {
+ if ( iCSLength )
+ {
+ // Codestream left
+ iCSLength -= ( iPtr - iPtrStartMarker );
+ }
+ iStartSOT += ( iPtr - iPtrStartMarker );
+ }
+
+// -----------------------------------------------------------------------------
+// TJ2kStreamReader::UpdateTileHeader
+// Update the codestream length read and length of data consumed
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void TJ2kStreamReader::UpdateTileHeader()
+ {
+ if ( iCSLength )
+ {
+ // Codestream left
+ iCSLength -= ( iPtr - iPtrStartMarker );
+ }
+ iDataUsed += ( iPtr - iPtrStartMarker );
+ }
+
+// -----------------------------------------------------------------------------
+// TJ2kStreamReader::ReadEPHMarker
+// Try to consume the EPH marker if there is one
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 TJ2kStreamReader::ReadEPHMarker()
+ {
+ if ( ( iPtrEnd - iPtr ) < 2 )
+ {
+ // EPH marker should be tried on next read
+ iTryEPHMarker = ETrue;
+ }
+ else
+ {
+ iTryEPHMarker = EFalse;
+
+ // Try to consume the EPH marker
+ if ( PtrReadUtil::ReadBigEndianUint16( iPtr ) == KEPH )
+ {
+ iPtr += 2;
+ }
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// TJ2kStreamReader::ReadBit
+// Read a bit from the packet header stream.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 TJ2kStreamReader::ReadBit( TUint8& aBit )
+ {
+ if ( iPos == 0 )
+ {
+ if ( iPtr < iPtrEnd )
+ {
+ // Buffer contains some packet header data
+ iData = *iPtr++;
+ iPos = iNextPos;
+ if ( iNextPos == 0x08 && iData == 0xff )
+ {
+ iNextPos = 0x07;
+ }
+ else
+ {
+ iNextPos = 0x08;
+ }
+ }
+ else
+ {
+ // No more data
+ return ETrue;
+ }
+ }
+ aBit = (TUint8)( ( iData >> ( --iPos ) ) & 0x01 );
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// TJ2kStreamReader::ReadBits
+// Read some bits from the packet header stream.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 TJ2kStreamReader::ReadBits( TUint8& aBit, TUint8 aBitLen )
+ {
+ aBit = (TUint8)0;
+ TUint8 bit;
+ for ( TInt8 index = (TInt8)( aBitLen - 1 ); index >= 0; --index )
+ {
+ if ( !ReadBit( bit ) )
+ {
+ aBit |= ( bit << index );
+ }
+ else
+ {
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// TJ2kStreamReader::ReadBits
+// Read some bits from the packet header stream.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 TJ2kStreamReader::ReadBits( TUint32& aBit, TUint8 aBitLen )
+ {
+ aBit = (TUint32)0;
+ TUint8 bit = 0;
+ for ( TInt8 index = ( TInt8 )( aBitLen - 1 ); index >= 0; --index )
+ {
+ if ( !ReadBit( bit ) )
+ {
+ aBit |= ( bit << index );
+ }
+ else
+ {
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// TJ2kStreamReader::StartReadBit
+// Start reading from packet header stream.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 TJ2kStreamReader::StartReadBit()
+ {
+ if ( iAlign )
+ {
+ // Byte alignment is required
+ ++iPtr;
+ iAlign = 0;
+ }
+ if ( iPtr < iPtrEnd )
+ {
+ // Buffer contains some packet header data
+ iData = *iPtr++;
+ iPos = iNextPos = 0x08;
+ if ( iData == 0xff )
+ {
+ iNextPos = 0x07;
+ }
+
+ return EFalse;
+ }
+ return ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// TJ2kStreamReader::AlignReader
+// Align the stream to the next byte boundary if necessary.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void TJ2kStreamReader::AlignReader()
+ {
+ iAlign = 0;
+ if ( iNextPos == 0x07 )
+ {
+ if ( iPtr < iPtrEnd )
+ {
+ ++iPtr;
+ }
+ else
+ {
+ // byte alignment is required on next read
+ iAlign = 1;
+ }
+ }
+ iData = iPos = iNextPos = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// TJ2kStreamReader::ReadSOPMarker
+// Try to consume the SOP marker if there is one
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 TJ2kStreamReader::ReadSOPMarker()
+ {
+ if ( ( iPtrEnd - iPtr ) < 6 )
+ {
+ return ETrue;
+ }
+ else
+ {
+ if ( PtrReadUtil::ReadBigEndianUint16( iPtr ) == KSOP )
+ {
+ iPtr += 2;
+ if ( PtrReadUtil::ReadBigEndianUint16( iPtr ) == KSOP_LEN )
+ {
+ // SOP marker found
+ iPtr += 4;
+ }
+ else
+ {
+ // SOP marker not found, backup the iterator
+ iPtr -= 2;
+ }
+ }
+ return EFalse;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// TJ2kStreamReader::TryReadEPHMarker
+// Try to consume the EPH marker after failure on previous try
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 TJ2kStreamReader::TryReadEPHMarker()
+ {
+ if ( iTryEPHMarker )
+ {
+ if ( ( iPtrEnd - iPtr ) < 2 )
+ {
+ return ETrue;
+ }
+ else
+ {
+ if ( PtrReadUtil::ReadBigEndianUint16( iPtr ) == KEPH )
+ {
+ iPtr += 2;
+ }
+ iTryEPHMarker = EFalse;
+ }
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// TJ2kStreamReader::TryReAlignReader
+// Try to align to byte boundary after failure on previous try
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 TJ2kStreamReader::TryReAlignReader()
+ {
+ if ( iAlign )
+ {
+ if ( ( iPtrEnd - iPtr ) < 1 )
+ {
+ return ETrue;
+ }
+ else
+ {
+ ++iPtr;
+ iAlign = 0;
+ }
+ }
+ return EFalse;
+ }
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Src/JP2KSubband.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,661 @@
+/*
+* Copyright (c) 2003, 2004 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: JP2KSubband class used to collect the subband related
+* information such as list of packets and list of subbands.
+*
+*/
+
+
+// INCLUDE FILES
+#include <icl/imagecodec.h>
+#include "JP2KImageUtils.h"
+#include "JP2KFormat.h"
+#include "JP2KStreamReader.h"
+#include "JP2KTileInfo.h"
+#include "JP2KImageInfo.h"
+#include "JP2KCodec.h"
+#include "JP2KPacket.h"
+#include "JP2KSubband.h"
+#include "JP2KComponentInfo.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// Destructor
+CJ2kSubband::~CJ2kSubband()
+ {
+ iPacketList.ResetAndDestroy();
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::BuildSubbandTreeL
+// Static method to set up the tree structure of the DWT subbands.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+CJ2kSubband* CJ2kSubband::BuildSubbandTreeL( TUint8 aMaxLevel, CJ2kComponentInfo& aComponent )
+ {
+ CJ2kSubband *root = CJ2kSubbandLL::NewLC();
+ root->iLevel = 0;
+
+ // The root subband, LLO, original image
+ root->iResLevel = (TUint8)( aMaxLevel + 1 );
+ root->iSubbandCanvas = aComponent.ComponentCanvas();
+ root->iHighPassFirst = TPoint( root->iSubbandCanvas.iTl.iX % 2,
+ root->iSubbandCanvas.iTl.iY % 2 );
+ CJ2kSubband *start = root;
+ CJ2kSubband *tmpLL = 0;
+ CJ2kSubband *tmpHL = 0;
+ CJ2kSubband *tmpLH = 0;
+ CJ2kSubband *tmpHH = 0;
+
+ for ( TUint8 index = 1; index <= aMaxLevel; ++index )
+ {
+ // Must be built in the following order - LL, HL, LH, and HH
+ // where all of them share the same parent - next lower LL
+ // but only the LL subband can be further sub-divided into
+ // lower resolution subband
+ // create LL subband
+ TUint8 highPassFirstX = (TUint8)( start->iHighPassFirst.iX );
+ TUint8 highPassFirstY = (TUint8)( start->iHighPassFirst.iY );
+
+ tmpLL = CJ2kSubbandLL::NewLC();
+ tmpLL->iLevel = index;
+ tmpLL->iResLevel = (TUint8)( aMaxLevel - index + 1 );
+
+ tmpLL->iSubbandCanvas.iTl = TPoint( (TUint32)( start->iSubbandCanvas.iTl.iX + 1 ) >> 1,
+ (TUint32)( start->iSubbandCanvas.iTl.iY + 1 ) >> 1 );
+
+ tmpLL->iSubbandCanvas.SetWidth( ( start->iSubbandCanvas.Width() + ( 1-highPassFirstX ) ) / 2 );
+
+ tmpLL->iSubbandCanvas.SetHeight( ( start->iSubbandCanvas.Height() + ( 1-highPassFirstY ) ) / 2 );
+
+ tmpLL->iHighPassFirst = TPoint( tmpLL->iSubbandCanvas.iTl.iX % 2,
+ tmpLL->iSubbandCanvas.iTl.iY % 2 );
+ start->AddChildL( tmpLL );
+ CleanupStack::Pop();
+
+ // Create HL subband
+ tmpHL = CJ2kSubbandNLL::NewLC();
+ tmpHL->iType = EBandHL;
+ tmpHL->iLevel = index;
+ tmpHL->iGain = 1;
+ tmpHL->iResLevel = tmpLL->iResLevel;
+ tmpHL->iSubbandCanvas.iTl = TPoint( (TUint32)start->iSubbandCanvas.iTl.iX >> 1,
+ (TUint32)( start->iSubbandCanvas.iTl.iY + 1 ) >> 1 );
+ tmpHL->iSubbandCanvas.SetWidth( ( start->iSubbandCanvas.Width() + highPassFirstX ) / 2 );
+ tmpHL->iSubbandCanvas.SetHeight( tmpLL->iSubbandCanvas.Height() );
+ tmpHL->iSubbandOrigin.iX = start->iSubbandOrigin.iX + ( ( start->iSubbandCanvas.Width() + ( 1-highPassFirstX ) ) / 2 );
+ tmpHL->iSubbandOrigin.iY = start->iSubbandOrigin.iY;
+ start->AddChildL( tmpHL );
+ CleanupStack::Pop();
+
+ // Create LH subband
+ tmpLH = CJ2kSubbandNLL::NewLC();
+ tmpLH->iType = EBandLH;
+ tmpLH->iLevel = index;
+ tmpLH->iGain = 1;
+ tmpLH->iResLevel = tmpLL->iResLevel;
+ tmpLH->iSubbandCanvas.iTl = TPoint( (TUint32)( start->iSubbandCanvas.iTl.iX + 1 ) >> 1,
+ (TUint32)start->iSubbandCanvas.iTl.iY >> 1 );
+ tmpLH->iSubbandCanvas.SetWidth( tmpLL->iSubbandCanvas.Width() );
+
+ tmpLH->iSubbandCanvas.SetHeight( ( start->iSubbandCanvas.Height() + highPassFirstY ) / 2 );
+ tmpLH->iSubbandOrigin.iX = start->iSubbandOrigin.iX;
+
+ tmpLH->iSubbandOrigin.iY = start->iSubbandOrigin.iY + ( ( start->iSubbandCanvas.Height() + ( 1-highPassFirstY ) ) / 2 );
+ start->AddChildL( tmpLH );
+ CleanupStack::Pop();
+
+ // Create HH subband
+ tmpHH = CJ2kSubbandNLL::NewLC();
+ tmpHH->iType = EBandHH;
+ tmpHH->iLevel = index;
+ tmpHH->iGain = 2;
+ tmpHH->iResLevel = tmpLL->iResLevel;
+ tmpHH->iSubbandCanvas.iTl = TPoint( ( TUint32 )start->iSubbandCanvas.iTl.iX >> 1,
+ ( TUint32 )start->iSubbandCanvas.iTl.iY >> 1 );
+ tmpHH->iSubbandCanvas.SetWidth( tmpHL->iSubbandCanvas.Width() );
+ tmpHH->iSubbandCanvas.SetHeight( tmpLH->iSubbandCanvas.Height() );
+ tmpHH->iSubbandOrigin.iX = tmpHL->iSubbandOrigin.iX;
+ tmpHH->iSubbandOrigin.iY = tmpLH->iSubbandOrigin.iY;
+ start->AddChildL( tmpHH );
+ CleanupStack::Pop();
+
+ start = start->ChildAt( EBandLL );
+ }
+
+ // The lowest resolution must be 0, so reset
+ // the resolution of NLL from 1 to 0.
+ start->iResLevel = 0;
+
+ CleanupStack::Pop();
+ return root;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::BuildPacketsL
+// Build the possible packets that may be in the subband
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSubband::BuildPacketsL( CJ2kComponentInfo& aComponent, HBufC8 *aPrecinctSiz, TUint16 aLayer )
+ {
+ CJ2kSubband *subband = 0;
+ CJ2kPacket *packet = 0;
+ TUint16 packetIndex = 0;
+ TUint16 xIndex = 0;
+ TUint16 yIndex = 0;
+ TInt denom = 0;
+ TInt ppx = 0;
+ TInt ppy = 0;
+ TInt ppxL = 0;
+ TInt ppyL = 0;
+ TInt32 trx0 = 0;
+ TInt32 try0 = 0;
+ TInt32 trx1 = 0;
+ TInt32 try1 = 0;
+ TInt32 n = 0;
+ TInt32 m = 0;
+ TInt32 nOrig = 0;
+ TInt32 mOrig = 0;
+ TInt32 xCoord = 0;
+ TInt32 yCoord = 0;
+ TInt32 numOfPackets = 0;
+ TInt32 tmpX = 0;
+ TInt32 tmpY = 0;
+ TSize cblkSize( 0, 0 );
+ TSize tmpSize( 0, 0 );
+
+ const TSize &compSize = aComponent.CodeBlockSize();
+ TInt compSizeLogWidth = TJ2kUtils::Log2( compSize.iWidth );
+ TInt compSizeLogHeight = TJ2kUtils::Log2( compSize.iHeight );
+
+ for ( TUint8 resLevel = 0; resLevel <= aComponent.Levels(); ++resLevel )
+ {
+ subband = SubbandAt( resLevel );
+ numOfPackets = aComponent.NumOfPackets( resLevel );
+ if ( numOfPackets )
+ {
+ do
+ {
+ for ( packetIndex = 0; packetIndex < numOfPackets; ++packetIndex )
+ {
+ CJ2kPacket *packet = new ( ELeave ) CJ2kPacket( aLayer ); //lint !e578 must be declared also earlier.
+ CleanupStack::PushL( packet );
+
+ User::LeaveIfError( subband->iPacketList.Append( packet ) );
+ CleanupStack::Pop( 1 );
+
+ if ( subband->iType == EBandLL || subband->iType == EBandHL )
+ {
+ subband->iPacketList[packetIndex]->BuildInclusiveInfoL();
+ }
+ }
+ subband = subband->NextSubbandRaster();
+ } while ( subband );
+
+ // Set to the default
+ ppx = ppy = 15;
+
+ if ( aPrecinctSiz )
+ {
+ ppxL = ( *aPrecinctSiz )[resLevel] & 0x0f;
+ ppyL = ( ( *aPrecinctSiz )[resLevel] & 0xf0 ) >> 4;
+ }
+ else
+ {
+ ppxL = ppyL = 15;
+ }
+
+ if ( ppxL != 15 || ppyL != 15 )
+ {
+ ppx = ( resLevel ) ? ppxL - 1 : ppxL;
+ ppy = ( resLevel ) ? ppyL - 1 : ppyL;
+ cblkSize.iWidth = ( compSizeLogWidth < ppx ) ? compSize.iWidth : 1 << ppx;
+ cblkSize.iHeight = ( compSizeLogHeight < ppy ) ? compSize.iHeight : 1 << ppy;
+ }
+ else
+ {
+ cblkSize = compSize;
+ }
+
+ denom = 1 << ( aComponent.Levels() - resLevel );
+
+ trx0 = TJ2kUtils::Ceil( aComponent.ComponentCanvas().iTl.iX, denom );
+ try0 = TJ2kUtils::Ceil( aComponent.ComponentCanvas().iTl.iY, denom );
+ trx1 = TJ2kUtils::Ceil( aComponent.ComponentCanvas().iBr.iX, denom );
+ try1 = TJ2kUtils::Ceil( aComponent.ComponentCanvas().iBr.iY, denom );
+
+ nOrig = ( trx0 / ( 1 << ppxL ) ) * ( 1 << ppxL );
+ mOrig = ( try0 / ( 1 << ppyL ) ) * ( 1 << ppyL );
+
+ // First subband at this resolution level
+ // at r = 0, it will be nLL
+ // at r > 0, it will be ( n-r+1 )HL
+
+ tmpSize = aComponent.PrecinctSizeAt( resLevel );
+ tmpX = 1 << ppx;
+ tmpY = 1 << ppy;
+ subband = SubbandAt( resLevel );
+ do
+ {
+ if ( subband->SubbandCanvasSize().iWidth > 0 &&
+ subband->SubbandCanvasSize().iHeight > 0 )
+ {
+ n = nOrig;
+ m = mOrig;
+
+ if ( subband->iType != EBandLL )
+ {
+ n /= 2;
+ m /= 2;
+ }
+
+ yCoord = m;
+ for ( yIndex = 0; yIndex < tmpSize.iHeight; ++yIndex )
+ {
+ xCoord = n;
+ for ( xIndex = 0; xIndex < tmpSize.iWidth; ++xIndex )
+ {
+ // Reuse the variables trx0, trx1, try0, try1
+ trx0 = Max( subband->SubbandCanvas().iTl.iX, xCoord );
+ try0 = Max( subband->SubbandCanvas().iTl.iY, yCoord );
+ trx1 = Min( xCoord + tmpX, subband->SubbandCanvas().iBr.iX ) - trx0;
+ try1 = Min( yCoord + tmpY, subband->SubbandCanvas().iBr.iY ) - try0;
+
+ if ( trx1 > 0 && try1 > 0 )
+ {
+ packetIndex = ( TUint16 )( yIndex * tmpSize.iWidth + xIndex );
+ packet = subband->iPacketList[packetIndex];
+ packet->SetPacketCanvas( trx0, try0, trx1, try1 );
+ packet->SetNumOfBlocks( cblkSize );
+ packet->BuildCodeBlocksL( xCoord, yCoord, cblkSize );
+ }
+ xCoord += tmpX;
+ } // end of xIndex
+ yCoord += tmpY;
+ } // end of yIndex
+ } // precinct size is greater than 0
+ subband = subband->NextSubbandRaster();
+ } while ( subband );
+ } // num of packets is greater than 0
+ } // end of resolution level
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::LRCPProgressionL
+// At each subband, parse the bitstream with LRCP progression order
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kSubband::LRCPProgressionL( CJ2kTileInfo& aTile, CJ2kComponentInfo& aComponent )
+ {
+ TUint8 incomplete = EFalse;
+ TUint16 marker = 0;
+ const TJ2kStreamReader& reader = aTile.StreamReader();
+ while ( iLastPacket < iPacketList.Count() )
+ {
+ if ( aTile.IsPOC() )
+ {
+ marker = PtrReadUtil::ReadBigEndianUint16( reader.iPtr );
+ if ( marker == KSOT || marker == KEOC )
+ {
+ break; //lint !e960 Break is OK.
+ }
+ }
+
+ incomplete = iPacketList[iLastPacket]->ReadPacketHeaderL( aTile, aComponent, *this );
+ if ( incomplete )
+ {
+ // Underflow
+ break; //lint !e960 Break is OK.
+ }
+ if ( iPacketList[iLastPacket]->IsBodyIncomplete() )
+ {
+ incomplete = iPacketList[iLastPacket]->ReadPacketBodyL( aTile, aComponent, *this );
+ if ( incomplete )
+ {
+ // Underflow
+ break; //lint !e960 Break is OK.
+ }
+ }
+ iPacketList[iLastPacket]->ResetInternalFlags();
+ ++iLastPacket;
+ }
+
+ if ( !incomplete && iLastPacket == iPacketList.Count() )
+ {
+ // Reset it back to 0 for the next layer
+ iLastPacket = 0;
+ }
+
+ return incomplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::RPCLProgressionL
+// At each subband, parse the bitstream with RPCL progression order
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kSubband::RPCLProgressionL( CJ2kTileInfo& aTile, CJ2kComponentInfo& aComponent )
+ {
+ TUint8 incomplete = EFalse;
+ TUint16 numOfLayers = aTile.NumOfLayersPOC();
+ TUint16 marker = 0;
+ const TJ2kStreamReader& reader = aTile.StreamReader();
+ while ( aTile.LastLayerProcessed() < numOfLayers )
+ {
+ if ( iPacketList.Count() )
+ {
+ if ( aTile.IsPOC() )
+ {
+ marker = PtrReadUtil::ReadBigEndianUint16( reader.iPtr );
+ if ( marker == KSOT || marker == KEOC )
+ {
+ break; //lint !e960 Break is OK.
+ }
+ }
+
+ incomplete = iPacketList[iLastPacket]->ReadPacketHeaderL( aTile, aComponent, *this );
+ if ( incomplete )
+ {
+ // Underflow
+ break; //lint !e960 Break is OK.
+ }
+ if ( iPacketList[iLastPacket]->IsBodyIncomplete() )
+ {
+ incomplete = iPacketList[iLastPacket]->ReadPacketBodyL( aTile, aComponent, *this );
+ if ( incomplete )
+ {
+ // Underflow
+ break; //lint !e960 Break is OK.
+ }
+ }
+ iPacketList[iLastPacket]->ResetInternalFlags();
+ }
+ aTile.IncrementLastLayerProcessed();
+ }
+
+ if ( !incomplete && aTile.LastLayerProcessed() == numOfLayers )
+ {
+ aTile.ResetLastLayerProcessed();
+ ++iLastPacket;
+ if ( iLastPacket == iPacketList.Count() )
+ {
+ iLastPacket = 0;
+ }
+ }
+ return incomplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::CPRLProgressionL
+// At each subband, parse the bitstream with CPRL progression order.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kSubband::CPRLProgressionL( CJ2kTileInfo& aTile, CJ2kComponentInfo& aComponent )
+ {
+ TUint8 incomplete = EFalse;
+ TUint16 numOfLayers = aTile.NumOfLayersPOC();
+ TUint16 marker = 0;
+ const TJ2kStreamReader& reader = aTile.StreamReader();
+ while ( aTile.LastLayerProcessed() < numOfLayers )
+ {
+ if ( iPacketList.Count() )
+ {
+ if ( aTile.IsPOC() )
+ {
+ marker = PtrReadUtil::ReadBigEndianUint16( reader.iPtr );
+ if ( marker == KSOT || marker == KEOC )
+ {
+ break; //lint !e960 Break is OK.
+ }
+ }
+
+ incomplete = iPacketList[iLastPacket]->ReadPacketHeaderL( aTile, aComponent, *this );
+ if ( incomplete )
+ {
+ // Underflow
+ break; //lint !e960 Break is OK.
+ }
+ if ( iPacketList[iLastPacket]->IsBodyIncomplete() )
+ {
+ incomplete = iPacketList[iLastPacket]->ReadPacketBodyL( aTile, aComponent, *this );
+ if ( incomplete )
+ {
+ // Underflow
+ break; //lint !e960 Break is OK.
+ }
+ }
+ iPacketList[iLastPacket]->ResetInternalFlags();
+ }
+ aTile.IncrementLastLayerProcessed();
+ }
+
+ if ( !incomplete && aTile.LastLayerProcessed() == numOfLayers )
+ {
+ aTile.ResetLastLayerProcessed();
+ ++iLastPacket;
+ if ( iLastPacket == iPacketList.Count() )
+ {
+ iLastPacket = 0;
+ }
+ }
+ return incomplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::ChildAt
+// Get the child subband at specific index
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CJ2kSubband* CJ2kSubband::ChildAt( TInt /*aBand*/ )
+ {
+ return 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::NextSubbandRaster
+// Get the sibling subband
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CJ2kSubband* CJ2kSubband::NextSubbandRaster()
+ {
+ return 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::SubbandAt
+// Get the subband at specific resolution level
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CJ2kSubband* CJ2kSubband::SubbandAt( TUint8 /*aResLevel*/ )
+ {
+ return 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::AddChildL
+// Add the child subband into the list of child subbands ( No-op )
+// -----------------------------------------------------------------------------
+//
+void CJ2kSubband::AddChildL( CJ2kSubband* /*aChild*/ )
+ { }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::SubbandTreeIndex
+// Get the subband tree index
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint16 CJ2kSubband::SubbandTreeIndex() const
+ {
+ TUint16 bandIndex = 0;
+ if ( iResLevel )
+ {
+ bandIndex = ( TUint16 )( ( iResLevel - 1 ) * 3 + iType );
+ }
+
+ return bandIndex;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::CJ2kSubband
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CJ2kSubband::CJ2kSubband() :
+ iPacketList( 1 )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubbandLL::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CJ2kSubbandLL* CJ2kSubbandLL::NewLC()
+ {
+ CJ2kSubbandLL* self = new ( ELeave ) CJ2kSubbandLL();
+
+ CleanupStack::PushL( self );
+ self->iType = EBandLL;
+
+ return self;
+ }
+
+// Destructor
+CJ2kSubbandLL::~CJ2kSubbandLL()
+ {
+ iChildList.ResetAndDestroy();
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubbandLL::ChildAt
+// Get the child subband at specific index
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CJ2kSubband* CJ2kSubbandLL::ChildAt( TInt aBand )
+ {
+ if ( iChildList.Count() > 0 )
+ {
+ return iChildList[aBand];
+ }
+
+ return 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubbandLL::SubbandAt
+// Get the subband at specific resolution level
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CJ2kSubband* CJ2kSubbandLL::SubbandAt( TUint8 aResLevel )
+ {
+ if ( iResLevel > aResLevel )
+ {
+ return ChildAt( EBandLL )->SubbandAt( aResLevel );
+ }
+ if ( iResLevel == 0 && aResLevel == 0 )
+ {
+ return this;
+ }
+ else
+ {
+ return Parent()->ChildAt( EBandHL );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubbandLL::AddChildL
+// Add the child subband into the list of child subbands
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSubbandLL::AddChildL( CJ2kSubband* aChild )
+ {
+ aChild->SetParent( this );
+ User::LeaveIfError( iChildList.Append( aChild ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubbandNLL::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CJ2kSubbandNLL* CJ2kSubbandNLL::NewLC()
+ {
+ CJ2kSubbandNLL* self = new ( ELeave ) CJ2kSubbandNLL();
+ CleanupStack::PushL( self );
+ return self;
+ }
+
+// Destructor
+CJ2kSubbandNLL::~CJ2kSubbandNLL()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubbandNLL::NextSubbandRaster
+// Get the sibling subband
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CJ2kSubband* CJ2kSubbandNLL::NextSubbandRaster()
+ {
+ CJ2kSubband *nextSubband = 0;
+ switch ( iType )
+ {
+ case EBandHL:
+ {
+ nextSubband = Parent()->ChildAt( EBandLH );
+ break;
+ }
+ case EBandLH:
+ {
+ nextSubband = Parent()->ChildAt( EBandHH );
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ return nextSubband;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Src/JP2KSynthesis.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,2366 @@
+/*
+* Copyright (c) 2003, 2004 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: CJ2kSynthesis class used to perform inverse quantization and
+* inverse DWT.
+*
+*/
+
+
+// INCLUDE FILES
+#include "JP2KTileInfo.h"
+#include "JP2KImageInfo.h"
+#include "JP2KImageWriter.h"
+#include "JP2KEntropyDecoder.h"
+#include "JP2KCodeBlock.h"
+#include "JP2KPacket.h"
+#include "JP2KSubband.h"
+#include "JP2KComponentInfo.h"
+#include "JP2KSynthesis.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CJ2kSynthesis::CJ2kSynthesis
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CJ2kSynthesis::CJ2kSynthesis()
+ {
+ // Set up the filter taps for irreversible filter
+ iTapsLow[0] = KFixedLow9x70;
+ iTapsLow[1] = KFixedLow9x71;
+ iTapsLow[2] = KFixedLow9x72;
+ iTapsLow[3] = KFixedLow9x73;
+
+ iTapsHigh[0] = KFixedHigh9x70;
+ iTapsHigh[1] = KFixedHigh9x71;
+ iTapsHigh[2] = KFixedHigh9x72;
+ iTapsHigh[3] = KFixedHigh9x73;
+ iTapsHigh[4] = KFixedHigh9x74;
+ }
+
+// Destructor
+CJ2kSynthesis::~CJ2kSynthesis()
+ {
+ if ( iInputBuffer )
+ {
+ iInputBuffer -= ( KFilterExtension + 1 );
+ User::Free( iInputBuffer );
+ iInputBuffer = 0;
+ }
+ if ( iOutputBuffer )
+ {
+ iOutputBuffer -= ( KFilterExtension + 1 );
+ User::Free( iOutputBuffer );
+ iOutputBuffer = 0;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSynthesis::DecodeTileL
+// Decode a single tile
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSynthesis::DecodeTileL( CJ2kImageWriter& aImageWriter,
+ CJ2kEntropyDecoder& aEntropyDecoder,
+ CJ2kImageInfo& aImageInfo,
+ CJ2kTileInfo& aTile )
+ {
+ if ( aImageInfo.Crop() )
+ {
+ // If this tile doesn't belong to the crop area, continue
+ if ( !aImageInfo.TileMaskAt( aTile.SotMarker().iIsot ) )
+ {
+ return;
+ }
+ }
+
+ CJ2kComponentInfo* componentInfo = 0;
+ TInt32 maxSize = 0;
+ TUint16 compIndex = 0;
+ TUint16 numOfComponents = aImageInfo.NumOfComponents();
+
+ // Find the largest width or height
+ for ( compIndex = 0; compIndex < numOfComponents; ++compIndex )
+ {
+ componentInfo = CONST_CAST( CJ2kComponentInfo*, &aTile.ComponentAt( compIndex ) );
+ maxSize = Max( maxSize, Max( componentInfo->ComponentCanvas().Height(),
+ componentInfo->ComponentCanvas().Width() ) );
+ }
+
+ maxSize += 2 * ( KFilterExtension + 1 );
+ AllocBufferL( maxSize );
+
+ TSize subbandSize( 0, 0 );
+ TUint16 bandIndex = 0;
+ TUint16 blockIndex = 0;
+
+ CJ2kSubband* subband = 0;
+ CJ2kPacket* packet = 0;
+ CJ2kCodeBlock* codeblock = 0;
+
+ TUint8 quantStyle = 0;
+ TUint8 bitDepth = 0;
+ TUint8 cblkStyle = 0;
+ TUint8 levelIndex = 0;
+ TUint32 packetIndex = 0;
+
+ CJ2kWriterComponentInfo* component = 0;
+ RPointerArray<CJ2kPacket>* packetList;
+
+ aEntropyDecoder.SetNewSizeL( aImageInfo.MaxBlockSize() );
+
+ // For each component in the tile
+ for ( compIndex = 0; compIndex < aImageInfo.NumOfComponents(); ++compIndex )
+ {
+ componentInfo = CONST_CAST( CJ2kComponentInfo*, &aTile.ComponentAt( compIndex ) );
+
+ // Skip the component when height or width is 0
+ if ( componentInfo->ComponentCanvas().Height() == 0 ||
+ componentInfo->ComponentCanvas().Width() == 0 )
+ {
+ continue; //lint !e960 Continue is OK.
+ }
+
+ // Check for component truncation
+ if ( aImageInfo.ComponentDrop() )
+ {
+ if ( aImageWriter.SingleFileOutput() )
+ {
+ if ( compIndex == ( aImageInfo.ComponentDrop() - 1 ) )
+ {
+ numOfComponents = compIndex;
+ }
+ else
+ {
+ continue; //lint !e960 Continue is OK.
+ }
+ }
+ else
+ {
+ if ( compIndex != ( aImageInfo.ComponentDrop() - 1 ) )
+ {
+ continue; //lint !e960 Continue is OK.
+ }
+ }
+ }
+
+ // Get the resolution level for this component
+ iWaveletLevels = (TInt16)( componentInfo->Levels() - aImageInfo.LevelDrop() );
+
+ TInt32 stepSize = 1;
+ if ( iWaveletLevels < 0 )
+ {
+ TInt32 i;
+
+ // Compute the output step size, the stepSize indicates how much more
+ // resolution has to be dropped if the image didn't have enough wavelet
+ // levels to begin with. One indicates no extra resolution drop (write
+ // each sample) and for each extra drop skip half of the samples, i.e.
+ // stepSize is 2^extraLevels in case extra drop is needed.
+
+ // Adjust the tile starting points and the stepSize
+ for ( i = 0; i < (-iWaveletLevels); i++ )
+ {
+ // Double the step size for every extra level dropped.
+ stepSize *= 2;
+ }
+
+ iWaveletLevels = 0;
+ }
+
+ // Get the top subband ( original image )
+ subband = CONST_CAST( CJ2kSubband*, componentInfo->SubbandAt( (TUint8)iWaveletLevels ) );
+
+ if ( subband->SubbandResLevel() != 0 )
+ {
+ subband = subband->Parent();
+ }
+
+ subbandSize = subband->SubbandCanvasSize();
+
+ // Skip the component when subband's height or width is 0
+ if ( subbandSize.iWidth == 0 || subbandSize.iHeight == 0 )
+ {
+ continue; //lint !e960 Continue is OK.
+ }
+
+ component = CONST_CAST( CJ2kWriterComponentInfo*, &aImageWriter.WriterComponentAt( compIndex ) );
+
+ // Have to allocate memory for each component in the image writer
+ component->AllocDataL( subbandSize );
+
+ bitDepth = aImageInfo.DepthOfComponent( compIndex );
+
+ // Get the right number of levels and transform type
+ // reversible == 1 for 5x3 filter and == 0 for 9x7 filter
+ iReversible = componentInfo->IsReversible();
+ iROIShift = componentInfo->RoiShift();
+
+ quantStyle = componentInfo->QuantizationStyle();
+ cblkStyle = componentInfo->CodeBlockStyle();
+
+ // For each resolution level in the component
+ for ( levelIndex = 0; levelIndex <= iWaveletLevels; levelIndex++ )
+ {
+ subband = CONST_CAST( CJ2kSubband*, componentInfo->SubbandAt( levelIndex ) );
+
+ // For each subband in the resolution level
+ do
+ {
+ bandIndex = ( quantStyle == 1 ) ? (TUint16)0 : subband->SubbandTreeIndex();
+
+ // Get the right magnitude bits for this band
+ iMagnitudeBitsHere = componentInfo->MagnitudeBits( bandIndex );
+
+ // Compute the Quantization parameters here, so we don't repeat that for every codeblock/precinct
+ ComputeQuantizationParameters( *componentInfo, bandIndex, subband->SubbandGain(), bitDepth );
+
+ // Set the lookup table for entropy decoder
+ aEntropyDecoder.SetCurrentZCLUT( (TUint8)( subband->SubbandType() ) );
+
+ packetList = CONST_CAST( RPointerArray<CJ2kPacket>*, &subband->PacketList() ); //lint !e665 the first parameter cannot be parenthesized here
+
+ // For each packet in the subband
+ for ( packetIndex = 0; packetIndex < componentInfo->NumOfPackets( levelIndex ); ++packetIndex )
+ {
+ packet = ( *packetList )[packetIndex];
+
+ // For each codeblock in the packet
+ for ( blockIndex = 0; blockIndex < packet->NumOfBlocks(); ++blockIndex )
+ {
+ codeblock = CONST_CAST( CJ2kCodeBlock*, &packet->CodeBlockAt( blockIndex ) );
+
+ // There is coded data in the codeblock
+ if ( codeblock->DataLength() )
+ {
+ // Decode the codeblock
+ aEntropyDecoder.DecodeCodeblock( *codeblock, cblkStyle, (TUint8)( iMagnitudeBitsHere + iROIShift ) );
+
+ // Copy data from the decoded codeblock for inverse quantization and ROI shifting
+ CopyDataToImage( aEntropyDecoder, component->Data(), *subband, *codeblock, quantStyle );
+ }
+ } // end of each codeblock
+ } // end of each packet
+
+ // Get the sibling subband
+ subband = subband->NextSubbandRaster();
+
+ } while ( subband ); // end of each subband in the resolution level
+
+ } // end of each resolution level in the component
+
+ // Point to the LL-band before calling inverse wavelet transform
+ subband = CONST_CAST( CJ2kSubband*, componentInfo->SubbandAt( 0 ) );
+
+ // Perform a full inverse wavelet transformation
+ FullWaveletInverse( component->Data(), subband );
+
+
+ // Check whether extra downsampling is needed
+ if(stepSize > 1)
+ {
+ TInt32 i,j;
+ TInt32 iStep,jStep;
+
+ // If the stepSize is larger than one it means that we have to downsample
+ // the output. This is because there were not enough wavelet levels to do
+ // the resolution dropping for this component.
+
+ // The reason why downsampling is done here and not in the ImageWriter is
+ // that different components might have different number of wavlet levels
+ // and thus it is easier to downsample the components here (so that we can
+ // just write out the samples normally in ImageWriter.
+ for(i = 0,iStep = 0; iStep < subbandSize.iHeight; i++,iStep += stepSize)
+ {
+ for(j = 0,jStep = 0; jStep < subbandSize.iWidth; j++,jStep += stepSize)
+ {
+ // Downsample the component so that downsampled image is in the
+ // upper left-hand corner.
+ component->Data()[i][j] = component->Data()[iStep][jStep];
+ }
+ }
+ }
+
+
+
+ if ( numOfComponents >= 3 )
+ {
+ if ( aTile.ColorTransformation() ||
+ ( aImageWriter.CSCode() == 18 || aImageWriter.CSCode() == 16 ) )
+ {
+ // Wait til we finish decoding all components before writing out the image
+ if ( compIndex < 2 )
+ {
+ continue; //lint !e960 Continue is OK.
+ }
+ }
+ else if ( aImageWriter.CSCode() == 0 )
+ {
+ // This case is also valid when no CSCode is defined, e.g. no file format is present
+ if( numOfComponents <= 3 )
+ {
+ if ( compIndex < 2 )
+ {
+ continue; //lint !e960 Continue is OK.
+ }
+ }
+ else
+ {
+ // Proceed to outputImageL
+ }
+ }
+ } //lint !e961 no else is needed here at the end of if...else if
+
+ // Write out the tile image
+ aImageWriter.OutputImageL( aTile, compIndex );
+
+ } // end of each component in the tile
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSynthesis::DecodeTileBlockL
+// Decode a single tile with lower memory using 256x256 blocks
+// for the inverse wavelet transform
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSynthesis::DecodeTileBlockL( CJ2kImageWriter& aImageWriter,
+ CJ2kEntropyDecoder& aEntropyDecoder,
+ CJ2kImageInfo& aImageInfo,
+ CJ2kTileInfo& aTile )
+ {
+ if ( aImageInfo.Crop() )
+ {
+ // If this tile doesn't belong to the crop area, continue
+ if ( !aImageInfo.TileMaskAt( aTile.SotMarker().iIsot ) )
+ {
+ return;
+ }
+ }
+
+ CJ2kComponentInfo* componentInfo = 0;
+ TInt32 maxSize = 0;
+ TUint16 compIndex = 0;
+ TUint16 numOfComponents = aImageInfo.NumOfComponents();
+
+ // Find the largest width or height
+ for ( compIndex = 0; compIndex < numOfComponents; ++compIndex )
+ {
+ componentInfo = CONST_CAST( CJ2kComponentInfo*, &aTile.ComponentAt( compIndex ) );
+ maxSize = Max( maxSize, Max( componentInfo->ComponentCanvas().Height(),
+ componentInfo->ComponentCanvas().Width() ) );
+ }
+
+ maxSize = KMaxBlockSupportSize;
+
+ maxSize += 2 * ( KFilterExtension + 1 );
+ AllocBufferL( maxSize );
+
+ TSize subbandSize( 0, 0 );
+ TUint16 bandIndex = 0;
+ TUint16 blockIndex = 0;
+
+ CJ2kSubband* subband = 0;
+ CJ2kPacket* packet = 0;
+ CJ2kCodeBlock* codeblock = 0;
+
+ TUint8 quantStyle = 0;
+ TUint8 bitDepth = 0;
+ TUint8 cblkStyle = 0;
+ TUint8 levelIndex = 0;
+ TUint32 packetIndex = 0;
+ TUint32 blockXCoord = 0;
+ TUint32 blockYCoord = 0;
+ TUint32 compXCoord = 0;
+ TUint32 compYCoord = 0;
+ TInt32 blockXEnd = 0;
+ TInt32 blockYEnd = 0;
+ TRect supportRegion( 0, 0, 0 , 0 );
+ TRect parentSupportRegion( 0, 0, 0 , 0 );
+ TPoint regionOffset( 0, 0 );
+ TInt16 tmpLevelIndex = 0;
+ TSize thisCompSize( 0, 0 );
+ TSize firstCompSize( 0, 0 );
+ TSize regionSize( 0, 0 );
+ TPoint tileEndPoint( 0, 0 );
+ TPoint tileStartPoint( 0, 0 );
+ TPoint blockStepSize( 0, 0 );
+
+ CJ2kWriterComponentInfo* component = 0;
+ RPointerArray<CJ2kPacket>* packetList;
+ TSizMarker& sizMarker = CONST_CAST( TSizMarker&, aImageInfo.SizMarker() );
+
+ aEntropyDecoder.SetNewSizeL( aImageInfo.MaxBlockSize() );
+ componentInfo = CONST_CAST( CJ2kComponentInfo*, &aTile.ComponentAt( 0 ) );
+
+ // Get the resolution level for this component
+ iWaveletLevels = (TInt16)( componentInfo->Levels() - aImageInfo.LevelDrop() );
+ if ( iWaveletLevels < 0 )
+ {
+ iWaveletLevels = 0;
+ }
+
+ // Get the top subband ( original image )
+ subband = CONST_CAST( CJ2kSubband*, componentInfo->SubbandAt( (TUint8)iWaveletLevels ) );
+ if ( subband->SubbandResLevel() != 0 )
+ {
+ subband = subband->Parent();
+ }
+
+ subbandSize = subband->SubbandCanvasSize();
+ tileEndPoint.iX = subbandSize.iWidth;
+ tileEndPoint.iY = subbandSize.iHeight;
+ tileStartPoint.iX = componentInfo->ComponentCanvas().iTl.iX;
+ tileStartPoint.iY = componentInfo->ComponentCanvas().iTl.iY;
+
+ // Loop on 256x256 blocks to reduce the memory required to perform the inverse wavelet
+ // First set as starting point the canvas coordinates of this component
+ blockXCoord = 0;
+ blockYCoord = 0;
+ blockStepSize.iX = KWaveletBlockSize;
+ blockStepSize.iY = KWaveletBlockSize;
+
+ for ( ; blockYCoord < (TUint32)tileEndPoint.iY; blockYCoord += KWaveletBlockSize )
+ {
+ // Start from the left border of this tile
+ blockXCoord = 0;
+
+ for ( ; blockXCoord < ( TUint32 )tileEndPoint.iX; blockXCoord += KWaveletBlockSize )
+ {
+ // For each component in the tile
+ for ( compIndex = 0; compIndex < aImageInfo.NumOfComponents(); ++compIndex )
+ {
+ compXCoord = blockXCoord;
+ compYCoord = blockYCoord;
+
+ componentInfo = CONST_CAST( CJ2kComponentInfo*, &aTile.ComponentAt( compIndex ) );
+
+ // Skip the component when height or width is 0
+ if ( componentInfo->ComponentCanvas().Height() == 0 ||
+ componentInfo->ComponentCanvas().Width() == 0 )
+ {
+ continue; //lint !e960 Continue is OK.
+ }
+
+ // Here we have to add a check that if we have sub sampled component together with color transform,
+ // we have to subsample also the block dimensions ( so that the inverse color transform is performed
+ // correctly.
+ blockStepSize.iX = KWaveletBlockSize;
+ blockStepSize.iY = KWaveletBlockSize;
+ if ( aImageInfo.NumOfComponents() == 3 )
+ {
+ if ( sizMarker.iXRsiz[1] == 2 * sizMarker.iXRsiz[0] &&
+ sizMarker.iXRsiz[2] == 2 * sizMarker.iXRsiz[0] )
+ {
+ if ( sizMarker.iXRsiz[1] == 2 * sizMarker.iXRsiz[0] &&
+ sizMarker.iXRsiz[2] == 2 * sizMarker.iXRsiz[0] )
+ {
+ if( compIndex == 1 || compIndex == 2 )
+ {
+ blockStepSize.iX = KWaveletBlockSize >> 1;
+ blockStepSize.iY = KWaveletBlockSize >> 1;
+ compXCoord >>= 1;
+ compYCoord >>= 1;
+ }
+ }
+ else
+ {
+ if( compIndex == 1 || compIndex == 2 )
+ {
+ blockStepSize.iX = KWaveletBlockSize >> 1;
+ compXCoord >>= 1;
+ blockStepSize.iY = KWaveletBlockSize;
+ }
+ }
+ }
+ }
+
+ // Check for component truncation
+ if ( aImageInfo.ComponentDrop() )
+ {
+ if ( aImageWriter.SingleFileOutput() )
+ {
+ if ( compIndex == ( aImageInfo.ComponentDrop() - 1 ) )
+ {
+ numOfComponents = compIndex;
+ }
+ else
+ {
+ continue; //lint !e960 Continue is OK.
+ }
+ }
+ else
+ {
+ if ( compIndex != ( aImageInfo.ComponentDrop() - 1 ) )
+ {
+ continue; //lint !e960 Continue is OK.
+ }
+ }
+ }
+
+ // Get the resolution level for this component
+ iWaveletLevels = (TInt16)( componentInfo->Levels() - aImageInfo.LevelDrop() );
+
+ TInt32 stepSize = 1;
+ if ( iWaveletLevels < 0 )
+ {
+ TInt32 i;
+
+ // Compute the output step size, the stepSize indicates how much more
+ // resolution has to be dropped if the image didn't have enough wavelet
+ // levels to begin with. One indicates no extra resolution drop (write
+ // each sample) and for each extra drop skip half of the samples, i.e.
+ // stepSize is 2^extraLevels in case extra drop is needed.
+
+ // Adjust the tile starting points and the stepSize
+ for ( i = 0; i < (-iWaveletLevels); i++ )
+ {
+ // Double the step size for every extra level dropped.
+ stepSize *= 2;
+ }
+
+
+ iWaveletLevels = 0;
+ }
+
+ // Get the top subband ( original image )
+ subband = CONST_CAST( CJ2kSubband*, componentInfo->SubbandAt( (TUint8)iWaveletLevels ) );
+
+ if ( subband->SubbandResLevel() != 0 )
+ {
+ subband = subband->Parent();
+ }
+
+ subbandSize = subband->SubbandCanvasSize();
+
+ // Skip the component when subband's height or width is 0
+ if ( subbandSize.iWidth == 0 || subbandSize.iHeight == 0 )
+ {
+ continue; //lint !e960 Continue is OK.
+ }
+
+ // Check that the block doesn't exceed the boundary of this component
+ if( (TInt32)compXCoord+blockStepSize.iX > subbandSize.iWidth )
+ {
+ blockXEnd = subbandSize.iWidth;
+ }
+ else
+ {
+ blockXEnd = compXCoord+blockStepSize.iX;
+ }
+ if( (TInt32)compYCoord+blockStepSize.iY > subbandSize.iHeight )
+ {
+ blockYEnd = subbandSize.iHeight;
+ }
+ else
+ {
+ blockYEnd = compYCoord+blockStepSize.iY;
+ }
+
+ // Store the block size on the first component in case the others are sub sampled
+ if( compIndex == 0 )
+ {
+ firstCompSize.iWidth = blockXEnd - blockXCoord;
+ firstCompSize.iHeight = blockYEnd - blockYCoord;
+ }
+
+ // Store the block size of this component
+ thisCompSize.iWidth = blockXEnd - compXCoord;
+ thisCompSize.iHeight = blockYEnd - compYCoord;
+
+ // This component could be sampled so that the block doesn't "exist"
+ // in this component, if so move to next component
+ if( thisCompSize.iWidth <= 0 || thisCompSize.iHeight <= 0 )
+ {
+ continue; //lint !e960 Continue is OK.
+ }
+
+ component = CONST_CAST( CJ2kWriterComponentInfo*, &aImageWriter.WriterComponentAt( compIndex ) );
+
+ // Have to allocate memory for each component in the image writer
+ subbandSize.iWidth = subbandSize.iHeight = KMaxBlockSupportSize;
+ component->AllocDataL( subbandSize );
+
+ bitDepth = aImageInfo.DepthOfComponent( compIndex );
+
+ // Get the right number of levels and transform type
+ // reversible == 1 for 5x3 filter and == 0 for 9x7 filter
+ iReversible = componentInfo->IsReversible();
+ iROIShift = componentInfo->RoiShift();
+
+ quantStyle = componentInfo->QuantizationStyle();
+ cblkStyle = componentInfo->CodeBlockStyle();
+
+ // The support region is the region needed on current level to
+ // compute the samples in current block.
+ supportRegion.iTl.iX = compXCoord;
+ supportRegion.iTl.iY = compYCoord;
+ supportRegion.iBr.iX = blockXEnd;
+ supportRegion.iBr.iY = blockYEnd;
+
+ // For each resolution level in the component
+ for ( levelIndex = 0; levelIndex <= iWaveletLevels; levelIndex++ )
+ {
+ // The support region is the region needed on current level to compute the samples in current block.
+ supportRegion.iTl.iX = compXCoord;
+ supportRegion.iTl.iY = compYCoord;
+ supportRegion.iBr.iX = blockXEnd;
+ supportRegion.iBr.iY = blockYEnd;
+ parentSupportRegion = supportRegion;
+ regionOffset.iX = regionOffset.iY = 0;
+
+ // Compute the support region of the parent level of the bands that are to be processed
+ // The support region is computed depending on the level we process currently.
+ for( tmpLevelIndex = iWaveletLevels; tmpLevelIndex > levelIndex; tmpLevelIndex-- )
+ {
+ // Get the subband on this ( temp )level in order to find out if high-pass first is true or not
+ subband = CONST_CAST( CJ2kSubband*, componentInfo->SubbandAt( (TUint8)( tmpLevelIndex ) ) );
+
+ // Level zero has the same support as level 1, so don't update the support for level zero.
+ if( tmpLevelIndex != 1 )
+ {
+ // Compute the new crop coordinates for the subbands on this level
+ if( iReversible )
+ {
+ // Support region for low-pass bands for 5x3 filter
+
+ // If this band is computed high-pass first, then one extra low-pass coefficient is needed from left.
+ // This is due to the fact that for Output[2n+1], we need five samples H[n-1], L[n], H[n], L[n+1] and H[n+1], but when high-pass
+ // is computed first, we actually need samples H[n-1], L[n-1], H[n], L[n] and H[n+1], where L are the low-pass filtered samples
+ // and H are the high-pass filtered samples.
+ if( subband->Parent()->HighPassFirst().iX )
+ {
+ parentSupportRegion.iTl.iX = ( ( ( parentSupportRegion.iTl.iX >> 1 ) - 1 ) > 0 ) ? //lint !e702 The shifted values cannot be negative here
+ ( ( parentSupportRegion.iTl.iX >> 1 ) - 1 ) : 0; //lint !e702 The shifted values cannot be negative here
+ }
+ else
+ {
+ parentSupportRegion.iTl.iX = parentSupportRegion.iTl.iX >> 1; //lint !e702 The shifted values cannot be negative here
+ }
+ // If this band is computed high-pass first, then one extra low-pass coefficient is needed from above.
+ if( subband->Parent()->HighPassFirst().iY )
+ {
+ parentSupportRegion.iTl.iY = ( ( ( parentSupportRegion.iTl.iY >> 1 ) - 1 )>0 ) ? //lint !e702 The shifted values cannot be negative here
+ ( ( parentSupportRegion.iTl.iY >> 1 ) - 1 ) : 0; //lint !e702 The shifted values cannot be negative here
+ }
+ else
+ {
+ parentSupportRegion.iTl.iY = parentSupportRegion.iTl.iY >> 1; //lint !e702 The shifted values cannot be negative here
+ }
+
+ parentSupportRegion.iBr.iX = ( ( parentSupportRegion.iBr.iX ) >> 1 ) + 1; //lint !e702 The shifted values cannot be negative here
+ parentSupportRegion.iBr.iY = ( ( parentSupportRegion.iBr.iY ) >> 1 ) + 1; //lint !e702 The shifted values cannot be negative here
+ }
+ else
+ {
+ // Support region for low-pass bands for 9x7 filter
+ // If this band is computed high-pass first, then one extra low-pass coefficient is needed ( from left ).
+ if( subband->Parent()->HighPassFirst().iX )
+ {
+ parentSupportRegion.iTl.iX = ( ( parentSupportRegion.iTl.iX >> 1 )-2 > 0 ) ? //lint !e702 The shifted values cannot be negative here
+ ( parentSupportRegion.iTl.iX >> 1 )-2 : 0; //lint !e702 the shifted values cannot be negative here
+ }
+ else
+ {
+ parentSupportRegion.iTl.iX = ( ( ( parentSupportRegion.iTl.iX >> 1 ) - 1 ) > 0 ) ? //lint !e702 The shifted values cannot be negative here
+ ( ( parentSupportRegion.iTl.iX >> 1 ) - 1 ) : 0; //lint !e702 the shifted values cannot be negative here
+ }
+ if( subband->Parent()->HighPassFirst().iY )
+ {
+ parentSupportRegion.iTl.iY = ( ( ( parentSupportRegion.iTl.iY >> 1 ) - 2 ) > 0 ) ? //lint !e702 The shifted values cannot be negative here
+ ( ( parentSupportRegion.iTl.iY >> 1 ) - 2 ) : 0; //lint !e702 the shifted values cannot be negative here
+ }
+ else
+ {
+ parentSupportRegion.iTl.iY = ( ( ( parentSupportRegion.iTl.iY >> 1 ) - 1 ) > 0 ) ? //lint !e702 The shifted values cannot be negative here
+ ( ( parentSupportRegion.iTl.iY >> 1 ) - 1 ) : 0; //lint !e702 the shifted values cannot be negative here
+ }
+
+ parentSupportRegion.iBr.iX = ( ( parentSupportRegion.iBr.iX ) >> 1 ) + 2; //lint !e702 the shifted values cannot be negative here
+ parentSupportRegion.iBr.iY = ( ( parentSupportRegion.iBr.iY ) >> 1 ) + 2; //lint !e702 the shifted values cannot be negative here
+ }
+ }
+ }
+
+
+ subband = CONST_CAST( CJ2kSubband*, componentInfo->SubbandAt( levelIndex ) );
+
+ // For each subband in the resolution level
+ do
+ {
+ bandIndex = ( quantStyle == 1 ) ? (TUint16)0 : subband->SubbandTreeIndex();
+
+ // Get the right magnitude_bits for this band
+ iMagnitudeBitsHere = componentInfo->MagnitudeBits( bandIndex );
+
+ // If iWaveletLevels == 0, do not update the supportRegion, since there is no wavelet decomposition ( zero levels )
+ if( iWaveletLevels != 0 )
+ {
+ // Now compute the support region for this band depending on whether it is LL, LH, HL or HH
+ // Use the support region of the parent for computation.
+ //
+ if( iReversible )
+ {
+ if( ( subband->SubbandType() ) == 0 || ( subband->SubbandType() ) == 2 )
+ {
+ if( subband->Parent()->HighPassFirst().iX )
+ {
+ supportRegion.iTl.iX = ( ( parentSupportRegion.iTl.iX >> 1 )-1 > 0 ) ? //lint !e702 The shifted values cannot be negative here
+ ( parentSupportRegion.iTl.iX >> 1 )-1 : 0; //lint !e702 the shifted values cannot be negative here
+ }
+ else
+ {
+ supportRegion.iTl.iX = parentSupportRegion.iTl.iX >> 1; //lint !e702 the shifted value cannot be negative here
+ }
+ }
+ else
+ {
+ supportRegion.iTl.iX = ( ( parentSupportRegion.iTl.iX >> 1 )-1 > 0 ) ? //lint !e702 The shifted values cannot be negative here
+ ( parentSupportRegion.iTl.iX >> 1 )-1 : 0; //lint !e702 the shifted values cannot be negative here
+ }
+
+
+ if( ( subband->SubbandType() ) == 0 || ( subband->SubbandType() ) == 1 )
+ {
+ if( subband->Parent()->HighPassFirst().iY )
+ {
+ supportRegion.iTl.iY = ( ( parentSupportRegion.iTl.iY >> 1 )-1 > 0 ) ? //lint !e702 The shifted values cannot be negative here
+ ( parentSupportRegion.iTl.iY >> 1 )-1 : 0; //lint !e702 the shifted values cannot be negative here
+ }
+ else
+ {
+ supportRegion.iTl.iY = parentSupportRegion.iTl.iY >>1; //lint !e702 the shifted value cannot be negative here
+ }
+ }
+ else
+ {
+ supportRegion.iTl.iY = ( ( parentSupportRegion.iTl.iY >> 1 )-1 > 0 ) ? //lint !e702 The shifted values cannot be negative here
+ ( parentSupportRegion.iTl.iY >> 1 )-1 : 0; //lint !e702 the shifted values cannot be negative here
+ }
+
+ // Compute the offset for this level
+ regionOffset.iX = parentSupportRegion.iTl.iX - 2*supportRegion.iTl.iX;
+ regionOffset.iY = parentSupportRegion.iTl.iY - 2*supportRegion.iTl.iY;
+
+ // Support region's bottom right corner for each band is ( supportParent.iBr>>1 )+1
+ supportRegion.iBr.iX = ( ( parentSupportRegion.iBr.iX ) >> 1 ) + 1; //lint !e702 the shifted value cannot be negative here
+ supportRegion.iBr.iY = ( ( parentSupportRegion.iBr.iY ) >> 1 ) + 1; //lint !e702 the shifted value cannot be negative here
+ }
+ else // irreversible ( 9x7 ) filter
+ {
+ // For low-pass filtering, the offset for the output is 1
+ if( ( subband->SubbandType() ) == 0 || ( subband->SubbandType() ) == 2 )
+ {
+ if( subband->Parent()->HighPassFirst().iX )
+ {
+ supportRegion.iTl.iX = ( ( parentSupportRegion.iTl.iX >> 1 )-2 > 0 ) ? //lint !e702 The shifted values cannot be negative here
+ ( parentSupportRegion.iTl.iX >> 1 )-2 : 0; //lint !e702 the shifted values cannot be negative here
+ }
+ else
+ {
+ supportRegion.iTl.iX = ( ( parentSupportRegion.iTl.iX >> 1 )-1 > 0 ) ? //lint !e702 The shifted values cannot be negative here
+ ( parentSupportRegion.iTl.iX >> 1 )-1 : 0; //lint !e702 the shifted values cannot be negative here
+ }
+
+ }
+ else
+ {
+ supportRegion.iTl.iX = ( ( parentSupportRegion.iTl.iX >> 1 )-2 > 0 ) ? //lint !e702 The shifted values cannot be negative here
+ ( parentSupportRegion.iTl.iX >> 1 )-2 : 0; //lint !e702 the shifted values cannot be negative here
+ }
+
+ if( ( subband->SubbandType() ) == 0 || ( subband->SubbandType() ) == 1 )
+ {
+ if( subband->Parent()->HighPassFirst().iY )
+ {
+ supportRegion.iTl.iY = ( ( parentSupportRegion.iTl.iY >> 1 )-2 > 0 ) ? //lint !e702 The shifted values cannot be negative here
+ ( parentSupportRegion.iTl.iY >> 1 )-2 : 0; //lint !e702 the shifted values cannot be negative here
+ }
+ else
+ {
+ supportRegion.iTl.iY = ( ( parentSupportRegion.iTl.iY >> 1 )-1 > 0 ) ? //lint !e702 The shifted values cannot be negative here
+ ( parentSupportRegion.iTl.iY >> 1 )-1 : 0; //lint !e702 the shifted values cannot be negative here
+ }
+ }
+ else
+ {
+ supportRegion.iTl.iY = ( ( parentSupportRegion.iTl.iY >> 1 )-2 > 0 ) ? //lint !e702 The shifted values cannot be negative here
+ ( parentSupportRegion.iTl.iY >> 1 )-2 : 0; //lint !e702 the shifted values cannot be negative here
+ }
+
+ // Compute the offset for this level
+ regionOffset.iY = parentSupportRegion.iTl.iY - 2*supportRegion.iTl.iY;
+ regionOffset.iX = parentSupportRegion.iTl.iX - 2*supportRegion.iTl.iX;
+
+ // Support region's bottom right corner for each band is ( supportParent.iBr>>1 )+2
+ supportRegion.iBr.iX = ( ( parentSupportRegion.iBr.iX ) >> 1 ) + 2; //lint !e702 the shifted value cannot be negative here
+ supportRegion.iBr.iY = ( ( parentSupportRegion.iBr.iY ) >> 1 ) + 2; //lint !e702 the shifted value cannot be negative here
+ }
+ }
+
+ // Check that the support region doesn't exceed the band boundaries
+ if( supportRegion.iBr.iX > subband->SubbandCanvasSize().iWidth )
+ {
+ supportRegion.iBr.iX = subband->SubbandCanvasSize().iWidth;
+ }
+ if( supportRegion.iBr.iY > subband->SubbandCanvasSize().iHeight )
+ {
+ supportRegion.iBr.iY = subband->SubbandCanvasSize().iHeight;
+ }
+
+ // Store the low-band's dimensions here to later compute the size of the whole region ( low-band plus high-band ).
+ if( subband->SubbandType() == 2 )
+ {
+ regionSize.iWidth = supportRegion.Width();
+ }
+ if( subband->SubbandType() == 1 )
+ {
+ regionSize.iHeight = supportRegion.Height();
+ }
+
+ // Compute the Quantization parameters here, so we don't repeat that for every codeblock/precinct
+ ComputeQuantizationParameters( *componentInfo, bandIndex, subband->SubbandGain(), bitDepth );
+
+ // Set the lookup table for entropy decoder
+ aEntropyDecoder.SetCurrentZCLUT( (TUint8)( subband->SubbandType() ) );
+
+ packetList = CONST_CAST( RPointerArray<CJ2kPacket>*, &subband->PacketList() ); //lint !e665 the first parameter cannot be parenthesized here
+
+ // For each packet in the subband
+ for ( packetIndex = 0; packetIndex < componentInfo->NumOfPackets( levelIndex );
+ ++packetIndex )
+ {
+ packet = ( *packetList )[packetIndex];
+
+ // For each codeblock in the packet
+ for ( blockIndex = 0; blockIndex < packet->NumOfBlocks(); ++blockIndex )
+ {
+ codeblock = CONST_CAST( CJ2kCodeBlock*, &packet->CodeBlockAt( blockIndex ) );
+
+ const TRect& cbCanvas = codeblock->CodeBlockCanvas();
+
+ TInt32 startRow = cbCanvas.iTl.iY - subband->SubbandCanvas().iTl.iY;
+ TInt32 startCol = cbCanvas.iTl.iX - subband->SubbandCanvas().iTl.iX;
+ TInt32 cblkHeight = cbCanvas.Height();
+ TInt32 cblkWidth = cbCanvas.Width();
+ TInt32 startRowCblk = 0;
+ TInt32 startColCblk = 0;
+ TInt32 startRowImage = 0;
+ TInt32 startColImage = 0;
+
+ if( startRow >= supportRegion.iBr.iY || startCol >= supportRegion.iBr.iX ||
+ ( startRow+cblkHeight ) <= supportRegion.iTl.iY ||
+ ( startCol+cblkWidth ) <= supportRegion.iTl.iX )
+ {
+ }
+ else
+ {
+ // Compute the start column from which to copy from ( in the codeblock ) and where to copy to ( in the image block )
+ if( startCol <= supportRegion.iTl.iX )
+ {
+ startColCblk = supportRegion.iTl.iX - startCol; // Ignore samples outside supportRegion
+ startColImage = 0; // First block, start from supportRegion's start
+ cblkWidth -= startColCblk; // Ignore samples outside supportRegion
+ }
+ else
+ {
+ startColCblk = 0; // First block, start from supportRegion's start
+ startColImage = startCol-supportRegion.iTl.iX; // First block, start from supportRegion's start
+ }
+ // If the last block extends outside supportRegion, we have to adjust codeblock's width
+ if( ( startCol+cbCanvas.Width() ) > supportRegion.iBr.iX )
+ {
+ cblkWidth -= ( ( startCol+cbCanvas.Width() ) - supportRegion.iBr.iX ); // Ignore samples outside supportRegion
+ }
+
+ // Compute the start row from which to copy from ( in the codeblock ) and where to copy to ( in the image block )
+ if( startRow <= supportRegion.iTl.iY )
+ {
+ startRowCblk = supportRegion.iTl.iY - startRow; // ignore samples outside supportRegion
+ startRowImage = 0; // First block, start from supportRegion's start
+ cblkHeight -= startRowCblk; // Ignore samples outside supportRegion
+ }
+ else
+ {
+ startRowCblk = 0; // First block, start from supportRegion's start
+ startRowImage = startRow-supportRegion.iTl.iY; // First block, start from supportRegion's start
+ }
+ // If the last block extends outside supportRegion, we have to adjust codeblock's height
+ if( ( startRow+cbCanvas.Height() ) > supportRegion.iBr.iY )
+ {
+ cblkHeight -= ( ( startRow+cbCanvas.Height() ) - supportRegion.iBr.iY ); // ignore samples outside supportRegion
+ }
+
+ // There is coded data in the codeblock
+ if ( codeblock->DataLength() )
+ {
+ // Decode the codeblock
+ aEntropyDecoder.DecodeCodeblock( *codeblock, cblkStyle,
+ (TUint8)( iMagnitudeBitsHere + iROIShift ) );
+
+ codeblock->SetCodeBlockDecoded();
+
+ CopyDataToBlock( aEntropyDecoder, component->Data(), *subband, quantStyle,
+ startRowCblk, startColCblk, startRowImage,
+ startColImage, cblkHeight, cblkWidth );
+ }
+ else
+ {
+ // Empty codeblock, fill the corresponding area with zero, since other wise there might be data left from lower levels.
+ FillDataWithZeros( component->Data(), *subband, startRowImage, startColImage, cblkHeight, cblkWidth );
+ }
+ }
+
+ } // end of each codeblock
+ } // end of each packet
+
+ // Get the sibling subband
+ subband = subband->NextSubbandRaster();
+
+ } while ( subband ); // end of each subband in the resolution level
+
+ // Now that we have processed all the blocks on this level, we can perform inverse wavelet transform on this level
+ // On resolution level zero, we don't have to inverse transform
+ if( levelIndex != 0 )
+ {
+ // The size of the inverse transformed region is the size of the low- ( stored in "regionSize" )
+ // and high-pass ( the supportRegion is always for HH-band, when we reach this point ) parts combined
+ regionSize = regionSize + supportRegion.Size();
+
+ subband = CONST_CAST( CJ2kSubband*, componentInfo->SubbandAt( levelIndex ) );
+ SingleLevelWaveletInverse( component->Data(), subband, regionOffset, regionSize, levelIndex );
+ }
+ } // end of each resolution level in the component
+
+ // Check whether extra downsampling is needed
+ if( stepSize > 1 )
+ {
+
+ TInt32 i,j;
+ TInt32 iStep,jStep;
+
+ // If the stepSize is larger than one it means that we have to downsample
+ // the output. This is because there were not enough wavelet levels to do
+ // the resolution dropping for this component.
+
+ // The reason why downsampling is done here and not in the ImageWriter is
+ // that different components might have different number of wavlet levels
+ // and thus it is easier to downsample the components here (so that we can
+ // just write out the samples normally in ImageWriter.
+ for( i = 0,iStep = 0; iStep<KMaxBlockSupportSize; i++,iStep += stepSize)
+ {
+ for( j = 0,jStep = 0; jStep<KMaxBlockSupportSize; j++,jStep += stepSize)
+ {
+
+ // Downsample the component so that downsampled image is in the
+ // upper left-hand corner.
+ component->Data()[i][j] = component->Data()[iStep][jStep];
+ }
+ }
+ }
+
+ if ( numOfComponents >= 3 )
+ {
+ if ( aTile.ColorTransformation() ||
+ ( aImageWriter.CSCode() == 18 || aImageWriter.CSCode() == 16 ) )
+ {
+ // Wait til we finish decoding all components before writing out the image
+ if ( compIndex < 2 )
+ {
+ continue; //lint !e960 Continue is OK.
+ }
+ }
+ else if ( aImageWriter.CSCode() == 0 )
+ {
+ // This case is also valid when no CSCode is defined, e.g. no file format is present
+ if( numOfComponents <= 3 )
+ {
+ if ( compIndex < 2 )
+ {
+ continue; //lint !e960 Continue is OK.
+ }
+ }
+ else
+ {
+ // Proceed to outputBlockL
+ }
+ }
+ } //lint !e961 no else is needed here at the end of if...else if
+
+ aImageWriter.OutputBlockL( aTile, compIndex, blockXCoord, blockYCoord, firstCompSize, thisCompSize );
+ } // end of each component in the tile
+ } // end of loop on the 256x256 blocks
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSynthesis::OneDimReversibleFilter
+// Perform one dimensional synthesis using reversible 5/3 filter
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSynthesis::OneDimReversibleFilter( TInt32 aStartPos, TInt32 aEndPos )
+ {
+ if ( ( aEndPos - aStartPos ) == 1 )
+ {
+ if ( aStartPos )
+ {
+ iOutputBuffer[aStartPos] = iInputBuffer[aStartPos] / 2;
+ }
+ else
+ {
+ iOutputBuffer[aStartPos] = iInputBuffer[aStartPos];
+ }
+ }
+ else
+ {
+ aEndPos++;
+ TInt32 idx = 0;
+ for ( idx = 0; idx < aEndPos; idx += 2 )
+ {
+ iOutputBuffer[idx] = iInputBuffer[idx] -
+ ( ( iInputBuffer[idx - 1] + iInputBuffer[idx + 1] + 2 ) >> 2 ); //lint !e704 shifting is OK.
+ }
+
+ for ( idx = 1; idx < aEndPos; idx += 2 )
+ {
+ iOutputBuffer[idx] = iInputBuffer[idx] +
+ ( ( iOutputBuffer[idx - 1] + iOutputBuffer[idx + 1] ) >> 1 ); //lint !e704 shifting is OK.
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSynthesis::PerformExtension
+// Performs one dimensional symmetric extension of the line of pixels from
+// the 2 extensions of the line.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSynthesis::PerformExtension( TInt32 aStartPos, TInt32 aEndPos )
+ {
+ TInt32* high = iInputBuffer + aEndPos - 1;
+ TInt32 dir = 1;
+ TInt32 posLeft = aStartPos;
+ TInt32 posRight = aEndPos - 1;
+
+ for ( TInt32 idx = 1; idx <= KFilterExtension; ++idx )
+ {
+ posLeft += dir;
+ posRight -= dir;
+ iInputBuffer[aStartPos - idx] = iInputBuffer[posLeft];
+ high[idx] = iInputBuffer[posRight];
+
+ if ( posLeft == ( aEndPos - 1 ) )
+ {
+ dir = -1;
+ }
+ if ( dir == -1 )
+ {
+ if ( posLeft == aStartPos )
+ {
+ dir = 1;
+ }
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSynthesis::OneDimIrrevFilter
+// Perform one dimensional synthesis using irreversible 9/7 filter
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSynthesis::OneDimIrrevFilter( TInt32 aStartPos,
+ TInt32 aEndPos,
+ TUint8 aLevel,
+ TUint8 aVertical )
+ {
+ if ( ( aEndPos - aStartPos ) == 1 )
+ {
+ if ( aStartPos )
+ {
+ iOutputBuffer[aStartPos] = iInputBuffer[aStartPos] / 2;
+ }
+ else
+ {
+ iOutputBuffer[aStartPos] = iInputBuffer[aStartPos];
+ }
+ }
+ else
+ {
+ // First the low-pass parts
+ TInt32 idx = aStartPos + ( aStartPos % 2 );
+ for ( ; idx < aEndPos; idx += 2 )
+ {
+ iOutputBuffer[idx] = iTapsLow[0] * iInputBuffer[idx] +
+ iTapsLow[2] * ( iInputBuffer[idx - 2] + iInputBuffer[idx + 2] );
+ }
+
+ idx = aStartPos + ( ( aStartPos + 1 ) % 2 );
+ for ( ; idx < aEndPos; idx += 2 )
+ {
+ iOutputBuffer[idx] = iTapsLow[1] * ( iInputBuffer[idx - 1] + iInputBuffer[idx + 1] ) +
+ iTapsLow[3] * ( iInputBuffer[idx - 3] + iInputBuffer[idx + 3] );
+ }
+
+ // Then the high-pass parts
+ idx = aStartPos + ( ( aStartPos + 1 ) % 2 );
+ for ( ; idx < aEndPos; idx += 2 )
+ {
+ iOutputBuffer[idx] += iTapsHigh[0] * iInputBuffer[idx] +
+ iTapsHigh[2] * ( iInputBuffer[idx - 2] + iInputBuffer[idx + 2] ) +
+ iTapsHigh[4] * ( iInputBuffer[idx - 4] + iInputBuffer[idx + 4] );
+ }
+
+ idx = aStartPos + ( aStartPos % 2 );
+ for ( ; idx < aEndPos; idx += 2 )
+ {
+ iOutputBuffer[idx] += iTapsHigh[1] * ( iInputBuffer[idx - 1] + iInputBuffer[idx + 1] ) +
+ iTapsHigh[3] * ( iInputBuffer[idx - 3] + iInputBuffer[idx + 3] );
+ }
+
+ TInt32 offset = 0;
+ TInt32 downshift = 0;
+
+ // Finally downshift all the samples
+ if ( !aVertical || ( aLevel != 0 ) )
+ {
+ downshift = KFilterShift;
+ }
+ else
+ {
+ downshift = KFilterShift + KWaveletShift;
+ }
+
+ offset = ( (TUint32)( 1 << downshift ) >> 1 );
+ idx = aStartPos;
+
+ for ( ; idx < aEndPos; idx++ )
+ {
+ iOutputBuffer[idx] = ( iOutputBuffer[idx] + offset ) >> downshift; //lint !e704 shifting is OK.
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSynthesis::OneDimFiltering
+// Perform one dimensional filtering
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSynthesis::OneDimFiltering( TInt32 aStartPos,
+ TInt32 aEndPos,
+ TUint8 aLevel,
+ TUint8 aVertical )
+ {
+ // Extend the signals ( at the start and end )
+ PerformExtension( aStartPos, aEndPos );
+
+ if ( iReversible )
+ {
+ OneDimReversibleFilter( aStartPos, aEndPos );
+ }
+ else
+ {
+ OneDimIrrevFilter( aStartPos, aEndPos, aLevel, aVertical );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSynthesis::HorizontalFilter
+// Perform one dimensional horizontal filtering
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSynthesis::HorizontalFilter( TPrecInt** aImage,
+ TInt32 aRow,
+ TUint32 aXtcSiz,
+ CJ2kSubband* aSubband )
+ {
+ TInt32 endPos = 0;
+ TInt32 startPos = aSubband->HighPassFirst().iX;
+
+ TInt32* rowImage = (TInt32*)aImage[aRow];
+ TInt32* rowImageHigh = rowImage + aSubband->ChildAt( CJ2kSubband::EBandLL )->SubbandCanvasSize().iWidth;
+ TInt32* iterator = iInputBuffer;
+
+ // Low-pass is first
+ if ( !startPos )
+ {
+ for ( endPos = aXtcSiz >> 1; endPos > 0; endPos-- )
+ {
+ *iterator++ = *rowImage++;
+ *iterator++ = *rowImageHigh++;
+ }
+ if ( aXtcSiz % 2 ) // One extra sample for low-pass
+ {
+ *iterator = *rowImage;
+ }
+ }
+ else // High-pass is first
+ {
+ iterator++;
+ for ( endPos = aXtcSiz >> 1; endPos > 0; endPos-- )
+ {
+ *iterator++ = *rowImageHigh++;
+ *iterator++ = *rowImage++;
+ }
+ if ( aXtcSiz % 2 ) // One extra sample for high-pass
+ {
+ *iterator = *rowImageHigh;
+ }
+ }
+
+ endPos = aXtcSiz + startPos;
+
+ OneDimFiltering( startPos, endPos, aSubband->SubbandLevel(), 0 );
+ Mem::Copy( aImage[aRow], iOutputBuffer + startPos, aXtcSiz * sizeof( TPrecInt ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSynthesis::VerticalFilter
+// Perform one dimensional vertical filtering
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSynthesis::VerticalFilter( TPrecInt **aImage,
+ TInt32 aColumn,
+ TUint32 aYtcSiz,
+ CJ2kSubband *aSubband )
+ {
+ TInt32 startPos = aSubband->HighPassFirst().iY;
+ TInt32 highStart = aSubband->ChildAt( CJ2kSubband::EBandLL )->SubbandCanvasSize().iHeight;
+ TInt32 highStop = aSubband->SubbandCanvasSize().iHeight;
+ TInt32 *iterator = iInputBuffer;
+
+ TInt32 lowIndex = 0;
+ TInt32 highIndex = highStart;
+ if ( !startPos )
+ {
+ for ( ; highIndex < highStop; lowIndex++, highIndex++ )
+ {
+ *iterator++ = aImage[lowIndex][aColumn];
+ *iterator++ = aImage[highIndex][aColumn];
+ }
+ if ( aYtcSiz % 2 )
+ {
+ *iterator = aImage[lowIndex][aColumn];
+ }
+ }
+ else
+ {
+ iterator++;
+ for ( ; lowIndex < highStart; highIndex++, lowIndex++ )
+ {
+ *iterator++ = aImage[highIndex][aColumn];
+ *iterator++ = aImage[lowIndex][aColumn];
+ }
+ if ( aYtcSiz % 2 )
+ {
+ *iterator = aImage[highIndex][aColumn];
+ }
+ }
+
+ OneDimFiltering( startPos, startPos + aYtcSiz, aSubband->SubbandLevel(), 1 );
+ iOutputBuffer += ( startPos + aYtcSiz - 1 );
+
+ for ( lowIndex = aYtcSiz - 1; lowIndex >= 0; lowIndex-- )
+ {
+ aImage[lowIndex][aColumn] = *iOutputBuffer--;
+ }
+ iOutputBuffer += ( 1 - startPos );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSynthesis::TwoDimFiltering
+// Perform two dimensional inverse wavelet transformation
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSynthesis::TwoDimFiltering( TPrecInt **aImage,
+ TInt32 aXtcSiz,
+ TInt32 aYtcSiz,
+ CJ2kSubband *aSubband )
+ {
+ TInt32 index = 0;
+
+ for ( index = aYtcSiz - 1; index >= 0; index-- )
+ {
+ HorizontalFilter( aImage, index, aXtcSiz, aSubband );
+ }
+
+ for ( index = aXtcSiz - 1; index >= 0; index-- )
+ {
+ VerticalFilter( aImage, index, aYtcSiz, aSubband );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSynthesis::FullWaveletInverse
+// Perform a full inverse wavelet transformation
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSynthesis::FullWaveletInverse( TPrecInt **aImage, CJ2kSubband *aSubband )
+ {
+ TSize canvas( 0, 0 );
+ TUint8 reduceLevels = 0;
+
+ // If truncating resolution levels, we have to compute the reduced levels,
+ // so that the final WAVELET_SHIFT in case of 9x7 filter is performed.
+ if ( aSubband->SubbandLevel() > iWaveletLevels )
+ {
+ reduceLevels = (TUint8)( aSubband->SubbandLevel() - iWaveletLevels );
+ }
+
+ for ( TUint8 levelIndex = (TUint8)iWaveletLevels; levelIndex > 0; levelIndex-- )
+ {
+ // The next lines assume that subband points to the LL-band and
+ // it is then moved to point to the parent i.e. to the last
+ // _decomposition level_ of the wavelet transform.
+ aSubband = aSubband->Parent();
+
+ // Adjust the level in case of resolution truncation
+ aSubband->SetSubbandLevel( (TUint8)( aSubband->SubbandLevel() - reduceLevels ) );
+
+ canvas = aSubband->SubbandCanvasSize();
+ if ( canvas.iWidth > 0 && canvas.iHeight > 0 )
+ {
+ TwoDimFiltering( aImage, canvas.iWidth, canvas.iHeight, aSubband );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSynthesis::ComputeQuantizationParameters
+// Compute the quantization parameters for a particular subband in the component
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSynthesis::ComputeQuantizationParameters( const CJ2kComponentInfo& aComponentInfo,
+ TInt16 aBandIndex,
+ TUint8 aBandGain,
+ TUint8 aBitDepth )
+ {
+ if ( iROIShift != 0 )
+ {
+ // ROI shifting is used
+ if ( aComponentInfo.QuantizationStyle() == 0 )
+ {
+ // Compute the shift for the codeblock's data, which is
+ // IMPLEMENTATION PRECISION -1( for sign ) - subband's range -
+ // the guard bits.
+ iDataShift = ( KImplementationPrecision - 1 ) - iMagnitudeBitsHere;
+ }
+ else // Irreversible case
+ {
+ // Because we have integer arithmetic only, we subtract WAVELET_SHIFT from the shift.
+ // This is to compensate for the fractional bits of the inverse quantized wavelet
+ // coefficients.
+ iDataShift = ( KImplementationPrecision - 1 ) - iMagnitudeBitsHere - KWaveletShift;
+
+ // The quantization step is computed from the equation
+ // step = ( 2^( Range-Exponent ) )*( 1+( Mantissa/( 2^11 ) ) ), where Range is the dynamic
+ // range of this subband ( = bitdepth + gain ). ( see Annex E of the standard for more
+ // information ).
+ //
+ // The "iStepExponent" is the shift needed to remove "iStepValue"'s fractional
+ // bits. The "iStepValue" is the shifted quantization step. Shifting back
+ // is done right after computing the quantized coefficient.
+ iStepExponent = aBitDepth + aBandGain - aComponentInfo.Exponent( aBandIndex ) - KStepBits;
+ iStepValue = aComponentInfo.Mantissa( aBandIndex ) + ( 1 << KStepBits );
+ }
+
+ // Compute the shift for the data inside the ROI
+ iROIDataShift = iDataShift - iROIShift;
+ }
+ else
+ {
+ // ROI is not present
+ if ( aComponentInfo.QuantizationStyle() == 0 )
+ {
+ // Compute the shift for the codeblock's data, which is
+ // IMPLEMENTATION PRECISION-1( for sign ) - subband's range -
+ // the guard bits.
+ iDataShift = ( KImplementationPrecision - 1 ) - iMagnitudeBitsHere;
+ // Shift all the samples in the codeblock
+ }
+ else // Irreversible case
+ {
+ // Because we have integer arithmetic only, we subtract WAVELET_SHIFT from the shift.
+ // This is to compensate for the fractional bits of the inverse quantized wavelet
+ // coefficients.
+ iDataShift = ( KImplementationPrecision - 1 ) - iMagnitudeBitsHere - KWaveletShift;
+
+ // To prevent overflows we check if the "shift" is at least 12. The minimum downshift of 12 is
+ // derived from the computation of "value*iStepValue", where "value" is downshifted previously by "shift"
+ // and "iStepValue" is at maximum 12 bits ( since iStepValue = mantissa + 1<<KStepBits, where mantissa is
+ // a 11-bit value and KStepBits is 11 ).
+ //
+ TInt32 iExtraBits = 0;
+ // If the implementation precision is 16 then we don't have to check if the shift is at least 12.
+ // This is because we use 32 bits for the computation and thus have at least 16 zero most significant
+ // bits at the "value".
+
+
+ if ( iDataShift < 12 ) // Test to prevent overflows
+ {
+ iExtraBits = 12 - iDataShift;
+ iDataShift += iExtraBits;
+ }
+
+ // The quantization step is computed from the equation
+ // step = ( 2^( Range-Exponent ) )*( 1+( Mantissa/( 2^11 ) ) ), where Range is the dynamic
+ // range of this subband ( = bitdepth + gain ). ( see Annex E of the standard for more
+ // information ).
+ //
+ // The "iStepExponent" is the shift needed to remove "iStepValue"'s fractional
+ // bits. The "iStepValue" is the shifted quantization step. Shifting back
+ // is done right after computing the quantized coefficient.
+ //
+ iStepExponent = aBitDepth + aBandGain - aComponentInfo.Exponent( aBandIndex ) - KStepBits;
+
+ // Test to prevent overflows
+ iStepExponent += iExtraBits;
+
+ iStepValue = aComponentInfo.Mantissa( aBandIndex ) + ( 1 << KStepBits );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSynthesis::CopyDataToImage
+// Apply inverse quantization and ROI shifting on the decoded
+// codeblock and copy to the image writer
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSynthesis::CopyDataToImage( CJ2kEntropyDecoder& aEntropyDecoder, TPrecInt** aImageBlock,
+ CJ2kSubband& aSubband, CJ2kCodeBlock& aCodeblock,
+ TUint8 aQuantizationStyle )
+ {
+ TPrecInt* buffer = 0; // To buffer one row of the aImageBlock
+ TPrecInt* imageRow = 0; // One row of the image
+ TPrecInt valueInt = 0;
+ TInt32 value = 0;
+ TInt32 j = 0;
+
+ const TRect& cbCanvas = aCodeblock.CodeBlockCanvas();
+
+ TInt32 startRow = cbCanvas.iTl.iY - aSubband.SubbandCanvas().iTl.iY + aSubband.SubbandOrigin().iY;
+ TInt32 startCol = cbCanvas.iTl.iX - aSubband.SubbandCanvas().iTl.iX + aSubband.SubbandOrigin().iX;
+ TInt32 endRow = startRow + cbCanvas.Height() - 1;
+ TInt32 endCol = startCol + cbCanvas.Width();
+
+ TInt32 cols = endCol - startCol - 1;
+
+ if ( iROIShift ) // ROI shifting is used
+ {
+ // Compute mask to determine which samples are in ROI
+ // for mask ROI coefficients
+ TInt32 mask = ( ( 1 << iMagnitudeBitsHere ) - 1 ) << ( ( KImplementationPrecision - 1 ) - iMagnitudeBitsHere );
+ TInt32 mask2 = ( ~mask ) & KMaximumPrecisionInteger;
+ TInt32 mask3 = ( ( 1 << iROIShift ) - 1 ) << ( ( KImplementationPrecision - 1 ) - iROIShift );
+ TInt32 maskShift = ( ~mask3 ) & KMaximumPrecisionInteger;
+
+ if ( !aQuantizationStyle )
+ {
+ // Shift all the samples in the codeblock
+ TInt32 roiDataShift = ( iROIDataShift < 0 ) ? -iROIDataShift : iROIDataShift;
+
+ for ( ; endRow >= startRow; endRow-- )
+ {
+ buffer = aEntropyDecoder.iData[endRow - startRow] + cols;
+ for ( j = endCol - 1; j >= startCol; j-- )
+ {
+ value = ( *buffer-- );
+ if ( !( value & mask ) ) // Background
+ {
+ // iROIDataShift can never be negative here!
+ if ( iROIDataShift < 0 )
+ {
+ aImageBlock[endRow][j] = ( value < 0 ) ? -( ( value & KMaximumPrecisionInteger ) << roiDataShift )
+ : ( value << roiDataShift ); //lint !e704 value is positive here
+ }
+ else
+ {
+ aImageBlock[endRow][j] = ( value < 0 ) ? -( ( value & maskShift ) >> roiDataShift ) //lint !e704 value&maskShift is positive, so no risk of right shifting negative values
+ : ( ( value & maskShift ) >> roiDataShift ); //lint !e704 value&maskShift is positive
+ }
+ }
+ else // ROI
+ {
+ if ( value & mask2 )
+ {
+ // Decoded more than magbits bit-planes, set
+ // quantization mid-interval approx. bit just after
+ // the magbits.
+ value &= ( ~mask2 );
+ }
+
+ aImageBlock[endRow][j] = ( value < 0 ) ? -( ( value & KMaximumPrecisionInteger ) >> iDataShift )
+ : ( value >> iDataShift ); //lint !e704 value is positive here
+ }
+ }
+ }
+ }
+ else // Irreversible case
+ {
+ // Shift all the samples in the codeblock
+ TInt32 stepExponent = ( iStepExponent < 0 ) ? -iStepExponent : iStepExponent;
+
+ // Divide into two cases depending on the sign of the iStepExponent to speed up coding
+ if ( iStepExponent < 0 )
+ {
+ for ( ; endRow >= startRow; endRow-- )
+ {
+ buffer = aEntropyDecoder.iData[endRow - startRow] + cols;
+ for ( j = endCol - 1; j >= startCol; j-- )
+ {
+ value = ( *buffer-- );
+
+ // Divide into two cases depending on whether value is negative
+ if ( value < 0 )
+ {
+ if ( !( value & mask ) ) // Background
+ {
+ value = ( ( value & maskShift ) >> iROIDataShift ); //lint !e704 value&maskShift is positive
+ valueInt = -( ( value * iStepValue ) >> stepExponent ); //lint !e704 ( value*iStepValue )&KMaximumPrecisionInteger is positive
+ }
+ else // ROI
+ {
+ if ( value & mask2 )
+ {
+ // Decoded more than magbits bit-planes, set
+ // quantization mid-interval approx. bit just after
+ // the magbits.
+ value = ( value & ( ~mask2 ) ) | ( 1 << ( KImplementationPrecision - 2 - iMagnitudeBitsHere ) );
+ }
+
+ value = ( ( value & KMaximumPrecisionInteger ) >> iDataShift );
+ valueInt = -( ( value * iStepValue ) >> stepExponent ); //lint !e704 ( value*iStepValue )&KMaximumPrecisionInteger is positive
+ }
+ }
+ else // Value is non-negative
+ {
+ if ( !( value & mask ) ) // background
+ {
+ value = ( ( value & maskShift ) >> iROIDataShift ); //lint !e704 value&maskShift is positive
+ valueInt = ( ( value * iStepValue ) >> stepExponent ); //lint !e704 value*iStepValue is positive
+ }
+ else // ROI
+ {
+ if ( value & mask2 )
+ {
+ // Decoded more than magbits bit-planes, set
+ // quantization mid-interval approx. bit just after
+ // the magbits.
+ value = ( value & ( ~mask2 ) ) | ( 1 << ( KImplementationPrecision - 2 - iMagnitudeBitsHere ) );
+ }
+
+ value = ( ( value & KMaximumPrecisionInteger ) >> iDataShift );
+ valueInt = ( ( value * iStepValue ) >> stepExponent ); //lint !e704 value*iStepValue is positive
+ }
+ }
+
+ aImageBlock[endRow][j] = valueInt;
+ }
+ }
+ }
+ else // iStepExponent is non-negative
+ {
+ for ( ; endRow >= startRow; endRow-- )
+ {
+ buffer = aEntropyDecoder.iData[endRow - startRow] + cols;
+ for ( j = endCol - 1; j >= startCol; j-- )
+ {
+ value = ( *buffer-- );
+
+ // Divide into two cases depending on whether value is negative
+ if ( value < 0 )
+ {
+
+ // Change value to be positive
+ value = -value;
+
+ if ( !( value & mask ) ) // Background
+ {
+ value = ( ( value & maskShift ) >> iROIDataShift ); //lint !e704 value&maskShift is positive
+ valueInt = ( ( value * iStepValue ) << stepExponent );
+ }
+ else // ROI
+ {
+ if ( value & mask2 )
+ {
+ // Decoded more than magbits bit-planes, set
+ // quantization mid-interval approx. bit just after
+ // the magbits.
+ value = ( value & ( ~mask2 ) ) | ( 1 << ( KImplementationPrecision - 2 - iMagnitudeBitsHere ) );
+ }
+
+ value = ( ( value & KMaximumPrecisionInteger ) >> iDataShift );
+ valueInt = ( ( value * iStepValue ) << stepExponent );
+ }
+
+ // Change the sign back to negative
+ aImageBlock[endRow][j] = -valueInt;
+ }
+ else // Value is non-negative
+ {
+ if ( !( value & mask ) ) // Background
+ {
+ value = ( ( value & maskShift ) >> iROIDataShift ); //lint !e704 value&maskShift is positive
+ valueInt = ( ( value * iStepValue ) << stepExponent );
+ }
+ else // ROI
+ {
+ if ( value & mask2 )
+ {
+ // Decoded more than magbits bit-planes, set
+ // quantization mid-interval approx. bit just after
+ // the magbits.
+ value = ( value & ( ~mask2 ) ) | ( 1 << ( KImplementationPrecision - 2 - iMagnitudeBitsHere ) );
+ }
+
+ value = ( ( value & KMaximumPrecisionInteger ) >> iDataShift );
+ valueInt = ( ( value * iStepValue ) << stepExponent );
+ }
+ aImageBlock[endRow][j] = valueInt;
+ }
+ }
+ }
+ }
+ }
+ }
+ else // ROI is not present
+ {
+ if ( !aQuantizationStyle )
+ {
+ // Shift all the samples in the codeblock
+ TInt32 i = endRow - startRow;
+ for ( ; endRow >= startRow; endRow--, i-- )
+ {
+ imageRow = aImageBlock[endRow] + endCol - 1;
+ buffer = aEntropyDecoder.iData[i] + cols;
+ for ( j = endCol - 1; j >= startCol; j-- )
+ {
+ value = *buffer--;
+ if ( value < 0 )
+ {
+ *imageRow-- = -( ( value & KMaximumPrecisionInteger ) >> iDataShift );
+ }
+ else
+ {
+ *imageRow-- = value >> iDataShift; //lint !e704 value is positive here
+ }
+ }
+ }
+ }
+ else // Irreversible case
+ {
+ // Shift all the samples in the codeblock
+ TInt32 stepExponent = ( iStepExponent < 0 ) ? -iStepExponent : iStepExponent;
+
+ // Divide into two cases depending on the sign of the iStepExponent to speed up coding
+ if ( iStepExponent < 0 )
+ {
+ for ( ; endRow >= startRow; endRow-- )
+ {
+ buffer = aEntropyDecoder.iData[endRow - startRow] + cols;
+ for ( j = endCol - 1; j >= startCol; j-- )
+ {
+ value = ( *buffer-- );
+
+ if ( value < 0 ) // Negative value
+ {
+ value = ( ( value & KMaximumPrecisionInteger ) >> iDataShift );
+ aImageBlock[endRow][j] = (TPrecInt)( -( ( value * iStepValue ) >> stepExponent ) ); //lint !e704 value*iStepValue is positive
+ }
+ else
+ {
+ value = ( ( value & KMaximumPrecisionInteger ) >> iDataShift );
+ aImageBlock[endRow][j] = (TPrecInt)( ( value * iStepValue ) >> stepExponent ); //lint !e704 value*iStepValue is positive
+ }
+ }
+ }
+ }
+ else // iStepExponent is non-negative
+ {
+ for ( ; endRow >= startRow; endRow-- )
+ {
+ buffer = aEntropyDecoder.iData[endRow - startRow] + cols;
+ for ( j = endCol - 1; j >= startCol; j-- )
+ {
+ value = ( *buffer-- );
+
+ if ( value < 0 ) // Negative value
+ {
+ value = ( ( value & KMaximumPrecisionInteger ) >> iDataShift );
+ aImageBlock[endRow][j] = (TPrecInt)( -( ( value * iStepValue ) << stepExponent ) );
+ }
+ else
+ {
+ value = ( ( value & KMaximumPrecisionInteger ) >> iDataShift );
+ aImageBlock[endRow][j] = (TPrecInt)( ( value * iStepValue ) << stepExponent );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // If number of levels is zero then we have to do the
+ // inverse wavelet shifting here.
+ //
+ if ( iWaveletLevels == 0 )
+ {
+ endRow = startRow + cbCanvas.Height();
+ endCol = startCol + cbCanvas.Width();
+
+ if ( aQuantizationStyle )
+ {
+ for ( TInt32 i = endRow - 1; i >= startRow; i-- )
+ {
+ for ( j = endCol - 1; j >= startCol; j-- )
+ {
+ aImageBlock[i][j] >>= KWaveletShift; //lint !e704 shifting is OK.
+ }
+ }
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSynthesis::AllocBufferL
+// Allocate internal buffer based on the requested size
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSynthesis::AllocBufferL( TInt32 aSize )
+ {
+ // Allocate memory for the input and output buffers
+ TInt32 totalSize = aSize * sizeof( TInt32 );
+
+ if ( iIOBufferSize )
+ {
+ // Resize only when the request buffer is larger than current buffer
+ if ( iIOBufferSize < totalSize )
+ {
+ iInputBuffer -= ( KFilterExtension + 1 );
+ TInt32* tmpBuffer = STATIC_CAST( TInt32*, User::ReAlloc( iInputBuffer, totalSize ) );
+ if ( !tmpBuffer )
+ {
+ iInputBuffer += ( KFilterExtension + 1 );
+ User::Leave( KErrNoMemory );
+ }
+ iInputBuffer = tmpBuffer;
+ iInputBuffer += ( KFilterExtension + 1 );
+
+ iOutputBuffer -= ( KFilterExtension + 1 );
+ tmpBuffer = STATIC_CAST( TInt32*, User::ReAlloc( iOutputBuffer, totalSize ) );
+ if ( !tmpBuffer )
+ {
+ iOutputBuffer += ( KFilterExtension + 1 );
+ User::Leave( KErrNoMemory );
+ }
+ iOutputBuffer = tmpBuffer;
+ iOutputBuffer += ( KFilterExtension + 1 );
+
+ iIOBufferSize = totalSize;
+ }
+ }
+ else
+ {
+ // First time buffer allocation
+ iInputBuffer = STATIC_CAST( TInt32*, User::Alloc( totalSize ) );
+ if ( !iInputBuffer )
+ {
+ User::Leave( KErrNoMemory );
+ }
+ iInputBuffer += ( KFilterExtension + 1 );
+ iOutputBuffer = STATIC_CAST( TInt32*, User::Alloc( totalSize ) );
+ if ( !iOutputBuffer )
+ {
+ User::Leave( KErrNoMemory );
+ }
+ iOutputBuffer += ( KFilterExtension + 1 );
+ iIOBufferSize = totalSize;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSynthesis::HorizontalBlockFilter
+// Perform one dimensional horizontal filtering ( block-based ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSynthesis::HorizontalBlockFilter( TPrecInt** aImage, TInt32 aRow,
+ TUint32 aXtcSiz, CJ2kSubband* aSubband,
+ TInt32 aXOffset, TUint8 aCurrentLevel )
+ {
+ TInt32 endPos = 0;
+ TInt32 startPos = aSubband->HighPassFirst().iX;
+
+ TInt32* rowImage = (TInt32*)aImage[aRow];
+ TInt32* rowImageHigh = rowImage + KWaveletBlockMidPoint;
+ TInt32* iterator = iInputBuffer;
+
+ // Insert one extra ( dummy, i.e. zero-valued ) low-pass sample.
+ // This sample is not actually needed in computations, but now we can use the same
+ // functions for filtering for block-based and normal wavelet.
+ if( !startPos && ( aXOffset > 0 ) )
+ {
+
+ // The need for one extra sample derives from the fact that the support region
+ // for the high-pass is extends one sample further than the low-pass region.
+ *iterator++ = 0;
+ *iterator++ = *rowImageHigh++;
+
+ // Increment aXtcSiz by one to account for the dummy sample
+ aXtcSiz++;
+ }
+
+ if ( !startPos ) // Low-pass first
+ {
+ for ( endPos = aXtcSiz >> 1; endPos > 0; endPos-- )
+ {
+ *iterator++ = *rowImage++;
+ *iterator++ = *rowImageHigh++;
+ }
+ if ( aXtcSiz % 2 ) // One extra sample for low-pass
+ {
+ *iterator = *rowImage;
+ }
+ }
+ else // High-pass first
+ {
+ iterator++;
+ for ( endPos = aXtcSiz >> 1; endPos > 0; endPos-- )
+ {
+ *iterator++ = *rowImageHigh++;
+ *iterator++ = *rowImage++;
+ }
+ if ( aXtcSiz % 2 ) // One extra sample for high-pass
+ {
+ *iterator = *rowImageHigh;
+ }
+ }
+
+ endPos = aXtcSiz + startPos;
+
+ OneDimFiltering( startPos, endPos, (TUint8)( iWaveletLevels - aCurrentLevel ), 0 );
+
+ // Copy row back to image, take care of offset
+ Mem::Copy( aImage[aRow], iOutputBuffer + startPos + ( aXOffset ), ( aXtcSiz - ( aXOffset ) ) * sizeof( TPrecInt ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSynthesis::VerticalBlockFilter
+// Perform one dimensional vertical filtering ( block-based )
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSynthesis::VerticalBlockFilter( TPrecInt** aImage, TInt32 aColumn, TUint32 aYtcSiz,
+ CJ2kSubband* aSubband, TInt32 aYOffset,
+ TUint8 aCurrentLevel )
+ {
+ TInt32 startPos = aSubband->HighPassFirst().iY;
+ TInt32 highStart = KWaveletBlockMidPoint;
+ TInt32* iterator = iInputBuffer;
+
+ TInt32 lowIndex = 0;
+ TInt32 highIndex = highStart;
+
+ // Insert one extra ( dummy, i.e. zero-valued ) low-pass sample.
+ if( !startPos && ( aYOffset > 0 ) )
+ {
+ *iterator++ = 0;
+ *iterator++ = aImage[highIndex++][aColumn];
+
+ // Increment aYtcSiz by one to account for the dummy sample
+ aYtcSiz++;
+ }
+
+ TInt32 highStop = KWaveletBlockMidPoint + ( aYtcSiz >> 1 );
+ TInt32 lowStop = aYtcSiz >> 1;
+
+ if ( !startPos )
+ {
+ for ( ; highIndex < highStop; lowIndex++, highIndex++ )
+ {
+ *iterator++ = aImage[lowIndex][aColumn];
+ *iterator++ = aImage[highIndex][aColumn];
+ }
+ if ( aYtcSiz % 2 )
+ {
+ *iterator = aImage[lowIndex][aColumn];
+ }
+ }
+ else
+ {
+ iterator++;
+ for ( ; lowIndex < lowStop; highIndex++, lowIndex++ )
+ {
+ *iterator++ = aImage[highIndex][aColumn];
+ *iterator++ = aImage[lowIndex][aColumn];
+ }
+ if ( aYtcSiz % 2 )
+ {
+ *iterator = aImage[highIndex][aColumn];
+ }
+ }
+
+ OneDimFiltering( startPos, startPos + aYtcSiz, (TUint8)( iWaveletLevels - aCurrentLevel ), 1 );
+ iOutputBuffer += ( startPos + aYtcSiz - 1 );
+
+ // Copy column back to image, take care of offset
+ for ( lowIndex = ( aYtcSiz - 1 - aYOffset ); lowIndex >= 0; lowIndex-- )
+ {
+ aImage[lowIndex][aColumn] = *iOutputBuffer--;
+ }
+ iOutputBuffer += ( 1 - startPos - aYOffset );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSynthesis::TwoDimBlockFiltering
+// Perform two dimensional inverse wavelet transformation ( block-based )
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSynthesis::TwoDimBlockFiltering( TPrecInt** aImage, TSize aRegion, CJ2kSubband* aSubband,
+ TPoint aOffset, TUint8 aCurrentLevel )
+ {
+ TInt32 index = 0;
+ TUint32 xtcSiz = aRegion.iWidth;
+ TUint32 ytcSiz = aRegion.iHeight;
+
+ // For block filtering we have the data in two blocks ( column-wise ),
+ // from 0 to ( ytcsiz+1 )>>1 ( +1 to take care of odd number of samples )
+ // and from KWaveletBlockMidPoint to KWaveletBlockMidPoint+( ( ytcsiz+1 )>>1 ).
+ index = KWaveletBlockMidPoint + ( ( ytcSiz+1 ) >> 1 ) - 1;
+
+ // First apply horizontal filter to the ( vertically ) high-pass samples
+ for ( ; index >= KWaveletBlockMidPoint; index-- )
+ {
+ HorizontalBlockFilter( aImage, index, xtcSiz, aSubband, aOffset.iX, aCurrentLevel );
+ }
+
+ // Then apply horizontal filter to the ( vertically ) low-pass samples
+ index = ( ( ytcSiz+1 ) >> 1 ) - 1;
+ for ( ; index >= 0; index-- )
+ {
+ HorizontalBlockFilter( aImage, index, xtcSiz, aSubband, aOffset.iX, aCurrentLevel );
+ }
+
+ // Because of the horizontal filtering, the data is now in one block row-wise, thus
+ // two loops are not needed for vertical fitering.
+ index = xtcSiz-1-( (TUint32)( aOffset.iX ) >> 1 );
+ for ( ; index >= 0; index-- )
+ {
+ VerticalBlockFilter( aImage, index, ytcSiz, aSubband, aOffset.iY, aCurrentLevel );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSynthesis::SingleLevelWaveletInverse
+// Perform a full inverse wavelet transformation ( block-based )
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSynthesis::SingleLevelWaveletInverse( TPrecInt **aImage, CJ2kSubband *aSubband,
+ TPoint aOffset, TSize aRegion, TUint8 aCurrentLevel )
+ {
+ if ( aRegion.iWidth > 0 && aRegion.iHeight > 0 )
+ {
+ aSubband = aSubband->Parent();
+ TwoDimBlockFiltering( aImage, aRegion, aSubband, aOffset, aCurrentLevel );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSynthesis::CopyDataToBlock
+// Apply inverse quantization and ROI shifting on the decoded
+// codeblock and copy to the image writer ( block-based ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSynthesis::CopyDataToBlock( CJ2kEntropyDecoder& aEntropyDecoder, TPrecInt** aImageBlock,
+ CJ2kSubband& aSubband, TUint8 aQuantizationStyle,
+ TInt32 aStartRowCblk, TInt32 aStartColCblk,
+ TInt32 aStartRowImage, TInt32 aStartColImage,
+ TInt32 aCblkHeight, TInt32 aCblkWidth )
+ {
+ TPrecInt* buffer = 0; // To buffer one row of the image_block
+ TPrecInt* imageRow = 0; // One row of the image
+ TPrecInt valueInt = 0;
+ TInt32 value = 0;
+ TInt32 j = 0;
+
+ TInt32 startRowImageBlock = aStartRowImage; // Start row's index in the image to copy to
+ TInt32 startColImageBlock = aStartColImage; // Start column's index in the image to copy to
+
+ TUint8 aBandIndex = (TUint8)( aSubband.SubbandType() );
+
+ // Adjust the place where to copy the data according to the subband type
+ // ( i.e. whether we have LL, HL, LH or HH band ).
+ if( aBandIndex == 1 )
+ {
+ startColImageBlock += KWaveletBlockMidPoint;
+ }
+ else if( aBandIndex == 2 )
+ {
+ startRowImageBlock += KWaveletBlockMidPoint;
+ }
+ else if( aBandIndex == 3 )
+ {
+ startRowImageBlock += KWaveletBlockMidPoint;
+ startColImageBlock += KWaveletBlockMidPoint;
+ }
+
+ // Compute the end of the copy region
+ TInt32 endRowImageBlock = startRowImageBlock + aCblkHeight - 1; //lint !e961 no else is needed here at the end of if...else if
+ TInt32 endColImageBlock = startColImageBlock + aCblkWidth;
+
+ // Index of the row to copy from in the codeblock
+ TInt32 codeblockRow = aStartRowCblk + aCblkHeight-1;
+
+ // Index of the row to copy from in the codeblock
+ TInt32 codeblockColumn = aStartColCblk + aCblkWidth-1;
+
+ if ( iROIShift ) // ROI shifting is used
+ {
+ // Compute mask to determine which samples are in ROI
+ // for mask ROI coefficients
+ TInt32 mask = ( ( 1 << iMagnitudeBitsHere ) - 1 ) << ( ( KImplementationPrecision - 1 ) - iMagnitudeBitsHere );
+ TInt32 mask2 = ( ~mask ) & KMaximumPrecisionInteger;
+ TInt32 mask3 = ( ( 1 << iROIShift ) - 1 ) << ( ( KImplementationPrecision - 1 ) - iROIShift );
+ TInt32 maskShift = ( ~mask3 ) & KMaximumPrecisionInteger;
+
+ if ( !aQuantizationStyle )
+ {
+ // Shift all the samples in the codeblock
+ TInt32 roiDataShift = ( iROIDataShift < 0 ) ? -iROIDataShift : iROIDataShift;
+
+ for ( ; endRowImageBlock >= startRowImageBlock; endRowImageBlock--,codeblockRow-- )
+ {
+ buffer = aEntropyDecoder.iData[codeblockRow] + codeblockColumn;
+ for ( j = endColImageBlock-1; j >= startColImageBlock; j-- )
+ {
+ value = ( *buffer-- );
+ if ( !( value & mask ) ) // Background
+ {
+ if ( iROIDataShift < 0 )
+ {
+ aImageBlock[endRowImageBlock][j] = ( value < 0 ) ? -( ( value & KMaximumPrecisionInteger ) << roiDataShift )
+ : ( value << roiDataShift );
+ }
+ else
+ {
+ aImageBlock[endRowImageBlock][j] = ( value < 0 ) ? -( ( value & maskShift ) >> roiDataShift ) //lint !e704 value&maskShift is positive, so no risk of right shifting negative values
+ : ( ( value & maskShift ) >> roiDataShift ); //lint !e704 value&maskShift is positive, so no risk of right shifting negative values
+ }
+ }
+ else // ROI
+ {
+ if ( value & mask2 )
+ {
+ // Decoded more than magbits bit-planes, set
+ // quantization mid-interval approx. bit just after
+ // the magbits.
+ value &= ( ~mask2 );
+ }
+ aImageBlock[endRowImageBlock][j] = ( value < 0 ) ? -( ( value & KMaximumPrecisionInteger ) >> iDataShift )
+ : ( value >> iDataShift ); //lint !e704 value is positive here
+ }
+ }
+ }
+ }
+ else // Irreversible case
+ {
+ // Shift all the samples in the codeblock
+ TInt32 stepExponent = ( iStepExponent < 0 ) ? -iStepExponent : iStepExponent;
+
+ // Divide into two cases depending on the sign of the iStepExponent to speed up coding
+ if ( iStepExponent < 0 )
+ {
+ for ( ; endRowImageBlock >= startRowImageBlock; endRowImageBlock--, codeblockRow-- )
+ {
+ buffer = aEntropyDecoder.iData[codeblockRow] + codeblockColumn;
+ for ( j = endColImageBlock-1; j >= startColImageBlock; j-- )
+ {
+ value = ( *buffer-- );
+
+ // Divide into two cases depending on whether value is negative
+ if ( value < 0 )
+ {
+ if ( !( value & mask ) ) // Background
+ {
+ value = ( ( value & maskShift ) >> iROIDataShift ); //lint !e704 value&maskShift is positive, so no risk of right shifting negative values
+ valueInt = -( ( value * iStepValue ) >> stepExponent ); //lint !e704 value*iStepValue is positive
+ }
+ else // ROI
+ {
+ if ( value & mask2 )
+ {
+ // Decoded more than magbits bit-planes, set
+ // quantization mid-interval approx. bit just after
+ // the magbits.
+ value = ( value & ( ~mask2 ) ) | ( 1 << ( KImplementationPrecision - 2 - iMagnitudeBitsHere ) );
+ }
+
+ value = ( ( value & KMaximumPrecisionInteger ) >> iDataShift );
+ valueInt = -( ( value * iStepValue ) >> stepExponent ); //lint !e704 value*iStepValue is positive
+ }
+ }
+ else // Value is non-negative
+ {
+ if ( !( value & mask ) ) // Background
+ {
+ value = ( ( value & maskShift ) >> iROIDataShift ); //lint !e704 value&maskShift is positive, so no risk of right shifting negative values
+ valueInt = ( ( value * iStepValue ) >> stepExponent ); //lint !e704 value*iStepValue is positive
+ }
+ else // ROI
+ {
+ if ( value & mask2 )
+ {
+ // Decoded more than magbits bit-planes, set
+ // quantization mid-interval approx. bit just after
+ // the magbits.
+ value = ( value & ( ~mask2 ) ) | ( 1 << ( KImplementationPrecision - 2 - iMagnitudeBitsHere ) );
+ }
+
+ value = ( ( value & KMaximumPrecisionInteger ) >> iDataShift );
+ valueInt = ( ( value * iStepValue ) >> stepExponent ); //lint !e704 value*iStepValue is positive
+ }
+ }
+
+ aImageBlock[endRowImageBlock][j] = valueInt;
+ }
+ }
+ }
+ else // iStepExponent is non-negative
+ {
+ for ( ; endRowImageBlock >= startRowImageBlock; endRowImageBlock--,codeblockRow-- )
+ {
+ buffer = aEntropyDecoder.iData[codeblockRow] + codeblockColumn;
+ for ( j = endColImageBlock-1; j >= startColImageBlock; j-- )
+ {
+ value = ( *buffer-- );
+ if ( !( value & mask ) ) // Background
+ {
+ if ( value < 0 ) // Get the sign
+ {
+ value = -( ( value & maskShift ) >> iROIDataShift ); //lint !e704 value&maskShift is positive, so no risk of right shifting negative values
+ }
+ else
+ {
+ value = ( ( value & maskShift ) >> iROIDataShift ); //lint !e704 value&maskShift is positive, so no risk of right shifting negative values
+ }
+
+ valueInt = ( ( value * iStepValue ) << stepExponent );
+ }
+ else // ROI
+ {
+ if ( value & mask2 )
+ {
+ // Decoded more than magbits bit-planes, set
+ // quantization mid-interval approx. bit just after
+ // the magbits.
+ value = ( value & ( ~mask2 ) ) | ( 1 << ( KImplementationPrecision - 2 - iMagnitudeBitsHere ) );
+ }
+ if ( value < 0 )
+ {
+ value = -( ( value & KMaximumPrecisionInteger ) >> iDataShift );
+ }
+ else
+ {
+ value = ( ( value & KMaximumPrecisionInteger ) >> iDataShift );
+ }
+
+ valueInt = ( ( value * iStepValue ) << stepExponent );
+ }
+ aImageBlock[endRowImageBlock][j] = valueInt;
+ }
+ }
+ }
+ }
+ }
+ else // ROI is not present
+ {
+ if ( !aQuantizationStyle )
+ {
+ // Shift all the samples in the codeblock
+ TInt32 i = codeblockRow;
+ for ( ; endRowImageBlock >= startRowImageBlock; endRowImageBlock--, i-- )
+ {
+ imageRow = aImageBlock[endRowImageBlock] + endColImageBlock - 1;
+ buffer = aEntropyDecoder.iData[i] + codeblockColumn;
+
+ for ( j = endColImageBlock-1; j >= startColImageBlock; j-- )
+ {
+ value = *buffer--;
+ if ( value < 0 )
+ {
+ *imageRow-- = -( ( value & KMaximumPrecisionInteger ) >> iDataShift );
+ }
+ else
+ {
+ *imageRow-- = value >> iDataShift; //lint !e704 value is positive here
+ }
+ }
+ }
+ }
+ else // Irreversible case
+ {
+ // Shift all the samples in the codeblock
+ TInt32 stepExponent = ( iStepExponent < 0 ) ? -iStepExponent : iStepExponent;
+
+ // Divide into two cases depending on the sign of the iStepExponent to speed up coding
+ if ( iStepExponent < 0 )
+ {
+ for ( ; endRowImageBlock >= startRowImageBlock; endRowImageBlock--,codeblockRow-- )
+ {
+ buffer = aEntropyDecoder.iData[codeblockRow] + codeblockColumn;
+ for ( j = endColImageBlock-1; j >= startColImageBlock; j-- )
+ {
+ value = ( *buffer-- );
+
+ if ( value < 0 ) // Negative value
+ {
+ value = ( ( value & KMaximumPrecisionInteger ) >> iDataShift );
+ aImageBlock[endRowImageBlock][j] = (TPrecInt)( -( ( value * iStepValue ) >> stepExponent ) ); //lint !e704 value*iStepValue is positive
+ }
+ else
+ {
+ value = ( ( value & KMaximumPrecisionInteger ) >> iDataShift );
+ aImageBlock[endRowImageBlock][j] = (TPrecInt)( ( value * iStepValue ) >> stepExponent ); //lint !e704 value*iStepValue is positive
+ }
+ }
+ }
+ }
+ else // iStepExponent is non-negative
+ {
+ for ( ; endRowImageBlock >= startRowImageBlock; endRowImageBlock--,codeblockRow-- )
+ {
+ buffer = aEntropyDecoder.iData[codeblockRow] + codeblockColumn;
+ for ( j = endColImageBlock-1; j >= startColImageBlock; j-- )
+ {
+ value = ( *buffer-- );
+
+ if ( value < 0 ) // Negative value
+ {
+ value = ( ( value & KMaximumPrecisionInteger ) >> iDataShift );
+ aImageBlock[endRowImageBlock][j] = (TPrecInt)( -( ( value * iStepValue ) << stepExponent ) );
+ }
+ else
+ {
+ value = ( ( value & KMaximumPrecisionInteger ) >> iDataShift );
+ aImageBlock[endRowImageBlock][j] = (TPrecInt)( ( value * iStepValue ) << stepExponent );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // If number of levels is zero then we have to do the
+ // inverse wavelet shifting here.
+ //
+ if ( iWaveletLevels == 0 )
+ {
+ endRowImageBlock = startRowImageBlock + aCblkHeight;
+ endColImageBlock = startColImageBlock + aCblkWidth;
+
+ if ( aQuantizationStyle )
+ {
+ for ( TInt32 i = endRowImageBlock - 1; i >= startRowImageBlock; i-- )
+ {
+ for ( j = endColImageBlock - 1; j >= startColImageBlock; j-- )
+ {
+ aImageBlock[i][j] >>= KWaveletShift; //lint !e704 shifting is OK.
+ }
+ }
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSynthesis::FillDataWithZeros
+// Fill a block in image writer with zeros ( corresponding to an empty block )
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSynthesis::FillDataWithZeros( TPrecInt** aImageBlock, CJ2kSubband& aSubband,
+ TInt32 aStartRowImage, TInt32 aStartColImage,
+ TInt32 aCblkHeight, TInt32 aCblkWidth )
+ {
+ TPrecInt* imageRow = 0; // One row of the image
+ TInt32 j = 0;
+
+ TInt32 startRowImageBlock = aStartRowImage; // Start row's index in the image to copy to
+ TInt32 startColImageBlock = aStartColImage; // Start column's index in the image to copy to
+
+ TUint8 aBandIndex = (TUint8)( aSubband.SubbandType() );
+
+ // Adjust the place where to copy the data according to the subband type
+ // ( i.e. whether we have LL, HL, LH or HH band ).
+ if( aBandIndex == 1 )
+ {
+ startColImageBlock += KWaveletBlockMidPoint;
+ }
+ else if( aBandIndex == 2 )
+ {
+ startRowImageBlock += KWaveletBlockMidPoint;
+ }
+ else if( aBandIndex == 3 )
+ {
+ startRowImageBlock += KWaveletBlockMidPoint;
+ startColImageBlock += KWaveletBlockMidPoint;
+ }
+
+ // Compute the end of the copy region
+ TInt32 endRowImageBlock = startRowImageBlock + aCblkHeight - 1; //lint !e961 no else is needed here at the end of if...else if
+ TInt32 endColImageBlock = startColImageBlock + aCblkWidth;
+
+ // Shift all the samples in the codeblock
+ for ( ; endRowImageBlock >= startRowImageBlock; endRowImageBlock-- )
+ {
+ imageRow = aImageBlock[endRowImageBlock] + endColImageBlock - 1;
+ for ( j = endColImageBlock-1; j >= startColImageBlock; j-- )
+ {
+ *imageRow-- = 0;
+ }
+ }
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Src/JP2KTileInfo.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,1323 @@
+/*
+* Copyright (c) 2003, 2004 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: CJ2kTileInfo class used to collect tile related information
+* such as Tile Part Header, SOT marker and list of components.
+*
+*/
+
+
+// INCLUDE FILES
+#include <icl/imagecodec.h>
+#include "JP2KImageUtils.h"
+#include "JP2KFormat.h"
+#include "JP2KStreamReader.h"
+#include "JP2KTileInfo.h"
+#include "JP2KImageInfo.h"
+#include "JP2KCodec.h"
+#include "JP2KComponentInfo.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::NewLC
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CJ2kTileInfo* CJ2kTileInfo::NewLC( CJ2kImageInfo& aImageInfo, TJ2kStreamReader& aReader )
+ {
+ CJ2kTileInfo* self = new ( ELeave ) CJ2kTileInfo( aImageInfo, aReader );
+
+ CleanupStack::PushL( self );
+
+ return self;
+ }
+
+// Destructor
+CJ2kTileInfo::~CJ2kTileInfo()
+ {
+ DoReleaseUnusedMarkers();
+
+ iComponentList.ResetAndDestroy();
+
+ delete iPpt;
+ iPpt = 0;
+
+ delete iPptBuffer;
+ iPptBuffer = 0;
+
+ // iPOC not owned - not deleted.
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::InitializeL
+// Initialize the components in the tile.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kTileInfo::InitializeL()
+ {
+ const TSizMarker &sizMarker = iImageInfo.SizMarker();
+ TUint16 numOfHorizTiles = iImageInfo.NumOfHorizTiles();
+
+ // Calculate the tile canvas
+ TDiv tDiv = TJ2kUtils::Div( iSot.iIsot, numOfHorizTiles );
+ iTileCanvas.iTl = TPoint( Max( sizMarker.iXTOsiz + tDiv.rem * sizMarker.iXTsiz, sizMarker.iXOsiz ),
+ Max( sizMarker.iYTOsiz + tDiv.quot * sizMarker.iYTsiz, sizMarker.iYOsiz ) );
+ iTileCanvas.iBr = TPoint( Min( sizMarker.iXTOsiz + ( tDiv.rem + 1 ) * sizMarker.iXTsiz, sizMarker.iXsiz ),
+ Min( sizMarker.iYTOsiz + ( tDiv.quot + 1 ) * sizMarker.iYTsiz, sizMarker.iYsiz ) );
+
+ CJ2kComponentInfo *component = 0;
+ for ( TUint16 index = 0; index < sizMarker.iCsiz; ++index )
+ {
+ // Instantiate the components in the tile
+ component = CJ2kComponentInfo::NewLC( *this, index );
+ User::LeaveIfError( iComponentList.Append( component ) );
+ CleanupStack::Pop();
+ }
+
+ iLastN1 = iTileCanvas.iTl.iY;
+ iLastN2 = iTileCanvas.iTl.iX;
+
+ // Initialize the end of layer, resolution level, component to process
+ iNumOfLayersPOC = NumOfLayers();
+ iNumOfLevelsPOC = NumOfLevels();
+ iNumOfComponentsPOC = sizMarker.iCsiz;
+
+ if ( IsSpeedup() )
+ {
+ iNumOfLevelsPOC = (TUint8)( iNumOfLevelsPOC - iImageInfo.LevelDrop() );
+ }
+
+ // Let iPOC points to the POC marker in Tile Part Header
+ iPOC = iTileMarker.iPoc;
+ if ( !iPOC )
+ {
+ // Let iPOC points to the POC marker in the Main Header
+ iPOC = iImageInfo.MainMarker().iPoc;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::AppendCOD
+// Verify and append COD to the tile part header.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kTileInfo::AppendCOD( TCODMarker *aMarker, TUint32 aLength )
+ {
+ if ( iSot.iTPsot == 0 )
+ {
+ // Use only for the first tile part of a tile
+ if ( iTileMarker.iCod == 0 )
+ {
+ iTileMarker.iCod = aMarker;
+ }
+ else
+ {
+ // No more than one COD per tile
+ delete aMarker;
+ aMarker = 0;
+ }
+ }
+ else
+ {
+ // Read but ignore it
+ delete aMarker;
+ aMarker = 0;
+ }
+
+ if ( iTileLength )
+ {
+ iTileLength -= aLength;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::AppendCOCL
+// Verify and append COC to the tile part header.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kTileInfo::AppendCOCL( TCOCMarker *aMarker, TUint32 aLength )
+ {
+ if ( iSot.iTPsot == 0 )
+ {
+ // Use only for the first tile part of a tile
+ TUint8 found = EFalse;
+ for ( TUint16 index = 0; index < iTileMarker.iCoc.Count(); ++index )
+ {
+ if ( iTileMarker.iCoc[index]->iCcoc == aMarker->iCcoc )
+ {
+ found = ETrue;
+ index = (TUint16)iTileMarker.iCoc.Count();
+ }
+ }
+ if ( !found )
+ {
+ User::LeaveIfError( iTileMarker.iCoc.Append( aMarker ) );
+ }
+ else
+ {
+ // No more than one COC per component
+ delete aMarker;
+ aMarker = 0;
+ }
+ }
+ else
+ {
+ // Read but ignore it
+ delete aMarker;
+ aMarker = 0;
+ }
+
+ if ( iTileLength )
+ {
+ iTileLength -= aLength;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::AppendQCD
+// Verify and append QCD to the tile part header.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kTileInfo::AppendQCD( TQCDMarker *aMarker, TUint32 aLength )
+ {
+ if ( iSot.iTPsot == 0 )
+ {
+ // Use only for the first tile part of a tile
+ if ( iTileMarker.iQcd == 0 )
+ {
+ iTileMarker.iQcd = aMarker;
+ }
+ else
+ {
+ // No more than one QCD per tile
+ delete aMarker;
+ aMarker = 0;
+ }
+ }
+ else
+ {
+ // Read but ignore it
+ delete aMarker;
+ aMarker = 0;
+ }
+
+ if ( iTileLength )
+ {
+ iTileLength -= aLength;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::AppendQCCL
+// Verify and append QCC to the tile part header.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kTileInfo::AppendQCCL( TQCCMarker *aMarker, TUint32 aLength )
+ {
+ if ( iSot.iTPsot == 0 )
+ {
+ // Use only for the first tile part of a tile
+ TUint8 found = EFalse;
+ for ( TUint16 index = 0; index < iTileMarker.iQcc.Count(); ++index )
+ {
+ if ( iTileMarker.iQcc[index]->iCqcc == aMarker->iCqcc )
+ {
+ found = ETrue;
+ index = (TUint16)iTileMarker.iQcc.Count();
+ }
+ }
+ if ( !found )
+ {
+ User::LeaveIfError( iTileMarker.iQcc.Append( aMarker ) );
+ }
+ else
+ {
+ // No more than one QCC per component
+ delete aMarker;
+ aMarker = 0;
+ }
+ }
+ else
+ {
+ // read but ignore it
+ delete aMarker;
+ aMarker = 0;
+ }
+
+ if ( iTileLength )
+ {
+ iTileLength -= aLength;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::AppendRGNL
+// Verify and append RGN to the tile part header.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kTileInfo::AppendRGNL( TRGNMarker *aMarker, TUint32 aLength )
+ {
+ if ( iSot.iTPsot == 0 )
+ {
+ // Use only for the first tile part of a tile
+ TUint8 found = EFalse;
+ for ( TUint16 index = 0; index < iTileMarker.iRgn.Count(); ++index )
+ {
+ if ( iTileMarker.iRgn[index]->iCrgn == aMarker->iCrgn )
+ {
+ found = ETrue;
+ index = (TUint16)iTileMarker.iRgn.Count();
+ }
+ }
+ if ( !found )
+ {
+ User::LeaveIfError( iTileMarker.iRgn.Append( aMarker ) );
+ }
+ else
+ {
+ // No more than one RGN per component
+ delete aMarker;
+ aMarker = 0;
+ }
+ }
+ else
+ {
+ // Read but ignore it
+ delete aMarker;
+ aMarker = 0;
+ }
+
+ if ( iTileLength )
+ {
+ iTileLength -= aLength;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::AppendPOCL
+// Verify and append POC to the tile part header.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kTileInfo::AppendPOCL( TPOCMarker *aMarker, TUint32 aLength )
+ {
+ if ( iTileMarker.iPoc == 0 )
+ {
+ iTileMarker.iPoc = aMarker;
+ }
+ else
+ {
+ // Appending the content of the POC to the
+ // existing tile part header POC
+ for ( TInt index = 0; index < aMarker->iPpoc.Count(); ++index )
+ {
+ User::LeaveIfError( iTileMarker.iPoc->iRSpoc.Append( aMarker->iRSpoc[index] ) );
+ User::LeaveIfError( iTileMarker.iPoc->iCSpoc.Append( aMarker->iCSpoc[index] ) );
+ User::LeaveIfError( iTileMarker.iPoc->iLYEpoc.Append( aMarker->iLYEpoc[index] ) );
+ User::LeaveIfError( iTileMarker.iPoc->iREpoc.Append( aMarker->iREpoc[index] ) );
+ User::LeaveIfError( iTileMarker.iPoc->iCEpoc.Append( aMarker->iCEpoc[index] ) );
+ User::LeaveIfError( iTileMarker.iPoc->iPpoc.Append( aMarker->iPpoc[index] ) );
+ }
+ // At most one POC may exist in tile part header
+ delete aMarker;
+ aMarker = 0;
+ }
+
+ if ( iTileLength )
+ {
+ iTileLength -= aLength;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::AppendCOML
+// Verify and append COM to the tile part header.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kTileInfo::AppendCOML( TCOMMarker *aMarker, TUint32 aLength )
+ {
+ User::LeaveIfError( iTileMarker.iCom.Append( aMarker ) );
+
+ if ( iTileLength )
+ {
+ iTileLength -= aLength;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::AppendPPTL
+// Verify and append PPT to the tile part header.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kTileInfo::AppendPPTL( TPPTMarker *aMarker, TUint32 aLength )
+ {
+ TUint8 inserted = EFalse;
+
+ // Insert the new PPT marker into the right order
+ for ( TUint16 index = 0; index < iTileMarker.iPpt.Count(); ++index )
+ {
+ // Order by iZppt of the PPT marker
+ if ( iTileMarker.iPpt[index]->iZppt > aMarker->iZppt )
+ {
+ User::LeaveIfError( iTileMarker.iPpt.Insert( aMarker, index ) );
+ inserted = ETrue;
+ index = (TUint16)( iTileMarker.iPpt.Count() );
+ }
+ }
+
+ if ( !inserted )
+ {
+ User::LeaveIfError( iTileMarker.iPpt.Append( aMarker ) );
+ }
+ if ( iTileLength )
+ {
+ iTileLength -= aLength;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::AppendPLTL
+// Verify and append PLT to the tile part header.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kTileInfo::AppendPLTL( TPLTMarker *aMarker, TUint32 aLength )
+ {
+ TUint8 inserted = EFalse;
+
+ // Insert the new PLT marker into the right order
+ for ( TUint16 index = 0; index < iTileMarker.iPlt.Count(); ++index )
+ {
+ // Order by iZplt of the PLT marker
+ if ( iTileMarker.iPlt[index]->iZplt > aMarker->iZplt )
+ {
+ User::LeaveIfError( iTileMarker.iPlt.Insert( aMarker, index ) );
+ inserted = ETrue;
+ index = (TUint16)( iTileMarker.iPlt.Count() );
+ }
+ }
+
+ if ( !inserted )
+ {
+ User::LeaveIfError( iTileMarker.iPlt.Append( aMarker ) );
+ }
+
+ if ( iTileLength )
+ {
+ iTileLength -= aLength;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::ReadBitStreamL
+// Parsing the bitstream data based on progression order.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kTileInfo::ReadBitStreamL( TUint8 aBool )
+ {
+ SetCheckMarker( aBool );
+ if ( iPOC )
+ {
+ TUint8 incomplete = EFalse;
+ while ( iLastPOC < iPOC->iPpoc.Count() )
+ {
+ if ( !iDoLoadPOC )
+ {
+ // Reload progression order change from POC marker
+ iDoLoadPOC = ETrue;
+ iLastLayer = 0;
+ iLastLevelOrig = iLastLevel = (TUint8)iPOC->iRSpoc[iLastPOC];
+ iLastComponentOrig = iLastComponent = (TUint16)iPOC->iCSpoc[iLastPOC];
+
+ iNumOfLayersPOC = (TUint16)iPOC->iLYEpoc[iLastPOC];
+ if ( iNumOfLayersPOC > NumOfLayers() )
+ {
+ iNumOfLayersPOC = NumOfLayers();
+ }
+
+ iNumOfLevelsPOC = (TUint8)( iPOC->iREpoc[iLastPOC] - 1 );
+ if ( iNumOfLevelsPOC > (TUint8)NumOfLevels() )
+ {
+ iNumOfLevelsPOC = (TUint8)NumOfLevels();
+ }
+
+ iNumOfComponentsPOC = (TUint16)iPOC->iCEpoc[iLastPOC];
+ if ( iNumOfComponentsPOC > NumOfComponents() )
+ {
+ iNumOfComponentsPOC = NumOfComponents();
+ }
+
+ for ( TUint16 index = 0; index < iNumOfComponentsPOC; ++index )
+ {
+ iComponentList[index]->ResetLastPacketProcessed();
+ }
+
+ iLastN2 = iTileCanvas.iTl.iX;
+ iLastN1 = iTileCanvas.iTl.iY;
+ }
+
+ switch ( iPOC->iPpoc[iLastPOC] )
+ {
+ case EProgression_L_R_C_P:
+ {
+ incomplete = LRCPProgressionL();
+ break;
+ }
+ case EProgression_R_L_C_P:
+ {
+ incomplete = RLCPProgressionL();
+ break;
+ }
+ case EProgression_R_P_C_L:
+ {
+ incomplete = RPCLProgressionL();
+ break;
+ }
+ case EProgression_P_C_R_L:
+ {
+ incomplete = PCRLProgressionL();
+ break;
+ }
+ case EProgression_C_P_R_L:
+ {
+ incomplete = CPRLProgressionL();
+ break;
+ }
+ default:
+ {
+ // Unrecognized progressin order
+ User::Leave( KErrCorrupt );
+ break;
+ }
+ }
+
+ if ( incomplete )
+ {
+ break; //lint !e960 It is Ok to break here.
+ }
+
+ if ( iLastPOC == iPOC->iPpoc.Count() && !iDoLoadPOC )
+ {
+ // Try to use Main POC if it is currently using Tile POC
+ if ( iTileMarker.iPoc && iPOC == iTileMarker.iPoc )
+ {
+ if ( iImageInfo.MainMarker().iPoc )
+ {
+ iPOC = iImageInfo.MainMarker().iPoc;
+ iLastPOC = 0;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // Without POC changes
+ switch ( ProgressionOrder() )
+ {
+ case EProgression_L_R_C_P:
+ {
+ LRCPProgressionL();
+ break;
+ }
+ case EProgression_R_L_C_P:
+ {
+ RLCPProgressionL();
+ break;
+ }
+ case EProgression_R_P_C_L:
+ {
+ RPCLProgressionL();
+ break;
+ }
+ case EProgression_P_C_R_L:
+ {
+ PCRLProgressionL();
+ break;
+ }
+ case EProgression_C_P_R_L:
+ {
+ CPRLProgressionL();
+ break;
+ }
+ default:
+ {
+ // Unrecognized progression order
+ User::Leave( KErrCorrupt );
+ break;
+ }
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::ColorTransformation
+// Get the color transformation.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kTileInfo::ColorTransformation() const
+ {
+ return ( iTileMarker.iCod ) ?
+ iTileMarker.iCod->iColorTransformation :
+ iImageInfo.MainMarker().iCod.iColorTransformation;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::ProgressionOrder
+// Get the progression order.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kTileInfo::ProgressionOrder() const
+ {
+ return ( iTileMarker.iCod ) ?
+ iTileMarker.iCod->iProgressionOrder :
+ iImageInfo.MainMarker().iCod.iProgressionOrder;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::NumOfLayers
+// Get the number of layers.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint16 CJ2kTileInfo::NumOfLayers() const
+ {
+ return ( iTileMarker.iCod ) ?
+ iTileMarker.iCod->iNumOfLayers :
+ iImageInfo.MainMarker().iCod.iNumOfLayers;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::NumOfLevels
+// Get the number of resolution level.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kTileInfo::NumOfLevels() const
+ {
+ TUint8 maxLevel = 0;
+ for ( TUint16 index = 0; index < iImageInfo.NumOfComponents(); ++index )
+ {
+ maxLevel = Max( maxLevel, iComponentList[index]->Levels() );
+ }
+
+ return maxLevel;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::GetMinGrid
+// Get the minimum grid among the components in the tile.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kTileInfo::GetMinGrid( TSize &aGrid ) const
+ {
+ TSize tmpGrid;
+ aGrid = iComponentList[0]->MinGrid();
+ for ( TUint16 index = 1; index < iImageInfo.NumOfComponents(); ++index )
+ {
+ tmpGrid = iComponentList[index]->MinGrid();
+ aGrid.iWidth = Min( aGrid.iWidth, tmpGrid.iWidth );
+ aGrid.iHeight = Min( aGrid.iHeight, tmpGrid.iHeight );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::UsePPTL
+// Set up to read the packet header from the PPT marker.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kTileInfo::UsePPTL()
+ {
+ if ( !iPpt )
+ {
+ iPpt = new ( ELeave ) TPPTStream;
+ }
+ Mem::FillZ( iPpt, sizeof( TPPTStream ) );
+
+ // Remove the previous ppt buffer
+ delete iPptBuffer;
+ iPptBuffer = 0;
+
+ if ( iTileMarker.iPpt.Count() > 1 )
+ {
+ // Concatenate all PPT markers into one
+ TInt bytes = 0;
+ TInt index = 0;
+ for ( index = 0; index < iTileMarker.iPpt.Count(); ++index )
+ {
+ bytes += iTileMarker.iPpt[index]->iIppt->Length();
+ }
+
+ iPptBuffer = HBufC8::NewL( bytes );
+ iPpt->iPtrEnd = (TUint32)bytes;
+ TPtr8 ptr = iPptBuffer->Des();
+ for ( index = 0; index < iTileMarker.iPpt.Count(); ++index )
+ {
+ ptr.Append( iTileMarker.iPpt[index]->iIppt->Ptr(), iTileMarker.iPpt[index]->iIppt->Length() );
+ }
+ }
+ else
+ {
+ // Use the only PPT marker
+ // transfer the ownership of the buffer from PPT to iPptBuffer
+ iPptBuffer = iTileMarker.iPpt[0]->iIppt;
+ iPpt->iPtrEnd = iPptBuffer->Length();
+ iTileMarker.iPpt[0]->iIppt = 0;
+ }
+
+ // PPT markers can be released
+ iTileMarker.iPpt.ResetAndDestroy();
+ iPacketHeaderReader = STATIC_CAST( MJ2kPacketHeaderReader*, this );
+ }
+
+// -----------------------------------------------------------------------------
+// From MJ2kPacketHeaderReader
+// CJ2kTileInfo::ReadEPHMarker
+// Try to consume the EPH marker if there is one.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kTileInfo::ReadEPHMarker()
+ {
+ if ( iPpt && ( iPpt->iPtrEnd - iPpt->iPtr ) >= 2 )
+ {
+ const TUint8 *ptr = iPptBuffer->Ptr();
+ ptr += iPpt->iPtr;
+ if ( PtrReadUtil::ReadBigEndianUint16( ptr ) == KEPH )
+ {
+ iPpt->iPtr += 2;
+ }
+ }
+
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// From MJ2kPacketHeaderReader
+// CJ2kTileInfo::ReadBit
+// Read a bit from the packet header stream.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kTileInfo::ReadBit( TUint8& aBit )
+ {
+ if ( iPpt->iPos == 0 )
+ {
+ if ( iPpt->iPtr < iPpt->iPtrEnd )
+ {
+ // Stream contains some packet header data
+ iPpt->iData = ( *iPptBuffer )[iPpt->iPtr++];
+ iPpt->iPos = iPpt->iNextPos;
+ if ( iPpt->iNextPos == 0x08 && iPpt->iData == 0xff )
+ {
+ iPpt->iNextPos = 0x07;
+ }
+ else
+ {
+ iPpt->iNextPos = 0x08;
+ }
+ }
+ else
+ {
+ // No more data
+ return ETrue;
+ }
+ }
+ aBit = (TUint8)( ( iPpt->iData >> ( --iPpt->iPos ) ) & 0x01 );
+
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// From MJ2kPacketHeaderReader
+// CJ2kTileInfo::ReadBits
+// Read some bits from the packet header stream.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kTileInfo::ReadBits( TUint8& aBit, TUint8 aBitLen )
+ {
+ aBit = (TUint8)0;
+ TUint8 bit = 0;
+ for ( TInt8 index = (TInt8)( aBitLen - 1 ); index >= 0; --index )
+ {
+ if ( !ReadBit( bit ) )
+ {
+ aBit |= ( bit << index );
+ }
+ else
+ {
+ return ETrue;
+ }
+ }
+
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// From MJ2kPacketHeaderReader
+// CJ2kTileInfo::ReadBits
+// Read some bits from the packet header stream.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kTileInfo::ReadBits( TUint32& aBit, TUint8 aBitLen )
+ {
+ aBit = ( TUint32 )0;
+ TUint8 bit = 0;
+ for ( TInt8 index = ( TInt8 )( aBitLen - 1 ); index >= 0; --index )
+ {
+ if ( !ReadBit( bit ) )
+ {
+ aBit |= ( bit << index );
+ }
+ else
+ {
+ return ETrue;
+ }
+ }
+
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// From MJ2kPacketHeaderReader
+// CJ2kTileInfo::StartReadBit
+// Start reading from packet header stream.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kTileInfo::StartReadBit()
+ {
+ if ( iPpt && iPpt->iPtr < iPpt->iPtrEnd )
+ {
+ // Stream contains some packet header data
+ iPpt->iData = ( *iPptBuffer )[iPpt->iPtr++];
+ iPpt->iPos = iPpt->iNextPos = 0x08;
+ if ( iPpt->iData == 0xff )
+ {
+ iPpt->iNextPos = 0x07;
+ }
+
+ return EFalse;
+ }
+ return ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// From MJ2kPacketHeaderReader
+// CJ2kTileInfo::AlignReader
+// Align the stream to the next byte boundary if necessary.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kTileInfo::AlignReader()
+ {
+ if ( iPpt->iNextPos == 0x07 )
+ {
+ if ( iPpt->iPtr < iPpt->iPtrEnd )
+ {
+ ++iPpt->iPtr;
+ }
+ }
+ iPpt->iData = iPpt->iPos = iPpt->iNextPos = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::DoReleaseUnusedMarkers
+// Release unused markers in tile part header.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kTileInfo::DoReleaseUnusedMarkers()
+ {
+ delete iPptBuffer;
+ iPptBuffer = 0;
+
+ iTileMarker.iPlt.ResetAndDestroy();
+ iTileMarker.iCom.ResetAndDestroy();
+
+ delete iTileMarker.iPoc;
+ iTileMarker.iPoc = 0;
+
+ delete iTileMarker.iCod;
+ iTileMarker.iCod = 0;
+
+ iTileMarker.iCoc.ResetAndDestroy();
+ iTileMarker.iRgn.ResetAndDestroy();
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::CJ2kTileInfo
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CJ2kTileInfo::CJ2kTileInfo( CJ2kImageInfo& aImageInfo, TJ2kStreamReader& aReader ) :
+ iComponentList( 3 ),
+ iImageInfo( aImageInfo ),
+ iReader( aReader )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::LRCPProgressionL
+// Parse the bitstream with LRCP progression order.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kTileInfo::LRCPProgressionL()
+ {
+ TUint16 marker = 0;
+ TUint8 compIncomplete = EFalse;
+
+ // For each layer
+ while ( iLastLayer < iNumOfLayersPOC )
+ {
+ // For each resolution level
+ while ( iLastLevel <= iNumOfLevelsPOC )
+ {
+ // For each component
+ while ( iLastComponent < iNumOfComponentsPOC )
+ {
+ compIncomplete = iComponentList[iLastComponent]->LRCPProgressionL( *this );
+ if ( compIncomplete )
+ {
+ // Underflow
+ return compIncomplete;
+ }
+
+ if ( IsPOC() )
+ {
+ // Check if we found next SOT or EOC
+ marker = PtrReadUtil::ReadBigEndianUint16( iReader.iPtr );
+ if ( marker == KSOT || marker == KEOC )
+ {
+ compIncomplete = ETrue;
+ return compIncomplete;
+ }
+ }
+
+ ++iLastComponent;
+ }
+
+ iLastComponent = iLastComponentOrig;
+ ++iLastLevel;
+
+ if ( IsCheckMarker() )
+ {
+ // Check if we found next SOT or EOC
+ // it signals the end of one LEVEL
+ marker = PtrReadUtil::ReadBigEndianUint16( iReader.iPtr );
+ if ( marker == KSOT || marker == KEOC )
+ {
+ compIncomplete = ETrue;
+ return compIncomplete;
+ }
+ }
+ }
+
+ iLastLevel = iLastLevelOrig;
+ ++iLastLayer;
+ }
+
+ // Continue using the next POC
+ ++iLastPOC;
+ iDoLoadPOC = EFalse;
+
+ return compIncomplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::RLCPProgressionL
+// Parse the bitstream with RLCP progression order.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kTileInfo::RLCPProgressionL()
+ {
+ TUint16 marker = 0;
+ TUint8 compIncomplete = EFalse;
+
+ // For each resolution level
+ while ( iLastLevel <= iNumOfLevelsPOC )
+ {
+ // For each layer
+ while ( iLastLayer < iNumOfLayersPOC )
+ {
+ // For each component
+ while ( iLastComponent < iNumOfComponentsPOC )
+ {
+ compIncomplete = iComponentList[iLastComponent]->LRCPProgressionL( *this );
+ if ( compIncomplete )
+ {
+ // Underflow
+ return compIncomplete;
+ }
+
+ if ( IsPOC() )
+ {
+ // Check if we found next SOT or EOC
+ marker = PtrReadUtil::ReadBigEndianUint16( iReader.iPtr );
+ if ( marker == KSOT || marker == KEOC )
+ {
+ compIncomplete = ETrue;
+ return compIncomplete;
+ }
+ }
+
+ ++iLastComponent;
+ }
+
+ iLastComponent = iLastComponentOrig;
+ ++iLastLayer;
+
+ if ( IsCheckMarker() )
+ {
+ // Check if we found next SOT or EOC
+ // it signals the end of one LAYER
+ marker = PtrReadUtil::ReadBigEndianUint16( iReader.iPtr );
+ if ( marker == KSOT || marker == KEOC )
+ {
+
+ // If we are at the end of layers, we have to reset
+ // layers and move to next resolution level
+ if(iLastLayer==iNumOfLayersPOC)
+ {
+ iLastLayer = 0;
+ ++iLastLevel;
+ }
+
+ compIncomplete = ETrue;
+ return compIncomplete;
+ }
+ }
+ }
+
+ iLastLayer = 0;
+ ++iLastLevel;
+ }
+
+ // Continue using the next POC
+ ++iLastPOC;
+ iDoLoadPOC = EFalse;
+
+ return compIncomplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::RPCLProgressionL
+// Parse the bitstream with RPCL progression order.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kTileInfo::RPCLProgressionL()
+ {
+ TUint16 marker = 0;
+ TUint8 compIncomplete = EFalse;
+
+ TSize minGrid( 0, 0 );
+ GetMinGrid( minGrid );
+
+ // Check that no divided by zero calculation are done.
+ if ( minGrid.iWidth == 0 || minGrid.iHeight == 0 )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ // For each resolution level
+ while ( iLastLevel <= iNumOfLevelsPOC )
+ {
+ // For each position in vertical direction
+ while ( iLastN1 < iTileCanvas.iBr.iY )
+ {
+ // For each position in horizontal direction
+ while ( iLastN2 < iTileCanvas.iBr.iX )
+ {
+ // For each component
+ while ( iLastComponent < iNumOfComponentsPOC )
+ {
+ compIncomplete = iComponentList[iLastComponent]->RPCLProgressionL( *this );
+ if ( compIncomplete )
+ {
+ // Underflow
+ return compIncomplete;
+ }
+
+ if ( IsPOC() )
+ {
+ // Check if we found next SOT or EOC
+ // it signals the end of one Precinct
+ marker = PtrReadUtil::ReadBigEndianUint16( iReader.iPtr );
+ if ( marker == KSOT || marker == KEOC )
+ {
+ compIncomplete = ETrue;
+ return compIncomplete;
+ }
+ }
+
+ ++iLastComponent;
+ }
+
+ iLastComponent = iLastComponentOrig;
+ iLastN2 += ( minGrid.iWidth - ( iLastN2 % minGrid.iWidth ) );
+
+ if ( IsCheckMarker() )
+ {
+ // Check if we found next SOT or EOC
+ // it signals the end of one Precinct
+ marker = PtrReadUtil::ReadBigEndianUint16( iReader.iPtr );
+ if ( marker == KSOT || marker == KEOC )
+ {
+
+ // If we are at the end of horizontal precincts, move to
+ // next row of vertical precincts
+ if(iLastN2 >= iTileCanvas.iBr.iX)
+ {
+ iLastN2 = iTileCanvas.iTl.iX;
+ iLastN1 += ( minGrid.iHeight - ( iLastN1 % minGrid.iHeight ) );
+ // If we are at the end of vertical precincts, move to next
+ // resolution level
+ if(iLastN1 >= iTileCanvas.iBr.iY)
+ {
+ iLastN1 = iTileCanvas.iTl.iY;
+ // Advance to next level to avoid a situation where we would
+ // return without reading any bytes from the frame the next
+ // time we enter this function
+ ++iLastLevel;
+ }
+ }
+
+ compIncomplete = ETrue;
+ return compIncomplete;
+ }
+ }
+ }
+
+ iLastN2 = iTileCanvas.iTl.iX;
+ iLastN1 += ( minGrid.iHeight - ( iLastN1 % minGrid.iHeight ) );
+ }
+
+ iLastN2 = iTileCanvas.iTl.iX;
+ iLastN1 = iTileCanvas.iTl.iY;
+ ++iLastLevel;
+ }
+
+ // Continue using the next POC
+ ++iLastPOC;
+ iDoLoadPOC = EFalse;
+
+ return compIncomplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::PCRLProgressionL
+// Parse the bitstream with PCRL progression order.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kTileInfo::PCRLProgressionL()
+ {
+ TUint16 marker = 0;
+ TUint8 compIncomplete = EFalse;
+
+ TSize minGrid;
+ GetMinGrid( minGrid );
+
+ // Check that no divided by zero calculation are done.
+ if ( minGrid.iWidth == 0 || minGrid.iHeight == 0 )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ // For each position in vertical direction
+ while ( iLastN1 < iTileCanvas.iBr.iY )
+ {
+ // For each position in horizontal direction
+ while ( iLastN2 < iTileCanvas.iBr.iX )
+ {
+ // For each component
+ while ( iLastComponent < iNumOfComponentsPOC )
+ {
+ // For each resolution level
+ while ( iLastLevel <= iNumOfLevelsPOC )
+ {
+ compIncomplete = iComponentList[iLastComponent]->CPRLProgressionL( *this );
+ if ( compIncomplete )
+ {
+ // Underflow
+ return compIncomplete;
+ }
+
+ if ( IsPOC() )
+ {
+ // Check if we found next SOT or EOC
+ // it signals the end of one Precinct
+ marker = PtrReadUtil::ReadBigEndianUint16( iReader.iPtr );
+ if ( marker == KSOT || marker == KEOC )
+ {
+ compIncomplete = ETrue;
+ return compIncomplete;
+ }
+ }
+
+ ++iLastLevel;
+ }
+
+ iLastLevel = iLastLevelOrig;
+ ++iLastComponent;
+
+ if ( IsCheckMarker() )
+ {
+ // Check if we found next SOT or EOC
+ // it signals the end of one Precinct
+ marker = PtrReadUtil::ReadBigEndianUint16( iReader.iPtr );
+ if ( marker == KSOT || marker == KEOC )
+ {
+ compIncomplete = ETrue;
+ return compIncomplete;
+ }
+ }
+ }
+
+ iLastComponent = iLastComponentOrig;
+ iLastN2 += ( minGrid.iWidth - ( iLastN2 % minGrid.iWidth ) );
+ }
+
+ iLastN2 = iTileCanvas.iTl.iX;
+ iLastN1 += ( minGrid.iHeight - ( iLastN1 % minGrid.iHeight ) );
+ }
+
+ // Continue using the next POC
+ ++iLastPOC;
+ iDoLoadPOC = EFalse;
+
+ return compIncomplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kTileInfo::CPRLProgressionL
+// Parse the bitstream with CPRL progression order.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kTileInfo::CPRLProgressionL()
+ {
+ TUint16 marker = 0;
+ TUint8 compIncomplete = EFalse;
+
+ TSize minGrid;
+ GetMinGrid( minGrid );
+
+ // Check that no divided by zero calculation are done.
+ if ( minGrid.iWidth == 0 || minGrid.iHeight == 0 )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ // For each component
+ while ( iLastComponent < iNumOfComponentsPOC )
+ {
+ // For each position in vertical direction
+ while ( iLastN1 < iTileCanvas.iBr.iY )
+ {
+ // For each position in horizontal direction
+ while ( iLastN2 < iTileCanvas.iBr.iX )
+ {
+ // For each resolution level
+ while ( iLastLevel <= iNumOfLevelsPOC )
+ {
+ compIncomplete = iComponentList[iLastComponent]->CPRLProgressionL( *this );
+ if ( compIncomplete )
+ {
+ // Underflow
+ return compIncomplete;
+ }
+
+ if ( IsPOC() )
+ {
+ // Check if we found next SOT or EOC
+ // it signals the end of one Precinct
+ marker = PtrReadUtil::ReadBigEndianUint16( iReader.iPtr );
+ if ( marker == KSOT || marker == KEOC )
+ {
+ compIncomplete = ETrue;
+ return compIncomplete;
+ }
+ }
+
+ ++iLastLevel;
+ }
+
+ iLastLevel = iLastLevelOrig;
+ iLastN2 += ( minGrid.iWidth - ( iLastN2 % minGrid.iWidth ) );
+
+ if ( IsCheckMarker() )
+ {
+ // Check if we found next SOT or EOC
+ // it signals the end of one Precinct
+ marker = PtrReadUtil::ReadBigEndianUint16( iReader.iPtr );
+ if ( marker == KSOT || marker == KEOC )
+ {
+ compIncomplete = ETrue;
+ return compIncomplete;
+ }
+ }
+ }
+
+ iLastN2 = iTileCanvas.iTl.iX;
+ iLastN1 += ( minGrid.iHeight - ( iLastN1 % minGrid.iHeight ) );
+ }
+
+ iLastN2 = iTileCanvas.iTl.iX;
+ iLastN1 = iTileCanvas.iTl.iY;
+ ++iLastComponent;
+ }
+
+ // Continue using the next POC
+ ++iLastPOC;
+ iDoLoadPOC = EFalse;
+
+ return compIncomplete;
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Src/JP2KUtils.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,238 @@
+/*
+* Copyright (c) 2003, 2004 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: TJ2kUtils class used to provide common public static
+* functions used by all classes in JP2KCodec.
+*
+*/
+
+
+// INCLUDE FILES
+#include "JP2KUtils.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+const TUint32 KLog2Table[] = { 0,1,2,4,8,16,32,64,128,256,512,1024,2048,
+ 4096,8192,16384,32768,65536,131072,262144,
+ 524288,1048576,2097152,4194304,8388608,
+ 16777216,33554432,67108864,134217728,
+ 268435456,536870912,1073741824,
+ KMaxTUint32 };
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// CONSTANTS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// TJ2kUtils::Ceil
+// Get the ceiling between two integers.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt32 TJ2kUtils::Ceil( TInt32 aL, TInt32 aR )
+ {
+ // Check that no divided by zero calculation are done.
+ if ( aR == 0 )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ if ( aL < 0 )
+ {
+ if ( aR < 0 )
+ {
+ aL = -aL;
+ aR = -aR;
+ return ( aL % aR ) ? ( aL / aR ) + 1 : aL / aR;
+ }
+ else
+ {
+ return -( ( -aL ) / aR );
+ }
+ }
+ else if ( aR < 0 )
+ {
+ return -( aL / ( -aR ) );
+ }
+ else
+ {
+ return ( aL % aR ) ? ( aL / aR ) + 1 : aL / aR;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// TJ2kUtils::Floor
+// Get the floor between two integers.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt32 TJ2kUtils::Floor( TInt32 aL, TInt32 aR )
+ {
+ // Check that no divided by zero calculation are done.
+ if ( aR == 0 )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ if ( ( aL < 0 || aR < 0 ) && !( aL < 0 && aR < 0 ) )
+ {
+ return aL / aR - 1;
+ }
+ else
+ {
+ return aL / aR;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// TJ2kUtils::Div
+// Get the quotient and remainder.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TDiv TJ2kUtils::Div( TInt aNum, TInt aDenom )
+ {
+ // Check that no divided by zero calculation are done.
+ if ( aDenom == 0 )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ TDiv aDiv;
+ aDiv.quot = aNum / aDenom;
+ aDiv.rem = aNum % aDenom;
+
+ /*
+ * The ANSI standard says that |r.quot| <= |n/d|, where
+ * n/d is to be computed in infinite precision. In other
+ * words, we should always truncate the quotient towards
+ * 0, never -infinity.
+ *
+ * Machine division and remainer may work either way when
+ * one or both of n or d is negative. If only one is
+ * negative and r.quot has been truncated towards -inf,
+ * r.rem will have the same sign as denom and the opposite
+ * sign of num; if both are negative and r.quot has been
+ * truncated towards -inf, r.rem will be positive ( will
+ * have the opposite sign of num ). These are considered
+ * `wrong'.
+ *
+ * If both are num and denom are positive, r will always
+ * be positive.
+ *
+ * This all boils down to:
+ * if num >= 0, but r.rem < 0, we got the wrong answer.
+ * In that case, to get the right answer, add 1 to r.quot and
+ * subtract denom from r.rem.
+ */
+ if ( aNum >= 0 && aDiv.rem < 0 )
+ {
+ aDiv.quot++;
+ aDiv.rem -= aDenom;
+ }
+ return aDiv;
+ }
+
+// -----------------------------------------------------------------------------
+// TJ2kUtils::Log2
+// Get he log2 value of an integer.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt32 TJ2kUtils::Log2( TUint32 aI )
+ {
+ TInt32 index = 0;
+ TInt32 count = sizeof( KLog2Table ) / sizeof( TUint32 );
+ for ( index = 0; index < count; ++index )
+ {
+ if ( KLog2Table[index] > aI )
+ {
+ break; //lint !e960 Break is OK.
+ }
+ }
+ return index - 2;
+ }
+
+// -----------------------------------------------------------------------------
+// TJ2kUtils::Alloc2DArrayL
+// Allocate 2-D array.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TPrecInt** TJ2kUtils::Alloc2DArrayL( TInt aRowSize, TInt aColSize )
+ {
+ TPrecInt **ptr = STATIC_CAST( TPrecInt**, User::Alloc( aRowSize * sizeof( TPrecInt* ) ) );
+ if ( !ptr )
+ {
+ User::Leave( KErrNoMemory );
+ }
+ CleanupStack::PushL( ptr );
+
+ // If first allocation fail, it will not reach here
+ TPrecInt *ptrRow = STATIC_CAST( TPrecInt*, User::Alloc( aRowSize * aColSize * sizeof( TPrecInt ) ) );
+ if ( !ptrRow )
+ {
+ User::Leave( KErrNoMemory );
+ }
+ Mem::FillZ( ptrRow, ( aRowSize * aColSize * sizeof( TPrecInt ) ) );
+ for ( TInt i = 0; i < aRowSize; ++i )
+ {
+ ptr[i] = ptrRow + ( i * aColSize );
+ }
+
+ CleanupStack::Pop( 1 );
+ return ptr;
+ }
+
+// -----------------------------------------------------------------------------
+// TJ2kUtils::Free2DArray
+// Free 2-D array.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void TJ2kUtils::Free2DArray( TPrecInt **aPtr )
+ {
+ if ( aPtr )
+ {
+ if ( aPtr[0] )
+ {
+ User::Free( aPtr[0] );
+ }
+ User::Free( aPtr );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// TJ2kUtils::Free2DArray
+// Wrapper to free 2-D array when put into TCleanupItem.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void TJ2kUtils::Free2DArray( TAny *aPtr ) //lint !e1714 Referenced from CleanupStack item.
+ {
+ Free2DArray( ( TPrecInt ** )aPtr );
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/rom/JP2KCodec.iby Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,27 @@
+/*
+* Copyright (c) 2002-2006 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: IBY file for JP2KCodec
+*
+*/
+
+
+#ifndef __JP2KCODEC_IBY
+#define __JP2KCODEC_IBY
+
+//JP2KCodec:
+ECOM_PLUGIN(JP2KCodec.dll,101F862D.rsc)
+data=DATAZ_\RESOURCE_FILES_DIR\ICL\101F862D_extra.rsc RESOURCE_FILES_DIR\ICL\101F862D_extra.rsc
+
+#endif //__JP2KCODEC_IBY
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/layers.sysdef.xml Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!DOCTYPE SystemDefinition SYSTEM "sysdef_1_4_0.dtd" [
+ <!ENTITY layer_real_source_path "sf/os/imagingext" >
+]>
+
+<SystemDefinition name="imagingext" schema="1.4.0">
+ <systemModel>
+ <layer name="os_layer">
+ <module name="imagingext">
+ <unit unitID="imm.imagingext" mrp="" bldFile="&layer_real_source_path;/group" name="imagingext" />
+ </module>
+
+ <module name="">
+ <unit unitID="imm.imagingext.imagingmodules.videoencpluginarm" mrp=""
+ bldFile="&layer_real_source_path;/imagingmodules/VideoEncPluginARM/Build"
+ filter="oem_build"
+ name="imm_imagingext_imagingmodules_videoencpluginarm" />
+ </module>
+
+ <module name="">
+ <unit unitID="imm.imagingext.imagingmodules.h264avcvideoencarm" mrp=""
+ bldFile="&layer_real_source_path;/imagingmodules/H264AVCVideoEncARM/group"
+ filter="oem_build"
+ name="imm_imagingext_imagingmodules_h264avcvideoencarm" />
+ </module>
+ </layer>
+
+ <layer name="api_test_layer">
+ <module name="imagingext_api_tests">
+ <unit unitID="imm.imagingext.exif_api" mrp="" bldFile="&layer_real_source_path;/imagingext_pub/exif_api/tsrc/group" name="exif_api" />
+ <unit unitID="imm.imagingext.iclextjpegapi_api" mrp="" bldFile="&layer_real_source_path;/imagingext_plat/extended_icl_jpeg_api/tsrc/group" name="iclextjpegapi_api" />
+ </module>
+ </layer>
+
+ </systemModel>
+</SystemDefinition>
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/package_definition.xml Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<SystemDefinition schema="3.0.0">
+ <package id="imagingext" name="Imaging Extensions" levels="adaptation hw-if plugin framework server app-if">
+ <collection id="imageadaptationextensions" name="Image Adaptation Extensions" level="app-if">
+ <component id="iclextjpegapi" filter="s60" name="ICL Extension JPEG API">
+ <unit bldFile="imageadaptationextensions/iclextjpegapi/group"/>
+ </component>
+ <component id="imageadaptationextensions_build" filter="s60" name="Image Adaptation Extensions Build">
+ <!-- consider moving the export from this bld.inf into the above one and remove this component -->
+ <unit bldFile="imageadaptationextensions/group"/>
+ </component>
+ </collection>
+ <collection id="imagingmodules" name="Imaging Modules" level="hw-if">
+ <component id="exiflib" filter="s60" name="Exif Library">
+ <unit bldFile="imagingmodules/exiflib/group"/>
+ </component>
+ <component id="jp2kcodec" filter="s60" name="JPEG2000 Decoder Plugin" class="plugin">
+ <unit bldFile="imagingmodules/jp2kcodec/group"/>
+ </component>
+ </collection>
+ <collection id="imagingext_info" name="Imaging Extensions Info" level="app-if">
+ <component id="imagingext_plat" filter="s60" name="Imaging Extensions Platform Interfaces" class="api">
+ <unit bldFile="imagingext_plat/group"/>
+ </component>
+ <component id="imagingext_build" filter="s60" name="Imaging Extensions Build">
+ <unit bldFile="group"/>
+ </component>
+ <component id="imagingext_pub" filter="s60" name="Imaging Extensions Public Interfaces" class="api">
+ <unit bldFile="imagingext_pub/group"/>
+ <!-- does this tes unit need to be #included in the above one? -->
+ <!-- <unit bldFile="imagingext_pub/exif_api/tsrc/group"/> -->
+ </component>
+ </collection>
+ </package>
+</SystemDefinition>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdef_1_4_0.dtd Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,86 @@
+ <!ELEMENT SystemDefinition (systemModel?, build?)>
+ <!ATTLIST SystemDefinition
+ name CDATA #REQUIRED
+ schema CDATA #REQUIRED>
+ <!ELEMENT systemModel (layer+)>
+ <!ELEMENT layer (logicalset* | module*)*>
+ <!ATTLIST layer
+ name CDATA #REQUIRED
+ levels CDATA #IMPLIED
+ span CDATA #IMPLIED>
+ <!ELEMENT logicalset (logicalsubset* | module* | unit* | package* | prebuilt*)*>
+ <!ATTLIST logicalset name CDATA #REQUIRED>
+ <!ELEMENT logicalsubset (module* | unit* | package* | prebuilt*)*>
+ <!ATTLIST logicalsubset name CDATA #REQUIRED>
+ <!ELEMENT module (component* | unit* | package* | prebuilt*)*>
+ <!ATTLIST module
+ name CDATA #REQUIRED
+ level CDATA #IMPLIED>
+ <!ELEMENT component (unit* | package* | prebuilt*)*>
+ <!ATTLIST component name CDATA #REQUIRED>
+ <!ELEMENT unit EMPTY>
+ <!ATTLIST unit
+ unitID ID #REQUIRED
+ name CDATA #REQUIRED
+ mrp CDATA #REQUIRED
+ filter CDATA #IMPLIED
+ bldFile CDATA #REQUIRED
+ priority CDATA #IMPLIED
+ contract CDATA #IMPLIED>
+ <!ELEMENT package EMPTY>
+ <!ATTLIST package
+ name CDATA #REQUIRED
+ mrp CDATA #REQUIRED
+ filter CDATA #IMPLIED
+ contract CDATA #IMPLIED>
+ <!ELEMENT prebuilt EMPTY>
+ <!ATTLIST prebuilt
+ name CDATA #REQUIRED
+ version CDATA #REQUIRED
+ late (Y|N) #IMPLIED
+ filter CDATA #IMPLIED
+ contract CDATA #IMPLIED>
+ <!ELEMENT build (option* | target+ | targetList+ | unitList+ | configuration+)*>
+ <!ELEMENT unitList (unitRef+)>
+ <!ATTLIST unitList
+ name ID #REQUIRED
+ description CDATA #REQUIRED>
+ <!ELEMENT unitRef EMPTY>
+ <!ATTLIST unitRef unit IDREF #REQUIRED>
+ <!ELEMENT targetList EMPTY>
+ <!ATTLIST targetList
+ name ID #REQUIRED
+ description CDATA #REQUIRED
+ target IDREFS #REQUIRED>
+ <!ELEMENT target EMPTY>
+ <!ATTLIST target
+ name ID #REQUIRED
+ abldTarget CDATA #REQUIRED
+ description CDATA #REQUIRED>
+ <!ELEMENT option EMPTY>
+ <!ATTLIST option
+ name ID #REQUIRED
+ abldOption CDATA #REQUIRED
+ description CDATA #REQUIRED
+ enable (Y | N | y | n) #REQUIRED>
+ <!ELEMENT configuration (unitListRef+ | layerRef+ | task+)*>
+ <!ATTLIST configuration
+ name ID #REQUIRED
+ description CDATA #REQUIRED
+ filter CDATA #REQUIRED>
+ <!ELEMENT task ( unitListRef* , (buildLayer | specialInstructions))>
+ <!ELEMENT unitListRef EMPTY>
+ <!ATTLIST unitListRef unitList IDREF #REQUIRED>
+ <!ELEMENT layerRef EMPTY>
+ <!ATTLIST layerRef layerName CDATA #REQUIRED>
+ <!ELEMENT buildLayer EMPTY>
+ <!ATTLIST buildLayer
+ command CDATA #REQUIRED
+ targetList IDREFS #IMPLIED
+ unitParallel (Y | N | y | n) #REQUIRED
+ targetParallel (Y | N | y | n) #IMPLIED>
+ <!ELEMENT specialInstructions EMPTY>
+ <!ATTLIST specialInstructions
+ name CDATA #REQUIRED
+ cwd CDATA #REQUIRED
+ command CDATA #REQUIRED>