home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
drdobbs
/
1989
/
07
/
duvanenk.lst
next >
Wrap
File List
|
1989-06-01
|
12KB
|
356 lines
_IMAGE MATHEMATICS_
by Victor Duvanenko
[LISTING ONE]
/* Created by Victor J. Duvanenko 10-17-88
Image addition using the CPU/80386. The program reads a buffer full of
pixels from two images, adds their pixels together and stores the result
back into the second image.
*/
#include "cmdtypes.h"
#include <stdio.h>
#include <setjmp.h>
#include "const.h"
#include <fcntl.h>
#define DEBUG 0
#define ADD 1
#define DRAW 0
extern int _fmode; /* file mode */
/* CMD configuration parameters: */
unsigned memseg=0xD000; /* memory segment */
int pbase=0x208; /* port base */
/* entire bitmap expressed as a RECT: */
RECT screen={0,0,XRES-1,YRES-1};
POINT vertices[3];
extern jmp_buf errjmp;
int frame_grab=0; /* frame/field grab */
int hiquality=0; /* use high quality image reduction routines? */
/* current video parameters */
int hue=101;
int sat=111;
int con=123;
int bri=40;
/* Red, green and blue buffers */
unsigned char red_1[ 640 * 13 ],
red_2[ 640 * 13 ],
green_1[ 640 * 13 ],
green_2[ 640 * 13 ],
blue_1[ 640 * 13 ],
blue_2[ 640 * 13 ];
/*-------------------------------------------------------------------
Invocation: add_blt
---------------------------------------------------------------------*/
main(argc,argv)
int argc;
char *argv[];
{
register i, tmp, line;
RECT image1;
int saturate;
unsigned char *r1_p, *r2_p, *g1_p, *g2_p, *b1_p, *b2_p;
cmd_init( 0xD000, 0x208 );
cmd_display( 2 );
#if DRAW
cmd_clear( 1 );
cmd_clear( 2 );
cmd_clear( 3 );
cmd_text_fgcolor( 127, 127, 127 );
cmd_text_bgcolor( 0, 0, 0 );
cmd_line_attrib( 0, 0xffff, 127, 127, 127 );
cmd_write_string( 1, 10, 1, "First bitmap." );
cmd_line( 1, 639,0, 0,479 );
cmd_line( 1, 0,0, 639,479 );
cmd_write_string( 2, 20, 1, "Second bitmap." );
cmd_line( 2, 639,0, 0,479 );
cmd_line( 2, 0,0, 639,479 );
#endif
saturate = TRUE;
for( line = 0; line < 480; line += 13 )
{
#if ADD
r1_p = red_1;
r2_p = red_2;
g1_p = green_1;
g2_p = green_2;
b1_p = blue_1;
b2_p = blue_2;
#endif
/* Perform the same operation using the CPU - 80386 in our case. */
image1.llx = 0;
image1.lly = line;
image1.urx = 639;
image1.ury = line + 12;
cmd_read_area( 1, &image1, red_1, green_1, blue_1 );
cmd_read_area( 2, &image1, red_2, green_2, blue_2 );
#if ADD
/* Add all of the pixels together - use pointers for speed. */
if ( !saturate )
for( i = 0; i < 640 * 13; i++ )
{
*r2_p++ += *r1_p++;
*g2_p++ += *g1_p++;
*b2_p++ += *b1_p++;
}
else
for( i = 0; i < 640 * 13; i++, r1_p++, g1_p++, b1_p++ )
{
tmp = (int)( *r2_p ) + (int)( *r1_p );
if ( tmp > 255 ) tmp = 255;
*r2_p++ = (unsigned char)( tmp );
tmp = (int)( *g2_p ) + (int)( *g1_p );
if ( tmp > 255 ) tmp = 255;
*g2_p++ = (unsigned char)( tmp );
tmp = (int)( *b2_p ) + (int)( *b1_p );
if ( tmp > 255 ) tmp = 255;
*b2_p++ = (unsigned char)( tmp );
}
#endif
/* Place them back into bitmap 2 */
cmd_write_area( 2, &image1, red_2, green_2, blue_2, 0 );
}
return( 0 );
} /* end main */
[LISTING TWO]
/*-------------------------------------------------------------------
Procedure that is an extension to 'cmd_copy_image'. It performs
the image copy with an ADD operation.
This procedure figures out which of the 3 bitmaps is not being used
for the operation and uses it for scratch space. The effected area
is at the same location as the destination. The user has to be aware
of this.
---------------------------------------------------------------------*/
static void add_blt( from_bm, image, to_bm, to_x, to_y, saturate )
int from_bm;
RECT *image;
int to_bm,
to_x,
to_y,
saturate; /* 1 - saturate, 0 - don't saturate */
{
register i;
int scratch_bm, one_used, two_used, three_used;
unsigned int mask;
RECT to_image,
to_image1; /* 1 bpp coordinates */
/* Figure out which bitmap is not used in the operation and use it */
/* for scratch space. */
one_used = two_used = three_used = 0;
if ( from_bm == 1 || to_bm == 1 )
one_used = 1;
if ( from_bm == 2 || to_bm == 2 )
two_used = 1;
if ( from_bm == 3 || to_bm == 3 )
three_used = 1;
if ( !one_used )
scratch_bm = 1;
else if ( !two_used )
scratch_bm = 2;
else
scratch_bm = 3;
to_image.llx = to_x;
to_image.lly = to_y;
to_image.urx = to_x + ( image->urx - image->llx );
to_image.ury = to_y + ( image->ury - image->lly );
/* Adjust X only for 8 bpp to 1 bpp conversion */
to_image1.llx = to_x << 3;
to_image1.lly = to_y;
to_image1.urx = (( to_image.urx + 1 ) << 3 ) - 1;
to_image1.ury = to_image.ury;
/* Place a copy of the destination image in scratch space */
cmd_copy_image( to_bm, &to_image, scratch_bm, to_x, to_y, 0 );
/* Form the XOR/SUM result, in the destination bitmap */
cmd_copy_image( from_bm, image, to_bm, to_x, to_y, 1 );
/* Form the AND/CARRY result, in the scratch bitmap */
cmd_copy_image( from_bm, image, scratch_bm, to_x, to_y, 2 );
/* Now bit 0 of all pixels is done */
/* The sum 0 is already in destination bitmap and carry 0 is in AND */
/* We now need to form the sum 1, which is the XOR of bit 1 and carry 0 */
/* This requires bit 1 of destination bitmap to be XOR'ed with bit 0 of */
/* the AND/CARRY bitmap. The result is placed in the destination. */
/* This can not be accomplished at 8 bpp, as all operations happen on */
/* pixel boundaries - 8 bits. Therefore, from this point forward we */
/* must treat our bitmap as 1 bpp, since this allows single bit */
/* manipulation. */
for( i = 1, mask = 0x0202; i < 8; i++, mask <<= 1 )
{
/* Form the sum of bit i. */;
cmd_wm_copy_image( scratch_bm, &to_image1, to_bm, to_image1.llx - 1, to_image1.lly, 1, mask, 1 );
if (( mask == 0x8080 ) && ( !saturate ))
break; /* don't form the cary - done! */
/* Form the carry bit i by first using the carry in and AND'ing */
/* it with !SUM */
cmd_wm_copy_image( to_bm, &to_image1, scratch_bm, to_image1.llx + 1, to_image1.lly, 6, mask >> 1, 1 );
/* Form the OR part of the carry bit i. */
cmd_wm_copy_image( scratch_bm, &to_image1, scratch_bm, to_image1.llx - 1, to_image1.lly, 3, mask, 1 );
}
#if 0
/* the old method - took 8 blits */
/* Saturate the color based on the carry(7). */
if ( saturate )
for ( i = 7, mask = 0x0101; i >= 0; i--, mask <<= 1 )
cmd_wm_copy_image( scratch_bm, &to_image1, to_bm, to_image1.llx + i, to_image1.lly, 3, mask, 1 );
#endif
/* new and faster algorithm - takes only 4 blits */
if ( saturate )
{
/* replicate carry[7] throughout the whole pixel of scratch space */
cmd_wm_copy_image( scratch_bm, &to_image1, scratch_bm, to_image1.llx + 1, to_image1.lly, 0, 0x4040, 1 );
cmd_wm_copy_image( scratch_bm, &to_image1, scratch_bm, to_image1.llx + 2, to_image1.lly, 0, 0x3030, 1 );
cmd_wm_copy_image( scratch_bm, &to_image1, scratch_bm, to_image1.llx + 4, to_image1.lly, 0, 0x0f0f, 1 );
/* saturate the image all bits at once */
cmd_wm_copy_image( scratch_bm, &to_image1, to_bm, to_image1.llx, to_image1.lly, 3, 0xffff, 1 );
}
/* Restore modified bitmaps to 8 bpp */
set_gpbitmap_bpp( to_bm, 8 );
set_gpbitmap_bpp( scratch_bm, 8 );
}
/*-------------------------------------------------------------------
Procedure that is an extension to 'cmd_copy_image'. It performs
the image copy with an ADD operation.
This procedure figures out which of the 3 bitmaps is not being used
for the operation and uses it for scratch space. The effected area
is at the same location as the destination. The user has to be aware
of this.
---------------------------------------------------------------------*/
static void sub_blt( from_bm, image, to_bm, to_x, to_y, saturate )
int from_bm;
RECT *image;
int to_bm,
to_x,
to_y,
saturate; /* 1 - saturate, 0 - don't saturate */
{
register i;
int scratch_bm, one_used, two_used, three_used;
unsigned int mask;
RECT to_image,
to_image1; /* 1 bpp coordinates */
/* Figure out which bitmap is not used in the operation and use it */
/* for scratch space. */
one_used = two_used = three_used = 0;
if ( from_bm == 1 || to_bm == 1 )
one_used = 1;
if ( from_bm == 2 || to_bm == 2 )
two_used = 1;
if ( from_bm == 3 || to_bm == 3 )
three_used = 1;
if ( !one_used )
scratch_bm = 1;
else if ( !two_used )
scratch_bm = 2;
else
scratch_bm = 3;
to_image.llx = to_x;
to_image.lly = to_y;
to_image.urx = to_x + ( image->urx - image->llx );
to_image.ury = to_y + ( image->ury - image->lly );
/* Adjust X only for 8 bpp to 1 bpp conversion */
to_image1.llx = to_x << 3;
to_image1.lly = to_y;
to_image1.urx = (( to_image.urx + 1 ) << 3 ) - 1;
to_image1.ury = to_image.ury;
/* Place a copy of the destination image in scratch space */
cmd_copy_image( to_bm, &to_image, scratch_bm, to_x, to_y, 0 );
/* Form the XOR/SUM result, in the destination bitmap */
cmd_copy_image( from_bm, image, to_bm, to_x, to_y, 1 );
/* Form the AND/CARRY result, in the scratch bitmap */
cmd_copy_image( from_bm, image, scratch_bm, to_x, to_y, 6 );
/* Now bit 0 of all pixels is done */
/* The sum 0 is already in destination bitmap and carry 0 is in AND */
/* We now need to form the sum 1, which is the XOR of bit 1 and carry 0 */
/* This requires bit 1 of destination bitmap to be XOR'ed with bit 0 of */
/* the AND/CARRY bitmap. The result is placed in the destination. */
/* This can not be accomplished at 8 bpp, as all operations happen on */
/* pixel boundaries - 8 bits. Therefore, from this point forward we */
/* must treat our bitmap as 1 bpp, since this allows single bit */
/* manipulation. */
for( i = 1, mask = 0x0202; i < 8; i++, mask <<= 1 )
{
/* Form the sum of bit i. */;
cmd_wm_copy_image( scratch_bm, &to_image1, to_bm, to_image1.llx - 1, to_image1.lly, 1, mask, 1 );
if (( mask == 0x8080 ) && ( !saturate ))
break; /* don't form the cary - done! */
/* Form the carry bit i by first using the carry in and AND'ing */
/* it with !SUM */
cmd_wm_copy_image( to_bm, &to_image1, scratch_bm, to_image1.llx + 1, to_image1.lly, 2, mask >> 1, 1 );
/* Form the OR part of the carry bit i. */
cmd_wm_copy_image( scratch_bm, &to_image1, scratch_bm, to_image1.llx - 1, to_image1.lly, 3, mask, 1 );
}
#if 0
/* Saturate the color based on the borrow(7). */
if ( saturate )
for ( i = 7, mask = 0x0101; i >= 0; i--, mask <<= 1 )
cmd_wm_copy_image( scratch_bm, &to_image1, to_bm, to_image1.llx + i, to_image1.lly, 6, mask, 1 );
#endif
/* new and faster algorithm - takes only 4 blits */
if ( saturate )
{
/* replicate carry[7] throughout the whole pixel of scratch space */
cmd_wm_copy_image( scratch_bm, &to_image1, scratch_bm, to_image1.llx + 1, to_image1.lly, 0, 0x4040, 1 );
cmd_wm_copy_image( scratch_bm, &to_image1, scratch_bm, to_image1.llx + 2, to_image1.lly, 0, 0x3030, 1 );
cmd_wm_copy_image( scratch_bm, &to_image1, scratch_bm, to_image1.llx + 4, to_image1.lly, 0, 0x0f0f, 1 );
/* saturate the image all bits at once */
cmd_wm_copy_image( scratch_bm, &to_image1, to_bm, to_image1.llx, to_image1.lly, 6, 0xffff, 1 );
}
/* Restore modified bitmaps to 8 bpp */
set_gpbitmap_bpp( to_bm, 8 );
set_gpbitmap_bpp( scratch_bm, 8 );
}