/*-------------------------------------------------------------------
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 );
}