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