import sys

import Cocoa

# import DataProvidersAndConsumers
import Images
import Quartz
import Utilities


def exportImageWithMaskFromURLWithDestination(
    context,
    imageURL,
    imagewidth,
    imageheight,
    bitsPerComponent,
    theMaskingImageURL,
    maskwidth,
    maskheight,
):
    imageBitsPerPixel = bitsPerComponent * 3
    bytesPerRow = ((imagewidth * imageBitsPerPixel) + 7) / 8
    shouldInterpolate = True
    imageDataProvider = Quartz.CGDataProviderCreateWithURL(imageURL)
    if imageDataProvider is None:
        print("Couldn't create Image Data provider!")
        return

    colorspace = Utilities.getTheCalibratedRGBColorSpace()
    image = Quartz.CGImageCreate(
        imagewidth,
        imageheight,
        bitsPerComponent,
        imageBitsPerPixel,
        bytesPerRow,
        colorspace,
        Quartz.kCGImageAlphaNone,
        imageDataProvider,
        None,
        shouldInterpolate,
        Quartz.kCGRenderingIntentDefault,
    )
    del imageDataProvider
    if image is None:
        print("Couldn't create CGImageRef for this data!")
        return

    imageRect = Quartz.CGRectMake(0.0, imageheight, imagewidth, imageheight)
    # Draw the image.
    Quartz.CGContextDrawImage(context, imageRect, image)

    # Now the mask.
    maskDataProvider = Quartz.CGDataProviderCreateWithURL(theMaskingImageURL)
    if maskDataProvider is None:
        print("Couldn't create Image Data provider!")
        return

    mask = Quartz.CGImageMaskCreate(
        maskwidth,
        maskheight,
        bitsPerComponent,
        bitsPerComponent,
        maskwidth,
        maskDataProvider,
        None,
        shouldInterpolate,
    )
    del maskDataProvider
    if mask is None:
        print("Couldn't create CGImageRef for mask data!")
        return

    # Draw the mask below the image.
    maskRect = Quartz.CGRectMake(0.0, 0.0, maskwidth, maskheight)
    Quartz.CGContextDrawImage(context, maskRect, mask)

    # Create a new CGImage object, the image, masked with mask.
    imageMaskedWithImage = Quartz.CGImageCreateWithMask(image, mask)
    # Once the new image is created, we can release the image
    # and the mask which make it up. Quartz retains what it needs
    # for the new masked image.
    del image
    del mask

    if imageMaskedWithImage is None:
        print("Couldn't create image masked with mask!")
        return

    imageRect = Quartz.CGRectMake(imagewidth, imageheight / 2, imagewidth, imageheight)
    # Draw the masked image to the right of the image and its mask.
    Quartz.CGContextDrawImage(context, imageRect, imageMaskedWithImage)

    # Of course this is a total hack.
    outPath = b"/tmp/imageout.png"
    exportURL = Cocoa.CFURLCreateFromFileSystemRepresentation(
        None, outPath, len(outPath), False
    )

    if exportURL is not None:
        Images.exportCGImageToPNGFileWithDestination(imageMaskedWithImage, exportURL)


if sys.version_info[0] == 2:

    def make_bytes(values):
        return "".join(map(chr, values))

else:

    def make_bytes(values):
        return bytes(values)


