13b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang/* 23b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang * Copyright (C) 2011 The Android Open Source Project 33b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang * 43b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang * Licensed under the Apache License, Version 2.0 (the "License"); 53b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang * you may not use this file except in compliance with the License. 63b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang * You may obtain a copy of the License at 73b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang * 83b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang * http://www.apache.org/licenses/LICENSE-2.0 93b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang * 103b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang * Unless required by applicable law or agreed to in writing, software 113b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang * distributed under the License is distributed on an "AS IS" BASIS, 123b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang * See the License for the specific language governing permissions and 143b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang * limitations under the License. 153b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang */ 163b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 173b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang#include "TextDescriptions.h" 183b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang#include <media/stagefright/Utils.h> 193b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang#include <media/stagefright/MediaErrors.h> 203b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 213b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wangnamespace android { 223b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 233b573f7bf1c5736d500e39013b8d32478a1429e6Gloria WangTextDescriptions::TextDescriptions() { 243b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang} 253b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 263b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wangstatus_t TextDescriptions::getParcelOfDescriptions( 273b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const uint8_t *data, ssize_t size, 283b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t flags, int timeMs, Parcel *parcel) { 293b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->freeData(); 303b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 313b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (flags & IN_BAND_TEXT_3GPP) { 323b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (flags & GLOBAL_DESCRIPTIONS) { 333b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return extract3GPPGlobalDescriptions(data, size, parcel, 0); 343b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } else if (flags & LOCAL_DESCRIPTIONS) { 353b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return extract3GPPLocalDescriptions(data, size, timeMs, parcel, 0); 363b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 373b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } else if (flags & OUT_OF_BAND_TEXT_SRT) { 383b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (flags & LOCAL_DESCRIPTIONS) { 393b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return extractSRTLocalDescriptions(data, size, timeMs, parcel); 403b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 413b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 423b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 433b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_UNSUPPORTED; 443b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang} 453b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 463b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang// Parse the SRT text sample, and store the timing and text sample in a Parcel. 473b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang// The Parcel will be sent to MediaPlayer.java through event, and will be 483b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang// parsed in TimedText.java. 493b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wangstatus_t TextDescriptions::extractSRTLocalDescriptions( 503b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const uint8_t *data, ssize_t size, int timeMs, Parcel *parcel) { 513b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_LOCAL_SETTING); 523b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_START_TIME); 533b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(timeMs); 543b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 553b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_STRUCT_TEXT); 563b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // write the size of the text sample 573b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(size); 583b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // write the text sample as a byte array 593b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(size); 603b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->write(data, size); 613b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 623b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return OK; 633b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang} 643b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 653b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang// Extract the local 3GPP display descriptions. 3GPP local descriptions 663b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang// are appended to the text sample if any. The descriptions could include 673b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang// information such as text styles, highlights, karaoke and so on. They 683b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang// are contained in different boxes, such as 'styl' box contains text 693b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang// styles, and 'krok' box contains karaoke timing and positions. 703b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wangstatus_t TextDescriptions::extract3GPPLocalDescriptions( 713b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const uint8_t *data, ssize_t size, 723b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang int timeMs, Parcel *parcel, int depth) { 733b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (depth == 0) { 743b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_LOCAL_SETTING); 753b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 763b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // write start time to display this text sample 773b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_START_TIME); 783b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(timeMs); 793b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 803b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang ssize_t textLen = (*data) << 8 | (*(data + 1)); 813b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 823b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // write text sample length and text sample itself 833b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_STRUCT_TEXT); 843b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(textLen); 853b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(textLen); 863b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->write(data + 2, textLen); 873b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 883b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (size > textLen) { 893b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang data += (textLen + 2); 903b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size -= (textLen + 2); 913b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } else { 923b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return OK; 933b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 943b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 953b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 963b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const uint8_t *tmpData = data; 973b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang ssize_t chunkSize = U32_AT(tmpData); 983b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t chunkType = U32_AT(tmpData + 4); 993b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1003b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (chunkSize <= 0) { 1013b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return OK; 1023b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 1033b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1043b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang tmpData += 8; 1053b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1063b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang switch(chunkType) { 1073b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // 'styl' box specifies the style of the text. 1083b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang case FOURCC('s', 't', 'y', 'l'): 1093b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 1103b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint16_t count = U16_AT(tmpData); 1113b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1123b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang tmpData += 2; 1133b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1143b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang for (int i = 0; i < count; i++) { 1153b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_STRUCT_STYLE_LIST); 1163b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_START_CHAR); 1173b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData)); 1183b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1193b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_END_CHAR); 1203b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData + 2)); 1213b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1223b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_FONT_ID); 1233b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData + 4)); 1243b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1253b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_STYLE_FLAGS); 1263b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(*(tmpData + 6)); 1273b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1283b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_FONT_SIZE); 1293b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(*(tmpData + 7)); 1303b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1313b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_TEXT_COLOR_RGBA); 1323b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t rgba = *(tmpData + 8) << 24 | *(tmpData + 9) << 16 1333b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang | *(tmpData + 10) << 8 | *(tmpData + 11); 1343b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(rgba); 1353b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1363b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang tmpData += 12; 1373b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 1383b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1393b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 1403b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 1413b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // 'krok' box. The number of highlight events is specified, and each 1423b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // event is specified by a starting and ending char offset and an end 1433b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // time for the event. 1443b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang case FOURCC('k', 'r', 'o', 'k'): 1453b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 1463b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1473b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_STRUCT_KARAOKE_LIST); 1483b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1493b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang int startTime = U32_AT(tmpData); 1503b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint16_t count = U16_AT(tmpData + 4); 1513b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(count); 1523b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1533b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang tmpData += 6; 1543b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang int lastEndTime = 0; 1553b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1563b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang for (int i = 0; i < count; i++) { 1573b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(startTime + lastEndTime); 1583b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1593b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang lastEndTime = U32_AT(tmpData); 1603b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(lastEndTime); 1613b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1623b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData + 4)); 1633b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData + 6)); 1643b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1653b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang tmpData += 8; 1663b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 1673b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1683b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 1693b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 1703b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // 'hlit' box specifies highlighted text 1713b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang case FOURCC('h', 'l', 'i', 't'): 1723b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 1733b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_STRUCT_HIGHLIGHT_LIST); 1743b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1753b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // the start char offset to highlight 1763b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData)); 1773b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // the last char offset to highlight 1783b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData + 2)); 1793b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1803b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 1813b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 1823b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // 'hclr' box specifies the RGBA color: 8 bits each of 1833b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // red, green, blue, and an alpha(transparency) value 1843b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang case FOURCC('h', 'c', 'l', 'r'): 1853b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 1863b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_HIGHLIGHT_COLOR_RGBA); 1873b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1883b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t rgba = *(tmpData) << 24 | *(tmpData + 1) << 16 1893b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang | *(tmpData + 2) << 8 | *(tmpData + 3); 1903b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(rgba); 1913b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1923b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 1933b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 1943b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // 'dlay' box specifies a delay after a scroll in and/or 1953b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // before scroll out. 1963b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang case FOURCC('d', 'l', 'a', 'y'): 1973b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 1983b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_SCROLL_DELAY); 1993b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 2003b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t delay = *(tmpData) << 24 | *(tmpData + 1) << 16 2013b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang | *(tmpData + 2) << 8 | *(tmpData + 3); 2023b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(delay); 2033b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 2043b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 2053b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 2063b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // 'href' box for hyper text link 2073b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang case FOURCC('h', 'r', 'e', 'f'): 2083b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 2093b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_STRUCT_HYPER_TEXT_LIST); 2103b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 2113b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // the start offset of the text to be linked 2123b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData)); 2133b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // the end offset of the text 2143b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData + 2)); 2153b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 2163b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // the number of bytes in the following URL 2173b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang int len = *(tmpData + 4); 2183b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(len); 2193b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 2203b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // the linked-to URL 2213b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(len); 2223b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->write(tmpData + 5, len); 2233b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 2243b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang tmpData += (5 + len); 2253b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 2263b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // the number of bytes in the following "alt" string 2273b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang len = *tmpData; 2283b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(len); 2293b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 2303b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // an "alt" string for user display 2313b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(len); 2323b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->write(tmpData + 1, len); 2333b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 2343b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 2353b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 2363b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // 'tbox' box to indicate the position of the text with values 2373b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // of top, left, bottom and right 2383b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang case FOURCC('t', 'b', 'o', 'x'): 2393b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 2403b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_STRUCT_TEXT_POS); 2413b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData)); 2423b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData + 2)); 2433b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData + 4)); 2443b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData + 6)); 2453b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 2463b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 2473b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 2483b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // 'blnk' to specify the char range to be blinked 2493b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang case FOURCC('b', 'l', 'n', 'k'): 2503b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 2513b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_STRUCT_BLINKING_TEXT_LIST); 2523b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 2533b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // start char offset 2543b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData)); 2553b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // end char offset 2563b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData + 2)); 2573b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 2583b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 2593b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 2603b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // 'twrp' box specifies text wrap behavior. If the value if 0x00, 2613b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // then no wrap. If it's 0x01, then automatic 'soft' wrap is enabled. 2623b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // 0x02-0xff are reserved. 2633b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang case FOURCC('t', 'w', 'r', 'p'): 2643b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 2653b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_WRAP_TEXT); 2663b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(*tmpData); 2673b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 2683b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 2693b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 2703b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang default: 2713b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 2723b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 2733b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 2743b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 2753b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 2763b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (size > chunkSize) { 2773b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang data += chunkSize; 2783b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size -= chunkSize; 2793b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // continue to parse next box 2803b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return extract3GPPLocalDescriptions(data, size, 0, parcel, 1); 2813b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 2823b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 2833b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return OK; 2843b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang} 2853b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 2863b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang// To extract box 'tx3g' defined in 3GPP TS 26.245, and store it in a Parcel 2873b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wangstatus_t TextDescriptions::extract3GPPGlobalDescriptions( 2883b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const uint8_t *data, ssize_t size, Parcel *parcel, int depth) { 2893b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 2903b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang ssize_t chunkSize = U32_AT(data); 2913b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t chunkType = U32_AT(data + 4); 2923b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const uint8_t *tmpData = data; 2933b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang tmpData += 8; 2943b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 2953b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (size < chunkSize) { 2963b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return OK; 2973b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 2983b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 2993b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (depth == 0) { 3003b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_GLOBAL_SETTING); 3013b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 3023b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang switch(chunkType) { 3033b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang case FOURCC('t', 'x', '3', 'g'): 3043b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 3053b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang tmpData += 8; // skip the first 8 bytes 3063b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_DISPLAY_FLAGS); 3073b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U32_AT(tmpData)); 3083b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 3093b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_STRUCT_JUSTIFICATION); 3103b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(tmpData[4]); 3113b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(tmpData[5]); 3123b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 3133b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_BACKGROUND_COLOR_RGBA); 3143b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t rgba = *(tmpData + 6) << 24 | *(tmpData + 7) << 16 3153b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang | *(tmpData + 8) << 8 | *(tmpData + 9); 3163b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(rgba); 3173b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 3183b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang tmpData += 10; 3193b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_STRUCT_TEXT_POS); 3203b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData)); 3213b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData + 2)); 3223b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData + 4)); 3233b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData + 6)); 3243b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 3253b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang tmpData += 8; 3263b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_STRUCT_STYLE_LIST); 3273b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_START_CHAR); 3283b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData)); 3293b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 3303b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_END_CHAR); 3313b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData + 2)); 3323b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 3333b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_FONT_ID); 3343b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData + 4)); 3353b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 3363b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_STYLE_FLAGS); 3373b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(*(tmpData + 6)); 3383b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 3393b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_FONT_SIZE); 3403b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(*(tmpData + 7)); 3413b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 3423b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_TEXT_COLOR_RGBA); 3433b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang rgba = *(tmpData + 8) << 24 | *(tmpData + 9) << 16 3443b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang | *(tmpData + 10) << 8 | *(tmpData + 11); 3453b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(rgba); 3463b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 3473b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang tmpData += 12; 3483b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(KEY_STRUCT_FONT_LIST); 3493b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint16_t count = U16_AT(tmpData); 3503b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(count); 3513b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 3523b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang tmpData += 2; 3533b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang for (int i = 0; i < count; i++) { 3543b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // font ID 3553b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData)); 3563b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 3573b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // font name length 3583b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(*(tmpData + 2)); 3593b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 3603b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang int len = *(tmpData + 2); 3613b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 3623b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->write(tmpData + 3, len); 3633b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang tmpData += 3 + len; 3643b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 3653b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 3663b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 3673b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 3683b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang default: 3693b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 3703b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 3713b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 3723b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 3733b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 3743b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang data += chunkSize; 3753b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size -= chunkSize; 3763b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 3773b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (size > 0) { 3783b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // continue to extract next 'tx3g' 3793b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return extract3GPPGlobalDescriptions(data, size, parcel, 1); 3803b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 3813b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 3823b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return OK; 3833b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang} 3843b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 3853b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang} // namespace android 386