From 88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22 Mon Sep 17 00:00:00 2001 From: zautrix Date: Sat, 07 Aug 2004 17:24:40 +0000 Subject: Initial revision --- (limited to 'gammu/emb/common/service/gsmlogo.c') diff --git a/gammu/emb/common/service/gsmlogo.c b/gammu/emb/common/service/gsmlogo.c new file mode 100644 index 0000000..c992915 --- a/dev/null +++ b/gammu/emb/common/service/gsmlogo.c @@ -0,0 +1,1003 @@ +/* (c) 2001-2004 by Marcin Wiacek */ + +#include +#include + +#include "../misc/misc.h" +#include "../misc/coding/coding.h" +#include "gsmlogo.h" +#include "gsmnet.h" + +void PHONE_GetBitmapWidthHeight(GSM_Phone_Bitmap_Types Type, int *width, int *height) +{ + *width = 0; + *height = 0; + switch (Type) { + case GSM_EMSSmallPicture : *width=8; *height=8; break; + case GSM_EMSMediumPicture : *width=16; *height=16; break; + case GSM_EMSBigPicture : *width=32; *height=32; break; + case GSM_NokiaOperatorLogo : + case GSM_NokiaCallerLogo : *width=72; *height=14; break; + case GSM_NokiaPictureImage : *width=72; *height=28; break; + case GSM_Nokia7110OperatorLogo : + case GSM_Nokia6510OperatorLogo : *width=78; *height=21; break; + case GSM_NokiaStartupLogo : *width=84; *height=48; break; + case GSM_Nokia6210StartupLogo : *width=96; *height=60; break; + case GSM_Nokia7110StartupLogo : *width=96; *height=65; break; + case GSM_EMSVariablePicture : break; + case GSM_AlcatelBMMIPicture : break; + } +} + +int PHONE_GetBitmapSize(GSM_Phone_Bitmap_Types Type, int Width, int Height) +{ + int width, height, x; + + PHONE_GetBitmapWidthHeight(Type, &width, &height); + if (width == 0 && height == 0) { + width = Width; + height = Height; + } + switch (Type) { + case GSM_Nokia6510OperatorLogo: + x = width * height; + return x/8 + (x%8 > 0); + case GSM_Nokia7110OperatorLogo: + return (width*height + 7)/8; + case GSM_NokiaStartupLogo: + case GSM_NokiaOperatorLogo: + case GSM_NokiaCallerLogo: + case GSM_NokiaPictureImage: + case GSM_EMSSmallPicture: + case GSM_EMSMediumPicture: + case GSM_EMSBigPicture: + case GSM_EMSVariablePicture: + return height*width/8; + case GSM_Nokia7110StartupLogo: + case GSM_Nokia6210StartupLogo: + return (height+7)/8*width; + case GSM_AlcatelBMMIPicture: + return width*((height+7)/8); + } + return 0; +} + +static bool PHONE_IsPointBitmap(GSM_Phone_Bitmap_Types Type, char *buffer, int x, int y, int width, int height) +{ + int i=0, pixel; + + switch (Type) { + case GSM_NokiaStartupLogo: + case GSM_Nokia6210StartupLogo: + case GSM_Nokia7110StartupLogo: + case GSM_Nokia6510OperatorLogo: + i=(buffer[(y/8*width) + x] & 1<<(y%8)); + break; + case GSM_NokiaOperatorLogo: + case GSM_Nokia7110OperatorLogo: + case GSM_NokiaCallerLogo: + case GSM_EMSVariablePicture: + case GSM_EMSSmallPicture: + case GSM_EMSMediumPicture: + case GSM_EMSBigPicture: + pixel=width*y + x; + i=(buffer[pixel/8] & 1<<(7-(pixel%8))); + break; + case GSM_NokiaPictureImage: + i=(buffer[9*y + x/8] & 1<<(7-(x%8))); + break; + case GSM_AlcatelBMMIPicture: + break; + } + if (i) return true; else return false; +} + +static void PHONE_SetPointBitmap(GSM_Phone_Bitmap_Types Type, char *buffer, int x, int y, int width, int height) +{ + int pixel; + + switch (Type) { + case GSM_NokiaStartupLogo: + case GSM_Nokia6210StartupLogo: + case GSM_Nokia7110StartupLogo: + case GSM_Nokia6510OperatorLogo: + buffer[(y/8*width)+x] |= 1 << (y%8); + break; + case GSM_NokiaOperatorLogo: + case GSM_Nokia7110OperatorLogo: + case GSM_NokiaCallerLogo: + case GSM_EMSSmallPicture: + case GSM_EMSMediumPicture: + case GSM_EMSBigPicture: + case GSM_EMSVariablePicture: + pixel = width*y + x; + buffer[pixel/8] |= 1 << (7-(pixel%8)); + break; + case GSM_NokiaPictureImage: + buffer[9*y + x/8] |= 1 << (7-(x%8)); + break; + case GSM_AlcatelBMMIPicture: + pixel = height / 8; + if ((height % 8) != 0) pixel++; + buffer[pixel*x + y/8] |= 1 << (7 - (y%8)); + break; + } +} + +void PHONE_DecodeBitmap(GSM_Phone_Bitmap_Types Type, char *buffer, GSM_Bitmap *Bitmap) +{ + int width, height, x,y; + + PHONE_GetBitmapWidthHeight(Type, &width, &height); + if (Type != GSM_Nokia6510OperatorLogo && Type != GSM_Nokia7110OperatorLogo && Type != GSM_EMSVariablePicture) { + Bitmap->BitmapHeight = height; + Bitmap->BitmapWidth = width; + } + switch (Type) { + case GSM_NokiaOperatorLogo : + case GSM_Nokia7110OperatorLogo : + case GSM_Nokia6510OperatorLogo : Bitmap->Type=GSM_OperatorLogo; break; + case GSM_NokiaCallerLogo : Bitmap->Type=GSM_CallerGroupLogo; break; + case GSM_AlcatelBMMIPicture : + case GSM_NokiaStartupLogo : + case GSM_Nokia7110StartupLogo : + case GSM_Nokia6210StartupLogo : Bitmap->Type=GSM_StartupLogo; break; + case GSM_NokiaPictureImage : + case GSM_EMSVariablePicture : + case GSM_EMSSmallPicture : + case GSM_EMSMediumPicture : + case GSM_EMSBigPicture : Bitmap->Type=GSM_PictureImage; break; + } + + Bitmap->Location = 0; + Bitmap->Text[0] = 0; + Bitmap->Text[1] = 0; + Bitmap->BitmapEnabled = false; + Bitmap->DefaultName = false; + Bitmap->DefaultBitmap = false; + Bitmap->DefaultRingtone = false; + Bitmap->RingtoneID = 0; + Bitmap->NetworkCode[0] = 0; + Bitmap->Sender[0] = 0; + Bitmap->Sender[1] = 0; + Bitmap->ID = 0; + + GSM_ClearBitmap(Bitmap); + for (x=0;xBitmapWidth;x++) { + for (y=0;yBitmapHeight;y++) { + if (PHONE_IsPointBitmap(Type, buffer, x, y, Bitmap->BitmapWidth, Bitmap->BitmapHeight)) { + GSM_SetPointBitmap(Bitmap,x,y); + } + } + } +} + +void PHONE_ClearBitmap(GSM_Phone_Bitmap_Types Type, char *buffer, int width, int height) +{ + memset(buffer,0,PHONE_GetBitmapSize(Type,width,height)); +} + +void PHONE_EncodeBitmap(GSM_Phone_Bitmap_Types Type, char *buffer, GSM_Bitmap *Bitmap) +{ + int width, height, x, y; + GSM_Bitmap dest; + + PHONE_GetBitmapWidthHeight(Type, &width, &height); + if (width == 0 && height == 0) { + width = Bitmap->BitmapWidth; + height = Bitmap->BitmapHeight; + } + GSM_ResizeBitmap(&dest, Bitmap, width, height); + PHONE_ClearBitmap(Type, buffer, width, height); + + for (x=0;xBitmapPoints,y*bmp->BitmapWidth+x); +} + +void GSM_ClearPointBitmap(GSM_Bitmap *bmp, int x, int y) +{ + ClearBit(bmp->BitmapPoints,y*bmp->BitmapWidth+x); +} + +bool GSM_IsPointBitmap(GSM_Bitmap *bmp, int x, int y) +{ + if (GetBit(bmp->BitmapPoints,y*bmp->BitmapWidth+x)) return true; else return false; +} + +void GSM_ClearBitmap(GSM_Bitmap *bmp) +{ + memset(bmp->BitmapPoints,0,GSM_GetBitmapSize(bmp)); +} + +int GSM_GetBitmapSize(GSM_Bitmap *bmp) +{ + return bmp->BitmapWidth*bmp->BitmapHeight/8+1; +} + +void GSM_PrintBitmap(FILE *file, GSM_Bitmap *bitmap) +{ + int x,y; + + for (y=0;yBitmapHeight;y++) { + for (x=0;xBitmapWidth;x++) { + if (GSM_IsPointBitmap(bitmap,x,y)) { + fprintf(file,"#"); + } else { + fprintf(file," "); + } + } + fprintf(file,"\n"); + } +} + +void GSM_ReverseBitmap(GSM_Bitmap *Bitmap) +{ + int x, y; + + for (x=0;xBitmapWidth;x++) { + for (y=0;yBitmapHeight;y++) { + if (GSM_IsPointBitmap(Bitmap,x,y)) { + GSM_ClearPointBitmap(Bitmap, x, y); + } else { + GSM_SetPointBitmap(Bitmap, x, y); + } + } + } +} + +void GSM_ResizeBitmap(GSM_Bitmap *dest, GSM_Bitmap *src, int width, int height) +{ + int startx=0,endx=0,setx=0, starty=0,endy=0,sety=0, x, y; + + if (src->BitmapWidth<=width) { + startx = 0; + endx = src->BitmapWidth; + setx = (width-src->BitmapWidth)/2; + } else { + startx = (src->BitmapWidth-width)/2; + endx = startx + width; + setx = 0; + } + if (src->BitmapHeight<=height) { + starty = 0; + endy = src->BitmapHeight; + sety = (height-src->BitmapHeight)/2; + } else { + starty = (src->BitmapHeight-height)/2; + endy = starty + height; + sety = 0; + } + dest->BitmapHeight = height; + dest->BitmapWidth = width; + GSM_ClearBitmap(dest); + for (x=startx;xBitmapHeight; + header[18]=bitmap->BitmapWidth; + + pos = 7; + sizeimage = 0; + /*lines are written from the last to the first*/ + for (y=bitmap->BitmapHeight-1;y>=0;y--) { + i=1; + for (x=0;xBitmapWidth;x++) { + /*new byte !*/ + if (pos==7) { + if (x!=0) sizeimage++; + i++; + /*each line is written in multiply of 4 bytes*/ + if(i==5) i=1; + } + pos--; + /*going to new byte*/ + if (pos<0) pos=7; + } + /*going to new byte*/ + pos=7; + sizeimage++; + if (i!=1) { + /*each line is written in multiply of 4 bytes*/ + while (i!=5) { + sizeimage++; + i++; + } + } + } + dbgprintf("Data size in BMP file: %i\n",sizeimage); + division=div(sizeimage,256); + header[35]=division.quot; + header[34]=sizeimage-(division.quot*256); + sizeimage=sizeimage+sizeof(header); + dbgprintf("Size of BMP file: %i\n",sizeimage); + division=div(sizeimage,256); + header[3]=division.quot; + header[2]=sizeimage-(division.quot*256); + + if (isfile) { + fwrite(header,1,sizeof(header),file); + } else { + memcpy(buffer,header,sizeof(header)); + buffpos += sizeof(header); + } + + pos=7; + /*lines are written from the last to the first*/ + for (y=bitmap->BitmapHeight-1;y>=0;y--) { + i=1; + for (x=0;xBitmapWidth;x++) { + /*new byte !*/ + if (pos==7) { + if (x!=0) { + if (isfile) { + fwrite(buff, 1, sizeof(buff), file); + } else { + memcpy (buffer+buffpos,buff,1); + buffpos++; + } + } + i++; + /*each line is written in multiply of 4 bytes*/ + if(i==5) i=1; + buff[0]=0; + } + if (!GSM_IsPointBitmap(bitmap,x,y)) buff[0]|=(1<Bitmap[0]); + return error; +} + +static void PrivSaveNLMWBMP(FILE *file, GSM_Bitmap *Bitmap) +{ + unsigned char buffer[1000]; + int x,y,pos,pos2; + div_t division; + + pos=0;pos2=7; + for (y=0;yBitmapHeight;y++) { + for (x=0;xBitmapWidth;x++) { + if (pos2==7) buffer[pos]=0; + if (GSM_IsPointBitmap(Bitmap,x,y)) buffer[pos]|=(1<BitmapWidth,8); + /* For startup logos */ + if (division.rem!=0) division.quot++; + + fwrite(buffer,1,(division.quot*Bitmap->BitmapHeight),file); +} + +static GSM_Error savenlm(FILE *file, GSM_MultiBitmap *bitmap) +{ + int i; + char header[]={ + 'N','L','M',' ', /* Nokia Logo Manager file ID. */ + 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}; + + switch (bitmap->Bitmap[0].Type) { + case GSM_OperatorLogo : header[5]=0x00; break; + case GSM_CallerGroupLogo : header[5]=0x01; break; + case GSM_StartupLogo : header[5]=0x02; break; + case GSM_PictureImage : header[5]=0x03; break; + default : return ERR_UNKNOWN; + } + header[6] = bitmap->Number - 1; + header[7] = bitmap->Bitmap[0].BitmapWidth; + header[8] = bitmap->Bitmap[0].BitmapHeight; + fwrite(header,1,sizeof(header),file); + + for (i=0;iNumber;i++) { + PrivSaveNLMWBMP(file, &bitmap->Bitmap[i]); + } + + return ERR_NONE; +} + +static void PrivSaveNGGNOL(FILE *file, GSM_MultiBitmap *bitmap) +{ + char buffer[GSM_BITMAP_SIZE]; + int x,y,current=0; + + for (y=0;yBitmap[0].BitmapHeight;y++) { + for (x=0;xBitmap[0].BitmapWidth;x++) { + if (GSM_IsPointBitmap(&bitmap->Bitmap[0],x,y)) { + buffer[current++] = '1'; + } else { + buffer[current++] = '0'; + } + } + } + fwrite(buffer,1,current,file); +} + +static GSM_Error savengg(FILE *file, GSM_MultiBitmap *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}; + + header[6] = bitmap->Bitmap[0].BitmapWidth; + header[8] = bitmap->Bitmap[0].BitmapHeight; + fwrite(header,1,sizeof(header),file); + + PrivSaveNGGNOL(file,bitmap); + + return ERR_NONE; +} + +static GSM_Error savenol(FILE *file, GSM_MultiBitmap *bitmap) +{ + int country,net; + 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}; + + if (bitmap->Bitmap[0].Type == GSM_OperatorLogo) sscanf(bitmap->Bitmap[0].NetworkCode, "%d %d", &country, &net); + + header[6] = country%256; + header[7] = country/256; + header[8] = net%256; + header[9] = net/256; + header[10] = bitmap->Bitmap[0].BitmapWidth; + header[12] = bitmap->Bitmap[0].BitmapHeight; + fwrite(header,1,sizeof(header),file); + + PrivSaveNGGNOL(file,bitmap); + + return ERR_NONE; +} + +static GSM_Error savexpm(FILE *file, GSM_MultiBitmap *bitmap) +{ + int x,y; + + fprintf(file,"/* XPM */\n"); + fprintf(file,"static char * ala_xpm[] = {\n"); + fprintf(file,"\"%i %i 2 1\",\n",bitmap->Bitmap[0].BitmapWidth,bitmap->Bitmap[0].BitmapHeight); + 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;yBitmap[0].BitmapHeight;y++) { + fprintf(file,"\""); + for (x=0;xBitmap[0].BitmapWidth;x++) + if (GSM_IsPointBitmap(&bitmap->Bitmap[0],x,y)) { + fprintf(file,"."); + } else { + fprintf(file,"#"); + } + fprintf(file,"\""); + if (y==bitmap->Bitmap[0].BitmapHeight-1) { + fprintf(file,"};\n"); + } else { + fprintf(file,",\n"); + } + } + + return ERR_NONE; +} + +static GSM_Error savensl(FILE *file, GSM_MultiBitmap *bitmap) +{ + char buffer[GSM_BITMAP_SIZE]; + unsigned char 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*/ + + fwrite(header,1,sizeof(header),file); + PHONE_EncodeBitmap(GSM_NokiaStartupLogo, buffer, &bitmap->Bitmap[0]); + fwrite(buffer,1,PHONE_GetBitmapSize(GSM_NokiaStartupLogo,0,0),file); + + return ERR_NONE; +} + +static GSM_Error savewbmp(FILE *file, GSM_MultiBitmap *bitmap) +{ + unsigned char buffer[4]; + + buffer[0] = 0x00; + buffer[1] = 0x00; + buffer[2] = bitmap->Bitmap[0].BitmapWidth; + buffer[3] = bitmap->Bitmap[0].BitmapHeight; + fwrite(buffer,1,4,file); + + PrivSaveNLMWBMP(file, &bitmap->Bitmap[0]); + + return ERR_NONE; +} + +GSM_Error GSM_SaveBitmapFile(char *FileName, GSM_MultiBitmap *bitmap) +{ + FILE *file; + GSM_Error error=ERR_NONE; + + file = fopen(FileName, "wb"); + if (file == NULL) return ERR_CANTOPENFILE; + + /* Attempt to identify filetype */ + if (strstr(FileName,".nlm")) { + error=savenlm(file,bitmap); + } else if (strstr(FileName,".ngg")) { + error=savengg(file,bitmap); + } else if (strstr(FileName,".nol")) { + error=savenol(file,bitmap); + } else if (strstr(FileName,".xpm")) { + error=savexpm(file,bitmap); + } else if (strstr(FileName,".nsl")) { + error=savensl(file,bitmap); + } else if (strstr(FileName,".wbmp")) { + error=savewbmp(file,bitmap); + } else { + error=savebmp(file,bitmap); + } + fclose(file); + + return error; +} + +GSM_Error BMP2Bitmap(unsigned char *buffer, FILE *file,GSM_Bitmap *bitmap) +{ + bool first_white,isfile=false; + unsigned char buff[34]; + int w,h,pos,y,x,i,buffpos=0; +#ifdef DEBUG + int sizeimage=0; +#endif + + if (bitmap->Type == GSM_None) bitmap->Type = GSM_StartupLogo; + if (file!=NULL) isfile=true; + if (isfile) { + fread(buff, 1, 34, file); + } else { + memcpy(buff,buffer,34); + } + + /* height and width of image in the file */ + h=buff[22]+256*buff[21]; + w=buff[18]+256*buff[17]; + dbgprintf("Image Size in BMP file: %dx%d\n",w,h); + + GSM_GetMaxBitmapWidthHeight(bitmap->Type, &bitmap->BitmapWidth, &bitmap->BitmapHeight); + if (hBitmapHeight) bitmap->BitmapHeight=h; + if (wBitmapWidth) bitmap->BitmapWidth=w; + dbgprintf("Height %i %i, width %i %i\n",h,bitmap->BitmapHeight,w,bitmap->BitmapWidth); + + GSM_ClearBitmap(bitmap); + +#ifdef DEBUG + dbgprintf("Number of colors in BMP file: "); + switch (buff[28]) { + case 1 : dbgprintf("2 (supported)\n"); break; + case 4 : dbgprintf("16 (NOT SUPPORTED)\n"); break; + case 8 : dbgprintf("256 (NOT SUPPORTED)\n"); break; + case 24 : dbgprintf("True Color (NOT SUPPORTED)\n"); break; + default : dbgprintf("unknown\n"); break; + } +#endif + if (buff[28]!=1) { + dbgprintf("Wrong number of colors\n"); + return ERR_FILENOTSUPPORTED; + } + +#ifdef DEBUG + dbgprintf("Compression in BMP file: "); + switch (buff[30]) { + case 0 :dbgprintf("no compression (supported)\n"); break; + case 1 :dbgprintf("RLE8 (NOT SUPPORTED)\n"); break; + case 2 :dbgprintf("RLE4 (NOT SUPPORTED)\n"); break; + default :dbgprintf("unknown\n"); break; + } +#endif + if (buff[30]!=0) { + dbgprintf("Compression type not supported\n"); + return ERR_FILENOTSUPPORTED; + } + + /* read rest of header (if exists) and color palette */ + if (isfile) { + pos=buff[10]-34; + fread(buff, 1, pos, file); + } else { + pos=buff[10]-34; + buffpos=buff[10]; + memcpy (buff,buffer+34,pos); + } + +#ifdef DEBUG + dbgprintf("First color in BMP file: %i %i %i ",buff[pos-8], buff[pos-7], buff[pos-6]); + if (buff[pos-8]==0 && buff[pos-7]==0 && buff[pos-6]==0) dbgprintf("(white)"); + if (buff[pos-8]==0xFF && buff[pos-7]==0xFF && buff[pos-6]==0xFF) dbgprintf("(black)"); + if (buff[pos-8]==102 && buff[pos-7]==204 && buff[pos-6]==102) dbgprintf("(green)"); + dbgprintf("\n"); + dbgprintf("Second color in BMP file: %i %i %i ",buff[pos-38], buff[pos-37], buff[pos-36]); + if (buff[pos-4]==0 && buff[pos-3]==0 && buff[pos-2]==0) dbgprintf("(white)"); + if (buff[pos-4]==0xFF && buff[pos-3]==0xFF && buff[pos-2]==0xFF) dbgprintf("(black)"); + dbgprintf("\n"); +#endif + first_white=true; + if (buff[pos-8]!=0 || buff[pos-7]!=0 || buff[pos-6]!=0) first_white=false; + + pos=7; + /* lines are written from the last to the first */ + for (y=h-1;y>=0;y--) { i=1; + for (x=0;xBitmapWidth && y<=bitmap->BitmapHeight) { if (first_white) { + if ((buff[0]&(1<0) GSM_SetPointBitmap(bitmap,x,y); + } + } + pos--; + /* going to new byte */ + if (pos<0) pos=7; + } + /* going to new byte */ + pos=7; + if (i!=1) { + /* each line is written in multiply of 4 bytes */ + while (i!=5) { + if (isfile) { + fread(buff, 1, 1, file); + } else { + memcpy (buff,buffer+buffpos,1); + buffpos++; + } +#ifdef DEBUG + sizeimage++; +#endif + i++; + } + } + } +#ifdef DEBUG + dbgprintf("Data size in BMP file: %i\n",sizeimage); +#endif + return(ERR_NONE); +} + +static GSM_Error loadbmp(FILE *file, GSM_MultiBitmap *bitmap) +{ + GSM_Error error; + + error=BMP2Bitmap(NULL,file,&bitmap->Bitmap[0]); + bitmap->Number = 1; + return error; +} + +static GSM_Error loadnlm (FILE *file, GSM_MultiBitmap *bitmap) +{ + unsigned char buffer[1000]; + int pos,pos2,x,y,h,w,i,number; + div_t division; + + fread(buffer,1,5,file); + + fread(buffer,1,1,file); + switch (buffer[0]) { + case 0x00: + dbgprintf("Operator logo\n"); + if (bitmap->Bitmap[0].Type == GSM_None) bitmap->Bitmap[0].Type = GSM_OperatorLogo; + break; + case 0x01: + dbgprintf("Caller logo\n"); + if (bitmap->Bitmap[0].Type == GSM_None) bitmap->Bitmap[0].Type = GSM_CallerGroupLogo; + break; + case 0x02: + dbgprintf("Startup logo\n"); + if (bitmap->Bitmap[0].Type == GSM_None) bitmap->Bitmap[0].Type = GSM_StartupLogo; + break; + case 0x03: + dbgprintf("Picture Image logo\n"); + if (bitmap->Bitmap[0].Type == GSM_None) bitmap->Bitmap[0].Type = GSM_PictureImage; + break; + } + + bitmap->Number = 0; + fread(buffer,1,4,file); + number = buffer[0] + 1; + w = buffer[1]; + h = buffer[2]; + for (i=0;iBitmap[i].Type = bitmap->Bitmap[0].Type; + GSM_GetMaxBitmapWidthHeight(bitmap->Bitmap[i].Type, &bitmap->Bitmap[i].BitmapWidth, &bitmap->Bitmap[i].BitmapHeight); + if (h < bitmap->Bitmap[i].BitmapHeight) bitmap->Bitmap[i].BitmapHeight = h; + if (w < bitmap->Bitmap[i].BitmapWidth) bitmap->Bitmap[i].BitmapWidth = w; + + division=div(w,8); + /* For startup logos */ + if (division.rem!=0) division.quot++; + if (fread(buffer,1,(division.quot*h),file)!=(unsigned int)(division.quot*h)) return ERR_UNKNOWN; + + GSM_ClearBitmap(&bitmap->Bitmap[i]); + + pos=0;pos2=7; + for (y=0;y0) { + if (yBitmap[i].BitmapHeight && xBitmap[i].BitmapWidth) GSM_SetPointBitmap(&bitmap->Bitmap[i],x,y); + } + pos2--; + /* going to new byte */ + if (pos2<0) {pos2=7;pos++;} + } + /* for startup logos-new line means new byte */ + if (pos2!=7) {pos2=7;pos++;} + } + bitmap->Number++; + if (bitmap->Number == MAX_MULTI_BITMAP) break; + } + return (ERR_NONE); +} + +static GSM_Error loadnolngg(FILE *file, GSM_MultiBitmap *bitmap, bool nolformat) +{ + unsigned char buffer[2000]; + int i,h,w,x,y; + + fread(buffer, 1, 6, file); + + if (bitmap->Bitmap[0].Type == GSM_None) bitmap->Bitmap[0].Type = GSM_CallerGroupLogo; + if (nolformat) { + fread(buffer, 1, 4, file); + sprintf(bitmap->Bitmap[0].NetworkCode, "%d %02d", buffer[0]+256*buffer[1], buffer[2]); + if (bitmap->Bitmap[0].Type == GSM_None) bitmap->Bitmap[0].Type = GSM_OperatorLogo; + } + + fread(buffer, 1, 4, file); + w = buffer[0]; + h = buffer[2]; + GSM_GetMaxBitmapWidthHeight(bitmap->Bitmap[0].Type, &bitmap->Bitmap[0].BitmapWidth, &bitmap->Bitmap[0].BitmapHeight); + if (h < bitmap->Bitmap[0].BitmapHeight) bitmap->Bitmap[0].BitmapHeight = h; + if (w < bitmap->Bitmap[0].BitmapWidth) bitmap->Bitmap[0].BitmapWidth = w; + + /* Unknown bytes. */ + fread(buffer, 1, 6, file); + + GSM_ClearBitmap(&bitmap->Bitmap[0]); + + x=0; y=0; + for (i=0; iBitmap[0],x,y); + x++; + if (x==w) {x=0; y++;} + } + +#ifdef DEBUG + /* Some programs writes here fileinfo */ + if (fread(buffer, 1, 1, file)==1) { + dbgprintf("Fileinfo: %c",buffer[0]); + while (fread(buffer, 1, 1, file)==1) { + if (buffer[0]!=0x0A) dbgprintf("%c",buffer[0]); + } + dbgprintf("\n"); + } +#endif + bitmap->Number = 1; + return(ERR_NONE); +} + +static GSM_Error loadnsl(FILE *file, GSM_MultiBitmap *bitmap) +{ + unsigned char block[6],buffer[505]; + int block_size; + GSM_Bitmap_Types OldType; + + while (fread(block,1,6,file)==6) { + block_size = block[4]*256 + block[5]; + dbgprintf("Block %c%c%c%c, size %i\n",block[0],block[1],block[2],block[3],block_size); + if (!strncmp(block, "FORM", 4)) { + dbgprintf("File ID\n"); + } else { + if (block_size>504) return ERR_UNKNOWN; + if (block_size!=0) { + fread(buffer,1,block_size,file); + /* if it's string, we end it with 0 */ + buffer[block_size]=0; +#ifdef DEBUG + if (!strncmp(block, "VERS", 4)) dbgprintf("File saved by: %s\n",buffer); + if (!strncmp(block, "MODL", 4)) dbgprintf("Logo saved from: %s\n",buffer); + if (!strncmp(block, "COMM", 4)) dbgprintf("Phone was connected to COM port: %s\n",buffer); +#endif + if (!strncmp(block, "NSLD", 4)) { + bitmap->Bitmap[0].BitmapHeight = 48; + bitmap->Bitmap[0].BitmapWidth = 84; + OldType = bitmap->Bitmap[0].Type; + PHONE_DecodeBitmap(GSM_NokiaStartupLogo, buffer, &bitmap->Bitmap[0]); + if (OldType != GSM_None) bitmap->Bitmap[0].Type = OldType; + dbgprintf("Startup logo (size %i)\n",block_size); + } + } + } + } + bitmap->Number = 1; + return(ERR_NONE); +} + +static GSM_Error loadwbmp(FILE *file, GSM_MultiBitmap *bitmap) +{ + unsigned char buffer[10000]; + + fread(buffer,1,4,file); + bitmap->Bitmap[0].BitmapWidth = buffer[2]; + bitmap->Bitmap[0].BitmapHeight = buffer[3]; + bitmap->Number = 1; + + fread(buffer,1,10000,file); + PHONE_DecodeBitmap(GSM_Nokia7110OperatorLogo, buffer, &bitmap->Bitmap[0]); + GSM_ReverseBitmap(&bitmap->Bitmap[0]); + + return ERR_NONE; +} + +GSM_Error GSM_ReadBitmapFile(char *FileName, GSM_MultiBitmap *bitmap) +{ + FILE *file; + unsigned char buffer[300]; + + file = fopen(FileName, "rb"); + if (file == NULL) return ERR_CANTOPENFILE; + + fread(buffer, 1, 9, file); /* Read the header of the file. */ + rewind(file); + + bitmap->Bitmap[0].DefaultBitmap = false; + + /* Attempt to identify filetype */ + if (memcmp(buffer, "BM",2)==0) { + return loadbmp(file,bitmap); + } else if (buffer[0] == 0x00 && buffer[1] == 0x00) { + return loadwbmp(file,bitmap); + } else if (memcmp(buffer, "NLM",3)==0) { + return loadnlm(file,bitmap); + } else if (memcmp(buffer, "NOL",3)==0) { + return loadnolngg(file,bitmap,true); + } else if (memcmp(buffer, "NGG",3)==0) { + return loadnolngg(file,bitmap,false); + } else if (memcmp(buffer, "FORM",4)==0) { + return loadnsl(file,bitmap); + } + return ERR_UNKNOWN; +} + +void NOKIA_CopyBitmap(GSM_Phone_Bitmap_Types Type, GSM_Bitmap *Bitmap, char *Buffer, int *Length) +{ + int Width, Height; + + Buffer[(*Length)++] = 0x00; + PHONE_GetBitmapWidthHeight(Type, &Width, &Height); + Buffer[(*Length)++] = Width; + Buffer[(*Length)++] = Height; + Buffer[(*Length)++] = 0x01; + PHONE_EncodeBitmap(Type, Buffer + (*Length), Bitmap); + (*Length) = (*Length) + PHONE_GetBitmapSize(Type,0,0); +} + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ -- cgit v0.9.0.2