_data = make_bytes(
    (
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x7F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x1F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF8,
        0x00,
        0x03,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0x00,
        0xF8,
        0xE7,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xE0,
        0x00,
        0x00,
        0x00,
        0x40,
        0x7F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xC0,
        0x00,
        0x00,
        0x00,
        0x00,
        0x7F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x1F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFC,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x03,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF8,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x01,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF8,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x01,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xE0,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xE0,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x3F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xC0,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x3F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x80,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x0F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x0F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x07,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x06,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x7F,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x7F,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x00,
        0x00,
        0x01,
        0xC0,
        0x00,
        0x00,
        0x7F,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x00,
        0x00,
        0x0F,
        0xF8,
        0x00,
        0x00,
        0x7F,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x00,
        0x0F,
        0xFF,
        0xF8,
        0x00,
        0x00,
        0x7F,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x00,
        0x1F,
        0xFF,
        0xFC,
        0x00,
        0x00,
        0x7F,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x00,
        0x7F,
        0xFF,
        0xFC,
        0x00,
        0x00,
        0x7F,
        0xFF,
        0xFF,
        0xF8,
        0x00,
        0x00,
        0x00,
        0xFF,
        0xFF,
        0xFC,
        0x00,
        0x00,
        0xFF,
        0xFF,
        0xFF,
        0xF8,
        0x00,
        0x00,
        0x03,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0x00,
        0xFF,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0x00,
        0x03,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0x00,
        0x7F,
        0xFF,
        0xFF,
        0xF8,
        0x00,
        0x00,
        0x0F,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0x00,
        0x7F,
        0xFF,
        0xFF,
        0xF8,
        0x00,
        0x00,
        0x0F,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0x00,
        0xFF,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0x00,
        0x1F,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0x00,
        0xFF,
        0xFF,
        0xFF,
        0xE0,
        0x00,
        0x00,
        0x3F,
        0xFF,
        0xFF,
        0xFF,
        0x80,
        0x01,
        0xFF,
        0xFF,
        0xFF,
        0xE0,
        0x00,
        0x00,
        0x7F,
        0xFF,
        0xFF,
        0xFF,
        0x80,
        0x00,
        0x1F,
        0xFF,
        0xFF,
        0xE0,
        0x00,
        0x00,
        0x7F,
        0xFF,
        0xFF,
        0xFF,
        0x80,
        0x00,
        0x1F,
        0xFF,
        0xFF,
        0xE0,
        0x00,
        0x00,
        0x3F,
        0xFF,
        0xFF,
        0xFF,
        0xC0,
        0x00,
        0x1F,
        0xFF,
        0xFF,
        0xF8,
        0x00,
        0x00,
        0x3F,
        0xFF,
        0xFF,
        0xFF,
        0xE0,
        0x00,
        0x1F,
        0xFF,
        0xFF,
        0xF8,
        0x00,
        0x00,
        0x7F,
        0xFF,
        0xFF,
        0xFF,
        0xC0,
        0x00,
        0x1F,
        0xFF,
        0xFF,
        0xFC,
        0x00,
        0x00,
        0x7F,
        0xFF,
        0xFF,
        0xFE,
        0x40,
        0x00,
        0x0F,
        0xFF,
        0xFF,
        0xFC,
        0x00,
        0x00,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x1F,
        0xFF,
        0xFF,
        0xFC,
        0x00,
        0x00,
        0xFF,
        0xFF,
        0xFF,
        0xC0,
        0x00,
        0x00,
        0x1F,
        0xFF,
        0xFF,
        0xFC,
        0x00,
        0x01,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0x00,
        0x00,
        0x3F,
        0xFF,
        0xFF,
        0xFC,
        0x00,
        0x05,
        0xEF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x00,
        0x3F,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0x3F,
        0x00,
        0x03,
        0xFC,
        0x00,
        0x00,
        0x00,
        0x3F,
        0xFF,
        0xFF,
        0xE0,
        0x00,
        0x7C,
        0x00,
        0x00,
        0x78,
        0x1F,
        0x00,
        0x00,
        0x7F,
        0xFF,
        0xFF,
        0xC0,
        0x00,
        0x38,
        0x00,
        0x00,
        0x78,
        0x3C,
        0x00,
        0x01,
        0xFF,
        0xFF,
        0xFF,
        0xC0,
        0x00,
        0x78,
        0x00,
        0x00,
        0x70,
        0x18,
        0x00,
        0x01,
        0xFF,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0x78,
        0x1F,
        0x00,
        0x30,
        0x00,
        0x00,
        0x01,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0x7C,
        0x3F,
        0x00,
        0x18,
        0x00,
        0x00,
        0x01,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x00,
        0x00,
        0x38,
        0x00,
        0x00,
        0x03,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x80,
        0x00,
        0x3C,
        0x00,
        0x0C,
        0x03,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0x00,
        0x00,
        0x00,
        0x3C,
        0x20,
        0x1C,
        0x03,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0x00,
        0x04,
        0x00,
        0x3C,
        0x00,
        0x3C,
        0x03,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0x70,
        0xBF,
        0x86,
        0x3C,
        0x1F,
        0xFC,
        0x0B,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xA0,
        0x11,
        0xF0,
        0x0E,
        0x3C,
        0x1F,
        0xFE,
        0x8B,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xA0,
        0x19,
        0xF0,
        0x0C,
        0x3C,
        0x0F,
        0xFF,
        0x0B,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xB0,
        0x1D,
        0xFE,
        0x1C,
        0x7E,
        0x0F,
        0xFF,
        0x03,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xB8,
        0x1C,
        0xFF,
        0x3C,
        0xFE,
        0x03,
        0xFE,
        0x03,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFC,
        0x1E,
        0x7F,
        0xF8,
        0xDE,
        0x00,
        0x7C,
        0x03,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x1E,
        0x7F,
        0xF1,
        0xDF,
        0x30,
        0x03,
        0x83,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x1F,
        0x3F,
        0xE3,
        0x9F,
        0x10,
        0x3F,
        0x83,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x0F,
        0xFF,
        0x83,
        0xDF,
        0x80,
        0x1F,
        0x83,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x03,
        0xFC,
        0x03,
        0xDF,
        0x81,
        0x8F,
        0x83,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x07,
        0xFE,
        0x1F,
        0x8F,
        0x00,
        0x07,
        0x83,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x07,
        0xFE,
        0x3C,
        0x06,
        0x00,
        0x01,
        0x83,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x03,
        0xFC,
        0x7C,
        0x00,
        0x00,
        0x01,
        0x83,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x01,
        0xF8,
        0x7F,
        0x00,
        0x00,
        0x01,
        0x83,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x01,
        0xF8,
        0xFF,
        0xE0,
        0x30,
        0x01,
        0x83,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0xF1,
        0xEF,
        0xF9,
        0xE0,
        0x03,
        0x83,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x80,
        0xF1,
        0xFF,
        0xFF,
        0x80,
        0x0F,
        0x83,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFC,
        0x03,
        0xE2,
        0xFF,
        0xFE,
        0x00,
        0x1F,
        0x87,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x83,
        0xF0,
        0x00,
        0x00,
        0x1C,
        0x3F,
        0x87,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xC3,
        0xF0,
        0x00,
        0x01,
        0xF8,
        0x0F,
        0x87,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xC3,
        0xF0,
        0x03,
        0xFF,
        0xF0,
        0x5F,
        0x07,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xC1,
        0xFF,
        0xC7,
        0xFF,
        0xE0,
        0x7F,
        0x0F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xE1,
        0xFF,
        0xF1,
        0xFF,
        0x80,
        0x2F,
        0x0F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xE1,
        0xFF,
        0xF8,
        0x0F,
        0xC0,
        0x06,
        0x1F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF4,
        0xFF,
        0xFE,
        0x0F,
        0xF8,
        0x44,
        0x1F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF4,
        0xFF,
        0xFF,
        0xFF,
        0xF8,
        0x64,
        0x3F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF9,
        0xFF,
        0xFF,
        0xFF,
        0x3C,
        0xE4,
        0x7F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFD,
        0x9F,
        0xFF,
        0xFC,
        0x1F,
        0xC0,
        0x7F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFD,
        0x1F,
        0xFF,
        0xFC,
        0x03,
        0xC0,
        0x7F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x01,
        0xFF,
        0xFF,
        0xFF,
        0xC0,
        0x7F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0x7F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0x7F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x80,
        0x7F,
        0xFF,
        0xFF,
        0x00,
        0x3F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x80,
        0x1F,
        0xFF,
        0xFF,
        0x00,
        0x3F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0xC0,
        0x0F,
        0xFF,
        0xFF,
        0x00,
        0x1F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xE0,
        0x07,
        0xFF,
        0xFF,
        0x00,
        0x0F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF0,
        0x03,
        0xFF,
        0xFF,
        0x00,
        0x1F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x70,
        0x01,
        0xFF,
        0xFC,
        0x00,
        0x17,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFC,
        0x78,
        0x00,
        0x7F,
        0xF0,
        0x00,
        0x07,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF0,
        0xFC,
        0x00,
        0x00,
        0x00,
        0x00,
        0x07,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x03,
        0xFE,
        0x00,
        0x00,
        0x00,
        0x00,
        0x07,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x1F,
        0xFF,
        0x80,
        0x00,
        0x00,
        0x00,
        0x07,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFC,
        0x7F,
        0x7F,
        0xC0,
        0x00,
        0x00,
        0x00,
        0x07,
        0xFF,
        0xFF,
    )
)


