Meta-programming methods and apparatus5905894Abstract The described programming techniques allow for the passing of code arguments to functions, referred to as meta-functions, at compile time through the use of compiler directives. Methods for implementing functions, referred to as meta-loops, which allow for a block of code to be repeated a variable number of times at compile time are also described. The programming methods of the present invention allow for greater code reuse since code arguments can be used to modify the functionality of a meta-function thereby altering its functionality. Meta-functions and meta-loops can also be used to generate a group of functions which share common behaviors. In accordance with the present invention the common behaviors are produced via the use of a common meta-function. This allows the behavior of a group of functions to be altered. This reduces the time and expense associated with creating and maintaining libraries of functions with shared behaviors. Because the programming methods of the present invention can be implemented using compiler commands and functionality supported by existing compiled languages such as C++ they serve to supplement and argument the functionality of existing compiled languages without requiring modifications thereto. Claims What is claimed is: Description FIELD OF THE INVENTION
______________________________________
meta-function declaration:
meta.sub.-- function meta-function-name (FunctionName,
code-argument-list)
(template<template-argument-list>)
return-value FunctionName (function-argument-list)
{
›Statements*.backslash.code-arguments*.backslash.function-arguments*!
}
for example:
meta.sub.-- function PrintCalculation (FunctionName, CodeArgument1,
CodeArgument2)
template <class TYPE1, class TYPE2>
void FunctionName (Type1 variable1, Type2 variable 2)
{
// this is an example of a meta function which
// uses templated arguments, as well as code arguments
// print the original values
cout << variable1 <<""<< variable2 <<"";
// apply some unknown block of code
CodeArgument1;
// print the intermediate values
cout << variable1 <<""<< variable2 <<"";
// apply another unknown block of code
CodeArgument2;
// print the final values
cout << variable1 <<""<< variable2 << EOL;
______________________________________
After such a function is created, e.g., in a separate file bearing the name of the function, it can be instantiated, i.e., included, in a program by making the following function call:
______________________________________
PrintCalculation(SumSqrAndSqrtSumSqr,
{ variable1 *= variable1; variable2* = variable2; },
{ variable1 += variable2; variable2 = sqrt(variable1}; }};
______________________________________
Though the above syntax and functionality is desirable, it unfortunately is not supported by existing compiled languages or existing compilers, e.g., the C++ language and C++ compilers. Incorporating such a change into an existing language such as C++ would involve changing the C++ standard and rewriting C++ and C++ compilers. To avoid the need for such alterations to the C++ language it is highly desirable to provide the above described functionality as a meta-function, i.e., one that uses existing C++ functionality to provide even greater functionality and programming flexibility. The methods of the present invention achieve the above described functionality without requiring alterations to existing languages by using compiler preprocessor directives such as the "# define" and "# include" directives supported by many existing compilers including existing C++ compilers. In accordance with the present invention, by placing the meta-function in its own file and then using a series of # defines followed by a # include directive, e.g., in the main program, the functionality afforded by the above syntax is generally achieved. FIGS. 2A and 2B collectively illustrate a meta-function programming method of the present invention whereby the above described functionality can be achieved using an existing language, e.g., the C++ language. The method illustrated in FIGS. 2A-2B will be explained with references to FIG. 3 which illustrates an example of a meta-function which is passed code as an argument. Referring now to FIG. 2A, the programming method of the present invention begins with the start step 202. In this step, the computer system receives an input signal from, e.g., the user input device 170 indicating that a user, e.g., programmer, wants to create a new program. In response to this input, the processor 124 begins executing a program editor which may be included as part of the compiler 133 or as a separate application program 128. Once the processor 124 initializes the program editor, operation progresses to step 204. In step 204, the programmer, using the computer system 120, generates a function routine, e.g., representing a meta-function such as that illustrated in block 302 of FIG. 3, which includes one or more undefined labels representing code arguments. A graphical representation of a meta-function generated in step 204 is illustrated in FIG. 4. The meta-function 400 receives standard function arguments 404, one or more code arguments 402, and returns a value 406, e.g., void. The code argument labels are left undefined in the meta-function. Referring now to FIG. 3, in block 302 the relatively simple meta-function MetaEx1.h is illustrated. Note that this meta-function defines a function with the name FXN which returns a value which is void. For purposes of the FIG. 3 example, no function arguments are passed to the meta-function as indicated by the empty () following FXN. However, it should be understood that standard function arguments may be passed to such a meta-function if desired as illustrated in FIG. 4. In MetaEx1.h the code argument label LABEL is used but not defined. While the code argument label LABEL is not defined in MetaEx1.h, at the end of FXN it is undefined in accordance with common programming practice since its use is complete for the particular function. This operation is merely a matter of good programming practice so that the label LABEL can be reused. Referring again to FIG. 2, after the meta-function is generated in step 204, in step 206 it is saved in memory 126. Operation then progresses to step 208 wherein a program segment is generated. This program segment may be part of, e.g., a main program being generated such as Main.crp illustrated in block 304 of FIG. 3. The generated program segment, e.g., segment 305 of FIG. 3, includes one or more compiler directives, e.g., # define directives, that define the code argument label(s) used in the previously generated meta-function. These definition directives are followed by a compiler directive, e.g., an # include directive, which instructs a compiler to include the previously generated meta-function, e.g., MetaEx1.h, in the program segment being generated before the compilation operation is performed. From step 208, operation progresses to step 210 which involves repeating step 208 as many times as desired for a particular application. Thus, in step 210 the previously generated meta-function is reused one or more times. With each reuse of the meta-function, a different code argument can be passed to the meta-function via the definition assigned to the label(s) used in the meta-function. A new name may also be assigned to the function created by re-including the meta-function. Consider for example, Main.crp 304 illustrated in FIG. 3. In step 208 program segment 305 is initially generated. This segment passes the code argument "a+b" to MetaEx1.h by defining LABEL as "a+b". Program segment 305 also renames FXN as the function ADD thereby creating an ADD function in Main.crp using the meta-function MetaEx1.h. In step 210, step 208 is repeated. In the example of FIG. 3 this results in the second program segment 307 being generated. This segment 307 passes the code argument "a-b" to MetaEx1.h by defining LABEL as "a-b". Note that this effectively alters the functionality of FXN which is defined in program segment 307 as the function "SUB" to reflect the operation performed by the newly created function. Operation progresses from step 210 to step 212. In step 212, the generated program segments are arranged to generate a main program suitable for compilation. This may involve e.g., combining the previously generated program segments into a single file and adding additional program segments including, e.g., standard functions. FIG. 5, illustrates a main program 500 generated in accordance with step 212. The main program 500 includes the meta-function ADD 502 which incorporates the code argument a+b 504, the meta-function SUB 506 which incorporates the code argument a-b 508 and a standard function 510. After the main program is generated in step 212 of FIG. 2A, in step 214 it is stored in the memory 126. Operation then progresses to step 216 wherein the processor 124 compiles the main program using the compiler 133. The compilation operation is generally performed in two steps. First the compiler processes the program being compiled in response to the compiler directives included in the program. In this portion of the compilation process, the code substitutions and other operations specified by the compiler directives are performed to generate what is referred to as a "preprocessed program". The preprocessed program is then compiled to generate object code which is used to control the processor 124 to perform the desired processing operation, e.g., image processing operation. After compilation, the compiled program is stored in memory 126 as indicated in step 218, e.g., in the applications segment thereof, and the method is completed as indicated by the stop step 220. Referring once again to FIG. 3, block 306 illustrates the preprocessed program resulting from the first step of the compilation of the program Main.crp. As illustrated, the # preprocessed program includes two distinct functions, the ADD function and the SUB function both of which were created using the original meta-function MetaEx1.h. Note how the code argument a+b was substituted by the compiler for the first occurrence of LABEL while a-b was substituted for the second occurrence of LABEL as a result of the # define directives. Note also how the use of the # include directives resulted in the inclusion of the MetaEx1.h code in the preprocessed program 306. The result of executing the stored program produced as a result of preprocessing and compiling Main.crp 304 is illustrated in block 308. Note the difference in the value of c caused by the alteration of the functionality of the meta-function MetaEx1.h achieved though the use of two different code arguments, first a+b and then a-b. While the above described example of a meta-function is a relatively simple one, it can be appreciated that the meta-function programming technique of the present invention can be used to generate far more complicated functions which will be included in a program at compilation time as opposed to run time. A slightly more complicated example of a meta-function which uses template arguments to provide greater programming flexibility will now be described. In accordance with the present invention, a C++ compatible meta-function can be generated by placing the following code within a file called "PrintCalculation.h":
______________________________________
template <class TYPE1, class TYPE2>
void FunctionName (TYPE1 variable1, TYPE2 variable2)
// this is an example of a meta function which
// uses templated arguments, as well as code arguments
// print the original values
cout << variable1 << " " << variable2 << " ";
// apply some unknown block of code
CodeArgument1;
// print the intermediate values
cout << variable1 << " " << variable2 << " ";
// apply another unknown block of code
CodeArgument2;
// print the final values
cout << variable1 < " " << variable2 << EOL;
}
#undef FunctionName
#undef CodeArgument1
#undef CodeArgument2
______________________________________
The meta-function can then be used by generating a program segment which uses the following series of # defines to pass code arguments to the meta-function followed by an # include directive to instantiate the meta-function:
______________________________________
#define FunctionName SumSqrAndSqrtSumSqr,
#define CodeArgument1 { variable1 *= variable1;
variable2*= variable2; }
#define CodeArgument2 { variable1 += variable2; variable2 =
sqrt(variable1); }
#include "PrintCaculation.h"
______________________________________
The above program segment effectively produces a function titled SumSqrAndSqrtSumSqr using the meta-function "PrintCalculation.h". In addition to generating the function SumSqrAndSqrtSumSqr, the meta-function "PrintCalculation.h" can be used in accordance with the present invention to generate other similar functions. Consider the following program which uses three program segments each of which uses the meta-function "PrintCalculation.h":
______________________________________
#include "stdio.h"
#include "conio.h"
#define FunctionName SumSqrAndSqrtumSqr,
#define CodeArgument1 { variable1 *= variable1;
variable2*= variable2; }
#define CodeArgument2 { variable1 += variable2; variable2 =
sqrt(variable1); }
#include "PrintCaculation.h"
#define FunctionName AverageAndVariance,
#define CodeArgument1 ( TYPE1 temp = variable2; .backslash.
variable2 = sqr(variable1) + sqr(variable2);.backslash.
variable1 += temp;
#define CodeArgument2 { variable1 /= 2;.backslash.
variable2 = variable2/2 - sqr(variable1); }
#include "PrintCaculation.h"
#define FunctionName SqrAndCube,
#define CodeArgument1 { variable2 = variable1; .backslash.
variable1 *= variable1; }
#define CodeArgument2 { variable2 *= variable1; }
#include "PrintCaculation.h"
void main(void)
SumsqrAndSqrtSumSqr(6, 8);
AverageAndVariance(6, 8);
SqrAndCube(6, 8);
}
______________________________________
The output the above program at execution time, after it has been compiled will be:
______________________________________
6 8 36 64 100 10
6 8 14 100 7 1
6 8 36 6 36 212
______________________________________
Though the above program, which uses the meta-function "PrintCalculation.h" multiple times, is more manageable and compact than copying the main body of the function "PrintCalculation.h" three times, the more significant advantage of the programming method of the present invention relates to the use of a single block of code, e.g., the meta-function, to provide common functionality to all the functions in the group of functions which use the meta-function. Changes to the functionality, e.g., to correct bugs, can be easily made in a uniform manner to all the functions in the group by merely modifying the meta-function. Consider, for example, changing the format for the output of the three above described functions generated using "PrintCalculation.h". In accordance with the method of the present invention, to change the print format of the three functions all we need to do is modify the single file "PrintCalculation.h" and the changes are automatically incorporated into each of the three functions generated therefrom. For example if we change the meta-function "PrintCalculation.h" to:
______________________________________
template <class TYPE1, class TYPE2>
void FunctionName (TYPE1 variable1, TYPE2 variable2)
// this is an example of a meta function which
// uses templated arguments, as well as code arguments
// print the function information
cout << "Now entering function: "<< .sub.-- FUNCTION.sub.-- <<"";
// print the original values
cout << "with initial arguments: "variable1
<< "and "<< variable2 << "."<< EOL:
// apply some unknown block of code
CodeArgument1;
// print the intermediate values
cout << "The intermediate values are: " variable1
<< "and " << variable2 << "." << EOL;
// apply another unknown block of code
CodeArgument2;
// print the final values
cout << "The resulting values are: "variable1
<< "and " << variable2 << "." << EOL << EOL;
}
#undef FunctionName
#undef CodeArgument1
#undef CodeArgument2
______________________________________
The output at execution time becomes:
______________________________________
Now entering function SumSqrAndSqrtSumSqr with initial
arguments 6 and 8.
The intermediate values are: 36 and 64.
The resulting values are: 100 and 10.
Now entering function AverageAndVariance with initial
arguments 6 and 8.
The intermediate values are: 14 and 100.
The resulting values are: 7 and 1.
Now entering function SqrAndCube with initial arguments 6
and 8.
The intermediate values are: 36 and 6.
The resulting values are: 36 and 212.
______________________________________
As discussed above, while various compiled programming languages provide a mechanism for multiple executions of the same code, e.g., using a standard looping mechanism such as a "for" or "while" loop, they fail to provide an explicit mechanism for reusing meta-function code repeatedly for several different instantiations of functions specified prior to compilation. Having described the meta-function programming technique of the present invention, meta-loops will now be discussed. A meta-loop is a programming device which allows for the generation of unrolled loops of repeated code prior to compilation. This is in sharp contrast to conventional programming techniques where code is executed a variable number of times at run time. In accordance with the present invention the actual number of times the code is repeated can be specified, e.g., in a header of a main program, just before compilation. Accordingly, the number of loops need not be specified at the initial programming time as long as the number of loops is specified at or before compile time. By using the above described meta-function programming techniques in combination with the meta-loop programming techniques of the present invention, the functionality of the code being repeated can be varied, e.g., each time a meta-loop is called. This provides an extremely efficient and flexible way to reuse code. FIG. 6 graphically illustrates a meta-loop 602, and the repeating blocks of code generated via a preprocessing operation 609 as a result from using the meta-loop 602. As illustrated, the meta-loop receives control parameters s 604 and e 606, which represent meta-loop start and meta-loop end counter values, respectively, and a code argument 608. Although a single code argument 608 is illustrated, multiple code arguments may be used with the meta-loop 602. The meta-loop 602 may also receive standard function arguments in addition to the illustrated code argument 608. The meta-loop control parameters are specified, e.g., in a main program file before compilation using e.g., # define compiler directives. As a result of the preprocessing process 609, repeated blocks of code 610 beginning with the starting value specified by the meta-loop control parameter s and ending with the meta-loop control parameter e are generated. The repeated code blocks 610 need not be identical since they can be implemented to incorporate different code arguments, e.g., as a function of the control parameters, e.g., the first of the repeated code blocks may implement a function LABEL1, the second may implement a function LABEL2, . . . and the last LABELEND. The illustrated meta-loop counter values 612 each correspond to a different iteration of the meta-loop code and, as will be discussed below, are achieved in one exemplary embodiment through the use of conditional compiler pre-processor directives as opposed to an incrementing counter routine. FIGS. 7A and 7B are a flow chart collectively illustrating a programming method for implementing a meta-loop in accordance with one embodiment of the present invention. The method illustrated in FIGS. 7A and 7B will now be described with reference to FIGS. 8 and 9. The meta-loop programming method of the present invention illustrated in FIGS. 7A and 7B begins with the start step 702. In this step, the computer system 120 receives an input signal from, e.g., the user input device 170 indicating that the programmer wants to create a new program or program segment. In response to this input, the processor 124 begins executing the program editor application if it is not already executing. From step 702, operation progresses to step 704, wherein a meta-loop function routine, e.g., the routine 802 is generated. The generated function routine includes one or more labels representing control parameters, e.g., loop start and loop end parameters. For example, function 802 includes the label MetaLoopEnd which represents a control parameter used to determine the number of loop iterations to be performed. For purposes of providing a simplified example, the loop counter always beings at one and no control parameter is used to determine the starting point of the loop. In addition to the label(s) representing control parameters, the function generated in step 704 includes one or more conditional compiler directives used to effectively implement a loop counter without having to actually use a counter routine. Consider for example, the function 802 which includes the conditional compiler directives # if and # else. A set of such conditional compiler directive is used to implement each one of the possible iterations of the meta-loop upto the maximum number of supported iterations represented by MaxNumLoops. The maximum number of loop iterations supported by a meta-loop is normally determined at the time the meta-loop function 802 is created. Accordingly, MaxNumLoops represents a fixed integer number normally determined when the meta-loop is created. The # if statement involves a testing of the loop start and end conditions. In the function 802, since only an end parameter MetaLoopEnd is used, only this parameter needs to be analyzed in the # if condition statement to determine if a block of code representing an iteration of the loop should be included in a program calling the meta-loop through, e.g., the use of a # include compiler directive. If the loop conditions are satisfied, the code immediately following the # if statement will be processed, e.g., a function corresponding to the iteration of the loop represented by the # if statement will be defined using a label which represents a code argument. However, if the loop condition is not satisfied, the code immediately following the # else statement will be processed instead and this code will define the function to be null. After the conditional statements, each of the individual functions corresponding to one of the iterations of the loop is recited. Consequently, the functions, defined as corresponding to labels, include the code corresponding to the label. Functions defined as null will contribute no code to the compiled program. After the meta-loop function, e.g., Meta.sub.-- forEx1.h 802, is generated in step 704, it is stored in memory, e.g., in a separate file titled Meta.sub.-- forEx1.h which can be incorporated into subsequently generated programs, e.g., through the use of a # include compiler directive. The storing of the meta-loop function occurs in step 706. From step 706 operation progresses to step 708 in which a program segment 805 is generated. The program segment includes one or more compiler directives, e.g., # define directives, that define labels used as control parameters, e.g., MetaLoopEnd, used in the previously generated meta-loop 802. The first line of program segment 805 serves this purpose by defining MetaLoopEnd to be 3. The program segment generated in step 708 also includes one or more compiler directives, e.g., # define directives, which define the label(s) in the previously generated meta-loop function representing code arguments. In this manner, code arguments are passed from the program segment to the meta-loop. In program segment 805, the second line of code performs this operation. Note the use of the concatenation compiler directive ## in the code argument being passed to the meta-loop, e.g., in line 2 of program segment 805. The use of this compiler directive increases the versatility of the programming technique of the present invention. In addition to defining meta-loop control parameters and meta-loop arguments, the program segment 805 generated in step 708 includes a compiler directive, e.g., a # include directive, which instructs the compiler to incorporate the generated meta-loop function. The third line of program segment 805 performs this function and instructs a compiler to include the meta-loop function Meta.sub.-- forEx1.h 802 into program segment 805. From step 708, operation progresses to step 710 in which step 708 is repeated as may times as desired. In this manner, the meta-loop Meta.sub.-- forEx1.h is used repeatedly. Program segment 807 represents a program segment which is generated by repeating step 708. Note that in program segment 807, the control parameter MetaLoopEnd is set to 5 in order to generate 5 iterations of code as opposed to 3. While the code argument passed to the meta-loop function is the same in the example of FIG. 8, this need not be the case. From step 710 operation progresses to step 712 wherein the program segments are arranged to form a main program routine which optionally includes, e.g., additional program segments, standard functions and program headers. After the main program is generated in step 712, in step 714 it is stored in the memory 126. Operation then progresses to step 716 wherein the processor 124 compiles the main program, e.g., Main.crp 804 using the compiler 133. As previously discussed, the compilation process is performed in two steps with the compiler processing the compiler directives included in the program being compiled in the first step. The preprocessed program resulting from the code substitutions, conditional compiler operations, and file inclusions performed by the compiler 133 on the program Main.crp is illustrated in block 902 of FIG. 9. As can be seen, as a result of the meta-loop being used twice in the program Main.crp, with a different control parameter being used each time, the code argument passed to the meta-loop is repeated in the preprocessed program a different number of times each timer the meta-loop is used. The number of times the code argument is repeated corresponds to the number of times specified by the control parameter MetaLoopEnd passed to the meta-loop Meta.sub.-- forEx1.h 802. As a result of setting MetaLoopEnd to three the first time Meta.sub.-- LoopEx1.h is used results in the first three lines of code, 901, being generated while setting MetaLoopEnd to five the second time Meta.sub.-- LoopEx1.h is used results in the five lines of code, 903, being generated. After generation of the preprocessed program 902, as shown in step 716, the preprocessed program is compiled into object code representing the compiled program. In step 718 the compiled program is stored in the memory 126, e.g., in the applications segment thereof and the method is completed as indicated by the stop step 720. The result of executing the program produced by compiling Main.crp 804 is illustrated in block 904. Note the first three lines 905 result from the initial use of the meta-loop Meta.sub.-- ForEx1.h and the subsequent 5 lines 907 result from the second use of the meta-loop Meta.sub.-- ForEx1.h. Note also how the use of the concatenation compiler directive allowed the number representing the loop iteration to be concatenated to Iin. A slightly more complicated example of Meta-loop programming will now be discussed using an example directly applicable to an image processing application which performs operations on pixel data stored as a function of the pixel's row and column coordinates within an image. As discussed above, in image processing applications there are occasions where it is desirable to be able to force a compiler to generate a block of code multiple times, e.g., when making a function which will have a fixed number of input arguments which is to be determined after the time the function is generated but before compilation time. A meta-loop construction can provide such desired functionality if it is supported by a compiler's syntax. One example of a possible hypothetical syntax for a meta-loop is:
______________________________________
Image SumImages(const Image &image0
MetaLoop(n=1; n<NumberOfImages; n++)
( , const Image &image##n ))
Image imageResult;
imageResult.Allocate(image1.Shape())
for (int col=0; col<image0.NCols(); col++)
for (int row=0; row<image0.NRows(); row++)
MetaLoop(n=0; n<numberOfImages; n++)
{
imageResult.Pixel(row,col)
+=image##n.Pixel(row, col);
}
}
______________________________________
If, say NumberOfImages were defined to be 5, this meta-loop would generate the code:
______________________________________
Image SumImages ( const Image &image0, const Image &image1
const Image &image2, const Image &image3,
const Image &image4)
Image imageResult;
imageResult.Allocate (image0.Shape ())
for (int col=0; col<image0.NCols(); col++)
for (int row=0; row<image0.NRows(); row++)
}
imageResult.Pixel (row,col) += image0.Pixel (row,col);
imageResult.Pixel (row,col) += image1.Pixel (row,col);
imageResult.Pixel (row,col) += image3.Pixel (row,col);
imageResult.Pixel (row,col) += image4.Pixel (row,col);
}
}
______________________________________
One advantage of using a meta-loop is that if, at some point, the number of images on which the function operates is to be changed, such change may be effected by simply changing the value of NumberofImages. No modification of the function code is required. Unfortunately, C++ and other existing compiled languages do not presently support such meta-loops and incorporating a meta-loop operator would require a change to existing compilers and/or standards such as the C++ standard. By using the presently existing C++ "# include" and "# define" compiler preprocessor directives, the desired meta-loop functionality is achieved in accordance with the present invention without requiring any changes to existing C++ compilers. This functionality is achieved by placing a series of meta-loop control macros representing a meta-loop in a separate file and then using a series of # define's and # include compiler directives in the main program to achieve the functionality afforded by the above described hypothetical meta-loop syntax. To generate a meta-loop in this image processing example, a series of macros, which either perform the operation defined by a code argument specified by a label, e.g., MetaLoop, or do nothing (depending on whether or not a control parameter in the macros is less than a specified end value, represented by MetaLoopEnd) are first defined within a file, e.g., the file "MetaLoop.h". For example the following code could be placed in a file called MetaLoop.h:
______________________________________
#if MetaLoopstart <= 1 && MetaLoopEnd >= 1
# define MetaLoopIteration1 MetaLoop(1)
#else
# define MetaLoopIteration1
#endif
#if MetaLoopstart <= 2 && MetaLoopEnd>=2
# define MetaLoopIteration2 MetaLoop(2)
#else
# define MetaLoopIteration2
#endif
#if MetaLoopStart <= 3 && MetaLoopEnd >= 3
# define MetaLoopIteration3 MetaLoop (3)
#else
# define MetaLoopIteration3
#endif
.
.
#if MetaLoopStart <= MetaLoopMax &&
MetaLoopEnd >= MetaLoopMax
# define MetaLoopIteration3 MetaLoop (3)
#else
# define MetaLoopIteration3
#endif
//where MetaLoopMax is a preselected constant, e.g., 20
MetaLoopIteration1 //instantiate macros
MetaLoopIteration2
MetaLoopIteration3
.
.
.
MetaLoopIterationMetaLoopMax
______________________________________
Having created a file MetaLoop.h with the above code and conditional compiler directives, macros, which include, e.g., a code argument which describes the action to be performed, and one or more control parameters which define the number of times the action described by the code argument is to be performed, are then defined. In this example:
______________________________________
#define MetaLoopStart 1 .sup. //define start control parameter
#define MetaLoopEnd NumberOfImages //define end control parameter
#define MetaLoop(n) , const Image &image##n //define code
______________________________________
argument
is defined for a first meta-loop to be used in an image processing program and;
______________________________________
#define MetaLoopStart 0
#define MetaLoopEnd NumberOfImages
#define MetaLoop(n) imageResult.Pixe1(row,col) +=
image##n.Pixel(row,col);
______________________________________
is defined for a second meta-loop to be included in the image processing program. To instantiate a meta-loop function in accordance with the present invention one need only # include the "MetaLoop.h" file, e.g., after defining the control parameters and code arguments to be used with the meta-loop. For the above example, use of this technique to write an image processing program, e.g., Proc.sub.-- Image.crp is as follows:
______________________________________
Image SumImages(const Image &image0
#define MetaLoopStart 1
#define MetaLoopEnd NumberofImages
#define MetaLoop(n) , const Image &image##n
#include "MetaLoop.h"
Image imageResult;
imageResult.Allocate (image0.shape ())
imageResult=CopyOf (image)0;
for (int col=0; col<image0.NCols(); col++)
for (int row=0; row<image0.NRows(); row++)
{
#define MetaLoopStart 0
#define MetaLoopEnd NumberOfImages
#define MetaLoop(n) imageResult.Pixel(row1col) +=
image##n.Pixel (row,col);
#include "MetaLoop.h"
}
}
______________________________________
As discussed above, by combining meta-functions and meta-loops, which are a particular type of meta-function, it is possible to produce an elaborate set of meta-functions which can be used, e.g., to generate optimized image processing and computer vision routines which reduce or avoid the delays associated with run time function calls. In accordance with the above discussed programming techniques of the present invention, meta-functions can allow a variable number of input images which can be specified at or just before compile time, different return types, access to the data of neighboring pixels, additional parameters and/or adjustable initialization. FIG. 10 graphically illustrates a meta-function 1000 which receives a code argument 1004, a meta-loop 1001, and standard function arguments 1002 as illustrated. Using the meta-function and meta-loop programming techniques of the present invention it is possible to generate a general image processing meta-function. For example, the following general image processing meta-function code could be generated using the above discussed meta-loop function MetaLoop.h, and could be placed in a file
______________________________________
Image FunctionName (const Image &image0
#define MetaLoopStart 1
#define MetaLoopEnd NumberofImages
#define MetaLoop(n) , const Image &image##n
#include "MetaLoop.h"
)
Image imageResult;
imageResult.Allocate (image1.Shape ())
for (int col=0; col<image0.NCols(); col++)
for (int row=0; row<image0.NRows(); row++)
{
#define MetaLoopstart 0
#define MetaLoopEnd NumberofImages
#define MetaLoop(n) CodeArgument(n);.
#include "MetaLoop.h"
}
}
#undef CodeArgument
#undef NumberofImages
#undef FunctionName
______________________________________
Using the above exemplary general image processing meta-function, GeneralImageFunction.h, a host of different image-processing routines, e.g., in the form of program segments, can easily be generated. For example, first consider the following program segment which will sum 5 images using the meta-function
______________________________________
#define FunctionName SumOf
#define NumberOfImages 5
#define CodeArgument(n) imageResult.Pixel(row,
col)+=image##n.Pixel(row,col);
#include GeneralImageFunction.h
______________________________________
Also consider for example the following program segment which also uses use the same meta-function, GeneralImageFunction.h, to get the exclusive-or (XOR) of 7 images:
______________________________________
#define FunctionName XOROf
#define NumberOfImages 7
#define CodeArgument(n)
imageResult.Pixel(row,col) =image##n.Pixel(row,col);
#include GeneralImageFunction.h
______________________________________
In addition GeneralImageFunction.h can be used to do alpha channel compositing as per the following exemplary program segment:
______________________________________
#define FunctionName XOROf
#define NumberofImage 7
#define CodeArgument(n) if (imageResult.Pixel(row,col).A()<1).backslash.
imageResult.Pixel(row,col)+=image##n.Pixel (row,
col).A()*image##n.Pixel(row,col);
# include GeneralImageFunction.h
______________________________________
The above discussions of exemplary embodiments of the present invention describe generating a meta-function routine and storing it in memory, e.g., in a file, before the creation of program segments which utilize the generated meta-function. However, the order of the creation of the program segments which use a meta-function and the creation of the meta-function itself is not critical to the invention. Accordingly, a meta-function may be generated after a program segment which uses the meta-function so long as both the program and meta-functions used therein exist prior to preprocessing of the program. While the present invention has been illustrated with reference to exemplary embodiments, those skilled in the art will appreciate that various changes in form and detail may be made without departing from the intended scope of the present invention as defined in the appended claims. Because of the variations that can be applied to the illustrated and described embodiments of the invention, the invention should be defined with reference to the appended claims.
|
Same subclass Same class |
||||||||||
