3 Copyright 1986, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
30 #include <X11/Xlibint.h>
31 #include <X11/Xutil.h>
35 static int _XDestroyImage(XImage *);
36 static unsigned long _XGetPixel(XImage *, int, int);
37 static unsigned long _XGetPixel1(XImage *, int, int);
38 static unsigned long _XGetPixel8(XImage *, int, int);
39 static unsigned long _XGetPixel16(XImage *, int, int);
40 static unsigned long _XGetPixel32(XImage *, int, int);
41 static int _XPutPixel(XImage *, int, int, unsigned long);
42 static int _XPutPixel1(XImage *, int, int, unsigned long);
43 static int _XPutPixel8(XImage *, int, int, unsigned long);
44 static int _XPutPixel16(XImage *, int, int, unsigned long);
45 static int _XPutPixel32(XImage *, int, int, unsigned long);
46 static XImage *_XSubImage(XImage *, int, int, unsigned int, unsigned int);
47 static int _XAddPixel(XImage *, long);
49 static unsigned char const _lomask[0x09] = { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
50 static unsigned char const _himask[0x09] = { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00 };
52 /* These two convenience routines return the scanline_pad and bits_per_pixel
53 associated with a specific depth of ZPixmap format image for a
61 register ScreenFormat *fmt = dpy->pixmap_format;
64 for (i = dpy->nformats + 1; --i; ++fmt)
65 if (fmt->depth == depth)
66 return(fmt->scanline_pad);
68 return(dpy->bitmap_pad);
76 register ScreenFormat *fmt = dpy->pixmap_format;
79 for (i = dpy->nformats + 1; --i; ++fmt)
80 if (fmt->depth == depth)
81 return(fmt->bits_per_pixel);
93 * This module provides rudimentary manipulation routines for image data
94 * structures. The functions provided are:
96 * XCreateImage Creates a default XImage data structure
97 * _XDestroyImage Deletes an XImage data structure
98 * _XGetPixel Reads a pixel from an image data structure
99 * _XGetPixel32 Reads a pixel from a 32-bit Z image data structure
100 * _XGetPixel16 Reads a pixel from a 16-bit Z image data structure
101 * _XGetPixel8 Reads a pixel from an 8-bit Z image data structure
102 * _XGetPixel1 Reads a pixel from an 1-bit image data structure
103 * _XPutPixel Writes a pixel into an image data structure
104 * _XPutPixel32 Writes a pixel into a 32-bit Z image data structure
105 * _XPutPixel16 Writes a pixel into a 16-bit Z image data structure
106 * _XPutPixel8 Writes a pixel into an 8-bit Z image data structure
107 * _XPutPixel1 Writes a pixel into an 1-bit image data structure
108 * _XSubImage Clones a new (sub)image from an existing one
109 * _XSetImage Writes an image data pattern into another image
110 * _XAddPixel Adds a constant value to every pixel in an image
112 * The logic contained in these routines makes several assumptions about
113 * the image data structures, and at least for current implementations
114 * these assumptions are believed to be true. They are:
116 * For all formats, bits_per_pixel is less than or equal to 32.
117 * For XY formats, bitmap_unit is always less than or equal to bitmap_pad.
118 * For XY formats, bitmap_unit is 8, 16, or 32 bits.
119 * For Z format, bits_per_pixel is 1, 4, 8, 16, 24, or 32 bits.
121 static void _xynormalizeimagebits (
122 register unsigned char *bp,
123 register XImage *img)
125 register unsigned char c;
127 if (img->byte_order != img->bitmap_bit_order) {
128 switch (img->bitmap_unit) {
141 *(bp + 2) = *(bp + 1);
146 if (img->bitmap_bit_order == MSBFirst)
147 _XReverse_Bytes (bp, img->bitmap_unit >> 3);
150 static void _znormalizeimagebits (
151 register unsigned char *bp,
152 register XImage *img)
154 register unsigned char c;
155 switch (img->bits_per_pixel) {
158 *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF);
178 *(bp + 2) = *(bp + 1);
184 static void _putbits(
185 register char *src, /* address of source bit string */
186 int dstoffset, /* bit offset into destination; range is 0-31 */
187 register int numbits,/* number of bits to copy to destination */
188 register char *dst) /* address of destination bit string */
190 register unsigned char chlo, chhi;
192 dst = dst + (dstoffset >> 3);
193 dstoffset = dstoffset & 7;
194 hibits = 8 - dstoffset;
195 chlo = *dst & _lomask[dstoffset];
197 chhi = (*src << dstoffset) & _himask[dstoffset];
198 if (numbits <= hibits) {
199 chhi = chhi & _lomask[dstoffset + numbits];
200 *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi;
205 numbits = numbits - hibits;
206 chlo = (unsigned char) (*src & _himask[hibits]) >> hibits;
208 if (numbits <= dstoffset) {
209 chlo = chlo & _lomask[numbits];
210 *dst = (*dst & _himask[numbits]) | chlo;
213 numbits = numbits - dstoffset;
221 * The ROUNDUP macro rounds up a quantity to the specified boundary,
222 * then truncates to bytes.
224 * The XYNORMALIZE macro determines whether XY format data requires
225 * normalization and calls a routine to do so if needed. The logic in
226 * this module is designed for LSBFirst byte and bit order, so
227 * normalization is done as required to present the data in this order.
229 * The ZNORMALIZE macro performs byte and nibble order normalization if
230 * required for Z format data.
232 * The XYINDEX macro computes the index to the starting byte (char) boundary
233 * for a bitmap_unit containing a pixel with coordinates x and y for image
236 * The ZINDEX macro computes the index to the starting byte (char) boundary
237 * for a pixel with coordinates x and y for image data in ZPixmap format.
241 #if defined(Lynx) && defined(ROUNDUP)
245 #define ROUNDUP(nbytes, pad) ((((nbytes) + ((pad)-1)) / (pad)) * ((pad)>>3))
247 #define XYNORMALIZE(bp, img) \
248 if ((img->byte_order == MSBFirst) || (img->bitmap_bit_order == MSBFirst)) \
249 _xynormalizeimagebits((unsigned char *)(bp), img)
251 #define ZNORMALIZE(bp, img) \
252 if (img->byte_order == MSBFirst) \
253 _znormalizeimagebits((unsigned char *)(bp), img)
255 #define XYINDEX(x, y, img) \
256 ((y) * img->bytes_per_line) + \
257 (((x) + img->xoffset) / img->bitmap_unit) * (img->bitmap_unit >> 3)
259 #define ZINDEX(x, y, img) ((y) * img->bytes_per_line) + \
260 (((x) * img->bits_per_pixel) >> 3)
263 * This routine initializes the image object function pointers. The
264 * intent is to provide native (i.e. fast) routines for native format images
265 * only using the generic (i.e. slow) routines when fast ones don't exist.
266 * However, with the current rather botched external interface, clients may
267 * have to mung image attributes after the image gets created, so the fast
268 * routines always have to check to make sure the optimization is still
269 * valid, and reinit the functions if not.
271 void _XInitImageFuncPtrs (
272 register XImage *image)
274 image->f.create_image = XCreateImage;
275 image->f.destroy_image = _XDestroyImage;
276 if ((image->format == ZPixmap) && (image->bits_per_pixel == 8)) {
277 image->f.get_pixel = _XGetPixel8;
278 image->f.put_pixel = _XPutPixel8;
279 } else if (((image->bits_per_pixel | image->depth) == 1) &&
280 (image->byte_order == image->bitmap_bit_order)) {
281 image->f.get_pixel = _XGetPixel1;
282 image->f.put_pixel = _XPutPixel1;
283 } else if ((image->format == ZPixmap) &&
284 (image->bits_per_pixel == 32)) {
285 image->f.get_pixel = _XGetPixel32;
286 image->f.put_pixel = _XPutPixel32;
287 } else if ((image->format == ZPixmap) &&
288 (image->bits_per_pixel == 16)) {
289 image->f.get_pixel = _XGetPixel16;
290 image->f.put_pixel = _XPutPixel16;
292 image->f.get_pixel = _XGetPixel;
293 image->f.put_pixel = _XPutPixel;
295 image->f.sub_image = _XSubImage;
296 /* image->f.set_image = _XSetImage;*/
297 image->f.add_pixel = _XAddPixel;
303 * Allocates the memory necessary for an XImage data structure.
304 * Initializes the structure with "default" values and returns XImage.
308 XImage *XCreateImage (
309 register Display *dpy,
310 register Visual *visual,
313 int offset, /*How many pixels from the start of the data does the
314 picture to be transmitted start?*/
320 int image_bytes_per_line)
321 /*How many bytes between a pixel on one line and the pixel with
322 the same X coordinate on the next line? 0 means
323 XCreateImage can calculate it.*/
325 register XImage *image;
326 int bits_per_pixel = 1;
327 int min_bytes_per_line;
329 if (depth == 0 || depth > 32 ||
330 (format != XYBitmap && format != XYPixmap && format != ZPixmap) ||
331 (format == XYBitmap && depth != 1) ||
332 (xpad != 8 && xpad != 16 && xpad != 32) ||
334 return (XImage *) NULL;
335 if ((image = (XImage *) Xcalloc(1, (unsigned) sizeof(XImage))) == NULL)
336 return (XImage *) NULL;
338 image->width = width;
339 image->height = height;
340 image->format = format;
341 image->byte_order = dpy->byte_order;
342 image->bitmap_unit = dpy->bitmap_unit;
343 image->bitmap_bit_order = dpy->bitmap_bit_order;
344 if (visual != NULL) {
345 image->red_mask = visual->red_mask;
346 image->green_mask = visual->green_mask;
347 image->blue_mask = visual->blue_mask;
350 image->red_mask = image->green_mask = image->blue_mask = 0;
352 if (format == ZPixmap)
354 bits_per_pixel = _XGetBitsPerPixel(dpy, (int) depth);
357 image->xoffset = offset;
358 image->bitmap_pad = xpad;
359 image->depth = depth;
362 * compute per line accelerator.
365 if (format == ZPixmap)
367 ROUNDUP((bits_per_pixel * width), image->bitmap_pad);
370 ROUNDUP((width + offset), image->bitmap_pad);
372 if (image_bytes_per_line == 0) {
373 image->bytes_per_line = min_bytes_per_line;
374 } else if (image_bytes_per_line < min_bytes_per_line) {
378 image->bytes_per_line = image_bytes_per_line;
381 image->bits_per_pixel = bits_per_pixel;
382 image->obdata = NULL;
383 _XInitImageFuncPtrs (image);
388 Status XInitImage (XImage *image)
390 int min_bytes_per_line;
392 if (image->depth == 0 || image->depth > 32 ||
393 image->bits_per_pixel > 32 || image->bitmap_unit > 32 ||
394 image->bits_per_pixel < 0 || image->bitmap_unit < 0 ||
395 (image->format != XYBitmap &&
396 image->format != XYPixmap &&
397 image->format != ZPixmap) ||
398 (image->format == XYBitmap && image->depth != 1) ||
399 (image->bitmap_pad != 8 &&
400 image->bitmap_pad != 16 &&
401 image->bitmap_pad != 32) ||
406 * compute per line accelerator.
408 if (image->format == ZPixmap)
410 ROUNDUP((image->bits_per_pixel * image->width),
414 ROUNDUP((image->width + image->xoffset), image->bitmap_pad);
416 if (image->bytes_per_line == 0) {
417 image->bytes_per_line = min_bytes_per_line;
418 } else if (image->bytes_per_line < min_bytes_per_line) {
422 _XInitImageFuncPtrs (image);
430 * Deallocates the memory associated with the ximage data structure.
431 * this version handles the case of the image data being malloc'd
432 * entirely by the library.
435 static int _XDestroyImage (XImage *ximage)
437 if (ximage->data != NULL) Xfree((char *)ximage->data);
438 if (ximage->obdata != NULL) Xfree((char *)ximage->obdata);
439 Xfree((char *)ximage);
447 * Returns the specified pixel. The X and Y coordinates are relative to
448 * the origin (upper left [0,0]) of the image. The pixel value is returned
449 * in normalized format, i.e. the LSB of the long is the LSB of the pixel.
450 * The algorithm used is:
452 * copy the source bitmap_unit or Zpixel into temp
453 * normalize temp if needed
454 * extract the pixel bits into return value
458 static unsigned long const low_bits_table[] = {
459 0x00000000, 0x00000001, 0x00000003, 0x00000007,
460 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
461 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
462 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
463 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
464 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
465 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
466 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
470 static unsigned long _XGetPixel (
471 register XImage *ximage,
476 unsigned long pixel, px;
483 if ((ximage->bits_per_pixel | ximage->depth) == 1) {
484 src = &ximage->data[XYINDEX(x, y, ximage)];
485 dst = (char *)&pixel;
487 for (i = ximage->bitmap_unit >> 3; --i >= 0; ) *dst++ = *src++;
488 XYNORMALIZE(&pixel, ximage);
489 bits = (x + ximage->xoffset) % ximage->bitmap_unit;
490 pixel = ((((char *)&pixel)[bits>>3])>>(bits&7)) & 1;
491 } else if (ximage->format == XYPixmap) {
494 nbytes = ximage->bitmap_unit >> 3;
495 for (i = ximage->depth; --i >= 0; ) {
496 src = &ximage->data[XYINDEX(x, y, ximage)+ plane];
499 for (j = nbytes; --j >= 0; ) *dst++ = *src++;
500 XYNORMALIZE(&px, ximage);
501 bits = (x + ximage->xoffset) % ximage->bitmap_unit;
502 pixel = (pixel << 1) |
503 (((((char *)&px)[bits>>3])>>(bits&7)) & 1);
504 plane = plane + (ximage->bytes_per_line * ximage->height);
506 } else if (ximage->format == ZPixmap) {
507 src = &ximage->data[ZINDEX(x, y, ximage)];
510 for (i = (ximage->bits_per_pixel + 7) >> 3; --i >= 0; )
512 ZNORMALIZE(&px, ximage);
514 for (i=sizeof(unsigned long); --i >= 0; )
515 pixel = (pixel << 8) | ((unsigned char *)&px)[i];
516 if (ximage->bits_per_pixel == 4) {
523 return 0; /* bad image */
525 if (ximage->bits_per_pixel == ximage->depth)
528 return (pixel & low_bits_table[ximage->depth]);
532 static CARD32 const byteorderpixel = MSBFirst << 24;
535 static unsigned long _XGetPixel32 (
536 register XImage *ximage,
540 register unsigned char *addr;
543 if ((ximage->format == ZPixmap) && (ximage->bits_per_pixel == 32)) {
544 addr = &((unsigned char *)ximage->data)
545 [y * ximage->bytes_per_line + (x << 2)];
547 if (*((const char *)&byteorderpixel) == ximage->byte_order)
548 pixel = *((CARD32 *)addr);
551 if (ximage->byte_order == MSBFirst)
552 pixel = ((unsigned long)addr[0] << 24 |
553 (unsigned long)addr[1] << 16 |
554 (unsigned long)addr[2] << 8 |
557 pixel = ((unsigned long)addr[3] << 24 |
558 (unsigned long)addr[2] << 16 |
559 (unsigned long)addr[1] << 8 |
561 if (ximage->depth != 32)
562 pixel &= low_bits_table[ximage->depth];
565 _XInitImageFuncPtrs(ximage);
566 return XGetPixel(ximage, x, y);
570 static unsigned long _XGetPixel16 (
571 register XImage *ximage,
575 register unsigned char *addr;
578 if ((ximage->format == ZPixmap) && (ximage->bits_per_pixel == 16)) {
579 addr = &((unsigned char *)ximage->data)
580 [y * ximage->bytes_per_line + (x << 1)];
581 if (ximage->byte_order == MSBFirst)
582 pixel = addr[0] << 8 | addr[1];
584 pixel = addr[1] << 8 | addr[0];
585 if (ximage->depth != 16)
586 pixel &= low_bits_table[ximage->depth];
589 _XInitImageFuncPtrs(ximage);
590 return XGetPixel(ximage, x, y);
594 static unsigned long _XGetPixel8 (
595 register XImage *ximage,
601 if ((ximage->format == ZPixmap) && (ximage->bits_per_pixel == 8)) {
602 pixel = ((unsigned char *)ximage->data)
603 [y * ximage->bytes_per_line + x];
604 if (ximage->depth != 8)
605 pixel &= low_bits_table[ximage->depth];
608 _XInitImageFuncPtrs(ximage);
609 return XGetPixel(ximage, x, y);
613 static unsigned long _XGetPixel1 (
614 register XImage *ximage,
621 if (((ximage->bits_per_pixel | ximage->depth) == 1) &&
622 (ximage->byte_order == ximage->bitmap_bit_order)) {
623 xoff = x + ximage->xoffset;
624 yoff = y * ximage->bytes_per_line + (xoff >> 3);
626 if (ximage->bitmap_bit_order == MSBFirst)
630 return (ximage->data[yoff] & bit) ? 1 : 0;
632 _XInitImageFuncPtrs(ximage);
633 return XGetPixel(ximage, x, y);
640 * Overwrites the specified pixel. The X and Y coordinates are relative to
641 * the origin (upper left [0,0]) of the image. The input pixel value must be
642 * in normalized format, i.e. the LSB of the long is the LSB of the pixel.
643 * The algorithm used is:
645 * copy the destination bitmap_unit or Zpixel to temp
646 * normalize temp if needed
647 * copy the pixel bits into the temp
648 * renormalize temp if needed
649 * copy the temp back into the destination image data
653 static int _XPutPixel (
654 register XImage *ximage,
660 unsigned long px, npixel;
667 if (ximage->depth == 4)
670 for (i=0, px=pixel; i<sizeof(unsigned long); i++, px>>=8)
671 ((unsigned char *)&pixel)[i] = px;
672 if ((ximage->bits_per_pixel | ximage->depth) == 1) {
673 src = &ximage->data[XYINDEX(x, y, ximage)];
676 nbytes = ximage->bitmap_unit >> 3;
677 for (i = nbytes; --i >= 0; ) *dst++ = *src++;
678 XYNORMALIZE(&px, ximage);
679 i = ((x + ximage->xoffset) % ximage->bitmap_unit);
680 _putbits ((char *)&pixel, i, 1, (char *)&px);
681 XYNORMALIZE(&px, ximage);
683 dst = &ximage->data[XYINDEX(x, y, ximage)];
684 for (i = nbytes; --i >= 0; ) *dst++ = *src++;
685 } else if (ximage->format == XYPixmap) {
686 plane = (ximage->bytes_per_line * ximage->height) *
687 (ximage->depth - 1); /* do least signif plane 1st */
688 nbytes = ximage->bitmap_unit >> 3;
689 for (j = ximage->depth; --j >= 0; ) {
690 src = &ximage->data[XYINDEX(x, y, ximage) + plane];
693 for (i = nbytes; --i >= 0; ) *dst++ = *src++;
694 XYNORMALIZE(&px, ximage);
695 i = ((x + ximage->xoffset) % ximage->bitmap_unit);
696 _putbits ((char *)&pixel, i, 1, (char *)&px);
697 XYNORMALIZE(&px, ximage);
699 dst = &ximage->data[XYINDEX(x, y, ximage) + plane];
700 for (i = nbytes; --i >= 0; ) *dst++ = *src++;
701 npixel = npixel >> 1;
702 for (i=0, px=npixel; i<sizeof(unsigned long); i++, px>>=8)
703 ((unsigned char *)&pixel)[i] = px;
704 plane = plane - (ximage->bytes_per_line * ximage->height);
706 } else if (ximage->format == ZPixmap) {
707 src = &ximage->data[ZINDEX(x, y, ximage)];
710 nbytes = (ximage->bits_per_pixel + 7) >> 3;
711 for (i = nbytes; --i >= 0; ) *dst++ = *src++;
712 ZNORMALIZE(&px, ximage);
713 _putbits ((char *)&pixel,
714 (x * ximage->bits_per_pixel) & 7,
715 ximage->bits_per_pixel, (char *)&px);
716 ZNORMALIZE(&px, ximage);
718 dst = &ximage->data[ZINDEX(x, y, ximage)];
719 for (i = nbytes; --i >= 0; ) *dst++ = *src++;
721 return 0; /* bad image */
726 static int _XPutPixel32 (
727 register XImage *ximage,
734 if ((ximage->format == ZPixmap) && (ximage->bits_per_pixel == 32)) {
735 addr = &((unsigned char *)ximage->data)
736 [y * ximage->bytes_per_line + (x << 2)];
738 if (*((const char *)&byteorderpixel) == ximage->byte_order)
739 *((CARD32 *)addr) = pixel;
742 if (ximage->byte_order == MSBFirst) {
743 addr[0] = pixel >> 24;
744 addr[1] = pixel >> 16;
745 addr[2] = pixel >> 8;
748 addr[3] = pixel >> 24;
749 addr[2] = pixel >> 16;
750 addr[1] = pixel >> 8;
755 _XInitImageFuncPtrs(ximage);
756 return XPutPixel(ximage, x, y, pixel);
760 static int _XPutPixel16 (
761 register XImage *ximage,
768 if ((ximage->format == ZPixmap) && (ximage->bits_per_pixel == 16)) {
769 addr = &((unsigned char *)ximage->data)
770 [y * ximage->bytes_per_line + (x << 1)];
771 if (ximage->byte_order == MSBFirst) {
772 addr[0] = pixel >> 8;
775 addr[1] = pixel >> 8;
780 _XInitImageFuncPtrs(ximage);
781 return XPutPixel(ximage, x, y, pixel);
785 static int _XPutPixel8 (
786 register XImage *ximage,
791 if ((ximage->format == ZPixmap) && (ximage->bits_per_pixel == 8)) {
792 ximage->data[y * ximage->bytes_per_line + x] = pixel;
795 _XInitImageFuncPtrs(ximage);
796 return XPutPixel(ximage, x, y, pixel);
800 static int _XPutPixel1 (
801 register XImage *ximage,
809 if (((ximage->bits_per_pixel | ximage->depth) == 1) &&
810 (ximage->byte_order == ximage->bitmap_bit_order)) {
811 xoff = x + ximage->xoffset;
812 yoff = y * ximage->bytes_per_line + (xoff >> 3);
814 if (ximage->bitmap_bit_order == MSBFirst)
819 ximage->data[yoff] |= bit;
821 ximage->data[yoff] &= ~bit;
824 _XInitImageFuncPtrs(ximage);
825 return XPutPixel(ximage, x, y, pixel);
832 * Creates a new image that is a subsection of an existing one.
833 * Allocates the memory necessary for the new XImage data structure.
834 * Pointer to new image is returned. The algorithm used is repetitive
835 * calls to get and put pixel.
839 static XImage *_XSubImage (
841 register int x, /* starting x coordinate in existing image */
842 register int y, /* starting y coordinate in existing image */
843 unsigned int width, /* width in pixels of new subimage */
844 unsigned int height)/* height in pixels of new subimage */
847 register XImage *subimage;
849 register int row, col;
850 register unsigned long pixel;
853 if ((subimage = (XImage *) Xcalloc (1, sizeof (XImage))) == NULL)
854 return (XImage *) NULL;
855 subimage->width = width;
856 subimage->height = height;
857 subimage->xoffset = 0;
858 subimage->format = ximage->format;
859 subimage->byte_order = ximage->byte_order;
860 subimage->bitmap_unit = ximage->bitmap_unit;
861 subimage->bitmap_bit_order = ximage->bitmap_bit_order;
862 subimage->bitmap_pad = ximage->bitmap_pad;
863 subimage->bits_per_pixel = ximage->bits_per_pixel;
864 subimage->depth = ximage->depth;
866 * compute per line accelerator.
868 if (subimage->format == ZPixmap)
869 subimage->bytes_per_line =
870 ROUNDUP(subimage->bits_per_pixel * width,
871 subimage->bitmap_pad);
873 subimage->bytes_per_line =
874 ROUNDUP(width, subimage->bitmap_pad);
875 subimage->obdata = NULL;
876 _XInitImageFuncPtrs (subimage);
877 dsize = subimage->bytes_per_line * height;
878 if (subimage->format == XYPixmap) dsize = dsize * subimage->depth;
879 if (((data = Xcalloc (1, (unsigned) dsize)) == NULL) && (dsize > 0)) {
880 Xfree((char *) subimage);
881 return (XImage *) NULL;
883 subimage->data = data;
886 * Test for cases where the new subimage is larger than the region
887 * that we are copying from the existing data. In those cases,
888 * copy the area of the existing image, and allow the "uncovered"
889 * area of new subimage to remain with zero filled pixels.
891 if (height > ximage->height - y ) height = ximage->height - y;
892 if (width > ximage->width - x ) width = ximage->width - x;
894 for (row = y; row < (y + height); row++) {
895 for (col = x; col < (x + width); col++) {
896 pixel = XGetPixel(ximage, col, row);
897 XPutPixel(subimage, (col - x), (row - y), pixel);
907 * Overwrites a section of one image with all of the data from another.
908 * If the two images are not of the same format (i.e. XYPixmap and ZPixmap),
909 * the image data is converted to the destination format. The following
910 * restrictions apply:
912 * 1. The depths of the source and destination images must be equal.
914 * 2. If the height of the source image is too large to fit between
915 * the specified y starting point and the bottom of the image,
916 * then scanlines are truncated on the bottom.
918 * 3. If the width of the source image is too large to fit between
919 * the specified x starting point and the end of the scanline,
920 * then pixels are truncated on the right.
922 * The images need not have the same bitmap_bit_order, byte_order,
923 * bitmap_unit, bits_per_pixel, bitmap_pad, or xoffset.
929 register XImage *dstimg,
933 register unsigned long pixel;
934 register int row, col;
935 int width, height, startrow, startcol;
946 width = dstimg->width - x;
947 if (srcimg->width < width)
948 width = srcimg->width;
949 height = dstimg->height - y;
950 if (srcimg->height < height)
951 height = srcimg->height;
953 /* this is slow, will do better later */
954 for (row = startrow; row < height; row++) {
955 for (col = startcol; col < width; col++) {
956 pixel = XGetPixel(srcimg, col, row);
957 XPutPixel(dstimg, x + col, y + row, pixel);
966 * Adds a constant value to every pixel in a pixmap.
972 register XImage *ximage,
980 if ((ximage->bits_per_pixel | ximage->depth) == 1) {
981 /* The only value that we can add here to an XYBitmap
982 * is one. Since 1 + value = ~value for one bit wide
983 * data, we do this quickly by taking the ones complement
984 * of the entire bitmap data (offset and pad included!).
985 * Note that we don't need to be concerned with bit or
988 register unsigned char *dp = (unsigned char *) ximage->data;
989 x = ximage->bytes_per_line * ximage->height;
994 } else if ((ximage->format == ZPixmap) &&
995 (ximage->bits_per_pixel == 8)) {
996 register unsigned char *dp = (unsigned char *) ximage->data;
997 x = ximage->bytes_per_line * ximage->height;
1001 } else if ((ximage->format == ZPixmap) &&
1002 (ximage->bits_per_pixel == 16) &&
1003 (*((const char *)&byteorderpixel) == ximage->byte_order)) {
1004 register unsigned short *dp = (unsigned short *) ximage->data;
1005 x = (ximage->bytes_per_line >> 1) * ximage->height;
1008 } else if ((ximage->format == ZPixmap) &&
1009 (ximage->bits_per_pixel == 32) &&
1010 (*((const char *)&byteorderpixel) == ximage->byte_order)) {
1011 register CARD32 *dp = (CARD32 *) ximage->data;
1012 x = (ximage->bytes_per_line >> 2) * ximage->height;
1017 for (y = ximage->height; --y >= 0; ) {
1018 for (x = ximage->width; --x >= 0; ) {
1019 register unsigned long pixel = XGetPixel(ximage, x, y);
1020 pixel = pixel + value;
1021 XPutPixel(ximage, x, y, pixel);