source: svn/trunk/newcon3bcm2_21bu/BSEAV/lib/mpeg2_ts_parse/psip_mss.c

Last change on this file was 2, checked in by phkim, 11 years ago

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 5.8 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003-2007, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: psip_mss.c $
11 * $brcm_Revision: 4 $
12 * $brcm_Date: 5/9/07 4:50p $
13 *
14 * [File Description:]
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /BSEAV/lib/mpeg2_ts_parse/psip_mss.c $
19 *
20 * 4   5/9/07 4:50p marcusk
21 * PR 28094: Fixed a problem when decoding a compressed string and an
22 * escaped character is byte aligned.
23 *
24 * 3   2/27/07 11:09a marcusk
25 * PR 28155: Added support for language code.
26 *
27 * 2   2/23/07 5:37p marcusk
28 * PR 28094: Fixed huffman decoding.
29 *
30 * 1   2/7/05 11:26p dlwin
31 * Merge down for release 2005_REFSW_MERGETOMAIN:
32 *
33 * Irvine_BSEAVSW_Devel/2   2/4/04 9:56a erickson
34 * PR9217: converted BDBG_ASSERT calls to CHECK calls. Don't assert on bad
35 * data.
36 *
37 * Irvine_BSEAVSW_Devel/1   8/29/03 5:04p marcusk
38 * Initial Version.
39 *
40 ***************************************************************************/
41#include "bstd.h"
42#include "psip_priv.h"
43#include "psip_mss.h"
44BDBG_MODULE(psip_mss);
45
46extern const uint8_t PSIP_decode_tree_01[];
47extern const uint8_t PSIP_decode_tree_02[];
48
49typedef struct
50{
51        uint32_t        ISO_639_language_code;
52        uint32_t        number_segments;
53} PSIP_MSS_header;
54
55typedef enum
56{
57        no_compression,
58        huffman_program_title,
59        huffman_program_description
60} PSIP_MSS_compression_type;
61
62uint8_t PSIP_MSS_getNumStrings( PSIP_MSS_string mss )
63{
64        return mss[0];
65}
66
67void PSIP_MSS_P_decompressString( const uint8_t *p_decodeTree, const uint8_t *p_compressedString, uint8_t numberBytes, int *p_stringSize, char *p_string )
68{
69        int maxSize = *p_stringSize;
70        uint32_t treeRootOffset = 0;
71        uint32_t childOffset = 0;
72        int curBitNum = 0;
73        uint8_t priorSymbol = 0;
74        bool newCharacter = true;
75        uint8_t curByteValue = p_compressedString[0];
76
77        *p_stringSize = 0;
78
79        while( curBitNum < (numberBytes*8) )
80        {
81                if( !(curBitNum % 8) )
82                {
83                        curByteValue = p_compressedString[curBitNum/8];
84                }
85
86                /* Bytes following esc code (0x27) or characters greater than 127 are never compressed */
87                while( priorSymbol > 127 || priorSymbol == 27 )
88                {
89                        /* Most likely we do not have all 8 bits available from our bitstream,
90                         * so read them from the next byte and or them into our symbol. */
91                        int bitsMissing;
92                        priorSymbol = curByteValue;
93                        curByteValue = p_compressedString[(curBitNum/8)+1];
94                        /* Determine how many bits we have */
95                        bitsMissing = curBitNum%8; 
96                        if( bitsMissing )
97                        {
98                                priorSymbol |= curByteValue>>(8-bitsMissing);
99                                curByteValue <<= bitsMissing;
100                        }
101
102                        p_string[*p_stringSize] = priorSymbol;
103                        *p_stringSize += 1;
104                        curBitNum += 8;
105
106                        newCharacter = true;
107                }
108
109                if( newCharacter )
110                {
111                        CHECK( priorSymbol < 128 );
112                       
113                        treeRootOffset = TS_READ_16( &p_decodeTree[priorSymbol*2] );
114                        childOffset = 0;
115                        newCharacter = false;
116                }
117               
118                /* Does the MSB bit point to the right or left node? (0=left, 1=right)*/
119                if( curByteValue & 0x80 )
120                {
121                        /* right node byte is found one byte ahead of left node */
122                        childOffset+=1;
123                }
124
125                /* Is this a leaf node? */
126                if( p_decodeTree[treeRootOffset+childOffset] & 0x80 )
127                {
128                        priorSymbol = (uint8_t)(p_decodeTree[treeRootOffset+childOffset] & 0x7F);
129
130                        if( priorSymbol < 127 && priorSymbol != 27 )
131                        {
132                                p_string[*p_stringSize] = priorSymbol;
133                                *p_stringSize += 1;
134                                newCharacter = true;
135
136                                if( priorSymbol == 0 || *p_stringSize >= maxSize )
137                                {
138                                        break;
139                                }
140                        }
141                }
142                else
143                {
144                        childOffset = p_decodeTree[treeRootOffset+childOffset] * 2;
145                }
146
147                curByteValue <<= 1;
148                curBitNum++;
149        }
150}
151
152void PSIP_MSS_P_decodeStringSegment( const uint8_t *segBuf, int *p_stringSize, char *p_string )
153{
154        const uint8_t *p_decodeTree = PSIP_decode_tree_02;
155        int i;
156
157        /* This routine currently only supports standard ASCII (Latin) character set */
158        if( segBuf[1] != 0 )
159        {
160                *p_stringSize = 0;
161                return;
162        }
163
164        switch( segBuf[0] )
165        {
166        case no_compression:
167                if( *p_stringSize > segBuf[2] )
168                {
169                        *p_stringSize = segBuf[2];
170                }
171                for( i = 0; i < *p_stringSize; i++ )
172                {
173                        p_string[i] = segBuf[3+i];
174                }
175                break;
176        case huffman_program_title:
177                p_decodeTree = PSIP_decode_tree_01;
178                /* Fallthrough */
179        case huffman_program_description:
180                PSIP_MSS_P_decompressString( p_decodeTree, &segBuf[3], segBuf[2], p_stringSize, p_string );
181                break;
182        default:
183                CHECK( false );
184                return;
185        }
186}
187
188
189static int PSIP_MSS_P_getStringOffset( PSIP_MSS_string mss, int stringNum )
190{
191        int i, j, numSegs;
192        int byteOffset = 1;
193
194        for( i = 0; i < stringNum; i++ )
195        {
196                numSegs = mss[byteOffset+3];
197                byteOffset += 4;
198                for( j=0; j<numSegs; j++ )
199                {
200                        byteOffset += mss[byteOffset+2] + 3;
201                }
202        }
203
204        return byteOffset;
205}
206
207BERR_Code PSIP_MSS_getString( PSIP_MSS_string mss, int stringNum, int *p_stringSize, char *p_string )
208{
209        int j, numSegs;
210        int byteOffset;
211        int stringOffset = 0;
212        int maxStringOffset = *p_stringSize - 1;
213        int size;
214
215        if( stringNum >= mss[0] )
216        {
217                return BERR_INVALID_PARAMETER;
218        }
219
220        byteOffset = PSIP_MSS_P_getStringOffset( mss, stringNum );
221        numSegs = mss[byteOffset+3];
222        byteOffset += 4;
223
224        for( j=0; j<numSegs; j++ )
225        {
226                size = maxStringOffset - stringOffset;
227                PSIP_MSS_P_decodeStringSegment( &mss[byteOffset], &size, &p_string[stringOffset] );
228                stringOffset += size;
229                byteOffset += mss[byteOffset+2] + 3;
230        }
231
232        p_string[stringOffset] = 0;
233        *p_stringSize = stringOffset;
234
235        return BERR_SUCCESS;
236}
237
238BERR_Code PSIP_MSS_getCode( PSIP_MSS_string mss, int stringNum, char **ppLanguageCode )
239{
240        int byteOffset;
241       
242        if( stringNum >= mss[0] )
243        {
244            return BERR_INVALID_PARAMETER;
245        }
246       
247        byteOffset = PSIP_MSS_P_getStringOffset( mss, stringNum );
248        *ppLanguageCode = (char *)&mss[byteOffset]; 
249        return BERR_SUCCESS;
250}
251
252/* End of File */
Note: See TracBrowser for help on using the repository browser.