XP_MEMCPY(maskp, cbuf, mask_header->widthBytes);
nsCRT::memcpy(maskp, cbuf, mask_header->widthBytes);
il_emit_row(    il_container *ic,   /* The image container */    uint8 *cbuf,        /* Color index data source, or NULL if source                           is RGB data */    uint8 *rgbbuf,      /* Packed RGBa data or RGBa workspace if <cbuf> != NULL */    int x_offset,       /* First column to write data into */    int len,            /* Width of source image, in pixels */    int row,            /* Starting row of image */    int dup_row_count,          /* Number of times to duplicate row */    il_draw_mode draw_mode,     /* ilOverlay or ilErase */    int pass)           /* Zero, unless  interlaced GIF,                           in which case ranges 1-4, or progressive JPEG,                           in which case ranges from 1-n. */{    IL_GroupContext *img_cx = ic->img_cx;	  IL_Pixmap *image = ic->image;    IL_Pixmap *mask = ic->mask;    NI_PixmapHeader *src_header = ic->src_header;    NI_PixmapHeader *img_header = &image->header;    NI_PixmapHeader *mask_header = 0;    NI_ColorSpace *src_color_space = src_header->color_space;    NI_ColorSpace *img_color_space = img_header->color_space;	  uint8 XP_HUGE *out;    uint8 XP_HUGE *dp;    uint8 XP_HUGE *mp;	  uint8 XP_HUGE *maskp = NULL;    uint8 XP_HUGE *alphabits, *alphabitstart = NULL;    uint8 *byte_mask = NULL;	  uint8 XP_HUGE *srcbuf = rgbbuf;    uint8 *p = cbuf;    uint8 *pl = cbuf+len;	int drow_start, drow_end, row_count, color_index, dup, do_dither;    int dcolumn_start, dcolumn_end, column_count, offset, src_len, dest_len;   	PR_ASSERT(row >= 0);	if(row >= (int) src_header->height) {		ILTRACE(2,("il: ignoring extra row (%d)", row));		return;	}	/* Set first and last destination row in the image.  Assume no scaling. */	drow_start = row;    drow_end = row + dup_row_count - 1;    dcolumn_start = x_offset;    dcolumn_end = x_offset + len - 1;    /* If scaling, convert vertical image coordinates to display space. */    if (img_header->height != src_header->height) {        int d = drow_start;        int next_drow_start = SCALE_YCOORD(img_header, src_header, drow_end+1);        drow_start = SCALE_YCOORD(img_header, src_header, drow_start);        /*         * Don't emit a row of pixels that will be overwritten later.         * (as may happen during when images are being reduced vertically).         */        if (drow_start == next_drow_start) {            /*             * Except that the bottom line of pixels can never be             * overwritten by a subsequent line.             */            if (d != (int) (src_header->height - 1))                return;            else                drow_end = drow_start;        } else {            drow_end = next_drow_start - 1;            if (drow_end >= (int)img_header->height)                drow_end = img_header->height - 1;        }    }    /* If scaling, convert horizontal image coordinates to display space. */    if (img_header->width != src_header->width) {        int d = dcolumn_start;        int next_dcolumn_start = SCALE_XCOORD(img_header, src_header,                                              dcolumn_end+1);        dcolumn_start = SCALE_XCOORD(img_header, src_header, dcolumn_start);        /*         * Don't emit a column of pixels that will be overwritten later.         * (as may happen during when images are being reduced vertically).         */        if (dcolumn_start == next_dcolumn_start) {            /*             * Except that the right column of pixels can never be             * overwritten by a subsequent column.             */            if (d != (int)(src_header->width - 1))                return;            else                dcolumn_end = dcolumn_start;        } else {            dcolumn_end = next_dcolumn_start - 1;            if (dcolumn_end >= (int)img_header->width)                dcolumn_end = img_header->width - 1;        }    }    /* Number of pixel rows and columns to emit into framebuffer */    row_count = drow_end - drow_start + 1;    column_count = dcolumn_end - dcolumn_start + 1;    /* If an alphamask (8 or 1 bit) exists......*/    if(img_header->alpha_bits) {         mask_header = &mask->header;       img_cx->img_cb->ControlPixmapBits(img_cx->dpy_cx, mask,                                          IL_LOCK_BITS);#ifdef _USD        alphabitstart = maskp = (uint8 XP_HUGE *)mask->bits +             (mask_header->height - drow_start - 1) * mask_header->widthBytes;#else        alphabitstart = maskp = (uint8 XP_HUGE *)mask->bits +            drow_start * mask_header->widthBytes;#endif       if(img_header->alpha_bits == 1)       {         // picks off alphachannel, packs it for 1bit mask and scales if necessary         il_alpha_mask(rgbbuf, (int)len, dcolumn_start,                 alphabitstart, column_count, draw_mode);           uint8 *tmpbuf, *rgbbuf_p;         int i;         rgbbuf_p = tmpbuf = rgbbuf;         for(i=0; i < len; i++){                *rgbbuf_p++ = *tmpbuf++;                *rgbbuf_p++ = *tmpbuf++;                *rgbbuf_p++ = *tmpbuf++;                tmpbuf++;  /* strip off alpha channel */          }        }       else{ /* alpha_bits=8*/          uint8 *tmpbuf, *rgbbuf_p;          int i;          unsigned char *scalemask;          rgbbuf_p = tmpbuf = rgbbuf;          alphabits= alphabitstart;            for(i=0; i < len; i++){                *rgbbuf_p++ = *tmpbuf++;                *rgbbuf_p++ = *tmpbuf++;                *rgbbuf_p++ = *tmpbuf++;                *alphabits++ = *tmpbuf++;  /* put alpha channel in separate buffer */            }                        alphabits = alphabitstart;            if(len != column_count ){                if (!(scalemask= (unsigned char *)PR_MALLOC(column_count)))                {                          ILTRACE(0,("il: MEM scaledmask"));                           return ;                }                il_scale_alpha8( alphabitstart, len, scalemask, column_count);                XP_MEMCPY(alphabitstart, scalemask, column_count);                PR_Free(scalemask);            }                   } /* else */       img_cx->img_cb->ControlPixmapBits(img_cx->dpy_cx, mask,                                          IL_UNLOCK_BITS);    } else if(mask){/* If a mask not attributed to an alpha channel exists..ie:                       a transparent image appears over a background image ... */        mask_header = &mask->header;        /* Bug, we retain the mask from a transparent           LOSRC GIF when the SRC is a JPEG. */        /* PR_ASSERT(cbuf); */                img_cx->img_cb->ControlPixmapBits(img_cx->dpy_cx, mask,                                          IL_LOCK_BITS);#ifdef _USD		maskp = (uint8 XP_HUGE *)mask->bits +             (mask_header->height - drow_start - 1) * mask_header->widthBytes;#else		maskp = (uint8 XP_HUGE *)mask->bits +            drow_start * mask_header->widthBytes;#endif         /* We know this mask is prescaled: */             if (nsCRT::strncasecmp(ic->type, "image/art",9)==0){              /* No scaling needed*/              if (len == column_count)                 XP_MEMCPY(maskp, cbuf, mask_header->widthBytes);              else /* Scale */                 il_scale_mask(cbuf, (int)len,                               dcolumn_start,                               maskp, column_count,                               draw_mode);                  /* Set to NULL, don't let anyone use it by mistake. */                  cbuf = NULL;               }else{               il_generate_scaled_transparency_mask(src_header->transparent_pixel,                                             cbuf, (int)len,                                             dcolumn_start,                                             maskp, column_count,                                             draw_mode);                 }        img_cx->img_cb->ControlPixmapBits(img_cx->dpy_cx, mask,                                          IL_UNLOCK_BITS);   }    	if (!ic->converter) {#ifdef M12N        int i;        int src_trans_pixel_index;        uint8 XP_HUGE * dest;        uint8 *indirect_map = src_color_space->cmap.index;		if (indirect_map == NULL) {		    indirect_map = il_identity_index_map;		}        if ((draw_mode == ilErase) || !src_header->transparent_pixel)            src_trans_pixel_index = -1; /* no transparency */        else            src_trans_pixel_index = src_header->transparent_pixel->index;        img_cx->img_cb->ControlPixmapBits(img_cx->dpy_cx, image,                                          IL_LOCK_BITS);		/* No converter, image is already rendered in pseudocolor. */#ifdef _USD		out = (uint8 XP_HUGE *)image->bits +            (img_header->height - drow_start - 1) * img_header->widthBytes;#else		out = (uint8 XP_HUGE *)image->bits +            drow_start * img_header->widthBytes;#endif        dest = out + dcolumn_start;                /* If horizontal scaling ... */        if (len != column_count) {            il_scale_CI_row(cbuf, len, dest, column_count,                            indirect_map, src_trans_pixel_index);        } else {            /* Convert to FE's palette indices */            for (i = 0; i < len; i++)                if (cbuf[i] != src_trans_pixel_index)                    dest[i] = indirect_map[cbuf[i]];        }        img_cx->img_cb->ControlPixmapBits(img_cx->dpy_cx, image,                                          IL_UNLOCK_BITS);#endif /* M12N */	} else {        /* Generate the output row in RGB space, regardless of screen depth. */		if (cbuf) {			uint8 *r = rgbbuf;			IL_RGB *map = src_color_space->cmap.map, *entry;			if (!src_header->transparent_pixel) {				/* Simple case: no transparency */				while (p < pl) {                    color_index = *p++;					entry = map + color_index;					r[0] = entry->red;					r[1] = entry->green;					r[2] = entry->blue;                    r += 3 ;				}			} else {				/*                 * There are two kinds of transparency, depending on whether                 * the image is overlaying:                 *   1) a solid color background, or                 *   2) another image                 *                 * The first case is easy.  We just substitute the background                 * color for all the transparent pixels in the image.  No mask                 * is necessary.  The second case requires that we generate a                 * bit mask (see the code above).  It also seems to require that                 * all the transparent pixels in the image be set to black.                 * XXX - Why ?  Is this some platform-specific thing ? - fur                 */                int background_r, background_g, background_b;                IL_IRGB *src_trans_pixel = src_header->transparent_pixel;				int src_trans_pixel_index = src_trans_pixel->index;                background_r = background_g = background_b = 0;				if (!ic->mask) {                    /* Solid background color */					background_r = src_trans_pixel->red;					background_g = src_trans_pixel->green;					background_b = src_trans_pixel->blue;                }                                /* Remap transparent pixels */                while (p < pl) {                    color_index = *p++;                    if (color_index == src_trans_pixel_index) {                        r[0] = background_r;                        r[1] = background_g;                        r[2] = background_b;                        r += 3;                    } else {                        entry = map + color_index;                        r[0] = entry->red;                        r[1] = entry->green;                        r[2] = entry->blue;                        r += 3;                    }                }			}		}		/* Now we are in RGB space. */		/* Simple anamorphic scaling (in RGB space for now) */        src_len = len;        dest_len = column_count;		if (src_len != dest_len) {			uint8 XP_HUGE *src = rgbbuf;			uint8 *dest = ic->scalerow;			srcbuf = dest;			/* Scale the pixel data (mask data already scaled) */            il_scale_RGB_row(src, src_len, dest, dest_len);		}        img_cx->img_cb->ControlPixmapBits(img_cx->dpy_cx, image,                                          IL_LOCK_BITS);#ifdef _USD		out = (uint8 XP_HUGE *)image->bits +            (img_header->height-drow_start-1) * (uint32)img_header->widthBytes;#else		out = (uint8 XP_HUGE *)image->bits +            drow_start * img_header->widthBytes;#endif        if (src_header->transparent_pixel && (draw_mode == ilOverlay))        {            if( cbuf ){                il_generate_byte_mask(ic, cbuf, len, il_tmpbuf, column_count);                byte_mask = il_tmpbuf;            }        }                      /*         * Convert RGB to display depth.  If display is pseudocolor, this may         * also color-quantize and dither.         */		(*ic->converter)(ic, byte_mask, srcbuf, dcolumn_start,                         column_count, out);        img_cx->img_cb->ControlPixmapBits(img_cx->dpy_cx, image,                                          IL_UNLOCK_BITS);        /*         * Have to reset transparent pixels to background color         * because color quantization may have mutated them.         */		if (src_header->transparent_pixel &&            (img_color_space->type == NI_PseudoColor) &&            !mask && (draw_mode == ilErase))            il_reset_background_pixels(ic, cbuf, len,                                       out + dcolumn_start, column_count);	}	/*     * We now have one row of pixels and, if required for transparency, a row     * of mask data.  If the pixels in this row of the image cover span more     * than one pixel vertically when displayed, the row needs to be     * replicated in the framebuffer.  (This replication is necessary when     * displaying interlaced GIFs and/or vertical scaling of any image type.)     * Actually, pixel rows are not simply copied: Dithering may need to be     * applied on a line-by-line basis.     */    dp = out;    mp = maskp;    dup = row_count - 1;    offset = dcolumn_start * (img_color_space->pixmap_depth / 8);#ifndef M12N                    /* Clean this up */    if (ic->image->pixmap_depth == 1)        do_dither = TRUE;    else        do_dither = ic->converter && (row_count <= 4) &&            ((ic->dither_mode == IL_Dither) ||             (nsCRT::strncasecmp(ic->type, "image/jpeg",10)==0);#else    do_dither = (ic->dither_mode == IL_Dither);    if ((nsCRT::strncasecmp(ic->type, "image/gif",9)==0)||        (nsCRT::strncasecmp(ic->type, "image/png",9)==0) &&        (!ic->converter || (row_count > 4)))              do_dither = FALSE;   #endif /* M12N */       while (dup--) {#ifdef _USD        dp -= img_header->widthBytes;        if (mask)            mp -= mask_header->widthBytes;#else        dp += img_header->widthBytes;        if (mask)            mp += mask_header->widthBytes;#endif        /* Is dithering being done (either mono or pseudocolor) ... ? */        if (do_dither) {                        /* Dither / color-quantize */            (*ic->converter)(ic, byte_mask, srcbuf, dcolumn_start,                             column_count, dp);            /*             * Have to reset transparent pixels to background color             * because color quantization may have mutated them.             */            if (img_header->transparent_pixel &&                (img_color_space->type == NI_PseudoColor) &&                !mask && (draw_mode == ilErase))                il_reset_background_pixels(ic, cbuf, len, dp + dcolumn_start,                                           column_count);        } else {            /* If no dithering, each row of pixels is exactly the same. */            if (byte_mask)                il_overlay(out + offset, dp + offset, byte_mask, column_count,                           (img_color_space->pixmap_depth/8));            else                XP_MEMCPY(dp + offset, out + offset,                          (img_color_space->pixmap_depth/8) * column_count);        }        /* Duplicate the mask also. */          if (maskp) {               XP_MEMCPY(mp, maskp, mask_header->widthBytes);        }    }    /* If enough rows accumulated, send to the front-end for display. */    il_partial(ic, drow_start, row_count, pass);}