00001
00034 #include "libinfo.h"
00035
00036
00037
00038 # ifdef LI_OUTPUT_XPM
00039
00040 int transparent = -1;
00041
00042 #endif
00043
00045 u8 mwb_palette[] = {
00046 149, 149, 149,
00047 0, 0, 0,
00048 255, 255, 255,
00049 59, 103, 162,
00050 123, 123, 123,
00051 175, 175, 175,
00052 170, 144, 124,
00053 255, 169, 151
00054 };
00055
00056
00057
00058
00059
00060
00061
00062
00063
00078 int LIReadDefIcon(const char *filename)
00079 {
00080 if((fileIcon = fopen(filename, "rb")) == NULL){
00081 LIErrorString = "Error opening input file.";
00082 return -1;
00083 }
00084
00085
00086 LIWidth = 0;
00087 LIHeight = 0;
00088 LINumColoursUnselected = 0;
00089 LINumColoursSelected = 0;
00090
00091 if(ReadHeader() == -1)
00092 return -1;
00093 if(ReadIcon(LI_UNSELECTED) == -1)
00094 return -1;
00095 if(image2)
00096 if(ReadIcon(LI_SELECTED) == -1)
00097 return -1;
00098
00099 fclose(fileIcon);
00100 return 0;
00101 }
00102
00103
00104
00105
00122 int LIReadNewIcon(const char *filename)
00123 {
00124 int ret;
00125
00126 if((fileIcon = fopen(filename, "rb")) == NULL){
00127 LIErrorString = "Error opening input file";
00128 return -1;
00129 }
00130
00131 if(ReadHeader() == -1)
00132 return -1;
00133 if(ReadIcon(LI_UNSELECTED) == -1)
00134 return -1;
00135 if(image2)
00136 if(ReadIcon(LI_SELECTED) == -1)
00137 return -1;
00138 if(tool)
00139 free(ReadString());
00140 if(StartTooltypes() == -1)
00141 return -1;
00142
00143
00144 LIWidth = 0;
00145 LIHeight = 0;
00146 LINumColoursUnselected = 0;
00147 LINumColoursSelected = 0;
00148
00149 ret = ReadNewicon(LI_UNSELECTED, "IM1=");
00150 if(ret == -2)
00151
00152 return -2;
00153 else if(ret == -1)
00154 return -1;
00155 ret = ReadNewicon(LI_SELECTED, "IM2=");
00156 if(ret == -2)
00157
00158 return -3;
00159 else if(ret == -1)
00160 return -1;
00161
00162 fclose(fileIcon);
00163 return 0;
00164 }
00165
00166
00167 #ifdef LI_OUTPUT_XPM
00168
00169
00170
00180 int LISetXPMTransparency(int colour, int image)
00181 {
00182 int ncols;
00183
00184 if(image == LI_UNSELECTED){
00185 ncols = LINumColoursUnselected;
00186 }
00187 else{
00188 ncols = LINumColoursSelected;
00189 }
00190
00191 if(colour >= ncols){
00192 LIErrorString = "Can't set colour transparency.";
00193 return -1;
00194 }
00195 transparent = colour;
00196
00197 return 0;
00198 }
00199
00200
00201
00202
00203
00215 int LIWriteXPM(char *filename, int image)
00216 {
00217 u8 *palette;
00218 int ncols;
00219
00220 if(image == LI_UNSELECTED){
00221 palette = LIPaletteUnselected;
00222 ncols = LINumColoursUnselected;
00223 }
00224 else{
00225 palette = LIPaletteSelected;
00226 ncols = LINumColoursSelected;
00227 }
00228
00229 return WriteXPM(filename, LIWidth, LIHeight, ncols, palette, image);
00230 }
00231
00232
00233
00234
00256 void LIGetMemoryXPM(char **xpm, int image)
00257 {
00258 u8 *palette;
00259 int ncols;
00260
00261 if(image == LI_UNSELECTED){
00262 palette = LIPaletteUnselected;
00263 ncols = LINumColoursUnselected;
00264 }
00265 else{
00266 palette = LIPaletteSelected;
00267 ncols = LINumColoursSelected;
00268 }
00269
00270 GetMemoryXPM(xpm, LIWidth, LIHeight, ncols, palette, image);
00271 }
00272
00273 #endif
00274 #ifdef LI_OUTPUT_PPM
00275
00276
00277
00278
00290 int LIWritePPM(char *filename, int image)
00291 {
00292 u8 *palette;
00293 int ncols;
00294
00295 if(image == LI_UNSELECTED){
00296 palette = LIPaletteUnselected;
00297 ncols = LINumColoursUnselected;
00298 }
00299 else{
00300 palette = LIPaletteSelected;
00301 ncols = LINumColoursSelected;
00302 }
00303
00304 return WritePPM(filename, LIWidth, LIHeight, ncols, palette, image);
00305 }
00306
00307 #endif
00308
00309
00310
00311
00319 void LICleanUp(void)
00320 {
00321 free(LIPaletteSelected);
00322 free(LIPaletteUnselected);
00323 free(LIBitmapSelected);
00324 free(LIBitmapUnselected);
00325 }
00326
00327
00328
00329
00330
00337 char *LIGetVersion(void)
00338 {
00339 return LIBINFO_VERSION;
00340 }
00341
00342
00343
00344
00345
00346
00353 char *LIGetDate(void)
00354 {
00355 return LIBINFO_DATE;
00356 }
00357
00358
00359
00360
00361
00368 char *LIGetCopyright(void)
00369 {
00370 return LIBINFO_COPYRIGHT;
00371 }
00372
00373
00374
00375
00376
00377 u16 Get16(u8 *p)
00378 {
00379 return(*p * 256) + *(p+1);
00380 }
00381
00382 u32 Get32(u8 *p)
00383 {
00384 return((*p * 256 + *(p+1)) * 256 + *(p+2)) * 256 + *(p+3);
00385 }
00386
00387 int Read8(u8 *buf, int len)
00388 {
00389 len = fread(buf, 1, len, fileIcon);
00390 return len;
00391 }
00392
00393 int ReadHeader()
00394 {
00395 u8 header[0x4e];
00396
00397 if(!Read8(header, sizeof header)){
00398 LIErrorString = "Unable to read header.";
00399 return -1;
00400 }
00401 magic = Get16(header);
00402 if(magic != 0xE310){
00403 LIErrorString = "Wrong magic number.";
00404 return -1;
00405 }
00406 version = Get16(header + 0x02);
00407 if(version != 1){
00408 LIErrorString = "Wrong version.";
00409 return -1;
00410 }
00411 type = Get16(header + 0x30);
00412 image1 = Get32(header + 0x16);
00413 if(!image1){
00414 LIErrorString = "Could not find image.";
00415 return -1;
00416 }
00417 image2 = Get32(header + 0x1A);
00418 tool = Get32(header + 0x32);
00419 if(Get32(header + 0x42)) {
00420 u8 drawer[0x38];
00421 if(!Read8(drawer, sizeof drawer)){
00422 LIErrorString = "Unable to read drawer.";
00423 return -1;
00424 }
00425 }
00426 return 0;
00427 }
00428
00429 #ifdef LI_OUTPUT_PPM
00430
00431 int WritePPM(char *filename, int width, int height, int ncols, u8 *palette, int image)
00432 {
00433 int x, y;
00434 u8 *bitmap;
00435 FILE *file;
00436
00437 if(image == LI_UNSELECTED)
00438 bitmap = LIBitmapUnselected;
00439 else
00440 bitmap = LIBitmapSelected;
00441
00442 if((file = fopen(filename, "w")) == NULL){
00443 LIErrorString = "Unable to create PPM file.";
00444 return -1;
00445 }
00446 fprintf(file, "P6 %d %d 255\n", width, height);
00447 for(y = 0; y < height; y++) {
00448 for(x = 0; x < width; x++) {
00449 u8 c = 3 * bitmap[x + y*width];
00450 putc(palette[c], file);
00451 putc(palette[c+1], file);
00452 putc(palette[c+2], file);
00453 }
00454 }
00455 if(fclose(file) != 0){
00456 LIErrorString = "Error closing PPM file.";
00457 return -1;
00458 }
00459 return 0;
00460 }
00461
00462 #endif
00463 #ifdef LI_OUTPUT_XPM
00464
00465 int WriteXPM(char *filename, int width, int height, int ncols, u8 *palette, int image)
00466 {
00467 int x, y;
00468 u8 *bitmap;
00469 FILE *file;
00470
00471 if(image == LI_UNSELECTED)
00472 bitmap = LIBitmapUnselected;
00473 else
00474 bitmap = LIBitmapSelected;
00475
00476 if((file = fopen(filename, "w")) == NULL){
00477 LIErrorString = "Unable to create XPM file.";
00478 return -1;
00479 }
00480 fprintf(file, "/* XPM */\nstatic const char * amigaicon_xpm[] = {\n"
00481 "\"%d %d %d 1\",\n", width, height, ncols);
00482 for(x = 0; x < ncols; x++)
00483 if (x == transparent)
00484 fprintf(file, "\"%c\tc None\",\n", 'a' + x);
00485 else
00486 fprintf(file, "\"%c\tc #%02x%02x%02x\",\n",
00487 'a' + x,
00488 palette[x * 3], palette[x * 3 + 1], palette[x * 3 + 2]);
00489 for(y = 0; y < height; y++) {
00490 fprintf(file, "%c", '"');
00491 for(x = 0; x < width; x++){
00492 putc('a' + bitmap[x + y * width], file);
00493 }
00494 if(y == height - 1)
00495 fprintf(file, "%s", "\"};");
00496 else
00497 fprintf(file, "%s", "\",\n");
00498 }
00499 if(fclose(file) != 0){
00500 LIErrorString = "Error closing XPM file.";
00501 return -1;
00502 }
00503 return 0;
00504 }
00505
00506 void GetMemoryXPM(char **xpm, int width, int height, int ncols, u8 *palette, int image)
00507 {
00508 int x, y, i = 0;
00509 u8 *bitmap;
00510 char *s, *t;
00511
00512 if(!xpm){
00513 LIErrorString = "XPM char** not initialised.";
00514 return;
00515 }
00516
00517 if(image == LI_UNSELECTED)
00518 bitmap = LIBitmapUnselected;
00519 else
00520 bitmap = LIBitmapSelected;
00521
00522
00523 s = malloc(width + 1 >= 20 ? width + 1 : 20);
00524 t = malloc(width + 1 >= 20 ? width + 1 : 20);
00525
00526 sprintf(s, "%d %d %d 1", width, height, ncols);
00527 strcpy(xpm[i++], s);
00528
00529 for(x = 0; x < ncols; x++){
00530 if(x == transparent){
00531 sprintf(s, "%c\tc None,", 'a' + x);
00532 strcpy(xpm[i++], s);
00533 }
00534 else{
00535 sprintf(s, "%c\tc #%02x%02x%02x", 'a' + x, palette[x * 3], palette[x * 3 + 1], palette[x * 3 + 2]);
00536 strcpy(xpm[i++], s);
00537 }
00538 }
00539 for(y = 0; y < height; y++){
00540 sprintf(s, "%s", "");
00541 for(x = 0; x < width; x++){
00542 sprintf(t, "%c", 'a' + bitmap[x + y * width]);
00543 strcat(s, t);
00544 }
00545 strcpy(xpm[i++], s);
00546 }
00547
00548 free(s);
00549 free(t);
00550 }
00551
00552 #endif
00553
00554 int ReadIcon(int image)
00555 {
00556 u8 header[0x14];
00557 u16 width, height, depth;
00558 u8 plane_pick, plane_onoff;
00559 u8 *row, *bitmap;
00560 int rwidth;
00561 int ib;
00562
00563 if (!Read8(header, sizeof header)){
00564 LIErrorString = "Unable to read icon header.";
00565 return -1;
00566 }
00567 width = Get16(header + 0x04);
00568 height = Get16(header + 0x06);
00569 depth = Get16(header + 0x08);
00570 plane_pick = *(header + 0x0e);
00571 if(!plane_pick){
00572 LIErrorString = "Icon does not have any bitplanes.";
00573 return -1;
00574 }
00575 plane_onoff = *(header + 0x0f);
00576 rwidth = ((width + 15) / 16) * 2;
00577 row = malloc(rwidth);
00578 bitmap = malloc(width * height);
00579 memset(bitmap, 0, width * height);
00580 for(ib = 0; ib < depth; ib++) {
00581 int ix, iy;
00582 int oslib = 1 << ib;
00583 if(plane_pick & oslib) {
00584 for(iy = 0; iy < height; iy++) {
00585 if(!Read8(row, rwidth)){
00586 LIErrorString = "Unable to read row.";
00587
00588 free(row);
00589 free(bitmap);
00590 return -1;
00591 }
00592 for(ix = 0; ix < width; ix++)
00593 if(row[ix/8] & (0x80 >> (ix & 0x7)))
00594 bitmap[ix + iy * width] |= oslib;
00595 }
00596 }else if (plane_onoff & oslib){
00597 for(iy = 0; iy < height; iy++)
00598 for(ix = 0; ix < width; ix++)
00599 bitmap[ix + iy * width] |= oslib;
00600 }
00601 }
00602 LIWidth = width;
00603 LIHeight = height;
00604 if(image == LI_UNSELECTED){
00605 LIBitmapUnselected = bitmap;
00606 LINumColoursUnselected = 8;
00607
00608 LIPaletteUnselected = malloc(sizeof(mwb_palette));
00609 memcpy(LIPaletteUnselected, mwb_palette, sizeof(mwb_palette));
00610 }
00611 else{
00612 LIBitmapSelected = bitmap;
00613 LINumColoursSelected = 8;
00614
00615 LIPaletteSelected = malloc(sizeof(mwb_palette));
00616 memcpy(LIPaletteSelected, mwb_palette, sizeof(mwb_palette));
00617 }
00618
00619 free(row);
00620 return 0;
00621 }
00622
00623 u8 *ReadString()
00624 {
00625 u8 *buf;
00626 u8 lenbuf[4];
00627 u32 len;
00628
00629 if(!Read8(lenbuf, sizeof lenbuf)){
00630 LIErrorString = "Unable to read string length.";
00631 return (u8*)"-1";
00632 }
00633 len = Get32(lenbuf);
00634 buf = malloc(len + 1);
00635 buf[len] = '\0';
00636 if(len > 0)
00637 if(!Read8(buf, len)){
00638 LIErrorString = "Unable to read string.";
00639
00640 free(buf);
00641 return (u8*)"-1";
00642 }
00643 return buf;
00644 }
00645
00646 int StartTooltypes()
00647 {
00648 u8 countbuf[4];
00649
00650 if(!Read8(countbuf, sizeof countbuf)){
00651 LIErrorString = "Unable to read number of tooltypes.";
00652 return -1;
00653 }
00654 num_tooltypes = Get32(countbuf)/4 - 1;
00655 return 0;
00656 }
00657
00658 u8 *GetTooltype(char *name)
00659 {
00660 while (num_tooltypes > 0) {
00661 u8 *s = ReadString();
00662 num_tooltypes--;
00663 if(strncmp((char*)s, name, strlen(name)) == 0){
00664 return s;
00665 }
00666 free(s);
00667 }
00668 return NULL;
00669 }
00670
00671 u8 *DecompressNewicon(u8 *src, char *name, int len, int bits)
00672 {
00673 u8 *s = src;
00674 u8 *data = malloc(len), *p = data;
00675 int bitmask = (1 << bits) - 1;
00676 int workbits, currentworkbit;
00677
00678 readblock:
00679 workbits = 0;
00680 currentworkbit = 7;
00681
00682 while(1){
00683 int runlength = 0;
00684 s8 c = (s8) *s++;
00685 if(c == 0){
00686 free(src);
00687 src = GetTooltype(name);
00688 if(!src){
00689 LIErrorString = "Ran out of tooltype data.";
00690 return (u8*)"-1";
00691 }
00692 s = src + 4;
00693 goto readblock;
00694 }
00695 c -= 0x20;
00696 if(c <= 0){
00697 c -= 0x31;
00698 if(c <= 0){
00699 runlength = c + 0x80;
00700 c = 0;
00701 }
00702 }
00703 workbits |= c;
00704 while(runlength-- >= 0){
00705 while(currentworkbit - bits >= 0){
00706 currentworkbit -= bits;
00707 *p = (workbits >> currentworkbit) & bitmask;
00708 p++;
00709 len--;
00710 if(len == 0){
00711 free(src);
00712 return data;
00713 }
00714 }
00715 workbits <<= 7;
00716 currentworkbit += 7;
00717 }
00718 }
00719 }
00720
00721 int ReadNewicon(int image, char *name)
00722 {
00723 u8 *s, *palette, *bitmap;
00724 u8 transparent, width, height;
00725 u16 colors;
00726 int bits;
00727
00728 s = GetTooltype(name);
00729 if(!s){
00730 LIErrorString = "NewIcon not found.";
00731 return -2;
00732 }
00733 if(strlen((char*)s) < 4){
00734 LIErrorString = "NewIcon header too short.";
00735 return -1;
00736 }
00737 transparent = s[4] - 0x21;
00738 width = s[5] - 0x21;
00739 height = s[6] - 0x21;
00740 colors = ((s[7] - 0x21) << 6) | (s[8] - 0x21);
00741 if(width > 95 || height > 95){
00742 LIErrorString = "Illegal NewIcon size.";
00743 return -1;
00744 }
00745 if(colors > 256){
00746 LIErrorString = "Illegal NewIcon palette size.";
00747 return -1;
00748 }
00749 palette = DecompressNewicon((u8*)strdup((char*)s + 9), name, colors * 3, 8);
00750 free(s);
00751
00752 bits = 1;
00753 while((colors - 1) >> bits)
00754 bits++;
00755 bitmap = DecompressNewicon((u8*)strdup(""), name, width * height, bits);
00756
00757 LIWidth = width;
00758 LIHeight = height;
00759 if(image == LI_UNSELECTED){
00760 LIBitmapUnselected = bitmap;
00761 LINumColoursUnselected = colors;
00762 LIPaletteUnselected = palette;
00763 }
00764 else{
00765 LIBitmapSelected = bitmap;
00766 LINumColoursSelected = colors;
00767 LIPaletteSelected = palette;
00768 }
00769
00770 return 0;
00771 }