File: | src/ImUtil.c |
Location: | line 813, column 22 |
Description: | Array access (via field 'data') results in a null pointer dereference |
1 | /* | |||
2 | ||||
3 | Copyright 1986, 1998 The Open Group | |||
4 | ||||
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 | |||
9 | documentation. | |||
10 | ||||
11 | The above copyright notice and this permission notice shall be included in | |||
12 | all copies or substantial portions of the Software. | |||
13 | ||||
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. | |||
20 | ||||
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. | |||
24 | ||||
25 | */ | |||
26 | ||||
27 | #ifdef HAVE_CONFIG_H1 | |||
28 | #include <config.h> | |||
29 | #endif | |||
30 | #include <X11/Xlibint.h> | |||
31 | #include <X11/Xutil.h> | |||
32 | #include <stdio.h> | |||
33 | #include "ImUtil.h" | |||
34 | ||||
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); | |||
48 | ||||
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 }; | |||
51 | ||||
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 | |||
54 | display. */ | |||
55 | ||||
56 | int | |||
57 | _XGetScanlinePad( | |||
58 | Display *dpy, | |||
59 | int depth) | |||
60 | { | |||
61 | register ScreenFormat *fmt = dpy->pixmap_format; | |||
62 | register int i; | |||
63 | ||||
64 | for (i = dpy->nformats + 1; --i; ++fmt) | |||
65 | if (fmt->depth == depth) | |||
66 | return(fmt->scanline_pad); | |||
67 | ||||
68 | return(dpy->bitmap_pad); | |||
69 | } | |||
70 | ||||
71 | int | |||
72 | _XGetBitsPerPixel( | |||
73 | Display *dpy, | |||
74 | int depth) | |||
75 | { | |||
76 | register ScreenFormat *fmt = dpy->pixmap_format; | |||
77 | register int i; | |||
78 | ||||
79 | for (i = dpy->nformats + 1; --i; ++fmt) | |||
80 | if (fmt->depth == depth) | |||
81 | return(fmt->bits_per_pixel); | |||
82 | if (depth <= 4) | |||
83 | return 4; | |||
84 | if (depth <= 8) | |||
85 | return 8; | |||
86 | if (depth <= 16) | |||
87 | return 16; | |||
88 | return 32; | |||
89 | } | |||
90 | ||||
91 | ||||
92 | /* | |||
93 | * This module provides rudimentary manipulation routines for image data | |||
94 | * structures. The functions provided are: | |||
95 | * | |||
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 | |||
111 | * | |||
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: | |||
115 | * | |||
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. | |||
120 | */ | |||
121 | static void _xynormalizeimagebits ( | |||
122 | register unsigned char *bp, | |||
123 | register XImage *img) | |||
124 | { | |||
125 | register unsigned char c; | |||
126 | ||||
127 | if (img->byte_order != img->bitmap_bit_order) { | |||
128 | switch (img->bitmap_unit) { | |||
129 | ||||
130 | case 16: | |||
131 | c = *bp; | |||
132 | *bp = *(bp + 1); | |||
133 | *(bp + 1) = c; | |||
134 | break; | |||
135 | ||||
136 | case 32: | |||
137 | c = *(bp + 3); | |||
138 | *(bp + 3) = *bp; | |||
139 | *bp = c; | |||
140 | c = *(bp + 2); | |||
141 | *(bp + 2) = *(bp + 1); | |||
142 | *(bp + 1) = c; | |||
143 | break; | |||
144 | } | |||
145 | } | |||
146 | if (img->bitmap_bit_order == MSBFirst1) | |||
147 | _XReverse_Bytes (bp, img->bitmap_unit >> 3); | |||
148 | } | |||
149 | ||||
150 | static void _znormalizeimagebits ( | |||
151 | register unsigned char *bp, | |||
152 | register XImage *img) | |||
153 | { | |||
154 | register unsigned char c; | |||
155 | switch (img->bits_per_pixel) { | |||
156 | ||||
157 | case 4: | |||
158 | *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF); | |||
159 | break; | |||
160 | ||||
161 | case 16: | |||
162 | c = *bp; | |||
163 | *bp = *(bp + 1); | |||
164 | *(bp + 1) = c; | |||
165 | break; | |||
166 | ||||
167 | case 24: | |||
168 | c = *(bp + 2); | |||
169 | *(bp + 2) = *bp; | |||
170 | *bp = c; | |||
171 | break; | |||
172 | ||||
173 | case 32: | |||
174 | c = *(bp + 3); | |||
175 | *(bp + 3) = *bp; | |||
176 | *bp = c; | |||
177 | c = *(bp + 2); | |||
178 | *(bp + 2) = *(bp + 1); | |||
179 | *(bp + 1) = c; | |||
180 | break; | |||
181 | } | |||
182 | } | |||
183 | ||||
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 */ | |||
189 | { | |||
190 | register unsigned char chlo, chhi; | |||
191 | int hibits; | |||
192 | dst = dst + (dstoffset >> 3); | |||
193 | dstoffset = dstoffset & 7; | |||
194 | hibits = 8 - dstoffset; | |||
195 | chlo = *dst & _lomask[dstoffset]; | |||
196 | for (;;) { | |||
197 | chhi = (*src << dstoffset) & _himask[dstoffset]; | |||
198 | if (numbits <= hibits) { | |||
199 | chhi = chhi & _lomask[dstoffset + numbits]; | |||
200 | *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi; | |||
201 | break; | |||
202 | } | |||
203 | *dst = chhi | chlo; | |||
204 | dst++; | |||
205 | numbits = numbits - hibits; | |||
206 | chlo = (unsigned char) (*src & _himask[hibits]) >> hibits; | |||
207 | src++; | |||
208 | if (numbits <= dstoffset) { | |||
209 | chlo = chlo & _lomask[numbits]; | |||
210 | *dst = (*dst & _himask[numbits]) | chlo; | |||
211 | break; | |||
212 | } | |||
213 | numbits = numbits - dstoffset; | |||
214 | } | |||
215 | } | |||
216 | ||||
217 | ||||
218 | /* | |||
219 | * Macros | |||
220 | * | |||
221 | * The ROUNDUP macro rounds up a quantity to the specified boundary, | |||
222 | * then truncates to bytes. | |||
223 | * | |||
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. | |||
228 | * | |||
229 | * The ZNORMALIZE macro performs byte and nibble order normalization if | |||
230 | * required for Z format data. | |||
231 | * | |||
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 | |||
234 | * data in XY format. | |||
235 | * | |||
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. | |||
238 | * | |||
239 | */ | |||
240 | ||||
241 | #if defined(Lynx) && defined(ROUNDUP) | |||
242 | #undef ROUNDUP | |||
243 | #endif | |||
244 | ||||
245 | #define ROUNDUP(nbytes, pad)((((nbytes) + ((pad)-1)) / (pad)) * ((pad)>>3)) ((((nbytes) + ((pad)-1)) / (pad)) * ((pad)>>3)) | |||
246 | ||||
247 | #define XYNORMALIZE(bp, img)if ((img->byte_order == 1) || (img->bitmap_bit_order == 1)) _xynormalizeimagebits((unsigned char *)(bp), img) \ | |||
248 | if ((img->byte_order == MSBFirst1) || (img->bitmap_bit_order == MSBFirst1)) \ | |||
249 | _xynormalizeimagebits((unsigned char *)(bp), img) | |||
250 | ||||
251 | #define ZNORMALIZE(bp, img)if (img->byte_order == 1) _znormalizeimagebits((unsigned char *)(bp), img) \ | |||
252 | if (img->byte_order == MSBFirst1) \ | |||
253 | _znormalizeimagebits((unsigned char *)(bp), img) | |||
254 | ||||
255 | #define XYINDEX(x, y, img)((y) * img->bytes_per_line) + (((x) + img->xoffset) / img ->bitmap_unit) * (img->bitmap_unit >> 3) \ | |||
256 | ((y) * img->bytes_per_line) + \ | |||
257 | (((x) + img->xoffset) / img->bitmap_unit) * (img->bitmap_unit >> 3) | |||
258 | ||||
259 | #define ZINDEX(x, y, img)((y) * img->bytes_per_line) + (((x) * img->bits_per_pixel ) >> 3) ((y) * img->bytes_per_line) + \ | |||
260 | (((x) * img->bits_per_pixel) >> 3) | |||
261 | ||||
262 | /* | |||
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. | |||
270 | */ | |||
271 | void _XInitImageFuncPtrs ( | |||
272 | register XImage *image) | |||
273 | { | |||
274 | image->f.create_image = XCreateImage; | |||
275 | image->f.destroy_image = _XDestroyImage; | |||
276 | if ((image->format == ZPixmap2) && (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 == ZPixmap2) && | |||
284 | (image->bits_per_pixel == 32)) { | |||
285 | image->f.get_pixel = _XGetPixel32; | |||
286 | image->f.put_pixel = _XPutPixel32; | |||
287 | } else if ((image->format == ZPixmap2) && | |||
288 | (image->bits_per_pixel == 16)) { | |||
289 | image->f.get_pixel = _XGetPixel16; | |||
290 | image->f.put_pixel = _XPutPixel16; | |||
291 | } else { | |||
292 | image->f.get_pixel = _XGetPixel; | |||
293 | image->f.put_pixel = _XPutPixel; | |||
294 | } | |||
295 | image->f.sub_image = _XSubImage; | |||
296 | /* image->f.set_image = _XSetImage;*/ | |||
297 | image->f.add_pixel = _XAddPixel; | |||
298 | } | |||
299 | ||||
300 | /* | |||
301 | * CreateImage | |||
302 | * | |||
303 | * Allocates the memory necessary for an XImage data structure. | |||
304 | * Initializes the structure with "default" values and returns XImage. | |||
305 | * | |||
306 | */ | |||
307 | ||||
308 | XImage *XCreateImage ( | |||
309 | register Display *dpy, | |||
310 | register Visual *visual, | |||
311 | unsigned int depth, | |||
312 | int format, | |||
313 | int offset, /*How many pixels from the start of the data does the | |||
314 | picture to be transmitted start?*/ | |||
315 | ||||
316 | char *data, | |||
317 | unsigned int width, | |||
318 | unsigned int height, | |||
319 | int xpad, | |||
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.*/ | |||
324 | { | |||
325 | register XImage *image; | |||
326 | int bits_per_pixel = 1; | |||
327 | int min_bytes_per_line; | |||
328 | ||||
329 | if (depth == 0 || depth > 32 || | |||
330 | (format != XYBitmap0 && format != XYPixmap1 && format != ZPixmap2) || | |||
331 | (format == XYBitmap0 && depth != 1) || | |||
332 | (xpad != 8 && xpad != 16 && xpad != 32) || | |||
333 | offset < 0) | |||
334 | return (XImage *) NULL((void*)0); | |||
335 | if ((image = Xcalloc(1, sizeof(XImage))calloc(((1) == 0 ? 1 : (1)), (sizeof(XImage)))) == NULL((void*)0)) | |||
336 | return (XImage *) NULL((void*)0); | |||
337 | ||||
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((void*)0)) { | |||
345 | image->red_mask = visual->red_mask; | |||
346 | image->green_mask = visual->green_mask; | |||
347 | image->blue_mask = visual->blue_mask; | |||
348 | } | |||
349 | else { | |||
350 | image->red_mask = image->green_mask = image->blue_mask = 0; | |||
351 | } | |||
352 | if (format == ZPixmap2) | |||
353 | { | |||
354 | bits_per_pixel = _XGetBitsPerPixel(dpy, (int) depth); | |||
355 | } | |||
356 | ||||
357 | image->xoffset = offset; | |||
358 | image->bitmap_pad = xpad; | |||
359 | image->depth = depth; | |||
360 | image->data = data; | |||
361 | /* | |||
362 | * compute per line accelerator. | |||
363 | */ | |||
364 | { | |||
365 | if (format == ZPixmap2) | |||
366 | min_bytes_per_line = | |||
367 | ROUNDUP((bits_per_pixel * width), image->bitmap_pad)(((((bits_per_pixel * width)) + ((image->bitmap_pad)-1)) / (image->bitmap_pad)) * ((image->bitmap_pad)>>3)); | |||
368 | else | |||
369 | min_bytes_per_line = | |||
370 | ROUNDUP((width + offset), image->bitmap_pad)(((((width + offset)) + ((image->bitmap_pad)-1)) / (image-> bitmap_pad)) * ((image->bitmap_pad)>>3)); | |||
371 | } | |||
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) { | |||
375 | Xfree(image)free((image)); | |||
376 | return NULL((void*)0); | |||
377 | } else { | |||
378 | image->bytes_per_line = image_bytes_per_line; | |||
379 | } | |||
380 | ||||
381 | image->bits_per_pixel = bits_per_pixel; | |||
382 | image->obdata = NULL((void*)0); | |||
383 | _XInitImageFuncPtrs (image); | |||
384 | ||||
385 | return image; | |||
386 | } | |||
387 | ||||
388 | Statusint XInitImage (XImage *image) | |||
389 | { | |||
390 | int min_bytes_per_line; | |||
391 | ||||
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 != XYBitmap0 && | |||
396 | image->format != XYPixmap1 && | |||
397 | image->format != ZPixmap2) || | |||
398 | (image->format == XYBitmap0 && image->depth != 1) || | |||
399 | (image->bitmap_pad != 8 && | |||
400 | image->bitmap_pad != 16 && | |||
401 | image->bitmap_pad != 32) || | |||
402 | image->xoffset < 0) | |||
403 | return 0; | |||
404 | ||||
405 | /* | |||
406 | * compute per line accelerator. | |||
407 | */ | |||
408 | if (image->format == ZPixmap2) | |||
409 | min_bytes_per_line = | |||
410 | ROUNDUP((image->bits_per_pixel * image->width),(((((image->bits_per_pixel * image->width)) + ((image-> bitmap_pad)-1)) / (image->bitmap_pad)) * ((image->bitmap_pad )>>3)) | |||
411 | image->bitmap_pad)(((((image->bits_per_pixel * image->width)) + ((image-> bitmap_pad)-1)) / (image->bitmap_pad)) * ((image->bitmap_pad )>>3)); | |||
412 | else | |||
413 | min_bytes_per_line = | |||
414 | ROUNDUP((image->width + image->xoffset), image->bitmap_pad)(((((image->width + image->xoffset)) + ((image->bitmap_pad )-1)) / (image->bitmap_pad)) * ((image->bitmap_pad)>> 3)); | |||
415 | ||||
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) { | |||
419 | return 0; | |||
420 | } | |||
421 | ||||
422 | _XInitImageFuncPtrs (image); | |||
423 | ||||
424 | return 1; | |||
425 | } | |||
426 | ||||
427 | /* | |||
428 | * _DestroyImage | |||
429 | * | |||
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. | |||
433 | */ | |||
434 | ||||
435 | static int _XDestroyImage (XImage *ximage) | |||
436 | { | |||
437 | Xfree(ximage->data)free((ximage->data)); | |||
438 | Xfree(ximage->obdata)free((ximage->obdata)); | |||
439 | Xfree(ximage)free((ximage)); | |||
440 | return 1; | |||
441 | } | |||
442 | ||||
443 | ||||
444 | /* | |||
445 | * GetPixel | |||
446 | * | |||
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: | |||
451 | * | |||
452 | * copy the source bitmap_unit or Zpixel into temp | |||
453 | * normalize temp if needed | |||
454 | * extract the pixel bits into return value | |||
455 | * | |||
456 | */ | |||
457 | ||||
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, | |||
467 | 0xffffffff | |||
468 | }; | |||
469 | ||||
470 | static unsigned long _XGetPixel ( | |||
471 | register XImage *ximage, | |||
472 | int x, | |||
473 | int y) | |||
474 | ||||
475 | { | |||
476 | unsigned long pixel, px; | |||
477 | register char *src; | |||
478 | register char *dst; | |||
479 | register int i, j; | |||
480 | int bits, nbytes; | |||
481 | long plane; | |||
482 | ||||
483 | if ((ximage->bits_per_pixel | ximage->depth) == 1) { | |||
484 | src = &ximage->data[XYINDEX(x, y, ximage)((y) * ximage->bytes_per_line) + (((x) + ximage->xoffset ) / ximage->bitmap_unit) * (ximage->bitmap_unit >> 3)]; | |||
485 | dst = (char *)&pixel; | |||
486 | pixel = 0; | |||
487 | for (i = ximage->bitmap_unit >> 3; --i >= 0; ) *dst++ = *src++; | |||
488 | XYNORMALIZE(&pixel, ximage)if ((ximage->byte_order == 1) || (ximage->bitmap_bit_order == 1)) _xynormalizeimagebits((unsigned char *)(&pixel), ximage ); | |||
489 | bits = (x + ximage->xoffset) % ximage->bitmap_unit; | |||
490 | pixel = ((((char *)&pixel)[bits>>3])>>(bits&7)) & 1; | |||
491 | } else if (ximage->format == XYPixmap1) { | |||
492 | pixel = 0; | |||
493 | plane = 0; | |||
494 | nbytes = ximage->bitmap_unit >> 3; | |||
495 | for (i = ximage->depth; --i >= 0; ) { | |||
496 | src = &ximage->data[XYINDEX(x, y, ximage)((y) * ximage->bytes_per_line) + (((x) + ximage->xoffset ) / ximage->bitmap_unit) * (ximage->bitmap_unit >> 3)+ plane]; | |||
497 | dst = (char *)&px; | |||
498 | px = 0; | |||
499 | for (j = nbytes; --j >= 0; ) *dst++ = *src++; | |||
500 | XYNORMALIZE(&px, ximage)if ((ximage->byte_order == 1) || (ximage->bitmap_bit_order == 1)) _xynormalizeimagebits((unsigned char *)(&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); | |||
505 | } | |||
506 | } else if (ximage->format == ZPixmap2) { | |||
507 | src = &ximage->data[ZINDEX(x, y, ximage)((y) * ximage->bytes_per_line) + (((x) * ximage->bits_per_pixel ) >> 3)]; | |||
508 | dst = (char *)&px; | |||
509 | px = 0; | |||
510 | for (i = (ximage->bits_per_pixel + 7) >> 3; --i >= 0; ) | |||
511 | *dst++ = *src++; | |||
512 | ZNORMALIZE(&px, ximage)if (ximage->byte_order == 1) _znormalizeimagebits((unsigned char *)(&px), ximage); | |||
513 | pixel = 0; | |||
514 | for (i=sizeof(unsigned long); --i >= 0; ) | |||
515 | pixel = (pixel << 8) | ((unsigned char *)&px)[i]; | |||
516 | if (ximage->bits_per_pixel == 4) { | |||
517 | if (x & 1) | |||
518 | pixel >>= 4; | |||
519 | else | |||
520 | pixel &= 0xf; | |||
521 | } | |||
522 | } else { | |||
523 | return 0; /* bad image */ | |||
524 | } | |||
525 | if (ximage->bits_per_pixel == ximage->depth) | |||
526 | return pixel; | |||
527 | else | |||
528 | return (pixel & low_bits_table[ximage->depth]); | |||
529 | } | |||
530 | ||||
531 | static CARD32 const byteorderpixel = MSBFirst1 << 24; | |||
532 | ||||
533 | static unsigned long _XGetPixel32 ( | |||
534 | register XImage *ximage, | |||
535 | int x, | |||
536 | int y) | |||
537 | { | |||
538 | register unsigned char *addr; | |||
539 | unsigned long pixel; | |||
540 | ||||
541 | if ((ximage->format == ZPixmap2) && (ximage->bits_per_pixel == 32)) { | |||
542 | addr = &((unsigned char *)ximage->data) | |||
543 | [y * ximage->bytes_per_line + (x << 2)]; | |||
544 | if (*((const char *)&byteorderpixel) == ximage->byte_order) | |||
545 | pixel = *((CARD32 *)addr); | |||
546 | else if (ximage->byte_order == MSBFirst1) | |||
547 | pixel = ((unsigned long)addr[0] << 24 | | |||
548 | (unsigned long)addr[1] << 16 | | |||
549 | (unsigned long)addr[2] << 8 | | |||
550 | addr[3]); | |||
551 | else | |||
552 | pixel = ((unsigned long)addr[3] << 24 | | |||
553 | (unsigned long)addr[2] << 16 | | |||
554 | (unsigned long)addr[1] << 8 | | |||
555 | addr[0]); | |||
556 | if (ximage->depth != 32) | |||
557 | pixel &= low_bits_table[ximage->depth]; | |||
558 | return pixel; | |||
559 | } else { | |||
560 | _XInitImageFuncPtrs(ximage); | |||
561 | return XGetPixel(ximage, x, y)((*((ximage)->f.get_pixel))((ximage), (x), (y))); | |||
562 | } | |||
563 | } | |||
564 | ||||
565 | static unsigned long _XGetPixel16 ( | |||
566 | register XImage *ximage, | |||
567 | int x, | |||
568 | int y) | |||
569 | { | |||
570 | register unsigned char *addr; | |||
571 | unsigned long pixel; | |||
572 | ||||
573 | if ((ximage->format == ZPixmap2) && (ximage->bits_per_pixel == 16)) { | |||
574 | addr = &((unsigned char *)ximage->data) | |||
575 | [y * ximage->bytes_per_line + (x << 1)]; | |||
576 | if (ximage->byte_order == MSBFirst1) | |||
577 | pixel = addr[0] << 8 | addr[1]; | |||
578 | else | |||
579 | pixel = addr[1] << 8 | addr[0]; | |||
580 | if (ximage->depth != 16) | |||
581 | pixel &= low_bits_table[ximage->depth]; | |||
582 | return pixel; | |||
583 | } else { | |||
584 | _XInitImageFuncPtrs(ximage); | |||
585 | return XGetPixel(ximage, x, y)((*((ximage)->f.get_pixel))((ximage), (x), (y))); | |||
586 | } | |||
587 | } | |||
588 | ||||
589 | static unsigned long _XGetPixel8 ( | |||
590 | register XImage *ximage, | |||
591 | int x, | |||
592 | int y) | |||
593 | { | |||
594 | unsigned char pixel; | |||
595 | ||||
596 | if ((ximage->format == ZPixmap2) && (ximage->bits_per_pixel == 8)) { | |||
597 | pixel = ((unsigned char *)ximage->data) | |||
598 | [y * ximage->bytes_per_line + x]; | |||
599 | if (ximage->depth != 8) | |||
600 | pixel &= low_bits_table[ximage->depth]; | |||
601 | return pixel; | |||
602 | } else { | |||
603 | _XInitImageFuncPtrs(ximage); | |||
604 | return XGetPixel(ximage, x, y)((*((ximage)->f.get_pixel))((ximage), (x), (y))); | |||
605 | } | |||
606 | } | |||
607 | ||||
608 | static unsigned long _XGetPixel1 ( | |||
609 | register XImage *ximage, | |||
610 | int x, | |||
611 | int y) | |||
612 | { | |||
613 | unsigned char bit; | |||
614 | int xoff, yoff; | |||
615 | ||||
616 | if (((ximage->bits_per_pixel | ximage->depth) == 1) && | |||
617 | (ximage->byte_order == ximage->bitmap_bit_order)) { | |||
618 | xoff = x + ximage->xoffset; | |||
619 | yoff = y * ximage->bytes_per_line + (xoff >> 3); | |||
620 | xoff &= 7; | |||
621 | if (ximage->bitmap_bit_order == MSBFirst1) | |||
622 | bit = 0x80 >> xoff; | |||
623 | else | |||
624 | bit = 1 << xoff; | |||
625 | return (ximage->data[yoff] & bit) ? 1 : 0; | |||
626 | } else { | |||
627 | _XInitImageFuncPtrs(ximage); | |||
628 | return XGetPixel(ximage, x, y)((*((ximage)->f.get_pixel))((ximage), (x), (y))); | |||
629 | } | |||
630 | } | |||
631 | ||||
632 | /* | |||
633 | * PutPixel | |||
634 | * | |||
635 | * Overwrites the specified pixel. The X and Y coordinates are relative to | |||
636 | * the origin (upper left [0,0]) of the image. The input pixel value must be | |||
637 | * in normalized format, i.e. the LSB of the long is the LSB of the pixel. | |||
638 | * The algorithm used is: | |||
639 | * | |||
640 | * copy the destination bitmap_unit or Zpixel to temp | |||
641 | * normalize temp if needed | |||
642 | * copy the pixel bits into the temp | |||
643 | * renormalize temp if needed | |||
644 | * copy the temp back into the destination image data | |||
645 | * | |||
646 | */ | |||
647 | ||||
648 | static int _XPutPixel ( | |||
649 | register XImage *ximage, | |||
650 | int x, | |||
651 | int y, | |||
652 | unsigned long pixel) | |||
653 | ||||
654 | { | |||
655 | unsigned long px, npixel; | |||
656 | register char *src; | |||
657 | register char *dst; | |||
658 | register int i; | |||
659 | int j, nbytes; | |||
660 | long plane; | |||
661 | ||||
662 | if (ximage->depth == 4) | |||
663 | pixel &= 0xf; | |||
664 | npixel = pixel; | |||
665 | for (i=0, px=pixel; i<sizeof(unsigned long); i++, px>>=8) | |||
666 | ((unsigned char *)&pixel)[i] = px; | |||
667 | if ((ximage->bits_per_pixel | ximage->depth) == 1) { | |||
668 | src = &ximage->data[XYINDEX(x, y, ximage)((y) * ximage->bytes_per_line) + (((x) + ximage->xoffset ) / ximage->bitmap_unit) * (ximage->bitmap_unit >> 3)]; | |||
669 | dst = (char *)&px; | |||
670 | px = 0; | |||
671 | nbytes = ximage->bitmap_unit >> 3; | |||
672 | for (i = nbytes; --i >= 0; ) *dst++ = *src++; | |||
673 | XYNORMALIZE(&px, ximage)if ((ximage->byte_order == 1) || (ximage->bitmap_bit_order == 1)) _xynormalizeimagebits((unsigned char *)(&px), ximage ); | |||
674 | i = ((x + ximage->xoffset) % ximage->bitmap_unit); | |||
675 | _putbits ((char *)&pixel, i, 1, (char *)&px); | |||
676 | XYNORMALIZE(&px, ximage)if ((ximage->byte_order == 1) || (ximage->bitmap_bit_order == 1)) _xynormalizeimagebits((unsigned char *)(&px), ximage ); | |||
677 | src = (char *) &px; | |||
678 | dst = &ximage->data[XYINDEX(x, y, ximage)((y) * ximage->bytes_per_line) + (((x) + ximage->xoffset ) / ximage->bitmap_unit) * (ximage->bitmap_unit >> 3)]; | |||
679 | for (i = nbytes; --i >= 0; ) *dst++ = *src++; | |||
680 | } else if (ximage->format == XYPixmap1) { | |||
681 | plane = (ximage->bytes_per_line * ximage->height) * | |||
682 | (ximage->depth - 1); /* do least signif plane 1st */ | |||
683 | nbytes = ximage->bitmap_unit >> 3; | |||
684 | for (j = ximage->depth; --j >= 0; ) { | |||
685 | src = &ximage->data[XYINDEX(x, y, ximage)((y) * ximage->bytes_per_line) + (((x) + ximage->xoffset ) / ximage->bitmap_unit) * (ximage->bitmap_unit >> 3) + plane]; | |||
686 | dst = (char *) &px; | |||
687 | px = 0; | |||
688 | for (i = nbytes; --i >= 0; ) *dst++ = *src++; | |||
689 | XYNORMALIZE(&px, ximage)if ((ximage->byte_order == 1) || (ximage->bitmap_bit_order == 1)) _xynormalizeimagebits((unsigned char *)(&px), ximage ); | |||
690 | i = ((x + ximage->xoffset) % ximage->bitmap_unit); | |||
691 | _putbits ((char *)&pixel, i, 1, (char *)&px); | |||
692 | XYNORMALIZE(&px, ximage)if ((ximage->byte_order == 1) || (ximage->bitmap_bit_order == 1)) _xynormalizeimagebits((unsigned char *)(&px), ximage ); | |||
693 | src = (char *)&px; | |||
694 | dst = &ximage->data[XYINDEX(x, y, ximage)((y) * ximage->bytes_per_line) + (((x) + ximage->xoffset ) / ximage->bitmap_unit) * (ximage->bitmap_unit >> 3) + plane]; | |||
695 | for (i = nbytes; --i >= 0; ) *dst++ = *src++; | |||
696 | npixel = npixel >> 1; | |||
697 | for (i=0, px=npixel; i<sizeof(unsigned long); i++, px>>=8) | |||
698 | ((unsigned char *)&pixel)[i] = px; | |||
699 | plane = plane - (ximage->bytes_per_line * ximage->height); | |||
700 | } | |||
701 | } else if (ximage->format == ZPixmap2) { | |||
702 | src = &ximage->data[ZINDEX(x, y, ximage)((y) * ximage->bytes_per_line) + (((x) * ximage->bits_per_pixel ) >> 3)]; | |||
703 | dst = (char *)&px; | |||
704 | px = 0; | |||
705 | nbytes = (ximage->bits_per_pixel + 7) >> 3; | |||
706 | for (i = nbytes; --i >= 0; ) *dst++ = *src++; | |||
707 | ZNORMALIZE(&px, ximage)if (ximage->byte_order == 1) _znormalizeimagebits((unsigned char *)(&px), ximage); | |||
708 | _putbits ((char *)&pixel, | |||
709 | (x * ximage->bits_per_pixel) & 7, | |||
710 | ximage->bits_per_pixel, (char *)&px); | |||
711 | ZNORMALIZE(&px, ximage)if (ximage->byte_order == 1) _znormalizeimagebits((unsigned char *)(&px), ximage); | |||
712 | src = (char *)&px; | |||
713 | dst = &ximage->data[ZINDEX(x, y, ximage)((y) * ximage->bytes_per_line) + (((x) * ximage->bits_per_pixel ) >> 3)]; | |||
714 | for (i = nbytes; --i >= 0; ) *dst++ = *src++; | |||
715 | } else { | |||
716 | return 0; /* bad image */ | |||
717 | } | |||
718 | return 1; | |||
719 | } | |||
720 | ||||
721 | static int _XPutPixel32 ( | |||
722 | register XImage *ximage, | |||
723 | int x, | |||
724 | int y, | |||
725 | unsigned long pixel) | |||
726 | { | |||
727 | unsigned char *addr; | |||
728 | ||||
729 | if ((ximage->format == ZPixmap2) && (ximage->bits_per_pixel == 32)) { | |||
730 | addr = &((unsigned char *)ximage->data) | |||
731 | [y * ximage->bytes_per_line + (x << 2)]; | |||
732 | if (*((const char *)&byteorderpixel) == ximage->byte_order) | |||
733 | *((CARD32 *)addr) = pixel; | |||
734 | else if (ximage->byte_order == MSBFirst1) { | |||
735 | addr[0] = pixel >> 24; | |||
736 | addr[1] = pixel >> 16; | |||
737 | addr[2] = pixel >> 8; | |||
738 | addr[3] = pixel; | |||
739 | } else { | |||
740 | addr[3] = pixel >> 24; | |||
741 | addr[2] = pixel >> 16; | |||
742 | addr[1] = pixel >> 8; | |||
743 | addr[0] = pixel; | |||
744 | } | |||
745 | return 1; | |||
746 | } else { | |||
747 | _XInitImageFuncPtrs(ximage); | |||
748 | return XPutPixel(ximage, x, y, pixel)((*((ximage)->f.put_pixel))((ximage), (x), (y), (pixel))); | |||
749 | } | |||
750 | } | |||
751 | ||||
752 | static int _XPutPixel16 ( | |||
753 | register XImage *ximage, | |||
754 | int x, | |||
755 | int y, | |||
756 | unsigned long pixel) | |||
757 | { | |||
758 | unsigned char *addr; | |||
759 | ||||
760 | if ((ximage->format == ZPixmap2) && (ximage->bits_per_pixel == 16)) { | |||
761 | addr = &((unsigned char *)ximage->data) | |||
762 | [y * ximage->bytes_per_line + (x << 1)]; | |||
763 | if (ximage->byte_order == MSBFirst1) { | |||
764 | addr[0] = pixel >> 8; | |||
765 | addr[1] = pixel; | |||
766 | } else { | |||
767 | addr[1] = pixel >> 8; | |||
768 | addr[0] = pixel; | |||
769 | } | |||
770 | return 1; | |||
771 | } else { | |||
772 | _XInitImageFuncPtrs(ximage); | |||
773 | return XPutPixel(ximage, x, y, pixel)((*((ximage)->f.put_pixel))((ximage), (x), (y), (pixel))); | |||
774 | } | |||
775 | } | |||
776 | ||||
777 | static int _XPutPixel8 ( | |||
778 | register XImage *ximage, | |||
779 | int x, | |||
780 | int y, | |||
781 | unsigned long pixel) | |||
782 | { | |||
783 | if ((ximage->format == ZPixmap2) && (ximage->bits_per_pixel == 8)) { | |||
784 | ximage->data[y * ximage->bytes_per_line + x] = pixel; | |||
785 | return 1; | |||
786 | } else { | |||
787 | _XInitImageFuncPtrs(ximage); | |||
788 | return XPutPixel(ximage, x, y, pixel)((*((ximage)->f.put_pixel))((ximage), (x), (y), (pixel))); | |||
789 | } | |||
790 | } | |||
791 | ||||
792 | static int _XPutPixel1 ( | |||
793 | register XImage *ximage, | |||
794 | int x, | |||
795 | int y, | |||
796 | unsigned long pixel) | |||
797 | { | |||
798 | unsigned char bit; | |||
799 | int xoff, yoff; | |||
800 | ||||
801 | if (((ximage->bits_per_pixel | ximage->depth) == 1) && | |||
802 | (ximage->byte_order == ximage->bitmap_bit_order)) { | |||
803 | xoff = x + ximage->xoffset; | |||
804 | yoff = y * ximage->bytes_per_line + (xoff >> 3); | |||
805 | xoff &= 7; | |||
806 | if (ximage->bitmap_bit_order == MSBFirst1) | |||
807 | bit = 0x80 >> xoff; | |||
808 | else | |||
809 | bit = 1 << xoff; | |||
810 | if (pixel & 1) | |||
811 | ximage->data[yoff] |= bit; | |||
812 | else | |||
813 | ximage->data[yoff] &= ~bit; | |||
| ||||
814 | return 1; | |||
815 | } else { | |||
816 | _XInitImageFuncPtrs(ximage); | |||
817 | return XPutPixel(ximage, x, y, pixel)((*((ximage)->f.put_pixel))((ximage), (x), (y), (pixel))); | |||
818 | } | |||
819 | } | |||
820 | ||||
821 | /* | |||
822 | * SubImage | |||
823 | * | |||
824 | * Creates a new image that is a subsection of an existing one. | |||
825 | * Allocates the memory necessary for the new XImage data structure. | |||
826 | * Pointer to new image is returned. The algorithm used is repetitive | |||
827 | * calls to get and put pixel. | |||
828 | * | |||
829 | */ | |||
830 | ||||
831 | static XImage *_XSubImage ( | |||
832 | XImage *ximage, | |||
833 | register int x, /* starting x coordinate in existing image */ | |||
834 | register int y, /* starting y coordinate in existing image */ | |||
835 | unsigned int width, /* width in pixels of new subimage */ | |||
836 | unsigned int height)/* height in pixels of new subimage */ | |||
837 | ||||
838 | { | |||
839 | register XImage *subimage; | |||
840 | int dsize; | |||
841 | register int row, col; | |||
842 | register unsigned long pixel; | |||
843 | char *data; | |||
844 | ||||
845 | if ((subimage = Xcalloc (1, sizeof (XImage))calloc(((1) == 0 ? 1 : (1)), (sizeof (XImage)))) == NULL((void*)0)) | |||
| ||||
846 | return (XImage *) NULL((void*)0); | |||
847 | subimage->width = width; | |||
848 | subimage->height = height; | |||
849 | subimage->xoffset = 0; | |||
850 | subimage->format = ximage->format; | |||
851 | subimage->byte_order = ximage->byte_order; | |||
852 | subimage->bitmap_unit = ximage->bitmap_unit; | |||
853 | subimage->bitmap_bit_order = ximage->bitmap_bit_order; | |||
854 | subimage->bitmap_pad = ximage->bitmap_pad; | |||
855 | subimage->bits_per_pixel = ximage->bits_per_pixel; | |||
856 | subimage->depth = ximage->depth; | |||
857 | /* | |||
858 | * compute per line accelerator. | |||
859 | */ | |||
860 | if (subimage->format == ZPixmap2) | |||
861 | subimage->bytes_per_line = | |||
862 | ROUNDUP(subimage->bits_per_pixel * width,((((subimage->bits_per_pixel * width) + ((subimage->bitmap_pad )-1)) / (subimage->bitmap_pad)) * ((subimage->bitmap_pad )>>3)) | |||
863 | subimage->bitmap_pad)((((subimage->bits_per_pixel * width) + ((subimage->bitmap_pad )-1)) / (subimage->bitmap_pad)) * ((subimage->bitmap_pad )>>3)); | |||
864 | else | |||
865 | subimage->bytes_per_line = | |||
866 | ROUNDUP(width, subimage->bitmap_pad)((((width) + ((subimage->bitmap_pad)-1)) / (subimage->bitmap_pad )) * ((subimage->bitmap_pad)>>3)); | |||
867 | subimage->obdata = NULL((void*)0); | |||
868 | _XInitImageFuncPtrs (subimage); | |||
869 | dsize = subimage->bytes_per_line * height; | |||
870 | if (subimage->format == XYPixmap1) dsize = dsize * subimage->depth; | |||
871 | if (((data = Xcalloc (1, dsize)calloc(((1) == 0 ? 1 : (1)), (dsize))) == NULL((void*)0)) && (dsize > 0)) { | |||
872 | Xfree(subimage)free((subimage)); | |||
873 | return (XImage *) NULL((void*)0); | |||
874 | } | |||
875 | subimage->data = data; | |||
876 | ||||
877 | /* | |||
878 | * Test for cases where the new subimage is larger than the region | |||
879 | * that we are copying from the existing data. In those cases, | |||
880 | * copy the area of the existing image, and allow the "uncovered" | |||
881 | * area of new subimage to remain with zero filled pixels. | |||
882 | */ | |||
883 | if (height > ximage->height - y ) height = ximage->height - y; | |||
884 | if (width > ximage->width - x ) width = ximage->width - x; | |||
885 | ||||
886 | for (row = y; row < (y + height); row++) { | |||
887 | for (col = x; col < (x + width); col++) { | |||
888 | pixel = XGetPixel(ximage, col, row)((*((ximage)->f.get_pixel))((ximage), (col), (row))); | |||
889 | XPutPixel(subimage, (col - x), (row - y), pixel)((*((subimage)->f.put_pixel))((subimage), ((col - x)), ((row - y)), (pixel))); | |||
890 | } | |||
891 | } | |||
892 | return subimage; | |||
893 | } | |||
894 | ||||
895 | ||||
896 | /* | |||
897 | * SetImage | |||
898 | * | |||
899 | * Overwrites a section of one image with all of the data from another. | |||
900 | * If the two images are not of the same format (i.e. XYPixmap and ZPixmap), | |||
901 | * the image data is converted to the destination format. The following | |||
902 | * restrictions apply: | |||
903 | * | |||
904 | * 1. The depths of the source and destination images must be equal. | |||
905 | * | |||
906 | * 2. If the height of the source image is too large to fit between | |||
907 | * the specified y starting point and the bottom of the image, | |||
908 | * then scanlines are truncated on the bottom. | |||
909 | * | |||
910 | * 3. If the width of the source image is too large to fit between | |||
911 | * the specified x starting point and the end of the scanline, | |||
912 | * then pixels are truncated on the right. | |||
913 | * | |||
914 | * The images need not have the same bitmap_bit_order, byte_order, | |||
915 | * bitmap_unit, bits_per_pixel, bitmap_pad, or xoffset. | |||
916 | * | |||
917 | */ | |||
918 | ||||
919 | int _XSetImage( | |||
920 | XImage *srcimg, | |||
921 | register XImage *dstimg, | |||
922 | register int x, | |||
923 | register int y) | |||
924 | { | |||
925 | register unsigned long pixel; | |||
926 | register int row, col; | |||
927 | int width, height, startrow, startcol; | |||
928 | if (x < 0) { | |||
929 | startcol = -x; | |||
930 | x = 0; | |||
931 | } else | |||
932 | startcol = 0; | |||
933 | if (y < 0) { | |||
934 | startrow = -y; | |||
935 | y = 0; | |||
936 | } else | |||
937 | startrow = 0; | |||
938 | width = dstimg->width - x; | |||
939 | if (srcimg->width < width) | |||
940 | width = srcimg->width; | |||
941 | height = dstimg->height - y; | |||
942 | if (srcimg->height < height) | |||
943 | height = srcimg->height; | |||
944 | ||||
945 | /* this is slow, will do better later */ | |||
946 | for (row = startrow; row < height; row++) { | |||
947 | for (col = startcol; col < width; col++) { | |||
948 | pixel = XGetPixel(srcimg, col, row)((*((srcimg)->f.get_pixel))((srcimg), (col), (row))); | |||
949 | XPutPixel(dstimg, x + col, y + row, pixel)((*((dstimg)->f.put_pixel))((dstimg), (x + col), (y + row) , (pixel))); | |||
950 | } | |||
951 | } | |||
952 | return 1; | |||
953 | } | |||
954 | ||||
955 | /* | |||
956 | * AddPixel | |||
957 | * | |||
958 | * Adds a constant value to every pixel in a pixmap. | |||
959 | * | |||
960 | */ | |||
961 | ||||
962 | static int | |||
963 | _XAddPixel ( | |||
964 | register XImage *ximage, | |||
965 | register long value) | |||
966 | { | |||
967 | register int x; | |||
968 | register int y; | |||
969 | ||||
970 | if (!value) | |||
971 | return 0; | |||
972 | if ((ximage->bits_per_pixel | ximage->depth) == 1) { | |||
973 | /* The only value that we can add here to an XYBitmap | |||
974 | * is one. Since 1 + value = ~value for one bit wide | |||
975 | * data, we do this quickly by taking the ones complement | |||
976 | * of the entire bitmap data (offset and pad included!). | |||
977 | * Note that we don't need to be concerned with bit or | |||
978 | * byte order at all. | |||
979 | */ | |||
980 | register unsigned char *dp = (unsigned char *) ximage->data; | |||
981 | x = ximage->bytes_per_line * ximage->height; | |||
982 | while (--x >= 0) { | |||
983 | *dp = ~*dp; | |||
984 | dp++; | |||
985 | } | |||
986 | } else if ((ximage->format == ZPixmap2) && | |||
987 | (ximage->bits_per_pixel == 8)) { | |||
988 | register unsigned char *dp = (unsigned char *) ximage->data; | |||
989 | x = ximage->bytes_per_line * ximage->height; | |||
990 | while (--x >= 0) | |||
991 | *dp++ += value; | |||
992 | } else if ((ximage->format == ZPixmap2) && | |||
993 | (ximage->bits_per_pixel == 16) && | |||
994 | (*((const char *)&byteorderpixel) == ximage->byte_order)) { | |||
995 | register unsigned short *dp = (unsigned short *) ximage->data; | |||
996 | x = (ximage->bytes_per_line >> 1) * ximage->height; | |||
997 | while (--x >= 0) | |||
998 | *dp++ += value; | |||
999 | } else if ((ximage->format == ZPixmap2) && | |||
1000 | (ximage->bits_per_pixel == 32) && | |||
1001 | (*((const char *)&byteorderpixel) == ximage->byte_order)) { | |||
1002 | register CARD32 *dp = (CARD32 *) ximage->data; | |||
1003 | x = (ximage->bytes_per_line >> 2) * ximage->height; | |||
1004 | while (--x >= 0) | |||
1005 | *dp++ += value; | |||
1006 | } else { | |||
1007 | for (y = ximage->height; --y >= 0; ) { | |||
1008 | for (x = ximage->width; --x >= 0; ) { | |||
1009 | register unsigned long pixel = XGetPixel(ximage, x, y)((*((ximage)->f.get_pixel))((ximage), (x), (y))); | |||
1010 | pixel = pixel + value; | |||
1011 | XPutPixel(ximage, x, y, pixel)((*((ximage)->f.put_pixel))((ximage), (x), (y), (pixel))); | |||
1012 | } | |||
1013 | } | |||
1014 | } | |||
1015 | return 0; | |||
1016 | } | |||
1017 |