home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
fish
/
icons
/
remapicon
/
remapicon.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-08
|
11KB
|
434 lines
/* $Revision Header * Header built automatically - do not edit! *************
*
* (C) Copyright 1990 by MXM
*
* Name .....: RemapIcon.c
* Created ..: Tuesday 26-Jun-90 14:19
* Revision .: 1
*
* Date Author Comment
* ========= ======== ====================
* 26-Jun-90 Olsen Added Arp interface
* 26-Jun-90 Olsen Created this file!
*
* $Revision Header ********************************************************/
#define __NO_PRAGMAS 1
#include <workbench/workbench.h>
#include <libraries/arpbase.h>
#include <hardware/blit.h>
#include <exec/memory.h>
#include <functions.h>
#include <fcntl.h>
/* Arp command line data. */
char *CLI_Template = "File,DIR/K,TO/K,INFO/S";
char *CLI_Help = "\nUsage: RemapIcon [FILE <Filename without .info>] [TO <Directory name>]\
\n [DIR <Directory name>] [TO <Directory name>]\
\n [INFO]\
\n\n Note: if the TO-argument is omitted, the icons will\
\n be written to the source directory.\n\n";
/* Argument vector offsets. */
#define ARG_FILE 1
#define ARG_DIR 2
#define ARG_TO 3
#define ARG_INFO 4
/* Icon.library base. */
struct Library *IconBase;
/* Calculate the amount of memory needed for a row of pixels. */
#define byte(width) (((width + 15) >> 4) << 1)
/* This is where the colour will go to. */
struct RastPort ColourRPort;
struct BitMap ColourBitMap;
/* The icon image will be turned into a RastPort. */
struct RastPort ImageRPort;
struct BitMap ImageBitMap;
/* Temporary mask and masks for both colours (1 and 2). */
struct BitMap TempMask,ColourMask1,ColourMask2;
/* RemapImage(struct Image *Icon):
*
* This routine will exchange the colours of the white
* and the black pixels in an image.
*/
BYTE
RemapImage(struct Image *Icon)
{
BYTE Success = FALSE;
SHORT i;
/* Transform the image into a RastPort. */
InitRastPort(&ImageRPort);
InitBitMap(&ImageBitMap,Icon -> Depth,Icon -> Width,Icon -> Height);
ImageRPort . BitMap = &ImageBitMap;
/* Set the planes accordingly. */
for(i = 0 ; i < Icon -> Depth ; i++)
ImageBitMap . Planes[i] = (PLANEPTR)((ULONG)Icon -> ImageData + i * byte(Icon -> Width) * Icon -> Height);
/* Alas, you cannot perform an area fill through a mask wider
* than sixteen pixels. For this reason we will create a
* RastPort whose BitMap has the colour we want the
* mask area to be filled with.
*/
InitRastPort(&ColourRPort);
InitBitMap(&ColourBitMap,Icon -> Depth,Icon -> Width,Icon -> Height);
ColourRPort . BitMap = &ColourBitMap;
/* Initialize the mask BitMaps. */
InitBitMap(&TempMask,Icon -> Depth,Icon -> Width,Icon -> Height);
InitBitMap(&ColourMask1,Icon -> Depth,Icon -> Width,Icon -> Height);
InitBitMap(&ColourMask2,Icon -> Depth,Icon -> Width,Icon -> Height);
/* Allocate memory for the colour BitMap. */
if(ColourBitMap . Planes[0] = (PLANEPTR)AllocMem(Icon -> Depth * byte(Icon -> Width) * Icon -> Height,MEMF_PUBLIC | MEMF_CHIP | MEMF_CLEAR))
{
for(i = 1 ; i < Icon -> Depth ; i++)
ColourBitMap . Planes[i] = (PLANEPTR)((ULONG)ColourBitMap . Planes[0] + i * byte(Icon -> Width) * Icon -> Height);
/* Allocate memory for the mask for colour 1. */
if(ColourMask1 . Planes[0] = (PLANEPTR)AllocMem(byte(Icon -> Width) * Icon -> Height,MEMF_PUBLIC | MEMF_CHIP | MEMF_CLEAR))
{
for(i = 1 ; i < Icon -> Depth ; i++)
ColourMask1 . Planes[i] = ColourMask1 . Planes[0];
/* Allocate memory for the mask for colour 2. */
if(ColourMask2 . Planes[0] = (PLANEPTR)AllocMem(byte(Icon -> Width) * Icon -> Height,MEMF_PUBLIC | MEMF_CHIP | MEMF_CLEAR))
{
for(i = 1 ; i < Icon -> Depth ; i++)
ColourMask2 . Planes[i] = ColourMask2 . Planes[0];
/* Allocate memory for the temporary mask. */
if(TempMask . Planes[0] = (PLANEPTR)AllocMem(byte(Icon -> Width) * Icon -> Height,MEMF_PUBLIC | MEMF_CHIP | MEMF_CLEAR))
{
Success = TRUE;
for(i = 1 ; i < Icon -> Depth ; i++)
TempMask . Planes[i] = TempMask . Planes[0];
/* Perform an OR-operation on all the planes associated with colour 1. */
BltBitMap(&ImageBitMap,0,0,&ColourMask1,0,0,Icon -> Width,Icon -> Height,0xE0,1,NULL);
/* Clear all pixels in the mask which belong to other colours. */
BltBitMap(&ImageBitMap,0,0,&ColourMask1,0,0,Icon -> Width,Icon -> Height,0x80,1,NULL);
/* Perform an OR-operation on all planes which do not belong to colour 1. */
BltBitMap(&ImageBitMap,0,0,&TempMask,0,0,Icon -> Width,Icon -> Height,0xE0,0xFF ^ 1,NULL);
/* Clear all pixels which do not belong to colour 1. */
BltBitMap(&TempMask,0,0,&ColourMask1,0,0,Icon -> Width,Icon -> Height,0x20,0xFF,NULL);
/* Clear the temporary mask. */
BltClear(TempMask . Planes[0],byte(Icon -> Width) * Icon -> Height,1);
/* Perform an OR-operation on all the planes associated with colour 2. */
BltBitMap(&ImageBitMap,0,0,&ColourMask2,0,0,Icon -> Width,Icon -> Height,0xE0,2,NULL);
/* Clear all pixels in the mask which belong to other colours. */
BltBitMap(&ImageBitMap,0,0,&ColourMask2,0,0,Icon -> Width,Icon -> Height,0x80,2,NULL);
/* Perform an OR-operation on all planes which do not belong to colour 2. */
BltBitMap(&ImageBitMap,0,0,&TempMask,0,0,Icon -> Width,Icon -> Height,0xE0,0xFF ^ 2,NULL);
/* Clear all pixels which do not belong to colour 1. */
BltBitMap(&TempMask,0,0,&ColourMask2,0,0,Icon -> Width,Icon -> Height,0x20,0xFF,NULL);
/* Replace colour 2 with colour 1. */
SetRast(&ColourRPort,1);
BltMaskBitMapRastPort(&ColourBitMap,0,0,&ImageRPort,0,0,Icon -> Width,Icon -> Height,(ABC|ABNC|ANBC),(APTR)ColourMask2 . Planes[0]);
/* Replace colour 1 with colour 2. */
SetRast(&ColourRPort,2);
BltMaskBitMapRastPort(&ColourBitMap,0,0,&ImageRPort,0,0,Icon -> Width,Icon -> Height,(ABC|ABNC|ANBC),(APTR)ColourMask1 . Planes[0]);
FreeMem(TempMask . Planes[0],byte(Icon -> Width) * Icon -> Height);
}
FreeMem(ColourMask2 . Planes[0],byte(Icon -> Width) * Icon -> Height);
}
FreeMem(ColourMask1 . Planes[0],byte(Icon -> Width) * Icon -> Height);
}
FreeMem(ColourBitMap . Planes[0],Icon -> Depth * byte(Icon -> Width) * Icon -> Height);
}
return(Success);
}
/* RemapIcon(char *Source,char *Dest):
*
* This routine loads the approriate icon file, causes
* the image(s) to be remapped and saves the resulting
* file back to disk.
*/
BYTE
RemapIcon(char *Source,char *Dest)
{
struct DiskObject *Icon;
BYTE Success = FALSE;
Printf("Remapping icon %s.info to %s.info... ",Source,Dest);
/* Read the icon file. */
if(Icon = GetDiskObject(Source))
{
/* Remap the standard image. */
if(RemapImage((struct Image *)Icon -> do_Gadget . GadgetRender))
{
Success = TRUE;
/* If it has an alternate image, remap it as well. */
if(Icon -> do_Gadget . SelectRender)
{
if(!RemapImage((struct Image *)Icon -> do_Gadget . SelectRender))
{
Printf("ERROR (%ld): Cannot remap icon select image.\a\n",ERROR_NO_FREE_STORE);
Success = FALSE;
}
}
/* If the remapping process succeeded, save
* the icon back to disk.
*/
if(Success)
{
if(!PutDiskObject(Dest,Icon))
{
Printf("ERROR (%ld): Cannot create file \"%s.info\".\a\n",IoErr(),Dest);
Success = FALSE;
}
}
}
else
Printf("ERROR (%ld): Cannot remap icon image.\a\n",ERROR_NO_FREE_STORE);
/* Release the icon. */
FreeDiskObject(Icon);
}
else
Printf("ERROR (%ld): Cannot read file \"%s.info\".\a\n",IoErr(),Source);
if(Success)
Puts("done.");
return(Success);
}
LONG Chk_Abort(VOID) { return(0); }
VOID _wb_parse(VOID) {}
VOID
main(int argc,char **argv)
{
BYTE Success = RETURN_OK;
/* Disable the standard ^C checking. */
Enable_Abort = FALSE;
/* Display program version. */
Puts("\n\33[1m\33[33mRemapIcon V1.1 \33[0m\33[31mCopyright © 1990 by MXM, all rights reserved\n");
/* User wants info? */
if(argv[ARG_INFO])
{
Puts("This program remaps icon images to fit the different colour");
Puts("palettes used by Amiga computers equipped with Kickstart 2.x");
Puts("and 1.3. The colours of pixels painted in colour 1 and 2");
Puts("are swapped, so pre-2.x icons and 2.x icons can be");
Puts("exchanged between both Workbench releases.\n");
Puts("Author: Olaf Barthel, MXM");
Puts(" Brabeckstrasse 35");
Puts(" D-3000 Hannover 71\n");
Puts(" Federal Republic of Germany\n");
Puts("Written at Hannover, Monday 25-Jun-90.\n");
Puts("This program is Share-Ware, if you like it and use it");
Puts("frequently a small donation will entitle you to receive");
Puts("updates and new programs from MXM.\n");
exit(RETURN_OK);
}
/* Do we have a valid command line? */
if(!argv[ARG_FILE] && !argv[ARG_DIR])
{
Puts(CLI_Help);
exit(RETURN_WARN);
}
/* Open icon.library. */
if(IconBase = OpenLibrary("icon.library",0))
{
char DestName[256];
/* Convert a single file? */
if(argv[ARG_FILE])
{
/* Do we have a path to write it to? */
if(argv[ARG_TO])
{
strcpy(DestName,argv[ARG_TO]);
TackOn(DestName,BaseName(argv[ARG_FILE]));
}
else
{
SHORT i;
strcpy(DestName,argv[ARG_FILE]);
for(i = strlen(DestName) - 1 ; i >= 0 ; i--)
{
if(DestName[i] == ':' || DestName[i] == '/')
break;
else
DestName[i] = 0;
}
strcat(DestName,BaseName(argv[ARG_FILE]));
}
/* Remap the icon. */
if(!RemapIcon(argv[ARG_FILE],DestName))
Success = RETURN_FAIL;
}
else
{
char SourceName[256],Pattern[256],*Pointer;
/* Build search path and pattern. */
strcpy(Pattern,argv[ARG_DIR]);
TackOn(Pattern,"*.info");
/* Scan the directory for .info files. */
while(Pointer = scdir(Pattern))
{
/* ^C = Abort scanning. */
if(SetSignal(0,0) & SIGBREAKF_CTRL_C)
{
SetSignal(0,SIGBREAKF_CTRL_C);
Puts("*** Break\a");
break;
}
/* ^D skip current file. */
if(SetSignal(0,0) & SIGBREAKF_CTRL_D)
{
SetSignal(0,SIGBREAKF_CTRL_D);
continue;
}
/* Is it an icon file? */
if(strlen(BaseName(Pointer)) > 5)
{
strcpy(SourceName,Pointer);
/* Skip the .info. */
SourceName[strlen(SourceName) - 5] = 0;
/* Do we have a path to write it to? */
if(argv[ARG_TO])
{
strcpy(DestName,argv[ARG_TO]);
TackOn(DestName,BaseName(SourceName));
}
else
{
SHORT i;
strcpy(DestName,SourceName);
for(i = strlen(DestName) - 1 ; i >= 0 ; i--)
{
if(DestName[i] == ':' || DestName[i] == '/')
break;
else
DestName[i] = 0;
}
strcat(DestName,BaseName(SourceName));
}
/* Remap the icon. */
RemapIcon(SourceName,DestName);
}
}
}
/* Close the library. */
CloseLibrary(IconBase);
}
else
{
Printf("ERROR (%ld): Cannot open icon.library.\a\n",IoErr());
Success = RETURN_FAIL;
}
/* And return. */
exit(Success);
}