os/mm/mmlibs/mmfw/Recogniser/src/id3parser.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include "parsers.h"
    17 
    18 // The ID3 tag has a 10 byte header.
    19 static const TInt KID3HeaderSize = 10;
    20 
    21 
    22 //
    23 // Checks if an ID3 header is present at the current
    24 // reader position, and skips over it if it is.
    25 // Returns ETrue if a header was found, EFalse otherwise.
    26 //
    27 TBool TID3Parser::ReadAndSkipID3L(CReader& aReader)
    28 	{
    29 	TBuf8<KID3HeaderSize> header;
    30 	TUint8 a;
    31 	TUint8 b;
    32 	TUint8 c;
    33 	TUint8 d;
    34 	
    35 	header.SetLength(KID3HeaderSize);
    36 	aReader.ReadBytesL(header);
    37 	
    38 	do
    39 		{
    40 		// Look for the ID3 header.
    41 		if ((header[0] != 'I') || (header[1] != 'D') || (header[2] != '3'))
    42 			{
    43 			break;
    44 			}
    45 			
    46 		// The last 4 bits of byte[5] should be zero.
    47 		if ((header[5] & 0x0f))	// [00001111]
    48 			{
    49 			break;
    50 			}
    51 			
    52 		// Read the tag size. It's stored in a sync-safe manner
    53 		// (the highest bit is never set so it won't be confused
    54 		// with a frame-sync). If the highest bit is set, it's invalid.
    55 		a = header[6];
    56 		b = header[7];
    57 		c = header[8];
    58 		d = header[9];
    59 		
    60 		// OR the values together and check that the highest bit of
    61 		// the result isn't set. Saves on doing four individual checks.
    62 		if ((a | b | c | d) & 0x80) // [10000000]
    63 			{
    64 			break;
    65 			}
    66 		
    67 		// Convert from sync-safe format to normal format.
    68 		// [0aaaaaaa][0bbbbbbb][0ccccccc][0ddddddd] is changed to
    69 		// [0000aaaa][aaabbbbb][bbcccccc][cddddddd]
    70 		//
    71 		// Copy bit[0] of c into bit[7] of d.
    72 		d |= ((c & 0x01) << 7);
    73 		c >>= 1;
    74 		
    75 		// Copy bit[1,0] of b into bit[7,6] of c.
    76 		c |= ((b & 0x03) << 6);
    77 		b >>= 2;
    78 		
    79 		// Copy bit[2,1,0] of a into bit[7,6,5] of b.
    80 		b |= ((a & 0x07) << 5);
    81 		a >>= 3;
    82 		
    83 		TInt length = MAKE_INT32(a, b, c, d);
    84 		aReader.SeekL(length);
    85 		return ETrue;
    86 		}
    87 	while (EFalse);
    88 	
    89 	// It's not an ID3 header.
    90 	// Undo the header read.
    91 	aReader.SeekL(-KID3HeaderSize);
    92 	return EFalse;
    93 	}