def getMaskData1():
    return _data


_data2 = make_bytes(
    (
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x03,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFC,
        0x00,
        0x1F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xE0,
        0x00,
        0x01,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x80,
        0x00,
        0x00,
        0x3F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0x00,
        0x00,
        0x1F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFC,
        0x00,
        0x00,
        0x00,
        0x07,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF8,
        0x00,
        0x00,
        0x00,
        0x03,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0x00,
        0x00,
        0x01,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xE0,
        0x00,
        0x00,
        0x00,
        0x01,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xC0,
        0x00,
        0x00,
        0x00,
        0x00,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x80,
        0x00,
        0x00,
        0x00,
        0x00,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x7F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x3F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x3F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFC,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x1F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF8,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x1F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF8,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x0F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0x00,
        0x00,
        0x01,
        0x80,
        0x07,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0x00,
        0x00,
        0x03,
        0xC0,
        0x07,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0x00,
        0x00,
        0x0B,
        0xE0,
        0x07,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xE0,
        0x00,
        0x00,
        0x00,
        0x07,
        0xF0,
        0x03,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xE0,
        0x00,
        0x00,
        0x00,
        0x1F,
        0xF4,
        0x83,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xC0,
        0x00,
        0x00,
        0x00,
        0x3F,
        0xE4,
        0x03,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xC0,
        0x00,
        0x00,
        0x00,
        0x3F,
        0xE4,
        0x43,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x80,
        0x00,
        0x00,
        0x00,
        0x3F,
        0xE4,
        0x4B,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x80,
        0x00,
        0x00,
        0x02,
        0xFF,
        0xE4,
        0x5B,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0x00,
        0x00,
        0x02,
        0xFF,
        0xE0,
        0x5B,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0x00,
        0x07,
        0xC1,
        0xFF,
        0xE0,
        0x59,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x18,
        0x00,
        0x7F,
        0xF0,
        0xFE,
        0x00,
        0x79,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x18,
        0x00,
        0x78,
        0x0F,
        0xFE,
        0x04,
        0xE1,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x18,
        0x00,
        0xB0,
        0x47,
        0xFF,
        0xFF,
        0xE1,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x10,
        0x00,
        0xC4,
        0x69,
        0xFF,
        0xFF,
        0xC3,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFE,
        0x10,
        0x01,
        0xFF,
        0xE1,
        0xFC,
        0x07,
        0xC1,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFC,
        0x00,
        0x01,
        0xFF,
        0xF8,
        0x78,
        0x01,
        0xC5,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFC,
        0x04,
        0x01,
        0xFF,
        0xF0,
        0x78,
        0x01,
        0xC5,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFC,
        0x0C,
        0x00,
        0xFF,
        0xF8,
        0x7E,
        0x3F,
        0xC1,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFC,
        0x0C,
        0x00,
        0x7F,
        0xF0,
        0x18,
        0xFF,
        0xC3,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFC,
        0x07,
        0x00,
        0x7F,
        0xF4,
        0x1F,
        0xFF,
        0xE3,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFC,
        0x23,
        0x00,
        0x7F,
        0xE0,
        0x3E,
        0xFF,
        0xE3,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF8,
        0x11,
        0x00,
        0x7F,
        0xEC,
        0x5F,
        0xBF,
        0xE3,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF8,
        0x01,
        0x00,
        0x3F,
        0xCE,
        0x7E,
        0x3F,
        0xE3,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF8,
        0x08,
        0x00,
        0x7F,
        0x80,
        0x2E,
        0x3F,
        0xE3,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF8,
        0x06,
        0x00,
        0x7F,
        0x00,
        0x6E,
        0x3F,
        0xEB,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0x00,
        0x7E,
        0x0D,
        0xFE,
        0xFF,
        0xEB,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0x00,
        0x3C,
        0x00,
        0xFE,
        0x3F,
        0xEB,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0x00,
        0x50,
        0x00,
        0xFE,
        0x3F,
        0xCB,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0x00,
        0x01,
        0x98,
        0xFF,
        0x3F,
        0xCB,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0x00,
        0xC7,
        0xE1,
        0xFF,
        0x3F,
        0x8B,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0x00,
        0x40,
        0xFF,
        0xFF,
        0xBF,
        0x8B,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0x00,
        0xE0,
        0x1F,
        0xFF,
        0xDF,
        0x0B,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0x00,
        0xE8,
        0x63,
        0xFF,
        0xDF,
        0x0F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0x02,
        0xFC,
        0xF9,
        0xFF,
        0xEF,
        0x0F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0x03,
        0xFE,
        0x7F,
        0xF8,
        0x1E,
        0x0F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xE0,
        0x00,
        0x03,
        0x7E,
        0x0F,
        0xF9,
        0xBE,
        0x05,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xE0,
        0x00,
        0x01,
        0x7F,
        0xC1,
        0xF3,
        0xFC,
        0x05,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xE0,
        0x00,
        0x01,
        0x3D,
        0xF8,
        0x0F,
        0x7C,
        0x05,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xE0,
        0x00,
        0x01,
        0xBC,
        0x7F,
        0xFF,
        0xF8,
        0x02,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xE0,
        0x00,
        0x00,
        0xBE,
        0xFF,
        0xFF,
        0xF8,
        0x02,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xC0,
        0x00,
        0x00,
        0x1D,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xC0,
        0x00,
        0x00,
        0x0F,
        0xF7,
        0xFF,
        0xE0,
        0x00,
        0x7F,
        0xFF,
        0xFF,
        0xFF,
        0xC0,
        0x00,
        0x00,
        0x0F,
        0xF3,
        0xFF,
        0xE0,
        0x00,
        0x7F,
        0xFF,
        0xFF,
        0xFF,
        0x80,
        0x00,
        0x00,
        0x03,
        0xF3,
        0xFF,
        0xC0,
        0x00,
        0x7F,
        0xFF,
        0xFF,
        0xFF,
        0x80,
        0x00,
        0x00,
        0x01,
        0xF7,
        0xFF,
        0x80,
        0x00,
        0x3F,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0x00,
        0x00,
        0x00,
        0x3F,
        0xFF,
        0x00,
        0x00,
        0x3F,
        0xFF,
        0xFF,
        0xFF,
        0x00,
        0x00,
        0x00,
        0x00,
        0x1F,
        0xFF,
        0x00,
        0x20,
        0x3F,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x00,
        0x00,
        0x1F,
        0xFF,
        0x00,
        0x10,
        0x3F,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x00,
        0x00,
        0x1F,
        0xFF,
        0x00,
        0x10,
        0x3F,
        0xFF,
        0xFF,
        0xFC,
        0x00,
        0x00,
        0x02,
        0x00,
        0x0F,
        0xFF,
        0x00,
        0x00,
        0x1F,
        0xFF,
        0xFF,
        0xFC,
        0x00,
        0x00,
        0x04,
        0x00,
        0x1F,
        0xFE,
        0x00,
        0x00,
        0x1F,
        0xFF,
        0xFF,
        0xF8,
        0x00,
        0x00,
        0x07,
        0x81,
        0x7F,
        0xFE,
        0x00,
        0x00,
        0x1F,
        0xFF,
        0xFF,
        0xF8,
        0x00,
        0x00,
        0x03,
        0xDF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x1F,
        0xFF,
        0xFF,
        0xF8,
        0x00,
        0x00,
        0x07,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x1F,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0x00,
        0x07,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x1F,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0x40,
        0x07,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x0F,
        0xFF,
        0xFF,
        0xF0,
        0x00,
        0xC0,
        0x03,
        0xFF,
        0xFF,
        0xFE,
        0x00,
        0x00,
        0x0F,
        0xFF,
        0xFF,
        0xE0,
        0x00,
        0xE0,
        0x07,
        0xFF,
        0xFF,
        0xFE,
        0x81,
        0x00,
        0x07,
        0xFF,
        0xFF,
        0xC0,
        0x01,
        0xE0,
        0x07,
        0xFF,
        0xFF,
        0xFE,
        0x01,
        0x00,
        0x07,
        0xFF,
        0xFF,
        0x80,
        0x0F,
        0xF0,
        0x03,
        0xFF,
        0xFF,
        0xFE,
        0x83,
        0x80,
        0x03,
        0xFF,
        0xFF,
        0x00,
        0x1F,
        0xF0,
        0x13,
        0xFF,
        0xFF,
        0xFE,
        0x03,
        0xE0,
        0x01,
        0xFF,
        0xFC,
        0x03,
        0x3F,
        0xF0,
        0x21,
        0xFF,
        0xFF,
        0xFE,
        0x03,
        0xFC,
        0x00,
        0x3F,
        0xF0,
        0x3F,
        0x3F,
        0xF8,
        0x3B,
        0xFF,
        0xFF,
        0xFE,
        0x03,
        0xFE,
        0xC0,
        0x0F,
        0xE3,
        0xFB,
        0x7F,
        0xF8,
        0x3B,
        0xFF,
        0xFF,
        0xFF,
        0x07,
        0xFF,
        0xFF,
        0x07,
        0x9F,
        0xFB,
        0x7F,
        0xFC,
        0x79,
        0xFF,
        0xFF,
        0xFF,
        0x07,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x7F,
        0xFC,
        0x39,
        0xFF,
        0xFF,
        0xFF,
        0x07,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x7F,
        0xFE,
        0x3F,
        0xFF,
        0xFF,
        0xFE,
        0x07,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x7F,
        0xFE,
        0x1F,
        0xFF,
        0xFF,
        0xFE,
        0x0F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x7F,
        0xFE,
        0x1F,
        0x7F,
        0xFF,
        0xFE,
        0x0F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x7F,
        0xFF,
        0x1F,
        0xFE,
        0xFF,
        0xFC,
        0x0F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x0F,
        0xFF,
        0xFF,
        0xFF,
        0x1F,
        0xFF,
        0xEF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0x87,
        0xFF,
        0xFF,
        0xFE,
        0x1F,
        0xFF,
        0xEF,
        0xFF,
        0xFF,
        0xFF,
        0xBF,
        0xFF,
        0x82,
        0xFF,
        0xFF,
        0xFC,
        0x3F,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xBF,
        0xFF,
        0x83,
        0xFF,
        0xFF,
        0xFC,
        0x3F,
        0xFF,
        0xBF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xC1,
        0xFF,
        0xFF,
        0xF8,
        0x7F,
        0xFF,
        0xBF,
        0xFF,
        0xFF,
        0xFF,
        0xBF,
        0xFF,
        0xE0,
        0xFF,
        0xFF,
        0xF0,
        0xFF,
        0xFF,
        0xBF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
        0xFF,
    )
)


