|
|
1.1 root 1: #include "copyright.h"
2:
3: /* $Header: XImUtil.c,v 11.17 87/09/01 14:53:59 toddb Exp $ */
4: /* Copyright Massachusetts Institute of Technology 1986 */
5:
6: #include "Xlibint.h"
7: #include "Xutil.h"
8: #include <stdio.h>
9:
10: extern char _reverse_byte[0x100]; /* found in XPutImage */
11: static char _lomask[0x09] = { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
12: static char _himask[0x09] = { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00 };
13:
14: /* These two convenience routines return the scanline_pad and bits_per_pixel
15: associated with a specific depth of ZPixmap format image for a
16: display. */
17:
18: _XGetScanlinePad(dpy, depth)
19: Display *dpy;
20: int depth;
21: {
22: register ScreenFormat *fmt = dpy->pixmap_format;
23: register int i;
24:
25: for (i = dpy->nformats + 1; --i; ++fmt)
26: if (fmt->depth == depth)
27: return(fmt->scanline_pad);
28:
29: return(dpy->bitmap_pad);
30: }
31:
32: _XGetBitsPerPixel(dpy, depth)
33: Display *dpy;
34: int depth;
35: {
36: register ScreenFormat *fmt = dpy->pixmap_format;
37: register int i;
38:
39: for (i = dpy->nformats + 1; --i; ++fmt)
40: if (fmt->depth == depth)
41: return(fmt->bits_per_pixel);
42:
43: return(depth);
44: }
45:
46:
47: /*
48: * This module provides rudimentary manipulation routines for image data
49: * structures. The functions provided are:
50: *
51: * XCreateImage Creates a default XImage data structure
52: * _XDestroyImage Deletes an XImage data structure
53: * _XGetPixel Reads a pixel from an image data structure
54: * _XPutPixel Writes a pixel into an image data structure
55: * _XSubImage Clones a new (sub)image from an existing one
56: * _XSetImage Writes an image data pattern into another image
57: * _XAddPixel Adds a constant value to every pixel in an image
58: *
59: * The logic contained in these routines makes several assumptions about
60: * the image data structures, and at least for current implementations
61: * these assumptions are believed to be true. They are:
62: *
63: * For all formats, bits_per_pixel is less than or equal to 32.
64: * For XY formats, bitmap_unit is 8, 16, 24, or 32 bits.
65: * For Z format, bits_per_pixel is 4, 8, 12, 16, 20, 24, 28 or 32 bits.
66: */
67: static _normalizeimagebits (bpt, nb, byteorder, unitsize, bitorder)
68: unsigned char *bpt; /* beginning pointer to image bits */
69: long nb; /* number of bytes to normalize */
70: int byteorder; /* swap bytes if byteorder == MSBFirst */
71: int unitsize; /* size of the bitmap_unit or Zpixel */
72: int bitorder; /* swap bits if bitorder == MSBFirst */
73: {
74: if (byteorder == MSBFirst) {
75: register char c;
76: register unsigned char *bp = bpt;
77: register unsigned char *ep = bpt + nb;
78: register unsigned char *sp;
79: switch (unitsize) {
80:
81: case 4:
82: do { /* swap nibble */
83: *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF);
84: bp++;
85: }
86: while (bp < ep);
87: break;
88:
89: case 16:
90: do { /* swap short */
91: c = *bp;
92: *bp = *(bp + 1);
93: bp++;
94: *bp = c;
95: bp++;
96: }
97: while (bp < ep);
98: break;
99:
100: case 24:
101: do { /* swap three */
102: c = *(bp + 2);
103: *(bp + 2) = *bp;
104: *bp = c;
105: bp += 3;
106: }
107: while (bp < ep);
108: break;
109:
110: case 32:
111: do { /* swap long */
112: sp = bp + 3;
113: c = *sp;
114: *sp = *bp;
115: *bp++ = c;
116: sp = bp + 1;
117: c = *sp;
118: *sp = *bp;
119: *bp++ = c;
120: bp += 2;
121: }
122: while (bp < ep);
123: break;
124: }
125: }
126: if (bitorder == MSBFirst) {
127: do {
128: *bpt = _reverse_byte[*bpt];
129: bpt++;
130: }
131: while (--nb > 0);
132: }
133: }
134:
135: static _putbits (src, dstoffset, numbits, dst)
136: register char *src; /* address of source bit string */
137: long dstoffset; /* bit offset into destination; range is 0-31 */
138: register int numbits;/* number of bits to copy to destination */
139: register char *dst; /* address of destination bit string */
140: {
141: register unsigned char chlo, chhi;
142: int hibits;
143: dst = dst + (dstoffset >> 3);
144: dstoffset = dstoffset % 8;
145: hibits = 8 - dstoffset;
146: chlo = *dst & _lomask[dstoffset];
147: for (;;) {
148: chhi = (*src << dstoffset) & _himask[dstoffset];
149: if (numbits <= hibits) {
150: chhi = chhi & _lomask[dstoffset + numbits];
151: *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi;
152: break;
153: }
154: *dst = chhi | chlo;
155: dst++;
156: numbits = numbits - hibits;
157: chlo = (unsigned char) (*src & _himask[hibits]) >> hibits;
158: src++;
159: if (numbits <= dstoffset) {
160: chlo = chlo & _lomask[numbits];
161: *dst = (*dst & _himask[numbits]) | chlo;
162: break;
163: }
164: numbits = numbits - dstoffset;
165: }
166: }
167:
168:
169: /*
170: * Macros
171: *
172: * The ROUNDUP macro rounds up a quantity to the specified boundary.
173: *
174: * The XYNORMALIZE macro determines whether XY format data requires
175: * normalization and calls a routine to do so if needed. The logic in
176: * this module is designed for LSBFirst byte and bit order, so
177: * normalization is done as required to present the data in this order.
178: *
179: * The ZNORMALIZE macro performs byte and nibble order normalization if
180: * required for Z format data.
181: *
182: * The XYINDEX macro computes the index to the starting byte (char) boundary
183: * for a bitmap_unit containing a pixel with coordinates x and y for image
184: * data in XY format.
185: *
186: * The ZINDEX macro computes the index to the starting byte (char) boundary
187: * for a pixel with coordinates x and y for image data in ZPixmap format.
188: *
189: */
190:
191: #define ROUNDUP(nbytes, pad) (((((nbytes) - 1) + (pad)) / (pad)) * (pad))
192:
193: #define XYNORMALIZE(bp, nbytes, img) \
194: if ((img->byte_order == MSBFirst) || (img->bitmap_bit_order == MSBFirst)) \
195: _normalizeimagebits((unsigned char *)(bp), (nbytes), img->byte_order, img->bitmap_unit, \
196: img->bitmap_bit_order)
197:
198: #define ZNORMALIZE(bp, nbytes, img) \
199: if (img->byte_order == MSBFirst) \
200: _normalizeimagebits((unsigned char *)(bp), (nbytes), MSBFirst, img->bits_per_pixel, \
201: LSBFirst)
202:
203: #define XYINDEX(x, y, img) \
204: ((y) * img->bytes_per_line) + \
205: (((x) + img->xoffset) / img->bitmap_unit) * (img->bitmap_unit >> 3)
206:
207: #define ZINDEX(x, y, img) ((y) * img->bytes_per_line) + \
208: (((x) * img->bits_per_pixel) >> 3)
209:
210:
211: /*
212: * CreateImage
213: *
214: * Allocates the memory necessary for an XImage data structure.
215: * Initializes the structure with "default" values and returns XImage.
216: *
217: */
218:
219: XImage *XCreateImage (dpy, visual, depth, format, offset, data, width, height,
220: xpad, image_bytes_per_line)
221: register Display *dpy;
222: register Visual *visual;
223: unsigned int depth;
224: int format;
225: int offset; /*How many pixels from the start of the data does the
226: picture to be transmitted start?*/
227:
228: char *data;
229: unsigned int width;
230: unsigned int height;
231: int xpad;
232: int image_bytes_per_line;
233: /*How many bytes between a pixel on one line and the pixel with
234: the same X coordinate on the next line? 0 means
235: XCreateImage can calculate it.*/
236: {
237: register XImage *image;
238: int bits_per_pixel = 1;
239: int byte_offset;
240: image = (XImage *) Xcalloc (1, (unsigned) sizeof (XImage));
241: image->width = width;
242: image->height = height;
243: image->format = format;
244: image->byte_order = dpy->byte_order;
245: image->bitmap_unit = dpy->bitmap_unit;
246: image->bitmap_bit_order = dpy->bitmap_bit_order;
247: if (visual != NULL) {
248: image->red_mask = visual->red_mask;
249: image->green_mask = visual->green_mask;
250: image->blue_mask = visual->blue_mask;
251: }
252: else {
253: image->red_mask = image->green_mask = image->blue_mask = 0;
254: }
255: if (format == ZPixmap)
256: {
257: bits_per_pixel = _XGetBitsPerPixel(dpy, depth);
258: }
259:
260: image->xoffset = offset;
261: image->bitmap_pad = xpad;
262: image->depth = depth;
263: image->data = data;
264: /*
265: * compute per line accelerator.
266: */
267: if (image_bytes_per_line == 0)
268: {
269: if (format == ZPixmap)
270: image->bytes_per_line =
271: ROUNDUP((bits_per_pixel * width), image->bitmap_pad) >> 3;
272: else
273: image->bytes_per_line =
274: ROUNDUP((width + offset), image->bitmap_pad) >> 3;
275: }
276: else image->bytes_per_line = image_bytes_per_line;
277:
278: image->bits_per_pixel = bits_per_pixel;
279: image->obdata = NULL;
280: _XInitImageFuncPtrs (image);
281:
282: return image;
283:
284: }
285:
286:
287: /*
288: * _DestroyImage
289: *
290: * Deallocates the memory associated with the ximage data structure.
291: * this version handles the case of the image data being malloc'd
292: * entirely by the library.
293: */
294:
295: int _XDestroyImage (ximage)
296: XImage *ximage;
297:
298: {
299: Xfree((char *)ximage->data);
300: if (ximage->obdata != NULL) Xfree((char *)ximage->obdata);
301: Xfree((char *)ximage);
302: return 1;
303: }
304:
305:
306: /*
307: * GetPixel
308: *
309: * Returns the specified pixel. The X and Y coordinates are relative to
310: * the origin (upper left [0,0]) of the image. The pixel value is returned
311: * in normalized format, i.e. the LSB of the long is the LSB of the pixel.
312: * The algorithm used is:
313: *
314: * copy the source bitmap_unit or Zpixel into temp
315: * normalize temp if needed
316: * extract the pixel bits into return value
317: *
318: */
319:
320: unsigned long _XGetPixel (ximage, x, y)
321: register XImage *ximage;
322: int x;
323: int y;
324:
325: {
326: unsigned long pixel, px;
327: register char *src;
328: register char *dst;
329: register long i, j;
330: int plane;
331: long nbytes;
332: switch (ximage->format) {
333:
334: case XYBitmap:
335: src = &ximage->data[XYINDEX(x, y, ximage)];
336: dst = (char *)&pixel;
337: pixel = 0;
338: nbytes = ximage->bitmap_unit >> 3;
339: for (i=0; i < nbytes; i++) *dst++ = *src++;
340: XYNORMALIZE(&pixel, nbytes, ximage);
341: pixel = pixel >> ((x + ximage->xoffset) % ximage->bitmap_unit);
342: pixel = pixel & 1;
343: break;
344:
345: case XYPixmap:
346: pixel = 0;
347: plane = 0;
348: nbytes = ximage->bitmap_unit >> 3;
349: for (i=0; i < ximage->depth; i++) {
350: src = &ximage->data[XYINDEX(x, y, ximage)+ plane];
351: dst = (char *)&px;
352: px = 0;
353: for (j=0; j < nbytes; j++) *dst++ = *src++;
354: XYNORMALIZE(&px, nbytes, ximage);
355: px = px >> ((x + ximage->xoffset) % ximage->bitmap_unit);
356: px = px & 1;
357: pixel = (pixel << 1) | px;
358: plane = plane + (ximage->bytes_per_line * ximage->height);
359: }
360: break;
361:
362: case ZPixmap:
363: src = &ximage->data[ZINDEX(x, y, ximage)];
364: dst = (char *)&pixel;
365: pixel = 0;
366: nbytes = ROUNDUP(ximage->bits_per_pixel, 8) >> 3;
367: for (i=0; i < nbytes; i++) *dst++ = *src++;
368: ZNORMALIZE(&pixel, nbytes, ximage);
369: pixel = pixel >> ((x * ximage->bits_per_pixel) % 8);
370: break;
371:
372: default: /* should never get here */
373: _XReportBadImage("format", ximage->format, "_XGetPixel");
374: break;
375: }
376: return pixel;
377: }
378:
379:
380: /*
381: * PutPixel
382: *
383: * Overwrites the specified pixel. The X and Y coordinates are relative to
384: * the origin (upper left [0,0]) of the image. The input pixel value must be
385: * in normalized format, i.e. the LSB of the long is the LSB of the pixel.
386: * The algorithm used is:
387: *
388: * copy the destination bitmap_unit or Zpixel to temp
389: * normalize temp if needed
390: * copy the pixel bits into the temp
391: * renormalize temp if needed
392: * copy the temp back into the destination image data
393: *
394: */
395:
396: int _XPutPixel (ximage, x, y, pixel)
397: register XImage *ximage;
398: int x;
399: int y;
400: unsigned long pixel;
401:
402: {
403: unsigned long px;
404: register char *src;
405: register char *dst;
406: register long i;
407: int plane, j;
408: register long nbytes;
409:
410: switch (ximage->format) {
411:
412: case XYBitmap:
413: src = &ximage->data[XYINDEX(x, y, ximage)];
414: dst = (char *)&px;
415: px = 0;
416: nbytes = ximage->bitmap_unit >> 3;
417: for (i=0; i < nbytes; i++) *dst++ = *src++;
418: XYNORMALIZE(&px, nbytes, ximage);
419: i = ((x + ximage->xoffset) % ximage->bitmap_unit);
420: _putbits ((char *)&pixel, i, 1, (char *)&px);
421: XYNORMALIZE(&px, nbytes, ximage);
422: src = (char *) &px;
423: dst = &ximage->data[XYINDEX(x, y, ximage)];
424: for (i=0; i < nbytes; i++) *dst++ = *src++;
425: break;
426:
427: case XYPixmap:
428: plane = (ximage->bytes_per_line * ximage->height) *
429: (ximage->depth - 1); /* do least signif plane 1st */
430: nbytes = ximage->bitmap_unit >> 3;
431: for (j=0; j < ximage->depth; j++) {
432: src = &ximage->data[XYINDEX(x, y, ximage) + plane];
433: dst = (char *) &px;
434: px = 0;
435: for (i=0; i < nbytes; i++) *dst++ = *src++;
436: XYNORMALIZE(&px, nbytes, ximage);
437: i = ((x + ximage->xoffset) % ximage->bitmap_unit);
438: _putbits ((char *)&pixel, i, 1, (char *)&px);
439: XYNORMALIZE(&px, nbytes, ximage);
440: src = (char *)&px;
441: dst = &ximage->data[XYINDEX(x, y, ximage) + plane];
442: for (i=0; i < nbytes; i++) *dst++ = *src++;
443: pixel = pixel >> 1;
444: plane = plane - (ximage->bytes_per_line * ximage->height);
445: }
446: break;
447:
448: case ZPixmap:
449: src = &ximage->data[ZINDEX(x, y, ximage)];
450: dst = (char *)&px;
451: px = 0;
452: nbytes = ROUNDUP(ximage->bits_per_pixel, 8) >> 3;
453: for (i=0; i < nbytes; i++) *dst++ = *src++;
454: ZNORMALIZE(&px, nbytes, ximage);
455: _putbits ((char *)&pixel,
456: (long) (x * ximage->bits_per_pixel) % 8,
457: ximage->bits_per_pixel, (char *)&px);
458: ZNORMALIZE(&px, nbytes, ximage);
459: src = (char *)&px;
460: dst = &ximage->data[ZINDEX(x, y, ximage)];
461: for (i=0; i < nbytes; i++) *dst++ = *src++;
462: break;
463:
464: default: /* should never get here */
465: _XReportBadImage("format", ximage->format, "_XPutPixel");
466: break;
467: }
468: return 1;
469: }
470:
471:
472: /*
473: * SubImage
474: *
475: * Creates a new image that is a subsection of an existing one.
476: * Allocates the memory necessary for the new XImage data structure.
477: * Pointer to new image is returned. The algorithm used is repetitive
478: * calls to get and put pixel.
479: *
480: */
481:
482: XImage *_XSubImage (ximage, x, y, width, height)
483: XImage *ximage;
484: register int x; /* starting x coordinate in existing image */
485: register int y; /* starting y coordinate in existing image */
486: int width; /* width in pixels of new subimage */
487: int height; /* height in pixels of new subimage */
488:
489: {
490: register XImage *subimage;
491: int dsize;
492: register int row, col;
493: register unsigned long pixel;
494: char *data;
495: subimage = (XImage *) Xcalloc (1, sizeof (XImage));
496: subimage->width = width;
497: subimage->height = height;
498: subimage->xoffset = 0;
499: subimage->format = ximage->format;
500: subimage->byte_order = ximage->byte_order;
501: subimage->bitmap_unit = ximage->bitmap_unit;
502: subimage->bitmap_bit_order = ximage->bitmap_bit_order;
503: subimage->bitmap_pad = ximage->bitmap_pad;
504: subimage->bits_per_pixel = ximage->bits_per_pixel;
505: subimage->depth = ximage->depth;
506: /*
507: * compute per line accelarator.
508: */
509: if (subimage->format == ZPixmap)
510: subimage->bytes_per_line =
511: ROUNDUP(((subimage->bits_per_pixel * width) >> 3),
512: subimage->bitmap_pad >> 3);
513: else
514: subimage->bytes_per_line =
515: ROUNDUP((width >> 3), subimage->bitmap_pad >> 3);
516: subimage->obdata = NULL;
517: _XInitImageFuncPtrs (subimage);
518: dsize = subimage->bytes_per_line * height;
519: if (subimage->format == XYPixmap) dsize = dsize * subimage->depth;
520: data = Xcalloc (1, (unsigned) dsize);
521: subimage->data = data;
522:
523: /*
524: * Test for cases where the new subimage is larger than the region
525: * that we are copying from the existing data. In those cases,
526: * copy the area of the existing image, and allow the "uncovered"
527: * area of new subimage to remain with zero filled pixels.
528: */
529: if (height > ximage->height - y ) height = ximage->height - y;
530: if (width > ximage->width - x ) width = ximage->width - x;
531:
532: for (row = y; row < (y + height); row++) {
533: for (col = x; col < (x + width); col++) {
534: pixel = XGetPixel(ximage, col, row);
535: XPutPixel(subimage, (col - x), (row - y), pixel);
536: }
537: }
538: return subimage;
539: }
540:
541:
542: /*
543: * SetImage
544: *
545: * Overwrites a section of one image with all of the data from another.
546: * If the two images are not of the same format (i.e. XYPixmap and ZPixmap),
547: * the image data is converted to the destination format. The following
548: * restrictions apply:
549: *
550: * 1. The depths of the source and destination images must be equal.
551: *
552: * 2. If the height of the source image is too large to fit between
553: * the specified x starting point and the bottom of the image,
554: * then scanlines are truncated on the bottom.
555: *
556: * 3. If the width of the source image is too large to fit between
557: * the specified y starting point and the end of the scanline,
558: * then pixels are truncated on the right.
559: *
560: * The images need not have the same bitmap_bit_order, byte_order,
561: * bitmap_unit, bits_per_pixel, bitmap_pad, or xoffset.
562: *
563: */
564:
565: int _XSetImage (srcimg, dstimg, x, y)
566: XImage *srcimg;
567: register XImage *dstimg;
568: register int x;
569: register int y;
570:
571: {
572: register unsigned long pixel;
573: register int row, col;
574: if (srcimg->depth != dstimg->depth)
575: _XReportBadImage ("depth", dstimg->depth, "_XSetImage");
576:
577: /* this is slow, will do better later */
578: for (row = y; row < dstimg->height; row++) {
579: for (col = x; col < dstimg->width; col++) {
580: pixel = XGetPixel(srcimg, col - x, row - y);
581: XPutPixel(dstimg, col, row, pixel);
582: }
583: }
584: return 1;
585: }
586:
587:
588: /*
589: * AddPixel
590: *
591: * Adds a constant value to every pixel in a pixmap.
592: *
593: */
594:
595: int _XAddPixel (ximage, value)
596: register XImage *ximage;
597: int value;
598:
599: {
600: unsigned long pixel;
601: register unsigned char *dp, *src, *dst, *tmp;
602: register int x;
603: int y;
604: long nbytes, i;
605: if (value != 0) {
606: switch(ximage->format) {
607:
608: case XYBitmap:
609: /* The only value that we can add here to an XYBitmap
610: * is one. Since 1 + value = ~value for one bit wide
611: * data, we do this quickly by taking the ones complement
612: * of the entire bitmap data (offset and pad included!).
613: * Note that we don't need to be concerned with bit or
614: * byte order at all.
615: */
616: dp = (unsigned char *) &ximage->data[0];
617: y = ximage->bytes_per_line * ximage->height;
618: for (x=0; x < y; x++) {
619: *dp = ~(*dp);
620: dp++;
621: }
622: break;
623:
624: case XYPixmap:
625: /* this is slow, may do better later */
626: for (y = 0; y < ximage->height; y++) {
627: for (x = 0; x < ximage->width; x++) {
628: pixel = XGetPixel(ximage, x, y);
629: pixel = pixel + value;
630: XPutPixel(ximage, x, y, pixel);
631: }
632: }
633: break;
634:
635: case ZPixmap:
636: /* If the bits_per_pixel makes the alignment occur on even
637: * byte boundaries, perform the addition by stepping thru
638: * the data one pixel at a time. Otherwise, do it the slow
639: * way by calling get and put pixel.
640: */
641: if ((ximage->bits_per_pixel % 8) == 0) {
642: nbytes = ROUNDUP(ximage->bits_per_pixel, 8) >> 3;
643: for (y = 0; y < ximage->height; y++) {
644: src = (unsigned char *) &ximage->data[ZINDEX(0, y, ximage)];
645: dst = src;
646: for (x = 0; x < ximage->width; x++) {
647: pixel = 0;
648: tmp = (unsigned char *)&pixel;
649: for (i = 0; i < nbytes; i++) *tmp++ = *src++;
650: ZNORMALIZE(&pixel, nbytes, ximage);
651: pixel = pixel + value;
652: ZNORMALIZE(&pixel, nbytes, ximage);
653: tmp = (unsigned char *)&pixel;
654: for (i = 0; i < nbytes; i++) *dst++ = *tmp++;
655: }
656: }
657: break;
658: }
659: else for (y = 0; y < ximage->height; y++) {
660: for (x = 0; x < ximage->width; x++) {
661: pixel = XGetPixel(ximage, x, y);
662: pixel = pixel + value;
663: XPutPixel(ximage, x, y, pixel);
664: }
665: }
666: break;
667:
668: default: /* should never get here */
669: _XReportBadImage("format", ximage->format, "_XAddPixel");
670: break;
671: }
672: }
673: return 1;
674: }
675:
676: /*
677: * This routine initializes the image object function pointers. The
678: * intent is to provide native (i.e. fast) routines for native format images
679: * only using the generic (i.e. slow) routines when fast ones don't exist.
680: * For now, just insert the generic routines.
681: */
682: _XInitImageFuncPtrs (image)
683: register XImage *image;
684: {
685: image->f.create_image = XCreateImage;
686: image->f.destroy_image = _XDestroyImage;
687: image->f.get_pixel = _XGetPixel;
688: image->f.put_pixel = _XPutPixel;
689: image->f.sub_image = _XSubImage;
690: /* image->f.set_image = _XSetImage;*/
691: image->f.add_pixel = _XAddPixel;
692: }
693:
694: void exit();
695: int _XReportBadImage (errtype, error, routine)
696: char errtype[];
697: int error;
698: char routine[];
699: {
700: (void) fprintf(stderr, "Bad image %s: %d found in routine: %s\n",
701: errtype, error, routine );
702: exit(1);
703: }
704:
705:
706: #ifdef notdef
707: _getbits (src, srcoffset, numbits, dst)
708: register char *src; /* address of source bit string */
709: int srcoffset; /* bit offset into source; range is 0-31 */
710: register int numbits; /* number of bits to copy to destination */
711: register char *dst; /* address of destination bit string */
712: {
713: register unsigned char chlo, chhi;
714: int lobits;
715: src = src + (srcoffset >> 3);
716: srcoffset = srcoffset % 8;
717: lobits = 8 - srcoffset;
718: for (;;) {
719: chlo = (unsigned char) (*src & _himask[srcoffset]) >> srcoffset;
720: src++;
721: if (numbits <= lobits) {
722: chlo = chlo & _lomask[numbits];
723: *dst = (*dst & _himask[numbits]) | chlo;
724: break;
725: }
726: numbits = numbits - lobits;
727: chhi = *src & _lomask[srcoffset];
728: if (numbits <= srcoffset) {
729: chhi = (chhi & _lomask[numbits]) << lobits;
730: *dst = (*dst & _himask[lobits + numbits]) | chlo | chhi;
731: break;
732: }
733: chhi = chhi << lobits;
734: *(dst++) = chhi | chlo;
735: numbits = numbits - srcoffset;
736: }
737: }
738: #endif
739:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.