home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
listings
/
v_10_11
/
1011099a
< prev
next >
Wrap
Text File
|
1992-09-02
|
19KB
|
554 lines
/***********************************************
*
* file d:\cips\scale.c
*
* Functions: This file contains
* zoom_image_array
* shrink_image_array
* interpolate_pixel
* average_pixel
* median_pixel
* get_scaling_options
* blank_image_array
*
* Purpose:
* These functions implement image array
* zooming (enlarging) and shrinking.
*
* External Calls:
* wtiff.c - does_not_exist
* round_off_image_size
* create_allocate_tiff_file
* write_array_into_tiff_image
* tiff.c - read_tiff_header
* rtiff.c - read_tiff_image
* rstring.c - read_string
* numcvrt.c - get_integer
* filter.c - median_of
*
* Modifications:
* 8 April 1992 - created
*
*************************************************/
#include "d:\cips\cips.h"
#include <malloc.h>
/*******************************************
*
* zoom_image_array(...
*
* This function zooms in on an input
* image array. It zooms by enlarging
* an input image array and writing the
* resulting image arrays to an output
* image file. It can zoom or enlarge by
* a factor of 2 or 4.
*
* You can zoom or enlarge an image array
* by using either the replication or
* interpolation methods.
*
*******************************************/
zoom_image_array(in_name, out_name, the_image, out_image,
il, ie, ll, le, scale, method)
char in_name[], out_name[], method[];
int il, ie, ll, le, scale;
short the_image[ROWS][COLS],
out_image[ROWS][COLS];
{
int A, B, a, b, count, factor, i, j, length, width;
struct tiff_header_struct image_header;
/*******************************************
*
* Check the scale factor. If it is not
* a valid factor (2 or 4), then set
* it to 2.
*
*******************************************/
factor = scale;
if(factor != 2 &&
factor != 4) factor = 2;
if(does_not_exist(out_name)){
printf("\n\n output file does not exist %s", out_name);
read_tiff_header(in_name, &image_header);
image_header.image_length = ROWS*factor;
image_header.image_width = COLS*factor;
create_allocate_tiff_file(out_name, &image_header,
out_image);
} /* ends if does_not_exist */
/*******************************************
*
* Let me try to explain the nested loops
* shown below.
*
* We will enlarge the_image by the factor.
* Therefore, we want to divide the_image
* into parts of size ROWS/factor by
* COLS/factor. We will loop through
* the_image parts ROWS/factor and COLS/factor
* using the loops over i and j.
*
* We divided the_image into parts so we must
* include all of these parts. That is why we
* do the loops over A and B. There are
* factor*factor parts.
*
* Finally, we do the loops over a and b.
* We must replicate every element in the_image
* factor*factor times and put these into
* out_image. The a and b loops perform this
* task.
*
* The equations inside the []'s for
* the_image and out_image are also confusing.
* If you work them out, you'll see that we
* are bouncing through the image arrays
* and fitting the pixels into the right
* places.
*
* The final proof is that this works.
*
* One final note: the factor should divide
* evenly into ROWS. For example, ROWS=100
* so using a factor of 8 is not good.
* 100/8 = 12.5 and this leave you with
* an empty strip along the right and
* bottom edges of the out_image.
*
*******************************************/
/*******************************************
*
* Replication method
*
*******************************************/
if(method[0] == 'r' || method[0] == 'R'){
read_tiff_image(in_name, the_image, il, ie, ll, le);
count = 1;
for(A=0; A<factor; A++){
for(B=0; B<factor; B++){
for(i=0; i<ROWS/factor; i++){
for(j=0; j<COLS/factor; j++){
for(a=0; a<factor; a++){
for(b=0; b<factor; b++){
out_image[factor*i+a][factor*j+b] =
the_image[i+A*ROWS/factor][j+B*COLS/factor];
} /* ends loop over b */
} /* ends loop over a */
} /* ends loop over j */
} /* ends loop over i */
printf("\nzooming replication %3d of %3d",
count++, factor*factor);
write_array_into_tiff_image(out_name, out_image,
1+A*ROWS, 1+B*COLS, 101+A*ROWS, 101+B*COLS);
} /* ends loop over B */
} /* ends loop over A */
} /* ends replication method */
/***************************
*
* Interpolation method
*
****************************/
if(method[0] == 'i' || method[0] == 'I'){
read_tiff_image(in_name, the_image,
il, ie, ll, le);
count = 1;
for(A=0; A<factor; A++){
for(B=0; B<factor; B++){
for(i=0; i<ROWS/factor; i++){
for(j=0; j<COLS/factor; j++){
for(a=0; a<factor; a++){
for(b=0; b<factor; b++){
out_image[factor*i+a][factor*j+b] =
interpolate_pixel(the_image, A, B,
i, j, a, b, factor);
} /* ends loop over b */
} /* ends loop over a */
} /* ends loop over j */
} /* ends loop over i */
printf("\nzooming interpolation %3d of %3d",
count++, factor*factor);
write_array_into_tiff_image(out_name, out_image,
1+A*ROWS, 1+B*COLS,
101+A*ROWS, 101+B*COLS);
} /* ends loop over B */
} /* ends loop over A */
} /* ends interpolation method */
} /* ends zoom_image_array */
/***********************************************
*
* interpolate_pixel(...
*
* This function interpolates between pixel
* values and returns the interlopated value.
*
***********************************************/
interpolate_pixel(the_image, A, B, i, j, a, b, factor)
int A, B, a, b, factor, i, j;
short the_image[ROWS][COLS];
{
int num, x = 0, y = 0;
short diff, result;
if(a > 0) y = 1;
if(b > 0) x = 1;
diff = the_image[y+i+A*ROWS/factor][x+j+B*COLS/factor] -
the_image[i+A*ROWS/factor][j+B*COLS/factor];
/***********************************************
*
* If you are at the edge of the input image
* array, then you cannot interpolate to the
* next point because there is no next point.
* Therefore, set the diff to 0.
*
***********************************************/
if((y+i+A*ROWS/factor) >= ROWS) diff = 0;
if((x+j+B*COLS/factor) >= COLS) diff = 0;
num = a+b;
if(num > factor) num = factor;
result = the_image[i+A*ROWS/factor][j+B*COLS/factor] +
num*diff/factor;
return(result);
} /* ends interpolate_pixel */
/*******************************************
*
* shrink_image_array(...
*
* This function shrinks a part of an
* image. It takes a part of an input
* image (described by il1, ie1, ll1, le1)
* shrinks a 200x200 or 400x400 area down
* to a 100x100 array, and writes this result
* to an output file. The location in the
* output file is described by il2, ie2,
* ll2, le2.
*
* You can shrink the input image area
* by using either the averaging, median,
* or corner method.
*
*******************************************/
shrink_image_array(in_name, out_name, the_image, out_image,
il1, ie1, ll1, le1, il2, ie2, ll2, le2,
scale, method)
char in_name[], out_name[], method[];
int il1, ie1, ll1, le1,
il2, ie2, ll2, le2, scale;
short the_image[ROWS][COLS],
out_image[ROWS][COLS];
{
int A, B, a, b, count, factor, i, j, length, width;
struct tiff_header_struct image_header;
/*******************************************
*
* Check the scale factor. If it is not
* a valid factor (2 or 4), then set
* it to 2.
*
*******************************************/
factor = scale;
if(factor != 2 &&
factor != 4) factor = 2;
if(does_not_exist(out_name)){
printf("\n\n output file does not exist %s", out_name);
read_tiff_header(in_name, &image_header);
image_header.image_length = ROWS;
image_header.image_width = COLS;
create_allocate_tiff_file(out_name, &image_header,
out_image);
} /* ends if does_not_exist */
read_tiff_header(in_name, &image_header);
/*******************************************
*
* Let me try to explain the nested loops
* shown below.
*
* We will shrink the_image by the factor.
* Therefore, we want to read in factor*factor
* image arrays and produce one ROWS by COLS
* array for writing to disk.
* That is why we loop over A and B.
*
* We want to set every pixel in the out_image
* array so we loop over i and j.
*
* The equations inside the out_image []'s
* look a little strange. What we are doing is
* setting every element and moving over every
* time through the loops over A and B. The first
* loop is for i=0,49 then i=50,99 for a factor=2
* and ROWS=100.
*
* The final proof is that this works.
*
* One final note: the factor should divide
* evenly into ROWS. For example, ROWS=100
* so using a factor of 8 is not good.
* 100/8 = 12.5 and this leave you with
* an empty strip along the right and
* bottom edges of the out_image.
*
*******************************************/
/********************************
*
* Corner method
*
*********************************/
if(method[0] == 'c' || method[0] == 'C'){
count = 1;
for(A=0; A<factor; A++){
for(B=0; B<factor; B++){
printf("\n shrinking by corner %3d of %3d",
count++, factor*factor);
if(image_header.image_length < il1+A*ROWS ||
image_header.image_width < ie1+B*COLS)
blank_image_array(the_image);
else
read_tiff_image(in_name, the_image,
il1+A*ROWS, ie1+B*COLS,
ll1+A*ROWS, le1+B*COLS);
for(i=0; i<ROWS/factor; i++){
for(j=0; j<COLS/factor; j++){
out_image[i+A*ROWS/factor][j+B*COLS/factor] =
the_image[factor*i][factor*j];
} /* ends loop over j */
} /* ends loop over i */
} /* ends loop over B */
} /* ends loop over A */
write_array_into_tiff_image(out_name, out_image,
il2, ie2, ll2, le2);
} /* ends corner method */
/******************************
*
* Average Method
*
******************************/
if(method[0] == 'a' || method[0] == 'A'){
count = 1;
for(A=0; A<factor; A++){
for(B=0; B<factor; B++){
printf("\n shrinking by average %3d of %3d",
count++, factor*factor);
if(image_header.image_length < il1+A*ROWS ||
image_header.image_width < ie1+B*COLS)
blank_image_array(the_image);
else
read_tiff_image(in_name, the_image,
il1+A*ROWS, ie1+B*COLS,
ll1+A*ROWS, le1+B*COLS);
for(i=0; i<ROWS/factor; i++){
for(j=0; j<COLS/factor; j++){
out_image[i+A*ROWS/factor][j+B*COLS/factor] =
average_pixel(the_image, factor, i, j);
} /* ends loop over j */
} /* ends loop over i */
} /* ends loop over B */
} /* ends loop over A */
write_array_into_tiff_image(out_name, out_image,
il2, ie2, ll2, le2);
} /* ends average method */
/************************
*
* Median Method
*
*************************/
if(method[0] == 'm' || method[0] == 'M'){
count = 1;
for(A=0; A<factor; A++){
for(B=0; B<factor; B++){
printf("\n shrinking by median %3d of %3d",
count++, factor*factor);
if(image_header.image_length < il1+A*ROWS ||
image_header.image_width < ie1+B*COLS)
blank_image_array(the_image);
else
read_tiff_image(in_name, the_image,
il1+A*ROWS, ie1+B*COLS,
ll1+A*ROWS, le1+B*COLS);
for(i=0; i<ROWS/factor; i++){
for(j=0; j<COLS/factor; j++){
out_image[i+A*ROWS/factor][j+B*COLS/factor] =
median_pixel(the_image, factor, i, j);
} /* ends loop over j */
} /* ends loop over i */
} /* ends loop over B */
} /* ends loop over A */
write_array_into_tiff_image(out_name, out_image,
il2, ie2, ll2, le2);
} /* ends median method */
} /* ends shrink_image_array */
/***********************************************
*
* average_pixel(...
*
* This function calculates the average
* pixel value of a factor x factor array
* of pixels inside the the_image array.
* The coordinates i and j point to the upper
* left hand corner of the small array.
*
***********************************************/
average_pixel(the_image, factor, i, j)
int factor, i, j;
short the_image[ROWS][COLS];
{
int a, b, result = 0;
for(a=0; a<factor; a++)
for(b=0; b<factor; b++)
result = result + the_image[factor*i+a][factor*j+a];
result = result/(factor*factor);
return(result);
} /* ends average_pixel */
/***********************************************
*
* median_pixel(...
*
* This function calculates the median
* pixel value of a factor x factor array
* of pixels inside the the_image array.
* The coordinates i and j point to the upper
* left hand corner of the small array.
*
***********************************************/
median_pixel(the_image, factor, i, j)
int factor, i, j;
short the_image[ROWS][COLS];
{
int a, b, count, ff, result = 0;
short *elements;
ff = factor*factor;
elements = (short *) malloc(ff * sizeof(short));
count = 0;
for(a=0; a<factor; a++){
for(b=0; b<factor; b++){
elements[count] = the_image[factor*i+a][factor*j+b];
count++;
}
}
result = median_of(elements, &ff);
free(elements);
return(result);
} /* ends median_pixel */
/***********************************************
*
* blank_image_array(...
*
* This function blanks out an image array
* by filling it with zeros.
*
***********************************************/
blank_image_array(image)
short image[ROWS][COLS];
{
int i, j;
for(i=0; i<ROWS; i++)
for(j=0; j<COLS; j++)
image[i][j] = 0;
} /* ends blank_image_array */
/***********************************************
*
* get_scaling_options(...
*
* This function queries the user for the
* parameters needed to perform scaling.
*
***********************************************/
get_scaling_options(zoom_shrink, scale, method)
int *scale;
char method[], zoom_shrink[];
{
int not_finished = 1, response;
while(not_finished){
printf("\n\t1. Zoom or Shrink is - %s", zoom_shrink);
printf("\n\t2. Scale factor is %d", *scale);
printf("\n\t3. Scaling Method is - %s", method);
printf("\n\t Replication or Interpolation for Zooming"
"\n\t Averaging Median or Corner for Shrinking");
printf("\n\n\tEnter choice (0 = no change) _\b");
get_integer(&response);
if(response == 0){
not_finished = 0;
}
if(response == 1){
printf("\nEnter Zoom or Shrink (z or s) __\b");
read_string(zoom_shrink);
}
if(response == 2){
printf("\nEnter Scale Factor (2 or 4) __\b");
get_integer(scale);
}
if(response == 3){
printf("\nEnter Scaling Method: "
"Replication or Interpolation for Zooming"
"\n "
"Averaging Median or Corner for Shrinking"
"\n\t__\b");
read_string(method);
}
} /* ends while not_finished */
} /* ends get_scaling_options */