def getMaskData2():
    return _data2


def doOneBitMaskImages(context):
    bitsPerComponent = 1
    bitsPerPixel = 1
    width = 96
    height = 96
    bytesPerRow = 12

    imageDataSize = bytesPerRow * height
    shouldInterpolate = True
    lightBlue = [0.482, 0.62, 0.871, 1.0]
    black = [0.0, 0.0, 0.0, 1.0]
    darkRed = [0.663, 0.0, 0.031, 1.0]
    darkGreen = [0.404, 0.808, 0.239, 1.0]
    darkBlue = [0.11, 0.208, 0.451, 1.0]
    purple = [0.69, 0.486, 0.722, 1.0]
    darkOrange = [0.965, 0.584, 0.059, 1.0]

    # A decode array contains two elements for each component. In this
    # case, an image mask has one component so the array consists of
    # two values. When using this decode array, a sample value of 0
    # is mapped into the value 1, and the maximum sample value is
    # mapped into the value 0. This inverts the sense of the mask data.
    decode = (1, 0)

    # Create a Quartz data provider for the image data. Because this
    # data is static data, we don't need to release it so the data
    # release function is None.
    data = getMaskData1()
    dataProvider = Quartz.CGDataProviderCreateWithData(None, data, imageDataSize, None)
    if dataProvider is None:
        print("Couldn't create Mask1 Data provider!")
        return

    # Create a mask from the data.
    mask1 = Quartz.CGImageMaskCreate(
        width,
        height,
        bitsPerComponent,
        bitsPerPixel,
        bytesPerRow,
        dataProvider,
        None,
        shouldInterpolate,
    )
    # Create the same mask but with a decode array that
    # inverts the sense of the mask.
    invertedmask1 = Quartz.CGImageMaskCreate(
        width,
        height,
        bitsPerComponent,
        bitsPerPixel,
        bytesPerRow,
        dataProvider,
        decode,
        shouldInterpolate,
    )
    # Release the data provider now that this code no longer needs it.
    del dataProvider

    if mask1 is None or invertedmask1 is None:
        if mask1 is None:
            print("Couldn't create CGImageRef for the mask data 1!")

        if invertedmask1 is None:
            print("Couldn't create CGImageRef for the inverted mask data 1!")
        return

    # Get the pointer to the data for the second mask.
    data = getMaskData2()
    dataProvider = Quartz.CGDataProviderCreateWithData(None, data, imageDataSize, None)
    if dataProvider is None:
        print("Couldn't create Mask2 Data provider!")
        return

    mask2 = Quartz.CGImageMaskCreate(
        width,
        height,
        bitsPerComponent,
        bitsPerPixel,
        bytesPerRow,
        dataProvider,
        None,
        shouldInterpolate,
    )
    # Create the same mask but with a decode array that
    # inverts the sense of the mask.
    invertedmask2 = Quartz.CGImageMaskCreate(
        width,
        height,
        bitsPerComponent,
        bitsPerPixel,
        bytesPerRow,
        dataProvider,
        decode,
        shouldInterpolate,
    )
    # Release the data provider now that this code no longer needs it.
    del dataProvider
    if mask2 is None or invertedmask2 is None:
        if mask2 is None:
            print("Couldn't create CGImageRef for the mask data 2!")

        if invertedmask2 is None:
            print("Couldn't create CGImageRef for the inverted mask data 2!")

        return

    Quartz.CGContextScaleCTM(context, 1.5, 1.5)
    colorSpace = Utilities.getTheCalibratedRGBColorSpace()
    Quartz.CGContextSetFillColorSpace(context, colorSpace)

    # Set the fill color to a light blue.
    Quartz.CGContextSetFillColor(context, lightBlue)
    # Paint part of the background.
    backRect = Quartz.CGRectMake(width / 2, height / 2, width * 3, height)
    Quartz.CGContextFillRect(context, backRect)

    imageRect = Quartz.CGRectMake(0.0, height, width, height)
    Quartz.CGContextSaveGState(context)
    # Set the fill color to opaque black.
    Quartz.CGContextSetFillColor(context, black)
    # Mask 1.
    Quartz.CGContextDrawImage(context, imageRect, mask1)

    Quartz.CGContextTranslateCTM(context, width, 0)
    # Set the fill color to opaque red.
    Quartz.CGContextSetFillColor(context, darkRed)
    # Mask 2.
    Quartz.CGContextDrawImage(context, imageRect, mask2)
    Quartz.CGContextTranslateCTM(context, width, 0)
    # Set the fill color to dark orange.
    Quartz.CGContextSetFillColor(context, darkOrange)
    # Mask 3.
    Quartz.CGContextDrawImage(context, imageRect, mask1)

    Quartz.CGContextTranslateCTM(context, width, 0)
    # Make the orange 50% transparent.
    darkOrange[3] = 0.5
    Quartz.CGContextSetFillColor(context, darkOrange)
    # Mask 4.
    Quartz.CGContextDrawImage(context, imageRect, mask2)
    Quartz.CGContextRestoreGState(context)

    # Translate down the page. The cast is necessary
    # since height is typed as size_t which is unsigned.
    Quartz.CGContextTranslateCTM(context, 0, -height)

    # Set the fill color to an opaque green.
    Quartz.CGContextSetFillColor(context, darkGreen)
    # Mask 5.
    Quartz.CGContextDrawImage(context, imageRect, invertedmask2)

    Quartz.CGContextTranslateCTM(context, width, 0)
    # Set the fill color to a dark blue.
    Quartz.CGContextSetFillColor(context, darkBlue)
    # Mask 6.
    Quartz.CGContextDrawImage(context, imageRect, invertedmask1)
    Quartz.CGContextTranslateCTM(context, width, 0)
    # Set the fill color to purple.
    Quartz.CGContextSetFillColor(context, purple)
    # Mask 7.
    Quartz.CGContextDrawImage(context, imageRect, invertedmask2)
    Quartz.CGContextTranslateCTM(context, width, 0)

    # Make the purple 50% transparent.
    purple[3] = 0.5
    Quartz.CGContextSetFillColor(context, purple)
    # Mask 8.
    Quartz.CGContextDrawImage(context, imageRect, invertedmask1)


