Branch update for mygnokii2002_03_17_19_29nl
[gnokii.git] / common / files / gsm-filetypes.c
index b625e14..8e5fc39 100644 (file)
@@ -10,9 +10,6 @@
        
   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>
@@ -256,14 +253,13 @@ GSM_Error GSM_ReadVCalendarFile(char *FileName, GSM_CalendarNote *cnote, int *nu
 GSM_Error GSM_ReadBinRingtoneFile(char *FileName, GSM_BinRingtone *ringtone)
 {
   FILE *file;
+  int i;
 
   file = fopen(FileName, "rb");
 
   if (!file)
     return(GE_CANTOPENFILE);
 
-//  fseek(file,3474485,0);
-  
   ringtone->length=fread(ringtone->frame, 1, 500, file);
 
   fclose(file);
@@ -272,6 +268,13 @@ GSM_Error GSM_ReadBinRingtoneFile(char *FileName, GSM_BinRingtone *ringtone)
       ringtone->frame[2]!=0x0C || ringtone->frame[3]!=0x01)
     return GE_NOTSUPPORTED;
 
+  i=5;
+  while (ringtone->frame[i]!=0x00) {
+    ringtone->name[i-5]=ringtone->frame[i];
+    i++;
+  }
+  ringtone->name[i-5]=0x00;
+
   return GE_NONE;
 }
 
@@ -1019,7 +1022,7 @@ GSM_Error loadxpm(char *filename, GSM_Bitmap *bitmap)
 
   bitmap->height=image.height;
   bitmap->width=image.width;
-  bitmap->size=bitmap->height*bitmap->width/8;
+  bitmap->size=GSM_GetBitmapSize(bitmap);
 
   GSM_ClearBitmap(bitmap);
   
@@ -1080,8 +1083,7 @@ GSM_Error loadbmp(FILE *file, GSM_Bitmap *bitmap)
     bitmap->type=GSM_7110OperatorLogo;    
   }    
 
-       /* Gabo !!! */
-  bitmap->size=(bitmap->width*bitmap->height + 7)/8;
+  bitmap->size=GSM_GetBitmapSize(bitmap);
 
   GSM_ClearBitmap(bitmap);  
 
@@ -1188,7 +1190,7 @@ GSM_Error loadnol(FILE *file, GSM_Bitmap *bitmap)
   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;
+  bitmap->size=GSM_GetBitmapSize(bitmap);
 
   if ((bitmap->height!=14) || (bitmap->width!=72)) {
 #ifdef DEBUG
@@ -1236,7 +1238,7 @@ GSM_Error loadngg(FILE *file, GSM_Bitmap *bitmap)
   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;
+  bitmap->size=GSM_GetBitmapSize(bitmap);
   
   if ((bitmap->height!=14) || (bitmap->width!=72)) {
 #ifdef DEBUG
@@ -1311,7 +1313,7 @@ GSM_Error loadnsl(FILE *file, GSM_Bitmap *bitmap)
           bitmap->type=GSM_StartupLogo;
           bitmap->height=48;
           bitmap->width=84;
-          bitmap->size=(bitmap->height*bitmap->width)/8;
+          bitmap->size=GSM_GetBitmapSize(bitmap);
 
           memcpy(bitmap->bitmap,buffer,bitmap->size);
 
@@ -1357,7 +1359,7 @@ GSM_Error loadnlm (FILE *file, GSM_Bitmap *bitmap)
   if (bitmap->type==GSM_OperatorLogo && bitmap->width==78 && bitmap->height==21)
     bitmap->type=GSM_7110OperatorLogo;
 
-  bitmap->size=bitmap->width*bitmap->height/8;
+  bitmap->size=GSM_GetBitmapSize(bitmap);
 
   division=div(bitmap->width,8);
   if (division.rem!=0) division.quot++; /* For startup logos */
@@ -1389,7 +1391,6 @@ GSM_Error loadota(FILE *file, GSM_Bitmap *bitmap)
 
   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;
@@ -1403,6 +1404,8 @@ GSM_Error loadota(FILE *file, GSM_Bitmap *bitmap)
 #endif
     return GE_INVALIDIMAGESIZE;
   }
+
+  bitmap->size=GSM_GetBitmapSize(bitmap);
   
   if (fread(bitmap->bitmap,1,bitmap->size,file)!=bitmap->size)
     return(GE_TOOSHORT);
@@ -1794,6 +1797,7 @@ void savelmbstartupentry(FILE *file, GSM_Bitmap startup, GSM_Bitmap text, bool a
   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;
@@ -1819,16 +1823,25 @@ 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};
+                  0x02,00,00,00,00,00,
 
-  int count=13;
+                   00};
+
+  int count=13,i;
 
   count=count+N6110_MakeOperatorLogoFrame(req+13,bitmap);
 
