accessoryservices/pluggeddisplay/edidparser/src/edidparserbase.cpp
changeset 0 4e1aa6a622a0
child 17 0b0048910c20
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/accessoryservices/pluggeddisplay/edidparser/src/edidparserbase.cpp	Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,1657 @@
+/*
+ * Copyright (c) 2008,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:
+ * Implementation of CEdidParserBase class.
+ *
+ */
+
+#include "trace.h"
+#include "edidparserbase.h"
+#include "cea861edidparser.h"
+#include "traceediddata.h"
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::CEdidParserBase
+// ---------------------------------------------------------------------------
+//
+CEdidParserBase::CEdidParserBase() :
+    iNumberOfExtensionBlocks( 0 )
+    {
+    FUNC_LOG;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CEdidParserBase::ConstructL( const TDesC8& aBinaryData )
+    {
+    FUNC_LOG;
+
+    //Check if it is EDID data
+    if( !IsEdidData( aBinaryData ) )
+        {
+        // Not EDID data
+        User::Leave( KErrNotSupported );
+        }
+
+    iRawData = HBufC8::NewL( aBinaryData.Length() );
+    TPtr8 rawPtr = iRawData->Des();
+    rawPtr.Copy( aBinaryData );
+
+    // Make a copy of base EDID data
+    Mem::Copy( &iBaseEdidData, rawPtr.Ptr(), KEdidParserSizeOfEdidBlock );
+    
+    TRACE_EDID_DATA( *this );
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::NewL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CEdidParserBase* CEdidParserBase::NewL( const TDesC8& aBinaryData )
+    {
+    FUNC_LOG;
+
+    CEdidParserBase* self = CEdidParserBase::NewLC( aBinaryData );
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::NewLC
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CEdidParserBase* CEdidParserBase::NewLC( const TDesC8& aBinaryData )
+    {
+    FUNC_LOG;
+
+    CEdidParserBase* self = new ( ELeave ) CEdidParserBase();
+    CleanupStack::PushL( self );
+    self->ConstructL( aBinaryData );
+
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::CEdidParserBase
+// ---------------------------------------------------------------------------
+//
+CEdidParserBase::~CEdidParserBase()
+    {
+    FUNC_LOG;
+
+    delete iRawData;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::IsEdidData
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CEdidParserBase::IsEdidData( const TDesC8& aBinaryData )
+    {
+    FUNC_LOG;
+    INFO_1( "TBool CEdidParserBase::IsEdidData: aBinaryData length: %d", aBinaryData.Length() );
+
+    TBool edidData = EFalse;
+
+    // Check the length
+    if( aBinaryData.Length() >= KEdidParserSizeOfEdidBlock )
+        {
+        for( int ii = 0; ii < KEdidParserSizeOfEdidHeader; ii++ )
+            {
+            if( aBinaryData[ii] != KBaseEdidHeader[ii] )
+                {
+                    // Not a valid EDID header
+                ERROR_1( KErrArgument, "TBool CEdidParserBase::IsEdidData: Not a valid EDID header: %d", ii );
+                return EFalse;
+                }
+            }
+        edidData = ETrue;
+        }
+
+    return edidData;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetManufacturerCode
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CEdidParserBase::GetManufacturerCode( TDes& aCode )
+    {
+    FUNC_LOG;
+
+    if( aCode.Length() < KEdidParserManufacturerCodeLength )
+        {
+        //return;
+        }
+
+    TUint16 data = iBaseEdidData.iVendorProductInfo.iManufacturerCode;
+
+    // Manufacturer codes are also called the ISA (Industry Standard Architecture)
+    // Plug and Play Device Identifier (PNPID). They are based on 5 bit compressed
+    // ASCII codes
+    // bits 14-10: first letter (01h='A', 02h='B',..)
+    // bits 9-5: second letter
+    // bits 4-0: third letter
+
+    // Convert to big endian
+    data = ( ( data >> 8 ) & 0xff ) + ( ( data << 8 ) & 0xff00 );
+
+    // Get ASCII codes
+    TChar asciicode;
+    asciicode = ( ( data >> 10 ) & 0x1f ) + 'A' - 1;
+    aCode.Append( asciicode );
+    asciicode = ( ( data >> 5 ) & 0x1f ) + 'A' - 1;
+    aCode.Append( asciicode );
+    asciicode = ( data & 0x1f ) + 'A' - 1;
+    aCode.Append( asciicode );
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetProductId
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CEdidParserBase::GetProductId( TDes& aCode )
+    {
+    FUNC_LOG;
+
+    aCode.AppendFormat( _L( "%04x" ), iBaseEdidData.iVendorProductInfo.iProductId );
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetManufactureWeek
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint8 CEdidParserBase::GetManufactureWeek()
+    {
+    FUNC_LOG;
+
+    return iBaseEdidData.iVendorProductInfo.iWeek;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetManufactureYear
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint16 CEdidParserBase::GetManufactureYear()
+    {
+    FUNC_LOG;
+
+    // Year of manufacture stored in EDID data is "Year of Manufacture - 1990"
+    return ( iBaseEdidData.iVendorProductInfo.iYear + KEdidBaseYear );
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetVersion
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint8 CEdidParserBase::GetVersion()
+    {
+    FUNC_LOG;
+
+    return iBaseEdidData.iVersion;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetRevision
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint8 CEdidParserBase::GetRevision()
+    {
+    FUNC_LOG;
+
+    return iBaseEdidData.iRevision;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetVideoInputDefinition
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint8 CEdidParserBase::GetVideoInputDefinition()
+    {
+    FUNC_LOG;
+
+    // Analog if bit 7 is 0. Digital if bit 7 is 1
+    return ( ( iBaseEdidData.iVideoInputDefinition & KBit7 ) == KBit7 ? 1 : 0 );
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetHorizontalScreenSize
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint8 CEdidParserBase::GetHorizontalScreenSize()
+    {
+    FUNC_LOG;
+
+    return iBaseEdidData.iScreenSize.iHorizontal;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetVerticalScreenSize
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint8 CEdidParserBase::GetVerticalScreenSize()
+    {
+    FUNC_LOG;
+
+    return iBaseEdidData.iScreenSize.iVertical;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetAspectRatioLandscape
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint8 CEdidParserBase::GetAspectRatioLandscape()
+    {
+	FUNC_LOG;
+	
+    // TEdidAspectRatio contains same values as TEdidScreenSize
+    // Horizontal = Landscape 
+    return iBaseEdidData.iScreenSize.iHorizontal;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetAspectRatioPortrait
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint8 CEdidParserBase::GetAspectRatioPortrait()
+    {
+	FUNC_LOG;
+	
+    // TEdidAspectRatio contains same values as TEdidScreenSize
+    // Vertical = Portrait 
+    return iBaseEdidData.iScreenSize.iVertical;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::IsAspectRationUsed
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CEdidParserBase::IsAspectRatioUsed()
+    {
+    FUNC_LOG;
+
+    // If byte 15h != 00h then byte 16h = Vertical Screen Size in cm.     (Range is 1 cm -> 255 cm)
+    // If byte 15h == 00h then byte 16h = Aspect Ratio (Portrait)         (Range is 0.28 : 1 AR -> 0.99 : 1 AR)
+    //
+    // If byte 16h != 00h then byte 15h = Horizontal Screen Size in cm.   (Range is 1 cm -> 255 cm)
+    // If byte 16h == 00h then byte 15h = Aspect Ratio (Landscape)        (Range is 1 : 1 AR -> 3.54 : 1 AR)
+
+    if( ( iBaseEdidData.iScreenSize.iHorizontal == 0 )
+        || ( iBaseEdidData.iScreenSize.iVertical == 0 ) )
+        {
+        return ETrue;
+        }
+
+    return EFalse;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::DisplayTransferCharacteristics
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint8 CEdidParserBase::DisplayTransferCharacteristics()
+    {
+    FUNC_LOG;
+
+    // Stored Value = (GAMMA x 100) – 100
+    return iBaseEdidData.iDisplayTransferCharasteristics;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetColorCoordinatesRedX
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint16 CEdidParserBase::GetColorCoordinatesRedX()
+    {
+    FUNC_LOG;
+
+    // Address 19h bits 7&6 are RedX bits 1&0
+    // Address 1Bh = RedX bits 9 to 2
+    TUint16 ret = iBaseEdidData.iColorCharasteristics[2]; //1Bh
+    ret = ret << 2;
+    TUint8 add = 0;
+    if( iBaseEdidData.iColorCharasteristics[0] & KBit7 )
+        {
+        add++;
+        }
+    add = add << 1;
+    if( iBaseEdidData.iColorCharasteristics[0] & KBit6 )
+        {
+        add++;
+        }
+    ret += add;
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetColorCoordinatesRedY
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint16 CEdidParserBase::GetColorCoordinatesRedY()
+    {
+    FUNC_LOG;
+
+    // Address 19h bits 5&4 are RedY bits 1&0
+    // Address 1Ch = RedY bits 9 to 2
+    TUint16 ret = iBaseEdidData.iColorCharasteristics[3]; //1Ch
+    ret = ret << 2;
+    TUint8 add = 0;
+    if( iBaseEdidData.iColorCharasteristics[0] & KBit5 )
+        {
+        add++;
+        }
+    add = add << 1;
+    if( iBaseEdidData.iColorCharasteristics[0] & KBit4 )
+        {
+        add++;
+        }
+    ret += add;
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetColorCoordinatesGreenX
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint16 CEdidParserBase::GetColorCoordinatesGreenX()
+    {
+    FUNC_LOG;
+
+    // Address 19h bits 3&2 are GreenX bits 1&0
+    // Address 1Dh = GreenX bits 9 to 2
+    TUint16 ret = iBaseEdidData.iColorCharasteristics[4]; //1Dh
+    ret = ret << 2;
+    TUint8 add = 0;
+    if( iBaseEdidData.iColorCharasteristics[0] & KBit3 )
+        {
+        add++;
+        }
+    add = add << 1;
+    if( iBaseEdidData.iColorCharasteristics[0] & KBit2 )
+        {
+        add++;
+        }
+    ret += add;
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetColorCoordinatesGreenY
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint16 CEdidParserBase::GetColorCoordinatesGreenY()
+    {
+    FUNC_LOG;
+
+    // Address 19h bits 1&0 are GreenY bits 1&0
+    // Address 1Eh = GreenY bits 9 to 2
+    TUint16 ret = iBaseEdidData.iColorCharasteristics[5]; //1Dh
+    ret = ret << 2;
+    TUint8 add = 0;
+    if( iBaseEdidData.iColorCharasteristics[0] & KBit1 )
+        {
+        add++;
+        }
+    add = add << 1;
+    if( iBaseEdidData.iColorCharasteristics[0] & KBit0 )
+        {
+        add++;
+        }
+    ret += add;
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetColorCoordinatesBlueX
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint16 CEdidParserBase::GetColorCoordinatesBlueX()
+    {
+    FUNC_LOG;
+
+    // Address 1Ah bits 7&6 are BlueX bits 1&0
+    // Address 1Fh = BlueX bits 9 to 2
+    TUint16 ret = iBaseEdidData.iColorCharasteristics[6]; //1Fh
+    ret = ret << 2;
+    TUint8 add = 0;
+    if( iBaseEdidData.iColorCharasteristics[1] & KBit7 )
+        {
+        add++;
+        }
+    add = add << 1;
+    if( iBaseEdidData.iColorCharasteristics[1] & KBit6 )
+        {
+        add++;
+        }
+    ret += add;
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetColorCoordinatesBlueY
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint16 CEdidParserBase::GetColorCoordinatesBlueY()
+    {
+    FUNC_LOG;
+
+    // Address 1Ah bits 5&4 are BlueY bits 1&0
+    // Address 20h = BlueY bits 9 to 2
+    TUint16 ret = iBaseEdidData.iColorCharasteristics[7]; //20h
+    ret = ret << 2;
+    TUint8 add = 0;
+    if( iBaseEdidData.iColorCharasteristics[1] & KBit5 )
+        {
+        add++;
+        }
+    add = add << 1;
+    if( iBaseEdidData.iColorCharasteristics[1] & KBit4 )
+        {
+        add++;
+        }
+    ret += add;
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetColorCoordinatesWhiteX
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint16 CEdidParserBase::GetColorCoordinatesWhiteX()
+    {
+    FUNC_LOG;
+
+    // Address 1Ah bits 3&2 are WhiteX bits 1&0
+    // Address 21h = WhiteX bits 9 to 2
+    TUint16 ret = iBaseEdidData.iColorCharasteristics[8]; //21h
+    ret = ret << 2;
+    TUint8 add = 0;
+    if( iBaseEdidData.iColorCharasteristics[1] & KBit3 )
+        {
+        add++;
+        }
+    add = add << 1;
+    if( iBaseEdidData.iColorCharasteristics[1] & KBit2 )
+        {
+        add++;
+        }
+    ret += add;
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetColorCoordinatesWhiteY
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint16 CEdidParserBase::GetColorCoordinatesWhiteY()
+    {
+    FUNC_LOG;
+
+    // Address 1Ah bits 3&2 are WhiteX bits 1&0
+    // Address 22h = WhiteX bits 9 to 2
+    TUint16 ret = iBaseEdidData.iColorCharasteristics[9]; //22h
+    ret = ret << 2;
+    TUint8 add = 0;
+    if( iBaseEdidData.iColorCharasteristics[1] & KBit1 )
+        {
+        add++;
+        }
+    add = add << 1;
+    if( iBaseEdidData.iColorCharasteristics[1] & KBit0 )
+        {
+        add++;
+        }
+    ret += add;
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetEstablishedTimings1
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint8 CEdidParserBase::GetEstablishedTimings1()
+    {
+    FUNC_LOG;
+
+    //Bit - Established Timing I
+    // 7     720 x 400  @ 70Hz
+    // 6     720 x 400  @ 88Hz
+    // 5     640 x 480  @ 60Hz
+    // 4     640 x 480  @ 67Hz
+    // 3     640 x 480  @ 72Hz
+    // 2     640 x 480  @ 75Hz
+    // 1     800 x 600  @ 56Hz
+    // 0     800 x 600  @ 60Hz
+    return iBaseEdidData.iEstablishedTimings[0];
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetEstablishedTimings2
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint8 CEdidParserBase::GetEstablishedTimings2()
+    {
+    FUNC_LOG;
+
+    //Bit - Established Timing I
+    // 7     800 x 600    @ 72Hz
+    // 6     800 x 600    @ 75Hz
+    // 5     832 x 624    @ 75Hz
+    // 4     1024 x 768   @ 87Hz
+    // 3     1024 x 768   @ 60Hz
+    // 2     1024 x 768   @ 70Hz
+    // 1     1024 x 768   @ 75Hz
+    // 0     1280 x 1024  @ 75Hz
+    return iBaseEdidData.iEstablishedTimings[1];
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetManufacturerTimings
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint8 CEdidParserBase::GetManufacturerTimings()
+    {
+    FUNC_LOG;
+
+    //Bit - Manufacturer Timing
+    // 7     1152 x 870   @ 75Hz
+    // 6-0   Reserved for Manufacturer Specified Timings
+    return iBaseEdidData.iEstablishedTimings[2];
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetManufacturerTimings
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint8 CEdidParserBase::GetStandardTimings( TInt aIndex )
+    {
+    FUNC_LOG;
+    
+    TUint8 byte = 0;
+    if( aIndex >= 0 && aIndex < 15 )
+        {
+        byte = iBaseEdidData.iStdTimingIdentifications[aIndex];
+        }
+    
+    return byte;
+    }
+
+// ----------------------------------------------------------------------------
+// CBaseEdid::GetDescriptorBlock
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TEdidDescriptorBlock CEdidParserBase::GetDescriptorBlock( TUint8 aDescriptorBlockNumber ) const
+    {
+    FUNC_LOG;
+
+    TEdidDescriptorBlock descBlock;
+
+    descBlock.iPixelClock = GetPixelClock( aDescriptorBlockNumber );
+
+    descBlock.iHorizontalAddressableVideoPixels
+        = GetHorizontalAddressableVideo( aDescriptorBlockNumber );
+
+    descBlock.iHorizontalBlanking
+        = GetHorizontalBlanking( aDescriptorBlockNumber );
+
+    descBlock.iVerticalAddressableVideoPixels
+        = GetVerticalAddressableVideo( aDescriptorBlockNumber );
+    
+    descBlock.iVerticalBlanking
+            = GetVerticalBlanking( aDescriptorBlockNumber );
+    
+    descBlock.iHorizontalFrontPorch
+        = GetHorizontalFrontPorch( aDescriptorBlockNumber );
+
+    descBlock.iHorizontalSyncPulse
+        = GetHorizontalSyncPulseWidth( aDescriptorBlockNumber );
+
+    descBlock.iVerticalFrontPorch
+        = GetVerticalFrontPorch( aDescriptorBlockNumber );
+
+    descBlock.iVerticalSyncPulse
+        = GetVerticalSyncPulseWidth( aDescriptorBlockNumber );
+
+    descBlock.iHorizontalAddressableImageSize
+        = GetHorizontalAddressableImageSize( aDescriptorBlockNumber );
+
+    descBlock.iVerticalAddressableImageSize
+        = GetVerticalAddressableImageSize( aDescriptorBlockNumber );
+
+    descBlock.iHorizontalBorder
+        = GetHorizontalBorderSize( aDescriptorBlockNumber );
+
+    descBlock.iVerticalBorder = GetVerticalBorderSize( aDescriptorBlockNumber );
+
+    descBlock.iInterlacedVideo = GetVideoIsInterlaced( aDescriptorBlockNumber );
+
+    descBlock.iStereoSupport = GetStereoViewingSupport( aDescriptorBlockNumber );
+
+    descBlock.iSyncs = GetSyncSignalDefinitions( aDescriptorBlockNumber );
+
+    return descBlock;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetNumberOfExtensions
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint8 CEdidParserBase::GetNumberOfExtensions()
+    {
+    FUNC_LOG;
+
+    // If Block Maps are used then 254 is the maximum value of number of
+    // extension blocks. If Block Maps are not used then 255 is the maximum
+    // value of number of extension blocks
+    return iBaseEdidData.iExtensionNumber;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetExtension
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CEdidParserBase::ReadExtension( TInt aNumber )
+    {
+    FUNC_LOG;
+
+    // |-----Base block-----|----Ext1----|---Ext2---|---.....|
+    //                            ^           ^
+    //                           Extension numbers (1,2,..)
+    TInt err = KErrNone;
+    if( aNumber <= GetNumberOfExtensions() )
+        {
+        // Make a copy of extension data. Call ReadExtensionL() with different
+        // extension number to read other extension
+        TPtr8 rawPtr = iRawData->Des();
+        Mem::Copy( &iExtensionData, rawPtr.Ptr() + ( aNumber
+            * KEdidParserSizeOfEdidBlock ), KEdidParserSizeOfEdidBlock );
+        }
+    else
+        {
+        // Invalid extension number. Return with KErrNotSupported
+        err = KErrNotSupported;
+        }
+
+    return err;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetExtensionType
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TEdidExtensionTagCode CEdidParserBase::GetExtensionType( TInt aNumber )
+    {
+    FUNC_LOG;
+
+    TEdidExtensionTagCode tag( EUnknownExt );
+    TInt err = ReadExtension( aNumber );
+    if( err == KErrNone )
+        {
+        switch( iExtensionData[0] )
+            {
+            case 0x02:
+                tag = ECea861Ext;
+                break;
+            case 0x10:
+                tag = EVTBExt;
+                break;
+            case 0x20:
+                tag = EEDID20;
+                break;
+            case 0x40:
+                tag = EDIExt;
+                break;
+            case 0x50:
+                tag = ELSExt;
+                break;
+            case 0x60:
+                tag = EDPVLExt;
+                break;
+            default:
+                // tag is EUnknownExt
+                break;
+            }
+        }
+
+    return tag;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::CreateCea861ExtensionParserL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CCea861EdidParser* CEdidParserBase::CreateCea861ExtensionParserL( TInt aNumber )
+    {
+    FUNC_LOG;
+
+    CCea861EdidParser* parser = NULL;
+    TInt ext = GetExtensionType( aNumber );
+    switch( ext )
+        {
+        case ECea861Ext:
+            {
+            // CEA 861 extension
+            parser = CCea861EdidParser::NewL( iExtensionData );
+            break;
+            }
+        default:
+            {
+            // Not supported
+            break;
+            }
+        }
+
+    // Extension is not supported. Return NULL
+    return parser;
+    }
+
+// ---------------------------------------------------------------------------
+// CEdidParserBase::GetChecksum
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint8 CEdidParserBase::GetChecksum()
+    {
+    FUNC_LOG;
+
+    // The Checksum Byte contains a value such that a checksum of the entire
+    // 128 byte base EDID equals 00h
+    return iBaseEdidData.iChecksum;
+    }
+
+// ----------------------------------------------------------------------------
+// CEdidParserBase::GetPixelClock
+// ----------------------------------------------------------------------------
+//
+TUint16 CEdidParserBase::GetPixelClock( TUint8 aDataBlockNumber ) const
+    {
+    FUNC_LOG;
+
+    // Stored Value = Pixel clock ÷ 10,000
+    // LSB stored in byte 0 and MSB stored in byte 1
+    // 0, 1 2 Range: 10 kHz to 655.35 MHz in 10 kHz steps
+    // (00 00)h Reserved: Do not use for Detailed Timing Descriptor
+
+    TUint16 word1;
+    TUint16 word2;
+
+    if( aDataBlockNumber == 1 )
+        {
+        word1 = iBaseEdidData.iTimingDescriptor[0];
+        word2 = iBaseEdidData.iTimingDescriptor[1];
+        }
+    else if( aDataBlockNumber == 2 )
+        {
+        word1 = iBaseEdidData.iSecondTimingDescriptor[0];
+        word2 = iBaseEdidData.iSecondTimingDescriptor[1];
+        }
+    else if( aDataBlockNumber == 3 )
+        {
+        word1 = iBaseEdidData.iMonitorDescriptor[0];
+        word2 = iBaseEdidData.iMonitorDescriptor[1];
+        }
+    else
+        {
+        //ERROR
+        return 0;
+        }
+
+    // xxxx xxxx 1010 1010
+    TUint16 pixelClock = word2;
+    // 1010 1010 xxxx xxxx shifted to left (MSB)
+    pixelClock = pixelClock << 8;
+    // 1010 1010 0101 0101 add the LSB
+    pixelClock += word1;
+
+    return pixelClock;
+    }
+
+// ----------------------------------------------------------------------------
+// CEdidParserBase::GetHorizontalAddressableVideo
+// ----------------------------------------------------------------------------
+//
+TUint16 CEdidParserBase::GetHorizontalAddressableVideo( TUint8 aDataBlockNumber ) const
+    {
+    FUNC_LOG;
+
+    TUint16 word1;
+    TUint16 word2;
+
+    if( aDataBlockNumber == 1 )
+        {
+        word1 = iBaseEdidData.iTimingDescriptor[4];
+        word2 = iBaseEdidData.iTimingDescriptor[2];
+        }
+    else if( aDataBlockNumber == 2 )
+        {
+        word1 = iBaseEdidData.iSecondTimingDescriptor[4];
+        word2 = iBaseEdidData.iSecondTimingDescriptor[2];
+        }
+    else if( aDataBlockNumber == 3 )
+        {
+        word1 = iBaseEdidData.iMonitorDescriptor[4];
+        word2 = iBaseEdidData.iMonitorDescriptor[2];
+        }
+    else
+        {
+        //ERROR
+        return 0;
+        }
+
+    // 12bits long, defined in 8 bits of byte 2 and
+    // upper nibble of byte 4 (4bits), range 0-4095
+    TUint16 horAddrVideo = 0;
+
+    // Nullify the 4 lsb
+    // ---- ---- xxxx yyyy >> 4  = ---- ---- ---- xxxx
+    horAddrVideo = word1 >> 4;
+    // return back to original position (4)+4
+    // ---- ---- ---- xxxx << 4  = ---- xxxx 0000 0000
+    horAddrVideo = horAddrVideo << ( 4 + 4 );
+    // ---- xxxx zzzz zzzz = correct values for the 12-bit-long var
+    horAddrVideo += word2;
+
+    return horAddrVideo;
+    }
+
+// ----------------------------------------------------------------------------
+// CBaseEdid::GetHorizontalBlanking
+// ----------------------------------------------------------------------------
+//
+TUint16 CEdidParserBase::GetHorizontalBlanking( TUint8 aDataBlockNumber ) const
+    {
+    FUNC_LOG;
+
+    TUint16 word1;
+    TUint16 word2;
+
+    if( aDataBlockNumber == 1 )
+        {
+        word1 = iBaseEdidData.iTimingDescriptor[4];
+        word2 = iBaseEdidData.iTimingDescriptor[3];
+        }
+    else if( aDataBlockNumber == 2 )
+        {
+        word1 = iBaseEdidData.iSecondTimingDescriptor[4];
+        word2 = iBaseEdidData.iSecondTimingDescriptor[3];
+        }
+    else if( aDataBlockNumber == 3 )
+        {
+        word1 = iBaseEdidData.iMonitorDescriptor[4];
+        word2 = iBaseEdidData.iMonitorDescriptor[3];
+        }
+    else
+        {
+        //ERROR
+        return 0;
+        }
+
+    TUint16 horBlanking = 0;
+
+    // nullify the 4 msb
+    //      ---- ---- xxxx yyyy << 12 = yyyy ---- ---- ----
+    horBlanking = word1 << 12;
+    // nullify the 4 msb
+    // yyyy ---- ---- ---- >> 4  = ---- yyyy ---- ----
+    horBlanking = horBlanking >> 4;
+    // ---- yyyy zzzz zzzz = correct values for the 12-bit-long var
+    horBlanking += word2;
+
+    return horBlanking;
+    }
+
+// ----------------------------------------------------------------------------
+// CBaseEdid::GetVerticalAddressableVideo
+// ----------------------------------------------------------------------------
+//
+TUint16 CEdidParserBase::GetVerticalAddressableVideo( TUint8 aDataBlockNumber ) const
+    {
+    FUNC_LOG;
+
+    TUint16 word1;
+    TUint16 word2;
+
+    if( aDataBlockNumber == 1 )
+        {
+        word1 = iBaseEdidData.iTimingDescriptor[7];
+        word2 = iBaseEdidData.iTimingDescriptor[5];
+        }
+    else if( aDataBlockNumber == 2 )
+        {
+        word1 = iBaseEdidData.iSecondTimingDescriptor[7];
+        word2 = iBaseEdidData.iSecondTimingDescriptor[5];
+        }
+    else if( aDataBlockNumber == 3 )
+        {
+        word1 = iBaseEdidData.iMonitorDescriptor[7];
+        word2 = iBaseEdidData.iMonitorDescriptor[5];
+        }
+    else
+        {
+        //ERROR
+        return 0;
+        }
+
+    //Upper nibble of byte 7 and the 8 bits of byte 5)
+    //Range is 0 lines to 4095 lines
+    TUint16 vertAddrVideo = 0;
+    vertAddrVideo = word1 >> 4;
+    vertAddrVideo = vertAddrVideo << ( 4 + 4 );
+    vertAddrVideo += word2;
+
+    return vertAddrVideo;
+    }
+
+// ----------------------------------------------------------------------------
+// CBaseEdid::GetVerticalBlanking
+// ----------------------------------------------------------------------------
+//
+TUint16 CEdidParserBase::GetVerticalBlanking( TUint8 aDataBlockNumber ) const
+    {
+    FUNC_LOG;
+
+    TUint16 word1;
+    TUint16 word2;
+
+    if( aDataBlockNumber == 1 )
+        {
+        word1 = iBaseEdidData.iTimingDescriptor[7];
+        word2 = iBaseEdidData.iTimingDescriptor[6];
+        }
+    else if( aDataBlockNumber == 2 )
+        {
+        word1 = iBaseEdidData.iSecondTimingDescriptor[7];
+        word2 = iBaseEdidData.iSecondTimingDescriptor[6];
+        }
+    else if( aDataBlockNumber == 3 )
+        {
+        word1 = iBaseEdidData.iMonitorDescriptor[7];
+        word2 = iBaseEdidData.iMonitorDescriptor[6];
+        }
+    else
+        {
+        //ERROR
+        return 0;
+        }
+
+    // 12bits long, defined in 8 bits of byte 2 and
+    // upper nibble of byte 4 (4bits), range 0-4095
+    TUint16 vertBlanking = 0;
+
+    // nullify the 4 msb
+    // ---- ---- xxxx yyyy << 12 = yyyy ---- ---- ----
+    vertBlanking = word1 << 12;
+    // nullify the 4 msb
+    // yyyy ---- ---- ---- >> 4  = 0000 yyyy ---- ----
+    vertBlanking = vertBlanking >> 4;
+    // ---- yyyy zzzz zzzz = correct values for the 12-bit-long var
+    vertBlanking += word2;
+
+    return vertBlanking;
+    }
+
+// ----------------------------------------------------------------------------
+// CBaseEdid::GetHorizontalFrontPorch
+// ----------------------------------------------------------------------------
+//
+TUint16 CEdidParserBase::GetHorizontalFrontPorch( TUint8 aDataBlockNumber ) const
+    {
+    FUNC_LOG;
+
+    TUint16 word1;
+    TUint16 word2;
+
+    if( aDataBlockNumber == 1 )
+        {
+        word1 = iBaseEdidData.iTimingDescriptor[6];
+        word2 = iBaseEdidData.iTimingDescriptor[8];
+        }
+    else if( aDataBlockNumber == 2 )
+        {
+        word1 = iBaseEdidData.iSecondTimingDescriptor[6];
+        word2 = iBaseEdidData.iSecondTimingDescriptor[8];
+        }
+    else if( aDataBlockNumber == 3 )
+        {
+        word1 = iBaseEdidData.iMonitorDescriptor[6];
+        word2 = iBaseEdidData.iMonitorDescriptor[8];
+        }
+    else
+        {
+        //ERROR
+        return 0;
+        }
+
+    // Horizontal Front Porch in Pixels (from blanking start to start of sync)
+    // is represented by a 10 bit number (Bits 7 & 6 of byte 11 and the 8 bits of byte 8)
+    // Range is 0 pixels to 1023 pixels.
+
+    TUint16 horFrontPorch = 0;
+
+    TUint8 bit67 = word1;
+    // bits 6 and 7 remain
+    bit67 = ( bit67 & KBit7 ) | ( bit67 & KBit6 );
+
+    horFrontPorch = bit67 << 2;
+    horFrontPorch += word2;
+
+    return horFrontPorch;
+    }
+
+// ----------------------------------------------------------------------------
+// CEdidParserBase::GetHorizontalSyncPulseWidth
+// ----------------------------------------------------------------------------
+//
+TUint16 CEdidParserBase::GetHorizontalSyncPulseWidth( TUint8 aDataBlockNumber ) const
+    {
+    FUNC_LOG;
+
+    //Horizontal Sync Pulse Width in Pixels (from the end of the front porch to the start of the back
+    //porch) is represented by a 10 bit number (Bits 5 & 4 of byte 11 and the 8 bits of byte 9) - Range
+    //is 0 pixels to 1023 pixels.
+
+    TUint8 word1;
+    TUint8 word2;
+
+    if( aDataBlockNumber == 1 )
+        {
+        word1 = iBaseEdidData.iTimingDescriptor[11];
+        word2 = iBaseEdidData.iTimingDescriptor[9];
+        }
+    else if( aDataBlockNumber == 2 )
+        {
+        word1 = iBaseEdidData.iSecondTimingDescriptor[11];
+        word2 = iBaseEdidData.iSecondTimingDescriptor[9];
+        }
+    else if( aDataBlockNumber == 3 )
+        {
+        word1 = iBaseEdidData.iMonitorDescriptor[11];
+        word2 = iBaseEdidData.iMonitorDescriptor[9];
+        }
+    else
+        {
+        //ERROR
+        return 0;
+        }
+
+    TUint16 horSyncPulseWidth = word1;
+
+    // only bits 5 and 4 remain: xx00 xxxx
+    horSyncPulseWidth = ( horSyncPulseWidth & KBit5 ) | ( horSyncPulseWidth
+        & KBit4 );
+
+    // xx00 xxxx -> xx00 xxxx xxxx
+    horSyncPulseWidth = horSyncPulseWidth << 4;
+
+    // xx00 xxxx xxxx -> 00 0000 0000
+    horSyncPulseWidth += word2;
+
+    return horSyncPulseWidth;
+    }
+
+// ----------------------------------------------------------------------------
+// CEdidParserBase::GetVerticalFrontPorch
+// ----------------------------------------------------------------------------
+//
+TUint16 CEdidParserBase::GetVerticalFrontPorch( TUint8 aDataBlockNumber ) const
+    {
+    FUNC_LOG;
+
+    // Vertical Front Porch in Lines (from blanking start to start of sync) is represented by a 6 bit
+    // number (Bits 3 & 2 of byte 11 and the upper nibble of byte 10) - Range is 0 lines to 63 lines.
+
+    TUint16 word1;
+    TUint16 word2;
+
+    if( aDataBlockNumber == 1 )
+        {
+        word1 = iBaseEdidData.iTimingDescriptor[11];
+        word2 = iBaseEdidData.iTimingDescriptor[10];
+        }
+    else if( aDataBlockNumber == 2 )
+        {
+        word1 = iBaseEdidData.iSecondTimingDescriptor[11];
+        word2 = iBaseEdidData.iSecondTimingDescriptor[10];
+        }
+    else if( aDataBlockNumber == 3 )
+        {
+        word1 = iBaseEdidData.iMonitorDescriptor[11];
+        word2 = iBaseEdidData.iMonitorDescriptor[10];
+        }
+    else
+        {
+        //ERROR
+        return 0;
+        }
+
+    TUint16 vertFrontPorch = 0;
+    TUint8 bit23 = word1;
+
+    // bits 2 and 3 remain  0000 xx00
+    bit23 = ( bit23 & KBit3 ) | ( bit23 & KBit2 );
+
+    // 00xx 0000
+    vertFrontPorch = bit23 << 2;
+
+    // only the upper nibble
+    // 00xx yyyy
+    vertFrontPorch += ( word2 >> 4 );
+
+    return vertFrontPorch;
+    }
+
+// ----------------------------------------------------------------------------
+// CEdidParserBase::GetVerticalSyncPulseWidth
+// ----------------------------------------------------------------------------
+//
+TUint8 CEdidParserBase::GetVerticalSyncPulseWidth( TUint8 aDataBlockNumber ) const
+    {
+    FUNC_LOG;
+
+    // Vertical Sync Pulse Width in Lines (from the end of the front porch to the start of the back
+    // porch) is represented by a 6 bit number (Bits 1 & 0 of byte 11 and the lower nibble of byte 10 -
+    // Range is 0 lines to 63 lines.
+
+    TUint8 word1;
+    TUint8 word2;
+
+    if( aDataBlockNumber == 1 )
+        {
+        word1 = iBaseEdidData.iTimingDescriptor[10];
+        word2 = iBaseEdidData.iTimingDescriptor[11];
+        }
+    else if( aDataBlockNumber == 2 )
+        {
+        word1 = iBaseEdidData.iSecondTimingDescriptor[10];
+        word2 = iBaseEdidData.iSecondTimingDescriptor[11];
+        }
+    else if( aDataBlockNumber == 3 )
+        {
+        word1 = iBaseEdidData.iMonitorDescriptor[10];
+        word2 = iBaseEdidData.iMonitorDescriptor[11];
+        }
+    else
+        {
+        //ERROR
+        return 0;
+        }
+
+    // Vertical Sync Pulse Width in Lines (from the end of the front porch to the start of the back
+    // porch) is represented by a 6 bit number (Bits 1 & 0 of byte 11 and the lower nibble of byte 10 -
+    // Range is 0 lines to 63 lines.
+    TUint8 vertSyncPulse = 0;
+
+    // bits 1 and 0 remain   0000 00xx
+    word2 = ( word2 & KBit1 ) | ( word2 & KBit0 );
+
+    // 00xx 0000
+    vertSyncPulse = word2 << 4;
+    // only the lower nibble, %16 removes the upper nibble
+    word1 = word1 % 16;
+    // 00xx yyyy
+    vertSyncPulse += word1;
+
+    return vertSyncPulse;
+    }
+
+// ----------------------------------------------------------------------------
+// CEdidParserBase::GetHorizontalAddressableImageSize
+// ----------------------------------------------------------------------------
+//
+TUint16 CEdidParserBase::GetHorizontalAddressableImageSize( TUint8 aDataBlockNumber ) const
+    {
+    FUNC_LOG;
+
+    TUint16 word1;
+    TUint16 word2;
+
+    if( aDataBlockNumber == 1 )
+        {
+        word1 = iBaseEdidData.iTimingDescriptor[14];
+        word2 = iBaseEdidData.iTimingDescriptor[12];
+        }
+    else if( aDataBlockNumber == 2 )
+        {
+        word1 = iBaseEdidData.iSecondTimingDescriptor[14];
+        word2 = iBaseEdidData.iSecondTimingDescriptor[12];
+        }
+    else if( aDataBlockNumber == 3 )
+        {
+        word1 = iBaseEdidData.iMonitorDescriptor[14];
+        word2 = iBaseEdidData.iMonitorDescriptor[12];
+        }
+    else
+        {
+        //ERROR
+        return 0;
+        }
+
+    //Horizontal Addressable Video Image Size in mm is represented by a 12 bit number (Upper
+    //nibble of byte 14 and the 8 bits of byte 12) - Range is 0 mm to 4095 mm.
+
+    TUint16 hais = word1 >> 4; // first nullify 4 lsb
+    hais = hais << ( 4 + 4 ); // and then move back the first 4 and then again 4
+    hais += word2;
+
+    return hais;
+    }
+
+// ----------------------------------------------------------------------------
+// CEdidParserBase::GetVerticalAddressableImageSize
+// ----------------------------------------------------------------------------
+//
+TUint16 CEdidParserBase::GetVerticalAddressableImageSize( TUint8 aDataBlockNumber ) const
+    {
+    FUNC_LOG;
+
+    TUint16 word1;
+    TUint16 word2;
+
+    if( aDataBlockNumber == 1 )
+        {
+        word1 = iBaseEdidData.iTimingDescriptor[14];
+        word2 = iBaseEdidData.iTimingDescriptor[13];
+        }
+    else if( aDataBlockNumber == 2 )
+        {
+        word1 = iBaseEdidData.iSecondTimingDescriptor[14];
+        word2 = iBaseEdidData.iSecondTimingDescriptor[13];
+        }
+    else if( aDataBlockNumber == 3 )
+        {
+        word1 = iBaseEdidData.iMonitorDescriptor[14];
+        word2 = iBaseEdidData.iMonitorDescriptor[13];
+        }
+    else
+        {
+        //ERROR
+        return 0;
+        }
+
+    //Vertical Addressable Video Image Size in mm is represented by a 12 bit number (Lower nibble
+    //of byte 14 and the 8 bits of byte 13) - Range is 0 mm to 4095 mm.
+
+    TUint16 vais = word1;
+    vais = vais << 12; // first nullify 4 msb and then move back 1 nibble
+    vais = vais >> 4;
+    vais += word2;
+
+    return vais;
+    }
+
+// ----------------------------------------------------------------------------
+// CEdidParserBase::GetHorizontalBorderSize
+// ----------------------------------------------------------------------------
+//
+TUint8 CEdidParserBase::GetHorizontalBorderSize( TUint8 aDataBlockNumber ) const
+    {
+    FUNC_LOG;
+
+    TUint16 word1;
+
+    if( aDataBlockNumber == 1 )
+        {
+        word1 = iBaseEdidData.iTimingDescriptor[15];
+        }
+    else if( aDataBlockNumber == 2 )
+        {
+        word1 = iBaseEdidData.iSecondTimingDescriptor[15];
+        }
+    else if( aDataBlockNumber == 3 )
+        {
+        word1 = iBaseEdidData.iMonitorDescriptor[15];
+        }
+    else
+        {
+        //ERROR
+        return 0;
+        }
+
+    //Right Horizontal Border or Left Horizontal Border in Pixels is represented by
+    // an 8 bit number (the 8 bits of byte 15) - Range is 0 pixels to 255 pixels.
+
+    // the same value is used for (left and right) / (top and bottom)
+    return word1;
+    }
+
+// ----------------------------------------------------------------------------
+// CEdidParserBase::GetVerticalBorderSize
+// ----------------------------------------------------------------------------
+//
+TUint8 CEdidParserBase::GetVerticalBorderSize( TUint8 aDataBlockNumber ) const
+    {
+    FUNC_LOG;
+
+    TUint16 word1;
+
+    if( aDataBlockNumber == 1 )
+        {
+        word1 = iBaseEdidData.iTimingDescriptor[16];
+        }
+    else if( aDataBlockNumber == 2 )
+        {
+        word1 = iBaseEdidData.iSecondTimingDescriptor[16];
+        }
+    else if( aDataBlockNumber == 3 )
+        {
+        word1 = iBaseEdidData.iMonitorDescriptor[16];
+        }
+    else
+        {
+        //ERROR
+        return 0;
+        }
+
+    //Top Vertical Border or Bottom Vertical Border in Lines is represented by an 8 bit number (the
+    //8 bits of byte 16) - Range is 0 lines to 255 lines.
+    return word1;
+    }
+
+// ----------------------------------------------------------------------------
+// CEdidParserBase::GetVideoIsInterlaced
+// ----------------------------------------------------------------------------
+//
+TBool CEdidParserBase::GetVideoIsInterlaced( TUint8 aDataBlockNumber ) const
+    {
+    FUNC_LOG;
+
+    TUint16 word1;
+    if( aDataBlockNumber == 1 )
+        {
+        word1 = iBaseEdidData.iTimingDescriptor[17];
+        }
+    else if( aDataBlockNumber == 2 )
+        {
+        word1 = iBaseEdidData.iSecondTimingDescriptor[17];
+        }
+    else if( aDataBlockNumber == 3 )
+        {
+        word1 = iBaseEdidData.iMonitorDescriptor[17];
+        }
+    else
+        {
+        //ERROR
+        return EFalse;
+        }
+
+    // byte 17
+    // Bytes Bit Definitions Detailed Timing Definitions
+    // 7 6 5 4 3 2 1 0 Signal Interface Type:
+    // 0 _ _ _ _ _ _ _ Non-Interlaced (1 frame = 1 field)
+    // 1 _ _ _ _ _ _ _ Interlaced (1 frame = 2 fields)
+
+    return KBit7 & word1;
+    }
+
+// ----------------------------------------------------------------------------
+// CBaseEdid::GetStereoViewingSupport
+// ----------------------------------------------------------------------------
+//
+TEdidStereoViewingSupport CEdidParserBase::GetStereoViewingSupport( TUint8 aDataBlockNumber ) const
+    {
+    FUNC_LOG;
+
+    TUint16 word1;
+
+    if( aDataBlockNumber == 1 )
+        {
+        word1 = iBaseEdidData.iTimingDescriptor[17];
+        }
+    else if( aDataBlockNumber == 2 )
+        {
+        word1 = iBaseEdidData.iSecondTimingDescriptor[17];
+        }
+    else if( aDataBlockNumber == 3 )
+        {
+        word1 = iBaseEdidData.iMonitorDescriptor[17];
+        }
+    else
+        {
+        //ERROR
+        return EUnknownStereoViewingSupport;
+        }
+
+    //Bytes Bit Definitions Detailed Timing Definitions
+    //_ 6 5 _ _ _ _ 0 Stereo Viewing Support:
+    //  0 0 _ _ _ _ x Normal Display – No Stereo. The value of bit 0 is "don't care"
+    //  0 1 _ _ _ _ 0 Field sequential stereo, right image when stereo sync signal = 1
+    //  1 0 _ _ _ _ 0 Field sequential stereo, left image when stereo sync signal = 1
+    //  0 1 _ _ _ _ 1 2-way interleaved stereo, right image on even lines
+    //  1 0 _ _ _ _ 1 2-way interleaved stereo, left image on even lines
+    //  1 1 _ _ _ _ 0 4-way interleaved stereo
+    //  1 1 _ _ _ _ 1 Side-by-Side interleaved stereo
+    TUint8 bit17 = word1;
+    if( !( ( KBit6 & bit17 ) | ( KBit5 & bit17 ) ) ) //  0 0 _ _ _ _ x Normal Display – No Stereo.
+        { //                The value of bit 0 is "don't care"
+        return ENormalDisplay;
+        }
+    else if( !( KBit6 & bit17 ) && ( KBit5 & bit17 ) && !( KBit0 & bit17 ) ) //  0 1 _ _ _ _ 0 Field sequential stereo,
+        { //                right image when stereo sync signal=1
+        return EFieldSequentialStereoRightWhenStereoSyncSignal1;
+        }
+    else if( ( KBit6 & bit17 ) && !( KBit5 & bit17 ) && !( KBit0 & bit17 ) ) //  1 0 _ _ _ _ 0 Field sequential stereo,
+        { //                left image when stereo sync signal=1
+        return EFieldSequentialStereoLeftWhenStereoSyncSignal1;
+        }
+    else if( !( KBit6 & bit17 ) && ( KBit5 & bit17 ) && ( KBit0 & bit17 ) ) //  0 1 _ _ _ _ 1 2-way interleaved stereo,
+        { //                right image on even lines
+        return ETwoWayInterleavedStereoRightImageOnEvenLines;
+        }
+    else if( ( KBit6 & bit17 ) && !( KBit5 & bit17 ) && ( KBit0 & bit17 ) ) //  1 0 _ _ _ _ 1 2-way interleaved stereo,
+        { //                left image on even lines
+        return ETwoWayInterleavedStereoLeftImageOnEvenLines;
+        }
+    else if( ( KBit6 & bit17 ) && ( KBit5 & bit17 ) && !( KBit0 & bit17 ) ) //  1 1 _ _ _ _ 0 4-way interleaved stereo
+        {
+        return EFourWayInterleaverStereo;
+        }
+    else if( ( KBit6 & bit17 ) && ( KBit5 & bit17 ) && ( KBit0 & bit17 ) ) //  1 1 _ _ _ _ 1 Side-by-Side interleaved stereo
+        {
+        return ESideBySideInterleavedStere;
+        }
+    else
+        {
+        // ERROR
+        return EUnknownStereoViewingSupport;
+        }
+
+    // Unreachable
+    }
+
+// ----------------------------------------------------------------------------
+// CBaseEdid::GetSyncSignalDefinitions
+// ----------------------------------------------------------------------------
+//
+TEdidSyncSignalDefinitions CEdidParserBase::GetSyncSignalDefinitions( TUint8 aDataBlockNumber ) const
+    {
+    FUNC_LOG;
+
+    // byte 17
+    // 4 3 2 1 _ Analog Sync Signal Definitions:
+    //------------------------------------------
+    // 0 0 _ _ _ Analog Composite Sync:
+    // 0 1 _ _ _ Bipolar Analog Composite Sync:
+
+    TUint8 byte17 = 0;
+    if( aDataBlockNumber == 1 )
+        {
+        byte17 = iBaseEdidData.iTimingDescriptor[17];
+        }
+    else if( aDataBlockNumber == 2 )
+        {
+        byte17 = iBaseEdidData.iSecondTimingDescriptor[17];
+        }
+    else if( aDataBlockNumber == 3 )
+        {
+        byte17 = iBaseEdidData.iMonitorDescriptor[17];
+        }
+    else
+        {
+        // ERROR
+        return EUnknownSignalDefinition;
+        }
+
+    if( !( KBit4 & byte17 ) ) // if bit4 == 0 then this is analog display
+        {
+        return GetAnalogSyncSignalDefinitions( byte17 );
+        }
+    else
+        {
+        return GetDigitalSyncSignalDefinitions( byte17 );
+        }
+    // unreachable
+    }
+
+// ----------------------------------------------------------------------------
+// CBaseEdid::GetAnalogSyncSignalDefinitions
+// ----------------------------------------------------------------------------
+//
+TEdidSyncSignalDefinitions CEdidParserBase::GetAnalogSyncSignalDefinitions( const TUint aByte17 )
+    {
+    FUNC_LOG;
+
+    // byte 17
+    // 4 3 2 1 _ Analog Sync Signal Definitions:
+    //------------------------------------------
+    // 0 0 _ _ _ Analog Composite Sync:
+    // 0 1 _ _ _ Bipolar Analog Composite Sync:
+    // 0 _ 0 _ _ ---------- Without Serrations;
+    // 0 _ 1 _ _ ---------- With Serrations (H-sync during V-sync);
+    // 0 _ _ 0 _ -------------------- Sync On Green Signal only
+    // 0 _ _ 1 _ -------------------- Sync On all three (RGB) video signals
+
+    TBool ACS = !( KBit3 & aByte17 ); // if true -> bipolar analog composite sync
+    TBool serrations = KBit2 & aByte17;
+    TBool syncOnGreen = !( KBit1 & aByte17 );
+
+    if( ACS )
+        {
+        if( !serrations )
+            {
+            if( syncOnGreen )
+                {
+                return EAnalogCompositeSyncWithoutSerrationsSyncSyncOnGreenSignalOnly;
+                }
+            else
+                {
+                return EAnalogCompositeSyncWithoutSerrationsSyncOnAllThreeVideoSignals;
+                }
+            }
+        else
+            {
+            if( syncOnGreen )
+                {
+                return EAnalogCompositeSyncWithoutSerrationsSyncSyncOnGreenSignalOnly;
+                }
+            else
+                {
+                return EAnalogCompositeSyncWithoutSerrationsSyncOnAllThreeVideoSignals;
+                }
+            }
+        }
+    else
+        {
+        if( !serrations )
+            {
+            if( syncOnGreen )
+                {
+                return EAnalogBipolarAnalogCompositeSyncWithoutSerrationsSyncSyncOnGreenSignalOnly;
+                }
+            else
+                {
+                return EAnalogBipolarAnalogCompositeSyncWithoutSerrationsSyncOnAllThreeVideoSignals;
+                }
+            }
+        else
+            {
+            if( syncOnGreen )
+                {
+                return EAnalogBipolarAnalogCompositeSyncWithSerrationsSyncSyncOnGreenSignalOnly;
+                }
+            else
+                {
+                return EAnalogBipolarAnalogCompositeSyncWithSerrationsSyncOnAllThreeVideoSignals;
+                }
+            }
+        }
+    // unreachable
+    }
+
+// ----------------------------------------------------------------------------
+// CBaseEdid::GetDigitalSyncSignalDefinitions
+// ----------------------------------------------------------------------------
+//
+TEdidSyncSignalDefinitions CEdidParserBase::GetDigitalSyncSignalDefinitions( const TUint aByte17 )
+    {
+    FUNC_LOG;
+
+    //        4 3 2 1 0 bit
+    //        --------------
+    //        1 0 _ _ _ Digital Composite Sync:
+    //        1 0 0 _ _ ---------- Without Serrations;
+    //        1 0 1 _ _ ---------- With Serrations (H-sync during V-sync);
+    //        1 1 _ _ _ Digital Separate Sync:
+    //        1 1 0 _ _ ---------- Vertical Sync is Negative;
+    //        1 1 1 _ _ ---------- Vertical Sync is Positive;
+    //        1 _ _ 0 _ -------------------- Horizontal Sync is Negative (outside of V-sync)
+    //        1 _ _ 1 _ -------------------- Horizontal Sync is Positive (outside of V-sync)
+    TBool digComp = ( KBit3 & aByte17 ); // ETrue == digital separate sync
+    TBool bit2 = KBit2 & aByte17;
+
+    if( !digComp ) // digital composite sync
+        {
+        if( !bit2 ) // without serrations
+            {
+            return EDigitalCompositeSyncWithoutSerrations;
+            }
+        else // with serrations
+            {
+            return EDigitalCompositeSyncWithSerrations;
+            }
+        } // endif  digital composite sync
+    else //        digital separate sync
+        {
+        TBool bit1 = KBit1 & aByte17;
+
+        if( !bit2 ) // vertical = neg
+            {
+            if( !bit1 )
+                { // vertical = neg, horizontal = neg
+                return EDigitalSeparateSyncVerticalSyncIsNegativeHorizontalSyncIsNegative;
+                }
+            else
+                { // vertical = neg, horizontal = pos
+                return EDigitalSeparateSyncVerticalSyncIsNegativeHorizontalSyncIsPositive;
+                }
+            }
+        else // vertical = pos
+            {
+            if( !bit1 )
+                { // vertical = pos, horizontal = neg
+                return EDigitalSeparateSyncVerticalSyncIsPositiveHorizontalSyncIsNegative;
+                }
+            else
+                { // vertical = pos, horizontal = pos
+                return EDigitalSeparateSyncVerticalSyncIsPositiveHorizontalSyncIsPositive;
+                }
+            }
+        }
+    // unreachable
+    }
+
+// End of file