5 #include "../misc/misc.h"
6 #include "../misc/coding/coding.h"
10 void PHONE_GetBitmapWidthHeight(GSM_Phone_Bitmap_Types Type
, int *width
, int *height
)
15 case GSM_EMSSmallPicture
: *width
=8; *height
=8; break;
16 case GSM_EMSMediumPicture
: *width
=16; *height
=16; break;
17 case GSM_EMSBigPicture
: *width
=32; *height
=32; break;
18 case GSM_NokiaOperatorLogo
:
19 case GSM_NokiaCallerLogo
: *width
=72; *height
=14; break;
20 case GSM_NokiaPictureImage
: *width
=72; *height
=28; break;
21 case GSM_Nokia7110OperatorLogo
:
22 case GSM_Nokia6510OperatorLogo
: *width
=78; *height
=21; break;
23 case GSM_NokiaStartupLogo
: *width
=84; *height
=48; break;
24 case GSM_Nokia6210StartupLogo
: *width
=96; *height
=60; break;
25 case GSM_Nokia7110StartupLogo
: *width
=96; *height
=65; break;
26 case GSM_EMSVariablePicture
: break;
30 int PHONE_GetBitmapSize(GSM_Phone_Bitmap_Types Type
, int Width
, int Height
)
34 PHONE_GetBitmapWidthHeight(Type
, &width
, &height
);
35 if (width
== 0 && height
== 0) {
40 case GSM_Nokia6510OperatorLogo
:
42 return (x
/ 8) + (x
% 8 > 0);
43 case GSM_Nokia7110OperatorLogo
:
44 return (width
*height
+ 7)/8;
45 case GSM_NokiaStartupLogo
:
46 case GSM_NokiaOperatorLogo
:
47 case GSM_NokiaCallerLogo
:
48 case GSM_NokiaPictureImage
:
49 case GSM_EMSSmallPicture
:
50 case GSM_EMSMediumPicture
:
51 case GSM_EMSBigPicture
:
52 case GSM_EMSVariablePicture
:
53 return height
*width
/8;
54 case GSM_Nokia7110StartupLogo
:
55 case GSM_Nokia6210StartupLogo
:
56 return (height
+7)/8*width
;
61 static bool PHONE_IsPointBitmap(GSM_Phone_Bitmap_Types Type
, char *buffer
, int x
, int y
, int width
, int height
)
66 case GSM_NokiaStartupLogo
:
67 case GSM_Nokia6210StartupLogo
:
68 case GSM_Nokia7110StartupLogo
:
69 case GSM_Nokia6510OperatorLogo
:
70 i
=(buffer
[((y
/8)*width
) + x
] & 1<<((y
%8)));
72 case GSM_NokiaOperatorLogo
:
73 case GSM_Nokia7110OperatorLogo
:
74 case GSM_NokiaCallerLogo
:
75 case GSM_EMSVariablePicture
:
76 case GSM_EMSSmallPicture
:
77 case GSM_EMSMediumPicture
:
78 case GSM_EMSBigPicture
:
80 i
=(buffer
[pixel
/8] & 1<<(7-(pixel
%8)));
82 case GSM_NokiaPictureImage
:
83 i
=(buffer
[9*y
+ (x
/8)] & 1<<(7-(x
%8)));
86 if (i
) return true; else return false;
89 static void PHONE_SetPointBitmap(GSM_Phone_Bitmap_Types Type
, char *buffer
, int x
, int y
, int width
, int height
)
94 case GSM_NokiaStartupLogo
:
95 case GSM_Nokia6210StartupLogo
:
96 case GSM_Nokia7110StartupLogo
:
97 case GSM_Nokia6510OperatorLogo
:
98 buffer
[((y
/8)*width
)+x
] |= 1 << (y
%8);
100 case GSM_NokiaOperatorLogo
:
101 case GSM_Nokia7110OperatorLogo
:
102 case GSM_NokiaCallerLogo
:
103 case GSM_EMSSmallPicture
:
104 case GSM_EMSMediumPicture
:
105 case GSM_EMSBigPicture
:
106 case GSM_EMSVariablePicture
:
108 buffer
[pixel
/8] |= 1 << (7-(pixel
%8));
110 case GSM_NokiaPictureImage
:
111 buffer
[9*y
+ (x
/8)] |= 1 << (7-(x
%8));
116 void PHONE_DecodeBitmap(GSM_Phone_Bitmap_Types Type
, char *buffer
, GSM_Bitmap
*Bitmap
)
118 int width
, height
, x
,y
;
120 PHONE_GetBitmapWidthHeight(Type
, &width
, &height
);
121 if (Type
!= GSM_Nokia6510OperatorLogo
&& Type
!= GSM_Nokia7110OperatorLogo
&& Type
!= GSM_EMSVariablePicture
) {
122 Bitmap
->Height
= height
;
123 Bitmap
->Width
= width
;
126 case GSM_NokiaOperatorLogo
:
127 case GSM_Nokia7110OperatorLogo
:
128 case GSM_Nokia6510OperatorLogo
: Bitmap
->Type
=GSM_OperatorLogo
; break;
129 case GSM_NokiaCallerLogo
: Bitmap
->Type
=GSM_CallerLogo
; break;
130 case GSM_NokiaStartupLogo
:
131 case GSM_Nokia7110StartupLogo
:
132 case GSM_Nokia6210StartupLogo
: Bitmap
->Type
=GSM_StartupLogo
; break;
133 case GSM_NokiaPictureImage
:
134 case GSM_EMSVariablePicture
:
135 case GSM_EMSSmallPicture
:
136 case GSM_EMSMediumPicture
:
137 case GSM_EMSBigPicture
: Bitmap
->Type
=GSM_PictureImage
; break;
140 GSM_ClearBitmap(Bitmap
);
141 for (x
=0;x
<Bitmap
->Width
;x
++) {
142 for (y
=0;y
<Bitmap
->Height
;y
++) {
143 if (PHONE_IsPointBitmap(Type
, buffer
, x
, y
, Bitmap
->Width
, Bitmap
->Height
)) {
144 GSM_SetPointBitmap(Bitmap
,x
,y
);
150 void PHONE_ClearBitmap(GSM_Phone_Bitmap_Types Type
, char *buffer
, int width
, int height
)
152 memset(buffer
,0,PHONE_GetBitmapSize(Type
,width
,height
));
155 void PHONE_EncodeBitmap(GSM_Phone_Bitmap_Types Type
, char *buffer
, GSM_Bitmap
*Bitmap
)
161 PHONE_GetBitmapWidthHeight(Type
, &width
, &height
);
162 if (width
== 0 && height
== 0) {
163 width
= Bitmap
->Width
;
164 height
= Bitmap
->Height
;
166 GSM_ResizeBitmap(&dest
, Bitmap
, width
, height
);
167 PHONE_ClearBitmap(Type
, buffer
, width
, height
);
169 for (x
=0;x
<width
;x
++) {
170 for (y
=0;y
<height
;y
++) {
171 if (GSM_IsPointBitmap(&dest
,x
,y
)) PHONE_SetPointBitmap(Type
, buffer
, x
, y
, width
, height
);
176 void GSM_GetMaxBitmapWidthHeight(GSM_Bitmap_Types Type
, unsigned char *width
, unsigned char *height
)
179 case GSM_CallerLogo
: *width
=72; *height
=14; break;
180 case GSM_OperatorLogo
: *width
=101;*height
=21; break;
181 case GSM_StartupLogo
: *width
=96; *height
=65; break;
182 case GSM_PictureImage
: *width
=72; *height
=28; break;
187 void GSM_SetPointBitmap(GSM_Bitmap
*bmp
, int x
, int y
)
189 SetBit(bmp
->Bitmap
,y
*bmp
->Width
+x
);
192 void GSM_ClearPointBitmap(GSM_Bitmap
*bmp
, int x
, int y
)
194 ClearBit(bmp
->Bitmap
,y
*bmp
->Width
+x
);
197 bool GSM_IsPointBitmap(GSM_Bitmap
*bmp
, int x
, int y
)
199 if (GetBit(bmp
->Bitmap
,y
*bmp
->Width
+x
)) return true; else return false;
202 void GSM_ClearBitmap(GSM_Bitmap
*bmp
)
204 memset(bmp
->Bitmap
,0,GSM_GetBitmapSize(bmp
));
207 int GSM_GetBitmapSize(GSM_Bitmap
*bmp
)
209 return bmp
->Width
*bmp
->Height
/8+1;
212 void GSM_PrintBitmap(FILE *file
, GSM_Bitmap
*bitmap
)
216 for (y
=0;y
<bitmap
->Height
;y
++) {
217 for (x
=0;x
<bitmap
->Width
;x
++) {
218 if (GSM_IsPointBitmap(bitmap
,x
,y
)) {
228 void GSM_ReverseBitmap(GSM_Bitmap
*Bitmap
)
232 for (x
=0;x
<Bitmap
->Width
;x
++) {
233 for (y
=0;y
<Bitmap
->Height
;y
++) {
234 if (GSM_IsPointBitmap(Bitmap
,x
,y
)) {
235 GSM_ClearPointBitmap(Bitmap
, x
, y
);
237 GSM_SetPointBitmap(Bitmap
, x
, y
);
243 void GSM_ResizeBitmap(GSM_Bitmap
*dest
, GSM_Bitmap
*src
, int width
, int height
)
245 int startx
=0,endx
=0,setx
=0;
246 int starty
=0,endy
=0,sety
=0;
249 if (src
->Width
<=width
) {
252 setx
= (width
-src
->Width
)/2;
254 startx
= (src
->Width
-width
)/2;
255 endx
= startx
+ width
;
258 if (src
->Height
<=height
) {
261 sety
= (height
-src
->Height
)/2;
263 starty
= (src
->Height
-height
)/2;
264 endy
= starty
+ height
;
267 dest
->Height
= height
;
269 GSM_ClearBitmap(dest
);
270 for (x
=startx
;x
<endx
;x
++) {
271 for (y
=starty
;y
<endy
;y
++) {
272 if (GSM_IsPointBitmap(src
,x
,y
))
273 GSM_SetPointBitmap(dest
,setx
+x
-startx
,sety
+y
-starty
);
278 GSM_Error
Bitmap2BMP(unsigned char *buffer
, FILE *file
,GSM_Bitmap
*bitmap
)
280 int x
,y
,pos
,i
,sizeimage
,buffpos
=0;
281 unsigned char buff
[1];
285 unsigned char header
[]={
286 /*1'st header*/ 'B','M', /* BMP file ID */
287 0x00,0x00,0x00,0x00, /* Size of file */
288 0x00,0x00, /* Reserved for future use */
289 0x00,0x00, /* Reserved for future use */
290 62,0x00,0x00,0x00, /* Offset for image data */
292 /*2'nd header*/ 40,0x00,0x00,0x00, /* Length of this part of header */
293 0x00,0x00,0x00,0x00, /* Width of image */
294 0x00,0x00,0x00,0x00, /* Height of image */
295 1,0x00, /* How many planes in target device */
296 1,0x00, /* How many colors in image. 1 means 2^1=2 colors */
297 0x00,0x00,0x00,0x00, /* Type of compression. 0 means no compression */
298 /*Sometimes */ 0x00,0x00,0x00,0x00, /* Size of part with image data */
299 /*ttttttt...*/ 0xE8,0x03,0x00,0x00, /* XPelsPerMeter */
300 /*hhiiiiissss*/ 0xE8,0x03,0x00,0x00, /* YPelsPerMeter */
301 /*part of header*/0x02,0x00,0x00,0x00, /* How many colors from palette is used */
302 /*doesn't exist*/ 0x00,0x00,0x00,0x00, /* How many colors from palette is required to display image. 0 means all */
304 /*Color palette*/ 0x00,0x00,0x00, /* First color in palette in Blue, Green, Red. Here white */
305 0x00, /* Each color in palette is end by 4'th byte */
306 102, 204, 102, /* Second color in palette in Blue, Green, Red. Here green */
307 0x00}; /* Each color in palette is end by 4'th byte */
309 if (file
!=NULL
) isfile
=true;
311 header
[22]=bitmap
->Height
;
312 header
[18]=bitmap
->Width
;
316 /*lines are written from the last to the first*/
317 for (y
=bitmap
->Height
-1;y
>=0;y
--) {
319 for (x
=0;x
<bitmap
->Width
;x
++) {
322 if (x
!=0) sizeimage
++;
324 /*each line is written in multiply of 4 bytes*/
328 /*going to new byte*/
331 /*going to new byte*/
335 /*each line is written in multiply of 4 bytes*/
342 dbgprintf("Data size in BMP file: %i\n",sizeimage
);
343 division
=div(sizeimage
,256);
344 header
[35]=division
.quot
;
345 header
[34]=sizeimage
-(division
.quot
*256);
346 sizeimage
=sizeimage
+sizeof(header
);
347 dbgprintf("Size of BMP file: %i\n",sizeimage
);
348 division
=div(sizeimage
,256);
349 header
[3]=division
.quot
;
350 header
[2]=sizeimage
-(division
.quot
*256);
352 if (isfile
) fwrite(header
,1,sizeof(header
),file
);
354 memcpy(buffer
,header
,sizeof(header
));
355 buffpos
+= sizeof(header
);
359 /*lines are written from the last to the first*/
360 for (y
=bitmap
->Height
-1;y
>=0;y
--) {
362 for (x
=0;x
<bitmap
->Width
;x
++) {
366 if (isfile
) fwrite(buff
, 1, sizeof(buff
), file
);
368 memcpy (buffer
+buffpos
,buff
,1);
373 /*each line is written in multiply of 4 bytes*/
377 if (!GSM_IsPointBitmap(bitmap
,x
,y
)) buff
[0]|=(1<<pos
);
379 /*going to new byte*/
382 /*going to new byte*/
384 if (isfile
) fwrite(buff
, 1, sizeof(buff
), file
);
386 memcpy (buffer
+buffpos
,buff
,1);
390 /*each line is written in multiply of 4 bytes*/
393 if (isfile
) fwrite(buff
, 1, sizeof(buff
), file
);
395 memcpy (buffer
+buffpos
,buff
,1);
405 static GSM_Error
savebmp(FILE *file
, GSM_MultiBitmap
*bitmap
)
409 error
=Bitmap2BMP(NULL
,file
,&bitmap
->Bitmap
[0]);
413 static void PrivSaveNLMWBMP(FILE *file
, GSM_Bitmap
*Bitmap
)
415 unsigned char buffer
[1000];
420 for (y
=0;y
<Bitmap
->Height
;y
++) {
421 for (x
=0;x
<Bitmap
->Width
;x
++) {
422 if (pos2
==7) buffer
[pos
]=0;
423 if (GSM_IsPointBitmap(Bitmap
,x
,y
)) buffer
[pos
]|=(1<<pos2
);
425 /* going to new line */
426 if (pos2
<0) {pos2
=7;pos
++;}
428 /* for startup logos - new line with new byte */
429 if (pos2
!=7) {pos2
=7;pos
++;}
432 division
=div(Bitmap
->Width
,8);
433 /* For startup logos */
434 if (division
.rem
!=0) division
.quot
++;
436 fwrite(buffer
,1,(division
.quot
*Bitmap
->Height
),file
);
439 static GSM_Error
savenlm(FILE *file
, GSM_MultiBitmap
*bitmap
)
443 'N','L','M',' ', /* Nokia Logo Manager file ID. */
445 0x00, /* 0x00 (OP), 0x01 (CLI), 0x02 (Startup), 0x03 (Picture)*/
446 0x00, /* Number of images inside file - 1. 0x01==2 images, 0x03==4 images, etc. */
451 switch (bitmap
->Bitmap
[0].Type
) {
452 case GSM_OperatorLogo
: header
[5]=0x00; break;
453 case GSM_CallerLogo
: header
[5]=0x01; break;
454 case GSM_StartupLogo
: header
[5]=0x02; break;
455 case GSM_PictureImage
: header
[5]=0x03; break;
456 default : return GE_UNKNOWN
;
458 header
[6] = bitmap
->Number
- 1;
459 header
[7] = bitmap
->Bitmap
[0].Width
;
460 header
[8] = bitmap
->Bitmap
[0].Height
;
461 fwrite(header
,1,sizeof(header
),file
);
463 for (i
=0;i
<bitmap
->Number
;i
++) {
464 PrivSaveNLMWBMP(file
, &bitmap
->Bitmap
[i
]);
470 static void PrivSaveNGGNOL(FILE *file
, GSM_MultiBitmap
*bitmap
)
472 char buffer
[GSM_BITMAP_SIZE
];
475 for (y
=0;y
<bitmap
->Bitmap
[0].Height
;y
++) {
476 for (x
=0;x
<bitmap
->Bitmap
[0].Width
;x
++) {
477 if (GSM_IsPointBitmap(&bitmap
->Bitmap
[0],x
,y
)) {
478 buffer
[current
++] = '1';
480 buffer
[current
++] = '0';
484 fwrite(buffer
,1,current
,file
);
487 static GSM_Error
savengg(FILE *file
, GSM_MultiBitmap
*bitmap
)
490 'N','G','G',0x00,0x01,0x00,
491 0x00,0x00, /* Width */
492 0x00,0x00, /* Height */
494 0x00, /* Unknown.Can't be checksum - for */
495 /* the same logo files can be different */
498 header
[6] = bitmap
->Bitmap
[0].Width
;
499 header
[8] = bitmap
->Bitmap
[0].Height
;
500 fwrite(header
,1,sizeof(header
),file
);
502 PrivSaveNGGNOL(file
,bitmap
);
507 static GSM_Error
savenol(FILE *file
, GSM_MultiBitmap
*bitmap
)
511 'N','O','L',0x00,0x01,0x00,
514 0x00,0x00, /* Width */
515 0x00,0x00, /* Height */
517 0x00, /* Unknown.Can't be checksum - for */
518 /* the same logo files can be different */
521 if (bitmap
->Bitmap
[0].Type
== GSM_OperatorLogo
) sscanf(bitmap
->Bitmap
[0].NetworkCode
, "%d %d", &country
, &net
);
523 header
[6] = country
%256;
524 header
[7] = country
/256;
527 header
[10] = bitmap
->Bitmap
[0].Width
;
528 header
[12] = bitmap
->Bitmap
[0].Height
;
529 fwrite(header
,1,sizeof(header
),file
);
531 PrivSaveNGGNOL(file
,bitmap
);
536 static GSM_Error
savexpm(FILE *file
, GSM_MultiBitmap
*bitmap
)
540 fprintf(file
,"/* XPM */\n");
541 fprintf(file
,"static char * ala_xpm[] = {\n");
542 fprintf(file
,"\"%i %i 2 1\",\n",bitmap
->Bitmap
[0].Width
,bitmap
->Bitmap
[0].Height
);
543 fprintf(file
,"\". s c m #000000 g4 #000000 g #000000 c #000000\",\n");
544 fprintf(file
,"\"# s c m #ffffff g4 #ffffff g #ffffff c #ffffff\",\n");
546 for (y
=0;y
<bitmap
->Bitmap
[0].Height
;y
++) {
548 for (x
=0;x
<bitmap
->Bitmap
[0].Width
;x
++)
549 if (GSM_IsPointBitmap(&bitmap
->Bitmap
[0],x
,y
))
554 if (y
==bitmap
->Bitmap
[0].Height
-1)
555 fprintf(file
,"};\n");
563 static GSM_Error
savensl(FILE *file
, GSM_MultiBitmap
*bitmap
)
565 char buffer
[GSM_BITMAP_SIZE
];
566 unsigned char header
[]={
567 'F','O','R','M', 0x01,0xFE, /* File ID block, size 1*256+0xFE=510*/
568 'N','S','L','D', 0x01,0xF8}; /* Startup Logo block, size 1*256+0xF8=504*/
570 fwrite(header
,1,sizeof(header
),file
);
571 PHONE_EncodeBitmap(GSM_NokiaStartupLogo
, buffer
, &bitmap
->Bitmap
[0]);
572 fwrite(buffer
,1,PHONE_GetBitmapSize(GSM_NokiaStartupLogo
,0,0),file
);
577 static GSM_Error
savewbmp(FILE *file
, GSM_MultiBitmap
*bitmap
)
579 unsigned char buffer
[4];
583 buffer
[2] = bitmap
->Bitmap
[0].Width
;
584 buffer
[3] = bitmap
->Bitmap
[0].Height
;
585 fwrite(buffer
,1,4,file
);
587 PrivSaveNLMWBMP(file
, &bitmap
->Bitmap
[0]);
592 GSM_Error
GSM_SaveBitmapFile(char *FileName
, GSM_MultiBitmap
*bitmap
)
595 GSM_Error error
=GE_NONE
;
597 file
= fopen(FileName
, "wb");
598 if (file
== NULL
) return(GE_CANTOPENFILE
);
600 /* Attempt to identify filetype */
601 if (strstr(FileName
,".nlm")) {
602 error
=savenlm(file
,bitmap
);
603 } else if (strstr(FileName
,".ngg")) {
604 error
=savengg(file
,bitmap
);
605 } else if (strstr(FileName
,".nol")) {
606 error
=savenol(file
,bitmap
);
607 } else if (strstr(FileName
,".xpm")) {
608 error
=savexpm(file
,bitmap
);
609 } else if (strstr(FileName
,".nsl")) {
610 error
=savensl(file
,bitmap
);
611 } else if (strstr(FileName
,".wbmp")) {
612 error
=savewbmp(file
,bitmap
);
614 error
=savebmp(file
,bitmap
);
621 GSM_Error
BMP2Bitmap(unsigned char *buffer
, FILE *file
,GSM_Bitmap
*bitmap
)
623 bool first_white
,isfile
=false;
624 unsigned char buff
[34];
625 int w
,h
,pos
,y
,x
,i
,buffpos
=0;
630 if (bitmap
->Type
== GSM_None
) bitmap
->Type
= GSM_StartupLogo
;
631 if (file
!=NULL
) isfile
=true;
633 fread(buff
, 1, 34, file
);
635 memcpy(buff
,buffer
,34);
638 /* height and width of image in the file */
639 h
=buff
[22]+256*buff
[21];
640 w
=buff
[18]+256*buff
[17];
641 dbgprintf("Image Size in BMP file: %dx%d\n",w
,h
);
643 GSM_GetMaxBitmapWidthHeight(bitmap
->Type
, &bitmap
->Width
, &bitmap
->Height
);
644 if (h
<bitmap
->Height
) bitmap
->Height
=h
;
645 if (w
<bitmap
->Width
) bitmap
->Width
=w
;
646 dbgprintf("Height %i %i, width %i %i\n",h
,bitmap
->Height
,w
,bitmap
->Width
);
648 GSM_ClearBitmap(bitmap
);
651 dbgprintf("Number of colors in BMP file: ");
653 case 1 : dbgprintf("2 (supported)\n"); break;
654 case 4 : dbgprintf("16 (NOT SUPPORTED)\n"); break;
655 case 8 : dbgprintf("256 (NOT SUPPORTED)\n"); break;
656 case 24 : dbgprintf("True Color (NOT SUPPORTED)\n"); break;
657 default : dbgprintf("unknown\n"); break;
661 dbgprintf("Wrong number of colors\n");
662 return GE_FILENOTSUPPORTED
;
666 dbgprintf("Compression in BMP file: ");
668 case 0 :dbgprintf("no compression (supported)\n"); break;
669 case 1 :dbgprintf("RLE8 (NOT SUPPORTED)\n"); break;
670 case 2 :dbgprintf("RLE4 (NOT SUPPORTED)\n"); break;
671 default :dbgprintf("unknown\n"); break;
675 dbgprintf("Compression type not supported\n");
676 return GE_FILENOTSUPPORTED
;
679 /* read rest of header (if exists) and color palette */
682 fread(buff
, 1, pos
, file
);
686 memcpy (buff
,buffer
+34,pos
);
690 dbgprintf("First color in BMP file: %i %i %i ",buff
[pos
-8], buff
[pos
-7], buff
[pos
-6]);
691 if (buff
[pos
-8]==0 && buff
[pos
-7]==0 && buff
[pos
-6]==0) dbgprintf("(white)");
692 if (buff
[pos
-8]==0xFF && buff
[pos
-7]==0xFF && buff
[pos
-6]==0xFF) dbgprintf("(black)");
693 if (buff
[pos
-8]==102 && buff
[pos
-7]==204 && buff
[pos
-6]==102) dbgprintf("(green)");
695 dbgprintf("Second color in BMP file: %i %i %i ",buff
[pos
-38], buff
[pos
-37], buff
[pos
-36]);
696 if (buff
[pos
-4]==0 && buff
[pos
-3]==0 && buff
[pos
-2]==0) dbgprintf("(white)");
697 if (buff
[pos
-4]==0xFF && buff
[pos
-3]==0xFF && buff
[pos
-2]==0xFF) dbgprintf("(black)");
701 if (buff
[pos
-8]!=0 || buff
[pos
-7]!=0 || buff
[pos
-6]!=0) first_white
=false;
704 /* lines are written from the last to the first */
705 for (y
=h
-1;y
>=0;y
--) {
i
=1;
706 for (x
=0;x
<w
;x
++) {
/* new byte ! */
707 if (pos
==7) {
if (isfile
) {
708 fread(buff
, 1, 1, file
);
710 memcpy (buff
,buffer
+buffpos
,1);
717 /* each line is written in multiply of 4 bytes */
720 /* we have top left corner ! */
721 if (x
<=bitmap
->Width
&& y
<=bitmap
->Height
) {
if (first_white
) {
722 if ((buff
[0]&(1<<pos
))<=0) GSM_SetPointBitmap(bitmap
,x
,y
);
724 if ((buff
[0]&(1<<pos
))>0) GSM_SetPointBitmap(bitmap
,x
,y
);
728 /* going to new byte */
731 /* going to new byte */
734 /* each line is written in multiply of 4 bytes */
737 fread(buff
, 1, 1, file
);
739 memcpy (buff
,buffer
+buffpos
,1);
750 dbgprintf("Data size in BMP file: %i\n",sizeimage
);
755 static GSM_Error
loadbmp(FILE *file
, GSM_MultiBitmap
*bitmap
)
759 error
=BMP2Bitmap(NULL
,file
,&bitmap
->Bitmap
[0]);
764 static GSM_Error
loadnlm (FILE *file
, GSM_MultiBitmap
*bitmap
)
766 unsigned char buffer
[1000];
767 int pos
,pos2
,x
,y
,h
,w
,i
,number
;
770 fread(buffer
,1,5,file
);
772 fread(buffer
,1,1,file
);
775 dbgprintf("Operator logo\n");
776 if (bitmap
->Bitmap
[0].Type
== GSM_None
) bitmap
->Bitmap
[0].Type
= GSM_OperatorLogo
;
779 dbgprintf("Caller logo\n");
780 if (bitmap
->Bitmap
[0].Type
== GSM_None
) bitmap
->Bitmap
[0].Type
= GSM_CallerLogo
;
783 dbgprintf("Startup logo\n");
784 if (bitmap
->Bitmap
[0].Type
== GSM_None
) bitmap
->Bitmap
[0].Type
= GSM_StartupLogo
;
787 dbgprintf("Picture Image logo\n");
788 if (bitmap
->Bitmap
[0].Type
== GSM_None
) bitmap
->Bitmap
[0].Type
= GSM_PictureImage
;
793 fread(buffer
,1,4,file
);
794 number
= buffer
[0] + 1;
797 for (i
=0;i
<number
;i
++) {
798 bitmap
->Bitmap
[i
].Type
= bitmap
->Bitmap
[0].Type
;
799 GSM_GetMaxBitmapWidthHeight(bitmap
->Bitmap
[i
].Type
, &bitmap
->Bitmap
[i
].Width
, &bitmap
->Bitmap
[i
].Height
);
800 if (h
< bitmap
->Bitmap
[i
].Height
) bitmap
->Bitmap
[i
].Height
= h
;
801 if (w
< bitmap
->Bitmap
[i
].Width
) bitmap
->Bitmap
[i
].Width
= w
;
804 /* For startup logos */
805 if (division
.rem
!=0) division
.quot
++;
806 if (fread(buffer
,1,(division
.quot
*h
),file
)!=(unsigned int)(division
.quot
*h
)) return GE_UNKNOWN
;
808 GSM_ClearBitmap(&bitmap
->Bitmap
[i
]);
813 if ((buffer
[pos
]&(1<<pos2
))>0) {
814 if (y
<bitmap
->Bitmap
[i
].Height
&& x
<bitmap
->Bitmap
[i
].Width
) GSM_SetPointBitmap(&bitmap
->Bitmap
[i
],x
,y
);
817 /* going to new byte */
818 if (pos2
<0) {pos2
=7;pos
++;}
820 /* for startup logos-new line means new byte */
821 if (pos2
!=7) {pos2
=7;pos
++;}
824 if (bitmap
->Number
== MAX_MULTI_BITMAP
) break;
829 static GSM_Error
loadnolngg(FILE *file
, GSM_MultiBitmap
*bitmap
, bool nolformat
)
831 unsigned char buffer
[2000];
834 fread(buffer
, 1, 6, file
);
836 if (bitmap
->Bitmap
[0].Type
== GSM_None
) bitmap
->Bitmap
[0].Type
= GSM_CallerLogo
;
838 fread(buffer
, 1, 4, file
);
839 sprintf(bitmap
->Bitmap
[0].NetworkCode
, "%d %02d", buffer
[0]+256*buffer
[1], buffer
[2]);
840 if (bitmap
->Bitmap
[0].Type
== GSM_None
) bitmap
->Bitmap
[0].Type
= GSM_OperatorLogo
;
843 fread(buffer
, 1, 4, file
);
846 GSM_GetMaxBitmapWidthHeight(bitmap
->Bitmap
[0].Type
, &bitmap
->Bitmap
[0].Width
, &bitmap
->Bitmap
[0].Height
);
847 if (h
< bitmap
->Bitmap
[0].Height
) bitmap
->Bitmap
[0].Height
= h
;
848 if (w
< bitmap
->Bitmap
[0].Width
) bitmap
->Bitmap
[0].Width
= w
;
851 fread(buffer
, 1, 6, file
);
853 GSM_ClearBitmap(&bitmap
->Bitmap
[0]);
856 for (i
=0; i
<w
*h
; i
++) {
857 if (fread(buffer
, 1, 1, file
)!=1) return GE_UNKNOWN
;
858 if (buffer
[0]=='1') GSM_SetPointBitmap(&bitmap
->Bitmap
[0],x
,y
);
860 if (x
==w
) {x
=0; y
++;}
864 /* Some programs writes here fileinfo */
865 if (fread(buffer
, 1, 1, file
)==1) {
866 dbgprintf("Fileinfo: %c",buffer
[0]);
867 while (fread(buffer
, 1, 1, file
)==1) {
868 if (buffer
[0]!=0x0A) dbgprintf("%c",buffer
[0]);
877 static GSM_Error
loadnsl(FILE *file
, GSM_MultiBitmap
*bitmap
)
879 unsigned char block
[6],buffer
[505];
881 GSM_Bitmap_Types OldType
;
883 while (fread(block
,1,6,file
)==6) {
884 block_size
= block
[4]*256 + block
[5];
885 dbgprintf("Block %c%c%c%c, size %i\n",block
[0],block
[1],block
[2],block
[3],block_size
);
886 if (!strncmp(block
, "FORM", 4)) {
887 dbgprintf("File ID\n");
889 if (block_size
>504) return(GE_UNKNOWN
);
891 fread(buffer
,1,block_size
,file
);
892 /* if it's string, we end it with 0 */
893 buffer
[block_size
]=0;
895 if (!strncmp(block
, "VERS", 4)) dbgprintf("File saved by: %s\n",buffer
);
896 if (!strncmp(block
, "MODL", 4)) dbgprintf("Logo saved from: %s\n",buffer
);
897 if (!strncmp(block
, "COMM", 4)) dbgprintf("Phone was connected to COM port: %s\n",buffer
);
899 if (!strncmp(block
, "NSLD", 4)) {
900 bitmap
->Bitmap
[0].Height
= 48;
901 bitmap
->Bitmap
[0].Width
= 84;
902 OldType
= bitmap
->Bitmap
[0].Type
;
903 PHONE_DecodeBitmap(GSM_NokiaStartupLogo
, buffer
, &bitmap
->Bitmap
[0]);
904 if (OldType
!= GSM_None
) bitmap
->Bitmap
[0].Type
= OldType
;
905 dbgprintf("Startup logo (size %i)\n",block_size
);
914 static GSM_Error
loadwbmp(FILE *file
, GSM_MultiBitmap
*bitmap
)
916 unsigned char buffer
[10000];
918 fread(buffer
,1,4,file
);
919 bitmap
->Bitmap
[0].Width
= buffer
[2];
920 bitmap
->Bitmap
[0].Height
= buffer
[3];
923 fread(buffer
,1,10000,file
);
924 PHONE_DecodeBitmap(GSM_Nokia7110OperatorLogo
, buffer
, &bitmap
->Bitmap
[0]);
925 GSM_ReverseBitmap(&bitmap
->Bitmap
[0]);
930 GSM_Error
GSM_ReadBitmapFile(char *FileName
, GSM_MultiBitmap
*bitmap
)
933 unsigned char buffer
[300];
935 file
= fopen(FileName
, "rb");
936 if (file
== NULL
) return(GE_CANTOPENFILE
);
938 fread(buffer
, 1, 9, file
); /* Read the header of the file. */
941 bitmap
->Bitmap
[0].DefaultBitmap
= false;
943 /* Attempt to identify filetype */
944 if (memcmp(buffer
, "BM",2)==0) {
945 return loadbmp(file
,bitmap
);
946 } else if (buffer
[0] == 0x00 && buffer
[1] == 0x00) {
947 return loadwbmp(file
,bitmap
);
948 } else if (memcmp(buffer
, "NLM",3)==0) {
949 return loadnlm(file
,bitmap
);
950 } else if (memcmp(buffer
, "NOL",3)==0) {
951 return loadnolngg(file
,bitmap
,true);
952 } else if (memcmp(buffer
, "NGG",3)==0) {
953 return loadnolngg(file
,bitmap
,false);
954 } else if (memcmp(buffer
, "FORM",4)==0) {
955 return loadnsl(file
,bitmap
);
960 void NOKIA_CopyBitmap(GSM_Phone_Bitmap_Types Type
, GSM_Bitmap
*Bitmap
, char *Buffer
, int *Length
)
964 Buffer
[(*Length
)++] = 0x00;
965 PHONE_GetBitmapWidthHeight(Type
, &Width
, &Height
);
966 Buffer
[(*Length
)++] = Width
;
967 Buffer
[(*Length
)++] = Height
;
968 Buffer
[(*Length
)++] = 0x01;
969 PHONE_EncodeBitmap(Type
, Buffer
+ (*Length
), Bitmap
);
970 (*Length
) = (*Length
) + PHONE_GetBitmapSize(Type
,0,0);
973 /* How should editor hadle tabs in this file? Add editor commands here.
974 * vim: noexpandtab sw=8 ts=8 sts=8: