void GSM_ResizeBitmap(GSM_Bitmap *dest, GSM_Bitmap *src, size_t width, size_t height) { size_t 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;x<endx;x++) { for (y=starty;y<endy;y++) { if (GSM_IsPointBitmap(src,x,y)) GSM_SetPointBitmap(dest,setx+x-startx,sety+y-starty); } } }
static GSM_Error loadnolngg(FILE *file, GSM_MultiBitmap *bitmap, gboolean nolformat) { unsigned char buffer[2000]; size_t i,h,w,x,y; size_t readbytes; readbytes = fread(buffer, 1, 6, file); if (readbytes != 6) return ERR_FILENOTSUPPORTED; if (bitmap->Bitmap[0].Type == GSM_None) bitmap->Bitmap[0].Type = GSM_CallerGroupLogo; if (nolformat) { readbytes = fread(buffer, 1, 4, file); if (readbytes != 4) return ERR_FILENOTSUPPORTED; 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; } readbytes = fread(buffer, 1, 4, file); if (readbytes != 4) return ERR_FILENOTSUPPORTED; 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. */ readbytes = fread(buffer, 1, 6, file); if (readbytes != 6) return ERR_FILENOTSUPPORTED; GSM_ClearBitmap(&bitmap->Bitmap[0]); x=0; y=0; for (i=0; i<w*h; i++) { if (fread(buffer, 1, 1, file)!=1) return ERR_FILENOTSUPPORTED; if (buffer[0]=='1') GSM_SetPointBitmap(&bitmap->Bitmap[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(NULL, "Fileinfo: %c",buffer[0]); while (fread(buffer, 1, 1, file)==1) { if (buffer[0]!=0x0A) dbgprintf(NULL, "%c",buffer[0]); } dbgprintf(NULL, "\n"); } #endif bitmap->Number = 1; return(ERR_NONE); }
void GSM_ReverseBitmap(GSM_Bitmap *Bitmap) { size_t x, y; for (x=0;x<Bitmap->BitmapWidth;x++) { for (y=0;y<Bitmap->BitmapHeight;y++) { if (GSM_IsPointBitmap(Bitmap,x,y)) { GSM_ClearPointBitmap(Bitmap, x, y); } else { GSM_SetPointBitmap(Bitmap, x, y); } } } }
void PHONE_DecodeBitmap(GSM_Phone_Bitmap_Types Type, char *buffer, GSM_Bitmap *Bitmap) { size_t 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->FileSystemPicture = 0; Bitmap->NetworkCode[0] = 0; Bitmap->Sender[0] = 0; Bitmap->Sender[1] = 0; Bitmap->ID = 0; Bitmap->Name[0] = 0; Bitmap->Name[1] = 0; 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); } } } }
int BitmapFromPython(PyObject * dict, GSM_Bitmap * entry) { char *s; int i, j; int w, h, cols, chars; char c, black = 0, transp = 0; char buffer[1000]; int x, y; PyObject *o; PyObject *item; int len; if (!PyDict_Check(dict)) { PyErr_Format(PyExc_ValueError, "Bitmap is not a dictionary"); return 0; } memset(entry, 0, sizeof(GSM_Bitmap)); s = GetCharFromDict(dict, "Type"); if (s == NULL) return 0; entry->Type = StringToBitmapType(s); if (entry->Type == 0) return 0; s = GetCharFromDict(dict, "NetworkCode"); if (s == NULL) { PyErr_Clear(); entry->NetworkCode[0] = 0; } else { mystrncpy(entry->NetworkCode, s, 6); } i = GetIntFromDict(dict, "Location"); if (i == INT_INVALID) { PyErr_Clear(); } else { entry->Location = i; } i = GetIntFromDict(dict, "BitmapEnabled"); if (i == INT_INVALID) { PyErr_Clear(); } else { entry->BitmapEnabled = i; } i = GetIntFromDict(dict, "DefaultName"); if (i == INT_INVALID) { PyErr_Clear(); } else { entry->DefaultName = i; } i = GetIntFromDict(dict, "DefaultBitmap"); if (i == INT_INVALID) { PyErr_Clear(); } else { entry->DefaultBitmap = i; } i = GetIntFromDict(dict, "DefaultRingtone"); if (i == INT_INVALID) { PyErr_Clear(); } else { entry->DefaultRingtone = i; } i = GetIntFromDict(dict, "RingtoneID"); if (i == INT_INVALID) { PyErr_Clear(); } else { entry->RingtoneID = i; } i = GetIntFromDict(dict, "ID"); if (i == INT_INVALID) { PyErr_Clear(); } else { entry->ID = i; } if (!CopyStringFromDict (dict, "Text", GSM_BITMAP_TEXT_LENGTH, entry->Text)) { PyErr_Clear(); entry->Text[0] = 0; entry->Text[1] = 0; } if (!CopyStringFromDict (dict, "Sender", GSM_MAX_NUMBER_LENGTH, entry->Sender)) { PyErr_Clear(); entry->Text[0] = 0; entry->Text[1] = 0; } o = PyDict_GetItemString(dict, "XPM"); if (o == NULL) { PyErr_Format(PyExc_ValueError, "Could not get XPM for bitmap!"); return 0; } if (!PyList_Check(o)) { PyErr_Format(PyExc_ValueError, "XPM isn't list!"); return 0; } len = PyList_Size(o); if (len < 3) { PyErr_Format(PyExc_ValueError, "XPM list too small!"); return 0; } #define GetString(s, x) \ item = PyList_GetItem(o, x);\ if (!PyString_Check(item)) {\ PyErr_Format(PyExc_ValueError, "XPM contains something different than string!");\ return 0;\ }\ \ s = PyString_AsString(item);\ if (s == NULL) {\ PyErr_Format(PyExc_ValueError, "XPM contains something different than string!");\ return 0;\ } GetString(s, 0); if (sscanf(s, "%d %d %d %d", &w, &h, &cols, &chars) != 4) { PyErr_Format(PyExc_ValueError, "Bad first XPM row"); return 0; } if (chars != 1 || cols != 2) { PyErr_Format(PyExc_ValueError, "Only two color XPM with one char per pixel supported"); return 0; } if (w > 255 || h > 255 || w < 0 || h < 0 || w * h / 8 > GSM_BITMAP_SIZE) { PyErr_Format(PyExc_ValueError, "Bad size of bitmap"); return 0; } entry->BitmapWidth = w; entry->BitmapHeight = h; for (i = 1; i < 3; i++) { GetString(s, i); if (sscanf(s, "%c c %999s", &c, buffer) != 2) { PyErr_Format(PyExc_ValueError, "Can not parse XPM line: '%s'", s); return 0; } j = 0; while (buffer[j] != 0) { buffer[j] = tolower((int)buffer[j]); j++; } if (strcmp(buffer, "none") == 0 || strcmp(buffer, "#fff") == 0 || strcmp(buffer, "#ffffff") == 0 || strcmp(buffer, "white") == 0) transp = c; else if (strcmp(buffer, "#000") == 0 || strcmp(buffer, "#000000") == 0 || strcmp(buffer, "black") == 0) black = c; else { PyErr_Format(PyExc_ValueError, "Only black and write are supported (guven was %s)", buffer); return 0; } } if (black == 0 || transp == 0) { PyErr_Format(PyExc_ValueError, "At least one XPM color was not found"); return 0; } for (y = 0; y < h; y++) { GetString(s, y + 3); if ((ssize_t) strlen(s) != w) { PyErr_Format(PyExc_ValueError, "XPM line has bad length: '%s'", s); return 0; } for (x = 0; x < w; x++) { if (s[x] == black) GSM_SetPointBitmap(entry, x, y); else if (s[x] == transp) GSM_ClearPointBitmap(entry, x, y); else { PyErr_Format(PyExc_ValueError, "Bad character in XPM data: '%c'", s[x]); return 0; } } } return 1; }
static GSM_Error loadnlm (FILE *file, GSM_MultiBitmap *bitmap) { unsigned char buffer[1000]; size_t pos,x,y,h,w,i,number; ssize_t pos2; div_t division; size_t readbytes; readbytes = fread(buffer,1,5,file); if (readbytes != 5) return ERR_FILENOTSUPPORTED; readbytes = fread(buffer,1,1,file); if (readbytes != 1) return ERR_FILENOTSUPPORTED; switch (buffer[0]) { case 0x00: dbgprintf(NULL, "Operator logo\n"); if (bitmap->Bitmap[0].Type == GSM_None) bitmap->Bitmap[0].Type = GSM_OperatorLogo; break; case 0x01: dbgprintf(NULL, "Caller logo\n"); if (bitmap->Bitmap[0].Type == GSM_None) bitmap->Bitmap[0].Type = GSM_CallerGroupLogo; break; case 0x02: dbgprintf(NULL, "Startup logo\n"); if (bitmap->Bitmap[0].Type == GSM_None) bitmap->Bitmap[0].Type = GSM_StartupLogo; break; case 0x03: dbgprintf(NULL, "Picture Image logo\n"); if (bitmap->Bitmap[0].Type == GSM_None) bitmap->Bitmap[0].Type = GSM_PictureImage; break; } bitmap->Number = 0; readbytes = fread(buffer,1,4,file); if (readbytes != 4) return ERR_FILENOTSUPPORTED; number = buffer[0] + 1; w = buffer[1]; h = buffer[2]; for (i=0;i<number;i++) { bitmap->Bitmap[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;y<h;y++) { for (x=0;x<w;x++) { if ((buffer[pos]&(1<<pos2))>0) { if (y<bitmap->Bitmap[i].BitmapHeight && x<bitmap->Bitmap[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 == GSM_MAX_MULTI_BITMAP) break; } return (ERR_NONE); }
GSM_Error BMP2Bitmap(unsigned char *buffer, FILE *file,GSM_Bitmap *bitmap) { gboolean first_white,isfile=FALSE; unsigned char buff[60]; size_t w,h,x,i,buffpos=0; ssize_t y, pos; size_t readbytes; #ifdef DEBUG int sizeimage=0; #endif if (bitmap->Type == GSM_None) bitmap->Type = GSM_StartupLogo; if (file!=NULL) isfile=TRUE; /* Read the header */ if (isfile) { readbytes = fread(buff, 1, 54, file); if (readbytes != 54) return ERR_FILENOTSUPPORTED; } else { memcpy(buff,buffer,54); } /* height and width of image in the file */ h=buff[22]+256*buff[21]; w=buff[18]+256*buff[17]; dbgprintf(NULL, "Image Size in BMP file: %ldx%ld\n", (long)w, (long)h); GSM_GetMaxBitmapWidthHeight(bitmap->Type, &bitmap->BitmapWidth, &bitmap->BitmapHeight); if (h<bitmap->BitmapHeight) bitmap->BitmapHeight=h; if (w<bitmap->BitmapWidth) bitmap->BitmapWidth=w; dbgprintf(NULL, "Height %ld %ld width %ld %ld\n", (long)h, (long)bitmap->BitmapHeight, (long)w, (long)bitmap->BitmapWidth); GSM_ClearBitmap(bitmap); #ifdef DEBUG dbgprintf(NULL, "Number of colors in BMP file: "); switch (buff[28]) { case 1 : dbgprintf(NULL, "2 (supported)\n"); break; case 4 : dbgprintf(NULL, "16 (NOT SUPPORTED)\n"); break; case 8 : dbgprintf(NULL, "256 (NOT SUPPORTED)\n"); break; case 24 : dbgprintf(NULL, "True Color (NOT SUPPORTED)\n"); break; default : dbgprintf(NULL, "unknown\n"); break; } #endif if (buff[28]!=1) { dbgprintf(NULL, "Wrong number of colors\n"); return ERR_FILENOTSUPPORTED; } #ifdef DEBUG dbgprintf(NULL, "Compression in BMP file: "); switch (buff[30]) { case 0 :dbgprintf(NULL, "no compression (supported)\n"); break; case 1 :dbgprintf(NULL, "RLE8 (NOT SUPPORTED)\n"); break; case 2 :dbgprintf(NULL, "RLE4 (NOT SUPPORTED)\n"); break; default :dbgprintf(NULL, "unknown\n"); break; } #endif if (buff[30]!=0) { dbgprintf(NULL, "Compression type not supported\n"); return ERR_FILENOTSUPPORTED; } /* Read palette */ if (isfile) { pos=buff[10]-54; readbytes = fread(buff, 1, pos, file); if (readbytes != (size_t)pos) return ERR_FILENOTSUPPORTED; } else { pos=buff[10]-54; buffpos=buff[10]; memcpy (buff,buffer+54,pos); } first_white = ((buff[6] * buff[5] * buff[4]) > (buff[2] * buff[1] * buff[0])); #ifdef DEBUG dbgprintf(NULL, "First color in BMP file: #%02x%02x%02x%s\n", buff[2], buff[1], buff[0], first_white ? " (used as white)" : " (used as black)" ); dbgprintf(NULL, "Second color in BMP file: #%02x%02x%02x%s\n", buff[6], buff[5], buff[4], !first_white ? " (used as white)" : " (used as black)" ); #endif pos=7; /* lines are written from the last to the first */ for (y=h-1;y>=0;y--) { i=1; for (x=0;x<w;x++) { /* new byte ! */ if (pos==7) { if (isfile) { readbytes = fread(buff, 1, 1, file); if (readbytes != 1) return ERR_FILENOTSUPPORTED; } else { memcpy (buff,buffer+buffpos,1); buffpos++; } #ifdef DEBUG sizeimage++; #endif i++; /* each line is written in multiply of 4 bytes */ if(i==5) i=1; } /* we have top left corner ! */ if (x<=bitmap->BitmapWidth && (size_t)y<=bitmap->BitmapHeight) { if (first_white) { if ((buff[0]&(1<<pos))<=0) GSM_SetPointBitmap(bitmap,x,y); } else { if ((buff[0]&(1<<pos))>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) { readbytes = fread(buff, 1, 1, file); if (readbytes != 1) return ERR_FILENOTSUPPORTED; } else { memcpy (buff,buffer+buffpos,1); buffpos++; } #ifdef DEBUG sizeimage++; #endif i++; } } } #ifdef DEBUG dbgprintf(NULL, "Data size in BMP file: %i\n",sizeimage); #endif return(ERR_NONE); }