def doMaskImageWithMaskFromURL(
    context,
    imageURL,
    imagewidth,
    imageheight,
    bitsPerComponent,
    theMaskingImageURL,
    maskwidth,
    maskheight,
):
    imageBitsPerPixel = bitsPerComponent * 3
    bytesPerRow = ((imagewidth * imageBitsPerPixel) + 7) / 8
    shouldInterpolate = True
    imageDataProvider = Quartz.CGDataProviderCreateWithURL(imageURL)
    if imageDataProvider is None:
        print("Couldn't create Image Data provider!")
        return

    colorspace = Utilities.getTheCalibratedRGBColorSpace()
    image = Quartz.CGImageCreate(
        imagewidth,
        imageheight,
        bitsPerComponent,
        imageBitsPerPixel,
        bytesPerRow,
        colorspace,
        Quartz.kCGImageAlphaNone,
        imageDataProvider,
        None,
        shouldInterpolate,
        Quartz.kCGRenderingIntentDefault,
    )
    del imageDataProvider
    if image is None:
        print("Couldn't create CGImageRef for this data!")
        return

    imageRect = Quartz.CGRectMake(0.0, imageheight, imagewidth, imageheight)
    # Draw the image.
    Quartz.CGContextDrawImage(context, imageRect, image)

    # Now the mask.
    maskDataProvider = Quartz.CGDataProviderCreateWithURL(theMaskingImageURL)
    if maskDataProvider is None:
        print("Couldn't create Image Data provider!")
        return

    mask = Quartz.CGImageMaskCreate(
        maskwidth,
        maskheight,
        bitsPerComponent,
        bitsPerComponent,
        maskwidth,
        maskDataProvider,
        None,
        shouldInterpolate,
    )
    del maskDataProvider
    if mask is None:
        print("Couldn't create CGImageRef for mask data!")
        return

    # Draw the mask below the image. The current fill color (black)
    # is painted through the mask.
    maskRect = Quartz.CGRectMake(0.0, 0.0, maskwidth, maskheight)
    Quartz.CGContextDrawImage(context, maskRect, mask)

    # Create a new CGImage object, the image, masked with mask.
    imageMaskedWithImage = Quartz.CGImageCreateWithMask(image, mask)
    # Once the new image is created, the code can release the image
    # and the mask which make it up. Quartz retains what it needs
    # for the new masked image 'imageMaskedWithImage'.
    del image
    del mask
    if imageMaskedWithImage is None:
        print("Couldn't create image masked with mask!")
        return

    imageRect = Quartz.CGRectMake(
        imagewidth + 10, imageheight / 2, imagewidth, imageheight
    )
    # Draw the masked image to the right of the image and its mask.
    Quartz.CGContextDrawImage(context, imageRect, imageMaskedWithImage)