-  req[4]=(count-7)%256;
-  req[5]=(count-7)/256;
+  if (bitmap.width!=0x48) {
+    req[4]=(count-7)%256;
+    req[5]=(count-7)/256;
+
+    for (i=1;i<=5;i++) req[count++]=0;
 
-  req[17]=req[17]+5; //we fix size of logo block
+    req[17]=req[17]+5; //we fix size of logo block
+  } else {
+    req[4]=(count-12)%256;
+    req[5]=(count-12)/256;
+  }
 
   fwrite(req, 1, count, file);
 }                   
@@ -1842,6 +1855,7 @@ void savelmbspeedentry(FILE *file, GSM_SpeedDial speed)
                 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*/
@@ -1869,8 +1883,10 @@ void savelmbcallerentry(FILE *file, GSM_Bitmap bitmap)
 
   count=count+N6110_MakeCallerGroupFrame(req+12,bitmap);
 
-  req[4]=(count-11)%256;
-  req[5]=(count-11)/256;
+  req[count++]=0;
+
+  req[4]=(count-12)%256;
+  req[5]=(count-12)/256;
 
   fwrite(req, 1, count, file);
 }                   
@@ -1880,25 +1896,22 @@ 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,              
+                  00,00,           /*position of phonebook entry*/                              
                   03,              /*memory type. ME=02;SM=03*/
                   00,
-                   00,              /*position of phonebook entry*/
-                   00,
+
+                   00,00,           /*position of phonebook entry*/                   
                    03,              /*memory type. ME=02;SM=03*/
                    00};
 
   int count = 16, blocks;
 
-  req[8]=req[12]=entry.Location; //position of this entry
+  req[9]=req[13] = (entry.Location >> 8);
+  req[8]=req[12] = entry.Location & 0xff;
 
   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);
+  count=count+N7110_EncodePhonebookFrame(req+16, entry, &blocks);
 
   req[4]=(count-12)%256;
   req[5]=(count-12)/256;
@@ -1918,6 +1931,7 @@ void savelmb(FILE *file, GSM_Backup *backup)
                      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};
@@ -1947,18 +1961,233 @@ void savelmb(FILE *file, GSM_Backup *backup)
   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->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);
 }
 
