summaryrefslogtreecommitdiffabout
path: root/gammu/emb/common/service/gsmlogo.c
Side-by-side diff
Diffstat (limited to 'gammu/emb/common/service/gsmlogo.c') (more/less context) (show whitespace changes)
-rw-r--r--gammu/emb/common/service/gsmlogo.c47
1 files changed, 41 insertions, 6 deletions
diff --git a/gammu/emb/common/service/gsmlogo.c b/gammu/emb/common/service/gsmlogo.c
index c992915..7c19967 100644
--- a/gammu/emb/common/service/gsmlogo.c
+++ b/gammu/emb/common/service/gsmlogo.c
@@ -1,52 +1,53 @@
/* (c) 2001-2004 by Marcin Wiacek */
#include <string.h>
#include <stdlib.h>
+#include <sys/stat.h>
#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:
@@ -116,96 +117,97 @@ static void PHONE_SetPointBitmap(GSM_Phone_Bitmap_Types Type, char *buffer, int
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;x<Bitmap->BitmapWidth;x++) {
for (y=0;y<Bitmap->BitmapHeight;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;x<width;x++) {
for (y=0;y<height;y++) {
if (GSM_IsPointBitmap(&dest,x,y)) PHONE_SetPointBitmap(Type, buffer, x, y, width, height);
}
}
}
void GSM_GetMaxBitmapWidthHeight(GSM_Bitmap_Types Type, unsigned char *width, unsigned char *height)
{
switch (Type) {
case GSM_CallerGroupLogo: *width=72; *height=14; break;
case GSM_OperatorLogo : *width=101;*height=21; break;
case GSM_StartupLogo : *width=96; *height=65; break;
case GSM_PictureImage : *width=72; *height=28; break;
default : break;
}
}
void GSM_SetPointBitmap(GSM_Bitmap *bmp, int x, int y)
@@ -581,107 +583,107 @@ static GSM_Error savexpm(FILE *file, GSM_MultiBitmap *bitmap)
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")) {
+ if (mystrcasestr(FileName,".nlm")) {
error=savenlm(file,bitmap);
- } else if (strstr(FileName,".ngg")) {
+ } else if (mystrcasestr(FileName,".ngg")) {
error=savengg(file,bitmap);
- } else if (strstr(FileName,".nol")) {
+ } else if (mystrcasestr(FileName,".nol")) {
error=savenol(file,bitmap);
- } else if (strstr(FileName,".xpm")) {
+ } else if (mystrcasestr(FileName,".xpm")) {
error=savexpm(file,bitmap);
- } else if (strstr(FileName,".nsl")) {
+ } else if (mystrcasestr(FileName,".nsl")) {
error=savensl(file,bitmap);
- } else if (strstr(FileName,".wbmp")) {
+ } 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 (h<bitmap->BitmapHeight) bitmap->BitmapHeight=h;
if (w<bitmap->BitmapWidth) 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
@@ -910,94 +912,127 @@ static GSM_Error loadnsl(FILE *file, GSM_MultiBitmap *bitmap)
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:
*/