📄 xputimage.c
字号:
/* 2Lm */ { s s s S R W s n w S S S },/* 4Lm */ { l l l L W R l w n L L L },/* 1Ll */ { R R R n s l R S L n n n },/* 2Ll */ { R R R n s l R S L n n n },/* 4Ll */ { R R R n s l R S L n n n }#undef n#undef s#undef l#undef w#undef R#undef S#undef L#undef W};/* Of course, the table above is a lie. We also need to factor in the * order of the source data to cope with swapping half of a unit at the * end of a scanline, since we are trying to avoid de-ref'ing off the * end of the source. * * Defines whether the first half of a unit has the first half of the data */static int Const HalfOrder[12] = { LSBFirst, /* 1Mm */ LSBFirst, /* 2Mm */ LSBFirst, /* 4Mm */ LSBFirst, /* 1Ml */ MSBFirst, /* 2Ml */ MSBFirst, /* 4Ml */ LSBFirst, /* 1Lm */ MSBFirst, /* 2Lm */ MSBFirst, /* 4Lm */ LSBFirst, /* 1Ll */ LSBFirst, /* 2Ll */ LSBFirst /* 4Ll */ };/* Finally, for SwapWords cases, the half order depends not just on the source * but also on the destination scanline unit. Use of this table changes some * MSBFirsts to LSBFirsts that are "do not care" (because the function will be * NoSwap or SwapBits) in addition to changing the desired ones. */static int Const HalfOrderWord[12] = { MSBFirst, /* 1Mm */ MSBFirst, /* 2Mm */ MSBFirst, /* 4Mm */ MSBFirst, /* 1Ml */ MSBFirst, /* 2Ml */ LSBFirst, /* 4Ml */ MSBFirst, /* 1Lm */ MSBFirst, /* 2Lm */ LSBFirst, /* 4Lm */ MSBFirst, /* 1Ll */ MSBFirst, /* 2Ll */ MSBFirst /* 4Ll */ };/* * This macro creates a value from 0 to 11 suitable for indexing * into the table above. */#define ComposeIndex(bitmap_unit, bitmap_bit_order, byte_order) \ (((bitmap_unit == 32) ? 2 : ((bitmap_unit == 16) ? 1 : 0)) \ + (((bitmap_bit_order == MSBFirst) ? 0 : 3) \ + ((byte_order == MSBFirst) ? 0 : 6)))/* Cancel a GetReq operation, before doing _XSend or Data */#if __STDC__ && !(defined(UNIXCPP))#define UnGetReq(name)\ dpy->bufptr -= SIZEOF(x##name##Req);\ dpy->request--#else#define UnGetReq(name)\ dpy->bufptr -= SIZEOF(x/**/name/**/Req);\ dpy->request--#endifstatic voidSendXYImage(dpy, req, image, req_xoffset, req_yoffset) register Display *dpy; register xPutImageReq *req; register XImage *image; int req_xoffset, req_yoffset;{ register int j; long total_xoffset, bytes_per_src, bytes_per_dest, length; long bytes_per_line, bytes_per_src_plane, bytes_per_dest_plane; char *src, *dest, *buf; char *extra = (char *)NULL; register int (*swapfunc)(); int half_order; total_xoffset = image->xoffset + req_xoffset; req->leftPad = total_xoffset & (dpy->bitmap_unit - 1); total_xoffset = (unsigned)(total_xoffset - req->leftPad) >> 3; /* The protocol requires left-pad of zero on all ZPixmap, even * though the 1-bit case is identical to bitmap format. This is a * bug in the protocol, caused because 1-bit ZPixmap was added late * in the game. Hairy shifting code compensation isn't worth it, * just use XYPixmap format instead. */ if ((req->leftPad != 0) && (req->format == ZPixmap)) req->format = XYPixmap; bytes_per_dest = (unsigned long)ROUNDUP((long)req->width + req->leftPad, dpy->bitmap_pad) >> 3; bytes_per_dest_plane = bytes_per_dest * req->height; length = bytes_per_dest_plane * image->depth; req->length += (length + 3) >> 2; swapfunc = SwapFunction[ComposeIndex(image->bitmap_unit, image->bitmap_bit_order, image->byte_order)] [ComposeIndex(dpy->bitmap_unit, dpy->bitmap_bit_order, dpy->byte_order)]; half_order = HalfOrder[ComposeIndex(image->bitmap_unit, image->bitmap_bit_order, image->byte_order)]; if (half_order == MSBFirst) half_order = HalfOrderWord[ComposeIndex(dpy->bitmap_unit, dpy->bitmap_bit_order, dpy->byte_order)]; src = image->data + (image->bytes_per_line * req_yoffset) + total_xoffset; /* when total_xoffset > 0, we have to worry about stepping off the * end of image->data. */ if ((swapfunc == NoSwap) && (image->bytes_per_line == bytes_per_dest) && (((total_xoffset == 0) && ((image->depth == 1) || (image->height == req->height))) || ((image->depth == 1) && ((req_yoffset + req->height) < (unsigned)image->height)))) { Data(dpy, src, length); return; } length = ROUNDUP(length, 4); if ((dpy->bufptr + length) > dpy->bufmax) { if ((buf = _XAllocScratch(dpy, (unsigned long) (length))) == NULL) { UnGetReq(PutImage); return; } } else buf = dpy->bufptr; bytes_per_src = (req->width + req->leftPad + (unsigned)7) >> 3; bytes_per_line = image->bytes_per_line; bytes_per_src_plane = bytes_per_line * image->height; total_xoffset &= (image->bitmap_unit - 1) >> 3; if ((total_xoffset > 0) && (image->byte_order != image->bitmap_bit_order)) { char *temp; long bytes_per_temp_plane, temp_length; bytes_per_line = bytes_per_src + total_xoffset; src -= total_xoffset; bytes_per_temp_plane = bytes_per_line * req->height; temp_length = ROUNDUP(bytes_per_temp_plane * image->depth, 4); if (buf == dpy->bufptr) { if (! (temp = _XAllocScratch(dpy, (unsigned long) temp_length))) { UnGetReq(PutImage); return; } } else if ((extra = temp = Xmalloc((unsigned) temp_length)) == NULL) { UnGetReq(PutImage); return; } swapfunc = SwapFunction[ComposeIndex(image->bitmap_unit, image->bitmap_bit_order, image->byte_order)] [ComposeIndex(image->bitmap_unit, dpy->byte_order, dpy->byte_order)]; for (dest = temp, j = image->depth; --j >= 0; src += bytes_per_src_plane, dest += bytes_per_temp_plane) (*swapfunc)((unsigned char *)src, (unsigned char *)dest, bytes_per_line, (long)image->bytes_per_line, bytes_per_line, req->height, half_order); swapfunc = SwapFunction[ComposeIndex(image->bitmap_unit, dpy->byte_order, dpy->byte_order)] [ComposeIndex(dpy->bitmap_unit, dpy->bitmap_bit_order, dpy->byte_order)]; half_order = HalfOrder[ComposeIndex(image->bitmap_unit, dpy->byte_order, dpy->byte_order)]; src = temp + total_xoffset; bytes_per_src_plane = bytes_per_temp_plane; } for (dest = buf, j = image->depth; --j >= 0; src += bytes_per_src_plane, dest += bytes_per_dest_plane) (*swapfunc)((unsigned char *)src, (unsigned char *)dest, bytes_per_src, bytes_per_line, bytes_per_dest, req->height, half_order); if (extra) Xfree(extra); if (buf == dpy->bufptr) dpy->bufptr += length; else _XSend(dpy, buf, length); }static voidSendZImage(dpy, req, image, req_xoffset, req_yoffset, dest_bits_per_pixel, dest_scanline_pad) register Display *dpy; register xPutImageReq *req; register XImage *image; int req_xoffset, req_yoffset, dest_bits_per_pixel, dest_scanline_pad;{ long bytes_per_src, bytes_per_dest, length; unsigned char *src, *dest; unsigned char *shifted_src = NULL; req->leftPad = 0; bytes_per_src = ROUNDUP((long)req->width * image->bits_per_pixel, 8) >> 3; bytes_per_dest = ROUNDUP((long)req->width * dest_bits_per_pixel, dest_scanline_pad) >> 3; length = bytes_per_dest * req->height; req->length += (length + 3) >> 2; src = (unsigned char *)image->data + (req_yoffset * image->bytes_per_line) + ((req_xoffset * image->bits_per_pixel) >> 3); if ((image->bits_per_pixel == 4) && ((unsigned int) req_xoffset & 0x01)) { if (! (shifted_src = (unsigned char *) Xmalloc((unsigned) (req->height * image->bytes_per_line)))) { UnGetReq(PutImage); return; } ShiftNibblesLeft(src, shifted_src, bytes_per_src, (long) image->bytes_per_line, (long) image->bytes_per_line, req->height, image->byte_order); src = shifted_src; } /* when req_xoffset > 0, we have to worry about stepping off the * end of image->data. */ if (((image->byte_order == dpy->byte_order) || (image->bits_per_pixel == 8)) && ((long)image->bytes_per_line == bytes_per_dest) && ((req_xoffset == 0) || ((req_yoffset + req->height) < (unsigned)image->height))) { Data(dpy, (char *)src, length); if (shifted_src) Xfree((char *)shifted_src); return; } length = ROUNDUP(length, 4); if ((dpy->bufptr + length) <= dpy->bufmax) dest = (unsigned char *)dpy->bufptr; else if ((dest = (unsigned char *) _XAllocScratch(dpy, (unsigned long)(length))) == NULL) { if (shifted_src) Xfree((char *) shifted_src); UnGetReq(PutImage); return; } if ((image->byte_order == dpy->byte_order) || (image->bits_per_pixel == 8)) NoSwap(src, dest, bytes_per_src, (long)image->bytes_per_line, bytes_per_dest, req->height, image->byte_order); else if (image->bits_per_pixel == 32) SwapFourBytes(src, dest, bytes_per_src, (long)image->bytes_per_line, bytes_per_dest, req->height, image->byte_order); else if (image->bits_per_pixel == 24) SwapThreeBytes(src, dest, bytes_per_src, (long)image->bytes_per_line, bytes_per_dest, req->height, image->byte_order); else if (image->bits_per_pixel == 16) SwapTwoBytes(src, dest, bytes_per_src, (long)image->bytes_per_line, bytes_per_dest, req->height, image->byte_order); else SwapNibbles(src, dest, bytes_per_src, (long)image->bytes_per_line, bytes_per_dest, req->height); if (dest == (unsigned char *)dpy->bufptr) dpy->bufptr += length; else _XSend(dpy, (char *)dest, length); if (shifted_src) Xfree((char *)shifted_src);}static voidPutImageRequest(dpy, d, gc, image, req_xoffset, req_yoffset, x, y, req_width, req_height, dest_bits_per_pixel, dest_scanline_pad) register Display *dpy; Drawable d; GC gc; register XImage *image; int x, y; unsigned int req_width, req_height; int req_xoffset, req_yoffset, dest_bits_per_pixel, dest_scanline_pad;{ register xPutImageReq *req; GetReq(PutImage, req); req->drawable = d; req->gc = gc->gid; req->dstX = x; req->dstY = y; req->width = req_width; req->height = req_height; req->depth = image->depth; req->format = image->format; if ((image->depth == 1) || (image->format != ZPixmap)) SendXYImage(dpy, req, image, req_xoffset, req_yoffset); else SendZImage(dpy, req, image, req_xoffset, req_yoffset, dest_bits_per_pixel, dest_scanline_pad);} static voidPutSubImage (dpy, d, gc, image, req_xoffset, req_yoffset, x, y, req_width, req_height, dest_bits_per_pixel, dest_scanline_pad) register Display *dpy; Drawable d; GC gc; register XImage *image; int x, y; unsigned int req_width, req_height; int req_xoffset, req_yoffset, dest_bits_per_pixel, dest_scanline_pad;{ int left_pad, BytesPerRow, Available; if ((req_width == 0) || (req_height == 0)) return; Available = ((65536 < dpy->max_request_size) ? (65536 << 2) : (dpy->max_request_size << 2)) - SIZEOF(xPutImageReq); if ((image->depth == 1) || (image->format != ZPixmap)) { left_pad = (image->xoffset + req_xoffset) & (dpy->bitmap_unit - 1); BytesPerRow = (ROUNDUP((long)req_width + left_pad, dpy->bitmap_pad) >> 3) * image->depth; } else { left_pad = 0; BytesPerRow = ROUNDUP((long)req_width * dest_bits_per_pixel, dest_scanline_pad) >> 3; } if ((BytesPerRow * req_height) <= Available) { PutImageRequest(dpy, d, gc, image, req_xoffset, req_yoffset, x, y, req_width, req_height, dest_bits_per_pixel, dest_scanline_pad); } else if (req_height > 1) { int SubImageHeight = Available / BytesPerRow; if (SubImageHeight == 0) SubImageHeight = 1; PutSubImage(dpy, d, gc, image, req_xoffset, req_yoffset, x, y, req_width, (unsigned int) SubImageHeight, dest_bits_per_pixel, dest_scanline_pad); PutSubImage(dpy, d, gc, image, req_xoffset, req_yoffset + SubImageHeight, x, y + SubImageHeight, req_width, req_height - SubImageHeight, dest_bits_per_pixel, dest_scanline_pad); } else { int SubImageWidth = (((Available << 3) / dest_scanline_pad) * dest_scanline_pad) - left_pad; PutSubImage(dpy, d, gc, image, req_xoffset, req_yoffset, x, y, (unsigned int) SubImageWidth, 1, dest_bits_per_pixel, dest_scanline_pad); PutSubImage(dpy, d, gc, image, req_xoffset + SubImageWidth, req_yoffset, x + SubImageWidth, y, req_width - SubImageWidth, 1, dest_bits_per_pixel, dest_scanline_pad); }}XPutImage (dpy, d, gc, image, req_xoffset, req_yoffset, x, y, req_width, req_height) register Display *dpy; Drawable d; GC gc; register XImage *image; int x, y; unsigned int req_width, req_height; int req_xoffset, req_yoffset;{ long width = req_width; long height = req_height; int dest_bits_per_pixel, dest_scanline_pad; if (req_xoffset < 0) { width += req_xoffset; req_xoffset = 0; } if (req_yoffset < 0) { height += req_yoffset; req_yoffset = 0; } if ((req_xoffset + width) > image->width) width = image->width - req_xoffset; if ((req_yoffset + height) > image->height) height = image->height - req_yoffset; if ((width <= 0) || (height <= 0)) return; if ((image->depth == 1) || (image->format != ZPixmap)) { dest_bits_per_pixel = 1; dest_scanline_pad = dpy->bitmap_pad; } else { register int n; register ScreenFormat *format; dest_bits_per_pixel = image->bits_per_pixel; dest_scanline_pad = image->bitmap_pad; for (n = dpy->nformats, format = dpy->pixmap_format; --n >= 0; format++) if (format->depth == image->depth) { dest_bits_per_pixel = format->bits_per_pixel; dest_scanline_pad = format->scanline_pad; } if (dest_bits_per_pixel != image->bits_per_pixel) { XImage img; register long i, j; /* XXX slow, but works */ img.width = width; img.height = height; img.xoffset = 0; img.format = ZPixmap; img.byte_order = dpy->byte_order; img.bitmap_pad = dest_scanline_pad; img.depth = image->depth; img.bits_per_pixel = dest_bits_per_pixel; img.bytes_per_line = ROUNDUP((dest_bits_per_pixel * width), dest_scanline_pad) >> 3; img.data = Xmalloc((unsigned) (img.bytes_per_line * height)); if (img.data == NULL) return; _XInitImageFuncPtrs(&img); for (j = height; --j >= 0; ) for (i = width; --i >= 0; ) XPutPixel(&img, i, j, XGetPixel(image, req_xoffset + i, req_yoffset + j)); LockDisplay(dpy); FlushGC(dpy, gc); PutSubImage(dpy, d, gc, &img, 0, 0, x, y, (unsigned int) width, (unsigned int) height, dest_bits_per_pixel, dest_scanline_pad); UnlockDisplay(dpy); SyncHandle(); Xfree(img.data); return; } } LockDisplay(dpy); FlushGC(dpy, gc); PutSubImage(dpy, d, gc, image, req_xoffset, req_yoffset, x, y, (unsigned int) width, (unsigned int) height, dest_bits_per_pixel, dest_scanline_pad); UnlockDisplay(dpy); SyncHandle();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -