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