Initial commit
[xorg_rtime.git] / xorg-server-1.4 / afb / afbimage.c
blob81f49730aeb4393f4382e9ad01fc598fd1a44801
2 #ifdef HAVE_DIX_CONFIG_H
3 #include <dix-config.h>
4 #endif
6 #include <string.h>
8 #include <X11/X.h>
9 #include "windowstr.h"
10 #include "pixmapstr.h"
11 #include "scrnintstr.h"
12 #include "gcstruct.h"
13 #include "afb.h"
14 #include "maskbits.h"
15 #include "servermd.h"
16 #include "mfb.h"
18 void
19 afbPutImage(pDraw, pGC, depth, x, y, width, height, leftPad, format, pImage)
20 DrawablePtr pDraw;
21 GCPtr pGC;
22 int depth, x, y, width, height;
23 int leftPad;
24 int format;
25 char *pImage;
27 PixmapPtr pPixmap;
29 if ((width == 0) || (height == 0))
30 return;
32 if (format != ZPixmap || depth == 1 || pDraw->depth == 1) {
33 pPixmap = GetScratchPixmapHeader(pDraw->pScreen, width+leftPad, height,
34 depth, depth,
35 BitmapBytePad(width+leftPad),
36 (pointer)pImage);
37 if (!pPixmap)
38 return;
40 pGC->fExpose = FALSE;
41 if (format == XYBitmap)
42 (void)(*pGC->ops->CopyPlane)((DrawablePtr)pPixmap, pDraw, pGC, leftPad,
43 0, width, height, x, y, 1);
44 else {
45 (void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, pDraw, pGC, leftPad,
46 0, width, height, x, y);
49 pGC->fExpose = TRUE;
50 FreeScratchPixmapHeader(pPixmap);
51 } else {
52 /* Chunky to planar conversion required */
54 PixmapPtr pPixmap;
55 ScreenPtr pScreen = pDraw->pScreen;
56 int widthSrc;
57 int start_srcshift;
58 register int b;
59 register int dstshift;
60 register int shift_step;
61 register PixelType dst;
62 register PixelType srcbits;
63 register PixelType *pdst;
64 register PixelType *psrc;
65 int start_bit;
66 register int nl;
67 register int h;
68 register int d;
69 int sizeDst;
70 PixelType *pdstBase;
71 int widthDst;
72 int depthDst;
74 /* Create a tmp pixmap */
75 pPixmap = (pScreen->CreatePixmap)(pScreen, width, height, depth);
76 if (!pPixmap)
77 return;
79 afbGetPixelWidthSizeDepthAndPointer((DrawablePtr)pPixmap, widthDst,
80 sizeDst, depthDst, pdstBase);
82 widthSrc = PixmapWidthInPadUnits(width, depth);
83 /* XXX: if depth == 8, use fast chunky to planar assembly function.*/
84 if (depth > 4) {
85 start_srcshift = 24;
86 shift_step = 8;
87 } else {
88 start_srcshift = 28;
89 shift_step = 4;
92 for (d = 0; d < depth; d++, pdstBase += sizeDst) { /* @@@ NEXT PLANE @@@ */
93 start_bit = start_srcshift + d;
94 psrc = (PixelType *)pImage;
95 pdst = pdstBase;
96 h = height;
98 while (h--) {
99 dstshift = PPW - 1;
100 dst = 0;
101 nl = widthSrc;
102 while (nl--) {
103 srcbits = *psrc++;
104 for (b = start_bit; b >= 0; b -= shift_step) {
105 dst |= ((srcbits >> b) & 1) << dstshift;
106 if (--dstshift < 0) {
107 dstshift = PPW - 1;
108 *pdst++ = dst;
109 dst = 0;
113 if (dstshift != PPW - 1)
114 *pdst++ = dst;
116 } /* for (d = ...) */
118 pGC->fExpose = FALSE;
119 (void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, pDraw, pGC, leftPad, 0,
120 width, height, x, y);
121 pGC->fExpose = TRUE;
122 (*pScreen->DestroyPixmap)(pPixmap);
126 void
127 afbGetImage(pDrawable, sx, sy, width, height, format, planemask, pdstLine)
128 DrawablePtr pDrawable;
129 int sx, sy, width, height;
130 unsigned int format;
131 unsigned long planemask;
132 char *pdstLine;
134 BoxRec box;
135 DDXPointRec ptSrc;
136 RegionRec rgnDst;
137 ScreenPtr pScreen;
138 PixmapPtr pPixmap;
140 if ((width == 0) || (height == 0))
141 return;
143 pScreen = pDrawable->pScreen;
144 sx += pDrawable->x;
145 sy += pDrawable->y;
147 if (format == XYPixmap || pDrawable->depth == 1) {
148 pPixmap = GetScratchPixmapHeader(pScreen, width, height, 1, 1,
149 BitmapBytePad(width), (pointer)pdstLine);
150 if (!pPixmap)
151 return;
153 ptSrc.x = sx;
154 ptSrc.y = sy;
155 box.x1 = 0;
156 box.y1 = 0;
157 box.x2 = width;
158 box.y2 = height;
159 REGION_INIT(pScreen, &rgnDst, &box, 1);
161 pPixmap->drawable.depth = 1;
162 pPixmap->drawable.bitsPerPixel = 1;
163 /* dix layer only ever calls GetImage with 1 bit set in planemask
164 * when format is XYPixmap.
166 afbDoBitblt(pDrawable, (DrawablePtr)pPixmap, GXcopy, &rgnDst, &ptSrc,
167 planemask);
169 FreeScratchPixmapHeader(pPixmap);
170 REGION_UNINIT(pScreen, &rgnDst);
171 } else {
172 /* Planar to chunky conversion required */
174 PixelType *psrcBits;
175 PixelType *psrcLine;
176 PixelType startmask, endmask;
177 int depthSrc;
178 int widthSrc;
179 int sizeSrc;
180 int sizeDst;
181 int widthDst;
182 register PixelType *psrc;
183 register PixelType *pdst;
184 register PixelType dst;
185 register PixelType srcbits;
186 register int d;
187 register int b;
188 register int dstshift;
189 register int shift_step;
190 register int start_endbit;
191 int start_startbit;
192 register int end_endbit = 0;
193 register int start_dstshift;
194 register int nl;
195 register int h;
196 int nlmiddle;
198 widthDst = PixmapWidthInPadUnits(width, pDrawable->depth);
199 sizeDst = widthDst * height;
201 /* Clear the dest image */
202 bzero(pdstLine, sizeDst << 2);
204 afbGetPixelWidthSizeDepthAndPointer(pDrawable, widthSrc, sizeSrc,
205 depthSrc, psrcBits);
207 psrcBits = afbScanline(psrcBits, sx, sy, widthSrc);
209 start_startbit = PPW - 1 - (sx & PIM);
210 if ((sx & PIM) + width < PPW) {
211 maskpartialbits(sx, width, startmask);
212 nlmiddle = 0;
213 endmask = 0;
214 start_endbit = PPW - ((sx + width) & PIM);
215 } else {
216 maskbits(sx, width, startmask, endmask, nlmiddle);
217 start_endbit = 0;
218 end_endbit = PPW - ((sx + width) & PIM);
220 /* ZPixmap images have either 4 or 8 bits per pixel dependent on
221 * depth.
223 if (depthSrc > 4) {
224 start_dstshift = 24;
225 shift_step = 8;
226 } else {
227 start_dstshift = 28;
228 shift_step = 4;
230 #define SHIFT_BITS(start_bit,end_bit) \
231 for (b = (start_bit); b >= (end_bit); b--) { \
232 dst |= ((srcbits >> b) & 1) << dstshift; \
233 if ((dstshift -= shift_step) < 0) { \
234 dstshift = start_dstshift + d; \
235 *pdst++ = dst; \
236 dst = *pdst; \
240 for (d = 0; d < depthSrc; d++, psrcBits += sizeSrc) { /* @@@ NEXT PLANE @@@ */
241 psrcLine = psrcBits;
242 pdst = (PixelType *)pdstLine;
243 h = height;
245 while (h--) {
246 psrc = psrcLine;
247 psrcLine += widthSrc;
248 dst = *pdst;
249 dstshift = start_dstshift + d;
251 if (startmask) {
252 srcbits = *psrc++ & startmask;
253 SHIFT_BITS(start_startbit, start_endbit);
256 nl = nlmiddle;
257 while (nl--) {
258 srcbits = *psrc++;
259 SHIFT_BITS(PPW - 1, 0);
261 if (endmask) {
262 srcbits = *psrc & endmask;
263 SHIFT_BITS(PPW - 1, end_endbit);
266 if (dstshift != start_dstshift + d)
267 *pdst++ = dst;
268 } /* while (h--) */
269 } /* for (d = ...) */