+void loadlmbcallerentry(unsigned char *buffer, unsigned char *buffer2, GSM_Backup *backup, int number)
+{ 
+  int i;
+
+  backup->CallerAvailable=true;
+
+#ifdef DEBUG
+  fprintf(stdout, _("  Number %i, name \""), buffer2[0]);
+  for (i=0;i<buffer2[1];i++) {
+    fprintf(stdout, _("%c"), buffer2[i+2]);
+  }
+  fprintf(stdout, _("\"\n"));
+
+  fprintf(stdout,_("  Ringtone ID=%i\n"), buffer2[i+2]);
+
+  if (buffer2[i+3]==1) fprintf(stdout,_("  Logo enabled\n"));
+                  else fprintf(stdout,_("  Logo disabled\n")); 
+#endif
+
+  backup->CallerGroups[number].number=buffer2[0];
+  backup->CallerGroups[number].type=GSM_CallerLogo;
+
+  for (i=0;i<buffer2[1];i++) {
+    backup->CallerGroups[number].text[i]=buffer2[i+2];
+  }
+  backup->CallerGroups[number].text[buffer2[1]]=0;
+       
+  backup->CallerGroups[number].ringtone=buffer2[i+2];
+       
+  backup->CallerGroups[number].enabled=false;
+  if (buffer2[i+3]==1) backup->CallerGroups[number].enabled=true;
+
+  backup->CallerGroups[number].width=buffer2[i+7];
+  backup->CallerGroups[number].height=buffer2[i+8];
+               
+  backup->CallerGroups[number].size=GSM_GetBitmapSize(&backup->CallerGroups[number]);
+      
+  memcpy(backup->CallerGroups[number].bitmap,buffer2+i+10,backup->CallerGroups[number].size);
+
+#ifdef DEBUG
+  fprintf(stdout, _("  Caller logo"));
+  fprintf(stdout, _(" (size %ix%i - %i bytes)\n"),
+     backup->CallerGroups[number].width, backup->CallerGroups[number].height, backup->CallerGroups[number].size);
+  GSM_PrintBitmap(&backup->CallerGroups[number]);
+#endif
+
+}                   
+
+void loadlmbopentry(unsigned char *buffer, unsigned char *buffer2, GSM_Backup *backup)
+{  
+  backup->OperatorLogoAvailable=true;
+
+  DecodeNetworkCode(buffer2+1, backup->OperatorLogo.netcode);
+
+  backup->OperatorLogo.text[0]=0;
+
+  backup->OperatorLogo.width=buffer2[7];
+  backup->OperatorLogo.height=buffer2[8];
+
+  backup->OperatorLogo.type=GSM_OperatorLogo;      
+  if (backup->OperatorLogo.width==78) backup->OperatorLogo.type=GSM_7110OperatorLogo;      
+
+  backup->OperatorLogo.size=GSM_GetBitmapSize(&backup->OperatorLogo);      
+
+#ifdef DEBUG
+  fprintf(stdout, _("  GSM operator logo (size %ix%i - %i bytes) for %s (%s) network.\n"),
+       backup->OperatorLogo.width, backup->OperatorLogo.height,
+       backup->OperatorLogo.size, backup->OperatorLogo.netcode,
+       GSM_GetNetworkName(backup->OperatorLogo.netcode));
+#endif
+
+  memcpy(backup->OperatorLogo.bitmap,buffer2+10,backup->OperatorLogo.size);
+
+#ifdef DEBUG
+  GSM_PrintBitmap(&backup->OperatorLogo);
+#endif
+
+}                   
+
+void loadlmbpbkentry(unsigned char *buffer, unsigned char *buffer2, GSM_Backup *backup)
+{
+  GSM_PhonebookEntry pbk;
+
+#ifdef DEBUG
+  fprintf(stdout,_("  Memory : "));
+  switch(buffer[10]) {
+    case 2: fprintf(stdout, _("(internal)\n"));break;
+    case 3: fprintf(stdout, _("(sim)\n"));break;
+    default: fprintf(stdout, _("(unknown)\n"));break;
+  }
+  fprintf(stdout,_("  Location : %i\n"),buffer2[0]+buffer2[1]*256);
+#endif
+
+  pbk.Empty = true;
+  pbk.Group = 5;     /* 5 = no group as 6110 */
+  pbk.Name[0] = 0;
+  pbk.Number[0] = 0;
+  pbk.SubEntriesCount = 0;
+
+  N7110_DecodePhonebookFrame(&pbk,buffer2+4,(buffer[4]+buffer[5]*256)-4);
+
+  pbk.MemoryType=GMT_SM;
+  if (buffer[10]==2) pbk.MemoryType=GMT_ME;
+
+  pbk.Location=buffer2[0]+256*buffer2[1];
+
+  if (buffer[10]==2) backup->PhonePhonebook[backup->PhonePhonebookUsed++]=pbk;
+                else backup->SIMPhonebook  [backup->SIMPhonebookUsed++]  =pbk;
+}
+
+void loadlmbstartupentry(unsigned char *buffer, unsigned char *buffer2, GSM_Backup *backup)
+{
+  int i,j;
+#ifdef DEBUG
+  int z;
+#endif
+
+  j=1;
+  for (i=0;i<buffer2[0];i++) {
+    switch (buffer2[j++]) {
+      case 1:
+        backup->StartupLogoAvailable=true;
+       backup->StartupLogo.height=buffer2[j++];
+       backup->StartupLogo.width=buffer2[j++];
+       backup->StartupLogo.text[0]=0;
+       backup->StartupLogo.type=GSM_StartupLogo;
+        switch (backup->StartupLogo.height) {
+          case 65:backup->StartupLogo.type=GSM_7110StartupLogo;break;
+          case 60:backup->StartupLogo.type=GSM_6210StartupLogo;break;
+        }
+        backup->StartupLogo.size=GSM_GetBitmapSize(&backup->StartupLogo);
+           
+#ifdef DEBUG
+        fprintf(stdout, _("  Block 1 - startup logo (size %ix%i - %i bytes)\n"),
+              backup->StartupLogo.width, backup->StartupLogo.height, backup->StartupLogo.size);
+#endif
+
+        memcpy(backup->StartupLogo.bitmap,buffer2+j,backup->StartupLogo.size);
+#ifdef DEBUG
+        GSM_PrintBitmap(&backup->StartupLogo);
+#endif
+       j=j+backup->StartupLogo.size;
+
+       break;            
+      case 2:
+
+#ifdef DEBUG
+        fprintf(stdout, _("  Block 2 - welcome note \""));
+        for (z=0;z<buffer2[j];z++) fprintf(stdout, _("%c"),buffer2[j+z+1]);
+       fprintf(stdout, _("\"\n"));
+#endif
+        break;
+      default:
+#ifdef DEBUG
+        fprintf(stdout, _("  Unknown block %02x\n"),buffer2[j]);
+#endif
+       break;
+    }
+  }
+}
+
 GSM_Error loadlmb(FILE *file, GSM_Backup *backup)
 {
+#ifdef DEBUG
+  int i;
+#endif
+  int number=0;
+
+  unsigned char buffer[12], buffer2[1000]; //for data from file
+
+  fread(buffer, 1, 4, file); /* Read the header of the file. */
+
+  while (fread(buffer, 1, 12, file)==12) { //while we have something to read
+
+#ifdef DEBUG
+    /* Info about block in the file */
+    fprintf(stdout, _("Block \""));
+    for (i=0;i<4;i++) {fprintf(stdout, _("%c"),buffer[i]);}
+    fprintf(stdout, _("\" ("));
+    if (memcmp(buffer, "PBK ",4)==0) {fprintf(stdout, _("Phonebook"));      } else {
+    if (memcmp(buffer, "PBE2",4)==0) {fprintf(stdout, _("Phonebook entry"));} else {
+    if (memcmp(buffer, "CGR ",4)==0) {fprintf(stdout, _("Caller group"));   } else {      
+    if (memcmp(buffer, "SPD ",4)==0) {fprintf(stdout, _("Speed dial"));     } else {      
+    if (memcmp(buffer, "OLG ",4)==0) {fprintf(stdout, _("Operator logo"));  } else {      
+    if (memcmp(buffer, "WEL ",4)==0) {fprintf(stdout, _("Startup logo and welcome text")); } else {      
+                                      fprintf(stdout, _("uknown - ignored"));}}}}}}
+
+    fprintf(stdout, _(") - length %i\n"), buffer[4]+buffer[5]*256);
+#endif
+      
+    fread(buffer2, 1, buffer[4]+buffer[5]*256, file); //reading block data
+
+#ifdef DEBUG
+    if (memcmp(buffer, "PBK ",4)==0) { //phonebook
+      fprintf(stdout, _("  Size of phonebook %i, type %i "),(buffer2[0]+buffer2[1]*256),buffer[8]);
+      switch(buffer[8]) {
+       case 2 : fprintf(stdout, _("(internal)"));break;
+       case 3 : fprintf(stdout, _("(sim)"))     ;break;
+       default: fprintf(stdout, _("(unknown)")) ;break;
+      }
+      fprintf(stdout, _(", length of each position - %i\n"),buffer2[2]);
+    }
+#endif        
+
+    if (memcmp(buffer, "PBE2",4)==0) //phonebook entry        
+      loadlmbpbkentry(buffer,buffer2,backup);
+
+    if (memcmp(buffer, "CGR ",4)==0) { //caller groups
+      loadlmbcallerentry(buffer,buffer2,backup,number);
+      number++;
+    }
+
+    if (memcmp(buffer, "OLG ",4)==0) //operator logo
+      loadlmbopentry(buffer,buffer2,backup);
+
+    if (memcmp(buffer, "WEL ",4)==0) //welcome blocks
+      loadlmbstartupentry(buffer,buffer2,backup);
+  }
 
-//  fread(buffer, 1, 6, file);
   return(GE_NONE);
 }
 
@@ -1986,6 +2215,14 @@ GSM_Error GSM_ReadBackupFile(char *FileName, GSM_Backup *backup)
   
   rewind(file);
 
+  backup->PhonePhonebookUsed=0;
+  backup->SIMPhonebookUsed=0;
+  backup->StartupLogoAvailable=false;
+  backup->StartupText.text[0]=0;
+  backup->OperatorLogoAvailable=false;
+  backup->CallerAvailable=false;
+  backup->SpeedAvailable=false;
+
   switch (filetype) {
     case LMB: error=loadlmb(file,backup); fclose(file); break;
     default : error=GE_INVALIDFILEFORMAT;
@@ -1993,3 +2230,19 @@ GSM_Error GSM_ReadBackupFile(char *FileName, GSM_Backup *backup)
 
   return(error);
 }
+
+GSM_Error GSM_SaveBinRingtoneFile(char *FileName, GSM_BinRingtone *ringtone)
+{
+
+  FILE *file;
+
+  file = fopen(FileName, "wb");
+      
+  if (!file) return(GE_CANTOPENFILE);
+       
+  fwrite(ringtone->frame, 1, ringtone->length, file);          
+
+  fclose(file);
+   
+  return GE_NONE;
+}