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,
background is white. But I want to stamp this onto a colored
region with the artwork as white, and the background is transparent
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

I wonder what I could be doing incorrectly. This has worked perfectly
previously with a square image. (By square I mean height pixels =
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
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,

bmd = Picture.LockBits(rectngl,
Dim totalsize As Integer = bmd.Stride * bmd.Height
Dim img(totalsize - 1) As Byte
System.Runtime.InteropServices.Marshal.Copy(bmd.Scan0, img, 0,
SourceImage = *Image.CreateImageMask(mOut.mDoc, img, Picture.Width,
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
' Note: color was passed as white
Gstate.SetFillColor(New ColorPt(Color.R / 255.0, Color.G / 255.0,
Color.B / 255.0))
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);

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


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;