This commit was generated by cvs2svn to compensate for changes in r164,
[gnokii.git] / common / gsm-bitmaps.c
1 /*
2
3   G N O K I I
4
5   A Linux/Unix toolset and driver for Nokia mobile phones.
6
7   Copyright (C) 1999, 2000 Hugh Blemings & Pavel Janík ml. 
8
9   Released under the terms of the GNU GPL, see file COPYING for more details.
10         
11   Functions for common bitmap operations.
12  
13   Last modified: Sat 18 Nov 2000 by Chris Kemp
14
15 */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <ctype.h>
21 #include <sys/stat.h>
22
23 #include "gsm-common.h"
24 #include "gsm-bitmaps.h"
25 #include "gsm-api.h"
26
27 /* A few useful functions for bitmaps */
28
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));
32
33   /* Testing only! */
34   if (bmp->type == GSM_PictureImage) bmp->bitmap[9*y + (x/8)] |= 1 << (7-(x%8));
35 }
36
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)));
40
41   /* Testing only ! */
42   if (bmp->type == GSM_PictureImage) bmp->bitmap[9*y + (x/8)] &= 255 - (1 << (7-(x%8)));
43 }
44
45 bool GSM_IsPointBitmap(GSM_Bitmap *bmp, int x, int y) {
46   int i=0;
47
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)));
50   /* Testing only ! */
51   if (bmp->type == GSM_PictureImage) i=(bmp->bitmap[9*y + (x/8)] & 1<<(7-(x%8)));
52  
53   if (i) return true; else return false;
54 }
55
56 void GSM_ClearBitmap(GSM_Bitmap *bmp)
57 {
58   int i;
59
60   for (i=0;i<bmp->size;i++) bmp->bitmap[i]=0;
61 }
62
63
64 void GSM_ResizeBitmap(GSM_Bitmap *bitmap, GSM_Bitmap_Types target, GSM_Information *info)
65 {
66   GSM_Bitmap backup;
67   int x,y,copywidth,copyheight;
68
69   /* Copy into the backup */
70   memcpy(&backup,bitmap,sizeof(GSM_Bitmap));
71       
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;
76   }
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);
82   }
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);
88   }
89   if (target==GSM_PictureImage) {
90     bitmap->width=72;
91     bitmap->height=28;
92     bitmap->size=bitmap->width*bitmap->height/8;
93   }
94   bitmap->type=target;
95
96   if (backup.width>bitmap->width) {
97     copywidth=bitmap->width;
98 #ifdef DEBUG
99     fprintf(stdout,_("We lost some part of image - it's cut (width from %i to %i) !\n"),backup.width,bitmap->width);
100 #endif /* DEBUG */
101   } else copywidth=backup.width;
102
103   if (backup.height>bitmap->height) {
104     copyheight=bitmap->height;
105 #ifdef DEBUG
106     fprintf(stdout,_("We lost some part of image - it's cut (height from %i to %i) !\n"),backup.height,bitmap->height);
107 #endif /* DEBUG */
108   } else copyheight=backup.height;
109   
110
111   GSM_ClearBitmap(bitmap);
112   
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);
116   }
117 }
118
119 void GSM_PrintBitmap(GSM_Bitmap *bitmap)
120 {
121   int x,y;
122
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, _("#"));
127       } else {
128         fprintf(stdout, _(" "));
129       }
130     }
131     fprintf(stdout, _("\n"));
132   }
133 }
134
135
136 GSM_Error GSM_ReadSMSBitmap(GSM_SMSMessage *message, GSM_Bitmap *bitmap)
137 {
138   int offset = 1;
139
140   switch (SMS_DetectUDH(message)) {
141   case GSM_OpLogo:
142     if (message->MessageTextLength!=133+7) return GE_UNKNOWN;
143     
144     bitmap->type = GSM_OperatorLogo;
145
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;
153
154     offset = 4;
155     break;
156
157   case GSM_CallerIDLogo:
158     if (message->MessageTextLength!=130+7) return GE_UNKNOWN;
159     bitmap->type=GSM_CallerLogo;
160     break;
161   default: /* error */
162     return GE_UNKNOWN;
163     break;
164   }
165   bitmap->width = message->MessageText[offset];
166   bitmap->height = message->MessageText[offset + 1];
167   
168   if (bitmap->width!=72 || bitmap->height!=14) return GE_INVALIDIMAGESIZE;
169   
170   bitmap->size = (bitmap->width * bitmap->height) / 8;
171   memcpy(bitmap->bitmap, message->MessageText + offset + 3, bitmap->size);
172
173 #ifdef DEBUG
174   fprintf(stdout, _("Bitmap from SMS: width %i, height %i\n"),bitmap->width,bitmap->height);
175 #endif
176
177   return GE_NONE;
178 }
179
180
181 /* Returns message length */
182
183 int GSM_SaveSMSBitmap(GSM_SMSMessage *message, GSM_Bitmap *bitmap)
184 {
185   int current=0;
186   
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 */
193                                 0x00};
194
195   char Data[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
196   
197   /* Default settings for SMS message:
198       - no delivery report
199       - Class Message 1
200       - no compression
201       - 8 bit data
202       - SMSC no. 1
203       - validity 3 days
204       - set UserDataHeaderIndicator
205   */
206
207   message->Type = GST_MO;
208   message->Class = 1;
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;
214
215   switch (bitmap->type) {
216     case GSM_OperatorLogo:
217       message->UDHPresent = true;
218       UserDataHeader[4] = 0x82; /* NBS port 0x1582 */
219       
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);
224
225       break;
226     case GSM_CallerLogo:
227       message->UDHPresent = true;
228       UserDataHeader[4] = 0x83; /* NBS port 0x1583 */
229       break;
230     default: /* error */
231       break;
232   }
233         
234   /* Set the logo size */
235   current++;
236   Data[current++] = bitmap->width;
237   Data[current++] = bitmap->height;
238
239   Data[current++] = 0x01;
240
241   memcpy(message->UDH,UserDataHeader,7);
242   memcpy(message->MessageText,Data,current);
243   memcpy(message->MessageText+current,bitmap->bitmap,bitmap->size);
244
245   return current;
246 }