def doMaskImageWithGrayImageFromURL(
    context,
    imageURL,
    imagewidth,
    imageheight,
    bitsPerComponent,
    theMaskingImageURL,
    maskwidth,
    maskheight,
):
    imageBitsPerPixel = bitsPerComponent * 3
    bytesPerRow = ((imagewidth * imageBitsPerPixel) + 7) / 8
    shouldInterpolate = True

    imageDataProvider = Quartz.CGDataProviderCreateWithURL(imageURL)
    if imageDataProvider is None:
        print("Couldn't create Image Data provider!")
        return

    colorspace = Utilities.getTheCalibratedRGBColorSpace()
    image = Quartz.CGImageCreate(
        imagewidth,
        imageheight,
        bitsPerComponent,
        imageBitsPerPixel,
        bytesPerRow,
        colorspace,
        Quartz.kCGImageAlphaNone,
        imageDataProvider,
        None,
        shouldInterpolate,
        Quartz.kCGRenderingIntentDefault,
    )
    del imageDataProvider
    if image is None:
        print("Couldn't create CGImageRef for this data!")
        return

    imageRect = Quartz.CGRectMake(0.0, imageheight, imagewidth, imageheight)
    # Draw the image.
    Quartz.CGContextDrawImage(context, imageRect, image)

    # Now the mask.
    maskDataProvider = Quartz.CGDataProviderCreateWithURL(theMaskingImageURL)
    if maskDataProvider is None:
        print("Couldn't create Image Data provider!")
        return

    # The color space for the image MUST be DeviceGray for it to
    # be used as a masking image with CGImageCreateWithMask.
    deviceGraySpace = Quartz.CGColorSpaceCreateDeviceGray()
    mask = Quartz.CGImageCreate(
        maskwidth,
        maskheight,
        bitsPerComponent,
        bitsPerComponent,
        maskwidth,
        deviceGraySpace,
        Quartz.kCGImageAlphaNone,
        maskDataProvider,
        None,
        shouldInterpolate,
        Quartz.kCGRenderingIntentDefault,
    )
    # Release the color space since it is no longer needed.
    del deviceGraySpace
    del maskDataProvider

    if mask is None:
        print("Couldn't create CGImageRef for gray image data!")
        return

    # Draw the mask below the image. The current fill color (black)
    # is painted through the mask.
    maskRect = Quartz.CGRectMake(0.0, 0.0, maskwidth, maskheight)
    Quartz.CGContextDrawImage(context, maskRect, mask)

    # Create a new CGImage object, the image, masked with mask.
    imageMaskedWithImage = Quartz.CGImageCreateWithMask(image, mask)

    # Once the new image is created, the code can release the image
    # and the mask which make it up. Quartz retains what it needs
    # for the new masked image 'imageMaskedWithImage'.
    del image
    del mask

    if imageMaskedWithImage is None:
        print("Couldn't create image masked with mask!")
        return

    imageRect = Quartz.CGRectMake(
        imagewidth + 10, imageheight / 2, imagewidth, imageheight
    )
    # Draw the masked image to the right of the image and its mask.
    Quartz.CGContextDrawImage(context, imageRect, imageMaskedWithImage)
    # Be sure and release the masked image.
    del imageMaskedWithImage


