How do I create PDF image mask from 'System.Drawing.Bitmap'?

Q:I have a BMP file with a single bit plane. The artwork is black,
the
background is white. But I want to stamp this onto a colored
background
region with the artwork as white, and the background is transparent
on
the previously colored region. I believe this is done with an image
mask. For some reason, using samples I found, it appears to NOT be
observing the correct scan line stride. The image appears sidewise
sheared.

I wonder what I could be doing incorrectly. This has worked perfectly
previously with a square image. (By square I mean height pixels =
width
pixels) I double checked, and I can not see where I have swapped
horizontal and vertical sizes anywhere though. There is not a lot of
technical explanation on how CreateImageMask utilizes the raw bitmap
data that is passed to it.

Picture is passed as a Drawing.Bitmap from the application resources
to
a function which then...

Dim SourceImage As Image
Dim bmd As Drawing.Imaging.BitmapData = Nothing
Dim PDFImageHeight As Double = (Picture.Height /
Picture.VerticalResolution) * 72.0
Dim PDFImageWidth As Double = (Picture.Width /
Picture.HorizontalResolution) * 72.0
Dim rectngl As New Drawing.Rectangle(0, 0, Picture.Width,
Picture.Height)

bmd = Picture.LockBits(rectngl,
Drawing.Imaging.ImageLockMode.ReadOnly,
Drawing.Imaging.PixelFormat.Format1bppIndexed)
Dim totalsize As Integer = bmd.Stride * bmd.Height
GC.WaitForPendingFinalizers()
Dim img(totalsize - 1) As Byte
System.Runtime.InteropServices.Marshal.Copy(bmd.Scan0, img, 0,
totalsize)
SourceImage = *Image.CreateImageMask(mOut.mDoc, img, Picture.Width,
Picture.Height)*
elm = *mOut.mEB.CreateImage( _
         SourceImage, _
         New Matrix2D( _
            PDFImageWidth, _
            0, 0, _
            PDFImageHeight, _
            Me.HItoPt(HorizontalPosition), _
            Me.VItoPt(VerticalPosition) - PDFImageHeight))*
Dim Gstate As PDF.GState
Gstate = elm.GetGState
Gstate.SetFillColorSpace(PDFTRON.PDF.ColorSpace.CreateDeviceRGB)
' Note: color was passed as white
Gstate.SetFillColor(New ColorPt(Color.R / 255.0, Color.G / 255.0,
Color.B / 255.0))
mOut.mWriter.WritePlacedElement(elm)
If bmd IsNot Nothing Then Picture.UnlockBits(bmd)
-----
A: simpler way to create image mask from a monochrome
'System.Drawing.Bitmap' is as follows:

Image mask = Image.Create(doc, bmp);
mask.GetSDFObj().PutBool("ImageMask", true);
mask.GetSDFObj().Erase("ColorSpace");

Then you can set the image mask on another image object as follows:

Base_image.SetMask(mask);

---
In case you would still like to convert 'System.Drawing.Bitmap' to a
raw Data buffer that you can pass to one of pdftron.PDF.Image.Create()
methods, I suspect that the problem is caused by a mismatch between
'bmd.Stride' and 'bmd.Width'. A GDI+ bitmap may include some padding
bytes at the end of each line. The actual number of bytes for each
line can be calculated as follows:

int bits_per_component = 1; // for mono image
int num_colorants = 1; // for mono image
int bpl = ((colors * bits_per_component * img_width) + 7)/8;

As a result the total size of image buffer is:

int totalsize = bmd.Stride * bpl;

Also instead of copying data in a single shot
(System.Runtime.InteropServices.Marshal.Copy(bmd.Scan0, img, 0,
totalsize)) you will need to copy the image data line by line.
Something along the following lines:

// Loop through each row
char* sc = (char*) bmd.scan0;
int pos = 0;
for (int row=0; row<img_height; ++row) {
  memcpy(&buf[pos], sc, bpl);
  sc += bmd.Stride;
  pos +=bpl;
}