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) { 33d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return extract3GPPGlobalDescriptions(data, size, parcel); 343b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } else if (flags & LOCAL_DESCRIPTIONS) { 35d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return extract3GPPLocalDescriptions(data, size, timeMs, parcel); 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, 72d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen int timeMs, Parcel *parcel) { 73d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 74d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_LOCAL_SETTING); 75d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 76d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // write start time to display this text sample 77d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_START_TIME); 78d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(timeMs); 79d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 80d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (size < 2) { 81d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 823b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 83d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen ssize_t textLen = (*data) << 8 | (*(data + 1)); 843b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 85d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (size < textLen + 2) { 86d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 87d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 883b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 89d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // write text sample length and text sample itself 90d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_STRUCT_TEXT); 91d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(textLen); 92d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(textLen); 93d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->write(data + 2, textLen); 94d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 95d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (size > textLen + 2) { 96d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen data += (textLen + 2); 97d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen size -= (textLen + 2); 98d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } else { 993b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return OK; 1003b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 1013b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 102d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen while (size >= 8) { 103d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen const uint8_t *tmpData = data; 104d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen ssize_t chunkSize = U32_AT(tmpData); // size includes size and type 105d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen uint32_t chunkType = U32_AT(tmpData + 4); 1063b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 107d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (chunkSize <= 8 || chunkSize > size) { 108d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 109d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 1103b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 111d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen size_t remaining = chunkSize - 8; 1123b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 113d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen tmpData += 8; 1143b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 115d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen switch(chunkType) { 116d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // 'styl' box specifies the style of the text. 117d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen case FOURCC('s', 't', 'y', 'l'): 118d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen { 119d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (remaining < 2) { 120d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 121d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 122d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen size_t dataPos = parcel->dataPosition(); 123d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen uint16_t count = U16_AT(tmpData); 1243b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 125d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen tmpData += 2; 126d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen remaining -= 2; 1273b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 128d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen for (int i = 0; i < count; i++) { 129d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (remaining < 12) { 130d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // roll back 131d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->setDataPosition(dataPos); 132d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 133d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 134d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_STRUCT_STYLE_LIST); 135d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_START_CHAR); 136d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U16_AT(tmpData)); 1373b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 138d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_END_CHAR); 139d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U16_AT(tmpData + 2)); 1403b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 141d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_FONT_ID); 142d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U16_AT(tmpData + 4)); 1433b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 144d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_STYLE_FLAGS); 145d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(*(tmpData + 6)); 146d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 147d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_FONT_SIZE); 148d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(*(tmpData + 7)); 149d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 150d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_TEXT_COLOR_RGBA); 151d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen uint32_t rgba = *(tmpData + 8) << 24 | *(tmpData + 9) << 16 152d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen | *(tmpData + 10) << 8 | *(tmpData + 11); 153d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(rgba); 154d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 155d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen tmpData += 12; 156d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen remaining -= 12; 157d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 158d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 159d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen break; 160d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 161d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // 'krok' box. The number of highlight events is specified, and each 162d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // event is specified by a starting and ending char offset and an end 163d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // time for the event. 164d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen case FOURCC('k', 'r', 'o', 'k'): 165d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen { 166d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (remaining < 6) { 167d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 168d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 169d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen size_t dataPos = parcel->dataPosition(); 170d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 171d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_STRUCT_KARAOKE_LIST); 172d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 173d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen int startTime = U32_AT(tmpData); 174d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen uint16_t count = U16_AT(tmpData + 4); 175d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(count); 176d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 177d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen tmpData += 6; 178d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen remaining -= 6; 179d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen int lastEndTime = 0; 180d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 181d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen for (int i = 0; i < count; i++) { 182d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (remaining < 8) { 183d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // roll back 184d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->setDataPosition(dataPos); 185d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 186d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 187d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(startTime + lastEndTime); 188d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 189d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen lastEndTime = U32_AT(tmpData); 190d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(lastEndTime); 191d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 192d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U16_AT(tmpData + 4)); 193d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U16_AT(tmpData + 6)); 194d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 195d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen tmpData += 8; 196d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen remaining -= 8; 197d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 198d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 199d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen break; 2003b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 201d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // 'hlit' box specifies highlighted text 202d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen case FOURCC('h', 'l', 'i', 't'): 203d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen { 204d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (remaining < 4) { 205d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 206d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 2073b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 208d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_STRUCT_HIGHLIGHT_LIST); 2093b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 210d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // the start char offset to highlight 211d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U16_AT(tmpData)); 212d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // the last char offset to highlight 213d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U16_AT(tmpData + 2)); 2143b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 215d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen tmpData += 4; 216d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen remaining -= 4; 217d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen break; 218d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 219d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // 'hclr' box specifies the RGBA color: 8 bits each of 220d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // red, green, blue, and an alpha(transparency) value 221d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen case FOURCC('h', 'c', 'l', 'r'): 222d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen { 223d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (remaining < 4) { 224d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 225d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 226d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_HIGHLIGHT_COLOR_RGBA); 227d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 228d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen uint32_t rgba = *(tmpData) << 24 | *(tmpData + 1) << 16 229d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen | *(tmpData + 2) << 8 | *(tmpData + 3); 230d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(rgba); 231d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 232d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen tmpData += 4; 233d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen remaining -= 4; 234d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen break; 235d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 236d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // 'dlay' box specifies a delay after a scroll in and/or 237d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // before scroll out. 238d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen case FOURCC('d', 'l', 'a', 'y'): 239d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen { 240d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (remaining < 4) { 241d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 242d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 243d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_SCROLL_DELAY); 244d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 245d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen uint32_t delay = *(tmpData) << 24 | *(tmpData + 1) << 16 246d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen | *(tmpData + 2) << 8 | *(tmpData + 3); 247d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(delay); 248d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 249d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen tmpData += 4; 250d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen remaining -= 4; 251d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen break; 252d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 253d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // 'href' box for hyper text link 254d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen case FOURCC('h', 'r', 'e', 'f'): 255d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen { 256d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (remaining < 5) { 257d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 258d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 2593b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 260d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen size_t dataPos = parcel->dataPosition(); 2613b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 262d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_STRUCT_HYPER_TEXT_LIST); 2633b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 264d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // the start offset of the text to be linked 265d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U16_AT(tmpData)); 266d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // the end offset of the text 267d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U16_AT(tmpData + 2)); 2683b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 269d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // the number of bytes in the following URL 270d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen size_t len = *(tmpData + 4); 271d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(len); 272d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 273d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen remaining -= 5; 274d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 275d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (remaining < len) { 276d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->setDataPosition(dataPos); 277d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 278d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 279d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // the linked-to URL 280d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(len); 281d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->write(tmpData + 5, len); 282d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 283d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen tmpData += (5 + len); 284d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen remaining -= len; 285d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 286d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (remaining < 1) { 287d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->setDataPosition(dataPos); 288d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 289d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 290d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 291d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // the number of bytes in the following "alt" string 292d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen len = *tmpData; 293d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(len); 294d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 295d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen tmpData += 1; 296d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen remaining -= 1; 297d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (remaining < len) { 298d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->setDataPosition(dataPos); 299d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 300d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 301d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 302d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // an "alt" string for user display 303d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(len); 304d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->write(tmpData, len); 305d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 306d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen tmpData += 1; 307d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen remaining -= 1; 308d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen break; 309d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 310d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // 'tbox' box to indicate the position of the text with values 311d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // of top, left, bottom and right 312d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen case FOURCC('t', 'b', 'o', 'x'): 313d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen { 314d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (remaining < 8) { 315d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 316d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 317d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_STRUCT_TEXT_POS); 318d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U16_AT(tmpData)); 319d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U16_AT(tmpData + 2)); 3203b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData + 4)); 3213b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang parcel->writeInt32(U16_AT(tmpData + 6)); 3223b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 3233b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang tmpData += 8; 324d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen remaining -= 8; 325d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen break; 3263b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 327d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // 'blnk' to specify the char range to be blinked 328d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen case FOURCC('b', 'l', 'n', 'k'): 329d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen { 330d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (remaining < 4) { 331d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 332d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 3333b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 334d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_STRUCT_BLINKING_TEXT_LIST); 3353b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 336d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // start char offset 337d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U16_AT(tmpData)); 338d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // end char offset 339d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U16_AT(tmpData + 2)); 3403b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 341d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen tmpData += 4; 342d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen remaining -= 4; 343d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen break; 344d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 345d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // 'twrp' box specifies text wrap behavior. If the value if 0x00, 346d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // then no wrap. If it's 0x01, then automatic 'soft' wrap is enabled. 347d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // 0x02-0xff are reserved. 348d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen case FOURCC('t', 'w', 'r', 'p'): 349d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen { 350d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (remaining < 1) { 351d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 352d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 353d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_WRAP_TEXT); 354d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(*tmpData); 355d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 356d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen tmpData += 1; 357d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen remaining -= 1; 358d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen break; 359d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 360d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen default: 361d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen { 362d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen break; 363d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 3643b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 3653b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 366d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen data += chunkSize; 367d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen size -= chunkSize; 368d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 369d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 370d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 371d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen} 3723b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 373d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen// To extract box 'tx3g' defined in 3GPP TS 26.245, and store it in a Parcel 374d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissenstatus_t TextDescriptions::extract3GPPGlobalDescriptions( 375d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen const uint8_t *data, ssize_t size, Parcel *parcel) { 376d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 377d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_GLOBAL_SETTING); 3783b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 379d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen while (size >= 8) { 380d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen ssize_t chunkSize = U32_AT(data); 381d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen uint32_t chunkType = U32_AT(data + 4); 382d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen const uint8_t *tmpData = data; 383d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen tmpData += 8; 384d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen size_t remaining = size - 8; 3853b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 386d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (size < chunkSize) { 387d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 3883b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 389d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen switch(chunkType) { 390d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen case FOURCC('t', 'x', '3', 'g'): 391d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen { 392d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (remaining < 18) { // 8 just below, and another 10 a little further down 393d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 394d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 395d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen tmpData += 8; // skip the first 8 bytes 396d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen remaining -=8; 397d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_DISPLAY_FLAGS); 398d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U32_AT(tmpData)); 399d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 400d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_STRUCT_JUSTIFICATION); 401d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(tmpData[4]); 402d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(tmpData[5]); 403d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 404d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_BACKGROUND_COLOR_RGBA); 405d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen uint32_t rgba = *(tmpData + 6) << 24 | *(tmpData + 7) << 16 406d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen | *(tmpData + 8) << 8 | *(tmpData + 9); 407d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(rgba); 4083b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 409d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen tmpData += 10; 410d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen remaining -= 10; 4113b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 412d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (remaining < 8) { 413d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 414d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 415d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_STRUCT_TEXT_POS); 416d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U16_AT(tmpData)); 417d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U16_AT(tmpData + 2)); 418d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U16_AT(tmpData + 4)); 419d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U16_AT(tmpData + 6)); 4203b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 421d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen tmpData += 8; 422d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen remaining -= 8; 4233b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 424d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (remaining < 12) { 425d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 426d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 427d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_STRUCT_STYLE_LIST); 428d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_START_CHAR); 429d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U16_AT(tmpData)); 4303b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 431d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_END_CHAR); 432d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U16_AT(tmpData + 2)); 4333b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 434d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_FONT_ID); 435d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U16_AT(tmpData + 4)); 4363b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 437d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_STYLE_FLAGS); 438d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(*(tmpData + 6)); 4393b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 440d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_FONT_SIZE); 441d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(*(tmpData + 7)); 4423b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 443d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_TEXT_COLOR_RGBA); 444d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen rgba = *(tmpData + 8) << 24 | *(tmpData + 9) << 16 445d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen | *(tmpData + 10) << 8 | *(tmpData + 11); 446d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(rgba); 4473b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 448d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen tmpData += 12; 449d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen remaining -= 12; 4503b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 451d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (remaining < 2) { 452d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 453d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 4543b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 455d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen size_t dataPos = parcel->dataPosition(); 4563b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 457d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(KEY_STRUCT_FONT_LIST); 458d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen uint16_t count = U16_AT(tmpData); 459d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(count); 4603b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 461d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen tmpData += 2; 462d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen remaining -= 2; 4633b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 464d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen for (int i = 0; i < count; i++) { 465d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (remaining < 3) { 466d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // roll back 467d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->setDataPosition(dataPos); 468d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 469d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 470d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // font ID 471d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(U16_AT(tmpData)); 4723b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 473d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // font name length 474d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->writeInt32(*(tmpData + 2)); 4753b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 476d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen size_t len = *(tmpData + 2); 4773b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 478d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen tmpData += 3; 479d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen remaining -= 3; 4803b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 481d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen if (remaining < len) { 482d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // roll back 483d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->setDataPosition(dataPos); 484d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen return OK; 485d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 4863b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 487d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen parcel->write(tmpData, len); 488d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen tmpData += len; 489d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen remaining -= len; 490d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 4913b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 492d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen // there is a "DisparityBox" after this according to the spec, but we ignore it 493d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen break; 494d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 495d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen default: 496d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen { 497d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen break; 498d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 499d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen } 500d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen 501d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen data += chunkSize; 502d53aced041b7214a92b1f2fd5970d895bb9934e5Marco Nelissen size -= chunkSize; 5033b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 5043b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 5053b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return OK; 5063b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang} 5073b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 5083b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang} // namespace android 509