+++ /dev/null
-/*
-
- G N O K I I
-
- A Linux/Unix toolset and driver for Nokia mobile phones.
-
- Copyright (C) 1999, 2000 Hugh Blemings & Pavel JanÃk ml.
-
- Released under the terms of the GNU GPL, see file COPYING for more details.
-
- Functions to read and write common file types.
-
- Last modified: Mon Mar 20 22:02:15 CET 2000
- Modified by Chris Kemp
-
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/stat.h>
-#ifndef VC6
-#include <unistd.h>
-#endif
-
-#include "gsm-common.h"
-#include "gsm-ringtones.h"
-#include "gsm-bitmaps.h"
-#include "files/gsm-filetypes.h"
-#include "files/midifile.h"
-#include "gsm-coding.h"
-#include "misc.h"
-#include "newmodules/n7110.h"
-#include "newmodules/n6110.h"
-
-#ifdef XPM
- #include <X11/xpm.h>
-#endif
-
-/**
-* GetvCalTime
-*
-* Fills vCalendar time string into GSM_DateTime structure
-*
-* in:
-* dt: datetime structure
-* time: string in format yyyymmddThhmmss
-* out:
-* <>0 if error
-*/
-int GetvCalTime(GSM_DateTime *dt, char *time)
-{
- char year[5]="", month[3]="", day[3]="", hour[3]="", minute[3]="", second[3]="";
- dt->Year=dt->Month=dt->Day=dt->Hour=dt->Minute=dt->Second=dt->Timezone=0;
-
- strncpy(year, time, 4);
- strncpy(month, time+4, 2);
- strncpy(day, time+6, 2);
- strncpy(hour, time+9, 2);
- strncpy(minute, time+11, 2);
- strncpy(second, time+13, 2);
-
-/* FIXME: Should check ranges... */
- dt->Year=atoi(year);
- dt->Month=atoi(month);
- dt->Day=atoi(day);
- dt->Hour=atoi(hour);
- dt->Minute=atoi(minute);
- dt->Second=atoi(second);
-/* FIXME */
- dt->Timezone=0;
-
- return 0;
-}
-
-/**
-* FillCalendarNote
-*
-* Fills calendar data from strings into calendar note
-*
-* in:
-* note: calendar note structure
-* type: type of calendar note
-* text: text or phonenumber
-* time: string in format yyyymmddThhmmss
-* alarm: dito
-* out:
-* <>0 if error
-*/
-int FillCalendarNote(GSM_CalendarNote *note, char *type,
- char *text, char *time, char *alarm)
-{
- GetvCalTime(¬e->Time, time);
- GetvCalTime(¬e->Alarm, alarm);
-
- note->Location=0;
-
- strncpy(note->Text, text, MAX_CALENDAR_TEXT_LENGTH);
- strcpy(note->Phone, ""); /* correct in most cases */
-
- /* FIXME: Handle additional strings, maybe from configuration file */
-
- if(!strcmp(type, "PHONE CALL"))
- {
- strncpy(note->Phone, text, MAX_CALENDAR_PHONE_LENGTH);
- note->Type=GCN_CALL;
- }
- else if(!strcmp(type, "MEETING"))
- note->Type=GCN_MEETING;
- else if(!strcmp(type, "SPECIAL OCCASION"))
- note->Type=GCN_BIRTHDAY;
- else
- note->Type=GCN_REMINDER;
-
- return 0;
-}
-
-/**
-* GSM_ReadVCalendarFile
-*
-* Reads vCalendar file
-*
-* in:
-* FileName: name of vCalendar file
-* cnote: pointer to calendar note
-* number: number in file of calendar note to read
-* out:
-* <>0 if error
-*/
-GSM_Error GSM_ReadVCalendarFile(char *FileName, GSM_CalendarNote *cnote, int *number)
-{
- FILE *file;
- char type[21]="", text[40]="", time[16]="", alarm[16]="";
- char phone[40]="";
- long recurr=0L;
- char altype=0x00;
-
- int veventcounter=0;
- int isOK=0;
-
- bool NoteOK=false;
-
- char *Line, OLine[1024], BackLine[1024];
-
- Line = OLine;
-
- file=fopen(FileName, "r");
- if (!file) {
-#ifdef DEBUG
- fprintf(stderr, _("File cannot be opened!\n"));
-#endif
- return GE_CANTOPENFILE;
- }
-
- /* Go through data from file. */
- while (GetLine(file, Line, sizeof(OLine))!=-1) {
-
- strcpy(BackLine, Line);
-
- switch (isOK) {
- case 0:
- if (!strcmp(Line,"BEGIN:VCALENDAR"))
- isOK++;
- break;
- case 1:
- if (!strcmp(Line,"BEGIN:VEVENT")) {
- isOK++;
- veventcounter++;
- }
- if (!strcmp(Line,"END:VCALENDAR"))
- isOK--;
- break;
- case 2:
- if (veventcounter==*number) {
- if (!strncmp(Line,"CATEGORIES:",11)) {
- strncpy(type,Line+11,strlen(Line)-11);
- type[strlen(Line)-11]=0;
- }
- if (!strncmp(Line,"DESCRIPTION:",12)) {
- strncpy(phone,Line+12,strlen(Line)-12);
- phone[strlen(Line)-12]=0;
- }
- if (!strncmp(Line,"SUMMARY:",8)) {
- strncpy(text,Line+8,strlen(Line)-8);
- text[strlen(Line)-8]=0;
- }
- if (!strncmp(Line,"SUMMARY;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:",48)) {
- DecodeUTF8(text,Line+48,strlen(Line)-48);
- text[strlen(Line)-48]=0;
- }
- if (!strncmp(Line,"DTSTART:",8)) {
- strncpy(time,Line+8,strlen(Line)-8);
- time[strlen(Line)-8]=0;
- }
- if (!strncmp(Line,"DALARM:",7)) {
- strncpy(alarm,Line+7,strlen(Line)-7);
- alarm[strlen(Line)-7]=0;
- }
-
- /* Obsolete */
- if (!strncmp(Line,"RECURR:",7)) {
- recurr=mem_to_int(Line+7,strlen(Line)-7);
- }
-
- if (!strncmp(Line,"RRULE:D1 :",9)) {
- recurr=1;
- }
- if (!strncmp(Line,"RRULE:W1 :",9)) {
- recurr=7;
- }
- if (!strncmp(Line,"RRULE:W2 :",9)) {
- recurr=14;
- }
- if (!strncmp(Line,"RRULE:YD1 :",10)) {
- recurr=365;
- }
-
- if (!strncmp(Line,"ALTYPE:",7)) {
- altype=(!strncmp("TONE",Line+7,4)) ? 0x00 : 0x01;
- }
- }
- if (!strcmp(Line,"END:VEVENT")) {
- if (veventcounter==*number) NoteOK=true;
- isOK--;
- }
- break;
- }
-
- if (NoteOK) break;
- }
-
- if (!NoteOK) {
- *number=veventcounter;
-#ifdef DEBUG
- fprintf(stdout,_("Note not found in VCalendarfile\n"));
-#endif
- return GE_TOOSHORT;
- }
-
- FillCalendarNote(cnote, type, text, time, alarm);
-
- cnote->Recurrance = recurr*24; /* it was in days. I convert in hours */
- cnote->AlarmType = altype;
-
- if( strcmp( phone, "" ) ) { /* Invert data if CALL ... */
- strcpy( cnote->Text, phone );
- strcpy( cnote->Phone, text ); // alread FillCalendar does it ..
- }
-
- fclose(file);
-
- return 0;
-}
-
-GSM_Error GSM_ReadBinRingtoneFile(char *FileName, GSM_BinRingtone *ringtone)
-{
- FILE *file;
-
- file = fopen(FileName, "rb");
-
- if (!file)
- return(GE_CANTOPENFILE);
-
-// fseek(file,3474485,0);
-
- ringtone->length=fread(ringtone->frame, 1, 500, file);
-
- fclose(file);
-
- if (ringtone->frame[0]!=0x00 || ringtone->frame[1]!=0x00 ||
- ringtone->frame[2]!=0x0C || ringtone->frame[3]!=0x01)
- return GE_NOTSUPPORTED;
-
- return GE_NONE;
-}
-
-/* Function to convert scale field in to correct number. */
-int GetRTTLDuration (char *num)
-{
-
-int duration=0;
-
- switch (atoi(num)) {
-
- case 1: duration=128; break;
- case 2: duration= 64; break;
- case 4: duration= 32; break;
- case 8: duration= 16; break;
- case 16: duration= 8; break;
- case 32: duration= 4; break;
- }
-
- return (duration);
-
-}
-
-int GetRTTLScale (char *num)
-{
-
- /* This may well need improving. */
-
- int scale=0;
-
- if ((atoi(num))<4) scale=(atoi(num));
- if ((atoi(num))>4) scale=(atoi(num))-4;
-
- return (scale);
-}
-
-GSM_Error GSM_ReadRingtoneFile(char *FileName, GSM_Ringtone *ringtone)
-{
- FILE *file;
- unsigned char buffer[300];
- GSM_Error error;
- GSM_Filetypes filetype=RTTL;
-
- file = fopen(FileName, "rb");
-
- if (!file)
- return(GE_CANTOPENFILE);
-
- fread(buffer, 1, 4, file); /* Read the header of the file. */
-
- /* Attempt to identify filetype */
-
- if (memcmp(buffer, "MThd",3)==0) /* MIDI files have 'MThd' at the start */
- filetype=MIDI;
-
- if (buffer[0]==0xc7 && buffer[1]==0x45 && buffer[2]==0xc1 && buffer[3]==0x53)
- filetype=COMMUNICATOR;
-
- if (strstr(FileName,".ott")) filetype=OTT; /* OTT files saved by NCDS3 */
-
- error=GE_NONE;
-
- rewind(file);
-
- switch (filetype) {
- case RTTL:
- error=loadrttl(file,ringtone);
- fclose(file);
- break;
- case OTT:
- error=loadott(file,ringtone);
- fclose(file);
- break;
- case COMMUNICATOR:
- error=loadcommunicator(file,ringtone);
- fclose(file);
- break;
- case MIDI:
- fclose(file);
- error=loadmid(FileName,ringtone);
- break;
- default:
- error=GE_INVALIDFILEFORMAT;
- }
-
- return(error);
-
-}
-
-GSM_Error loadott(FILE *file, GSM_Ringtone *ringtone)
-{
- char Buffer[2000];
- int i;
-
- i=fread(Buffer, 1, 2000, file);
-
- if (!feof(file)) return GE_TOOLONG;
-
- return GSM_UnPackRingtone(ringtone, Buffer, i);
-}
-
-GSM_Error loadcommunicator(FILE *file, GSM_Ringtone *ringtone)
-{
- char Buffer[4000];
- int i,j;
-
- i=fread(Buffer, 1, 4000, file);
-
- if (!feof(file)) return GE_TOOLONG;
-
- i=0;j=0;
- while (true) {
- if (Buffer[j]==0x00 && Buffer[j+1]==0x02 &&
- Buffer[j+2]==0x4a && Buffer[j+3]==0x3a) break;
- if (j==i-4) return GE_INTERNALERROR;
- j++;
- }
- j++;
-
- return GSM_UnPackRingtone(ringtone, Buffer+j, i-j);
-}
-
-/* TODO: spaces should not be interpreted */
-/* Note: ringtone have to be in one line (without 0x13 and 0x10 chars) */
-GSM_Error loadrttl(FILE *file, GSM_Ringtone *ringtone)
-{
- int NrNote=0;
-
- u8 DefNoteScale=2, DefNoteDuration=4;
- int DefNoteTempo=63;
- u8 DefNoteStyle=ContinuousStyle;
-
- unsigned char buffer[2000];
- unsigned char *def, *notes, *ptr;
-
- ringtone->Loop=15; //default value
-
- fread(buffer, 2000, 1, file);
-
- /* This is for buggy RTTTL ringtones without name. */
- if (buffer[0] != RTTTL_SEP[0]) {
- strtok(buffer, RTTTL_SEP);
- sprintf(ringtone->name, "%s", buffer);
- def=strtok(NULL, RTTTL_SEP);
- notes=strtok(NULL, RTTTL_SEP);
- }
- else {
- sprintf(ringtone->name, "GNOKII");
- def=strtok(buffer, RTTTL_SEP);
- notes=strtok(NULL, RTTTL_SEP);
- }
-
- ptr=strtok(def, ", ");
-
- /* Parsing the <defaults> section. */
- while (ptr) {
-
- switch(*ptr) {
- case 'd':
- case 'D':
- DefNoteDuration=GetRTTLDuration(ptr+2);
- break;
- case 'o':
- case 'O':
- DefNoteScale=GetRTTLScale(ptr+2);
- break;
- case 'b':
- case 'B':
- DefNoteTempo=atoi(ptr+2);
- break;
- case 'l':
- case 'L':
- ringtone->Loop=atoi(ptr+2);
- break;
- case 's':
- case 'S':
- switch (*(ptr+1)) {
- case 'C':
- case 'c':
- DefNoteStyle=ContinuousStyle;
- break;
- case 'N':
- case 'n':
- DefNoteStyle=NaturalStyle;
- break;
- case 'S':
- case 's':
- DefNoteStyle=StaccatoStyle;
- break;
- }
- switch (*(ptr+2)) {
- case 'c':
- case 'C':
- DefNoteStyle=ContinuousStyle;
- break;
- case 'n':
- case 'N':
- DefNoteStyle=NaturalStyle;
- break;
- case 's':
- case 'S':
- DefNoteStyle=StaccatoStyle;
- break;
- }
- break;
- }
-
- ptr=strtok(NULL,", ");
- }
-
-#ifdef DEBUG
- printf("DefNoteDuration=%d\n", DefNoteDuration);
- printf("DefNoteScale=%d\n", DefNoteScale);
-#endif
-
- ptr=strtok(notes, ", ");
-
- /* Parsing the <note-command>+ section. */
- while (ptr && NrNote<MAX_RINGTONE_NOTES) {
-
- switch(*ptr) {
- case 'o':
- case 'O':
- DefNoteScale=GetRTTLScale(ptr+2);
- break;
- case 's':
- case 'S':
- switch (*(ptr+1)) {
- case 'C':
- case 'c':
- DefNoteStyle=ContinuousStyle;
- break;
- case 'N':
- case 'n':
- DefNoteStyle=NaturalStyle;
- break;
- case 'S':
- case 's':
- DefNoteStyle=StaccatoStyle;
- break;
- }
- switch (*(ptr+2)) {
- case 'C':
- case 'c':
- DefNoteStyle=ContinuousStyle;
- break;
- case 'N':
- case 'n':
- DefNoteStyle=NaturalStyle;
- break;
- case 'S':
- case 's':
- DefNoteStyle=StaccatoStyle;
- break;
- }
- break;
- default:
- /* [<duration>] */
- ringtone->notes[NrNote].duration=GetRTTLDuration(ptr);
- if (ringtone->notes[NrNote].duration==0)
- ringtone->notes[NrNote].duration=DefNoteDuration;
-
- /* Skip all numbers in duration specification. */
- while(isdigit(*ptr))
- ptr++;
-
- /* <note> */
- /* B or b is not in specs, but I decided to put it, because
- it's in some RTTL files. It's the same to H note */
- if ((*ptr=='B') || (*ptr=='b')) ringtone->notes[NrNote].note=12;
- else if ((*ptr=='H') || (*ptr=='h')) ringtone->notes[NrNote].note=12;
- else if ((*ptr>='a') && (*ptr<='g')) ringtone->notes[NrNote].note=((*ptr-'a')*2)+10;
- else if ((*ptr>='A') && (*ptr<='G')) ringtone->notes[NrNote].note=((*ptr-'A')*2)+10;
- else ringtone->notes[NrNote].note=255;
-
- if ((ringtone->notes[NrNote].note>13)&&(ringtone->notes[NrNote].note!=255))
- ringtone->notes[NrNote].note-=14;
-
- ptr++;
-
- if ((*ptr)=='#') {
- ringtone->notes[NrNote].note++;
- if ((ringtone->notes[NrNote].note==5) || (ringtone->notes[NrNote].note==13))
- ringtone->notes[NrNote].note++;
- ptr++;
- }
-
- /* Check for dodgy rttl */
- /* [<special-duration>] */
- if (*ptr=='.') {
- ringtone->notes[NrNote].duration*=1.5;
- ptr++;
- }
-
- /* [<scale>] */
- if (ringtone->notes[NrNote].note!=255) {
- if (isdigit(*ptr)) {
- ringtone->notes[NrNote].note+=GetRTTLScale(ptr)*14;
- ptr++;
- } else
- ringtone->notes[NrNote].note+=DefNoteScale*14;
- }
-
- /* [<special-duration>] */
- if (*ptr=='.') {
- ringtone->notes[NrNote].duration*=1.5;
- ptr++;
- }
-
- /* Style */
- ringtone->notes[NrNote].style=DefNoteStyle;
-
- /* Tempo */
- ringtone->notes[NrNote].tempo=DefNoteTempo;
-
- NrNote++;
-
- break;
- }
- ptr=strtok(NULL, ", ");
- }
-
- ringtone->NrNotes=NrNote;
-
- return GE_NONE;
-}
-
-GSM_Error GSM_SaveRingtoneFile(char *FileName, GSM_Ringtone *ringtone)
-{
-
- FILE *file;
- bool done=false;
-
- file = fopen(FileName, "wb");
-
- if (!file)
- return(GE_CANTOPENFILE);
-
- if (strstr(FileName,".ott"))
- {
- saveott(file, ringtone);
- done=true;
- }
- if (strstr(FileName,".mid"))
- {
- savemid(file, ringtone);
- done=true;
- }
-
- if (!done) saverttl(file, ringtone);
-
- fclose(file);
-
- return GE_NONE;
-}
-
-void saveott(FILE *file, GSM_Ringtone *ringtone)
-{
- char Buffer[2000];
-
- int i=2000;
-
- GSM_PackRingtone(ringtone, Buffer, &i);
-
- fwrite(Buffer, 1, i, file);
-}
-
-void saverttl(FILE *file, GSM_Ringtone *ringtone)
-{
- u8 DefNoteScale=2, DefNoteDuration=4;
- int DefNoteTempo=63;
- u8 DefNoteStyle=ContinuousStyle;
-
- int CurrentNote;\r
- int buffer[6];\r
- int i,j,k=0;\r
- \r
- /* Saves ringtone name */\r
- fprintf(file,_("%s:"),ringtone->name);\r
-\r
- /* Find the most frequently used duration and use this for the default */\r
- \r
- for (i=0;i<6;i++) buffer[i]=0;\r
- for (i=0;i<ringtone->NrNotes;i++) {\r
- switch (ringtone->notes[i].duration) {\r
- case 192:buffer[0]++; break;\r
- case 128:buffer[0]++; break;\r
- case 96:buffer[1]++; break;\r
- case 64:buffer[1]++; break;\r
- case 48:buffer[2]++; break;\r
- case 32:buffer[2]++; break;\r
- case 24:buffer[3]++; break;\r
- case 16:buffer[3]++; break;\r
- case 12:buffer[4]++; break;\r
- case 8:buffer[4]++; break;\r
- case 6:buffer[5]++; break;\r
- case 4:buffer[5]++; break;\r
- }\r
- }\r
-\r
- /* Now find the most frequently used */\r
- j=0;\r
- for (i=0;i<6;i++) {\r
- if (buffer[i]>j) {\r
- k=i; \r
- j=buffer[i];\r
- }\r
- }\r
-\r
- /* Finally convert and save the default duration */\r
-\r
- switch (k) {\r
- case 0: DefNoteDuration=128; fprintf(file, _("d=1,")); break; \r
- case 1: DefNoteDuration= 64; fprintf(file, _("d=2,")); break; \r
- case 2: DefNoteDuration= 32; fprintf(file, _("d=4,")); break; \r
- case 3: DefNoteDuration= 16; fprintf(file, _("d=8,")); break; \r
- case 4: DefNoteDuration= 8; fprintf(file,_("d=16,")); break; \r
- case 5: DefNoteDuration= 4; fprintf(file,_("d=32,")); break; \r
- default: DefNoteDuration= 16; fprintf(file, _("d=8,")); break; \r
- } \r
-\r
-\r
- /* Find the most frequently used scale and use this for the default */\r
-\r
- for (i=0;i<6;i++) buffer[i]=0;\r
- for (i=0;i<ringtone->NrNotes;i++) {\r
- if (ringtone->notes[i].note!=255) {\r
- buffer[ringtone->notes[i].note/14]++;\r
- }\r
- }\r
- j=0;\r
- for (i=0;i<6;i++) {\r
- if (buffer[i]>j) {\r
- DefNoteScale=i;\r
- j=buffer[i];\r
- }\r
- }\r
-
- if (ringtone->NrNotes!=0) {
- DefNoteTempo=ringtone->notes[0].tempo;
- DefNoteStyle=ringtone->notes[0].style;
- }
-
- /* Save the default scale */\r
- fprintf(file,_("o=%i,"),DefNoteScale+4);\r \r
-
- switch (DefNoteStyle) {
- case StaccatoStyle: fprintf(file,_("s=S,")); break;
- case NaturalStyle : fprintf(file,_("s=N,")); break;
- }
-\r
- /* Save the default tempo */
- fprintf(file,_("b=%i,"),DefNoteTempo);
-
- /* Save the default loop */
- fprintf(file,_("l=%i:"),ringtone->Loop);
-
-#ifdef DEBUG\r
- printf("DefNoteDuration=%d\n", DefNoteDuration);\r
- printf("DefNoteScale=%d\n", DefNoteScale);\r
- printf("Number of notes=%d\n",ringtone->NrNotes);\r
-#endif\r
- \r
- /* Now loop round for each note */\r
-\r
- for (i=0;i<ringtone->NrNotes;i++) {\r
- CurrentNote=ringtone->notes[i].note;\r
-\r
- if (ringtone->notes[i].style!=DefNoteStyle) {
- DefNoteStyle=ringtone->notes[i].style;
- switch (DefNoteStyle) {
- case StaccatoStyle : fprintf(file,_("s=S")); break;
- case NaturalStyle : fprintf(file,_("s=N")); break;
- case ContinuousStyle: fprintf(file,_("s=C")); break;
- }
- /* And a separator before next note */\r
- if (i!=ringtone->NrNotes-1)\r
- fprintf(file,_(","));\r
- }
-
- if (ringtone->notes[i].tempo!=DefNoteTempo) {
- DefNoteTempo=ringtone->notes[i].tempo;
- fprintf(file,_("b=%i"),DefNoteTempo);\r
- if (i!=ringtone->NrNotes-1)\r
- fprintf(file,_(","));\r
- }
-
- /* This note has a duration different than the default. We must save it */\r
- if (ringtone->notes[i].duration!=DefNoteDuration) {\r
- switch (ringtone->notes[i].duration) {\r
- case 192: fprintf(file, _("1")); break; //192=128*1.5\r
- case 128: fprintf(file, _("1")); break;\r
- case 96: fprintf(file, _("2")); break; //96=64*1.5\r
- case 64: fprintf(file, _("2")); break;\r
- case 48: fprintf(file, _("4")); break; //48=32*1.5\r
- case 32: fprintf(file, _("4")); break;\r
- case 24: fprintf(file, _("8")); break; //24=16*1.5\r
- case 16: fprintf(file, _("8")); break;\r
- case 12: fprintf(file,_("16")); break; //12=8*1.5\r
- case 8: fprintf(file,_("16")); break;\r
- case 6: fprintf(file,_("32")); break; //6=4*1.5\r
- case 4: fprintf(file,_("32")); break;\r
- default: \r
- break;\r
- }\r
- }\r
- \r
- /* Now save the actual note */\r
- switch (GSM_GetNote(CurrentNote)) {\r
- case Note_C :fprintf(file,_("c"));break;\r
- case Note_Cis:fprintf(file,_("c#"));break;\r
- case Note_D :fprintf(file,_("d"));break;\r
- case Note_Dis:fprintf(file,_("d#"));break;\r
- case Note_E :fprintf(file,_("e"));break;\r
- case Note_F :fprintf(file,_("f"));break;\r
- case Note_Fis:fprintf(file,_("f#"));break;\r
- case Note_G :fprintf(file,_("g"));break;\r
- case Note_Gis:fprintf(file,_("g#"));break;\r
- case Note_A :fprintf(file,_("a"));break;\r
- case Note_Ais:fprintf(file,_("a#"));break;\r
- case Note_H :fprintf(file,_("h"));break;\r
- default :fprintf(file,_("p"));break; //Pause ?\r
- }\r
-\r
- /* Saving info about special duration */\r
- if (ringtone->notes[i].duration==128*1.5 ||\r
- ringtone->notes[i].duration==64*1.5 ||\r
- ringtone->notes[i].duration==32*1.5 ||\r
- ringtone->notes[i].duration==16*1.5 ||\r
- ringtone->notes[i].duration==8*1.5 ||\r
- ringtone->notes[i].duration==4*1.5)\r
- fprintf(file,_("."));\r
- \r
- /* This note has a scale different than the default, so save it */\r
- if ( (CurrentNote!=255) && (CurrentNote/14!=DefNoteScale))\r
- fprintf(file,_("%i"),(CurrentNote/14)+4);\r
- \r
- /* And a separator before next note */\r
- if (i!=ringtone->NrNotes-1)\r
- fprintf(file,_(","));\r
-\r
- }\r
-}
-
-void WriteVarLen(char* midifile, int* current, long value)
-{
- long buffer;
-
- buffer = value & 0x7f;
-
- while (value >>= 7) {
- buffer <<= 8;
- buffer |= 0x80;
- buffer += (value & 0x7f);
- }
-
- while (1) {
- midifile[(*current)++] = buffer;
- if (buffer & 0x80)
- buffer >>= 8;
- else
- break;
- }
-}
-
-#define singlepauses
-
-/* FIXME: need adding tempo before each note and scale too ? */
-void savemid(FILE* file, GSM_Ringtone *ringtone)
-{
- char midifile[3000] = { 0x4D, 0x54, 0x68, 0x64, // MThd
- 0x00, 0x00, 0x00, 0x06, // chunk length
- 0x00, 0x00, // format 0
- 0x00, 0x01, // one track
- 0x00, 0x20, // 32 per quarter note
- 0x4D, 0x54, 0x72, 0x6B, // MTrk
- 0x00, 0x00, 0x00, 0x00, // chunk length
- 0x00, 0xFF, 0x51, 0x03, // tempo meta event
- 0x00, 0x00, 0x00 // 3 bytes for us for a quarter note
- };
-
-//{ "c", "c#", "d", "d#", "e", "f", "f#", "g", "g#", "a", "a#", "h" };
-char midinotes[14] =
- { 0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10 , 11, 11 };
-
- int length = 20;
- int start = 22;
- int current = 26, i, note, pause = 0;
- bool notesexisting = false;
-
- /* FIXME: we need add tempo before each note or so... */
- long duration=60000000/63; // us for a quarter note
- if (ringtone->NrNotes!=0)
- duration=60000000/ringtone->notes[0].tempo;
- midifile[current++] = duration >> 16;
- midifile[current++] = duration >> 8;
- midifile[current++] = duration;
-
- for (i = 0; i < ringtone->NrNotes; i++) {
-
- note = ringtone->notes[i].note;
- if (note == 255) { // readmid does not read pauses at the beginning
-
- if (notesexisting) {
- pause += ringtone->notes[i].duration;
-#ifdef singlepauses
- WriteVarLen(midifile,¤t,pause);
- pause=0;
- midifile[current++]=0x00; // pause
- midifile[current++]=0x00;
-#endif
- }
-
- } else {
-
- notesexisting = true;
- note = 48+12*((note/14)%4) + midinotes[note%14];
-
- WriteVarLen(midifile,¤t,pause);
- pause=0;
- midifile[current++]=0x90; // note on
- midifile[current++]=note;
- midifile[current++]=0x64; // forte
-
- WriteVarLen(midifile,¤t,ringtone->notes[i].duration);
- midifile[current++]=0x80; // note off
- midifile[current++]=note;
- midifile[current++]=0x64;
-
- }
- }
-
- if (pause) {
- WriteVarLen(midifile,¤t,pause);
- midifile[current++]=0x00; // pause
- midifile[current++]=0x00; //
- }
- midifile[current++] = 0x00;
- midifile[current++] = 0xFF; // track end
- midifile[current++] = 0x2F;
- midifile[current++] = 0x00;
- midifile[length++] = (current-start) >> 8;
- midifile[length++] = current-start;
-
- fwrite(midifile,1,current,file);
-}
-
-GSM_Error GSM_ReadBitmapFile(char *FileName, GSM_Bitmap *bitmap)
-{
-
- FILE *file;
- unsigned char buffer[300];
- GSM_Error error;
- GSM_Filetypes filetype=None;
-
- file = fopen(FileName, "rb");
-
- if (!file)
- return(GE_CANTOPENFILE);
-
- fread(buffer, 1, 9, file); /* Read the header of the file. */
-
- /* Attempt to identify filetype */
-
- if (memcmp(buffer, "NOL",3)==0) { /* NOL files have 'NOL' at the start */
- filetype=NOL;
- } else if (memcmp(buffer, "NGG",3)==0) { /* NGG files have 'NGG' at the start */
- filetype=NGG;
- } else if (memcmp(buffer, "FORM",4)==0) { /* NSL files have 'FORM' at the start */
- filetype=NSL;
- } else if (memcmp(buffer, "NLM",3)==0) { /* NLM files have 'NLM' at the start */
- filetype=NLM;
- } else if (memcmp(buffer, "BM",2)==0) { /* BMP, I61 and GGP files have 'BM' at the start */
- filetype=BMP;
- } else if (memcmp(buffer, "/* XPM */",9)==0) { /* XPM files have 'XPM' at the start */
- filetype=XPMF;
- } else filetype=None;
-
- if (strstr(FileName,".otb")) filetype=OTA; /* OTA files saved by NCDS3 */
-
- error=GE_NONE;
-
- rewind(file);
-
- switch (filetype) {
- case NOL: error=loadnol(file,bitmap); fclose(file); break;
- case NGG: error=loadngg(file,bitmap); fclose(file); break;
- case NSL: error=loadnsl(file,bitmap); fclose(file); break;
- case NLM: error=loadnlm(file,bitmap); fclose(file); break;
- case OTA: error=loadota(file,bitmap); fclose(file); break;
- case BMP: error=loadbmp(file,bitmap); fclose(file); break;
-#ifdef XPM
- case XPMF:fclose(file);error=loadxpm(FileName,bitmap);break;
-#endif
- default : error=GE_INVALIDFILEFORMAT;
- }
-
- return(error);
-}
-
-#ifdef XPM
-
-GSM_Error loadxpm(char *filename, GSM_Bitmap *bitmap)
-{
- int y,x,error;
- XpmImage image;
- XpmInfo info;
-
- error=XpmReadFileToXpmImage(filename,&image,&info);
-
- switch (error) {
- case XpmColorError: return GE_WRONGCOLORS;break;
- case XpmColorFailed: return GE_WRONGCOLORS;break;
- case XpmOpenFailed: return GE_CANTOPENFILE;break;
- case XpmFileInvalid: return GE_INVALIDFILEFORMAT;break;
- case XpmSuccess: break;
- }
-
- if (image.ncolors!=2) {
- printf("Wrong number of colors\n");
- return GE_WRONGNUMBEROFCOLORS;
- }
-
- if ((image.height==48) && (image.width==84)) {
- bitmap->type=GSM_StartupLogo;
- }
- else if ((image.height==65) && (image.width==96)) {
- bitmap->type=GSM_7110StartupLogo;
- }
- else if ((image.height==60) && (image.width==96)) {
- bitmap->type=GSM_6210StartupLogo;
- }
- else if ((image.height==28) && (image.width==72)) {
- bitmap->type=GSM_PictureImage;
- }
- else if ((image.height==14) && (image.width==72)) {
- bitmap->type=GSM_CallerLogo;
- }
- else {
-#ifdef DEBUG
- printf("Invalid Image Size (%dx%d).\n",image.width,image.height);
-#endif
- return GE_INVALIDIMAGESIZE;
- }
-
- bitmap->height=image.height;
- bitmap->width=image.width;
- bitmap->size=bitmap->height*bitmap->width/8;
-
- GSM_ClearBitmap(bitmap);
-
- for(y=0;y<image.height;y++) {
- for(x=0;x<image.width;x++) {
- if (image.data[y*image.width+x]==0) GSM_SetPointBitmap(bitmap,x,y);
- }
- }
-
- return GE_NONE;
-}
-
-#endif
-
-/* Based on the article from the Polish Magazine "Bajtek" 11/92 */
- /* Marcin-Wiacek@Topnet.PL */
-GSM_Error loadbmp(FILE *file, GSM_Bitmap *bitmap)
-{
- unsigned char buffer[34];
- bool first_white;
- int w,h,pos,y,x,i,sizeimage;
-
- fread(buffer, 1, 34, file); //required part of header
-
- h=buffer[22]+256*buffer[21]; //height of image in the file
- w=buffer[18]+256*buffer[17]; //width of image in the file
-#ifdef DEBUG
- printf("Image Size in BMP file: %dx%d\n",w,h);
-#endif
-
- bitmap->type=GSM_7110StartupLogo;
- bitmap->width=96;
- bitmap->height=65;
-
- if (h==48 && w==84) {
- bitmap->width=84;
- bitmap->height=48;
- bitmap->type=GSM_StartupLogo;
- }
- if (h==60 && w==96) {
- bitmap->width=96;
- bitmap->height=60;
- bitmap->type=GSM_6210StartupLogo;
- }
- if (h==14 && w==72) {
- bitmap->width=72;
- bitmap->height=14;
- bitmap->type=GSM_CallerLogo;
- }
- if (h==28 && w==72) {
- bitmap->width=72;
- bitmap->height=28;
- bitmap->type=GSM_PictureImage;
- }
- if (h==21 && w==78) {
- bitmap->width=78;
- bitmap->height=21;
- bitmap->type=GSM_7110OperatorLogo;
- }
-
- /* Gabo !!! */
- bitmap->size=(bitmap->width*bitmap->height + 7)/8;
-
- GSM_ClearBitmap(bitmap);
-
-#ifdef DEBUG
- printf("Number of colors in BMP file: ");
- switch (buffer[28]) {
- case 1:printf("2 (supported by gnokii)\n");break;
- case 4:printf("16 (not supported by gnokii)\n");break;
- case 8:printf("256 (not supported by gnokii)\n");break;
- case 24:printf("True Color (not supported by gnokii)\n");break;
- default:printf("unknown\n");break;
- }
-#endif
- if (buffer[28]!=1) {
- printf("Wrong number of colors\n"); //we support only 2 colors images !
- return GE_WRONGNUMBEROFCOLORS;
- }
-
-#ifdef DEBUG
- printf("Compression in BMP file: ");
- switch (buffer[30]) {
- case 0:printf("no compression (supported by gnokii)\n");break;
- case 1:printf("RLE8 (not supported by gnokii)\n");break;
- case 2:printf("RLE4 (not supported by gnokii)\n");break;
- default:printf("unknown\n");break;
- }
-#endif
- if (buffer[30]!=0) {
-#ifdef DEBUG
- printf("Subformat not supported\n"); //we don't support RLE compression
-#endif
- return GE_SUBFORMATNOTSUPPORTED;
- }
-
- pos=buffer[10]-34;
- fread(buffer, 1, pos, file); //rest of header (if exists) and color palette
-
-#ifdef DEBUG
- printf("First color in BMP file: %i %i %i ",buffer[pos-8], buffer[pos-7], buffer[pos-6]);
- if (buffer[pos-8]==0 && buffer[pos-7]==0 && buffer[pos-6]==0) printf("(white)");
- if (buffer[pos-8]==0xFF && buffer[pos-7]==0xFF && buffer[pos-6]==0xFF) printf("(black)");
- if (buffer[pos-8]==102 && buffer[pos-7]==204 && buffer[pos-6]==102) printf("(green)");
- printf("\n");
-
- printf("Second color in BMP file: %i %i %i ",buffer[pos-4], buffer[pos-3], buffer[pos-2]);
- if (buffer[pos-4]==0 && buffer[pos-3]==0 && buffer[pos-2]==0) printf("(white)");
- if (buffer[pos-4]==0xFF && buffer[pos-3]==0xFF && buffer[pos-2]==0xFF) printf("(black)");
- printf("\n");
-#endif
- first_white=true;
- if (buffer[pos-8]!=0 || buffer[pos-7]!=0 || buffer[pos-6]!=0) first_white=false;
-
- sizeimage=0;
- pos=7;
- for (y=h-1;y>=0;y--) { //lines are written from the last to the first
- i=1;
- for (x=0;x<w;x++) {
- if (pos==7) { //new byte !
- fread(buffer, 1, 1, file);
- sizeimage++;
- i++;
- if(i==5) i=1; //each line is written in multiply of 4 bytes
- }
- if (x<=bitmap->width && y<=bitmap->height) { //we have top left corner !
- if (first_white) {
- if ((buffer[0]&(1<<pos))<=0) GSM_SetPointBitmap(bitmap,x,y);
- } else {
- if ((buffer[0]&(1<<pos))>0) GSM_SetPointBitmap(bitmap,x,y);
- }
- }
- pos--;
- if (pos<0) pos=7; //going to new byte
- }
- pos=7; //going to new byte
- if (i!=1) {
- while (i!=5) //each line is written in multiply of 4 bytes
- {
- fread(buffer, 1, 1, file);
- sizeimage++;
- i++;
- }
- }
- }
-
-#ifdef DEBUG
- printf("Data size in BMP file: %i\n",sizeimage);
-#endif
-
- return(GE_NONE);
-}
-
-GSM_Error loadnol(FILE *file, GSM_Bitmap *bitmap)
-{
-
- unsigned char buffer[2000];
- int i,j;
-
- bitmap->type=GSM_OperatorLogo;
-
- fread(buffer, 1, 6, file);
- fread(buffer, 1, 4, file);
- sprintf(bitmap->netcode, "%d %02d", buffer[0]+256*buffer[1], buffer[2]);
-
- fread(buffer, 1, 4, file); /* Width and height of the icon. */
- bitmap->width=buffer[0];
- bitmap->height=buffer[2];
- bitmap->size=bitmap->height*bitmap->width/8;
-
- if ((bitmap->height!=14) || (bitmap->width!=72)) {
-#ifdef DEBUG
- printf("Invalid Image Size (%dx%d).\n",bitmap->width,bitmap->height);
-#endif
- return GE_INVALIDIMAGESIZE;
- }
-
- fread(buffer, 1, 6, file); /* Unknown bytes. */
-
- for (i=0; i<bitmap->size; i++) {
- if (fread(buffer, 1, 8, file)==8) {
- bitmap->bitmap[i]=0;
- for (j=7; j>=0;j--)
- if (buffer[7-j] == '1')
- bitmap->bitmap[i]|=(1<<j);
- }
- else
- return (GE_TOOSHORT);
- }
-
-#ifdef DEBUG
- /* Some programs writes here fileinfo */
- if (fread(buffer, 1, 1, file)==1) {
- fprintf(stdout, _("Fileinfo: %c"),buffer[0]);
- while (fread(buffer, 1, 1, file)==1) {
- if (buffer[0]!=0x0A) fprintf(stdout,_("%c"),buffer[0]);
- }
- fprintf(stdout, _("\n"));
- }
-#endif
-
- return(GE_NONE);
-}
-
-GSM_Error loadngg(FILE *file, GSM_Bitmap *bitmap)
-{
-
- unsigned char buffer[2000];
- int i,j;
-
- bitmap->type=GSM_CallerLogo;
-
- fread(buffer, 1, 6, file);
- fread(buffer, 1, 4, file); /* Width and height of the icon. */
- bitmap->width=buffer[0];
- bitmap->height=buffer[2];
- bitmap->size=bitmap->height*bitmap->width/8;
-
- if ((bitmap->height!=14) || (bitmap->width!=72)) {
-#ifdef DEBUG
- printf("Invalid Image Size (%dx%d).\n",bitmap->width,bitmap->height);
-#endif
- return GE_INVALIDIMAGESIZE;
- }
-
- fread(buffer, 1, 6, file); /* Unknown bytes. */
-
- for (i=0; i<bitmap->size; i++) {
- if (fread(buffer, 1, 8, file)==8){
- bitmap->bitmap[i]=0;
- for (j=7; j>=0;j--)
- if (buffer[7-j] == '1')
- bitmap->bitmap[i]|=(1<<j);
- }
- else
- return(GE_TOOSHORT);
- }
-
-#ifdef DEBUG
- /* Some programs writes here fileinfo */
- if (fread(buffer, 1, 1, file)==1) {
- fprintf(stdout, _("Fileinfo: %c"),buffer[0]);
- while (fread(buffer, 1, 1, file)==1) {
- if (buffer[0]!=0x0A) fprintf(stdout,_("%c"),buffer[0]);
- }
- fprintf(stdout, _("\n"));
- }
-#endif
-
- return(GE_NONE);
-}
-
-GSM_Error loadnsl(FILE *file, GSM_Bitmap *bitmap)
-{
-
- unsigned char block[6],buffer[505];
- int block_size;
-
- bitmap->size=0;
-
- while (fread(block,1,6,file)==6) {
-
- block_size=block[4]*256+block[5];
-
-#ifdef DEBUG
- fprintf(stdout,_("Block %c%c%c%c, size %i\n"),block[0],block[1],block[2],block[3],block_size);
-#endif
-
- if (!strncmp(block, "FORM", 4)) {
-#ifdef DEBUG
- fprintf(stdout,_(" File ID\n"));
-#endif
- } else
- {
- if (block_size>504) return(GE_INVALIDFILEFORMAT);
-
- if (block_size!=0) {
-
- fread(buffer,1,block_size,file);
- buffer[block_size]=0; //if it's string, we end it with \0
-
-#ifdef DEBUG
- if (!strncmp(block, "VERS", 4)) fprintf(stdout,_(" File saved by: %s\n"),buffer);
- if (!strncmp(block, "MODL", 4)) fprintf(stdout,_(" Logo saved from: %s\n"),buffer);
- if (!strncmp(block, "COMM", 4)) fprintf(stdout,_(" Phone was connected to COM port: %s\n"),buffer);
-#endif
-
- if (!strncmp(block, "NSLD", 4)) {
- bitmap->type=GSM_StartupLogo;
- bitmap->height=48;
- bitmap->width=84;
- bitmap->size=(bitmap->height*bitmap->width)/8;
-
- memcpy(bitmap->bitmap,buffer,bitmap->size);
-
-#ifdef DEBUG
- fprintf(stdout,_(" Startup logo (size %i)\n"),block_size);
-#endif
- }
- }
- }
- }
-
- if (bitmap->size==0) return(GE_TOOSHORT);
-
- return(GE_NONE);
-}
-
-GSM_Error loadnlm (FILE *file, GSM_Bitmap *bitmap)
-{
- unsigned char buffer[1000];
- int pos,pos2,x,y;
- div_t division;
-
- fread(buffer,1,5,file);
- fread(buffer,1,1,file);
-
- switch (buffer[0]) {
- case 0x00: bitmap->type=GSM_OperatorLogo; break;
- case 0x01: bitmap->type=GSM_CallerLogo; break;
- case 0x02: bitmap->type=GSM_StartupLogo; break;
- case 0x03: bitmap->type=GSM_PictureImage; break;
- default:
- return(GE_SUBFORMATNOTSUPPORTED);
- }
-
- fread(buffer,1,4,file);
- bitmap->width=buffer[1];
- bitmap->height=buffer[2];
-
- if (bitmap->type==GSM_StartupLogo && bitmap->width==96 && bitmap->height==65)
- bitmap->type=GSM_7110StartupLogo;
- if (bitmap->type==GSM_StartupLogo && bitmap->width==96 && bitmap->height==60)
- bitmap->type=GSM_6210StartupLogo;
- if (bitmap->type==GSM_OperatorLogo && bitmap->width==78 && bitmap->height==21)
- bitmap->type=GSM_7110OperatorLogo;
-
- bitmap->size=bitmap->width*bitmap->height/8;
-
- division=div(bitmap->width,8);
- if (division.rem!=0) division.quot++; /* For startup logos */
-
- if (fread(buffer,1,(division.quot*bitmap->height),file)!=(division.quot*bitmap->height))
- return(GE_TOOSHORT);
-
- GSM_ClearBitmap(bitmap);
-
- pos=0;pos2=7;
- for (y=0;y<bitmap->height;y++) {
- for (x=0;x<bitmap->width;x++) {
- if ((buffer[pos]&(1<<pos2))>0) GSM_SetPointBitmap(bitmap,x,y);
- pos2--;
- if (pos2<0) {pos2=7;pos++;} //going to new byte
- }
- if (pos2!=7) {pos2=7;pos++;} //for startup logos-new line means new byte
- }
-
- return (GE_NONE);
-}
-
-GSM_Error loadota(FILE *file, GSM_Bitmap *bitmap)
-{
-
- char buffer[4];
-
- fread(buffer,1,4,file);
-
- bitmap->width=buffer[1];
- bitmap->height=buffer[2];
- bitmap->size=bitmap->width*bitmap->height/8;
-
- if ((bitmap->height==48) && (bitmap->width==84)) {
- bitmap->type=GSM_StartupLogo;
- }
- else if ((bitmap->height==14) && (bitmap->width==72)) {
- bitmap->type=GSM_CallerLogo;
- }
- else {
-#ifdef DEBUG
- printf("Invalid Image Size (%dx%d).\n",bitmap->width,bitmap->height);
-#endif
- return GE_INVALIDIMAGESIZE;
- }
-
- if (fread(bitmap->bitmap,1,bitmap->size,file)!=bitmap->size)
- return(GE_TOOSHORT);
-
- return(GE_NONE);
-}
-
-GSM_Error GSM_SaveBitmapFile(char *FileName, GSM_Bitmap *bitmap)
-{
-
- FILE *file;
- bool done=false;
-
- file = fopen(FileName, "wb");
-
- if (!file)
- return(GE_CANTOPENFILE);
-
- if (strstr(FileName,".xpm")) { savexpm(file, bitmap); done=true; }
- if (strstr(FileName,".nlm")) { savenlm(file, bitmap); done=true; }
- if (strstr(FileName,".ngg")) { savengg(file, bitmap); done=true; }
- if (strstr(FileName,".nsl")) { savensl(file, bitmap); done=true; }
- if (strstr(FileName,".otb")) { saveota(file, bitmap); done=true; }
- if (strstr(FileName,".nol")) { savenol(file, bitmap); done=true; }
- if (strstr(FileName,".bmp") ||
- strstr(FileName,".ggp") ||
- strstr(FileName,".i61"))
- {
- savebmp(file, bitmap);
- done=true;
- }
-
- if (!done)
- {
- switch (bitmap->type) {
- case GSM_CallerLogo : savengg(file, bitmap); break;
- case GSM_OperatorLogo : savenol(file, bitmap); break;
- case GSM_7110OperatorLogo: savebmp(file, bitmap); break;
- case GSM_7110StartupLogo : savebmp(file, bitmap); break;
- case GSM_6210StartupLogo : savebmp(file, bitmap); break;
- case GSM_StartupLogo : savensl(file, bitmap); break;
- case GSM_PictureImage : savenlm(file, bitmap); break;
- case GSM_WelcomeNoteText : break;
- case GSM_DealerNoteText : break;
- case GSM_None : break;
- }
- }
-
- fclose(file);
-
- return GE_NONE;
-}
-
-void savexpm(FILE *file, GSM_Bitmap *bitmap)
-{
- int x,y;
-
- fprintf(file,_("/* XPM */\n"));
- fprintf(file,_("static char * ala_xpm[] = {\n"));
- fprintf(file,_("\"%i %i 2 1\",\n"),bitmap->width,bitmap->height);
- fprintf(file,_("\". s c m #000000 g4 #000000 g #000000 c #000000\",\n"));
- fprintf(file,_("\"# s c m #ffffff g4 #ffffff g #ffffff c #ffffff\",\n"));
-
- for (y=0;y<bitmap->height;y++) {
- fprintf(file,_("\""));
- for (x=0;x<bitmap->width;x++)
- if (GSM_IsPointBitmap(bitmap,x,y))
- fprintf(file,_("."));
- else
- fprintf(file,_("#"));
- fprintf(file,_("\""));
- if (y==bitmap->height-1)
- fprintf(file,_("};\n"));
- else
- fprintf(file,_(",\n"));
- }
-}
-
-/* Based on the article from the Polish Magazine "Bajtek" 11/92 */
- /* Marcin-Wiacek@Topnet.PL */
-void savebmp(FILE *file, GSM_Bitmap *bitmap)
-{
- int x,y,pos,i,sizeimage;
- unsigned char buffer[1];
- div_t division;
-
- unsigned char header[]={
-/*1'st header*/ 'B','M', /* BMP file ID */
- 0x00,0x00,0x00,0x00, /* Size of file */
- 0x00,0x00, /* Reserved for future use */
- 0x00,0x00, /* Reserved for future use */
- 62,0x00,0x00,0x00, /* Offset for image data */
-
-/*2'nd header*/ 40,0x00,0x00,0x00, /* Length of this part of header */
- 0x00,0x00,0x00,0x00, /* Width of image */
- 0x00,0x00,0x00,0x00, /* Height of image */
- 1,0x00, /* How many planes in target device */
- 1,0x00, /* How many colors in image. 1 means 2^1=2 colors */
- 0x00,0x00,0x00,0x00, /* Type of compression. 0 means no compression */
-/*Sometimes */ 0x00,0x00,0x00,0x00, /* Size of part with image data */
-/*ttttttt...*/ 0xE8,0x03,0x00,0x00, /* XPelsPerMeter */
-/*hhiiiiissss*/ 0xE8,0x03,0x00,0x00, /* YPelsPerMeter */
-/*part of header*/2,0x00,0x00,0x00, /* How many colors from palette is used */
-/*doesn't exist*/ 0x00,0x00,0x00,0x00, /* How many colors from palette is required to display image. 0 means all */
-
-/*Color palette*/ 0x00,0x00,0x00, /* First color in palette in Blue, Green, Red. Here white */
- 0x00, /* Each color in palette is end by 4'th byte */
- 102,204,102, /* Second color in palette in Blue, Green, Red. Here green */
- 0x00}; /* Each color in palette is end by 4'th byte */
-
- header[22]=bitmap->height;
- header[18]=bitmap->width;
-
- pos=7;
- sizeimage=0;
- for (y=bitmap->height-1;y>=0;y--) { //lines are written from the last to the first
- i=1;
- for (x=0;x<bitmap->width;x++) {
- if (pos==7) { //new byte !
- if (x!=0) sizeimage++;
- i++;
- if(i==5) i=1; //each line is written in multiply of 4 bytes
- }
- pos--;
- if (pos<0) pos=7; //going to new byte
- }
- pos=7; //going to new byte
- sizeimage++;
- if (i!=1) {
- while (i!=5) //each line is written in multiply of 4 bytes
- {
- sizeimage++;
- i++;
- }
- }
- }
-#ifdef DEBUG
- printf("Data size in BMP file: %i\n",sizeimage);
-#endif
- division=div(sizeimage,256);
- header[35]=division.quot;
- header[34]=sizeimage-(division.quot*256);
-
- sizeimage=sizeimage+sizeof(header);
-#ifdef DEBUG
- printf("Size of BMP file: %i\n",sizeimage);
-#endif
- division=div(sizeimage,256);
- header[3]=division.quot;
- header[2]=sizeimage-(division.quot*256);
-
- fwrite(header,1,sizeof(header),file);
-
- pos=7;
- for (y=bitmap->height-1;y>=0;y--) { //lines are written from the last to the first
- i=1;
- for (x=0;x<bitmap->width;x++) {
- if (pos==7) { //new byte !
- if (x!=0) fwrite(buffer, 1, sizeof(buffer), file);
- i++;
- if(i==5) i=1; //each line is written in multiply of 4 bytes
- buffer[0]=0;
- }
- if (!GSM_IsPointBitmap(bitmap,x,y)) buffer[0]|=(1<<pos);
- pos--;
- if (pos<0) pos=7; //going to new byte
- }
- pos=7; //going to new byte
- fwrite(buffer, 1, sizeof(buffer), file);
- if (i!=1) {
- while (i!=5) //each line is written in multiply of 4 bytes
- {
- buffer[0]=0;
- fwrite(buffer, 1, sizeof(buffer), file);
- i++;
- }
- }
- }
-}
-
-void savengg(FILE *file, GSM_Bitmap *bitmap)
-{
-
- char header[]={'N','G','G',0x00,0x01,0x00,
- 0x00,0x00, /* Width */
- 0x00,0x00, /* Height */
- 0x01,0x00,0x01,0x00,
- 0x00, /* Unknown.Can't be checksum - for */
- /* the same logo files can be different */
- 0x00};
-
- char buffer[8];
- int i,j;
- GSM_Bitmap copy;
-
- copy=*bitmap;
-
- GSM_ResizeBitmap(©,GSM_CallerLogo);
-
- header[6]=copy.width;
- header[8]=copy.height;
-
- fwrite(header,1,sizeof(header),file);
-
- for (i=0; i<copy.size; i++) {
- for (j=7; j>=0;j--)
- if ((copy.bitmap[i]&(1<<j))>0) {
- buffer[7-j] = '1';
- } else {
- buffer[7-j] = '0';
- }
- fwrite(buffer,1,8,file);
- }
-}
-
-void savenol(FILE *file, GSM_Bitmap *bitmap)
-{
-
- char header[]={'N','O','L',0x00,0x01,0x00,
- 0x00,0x00, /* MCC */
- 0x00,0x00, /* MNC */
- 0x00,0x00, /* Width */
- 0x00,0x00, /* Height */
- 0x01,0x00,0x01,0x00,
- 0x00, /* Unknown.Can't be checksum - for */
- /* the same logo files can be different */
- 0x00};
- char buffer[8];
- int i,j,country,net;
- GSM_Bitmap copy;
-
- copy=*bitmap;
-
- GSM_ResizeBitmap(©,GSM_OperatorLogo);
-
- sscanf(copy.netcode, "%d %d", &country, &net);
-
- header[6]=country%256;
- header[7]=country/256;
- header[8]=net%256;
- header[9]=net/256;
- header[10]=copy.width;
- header[12]=copy.height;
-
- fwrite(header,1,sizeof(header),file);
-
- for (i=0; i<copy.size; i++) {
- for (j=7; j>=0;j--)
- if ((copy.bitmap[i]&(1<<j))>0) {
- buffer[7-j] = '1';
- } else {
- buffer[7-j] = '0';
- }
- fwrite(buffer,1,8,file);
- }
-}
-
-void savensl(FILE *file, GSM_Bitmap *bitmap)
-{
-
- u8 header[]={'F','O','R','M', 0x01,0xFE, /* File ID block, size 1*256+0xFE=510*/
- 'N','S','L','D', 0x01,0xF8}; /* Startup Logo block, size 1*256+0xF8=504*/
- GSM_Bitmap copy;
-
- copy=*bitmap;
-
- GSM_ResizeBitmap(©,GSM_StartupLogo);
-
- fwrite(header,1,sizeof(header),file);
-
- fwrite(copy.bitmap,1,copy.size,file);
-}
-
-void saveota(FILE *file, GSM_Bitmap *bitmap)
-{
-
- char header[]={0x01,
- 0x00, /* Width */
- 0x00, /* Height */
- 0x01};
- GSM_Bitmap copy;
-
- copy=*bitmap;
-
- header[1]=copy.width;
- header[2]=copy.height;
-
- fwrite(header,1,sizeof(header),file);
-
- fwrite(copy.bitmap,1,copy.size,file);
-}
-
-void savenlm(FILE *file, GSM_Bitmap *bitmap)
-{
-
- char header[]={'N','L','M', /* Nokia Logo Manager file ID. */
- 0x20,
- 0x01,
- 0x00, /* 0x00 (OP), 0x01 (CLI), 0x02 (Startup), 0x03 (Picture)*/
- 0x00, /* Number of images inside file - 1. 0x01==2 images, 0x03==4 images, etc. */
- 0x00, /* Width. */
- 0x00, /* Height. */
- 0x01};
-
- unsigned char buffer[1000];
- int x,y,pos,pos2;
- div_t division;
- GSM_Bitmap copy;
-
- copy=*bitmap;
-
- switch (copy.type) {
- case GSM_OperatorLogo : header[5]=0x00; break;
- case GSM_7110OperatorLogo: header[5]=0x00; break;
- case GSM_CallerLogo : header[5]=0x01; break;
- case GSM_StartupLogo : header[5]=0x02; break;
- case GSM_7110StartupLogo : header[5]=0x02; break;
- case GSM_6210StartupLogo : header[5]=0x02; break;
- case GSM_PictureImage : header[5]=0x03; break;
- case GSM_WelcomeNoteText : break;
- case GSM_DealerNoteText : break;
- case GSM_None : break;
- }
-
- header[7]=copy.width;
- header[8]=copy.height;
-
- pos=0;pos2=7;
- for (y=0;y<copy.height;y++) {
- for (x=0;x<copy.width;x++) {
- if (pos2==7) buffer[pos]=0;
-
- if (GSM_IsPointBitmap(©,x,y)) buffer[pos]|=(1<<pos2);
-
- pos2--;
- if (pos2<0) {pos2=7;pos++;} //going to new line
- }
- if (pos2!=7) {pos2=7;pos++;} //for startup logos - new line with new byte
- }
-
- division=div(copy.width,8);
- if (division.rem!=0) division.quot++; /* For startup logos */
-
- fwrite(header,1,sizeof(header),file);
-
- fwrite(buffer,1,(division.quot*copy.height),file);
-}
-
-/* mode == 0 -> overwrite
- * mode == 1 -> ask
- * mode == 2 -> append
- */
-int GSM_SaveTextFile(char *FileName, char *text, int mode)
-{
-
- FILE *file;
-
- if (mode == 2) file = fopen(FileName, "a");
- else file = fopen(FileName, "w");
-
- if (!file) return -1;
-
- fprintf(file, "%s\n\n", text);
-
- fclose(file);
-
- return mode;
-}
-
-GSM_Error GSM_SaveBackupFile(char *FileName, GSM_Backup *backup)
-{
-
- FILE *file;
-
- file = fopen(FileName, "wb");
-
- if (!file) return(GE_CANTOPENFILE);
-
- savelmb(file, backup);
-
- fclose(file);
-
- return GE_NONE;
-}
-
-void savelmbstartupentry(FILE *file, GSM_Bitmap startup, GSM_Bitmap text, bool available)
-{
- /* Welcome note and logo header block */
- char req[1000] = {'W','E','L',' ', /*block identifier*/
- 00,00, /*block data size*/
- 0x02,00,00,00,00,00,
- 0x02}; /*number of blocks (like in 6110 frame)*/
-
- int count=13;
-
- if (!available) {
- } else {
- count=count+N6110_MakeStartupLogoFrame(req+13,startup);
- }
-
- req[count++]=0x02;
- req[count++]=strlen(text.text);
- memcpy(req+count,text.text,strlen(text.text));
- count=count+strlen(text.text);
-
- req[4]=(count-12)%256;
- req[5]=(count-12)/256;
-
- fwrite(req, 1, count, file);
-}
-
-void savelmbopentry(FILE *file, GSM_Bitmap bitmap)
-{
- /* Operator logo header block */
- char req[500] = {'O','L','G',' ', /*block identifier*/
- 0x88,00, /*block data size*/
- 0x02,00,00,00,00,00,00};
-
- int count=13;
-
- count=count+N6110_MakeOperatorLogoFrame(req+13,bitmap);
-
- req[4]=(count-7)%256;
- req[5]=(count-7)/256;
-
- req[17]=req[17]+5; //we fix size of logo block
-
- fwrite(req, 1, count, file);
-}
-
-/* Work in progress ! */
-void savelmbspeedentry(FILE *file, GSM_SpeedDial speed)
-{
- /* Speed dial header block */
- char req[] = {'S','P','D',' ', /*block identifier*/
- 0x03,00, /*block data size*/
- 0x02,00,
- 00, /*number of speed dial*/
- 00,0xFF,00,
- 00, /*number of speed dial*/
- 03, /*memory type. ME=02;SM=03*/
- 00}; /*number of location assigned to speed dial*/
-
- req[8]=req[12]=speed.Number;
-
- if (speed.MemoryType==GMT_ME) req[13]=2; //memory type=GMT_ME
-
- req[14]=speed.Location;
-
- fwrite(req, 1, 15, file);
-}
-
-void savelmbcallerentry(FILE *file, GSM_Bitmap bitmap)
-{
- char req[500] = {'C','G','R',' ', /*block identifier*/
- 00,00, /*block data size*/
- 02,00,
- 00, /*group number=0,1,etc.*/
- 00,00,00};
-
- int count=12;
-
- req[8]=bitmap.number;
-
- count=count+N6110_MakeCallerGroupFrame(req+12,bitmap);
-
- req[4]=(count-11)%256;
- req[5]=(count-11)/256;
-
- fwrite(req, 1, count, file);
-}
-
-void savelmbpbkentry(FILE *file, GSM_PhonebookEntry entry)
-{
- char req[500] = {'P','B','E','2', /*block identifier*/
- 00,00, /*block data size*/
- 00,00,
- 00, /*position of phonebook entry*/
- 00,
- 03, /*memory type. ME=02;SM=03*/
- 00,
- 00, /*position of phonebook entry*/
- 00,
- 03, /*memory type. ME=02;SM=03*/
- 00};
-
- int count = 16, blocks;
-
- req[8]=req[12]=entry.Location; //position of this entry
-
- if (entry.MemoryType==GMT_ME) req[10]=req[14]=2;
-
- /* There is NO full compatibility with files created by Logo Manager,
- anyway it works OK with files saved by this function - some bytes
- are probably random */
- count=count+N7110_MakePhonebookFrame(req+16, entry, &blocks);
-
- req[4]=(count-12)%256;
- req[5]=(count-12)/256;
-
- fwrite(req, 1, count, file);
-}
-
-void savelmb(FILE *file, GSM_Backup *backup)
-{
- int i;
-
- char LMBHeader[] = {'L','M','B',' '}; /*file identifier*/
-
- /* Phonebook header block */
- char PBKHeader[] = {'P','B','K',' ', /*block identifier*/
- 0x08,00, /*block data size*/
- 0x02,00,
- 03, /*memory type. ME=02;SM=03*/
- 00,00,00,
- 00,00, /*size of phonebook*/
- 14, /*max length of each position*/
- 00,00,00,00,00};
-
- fwrite(LMBHeader, 1, sizeof(LMBHeader), file); /* Write the header of the file. */
-
- if (backup->SIMPhonebookUsed!=0) {
- PBKHeader[12]=backup->SIMPhonebookSize%256;
- PBKHeader[13]=backup->SIMPhonebookSize/256;
- fwrite(PBKHeader, 1, sizeof(PBKHeader), file);
-
- for (i=0;i<backup->SIMPhonebookUsed;i++)
- savelmbpbkentry(file, backup->SIMPhonebook[i]);
- }
-
- if (backup->PhonePhonebookUsed!=0) {
- PBKHeader[8]=2; //memory type=GMT_ME
- PBKHeader[12]=backup->PhonePhonebookSize%256;
- PBKHeader[13]=backup->PhonePhonebookSize/256;
- PBKHeader[14]=0x16; //max size of one entry
- fwrite(PBKHeader, 1, sizeof(PBKHeader), file);
-
- for (i=0;i<backup->PhonePhonebookUsed;i++)
- savelmbpbkentry(file, backup->PhonePhonebook[i]);
- }
-
- if (backup->CallerAvailable)
- for (i=0;i<5;i++) savelmbcallerentry(file,backup->CallerGroups[i]);
-
- if (backup->SpeedAvailable)
- for (i=0;i<8;i++) savelmbspeedentry(file,backup->SpeedDials[i]);
-
- if (backup->OperatorLogoAvailable) savelmbopentry(file,backup->OperatorLogo);
-
- savelmbstartupentry(file,backup->StartupLogo,backup->StartupText,backup->StartupLogoAvailable);
-}
-
-GSM_Error loadlmb(FILE *file, GSM_Backup *backup)
-{
-
-// fread(buffer, 1, 6, file);
- return(GE_NONE);
-}
-
-GSM_Error GSM_ReadBackupFile(char *FileName, GSM_Backup *backup)
-{
-
- FILE *file;
- unsigned char buffer[300];
- GSM_Error error;
- GSM_Filetypes filetype=None;
-
- file = fopen(FileName, "rb");
-
- if (!file) return(GE_CANTOPENFILE);
-
- fread(buffer, 1, 4, file); /* Read the header of the file. */
-
- /* Attempt to identify filetype */
-
- if (memcmp(buffer, "LMB ",4)==0) { /* LMB files have 'LMB ' at the start */
- filetype=LMB;
- } else filetype=None;
-
- error=GE_NONE;
-
- rewind(file);
-
- switch (filetype) {
- case LMB: error=loadlmb(file,backup); fclose(file); break;
- default : error=GE_INVALIDFILEFORMAT;
- }
-
- return(error);
-}