Make ConnectNamedPipe work in overlapped mode.
[wine] / dlls / ddraw / convert.c
1 #include <string.h>
2 #include "ddraw_private.h"
3 #include "debugtools.h"
4
5 DEFAULT_DEBUG_CHANNEL(ddraw);
6
7 /* *************************************
8       16 / 15 bpp to palettized 8 bpp
9    ************************************* */
10 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
11     unsigned char  *c_src = (unsigned char  *) src;
12     unsigned short *c_dst = (unsigned short *) dst;
13     int y;
14
15     if (palette != NULL) {
16         const unsigned int * pal = (unsigned int *) palette->screen_palents;
17
18         for (y = height; y--; ) {
19 #if defined(__i386__) && defined(__GNUC__)
20             /* gcc generates slightly inefficient code for the the copy/lookup,
21              * it generates one excess memory access (to pal) per pixel. Since
22              * we know that pal is not modified by the memory write we can
23              * put it into a register and reduce the number of memory accesses 
24              * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline
25              * stalls. (This is not guaranteed to be the fastest method.)
26              */
27             __asm__ __volatile__(
28             "xor %%eax,%%eax\n"
29             "1:\n"
30             "    lodsb\n"
31             "    movw (%%edx,%%eax,4),%%ax\n"
32             "    stosw\n"
33             "      xor %%eax,%%eax\n"
34             "    loop 1b\n"
35             : "=S" (c_src), "=D" (c_dst)
36             : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
37             : "eax", "cc", "memory"
38             );
39             c_src+=(pitch-width);
40 #else
41             unsigned char * srclineend = c_src+width;
42             while (c_src < srclineend)
43                 *c_dst++ = pal[*c_src++];
44             c_src+=(pitch-width);
45 #endif
46         }
47     } else {
48         FIXME("No palette set...\n");
49         memset(dst, 0, width * height * 2);
50     }
51 }
52 static void palette_convert_16_to_8(
53         LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count
54 ) {
55     int i;
56     unsigned int *pal = (unsigned int *) screen_palette;
57
58     for (i = 0; i < count; i++)
59         pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
60                           ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
61                           ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
62 }
63
64 static void palette_convert_15_to_8(
65         LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count
66 ) {
67     int i;
68     unsigned int *pal = (unsigned int *) screen_palette;
69
70     for (i = 0; i < count; i++)
71         pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
72                           ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
73                           ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
74 }
75
76 /* *************************************
77       24 to palettized 8 bpp
78    ************************************* */
79 static void pixel_convert_24_to_8(
80         void *src, void *dst, DWORD width, DWORD height, LONG pitch,
81         IDirectDrawPaletteImpl* palette
82 ) {
83     unsigned char  *c_src = (unsigned char  *) src;
84     unsigned char *c_dst = (unsigned char *) dst;
85     int y;
86
87     if (palette != NULL) {
88         const unsigned int *pal = (unsigned int *) palette->screen_palents;
89
90         for (y = height; y--; ) {
91             unsigned char * srclineend = c_src+width;
92             while (c_src < srclineend ) {
93                 register long pixel = pal[*c_src++];
94                 *c_dst++ = pixel;
95                 *c_dst++ = pixel>>8;
96                 *c_dst++ = pixel>>16;
97             }
98             c_src+=(pitch-width);
99         }
100     } else {
101         FIXME("No palette set...\n");
102         memset(dst, 0, width * height * 3);
103     }
104 }
105
106 /* *************************************
107       32 bpp to palettized 8 bpp
108    ************************************* */
109 static void pixel_convert_32_to_8(
110         void *src, void *dst, DWORD width, DWORD height, LONG pitch,
111         IDirectDrawPaletteImpl* palette
112 ) {
113     unsigned char  *c_src = (unsigned char  *) src;
114     unsigned int *c_dst = (unsigned int *) dst;
115     int y;
116
117     if (palette != NULL) {
118         const unsigned int *pal = (unsigned int *) palette->screen_palents;
119
120         for (y = height; y--; ) {
121 #if defined(__i386__) && defined(__GNUC__)
122             /* See comment in pixel_convert_16_to_8 */
123             __asm__ __volatile__(
124             "xor %%eax,%%eax\n"
125             "1:\n"
126             "    lodsb\n"
127             "    movl (%%edx,%%eax,4),%%eax\n"
128             "    stosl\n"
129             "      xor %%eax,%%eax\n"
130             "    loop 1b\n"
131             : "=S" (c_src), "=D" (c_dst)
132             : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
133             : "eax", "cc", "memory"
134             );
135             c_src+=(pitch-width);
136 #else
137             unsigned char * srclineend = c_src+width;
138             while (c_src < srclineend )
139                 *c_dst++ = pal[*c_src++];
140             c_src+=(pitch-width);
141 #endif
142         }
143     } else {
144         FIXME("No palette set...\n");
145         memset(dst, 0, width * height * 4);
146     }
147 }
148
149 static void palette_convert_24_to_8(
150         LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count
151 ) {
152     int i;
153     unsigned int *pal = (unsigned int *) screen_palette;
154
155     for (i = 0; i < count; i++)
156         pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
157                           (((unsigned int) palent[i].peGreen) << 8) |
158                            ((unsigned int) palent[i].peBlue));
159 }
160
161 /* *************************************
162       16 bpp to 15 bpp
163    ************************************* */
164 static void pixel_convert_15_to_16(
165         void *src, void *dst, DWORD width, DWORD height, LONG pitch,
166         IDirectDrawPaletteImpl* palette
167 ) {
168     unsigned short *c_src = (unsigned short *) src;
169     unsigned short *c_dst = (unsigned short *) dst;
170     int y;
171
172     for (y = height; y--; ) {
173         unsigned short * srclineend = c_src+width;
174         while (c_src < srclineend ) {
175             unsigned short val = *c_src++;
176             *c_dst++=((val&0xFFC0)>>1)|(val&0x001f);
177         }
178         c_src+=((pitch/2)-width);
179     }
180 }
181
182 /* *************************************
183       32 bpp to 16 bpp
184    ************************************* */
185 static void pixel_convert_32_to_16(
186         void *src, void *dst, DWORD width, DWORD height, LONG pitch,
187         IDirectDrawPaletteImpl* palette
188 ) {
189     unsigned short *c_src = (unsigned short *) src;
190     unsigned int *c_dst = (unsigned int *) dst;
191     int y;
192
193     for (y = height; y--; ) {
194         unsigned short * srclineend = c_src+width;
195         while (c_src < srclineend ) {
196             *c_dst++ = (((*c_src & 0xF800) << 8) |
197                         ((*c_src & 0x07E0) << 5) |
198                         ((*c_src & 0x001F) << 3));
199             c_src++;
200         }
201         c_src+=((pitch/2)-width);
202     }
203 }
204
205 /* *************************************
206       32 bpp to 24 bpp
207    ************************************* */
208 static void pixel_convert_32_to_24(
209         void *src, void *dst, DWORD width, DWORD height, LONG pitch,
210         IDirectDrawPaletteImpl* palette
211 ) {
212     unsigned char *c_src = (unsigned char *) src;
213     unsigned int *c_dst = (unsigned int *) dst;
214     int y;
215
216     for (y = height; y--; ) {
217         unsigned char * srclineend = c_src+width*3;
218         while (c_src < srclineend ) {
219             /* FIXME: wrong for big endian */
220             memcpy(c_dst,c_src,3);
221             c_src+=3;
222             c_dst++;
223         }
224         c_src+=pitch-width*3;
225     }
226 }
227
228 /* *************************************
229       16 bpp to 32 bpp
230    ************************************* */
231 static void pixel_convert_16_to_32(
232         void *src, void *dst, DWORD width, DWORD height, LONG pitch,
233         IDirectDrawPaletteImpl* palette
234 ) {
235     unsigned int *c_src = (unsigned int *) src;
236     unsigned short *c_dst = (unsigned short *) dst;
237     int y;
238
239     for (y = height; y--; ) {
240         unsigned int * srclineend = c_src+width;
241         while (c_src < srclineend ) {
242             *c_dst++ = (((*c_src & 0xF80000) >> 8) |
243                         ((*c_src & 0x00FC00) >> 5) |
244                         ((*c_src & 0x0000F8) >> 3));
245             c_src++;
246         }
247         c_src+=((pitch/4)-width);
248     }
249 }
250
251 Convert ModeEmulations[8] = {
252   { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, {  24, 24, 0xFF0000, 0x00FF00, 0x0000FF }, { pixel_convert_32_to_24, NULL } },
253   { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, {  16, 16, 0xF800, 0x07E0, 0x001F }, { pixel_convert_32_to_16, NULL } },
254   { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, {  8,  8, 0x00, 0x00, 0x00 }, { pixel_convert_32_to_8,  palette_convert_24_to_8 } },
255   { { 24, 24,   0xFF0000,   0x00FF00,   0x0000FF }, {  8,  8, 0x00, 0x00, 0x00 }, { pixel_convert_24_to_8,  palette_convert_24_to_8 } },
256   { { 16, 15,     0x7C00,     0x03E0,     0x001F }, {  16,16, 0xf800, 0x07e0, 0x001f }, { pixel_convert_15_to_16,  NULL } },
257   { { 16, 16,     0xF800,     0x07E0,     0x001F }, {  8,  8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8,  palette_convert_16_to_8 } },
258   { { 16, 15,     0x7C00,     0x03E0,     0x001F }, {  8,  8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8,  palette_convert_15_to_8 } },
259   { { 16, 16,     0xF800,     0x07E0,     0x001F }, {  32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { pixel_convert_16_to_32, NULL } }
260 };