def doMaskImageWithColorFromURL(context, url, width, height, isColor):
    # This routine treats color images as RGB.
    bitsPerComponent = 8
    if isColor:
        bitsPerPixel = bitsPerComponent * 3
    else:
        bitsPerPixel = bitsPerComponent

    bytesPerRow = ((width * bitsPerPixel) + 7) / 8
    shouldInterpolate = True

    # This is a range of dark gray to black colors for an 8 bit per component
    # image in a gray or RGB color space. The entries are image sample
    # values of 0-0x1F for the first color component, 0-0x1F for the
    # second color component, and so on. For image sample values where
    # all components fall within the ranges in maskingColors, the sample
    # value is masked and therefore unpainted.
    maskingColors = (0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F)
    backColor = (1.0, 0.0, 0.0, 1.0)  # Opaque red.

    # Create a Quartz data provider from the supplied URL.
    dataProvider = Quartz.CGDataProviderCreateWithURL(url)
    if dataProvider is None:
        print("Couldn't create Image data provider!")
        return

    # Create an image of the specified width, height and bits per pixel
    # from the URL.
    if isColor:
        colorspace = Utilities.getTheCalibratedRGBColorSpace()
    else:
        colorspace = Utilities.getTheCalibratedGrayColorSpace()

    image = Quartz.CGImageCreate(
        width,
        height,
        bitsPerComponent,
        bitsPerPixel,
        bytesPerRow,
        colorspace,
        Quartz.kCGImageAlphaNone,
        dataProvider,
        None,
        shouldInterpolate,
        Quartz.kCGRenderingIntentDefault,
    )
    del dataProvider
    if image is None:
        print("Couldn't create CGImageRef for this data!")
        return

    imageRect = Quartz.CGRectMake(10.0, 10.0, width, height)
    # Quartz.CGContextScaleCTM(context, 0.33, 0.33)
    # Set the color space and the color, then
    # paint a red rectangle behind the image.
    Quartz.CGContextSetFillColorSpace(context, colorspace)
    Quartz.CGContextSetFillColor(context, backColor)
    Quartz.CGContextFillRect(context, imageRect)
    # Draw the image into the rectangle.
    Quartz.CGContextDrawImage(context, imageRect, image)
    # Create a new image from the original one, masking out a range
    # of the blackest sample values.
    imageMaskedWithColor = Quartz.CGImageCreateWithMaskingColors(image, maskingColors)
    # Release the original image; it is no longer needed.
    del image
    if imageMaskedWithColor is None:
        print("Couldn't create CGImageRef for masking color!")
        return

    # Paint the rectangle behind the next image with red.
    imageRect = Quartz.CGRectMake(30.0 + width, 10.0, width, height)
    Quartz.CGContextFillRect(context, imageRect)
    # Draw the image. Image sample values in the range of
    # the masking color are unpainted, allowing the background
    # to show through.
    Quartz.CGContextDrawImage(context, imageRect, imageMaskedWithColor)


