pdf14_fill_mask(gx_device * orig_dev,
                     const byte * data, int dx, int raster, gx_bitmap_id id,
                     int x, int y, int w, int h,
                     const gx_drawing_color * pdcolor, int depth,
                     gs_logical_operation_t lop, const gx_clip_path * pcpath)
{
    gx_device *dev;
    pdf14_device *p14dev = (pdf14_device *)orig_dev;
    gx_device_clip cdev;
    gx_color_tile *ptile = NULL;
    int code = 0;
    gs_int_rect group_rect;
    gx_pattern_trans_t *fill_trans_buffer = NULL;
    bool has_pattern_trans = false;
    cmm_dev_profile_t *dev_profile;

    if (pdcolor == NULL)
        return_error(gs_error_unknownerror);	/* color must be defined */
    /* If we are doing a fill with a pattern that has a transparency then
       go ahead and do a push and a pop of the transparency group */
    if (gx_dc_is_pattern1_color(pdcolor)) {
        if( gx_pattern1_get_transptr(pdcolor) != NULL) {
            ptile = pdcolor->colors.pattern.p_tile;
            /* Set up things in the ptile so that we get the proper
               blending etc */
            /* Set the blending procs and the is_additive setting based
               upon the number of channels */
            if (ptile->ttrans->n_chan-1 < 4) {
                ptile->ttrans->blending_procs = &rgb_blending_procs;
                ptile->ttrans->is_additive = true;
            } else {
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
                ptile->ttrans->is_additive = false;
            }
            /* Set the procs so that we use the proper filling method. */
            gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
            /* Based upon if the tiles overlap pick the type of rect
               fill that we will want to use */
            if (ptile->has_overlap) {
                /* This one does blending since there is tile overlap */
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
            } else {
                /* This one does no blending since there is no tile overlap */
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
            }
            /* Push the group */
            group_rect.p.x = x;
            group_rect.p.y = max(0,y);
            group_rect.q.x = x + w;
            group_rect.q.y = y + h;
            if (!(w <= 0 || h <= 0)) {
                code = pdf14_push_transparency_group(p14dev->ctx, &group_rect,
                     1, 0, 255,255, ptile->blending_mode, 0, 0,
                     ptile->ttrans->n_chan-1, false, NULL, NULL, NULL, NULL);
                if (code < 0)
                    return code;
                /* Set up the output buffer information now that we have
                   pushed the group */
                fill_trans_buffer = new_pattern_trans_buff(p14dev->memory);
                pdf14_get_buffer_information((gx_device *) p14dev,
                                              fill_trans_buffer, NULL, false);
                /* Store this in the appropriate place in pdcolor.  This
                   is released later after the mask fill */
                ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
                has_pattern_trans = true;
            }
        }
    }
    if (pcpath != 0) {
        gx_make_clip_device_on_stack(&cdev, pcpath, orig_dev);
        dev = (gx_device *) & cdev;
    } else
        dev = orig_dev;
    if (depth > 1) {
        /****** CAN'T DO ROP OR HALFTONE WITH ALPHA ******/
        code = (*dev_proc(dev, copy_alpha))
            (dev, data, dx, raster, id, x, y, w, h,
             gx_dc_pure_color(pdcolor), depth);
    } else {
        code = pdcolor->type->fill_masked(pdcolor, data, dx, raster, id,
                                          x, y, w, h, dev, lop, false);
    }
    if (has_pattern_trans) {
        if (code >= 0)
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
        if (code >= 0)
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx,
                                                p14dev->blend_procs,
                                                p14dev->color_info.num_components,
                                                dev_profile->device_profile[0],
                                                orig_dev);
        gs_free_object(p14dev->memory, ptile->ttrans->fill_trans_buffer,
                       "pdf14_fill_mask");
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
    }
    return code;
}