home *** CD-ROM | disk | FTP | other *** search
/ Graphics Programming Black Book (Special Edition) / BlackBook.bin / disk1 / source / chapter49 / l49-3.c < prev    next >
C/C++ Source or Header  |  1997-06-18  |  3KB  |  70 lines

  1. /* Generates all four possible mode X image/mask alignments, stores image 
  2. alignments in display memory, allocates memory for and generates mask 
  3. alignments, and fills out an AlignedMaskedImage structure. Image and mask must 
  4. both be in byte-per-pixel form, and must both be of width ImageWidth. Mask 
  5. maps isomorphically (one to one) onto image, with each 0-byte in mask masking
  6. off corresponding image pixel (causing it not to be drawn), and each non-0-byte
  7. allowing corresponding image pixel to be drawn. Returns 0 if failure, or # of 
  8. display memory addresses (4-pixel sets) used if success. For simplicity, 
  9. allocated memory is not deallocated in case of failure.
  10. Tested with Borland C++ 4.02 in small model by Jim Mischel 12/16/94.
  11. */
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include "maskim.h"
  15.  
  16. extern void CopySystemToScreenX(int, int, int, int, int, int, char *,
  17.    unsigned int, int, int);
  18. unsigned int CreateAlignedMaskedImage(MaskedImage * ImageToSet,
  19.    unsigned int DispMemStart, char * Image, int ImageWidth,
  20.    int ImageHeight, char * Mask)
  21. {
  22.    int Align, ScanLine, BitNum, Size, TempImageWidth;
  23.    unsigned char MaskTemp;
  24.    unsigned int DispMemOffset = DispMemStart;
  25.    AlignedMaskedImage *WorkingAMImage;
  26.    char *NewMaskPtr, *OldMaskPtr;
  27.    /* Generate each of the four alignments in turn */
  28.    for (Align = 0; Align < 4; Align++) {
  29.       /* Allocate space for the AlignedMaskedImage struct for this
  30.          alignment */
  31.       if ((WorkingAMImage = ImageToSet->Alignments[Align] =
  32.             malloc(sizeof(AlignedMaskedImage))) == NULL)
  33.          return 0;
  34.       WorkingAMImage->ImageWidth =
  35.             (ImageWidth + Align + 3) / 4; /* width in 4-pixel sets */
  36.       WorkingAMImage->ImagePtr = DispMemOffset; /* image dest */
  37.       /* Download this alignment of the image */
  38.       CopySystemToScreenX(0, 0, ImageWidth, ImageHeight, Align, 0,
  39.             Image, DispMemOffset, ImageWidth,
  40.             WorkingAMImage->ImageWidth * 4);
  41.       /* Calculate the number of bytes needed to store the mask in
  42.          nibble (Map Mask-ready) form, then allocate that space */
  43.       Size = WorkingAMImage->ImageWidth * ImageHeight;
  44.       if ((WorkingAMImage->MaskPtr = malloc(Size)) == NULL)
  45.          return 0;
  46.       /* Generate this nibble oriented (Map Mask-ready) alignment of
  47.          the mask, one scan line at a time */
  48.       OldMaskPtr = Mask;
  49.       NewMaskPtr = WorkingAMImage->MaskPtr;
  50.       for (ScanLine = 0; ScanLine < ImageHeight; ScanLine++) {
  51.          BitNum = Align;
  52.          MaskTemp = 0;
  53.          TempImageWidth = ImageWidth;
  54.          do {
  55.             /* Set the mask bit for next pixel according to its alignment */
  56.             MaskTemp |= (*OldMaskPtr++ != 0) << BitNum;
  57.             if (++BitNum > 3) {
  58.                *NewMaskPtr++ = MaskTemp;
  59.                MaskTemp = BitNum = 0;
  60.             }
  61.          } while (--TempImageWidth);
  62.          /* Set any partial final mask on this scan line */
  63.          if (BitNum != 0) *NewMaskPtr++ = MaskTemp;
  64.       }
  65.       DispMemOffset += Size; /* mark off the space we just used */
  66.    }
  67.    return DispMemOffset - DispMemStart;
  68. }
  69.  
  70.