1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.marre.sms.nokia;
24
25 import java.awt.image.BufferedImage;
26 import java.awt.image.Raster;
27
28 /***
29 * Nokia OTA Bitmap format
30 * <p>
31 * This class can currently only handle non-animated B/W OTA Bitmaps.
32 * <p>
33 * Format is:
34 *
35 * <pre>
36 * Octet 1 -> 0 : Not sure what this is
37 * Octet 2 -> <width> : Width of image
38 * Octet 3 -> <height> : Height of image
39 * Octet 4 -> 1 : Number of colors?? B/W == 1?
40 * Octet 5-n -> <imgdata> : Image data 1 bit for each pixel
41 * </pre>
42 *
43 * I have only verified this class with BufferedImages of type TYPE_INT_ARGB
44 *
45 * @author Markus Eriksson
46 */
47 public class OtaBitmap
48 {
49 private int myWidth;
50 private int myHeight;
51
52 private byte[] myOtaImgData;
53
54 /***
55 * Initialise with a raw Ota Bitmap
56 *
57 * @param otaBitmap
58 */
59 public OtaBitmap(byte[] otaBitmap)
60 {
61 if (otaBitmap != null)
62 {
63
64 int infoField = otaBitmap[0];
65 myWidth = otaBitmap[1];
66 myHeight = otaBitmap[2];
67 int depth = otaBitmap[3];
68
69 int length = otaBitmap.length - 4;
70 myOtaImgData = new byte[length];
71
72 System.arraycopy(otaBitmap, 4, myOtaImgData, 0, length);
73 }
74 }
75
76 /***
77 * Creates an OtaBitmap object from an BufferedImage.
78 * <p>
79 * Every pixel that is not white will be converted to black.
80 *
81 * @param theImg
82 * Image to convert.
83 */
84 public OtaBitmap(BufferedImage theImg)
85 {
86 int bitOffset = 0;
87 int data = 0;
88 int nByte = 0;
89 int nTotalBytes = 0;
90 Raster raster = theImg.getData();
91
92 myWidth = theImg.getWidth();
93 myHeight = theImg.getHeight();
94
95 nTotalBytes = (myWidth * myHeight) / 8;
96 if (((myWidth * myHeight) % 8) > 0)
97 {
98 nTotalBytes++;
99 }
100
101 myOtaImgData = new byte[nTotalBytes];
102
103 for (int y = 0; y < myHeight; y++)
104 {
105 for (int x = 0; x < myWidth; x++)
106 {
107 int color = theImg.getRGB(x, y);
108
109 if (color != 0)
110 {
111 data |= ((1 << (7 - bitOffset)) & 0xff);
112 }
113
114 bitOffset++;
115
116 if (bitOffset >= 8)
117 {
118 myOtaImgData[nByte] = (byte) (data & 0xff);
119
120 bitOffset = 0;
121 data = 0x00;
122 nByte++;
123 }
124 }
125 }
126
127 if (bitOffset > 0)
128 {
129 myOtaImgData[nByte] = (byte) (data & 0xff);
130 }
131 }
132
133 /***
134 * Returns the created image data (not including image header)
135 *
136 * @return Image data
137 */
138 public byte[] getImageData()
139 {
140 return myOtaImgData;
141 }
142
143 /***
144 * Returns the encoded OtaBitmap
145 *
146 * @return An encoded OtaBitmap
147 */
148 public byte[] getBytes()
149 {
150 byte[] otaBitmap = new byte[myOtaImgData.length + 4];
151
152 otaBitmap[0] = 0;
153 otaBitmap[1] = (byte) (myWidth & 0xff);
154 otaBitmap[2] = (byte) (myHeight & 0xff);
155 otaBitmap[3] = 1;
156
157
158 System.arraycopy(myOtaImgData, 0, otaBitmap, 4, myOtaImgData.length);
159
160 return otaBitmap;
161 }
162
163 /***
164 * @return
165 */
166 public int getHeight()
167 {
168 return myHeight;
169 }
170
171 /***
172 * @return
173 */
174 public int getWidth()
175 {
176 return myWidth;
177 }
178
179 /***
180 * @param i
181 */
182 public void setHeight(int i)
183 {
184 myHeight = i;
185 }
186
187 /***
188 * @param i
189 */
190 public void setWidth(int i)
191 {
192 myWidth = i;
193 }
194
195 }