00001
00029 #include "libinfo.h"
00030
00031
00032
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
00053
00054
00055
00056
00057
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
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
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
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
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
00201
00209 void LICleanUp(void)
00210 {
00211 free(LIPalette);
00212 free(LIBitmapSelected);
00213 free(LIBitmapUnselected);
00214 }
00215
00216
00217
00218
00219
00226 char *LIGetVersion(void)
00227 {
00228 return LIBINFO_VERSION;
00229 }
00230
00231
00232
00233
00234
00235
00242 char *LIGetDate(void)
00243 {
00244 return LIBINFO_DATE;
00245 }
00246
00247
00248
00249
00250
00257 char *LIGetCopyright(void)
00258 {
00259 return LIBINFO_COPYRIGHT;
00260 }
00261
00262
00263
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:
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 }