Main Page   File List   Globals  

libinfo.c

Go to the documentation of this file.
00001 
00029 #include "libinfo.h"
00030 
00031 
00032 /* XPM Transparency */
00033 # ifdef LI_OUTPUT_XPM
00034 
00035 int transparent = -1;
00036 
00037 #endif
00038 
00040 u8 mwb_palette[] = {
00041     149, 149, 149,
00042     0, 0, 0,
00043     255, 255, 255,
00044     59, 103, 162,
00045     123, 123, 123,
00046     175, 175, 175,
00047     170, 144, 124,
00048     255, 169, 151
00049 };
00050 
00051 /*************************************************************************
00052 **                              USER INTERFACE                          **
00053 *************************************************************************/
00054 
00055 
00056 /*************************************************
00057 **              LIReadDefIcon                 
00058 *************************************************/
00068 int LIReadDefIcon(char *filename)
00069 {
00070     if((fileIcon = fopen(filename, "rb")) == NULL){
00071         LIErrorString = "Error opening input file";
00072         return -1;
00073     }
00074 
00075     if(ReadHeader() == -1)
00076         return -1;
00077     if(ReadIcon(LI_UNSELECTED) == -1)
00078         return -1;
00079     if(image2)
00080         if(ReadIcon(LI_SELECTED) == -1)
00081             return -1;
00082 
00083     fclose(fileIcon);
00084     return 0;
00085 }
00086 
00087 /*************************************************
00088 **              LIReadNewIcon                 
00089 *************************************************/
00103 int LIReadNewIcon(char *filename)
00104 {
00105     if((fileIcon = fopen(filename, "rb")) == NULL){
00106         LIErrorString = "Error opening input file";
00107         return -1;
00108     }
00109 
00110     if(ReadHeader() == -1)
00111         return -1;
00112     if(ReadIcon(LI_UNSELECTED) == -1)
00113         return -1;
00114     if(image2)
00115         if(ReadIcon(LI_SELECTED) == -1)
00116             return -1;
00117     if(tool)
00118         free(ReadString());
00119     if(StartTooltypes() == -1)
00120         return -1;
00121     if(ReadNewicon(LI_UNSELECTED, "IM1=") == -1)
00122         return -1;
00123     if(ReadNewicon(LI_SELECTED, "IM2=") == -1)
00124         return -1;
00125 
00126     fclose(fileIcon);
00127     return 0;
00128 }
00129 
00130 
00131 #ifdef LI_OUTPUT_XPM
00132 /*************************************************
00133 **              LISetXPMTransparency              
00134 *************************************************/
00144 int LISetXPMTransparency(int colour)
00145 {
00146     if(colour >= LINumColours){
00147         LIErrorString = "Can't set colour transparency.";
00148         return -1;
00149     }
00150     transparent = colour;
00151 
00152     return 0;
00153 }
00154 
00155 
00156 /*************************************************
00157 **                  LIWriteXPM              
00158 *************************************************/
00170 int LIWriteXPM(char *filename, int image)
00171 {
00172     return WriteXPM(filename, LIWidth, LIHeight, LINumColours, LIPalette, image);
00173 }
00174 
00175 #endif
00176 #ifdef LI_OUTPUT_PPM
00177 
00178 /*************************************************
00179 **                  LIWritePPM              
00180 *************************************************/
00192 int LIWritePPM(char *filename, int image)
00193 {
00194     return WritePPM(filename, LIWidth, LIHeight, LINumColours, LIPalette, image);
00195 }
00196 
00197 #endif
00198 
00199 /**************************************************
00200 **                   LICleanUp                   
00201 **************************************************/
00209 void LICleanUp(void)
00210 {
00211     free(LIPalette);
00212     free(LIBitmapSelected);
00213     free(LIBitmapUnselected);
00214 }
00215 
00216 
00217 /**************************************************
00218 **                 LIGetVersion                 
00219 **************************************************/
00226 char *LIGetVersion(void)
00227 {
00228     return LIBINFO_VERSION;
00229 }
00230 
00231 
00232 
00233 /**************************************************
00234 **                    LIGetDate                   
00235 **************************************************/
00242 char *LIGetDate(void)
00243 {
00244     return LIBINFO_DATE;
00245 }
00246 
00247 
00248 /**************************************************
00249 **                 LIGetCopyright                 
00250 **************************************************/
00257 char *LIGetCopyright(void)
00258 {
00259     return LIBINFO_COPYRIGHT;
00260 }
00261 
00262 /*************************************************************************
00263 **                              INTERNAL STUFF                          **
00264 *************************************************************************/
00265 
00266 u16 Get16(u8 *p)
00267 {
00268     return(*p * 256) + *(p+1);
00269 }
00270 
00271 u32 Get32(u8 *p)
00272 {
00273     return((*p * 256 + *(p+1)) * 256 + *(p+2)) * 256 + *(p+3);
00274 }
00275 
00276 int Read8(u8 *buf, int len)
00277 {
00278     len = fread(buf, 1, len, fileIcon);
00279     return len;
00280 }
00281 
00282 int ReadHeader()
00283 {
00284     u8 header[0x4e];
00285 
00286     if(!Read8(header, sizeof header)){
00287         LIErrorString = "Unable to read header.";
00288         return -1;
00289     }
00290     magic = Get16(header);
00291     if(magic != 0xE310){
00292         LIErrorString = "Wrong magic number.";
00293         return -1;
00294     }
00295     version = Get16(header + 0x02);
00296     if(version != 1){
00297         LIErrorString = "Wrong version.";
00298         return -1;
00299     }
00300     type = Get16(header + 0x30);
00301     image1 = Get32(header + 0x16);
00302     if(!image1){
00303         LIErrorString = "Could not find image.";
00304         return -1;
00305     }
00306     image2 = Get32(header + 0x1A);
00307     tool = Get32(header + 0x32);
00308     if(Get32(header + 0x42)) {
00309         u8 drawer[0x38];
00310         if(!Read8(drawer, sizeof drawer)){
00311             LIErrorString = "Unable to read drawer.";
00312             return -1;
00313         }
00314     }
00315     return 0;
00316 }
00317 
00318 #ifdef LI_OUTPUT_PPM
00319 
00320 int WritePPM(char *filename, int width, int height, int ncols, u8 *palette, int image)
00321 {
00322     int     x, y;
00323     u8      *bitmap;
00324     FILE    *file;
00325 
00326     if(image == LI_UNSELECTED)
00327         bitmap = LIBitmapUnselected;
00328     else
00329         bitmap = LIBitmapSelected;
00330 
00331     if((file = fopen(filename, "w")) == NULL){
00332         LIErrorString = "Unable to create PPM file.";
00333         return -1;
00334     }
00335     fprintf(file, "P6 %d %d 255\n", width, height);
00336     for(y = 0; y < height; y++) {
00337         for(x = 0; x < width; x++) {
00338             u8 c = 3 * bitmap[x + y*width];
00339             putc(palette[c], file);
00340             putc(palette[c+1], file);
00341             putc(palette[c+2], file);
00342         }
00343     }
00344     if(fclose(file) != 0){
00345         LIErrorString = "Error closing PPM file.";
00346         return -1;
00347     }
00348     return 0;
00349 }
00350 
00351 #endif
00352 #ifdef LI_OUTPUT_XPM
00353 
00354 int WriteXPM(char *filename, int width, int height, int ncols, u8 *palette, int image)
00355 {
00356     int     x, y;
00357     u8      *bitmap;
00358     FILE    *file;
00359 
00360     if(image == LI_UNSELECTED)
00361         bitmap = LIBitmapUnselected;
00362     else
00363         bitmap = LIBitmapSelected;
00364 
00365     if((file = fopen(filename, "w")) == NULL){
00366         LIErrorString = "Unable to create XPM file.";
00367         return -1;
00368     }
00369     fprintf(file, "/* XPM */\nstatic char * amigaicon_xpm[] = {\n"
00370         "\"%d %d %d 1\",\n", width, height, ncols);
00371     for(x = 0; x < ncols; x++)
00372         if (x == transparent)
00373             fprintf(file, "\"%c\tc None\",\n", 'A' + x);
00374         else
00375             fprintf(file, "\"%c\tc #%02x%02x%02x\",\n",
00376                 'A' + x,
00377                 palette[x * 3], palette[x * 3 + 1], palette[x * 3 + 2]);
00378     for(y = 0; y < height; y++) {
00379         fprintf(file, "%c", '"');
00380         for(x = 0; x < width; x++){
00381             putc('A' + bitmap[x + y*width], file);
00382         }
00383         if(y == height - 1)
00384             fprintf(file, "%s", "\"};");
00385         else
00386             fprintf(file, "%s", "\",\n");
00387     }
00388     if(fclose(file) != 0){
00389         LIErrorString = "Error closing XPM file.";
00390         return -1;
00391     }
00392     return 0;
00393 }
00394 
00395 #endif
00396 
00397 int ReadIcon(int image)
00398 {
00399     u8 header[0x14];
00400     u16 width, height, depth;
00401     u8 plane_pick, plane_onoff;
00402     u8 *row, *bitmap;
00403     int rwidth;
00404     int ib;
00405 
00406     if (!Read8(header, sizeof header)){
00407         LIErrorString = "Unable to read icon header.";
00408         return -1;
00409     }
00410     width = Get16(header + 0x04);
00411     height = Get16(header + 0x06);
00412     depth = Get16(header + 0x08);
00413     plane_pick = *(header + 0x0e);
00414     if(!plane_pick){
00415         LIErrorString = "Icon does not have any bitplanes.";
00416         return -1;
00417     }
00418     plane_onoff = *(header + 0x0f);
00419     rwidth = ((width + 15) / 16) * 2;
00420     row = malloc(rwidth);
00421     bitmap = malloc(width * height);
00422     memset(bitmap, 0, width * height);
00423     for(ib = 0; ib < depth; ib++) {
00424         int ix, iy;
00425         int oslib = 1 << ib;
00426         if(plane_pick & oslib) {
00427             for(iy = 0; iy < height; iy++) {
00428                 if(!Read8(row, rwidth)){
00429                     LIErrorString = "Unable to read row.";
00430                     return -1;
00431                 }
00432                 for(ix = 0; ix < width; ix++)
00433                     if(row[ix/8] & (0x80 >> (ix & 0x7)))
00434                         bitmap[ix + iy * width] |= oslib;
00435             }
00436         }else if (plane_onoff & oslib){
00437             for(iy = 0; iy < height; iy++)
00438                 for(ix = 0; ix < width; ix++)
00439                     bitmap[ix + iy * width] |= oslib;
00440         }
00441     }
00442     LIWidth = width;
00443     LIHeight = height;
00444     LINumColours = 8;
00445     LIPalette = mwb_palette;
00446     if(image == LI_UNSELECTED)
00447         LIBitmapUnselected = bitmap;
00448     else
00449         LIBitmapSelected = bitmap;
00450 
00451     free(row);
00452     return 0;
00453 }
00454 
00455 char *ReadString()
00456 {
00457     u8 *buf;
00458     u8 lenbuf[4];
00459     u32 len;
00460 
00461     if(!Read8(lenbuf, sizeof lenbuf)){
00462         LIErrorString = "Unable to read string length.";
00463         return "-1";
00464     }
00465     len = Get32(lenbuf);
00466     buf = malloc(len + 1);
00467     buf[len] = '\0';
00468     if(len > 0)
00469         if(!Read8(buf, len)){
00470             LIErrorString = "Unable to read string.";
00471             return "-1";
00472         }
00473     return buf;
00474 }
00475 
00476 int StartTooltypes()
00477 {
00478     u8 countbuf[4];
00479 
00480     if(!Read8(countbuf, sizeof countbuf)){
00481         LIErrorString = "Unable to read number of tooltypes.";
00482         return -1;
00483     }
00484     num_tooltypes = Get32(countbuf)/4 - 1;
00485     return 0;
00486 }
00487 
00488 u8 *GetTooltype(char *name)
00489 {
00490     while (num_tooltypes > 0) {
00491         u8 *s = ReadString();
00492         num_tooltypes--;
00493         if(strncmp(s, name, strlen(name)) == 0){
00494             return s;
00495         }
00496         free(s);
00497     }
00498     return NULL;
00499 }
00500 
00501 u8 *DecompressNewicon(u8 *src, char *name, int len, int bits)
00502 {
00503     u8 *s = src;
00504     u8 *data = malloc(len), *p = data;
00505     int bitmask = (1 << bits) - 1;
00506     int workbits, currentworkbit;
00507 
00508     readblock:              /* goto */
00509     workbits = 0;
00510     currentworkbit = 7;
00511 
00512     while(1){
00513         int runlength = 0;
00514         s8 c = (s8) *s++;
00515         if(c == 0){
00516             free(src);
00517             src = GetTooltype(name);
00518             if(!src){
00519                 LIErrorString = "Ran out of tooltype data.";
00520                 return "-1";
00521             }
00522             s = src + 4;
00523             goto readblock;
00524         }
00525         c -= 0x20;
00526         if(c <= 0){
00527             c -= 0x31;
00528             if(c <= 0){
00529                 runlength = c + 0x80;
00530                 c = 0;
00531             }
00532         }
00533         workbits |= c;
00534         while(runlength-- >= 0){
00535             while(currentworkbit - bits >= 0){
00536                 currentworkbit -= bits;
00537                 *p = (workbits >> currentworkbit) & bitmask;
00538                 p++;
00539                 len--;
00540                 if(len == 0){
00541                     free(src);
00542                     return data;
00543                 }
00544             }
00545             workbits <<= 7;
00546             currentworkbit += 7;
00547         }
00548     }
00549 }
00550 
00551 int ReadNewicon(int image, char *name)
00552 {
00553     u8 *s, *palette, *bitmap;
00554     u8 transparent, width, height;
00555     u16 colors;
00556     int bits;
00557 
00558     s = GetTooltype(name);
00559     if(!s){
00560         LIErrorString = "NewIcon not found.";
00561         return -1;
00562     }
00563     if(strlen(s) < 4){
00564         LIErrorString = "NewIcon header too short.";
00565         return -1;
00566     }
00567     transparent = s[4] - 0x21;
00568     width = s[5] - 0x21;
00569     height = s[6] - 0x21;
00570     colors = ((s[7] - 0x21) << 6) | (s[8] - 0x21);
00571     if(width > 95 || height > 95){
00572         LIErrorString = "Illegal NewIcon size.";
00573         return -1;
00574     }
00575     if(colors > 256){
00576         LIErrorString = "Illegal NewIcon palette size.";
00577         return -1;
00578     }
00579     palette = DecompressNewicon(strdup(s + 9), name, colors * 3, 8);
00580     free(s);
00581 
00582     bits = 1;
00583     while((colors - 1) >> bits)
00584         bits++;
00585     bitmap = DecompressNewicon(strdup(""), name, width * height, bits);
00586 
00587     LIWidth = width;
00588     LIHeight = height;
00589     LINumColours = colors;
00590     LIPalette =  palette;
00591     if(image == LI_UNSELECTED)
00592         LIBitmapUnselected = bitmap;
00593     else
00594         LIBitmapSelected = bitmap;
00595 
00596     return 0;
00597 }

Generated on Tue Dec 23 15:34:24 2003 for LibInfo by doxygen1.3