5 A Linux/Unix toolset and driver for Nokia mobile phones.
7 Copyright (C) 1999, 2000 Hugh Blemings & Pavel JanÃk ml.
9 Released under the terms of the GNU GPL, see file COPYING for more details.
11 Functions for common bitmap operations.
13 Last modified: Sat 18 Nov 2000 by Chris Kemp
23 #include "gsm-common.h"
24 #include "gsm-bitmaps.h"
27 /* A few useful functions for bitmaps */
29 void GSM_SetPointBitmap(GSM_Bitmap *bmp, int x, int y) {
30 if (bmp->type == GSM_StartupLogo) bmp->bitmap[((y/8)*bmp->width)+x] |= 1 << (y%8);
31 if (bmp->type == GSM_OperatorLogo || bmp->type == GSM_CallerLogo) bmp->bitmap[(y*bmp->width+x)/8] |= 1 << (7-((y*bmp->width+x)%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) {
38 if (bmp->type == GSM_StartupLogo) bmp->bitmap[((y/8)*bmp->width)+x] &= 255 - (1 << (y%8));
39 if (bmp->type == GSM_OperatorLogo || bmp->type == GSM_CallerLogo) bmp->bitmap[(y*bmp->width+x)/8] &= 255 - (1 << (7-((y*bmp->width+x)%8)));
42 if (bmp->type == GSM_PictureImage) bmp->bitmap[9*y + (x/8)] &= 255 - (1 << (7-(x%8)));
45 bool GSM_IsPointBitmap(GSM_Bitmap *bmp, int x, int y) {
48 if (bmp->type == GSM_StartupLogo) i=(bmp->bitmap[((y/8)*bmp->width) + x] & 1<<((y%8)));
49 if (bmp->type == GSM_OperatorLogo || bmp->type == GSM_CallerLogo) i=(bmp->bitmap[(y*bmp->width+x)/8] & 1 << (7-((y*bmp->width+x)%8)));
51 if (bmp->type == GSM_PictureImage) i=(bmp->bitmap[9*y + (x/8)] & 1<<(7-(x%8)));
53 if (i) return true; else return false;
56 void GSM_ClearBitmap(GSM_Bitmap *bmp)
60 for (i=0;i<bmp->size;i++) bmp->bitmap[i]=0;
64 void GSM_ResizeBitmap(GSM_Bitmap *bitmap, GSM_Bitmap_Types target, GSM_Information *info)
67 int x,y,copywidth,copyheight;
69 /* Copy into the backup */
70 memcpy(&backup,bitmap,sizeof(GSM_Bitmap));
72 if (target==GSM_StartupLogo) {
73 bitmap->width=info->StartupLogoW;
74 bitmap->height=info->StartupLogoH;
75 bitmap->size=((bitmap->height/8)+(bitmap->height%8>0))*bitmap->width;
77 if (target==GSM_OperatorLogo) {
78 bitmap->width=info->OpLogoW;
79 bitmap->height=info->OpLogoH;
80 x=bitmap->width*bitmap->height;
81 bitmap->size=(x/8)+(x%8>0);
83 if (target==GSM_CallerLogo) {
84 bitmap->width=info->CallerLogoW;
85 bitmap->height=info->CallerLogoH;
86 x=bitmap->width*bitmap->height;
87 bitmap->size=(x/8)+(x%8>0);
89 if (target==GSM_PictureImage) {
92 bitmap->size=bitmap->width*bitmap->height/8;
96 if (backup.width>bitmap->width) {
97 copywidth=bitmap->width;
99 fprintf(stdout,_("We lost some part of image - it's cut (width from %i to %i) !\n"),backup.width,bitmap->width);
101 } else copywidth=backup.width;
103 if (backup.height>bitmap->height) {
104 copyheight=bitmap->height;
106 fprintf(stdout,_("We lost some part of image - it's cut (height from %i to %i) !\n"),backup.height,bitmap->height);
108 } else copyheight=backup.height;
111 GSM_ClearBitmap(bitmap);
113 for (y=0;y<copyheight;y++) {
114 for (x=0;x<copywidth;x++)
115 if (GSM_IsPointBitmap(&backup,x,y)) GSM_SetPointBitmap(bitmap,x,y);
119 void GSM_PrintBitmap(GSM_Bitmap *bitmap)
123 for (y=0;y<bitmap->height;y++) {
124 for (x=0;x<bitmap->width;x++) {
125 if (GSM_IsPointBitmap(bitmap,x,y)) {
126 fprintf(stdout, _("#"));
128 fprintf(stdout, _(" "));
131 fprintf(stdout, _("\n"));
136 GSM_Error GSM_ReadSMSBitmap(GSM_SMSMessage *message, GSM_Bitmap *bitmap)
140 switch (SMS_DetectUDH(message)) {
142 if (message->MessageTextLength!=133+7) return GE_UNKNOWN;
144 bitmap->type = GSM_OperatorLogo;
146 bitmap->netcode[0] = '0' + (message->MessageText[0] & 0x0f);
147 bitmap->netcode[1] = '0' + (message->MessageText[0] >> 4);
148 bitmap->netcode[2] = '0' + (message->MessageText[1] & 0x0f);
149 bitmap->netcode[3] = ' ';
150 bitmap->netcode[4] = '0' + (message->MessageText[2] & 0x0f);
151 bitmap->netcode[5] = '0' + (message->MessageText[2] >> 4);
152 bitmap->netcode[6] = 0;
157 case GSM_CallerIDLogo:
158 if (message->MessageTextLength!=130+7) return GE_UNKNOWN;
159 bitmap->type=GSM_CallerLogo;
165 bitmap->width = message->MessageText[offset];
166 bitmap->height = message->MessageText[offset + 1];
168 if (bitmap->width!=72 || bitmap->height!=14) return GE_INVALIDIMAGESIZE;
170 bitmap->size = (bitmap->width * bitmap->height) / 8;
171 memcpy(bitmap->bitmap, message->MessageText + offset + 3, bitmap->size);
174 fprintf(stdout, _("Bitmap from SMS: width %i, height %i\n"),bitmap->width,bitmap->height);
181 /* Returns message length */
183 int GSM_SaveSMSBitmap(GSM_SMSMessage *message, GSM_Bitmap *bitmap)
187 char UserDataHeader[7] = { 0x06, /* UDH Length */
188 0x05, /* IEI: application port addressing scheme, 16 bit address */
189 0x04, /* IEI length */
190 0x15, /* destination address: high byte */
191 0x00, /* destination address: low byte */
192 0x00, /* originator address */
195 char Data[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
197 /* Default settings for SMS message:
204 - set UserDataHeaderIndicator
207 message->Type = GST_MO;
209 message->Compression = false;
210 message->EightBit = true;
211 message->MessageCenter.No = 1;
212 message->Validity = 4320; /* 4320 minutes == 72 hours */
213 message->ReplyViaSameSMSC = false;
215 switch (bitmap->type) {
216 case GSM_OperatorLogo:
217 message->UDHPresent = true;
218 UserDataHeader[4] = 0x82; /* NBS port 0x1582 */
220 /* Set the network code */
221 Data[current++] = ((bitmap->netcode[1] & 0x0f) << 4) | (bitmap->netcode[0] & 0xf);
222 Data[current++] = 0xf0 | (bitmap->netcode[2] & 0x0f);
223 Data[current++] = ((bitmap->netcode[5] & 0x0f) << 4) | (bitmap->netcode[4] & 0xf);
227 message->UDHPresent = true;
228 UserDataHeader[4] = 0x83; /* NBS port 0x1583 */
234 /* Set the logo size */
236 Data[current++] = bitmap->width;
237 Data[current++] = bitmap->height;
239 Data[current++] = 0x01;
241 memcpy(message->UDH,UserDataHeader,7);
242 memcpy(message->MessageText,Data,current);
243 memcpy(message->MessageText+current,bitmap->bitmap,bitmap->size);