5 A Linux/Unix toolset and driver for Nokia mobile phones.
7 Released under the terms of the GNU GPL, see file COPYING for more details.
9 Functions for manipulating bitmaps
19 #include "gsm-common.h"
20 #include "gsm-bitmaps.h"
22 #include "gsm-coding.h"
23 #include "gsm-networks.h"
25 void GSM_SetPointBitmap(GSM_Bitmap *bmp, int x, int y)
28 if (bmp->type == GSM_StartupLogo || bmp->type == GSM_6210StartupLogo || bmp->type == GSM_7110StartupLogo)
29 bmp->bitmap[((y/8)*bmp->width)+x] |= 1 << (y%8);
30 if (bmp->type == GSM_OperatorLogo || bmp->type == GSM_7110OperatorLogo || bmp->type == GSM_CallerLogo) {
31 pixel=bmp->width*y + x;
32 bmp->bitmap[pixel/8] |= 1 << (7-(pixel%8));
34 if (bmp->type == GSM_PictureImage) bmp->bitmap[9*y + (x/8)] |= 1 << (7-(x%8));
37 void GSM_ClearPointBitmap(GSM_Bitmap *bmp, int x, int y)
40 if (bmp->type == GSM_StartupLogo || bmp->type == GSM_6210StartupLogo || bmp->type == GSM_7110StartupLogo)
41 bmp->bitmap[((y/8)*bmp->width)+x] &= 255 - (1 << (y%8));
42 if (bmp->type == GSM_OperatorLogo || bmp->type == GSM_7110OperatorLogo || bmp->type == GSM_CallerLogo) {
43 pixel=bmp->width*y + x;
44 bmp->bitmap[pixel/8] &= ~(1 << (7-(pixel%8)));
46 if (bmp->type == GSM_PictureImage) bmp->bitmap[9*y + (x/8)] &= 255 - (1 << (7-(x%8)));
49 bool GSM_IsPointBitmap(GSM_Bitmap *bmp, int x, int y)
54 if (bmp->type == GSM_StartupLogo || bmp->type == GSM_6210StartupLogo || bmp->type == GSM_7110StartupLogo)
55 i=(bmp->bitmap[((y/8)*bmp->width) + x] & 1<<((y%8)));
56 if (bmp->type == GSM_OperatorLogo || bmp->type == GSM_7110OperatorLogo || bmp->type == GSM_CallerLogo) {
57 pixel=bmp->width*y + x;
58 i=(bmp->bitmap[pixel/8] & 1<<(7-(pixel%8)));
60 if (bmp->type == GSM_PictureImage) i=(bmp->bitmap[9*y + (x/8)] & 1<<(7-(x%8)));
62 if (i) return true; else return false;
65 void GSM_ClearBitmap(GSM_Bitmap *bmp)
68 for (i=0;i<bmp->size;i++) bmp->bitmap[i]=0;
71 int GSM_GetBitmapSize(GSM_Bitmap *bitmap)
73 switch (bitmap->type) {
74 case GSM_StartupLogo : /*size 84*48*/
75 case GSM_OperatorLogo : /*size 72*14*/
76 case GSM_CallerLogo : /*size 72*14*/
77 case GSM_PictureImage : /*size 72*28*/
78 return bitmap->height*bitmap->width/8;
80 case GSM_7110OperatorLogo: /*size 78*21*/
81 return (bitmap->width*bitmap->height + 7)/8;
83 case GSM_7110StartupLogo: /*size 96*65*/
84 case GSM_6210StartupLogo: /*size 96*60*/
85 return (bitmap->height+7)/8*bitmap->width;
92 GSM_Error GSM_ReadBitmap(GSM_SMSMessage *message, GSM_Bitmap *bitmap)
95 unsigned char buffer[20];
97 switch (message->UDHType) {
99 EncodeUDHHeader(buffer, GSM_OperatorLogo);
100 if (message->Length!=133) return GE_UNKNOWN;
102 bitmap->type = GSM_OperatorLogo;
104 DecodeNetworkCode(message->MessageText, bitmap->netcode);
109 case GSM_CallerIDLogo:
110 EncodeUDHHeader(buffer, GSM_CallerLogo);
111 if (message->Length!=130) return GE_UNKNOWN;
113 bitmap->type=GSM_CallerLogo;
120 bitmap->width = message->MessageText[offset];
121 bitmap->height = message->MessageText[offset + 1];
123 if (bitmap->width!=72 || bitmap->height!=14) return GE_INVALIDIMAGESIZE;
125 bitmap->size = GSM_GetBitmapSize(bitmap);
126 memcpy(bitmap->bitmap, message->MessageText + offset + 3, bitmap->size);
129 fprintf(stdout, _("Bitmap from SMS: width %i, height %i\n"),bitmap->width,bitmap->height);
135 void GSM_ResizeBitmap(GSM_Bitmap *bitmap, GSM_Bitmap_Types target)
138 int x,y,width,height;
142 if (target==GSM_StartupLogo) {
146 if (target==GSM_7110StartupLogo) {
150 if (target==GSM_6210StartupLogo) {
154 if (target==GSM_OperatorLogo || target==GSM_CallerLogo) {
158 if (target==GSM_PictureImage ) {
162 if (target==GSM_7110OperatorLogo) {
167 bitmap->size=GSM_GetBitmapSize(bitmap);
170 if (bitmap->width<width) {
173 fprintf(stdout,_("We lost some part of image - it's cut (width from %i to %i) !\n"),backup.width,width);
177 height=backup.height;
178 if (bitmap->height<height) {
179 height=bitmap->height;
181 fprintf(stdout,_("We lost some part of image - it's cut (height from %i to %i) !\n"),backup.height,height);
185 GSM_ClearBitmap(bitmap);
187 for (y=0;y<height;y++) {
188 for (x=0;x<width;x++)
189 if (GSM_IsPointBitmap(&backup,x,y)) GSM_SetPointBitmap(bitmap,x,y);
192 //GSM_PrintBitmap(&backup);
193 //GSM_PrintBitmap(bitmap);
196 void GSM_PrintBitmap(GSM_Bitmap *bitmap)
200 for (y=0;y<bitmap->height;y++) {
201 for (x=0;x<bitmap->width;x++) {
202 if (GSM_IsPointBitmap(bitmap,x,y)) {
203 fprintf(stdout, _("#"));
205 fprintf(stdout, _(" "));
208 fprintf(stdout, _("\n"));
212 int GSM_SaveBitmapToSMS(GSM_MultiSMSMessage *SMS, GSM_Bitmap *bitmap,
213 bool ScreenSaver, bool UnicodeText)
215 char MessageBuffer[GSM_MAX_SMS_8_BIT_LENGTH*4];
217 GSM_UDH UDHType=GSM_NoUDH;
219 switch (bitmap->type) {
220 case GSM_OperatorLogo:
223 EncodeNetworkCode(MessageBuffer, bitmap->netcode);
226 /* Set the logo size */
227 MessageBuffer[MessageLength++] = 0x00;
228 MessageBuffer[MessageLength++] = bitmap->width;
229 MessageBuffer[MessageLength++] = bitmap->height;
230 MessageBuffer[MessageLength++] = 0x01;
232 memcpy(MessageBuffer+MessageLength,bitmap->bitmap,bitmap->size);
233 MessageLength=MessageLength+bitmap->size;
237 UDHType=GSM_CallerIDLogo;
239 /* Set the logo size */
240 MessageBuffer[MessageLength++] = 0x00;
241 MessageBuffer[MessageLength++] = bitmap->width;
242 MessageBuffer[MessageLength++] = bitmap->height;
243 MessageBuffer[MessageLength++] = 0x01;
245 memcpy(MessageBuffer+MessageLength,bitmap->bitmap,bitmap->size);
246 MessageLength=MessageLength+bitmap->size;
249 case GSM_PictureImage:
250 UDHType=GSM_ProfileUDH;
252 MessageBuffer[MessageLength++]=0x30; //SM version. Here 3.0
255 MessageBuffer[MessageLength++]=SM30_OTA; //ID for OTA bitmap
257 MessageBuffer[MessageLength++]=SM30_SCREENSAVER; //ID for screen saver
259 /* Length for picture part */
260 MessageBuffer[MessageLength++]=0x01; //length hi
261 MessageBuffer[MessageLength++]=0x00; //length lo
263 /* Set the logo size */
264 MessageBuffer[MessageLength++] = 0x00;
265 MessageBuffer[MessageLength++] = bitmap->width;
266 MessageBuffer[MessageLength++] = bitmap->height;
267 MessageBuffer[MessageLength++] = 0x01;
269 memcpy(MessageBuffer+MessageLength,bitmap->bitmap,bitmap->size);
270 MessageLength=MessageLength+bitmap->size;
272 if (strlen(bitmap->text)!=0) {
274 MessageBuffer[MessageLength++]=SM30_UNICODETEXT; //ID for Unicode text
276 /* Length for text part */
277 MessageBuffer[MessageLength++]=0x00; //length of text1
278 MessageBuffer[MessageLength++]=strlen(bitmap->text)*2;//length of text2
280 EncodeUnicode (MessageBuffer+MessageLength,bitmap->text,strlen(bitmap->text));
281 MessageLength=MessageLength+2*strlen(bitmap->text);
283 MessageBuffer[MessageLength++]=SM30_ISOTEXT; //ID for ISO-8859-1 text
285 /* Length for text part */
286 MessageBuffer[MessageLength++]=0x00; //length of text1
287 MessageBuffer[MessageLength++]=strlen(bitmap->text); //length of text2
289 memcpy(MessageBuffer+MessageLength,bitmap->text,strlen(bitmap->text));
290 MessageLength=MessageLength+strlen(bitmap->text);
299 GSM_MakeMultiPartSMS2(SMS,MessageBuffer,MessageLength, UDHType, GSM_Coding_Default);