Repaired shared PE data sections.
[wine/multimedia.git] / dlls / ddraw / convert.c
blob9091c194a008820f04bc2c32aee0f9f688be27fe
1 #include <string.h>
2 #include "ddraw_private.h"
3 #include "debugtools.h"
5 DEFAULT_DEBUG_CHANNEL(ddraw);
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;
15 if (palette != NULL) {
16 const unsigned int * pal = (unsigned int *) palette->screen_palents;
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.)
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"
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
47 } else {
48 FIXME("No palette set...\n");
49 memset(dst, 0, width * height * 2);
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;
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));
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;
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));
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;
87 if (palette != NULL) {
88 const unsigned int *pal = (unsigned int *) palette->screen_palents;
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;
98 c_src+=(pitch-width);
100 } else {
101 FIXME("No palette set...\n");
102 memset(dst, 0, width * height * 3);
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
113 unsigned char *c_src = (unsigned char *) src;
114 unsigned int *c_dst = (unsigned int *) dst;
115 int y;
117 if (palette != NULL) {
118 const unsigned int *pal = (unsigned int *) palette->screen_palents;
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"
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
143 } else {
144 FIXME("No palette set...\n");
145 memset(dst, 0, width * height * 4);
149 static void palette_convert_24_to_8(
150 LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count
152 int i;
153 unsigned int *pal = (unsigned int *) screen_palette;
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));
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
168 unsigned short *c_src = (unsigned short *) src;
169 unsigned short *c_dst = (unsigned short *) dst;
170 int y;
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);
178 c_src+=((pitch/2)-width);
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
189 unsigned short *c_src = (unsigned short *) src;
190 unsigned int *c_dst = (unsigned int *) dst;
191 int y;
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++;
201 c_src+=((pitch/2)-width);
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
212 unsigned char *c_src = (unsigned char *) src;
213 unsigned int *c_dst = (unsigned int *) dst;
214 int y;
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++;
224 c_src+=pitch-width*3;
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
235 unsigned int *c_src = (unsigned int *) src;
236 unsigned short *c_dst = (unsigned short *) dst;
237 int y;
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++;
247 c_src+=((pitch/4)-width);
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 } }