if 1:  # Set to 1 for code in the book.

    def drawWithClippingMask(context, theMaskingImageURL, imagewidth, imageheight):
        # An array of CGColor objects.
        colors = (
            Utilities.getRGBOpaqueDarkGreenColor(),
            Utilities.getRGBOpaqueDarkBlueColor(),
            Utilities.getRGBOpaqueBlueColor(),
            Utilities.getRGBOpaqueRedColor(),
        )

        imageBitsPerComponent = 8
        bytesPerRow = imagewidth
        shouldInterpolate = True
        decode = (1, 0)

        # Create the data.
        dataProvider = Quartz.CGDataProviderCreateWithURL(theMaskingImageURL)
        if dataProvider is None:
            print("Couldn't create Image data provider!")
            return

        cs = Quartz.CGColorSpaceCreateDeviceGray()
        image = Quartz.CGImageCreate(
            imagewidth,
            imageheight,
            imageBitsPerComponent,
            imageBitsPerComponent,
            bytesPerRow,
            cs,
            Quartz.kCGImageAlphaNone,
            dataProvider,
            decode,
            shouldInterpolate,
            Quartz.kCGRenderingIntentDefault,
        )
        del cs
        del dataProvider

        if image is None:
            print("Couldn't create Image!")
            return

        imageRect = Quartz.CGRectMake(0, 0, imagewidth * 2 / 3, imageheight * 2 / 3)

        # Position for drawing the image at the left side of the figure.
        Quartz.CGContextTranslateCTM(context, 50, 50)

        # Draw the image.
        Quartz.CGContextDrawImage(context, imageRect, image)

        # Position to the right of the image just painted.
        Quartz.CGContextTranslateCTM(context, Quartz.CGRectGetWidth(imageRect) + 25, 0)

        # Clip to the image.
        Quartz.CGContextClipToMask(context, imageRect, image)
        # Release the image since this code no longer needs it.
        del image

        # Make a rect that has a width and height 1/3 that of the image.
        rect = Quartz.CGRectMake(
            0,
            0,
            Quartz.CGRectGetWidth(imageRect) / 3,
            Quartz.CGRectGetHeight(imageRect) / 3,
        )

        Quartz.CGContextTranslateCTM(context, 0, 2 * Quartz.CGRectGetHeight(rect))

        # Draw a 3 x 3 grid of rectangles, setting the color for each rectangle
        # by cycling through the array of CGColor objects in the 'colors' array.
        for j in range(3):
            Quartz.CGContextSaveGState(context)
            for i in range(3):
                # Draw a row of rectangles.
                # Set the fill color using one of the CGColor objects in the
                # colors array.
                Quartz.CGContextSetFillColorWithColor(context, colors[(i + j) % 4])
                Quartz.CGContextFillRect(context, rect)
                Quartz.CGContextTranslateCTM(context, Quartz.CGRectGetWidth(rect), 0)

            Quartz.CGContextRestoreGState(context)
            # Position to draw the next row.
            Quartz.CGContextTranslateCTM(context, 0, -Quartz.CGRectGetHeight(rect))

else:
    # This code works just fine to screen but when drawing to a PDF
    # or printing context the masked drawing is completely masked out
    # due to a bug in Quartz prior to Tiger 10.4.3.
    def drawWithClippingMask(context, theMaskingImageURL, maskwidth, maskheight):
        # An array of Quartz.CGColor objects.
        colors = (
            Utilities.getRGBOpaqueDarkGreenColor(),
            Utilities.getRGBOpaqueDarkBlueColor(),
            Utilities.getRGBOpaqueBlueColor(),
            Utilities.getRGBOpaqueRedColor(),
        )
        maskBitsPerComponent = 8
        # bytesPerRow = ((maskwidth * maskBitsPerComponent) + 7) / 8
        shouldInterpolate = True
        maskDataProvider = Quartz.CGDataProviderCreateWithURL(theMaskingImageURL)

        if maskDataProvider is None:
            print("Couldn't create Image Mask provider!")
            return
        mask = Quartz.CGImageMaskCreate(
            maskwidth,
            maskheight,
            maskBitsPerComponent,
            maskBitsPerComponent,
            maskwidth,
            maskDataProvider,
            None,
            shouldInterpolate,
        )
        del maskDataProvider

        if mask is None:
            print("Couldn't create Image Mask!")
            return

        maskRect = Quartz.CGRectMake(0, 0, maskwidth / 3, maskheight / 3)

        # Position for drawing the mask at the left side of the figure.
        Quartz.CGContextTranslateCTM(context, 50, 50)
        # Set the context fill color to a Quartz.CGColor object that is black.
        Quartz.CGContextSetFillColorWithColor(
            context, Utilities.getRGBOpaqueBlackColor()
        )
        # Draw the mask. It is painted with with the black fill color.
        Quartz.CGContextDrawImage(context, maskRect, mask)

        # Position to the right of the mask just painted.
        Quartz.CGContextTranslateCTM(context, Quartz.CGRectGetWidth(maskRect) + 25, 0)

        # Clip to the mask.
        Quartz.CGContextClipToMask(context, maskRect, mask)
        # Release the mask since this code no longer needs it.
        del mask

        # Make a rect that has a width and height 1/3 that of the image mask.
        rect = Quartz.CGRectMake(
            0,
            0,
            Quartz.CGRectGetWidth(maskRect) / 3,
            Quartz.CGRectGetHeight(maskRect) / 3,
        )

        Quartz.CGContextTranslateCTM(context, 0, 2 * Quartz.CGRectGetHeight(rect))

        # Draw a 3 x 3 grid of rectangles, setting the color for each rectangle
        # by cycling through the array of CGColor objects in the 'colors' array.
        for j in range(3):
            Quartz.CGContextSaveGState(context)
            for i in range(3):
                # Draw a row of rectangles.
                # Set the fill color using one of the CGColor objects in the
                # colors array.
                Quartz.CGContextSetFillColorWithColor(context, colors[(i + j) % 4])
                Quartz.CGContextFillRect(context, rect)
                Quartz.CGContextTranslateCTM(context, Quartz.CGRectGetWidth(rect), 0)
            Quartz.CGContextRestoreGState(context)
            # Position to draw the next row.
            Quartz.CGContextTranslateCTM(context, 0, -Quartz.CGRectGetHeight(rect))
