10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/* 20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2006 The Android Open Source Project 30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License"); 50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License. 60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at 70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * http://www.apache.org/licenses/LICENSE-2.0 90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software 110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS, 120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and 140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License. 150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony; 180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.res.Resources; 200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.res.Resources.NotFoundException; 210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.graphics.Bitmap; 220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.graphics.Color; 2399c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Savilleimport android.telephony.Rlog; 240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.GsmAlphabet; 260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.UnsupportedEncodingException; 270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** 290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Various methods, useful for dealing with SIM data. 300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 310825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic class IccUtils { 320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final String LOG_TAG="IccUtils"; 330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Many fields in GSM SIM's are stored as nibble-swizzled BCD 360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Assumes left-justified field that may be padded right with 0xf 380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * values. 390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Stops on invalid BCD value, returning string so far 410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static String 430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bcdToString(byte[] data, int offset, int length) { 440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville StringBuilder ret = new StringBuilder(length*2); 450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int i = offset ; i < offset + length ; i++) { 470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte b; 480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int v; 490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville v = data[i] & 0xf; 510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (v > 9) break; 520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret.append((char)('0' + v)); 530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville v = (data[i] >> 4) & 0xf; 550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Some PLMNs have 'f' as high nibble, ignore it 560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (v == 0xf) continue; 570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (v > 9) break; 580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret.append((char)('0' + v)); 590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ret.toString(); 620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Decode cdma byte into String. 660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static String 680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cdmaBcdToString(byte[] data, int offset, int length) { 690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville StringBuilder ret = new StringBuilder(length); 700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int count = 0; 720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int i = offset; count < length; i++) { 730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int v; 740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville v = data[i] & 0xf; 750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (v > 9) v = 0; 760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret.append((char)('0' + v)); 770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (++count == length) break; 790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville v = (data[i] >> 4) & 0xf; 810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (v > 9) v = 0; 820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret.append((char)('0' + v)); 830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ++count; 840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ret.toString(); 860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Decodes a GSM-style BCD byte, returning an int ranging from 0-99. 900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * In GSM land, the least significant BCD digit is stored in the most 920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * significant nibble. 930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Out-of-range digits are treated as 0 for the sake of the time stamp, 950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * because of this: 960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TS 23.040 section 9.2.3.11 980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * "if the MS receives a non-integer value in the SCTS, it shall 990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * assume the digit is set to 0 but shall store the entire field 1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * exactly as received" 1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static int 1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville gsmBcdByteToInt(byte b) { 1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int ret = 0; 1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // treat out-of-range BCD values as 0 1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((b & 0xf0) <= 0x90) { 1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret = (b >> 4) & 0xf; 1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((b & 0x0f) <= 0x09) { 1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret += (b & 0xf) * 10; 1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ret; 1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 119cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville * Decodes a CDMA style BCD byte like {@link #gsmBcdByteToInt}, but 1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * opposite nibble format. The least significant BCD digit 1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * is in the least significant nibble and the most significant 1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * is in the most significant nibble. 1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static int 1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cdmaBcdByteToInt(byte b) { 1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int ret = 0; 1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // treat out-of-range BCD values as 0 1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((b & 0xf0) <= 0x90) { 1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret = ((b >> 4) & 0xf) * 10; 1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((b & 0x0f) <= 0x09) { 1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret += (b & 0xf); 1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ret; 1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Decodes a string field that's formatted like the EF[ADN] alpha 1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * identifier 1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * From TS 51.011 10.5.1: 1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Coding: 1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * this alpha tagging shall use either 1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * - the SMS default 7 bit coded alphabet as defined in 1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TS 23.038 [12] with bit 8 set to 0. The alpha identifier 1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * shall be left justified. Unused bytes shall be set to 'FF'; or 1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * - one of the UCS2 coded options as defined in annex B. 1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Annex B from TS 11.11 V8.13.0: 1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 1) If the first octet in the alpha string is '80', then the 1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * remaining octets are 16 bit UCS2 characters ... 1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 2) if the first octet in the alpha string is '81', then the 1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * second octet contains a value indicating the number of 1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * characters in the string, and the third octet contains an 1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 8 bit number which defines bits 15 to 8 of a 16 bit 1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * base pointer, where bit 16 is set to zero and bits 7 to 1 1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * are also set to zero. These sixteen bits constitute a 1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * base pointer to a "half page" in the UCS2 code space, to be 1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * used with some or all of the remaining octets in the string. 1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * The fourth and subsequent octets contain codings as follows: 1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * If bit 8 of the octet is set to zero, the remaining 7 bits 1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * of the octet contain a GSM Default Alphabet character, 1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * whereas if bit 8 of the octet is set to one, then the 1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * remaining seven bits are an offset value added to the 1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 16 bit base pointer defined earlier... 1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 3) If the first octet of the alpha string is set to '82', then 1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * the second octet contains a value indicating the number of 1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * characters in the string, and the third and fourth octets 1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * contain a 16 bit number which defines the complete 16 bit 1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * base pointer to a "half page" in the UCS2 code space... 1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static String 1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville adnStringFieldToString(byte[] data, int offset, int length) { 1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (length == 0) { 1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ""; 1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (length >= 1) { 1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (data[offset] == (byte) 0x80) { 1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int ucslen = (length - 1) / 2; 1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String ret = null; 1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret = new String(data, offset + 1, ucslen * 2, "utf-16be"); 1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (UnsupportedEncodingException ex) { 18899c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.e(LOG_TAG, "implausible UnsupportedEncodingException", 1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ex); 1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (ret != null) { 1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // trim off trailing FFFF characters 1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ucslen = ret.length(); 1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville while (ucslen > 0 && ret.charAt(ucslen - 1) == '\uFFFF') 1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ucslen--; 1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ret.substring(0, ucslen); 2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean isucs2 = false; 2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville char base = '\0'; 2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int len = 0; 2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (length >= 3 && data[offset] == (byte) 0x81) { 2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville len = data[offset + 1] & 0xFF; 2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (len > length - 3) 2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville len = length - 3; 2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville base = (char) ((data[offset + 2] & 0xFF) << 7); 2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville offset += 3; 2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville isucs2 = true; 2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (length >= 4 && data[offset] == (byte) 0x82) { 2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville len = data[offset + 1] & 0xFF; 2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (len > length - 4) 2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville len = length - 4; 2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville base = (char) (((data[offset + 2] & 0xFF) << 8) | 2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (data[offset + 3] & 0xFF)); 2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville offset += 4; 2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville isucs2 = true; 2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (isucs2) { 2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville StringBuilder ret = new StringBuilder(); 2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville while (len > 0) { 2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // UCS2 subset case 2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (data[offset] < 0) { 2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret.append((char) (base + (data[offset] & 0x7F))); 2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville offset++; 2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville len--; 2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // GSM character set case 2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int count = 0; 2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville while (count < len && data[offset + count] >= 0) 2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville count++; 2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret.append(GsmAlphabet.gsm8BitUnpackedToString(data, 2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville offset, count)); 2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville offset += count; 2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville len -= count; 2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ret.toString(); 2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Resources resource = Resources.getSystem(); 2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String defaultCharset = ""; 2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville defaultCharset = 2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville resource.getString(com.android.internal.R.string.gsm_alphabet_default_charset); 2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (NotFoundException e) { 2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Ignore Exception and defaultCharset is set to a empty string. 2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return GsmAlphabet.gsm8BitUnpackedToString(data, offset, length, defaultCharset.trim()); 2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static int 2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville hexCharToInt(char c) { 2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (c >= '0' && c <= '9') return (c - '0'); 2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (c >= 'A' && c <= 'F') return (c - 'A' + 10); 2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (c >= 'a' && c <= 'f') return (c - 'a' + 10); 2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throw new RuntimeException ("invalid hex char '" + c + "'"); 2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Converts a hex String to a byte array. 2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param s A string of hexadecimal characters, must be an even number of 2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * chars long 2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return byte array representation 2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @throws RuntimeException on invalid format 2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static byte[] 2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville hexStringToBytes(String s) { 2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] ret; 2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (s == null) return null; 2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int sz = s.length(); 2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret = new byte[sz/2]; 2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int i=0 ; i <sz ; i+=2) { 2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret[i/2] = (byte) ((hexCharToInt(s.charAt(i)) << 4) 2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville | hexCharToInt(s.charAt(i+1))); 2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ret; 3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Converts a byte array into a String of hexadecimal characters. 3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param bytes an array of bytes 3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return hex string representation of bytes array 3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static String 3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bytesToHexString(byte[] bytes) { 3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (bytes == null) return null; 3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville StringBuilder ret = new StringBuilder(2*bytes.length); 3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int i = 0 ; i < bytes.length ; i++) { 3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int b; 3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville b = 0x0f & (bytes[i] >> 4); 3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret.append("0123456789abcdef".charAt(b)); 3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville b = 0x0f & bytes[i]; 3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret.append("0123456789abcdef".charAt(b)); 3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ret.toString(); 3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Convert a TS 24.008 Section 10.5.3.5a Network Name field to a string 3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * "offset" points to "octet 3", the coding scheme byte 3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * empty string returned on decode error 3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static String 3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville networkNameToString(byte[] data, int offset, int length) { 3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String ret; 3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((data[offset] & 0x80) != 0x80 || length < 1) { 3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ""; 3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch ((data[offset] >>> 4) & 0x7) { 3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 0: 3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // SMS character set 3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int countSeptets; 3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int unusedBits = data[offset] & 7; 3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville countSeptets = (((length - 1) * 8) - unusedBits) / 7 ; 3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret = GsmAlphabet.gsm7BitPackedToString(data, offset + 1, countSeptets); 3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 1: 3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // UCS2 3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret = new String(data, 3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville offset + 1, length - 1, "utf-16"); 3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (UnsupportedEncodingException ex) { 3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret = ""; 36199c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.e(LOG_TAG,"implausible UnsupportedEncodingException", ex); 3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // unsupported encoding 3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret = ""; 3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // "Add CI" 3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // "The MS should add the letters for the Country's Initials and 3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // a separator (e.g. a space) to the text string" 3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((data[offset] & 0x40) != 0) { 3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // FIXME(mkf) add country initials here 3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ret; 3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Convert a TS 131.102 image instance of code scheme '11' into Bitmap 3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param data The raw data 3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param length The length of image body 3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return The bitmap 3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static Bitmap parseToBnW(byte[] data, int length){ 3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int valueIndex = 0; 3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int width = data[valueIndex++] & 0xFF; 3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int height = data[valueIndex++] & 0xFF; 3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int numOfPixels = width*height; 3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int[] pixels = new int[numOfPixels]; 3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int pixelIndex = 0; 3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int bitIndex = 7; 3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte currentByte = 0x00; 4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville while (pixelIndex < numOfPixels) { 4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // reassign data and index for every byte (8 bits). 4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (pixelIndex % 8 == 0) { 4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville currentByte = data[valueIndex++]; 4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bitIndex = 7; 4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pixels[pixelIndex++] = bitToRGB((currentByte >> bitIndex-- ) & 0x01); 407cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville } 4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (pixelIndex != numOfPixels) { 41099c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.e(LOG_TAG, "parse end and size error"); 4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888); 4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static int bitToRGB(int bit){ 4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if(bit == 1){ 4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Color.WHITE; 4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Color.BLACK; 4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * a TS 131.102 image instance of code scheme '11' into color Bitmap 4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param data The raw data 4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param length the length of image body 4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param transparency with or without transparency 4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return The color bitmap 4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static Bitmap parseToRGB(byte[] data, int length, 4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean transparency) { 4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int valueIndex = 0; 4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int width = data[valueIndex++] & 0xFF; 4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int height = data[valueIndex++] & 0xFF; 4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int bits = data[valueIndex++] & 0xFF; 4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int colorNumber = data[valueIndex++] & 0xFF; 4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int clutOffset = ((data[valueIndex++] & 0xFF) << 8) 4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville | (data[valueIndex++] & 0xFF); 4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int[] colorIndexArray = getCLUT(data, clutOffset, colorNumber); 4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (true == transparency) { 4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville colorIndexArray[colorNumber - 1] = Color.TRANSPARENT; 4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int[] resultArray = null; 4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (0 == (8 % bits)) { 4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville resultArray = mapTo2OrderBitColor(data, valueIndex, 4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (width * height), colorIndexArray, bits); 4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville resultArray = mapToNon2OrderBitColor(data, valueIndex, 4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (width * height), colorIndexArray, bits); 4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Bitmap.createBitmap(resultArray, width, height, 4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Bitmap.Config.RGB_565); 4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static int[] mapTo2OrderBitColor(byte[] data, int valueIndex, 4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int length, int[] colorArray, int bits) { 4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (0 != (8 % bits)) { 46299c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.e(LOG_TAG, "not event number of color"); 4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mapToNon2OrderBitColor(data, valueIndex, length, colorArray, 4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bits); 4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int mask = 0x01; 4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (bits) { 4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 1: 4700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mask = 0x01; 4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 2: 4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mask = 0x03; 4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 4: 4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mask = 0x0F; 4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 8: 4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mask = 0xFF; 4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 4810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int[] resultArray = new int[length]; 4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int resultIndex = 0; 4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int run = 8 / bits; 4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville while (resultIndex < length) { 4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte tempByte = data[valueIndex++]; 4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int runIndex = 0; runIndex < run; ++runIndex) { 4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int offset = run - runIndex - 1; 4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville resultArray[resultIndex++] = colorArray[(tempByte >> (offset * bits)) 4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville & mask]; 4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return resultArray; 4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static int[] mapToNon2OrderBitColor(byte[] data, int valueIndex, 4980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int length, int[] colorArray, int bits) { 4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (0 == (8 % bits)) { 50099c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.e(LOG_TAG, "not odd number of color"); 5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mapTo2OrderBitColor(data, valueIndex, length, colorArray, 5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bits); 5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int[] resultArray = new int[length]; 5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // TODO fix me: 5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return resultArray; 5080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static int[] getCLUT(byte[] rawData, int offset, int number) { 5110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (null == rawData) { 5120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return null; 5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int[] result = new int[number]; 5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int endIndex = offset + (number * 3); // 1 color use 3 bytes 5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int valueIndex = offset; 5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int colorIndex = 0; 5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int alpha = 0xff << 24; 5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville do { 5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result[colorIndex++] = alpha 5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville | ((rawData[valueIndex++] & 0xFF) << 16) 5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville | ((rawData[valueIndex++] & 0xFF) << 8) 5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville | ((rawData[valueIndex++] & 0xFF)); 5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } while (valueIndex < endIndex); 5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return result; 5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 529