/* (c) 2001-2004 by Marcin Wiacek */ #include #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; Bitmap->Name = NULL; 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 (mystrcasestr(FileName,".nlm")) { error=savenlm(file,bitmap); } else if (mystrcasestr(FileName,".ngg")) { error=savengg(file,bitmap); } else if (mystrcasestr(FileName,".nol")) { error=savenol(file,bitmap); } else if (mystrcasestr(FileName,".xpm")) { error=savexpm(file,bitmap); } else if (mystrcasestr(FileName,".nsl")) { error=savensl(file,bitmap); } else if (mystrcasestr(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; } static GSM_Error loadgif(FILE *file, GSM_MultiBitmap *bitmap) { GSM_Bitmap *bmap = &bitmap->Bitmap[0]; char *buffer; struct stat st; int length; dbgprintf("loading gif file\n"); fstat(fileno(file), &st); bmap->BinaryPic.Length = length = st.st_size; bmap->BinaryPic.Buffer = buffer = malloc(length); if (bmap->BinaryPic.Buffer == NULL) return ERR_MOREMEMORY; fread(buffer, 1, length, file); dbgprintf("Length %i name \"%s\"\n", length, DecodeUnicodeString(bmap->Name)); bmap->Type = GSM_PictureBinary; bmap->BinaryPic.Type = PICTURE_GIF; bmap->BitmapWidth = 256 * buffer[7] + buffer[6]; bmap->BitmapHeight = 256 * buffer[9] + buffer[8]; bitmap->Number = 1; 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; bitmap->Bitmap[0].Name = malloc((strlen(FileName) + 1) * 2); if (bitmap->Bitmap[0].Name == NULL) return ERR_MOREMEMORY; EncodeUnicode(bitmap->Bitmap[0].Name, FileName, strlen(FileName)); 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); } else if (memcmp(buffer, "GIF",3)==0) { return loadgif(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: */