This is imcopy.c in view mode; [Download] [Up]
/** ** $Header: /import/dev-vis/image/imtools/v2.0/imtools/src/RCS/imcopy.c,v 1.1 91/10/03 13:19:44 nadeau Exp $ ** Copyright (c) 1989, 1990 San Diego Supercomputer Center (SDSC) ** San Diego, California, USA ** ** Users and possessors of this source code are hereby granted a ** nonexclusive, royalty-free copyright and design patent license to ** use this code in individual software. License is not granted for ** commercial resale, in whole or in part, without prior written ** permission from SDSC. This source is provided "AS IS" without express ** or implied warranty of any kind. ** ** For further information contact: ** E-Mail: info@sds.sdsc.edu ** ** Surface Mail: Information Center ** San Diego Supercomputer Center ** P.O. Box 85608 ** San Diego, CA 92138-5608 ** (619) 534-5000 **/ #define HEADER " $Header: /import/dev-vis/image/imtools/v2.0/imtools/src/RCS/imcopy.c,v 1.1 91/10/03 13:19:44 nadeau Exp $" /** ** FILE ** imcopy.c - Copy a part of an image ** ** PROJECT ** IM - Image Manipulation Tools ** ** DESCRIPTION ** imcopy copies a piece of an image into a new file. ** ** PUBLIC CONTENTS ** d =defined constant ** f =function ** m =defined macro ** t =typedef/struct/union ** v =variable ** ? =other ** ** main f main program ** ** PRIVATE CONTENTS ** toolCommand v tool-specific tool info ** toolHelp v tool-specific help ** toolOptions v tool-specific options ** toolEquivs v tool-specific equivalent keywords ** ** toolInFilename v the name of the input file (could be 'stdin') ** toolOutFilename v the name of the output file (could be 'stdout') ** ** toolInFormat v the name of the input file's format (could be '\0') ** toolOutFormat v the name of the output file's format (could be '\0') ** ** toolInTable v a table for the storage of data read in ** toolFlagsTable v a table for the storage of read/write flags ** ** toolPosX v X image position ** toolPosY v Y image position ** toolCenterX v Flag X direction centering ** toolCenterY v Flag Y direction centering ** toolSizeW v Image width ** toolSizeH v Image height ** ** toolInit f initialize things for the tool ** ** HISTORY ** $Log: imcopy.c,v $ ** Revision 1.1 91/10/03 13:19:44 nadeau ** Initial revision ** ** **/ #include "imtools.h" extern void toolInit( ); /* Initialize things */ /* * GLOBALS * toolCommand - tool-specific tool info * toolHelp - tool-specific help * toolOptions - tool-specific options * toolEquivs - tool-specific equivalent keywords * * DESCRIPTION * toolCommand describes the command to the arg package. * * toolHelp is the tool-specific help for the tool. It will be * concatenated with the generic image tools help message and * added to the toolCommand structure as the help string to be * printed after the option listing. * * toolOptions is the tool-specific option list. It will be merged * with the generic image tools options, and the list of image file * format names supported by the library. This larger option list * is then used as the list of options supported by the tool. * * toolEquivs is the tool-specific option equivalent keyword list. * It will be merged with the generic image tools equivs. This large * equivs list is then used as the list of equivs supported by the tool. */ private ArgCommand toolCommand = { /* command name */ "imcopy", /* major version # */ IMTOOLSMAJOR, /* minor version # */ IMTOOLSMINOR, /* subminor version # */ IMTOOLSSUBMINOR, /* -help pre-option list information */ "%command copies a portion of an input image into a new file. Input and\n\ output files may have different image file formats.\n\ ", /* -help post-option list information */ NULL, /* filled in later on */ /* -fullhelp pre-option list information */ NULL, /* Use same message as for -help*/ /* -fullhelp post-option list information */ NULL, /* filled in later on */ ARGFNONE, /* No special flags */ "[options...] infilename outfilename", "[options...] infilename outfilename", "SDSC Image Tools, October 1991.", "Copyright (c) 1989-1991 San Diego Supercomputer Center (SDSC), CA, USA", NULL, /* filled in later on */ NULL, /* filled in later on */ }; private char *toolHelp = "\n\ Typical Invocations:\n\ Clip out a 100x100 pixel image whose upper-left corner is at (10,20),\n\ and save the clipped piece into an HDF file:\n\ %command infile.pix -xpos 10 -ypos 20 -xsize 100 -ysize 100 outfile.hdf\n\ Clip out the top 5 scanlines and save them in a Compuserve GIF file:\n\ %command infile.pix -ypos 0 -ysize 5 outfile.gif\n\ Clip out a centered 100x100 pixel region and save it as a TIFF file:\n\ %command infile.hdf -xsize 100 -ysize 100 outfile.tiff\n\ "; private char *toolFullHelp = "\n\ Files:\n\ -infile selects the file whose images are to be copied. -outfile\n\ selects the file into which to write the resulting image copies. The\n\ input file is unaltered.\n\ \n\ Copying:\n\ A region of each image in the input file is copied out into a new image\n\ and placed into the output file.\n\ \n\ -xsize and -ysize select the size of the region to copy. Both default to\n\ the full width and height of the image.\n\ \n\ -xposition and -yposition select the upper-left corner of the region to\n\ copy and must both be within the bounds of the source image. (0,0) is\n\ upper-left corner of the image. Both default to a position that centers\n\ the copy region within the source image.\n\ "; private char *toolNote = "\n\ Additional Help:\n\ This is an abbreviated help listing. For a full listing of options,\n\ including a list of image file formats supported, type:\n\ %command -fullhelp\n\ "; #define TOOLNOPTIONS 7 private ArgOption toolOptions[TOOLNOPTIONS] = { { "infile", "image_filename", "Specify an input image file name", ARGFREQUIRED | ARGFIMPKEYWORD, 1, 1, ARGTSTRING }, { "outfile", "image_filename", "Specify an output image file name", ARGFREQUIRED | ARGFIMPKEYWORD, 1, 1, ARGTSTRING }, { "xposition", "x", "Specify left edge of copy region", ARGFNONE, 1, 1, ARGTINT }, { "yposition", "y", "Specify top edge of copy region", ARGFNONE, 1, 1, ARGTINT }, { "xsize", "x", "Specify width of copy region in pixels", ARGFNONE, 1, 1, ARGTINT }, { "ysize", "y", "Specify height of copy region in pixels", ARGFNONE, 1, 1, ARGTINT }, { "verbose", NULL, "Be verbose", ARGFFULLHELP, 0, 0, ARGTNONE }, }; #define TOOLNEQUIVS 0 #if TOOLNEQUIVS == 0 private ArgEquiv *toolEquivs; #else private ArgEquiv toolEquivs[TOOLNEQUIVS] = { }; #endif /* * GLOBALS * toolInFilename - the name of the input file (could be 'stdin') * toolOutFilename - the name of the output file (could be 'stdout') * * toolInFormat - the name of the input file's format (could be NULL) * toolOutFormat - the name of the output file's format (could be NULL) * * toolInTable - a table for the storage of data read in * toolFlagsTable - a table for the storage of read/write flags * * toolPosX - X image position * toolPosY - Y image position * toolCenterX - Flag X direction centering * toolCenterY - Flag Y direction centering * toolSizeW - Image width * toolSizeH - Image height * * DESCRIPTION * Data held by these variables is used throughout the tool. */ private char toolInFilename[1024]; /* Input file name */ private char toolInFormat[1024]; /* Input file's format name */ private char toolOutFilename[1024];/* Output file name */ private char toolOutFormat[1024]; /* Output file's format name */ private TagTable *toolInTable; /* Data tag table */ private TagTable *toolFlagsTable; /* Flags tag table */ private int toolPosX; /* X Position */ private int toolPosY; /* Y Position */ private boolean toolCenterX; /* Center in X */ private boolean toolCenterY; /* Center in Y */ private int toolSizeW; /* Width */ private int toolSizeH; /* Height */ /* * FUNCTION * main - main program * * DESCRIPTION * Control things: * - Initialize things (parse arguments and set up tables). * - Read in the input file (put data into data table). * - Copy part of each image. * - Replace the data table images with their smaller copy pieces. * - Write out the output file (get data from data table). * That's about it. * * NOTES * This 'main' is pretty much the same for each of the image tools. * Differences between tools include: * - the number of input files read in * - the number of output files written out * - the actions taken on the data between read and write */ main( argc, argv ) int argc; /* Argument count */ char *argv[]; /* Argument vector */ { int nInVfb; /* Number of images in file */ int i; /* Counter */ TagEntry *dataEntry; /* Entry from data table */ ImVfb *sourceVfb; /* Source image */ ImVfb *regionVfb; /* Region image */ int regionFields; /* Region fields */ int regionW; /* Region width */ int regionH; /* Region height */ /* * Initialize things: * - Prepare the arg parsing data, then parse the command-line. * - Prepare the flags table based upon command-line args. * - Determine the file formats for input and output files. */ toolInit( argc, argv ); /* * Read in the input file. * - Open the file (or stdin) and read data into the data table. */ ImToolsFileRead( toolInFilename, toolInFormat, toolFlagsTable, toolInTable ); /* * Check for errors * - no input images */ nInVfb = TagTableQNEntry( toolInTable, "image vfb" ); if ( nInVfb == 0 ) { fprintf( stderr, "%s: Input file contains no images!\n", ImToolsProgram ); exit( 1 ); } /* * Copy! * - Walk the data table looking for images. For each one found, * get the VFB, copy the region out of it, and replace the * original with the copy back in the same data table. */ for ( i = 0; i < nInVfb; i++ ) { /* * Get the next image out of the data table. */ dataEntry = TagTableQDirect( toolInTable, "image vfb", i ); TagEntryQValue( dataEntry, &sourceVfb ); /* * Compute the copy region position if asked to center. */ if ( toolCenterX ) { if ( toolSizeW == -1 ) toolPosX = 0; else toolPosX = (ImVfbQWidth( sourceVfb ) - toolSizeW) / 2; } else if ( toolPosX > ImVfbQWidth( sourceVfb ) ) { fprintf( stderr, "%s: Copy position is out of bounds for image %d of %d.\n", ImToolsProgram, i+1, nInVfb ); fprintf( stderr, "%s: Entire image copied.\n", ImToolsProgram ); continue; } if ( toolCenterY ) { if ( toolSizeH == -1 ) toolPosY = 0; else toolPosY = (ImVfbQHeight( sourceVfb ) - toolSizeH) / 2; } else if ( toolPosY > ImVfbQHeight( sourceVfb ) ) { fprintf( stderr, "%s: Copy position is out of bounds for image %d of %d.\n", ImToolsProgram, i+1, nInVfb ); fprintf( stderr, "%s: Entire image copied.\n", ImToolsProgram ); continue; } /* * Determine the dimensions of the region to copy. */ if ( toolSizeW == -1 ) { /* * No region given on the command-line. Take * everything from the starting position up to the * right edge of the image. */ regionW = ImVfbQWidth( sourceVfb ) - toolPosX; } else { /* * Region size was given on the command-line. * Clip it to the edge of this image. */ regionW = toolSizeW; if ( regionW > ImVfbQWidth( sourceVfb ) - toolPosX ) regionW = ImVfbQWidth( sourceVfb ) - toolPosX; } if ( toolSizeH == -1 ) { /* * No region given on the command-line. Take * everything from the starting position up to the * bottom edge of the image. */ regionH = ImVfbQHeight( sourceVfb ) - toolPosY; } else { /* * Region size was given on the command-line. * Clip it to the edge of this image. */ regionH = toolSizeH; if ( regionH > ImVfbQHeight( sourceVfb ) - toolPosY ) regionH = ImVfbQHeight( sourceVfb ) - toolPosY; } regionFields = ImVfbQFields( sourceVfb ); /* * Check that the resulting copy region is reasonable. */ if ( regionW <= 0 || regionH <= 0 ) { fprintf( stderr, "%s: Copy size is zero for image %d of %d.\n", ImToolsProgram, i+1, nInVfb ); fprintf( stderr, "%s: Entire image copied.\n", ImToolsProgram ); continue; } /* * Copy the region into a new VFB. Give it the same CLT * (if any) as the source image. */ if ( ImToolsVerbose ) fprintf( stderr, "%s: Copying region at (%d,%d) of size (%d,%d) for image %d of %d\n", ImToolsProgram, toolPosX, toolPosY, regionW, regionH, i + 1, nInVfb ); regionVfb = ImVfbCopy( sourceVfb, /* Use this VFB */ toolPosX, toolPosY, /* Start here */ regionW, regionH, regionFields, /* Take this much*/ IMVFBNEW, /* Make a new VFB*/ 0, 0 ); /* Put it here */ if ( regionVfb == IMVFBNULL ) { ImPError( ImToolsProgram ); fprintf( stderr, "%s: Couldn't copy image region for image %d of %d.\n", ImToolsProgram, i + 1, nInVfb ); fprintf( stderr, "%s: Entire image copied.\n", ImToolsProgram ); continue; } ImVfbSClt( regionVfb, ImVfbQClt( sourceVfb ) ); /* * Replace the source image with the region image in the same * data table. */ TagTableReplace( toolInTable, TagEntryQNthEntry( dataEntry ), TagEntryAlloc( "image vfb", POINTER, ®ionVfb ) ); /* * Destroy the source VFB. */ ImVfbFree( sourceVfb ); } /* * Write out the output file. * - Open the file (or stdout) and write the data in the data * table. Upon failure, remove the bad output file. */ ImToolsFileWrite( toolOutFilename, toolOutFormat, toolFlagsTable, toolInTable ); exit( 0 ); } /* * FUNCTION * toolInit - initialize things for the tool * * DESCRIPTION * The tool's argument parsing data structures are set up to include: * - the full help message (generic help + tool-specific help) * - the full option list (generic options + tool-specific options) * - the full equivs list (generic equivs + tool-specific equivs) * * Command-line arguments are then parsed. The results are used to * set up the flags table (the generic -out* options). * * Input and output file's names and formats are determined from the * command-line arguments. * * NOTES * This function is included in most of the image tools and differs * only in slight ways. Typical differences include: * - the number of input and output file names found * - the number of input and output file formats found * - the number of command-line arg flags checked for */ private void /* Returns nothing */ toolInit( argc, argv ) int argc; /* Argument count */ char *argv[ ]; /* Argument vector */ { int i; /* Counter */ int noccur; /* Number of option occurrences */ int nOpt; /* Number of options */ int nEquiv; /* Number of equivalences */ ArgOption *options1; /* Argument options */ ArgOption *options; /* Argument options */ ArgEquiv *equivs1; /* Argument equivalent keywords */ ArgEquiv *equivs; /* Argument equivalent keywords */ char *tmp; /* Temporary string holder */ char *tmpFormat; /* Tmp format name */ /* * Save the name of the program, as invoked. */ ImToolsProgram = argv[0]; /* * Make a data table to hold the incomming data. */ if ( (toolInTable = TagTableAlloc( )) == TAGTABLENULL ) { TagPError( ImToolsProgram ); exit( 1 ); } /* * Use the standard Image Tools user registration and feedback forms. */ toolCommand.arg_register = ImToolsRegister; toolCommand.arg_feedback = ImToolsFeedback; /* * Allocate space for the total help string for the tool. Copy the * tool-specific help in, then concatenate on the generic help text * used by most of the image tools. */ if ( (tmp = (char *)malloc( sizeof( char ) * (strlen( toolNote ) + strlen( toolHelp ) + 1) )) == NULL ) { perror( ImToolsProgram ); exit( 1 ); } strcpy( tmp, toolHelp ); strcat( tmp, toolNote ); toolCommand.arg_help2 = tmp; if ( (tmp = (char *)malloc( sizeof( char ) * (strlen( ImToolsBaseHelp) + strlen( toolHelp ) + strlen( toolFullHelp ) + 1) )) == NULL ) { perror( ImToolsProgram ); exit( 1 ); } strcpy( tmp, toolHelp ); strcat( tmp, toolFullHelp ); strcat( tmp, ImToolsBaseHelp ); toolCommand.arg_fullhelp2 = tmp; /* * Build up an option list by merging the tool-specific options, * the standard (base) tool options, and those for the various * image file formats. */ nOpt = ImToolsMergeOptions( TOOLNOPTIONS, toolOptions, IMTOOLSNBASEOPTIONS, ImToolsBaseOptions, &options1 ); if ( (nOpt = ImFileFormatOptions( nOpt, options1, &options )) == -1) { ImPError( ImToolsProgram ); exit( 1 ); } /* * Build up an equivalent keyword list by merging the tool-specific * equivalences, the standard (base) tool equivalences, and those * for the various image file formats. */ nEquiv = ImToolsMergeEquivs( TOOLNEQUIVS, toolEquivs, IMTOOLSNBASEEQUIVS, ImToolsBaseEquivs, &equivs1 ); if ( (nEquiv = ImFileFormatEquivs( nEquiv, equivs1, &equivs )) == -1) { ImPError( ImToolsProgram ); exit( 1 ); } /* * Parse the command line! */ nOpt = ArgParse( argc, argv, &toolCommand, nOpt, options, nEquiv, equivs ); if ( ArgQNOccur( "verbose" ) != 0 ) ImToolsVerbose = TRUE; /* * Get the image position and size selections. */ toolPosX = toolPosY = 0; toolCenterX = toolCenterY = TRUE; if ( ArgQNOccur( "xposition" ) != 0 ) { toolPosX = ArgQValue( "xposition", 0, 0 )->arg_i; if ( toolPosX < 0 ) { fprintf( stderr, "%s: -xposition must be positive\n", ImToolsProgram ); exit( 1 ); } toolCenterX = FALSE; } if ( ArgQNOccur( "yposition" ) != 0 ) { toolPosY = ArgQValue( "yposition", 0, 0 )->arg_i; if ( toolPosY < 0 ) { fprintf( stderr, "%s: -yposition must be positive\n", ImToolsProgram ); exit( 1 ); } toolCenterY = FALSE; } toolSizeW = toolSizeH = -1; if ( ArgQNOccur( "xsize" ) != 0 ) { toolSizeW = ArgQValue( "xsize", 0, 0 )->arg_i; if ( toolSizeW <= 0 ) { fprintf( stderr, "%s: -xsize must be positive\n", ImToolsProgram ); exit( 1 ); } } if ( ArgQNOccur( "ysize" ) != 0 ) { toolSizeH = ArgQValue( "ysize", 0, 0 )->arg_i; if ( toolSizeH <= 0 ) { fprintf( stderr, "%s: -ysize must be positive\n", ImToolsProgram ); exit( 1 ); } } /* * Set up the flags table based upon command-line arguments. * This is primarily derived from the -out* directives part of the * standard image tool option set (see ImToolsBaseOptions above). * Also included are flags to direct error messages to stderr and * a flag giving the program's name for later use in error messages. */ toolFlagsTable = ImToolsBuildFlagsTable( ); /* * Get the input file's name (-infile), and search backwards in the * command-line option list to find the last format selection (if * any). Stop the search on the beginning of the command-line, or * on -outfile. */ strcpy( toolInFilename, ArgQValue( "infile", 0, 0 )->arg_s ); tmpFormat = NULL; for ( i = ArgQOccurOpt( "infile", 0 ) - 1; i >= 0; i-- ) { tmp = ArgQOpt( i, &noccur ); /* * Stop looking backward when we reach any other file name * argument. */ if ( strcmp( tmp, "outfile" ) == 0 ) break; /* * Skip it if it isn't the name of a file format. */ if ( !ImToolsIsFormat( tmp ) ) continue; if ( tmpFormat != NULL ) { fprintf( stderr, "%s: Only 1 file format selection may precede -infile.\n", ImToolsProgram ); exit( 1 ); } tmpFormat = tmp; } if ( tmpFormat == NULL ) *toolInFormat = '\0'; else strcpy( toolInFormat, tmpFormat ); /* * Get the output file's name (-outfile), and search backwards in the * command-line option list to find the last format selection (if * any). Stop the search on the beginning of the command-line, or * on -infile. */ strcpy( toolOutFilename, ArgQValue( "outfile", 0, 0 )->arg_s ); tmpFormat = NULL; for ( i = ArgQOccurOpt( "outfile", 0 ) - 1; i >= 0; i-- ) { tmp = ArgQOpt( i, &noccur ); /* * Stop looking backward when we reach any other file name * argument. */ if ( strcmp( tmp, "infile" ) == 0 ) break; /* * Skip it if it isn't the name of a file format. */ if ( !ImToolsIsFormat( tmp ) ) continue; if ( tmpFormat != NULL ) { fprintf( stderr, "%s: Only 1 file format selection may precede -outfile.\n", ImToolsProgram ); exit( 1 ); } tmpFormat = tmp; } if ( tmpFormat == NULL ) *toolOutFormat = '\0'; else strcpy( toolOutFormat, tmpFormat ); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.