gdi32: Add conversion routines to the primitive functions.
This commit is contained in:
parent
18a96edf69
commit
0a9eae97d2
|
@ -178,25 +178,6 @@ void copy_dib_color_info(dib_info *dst, const dib_info *src)
|
|||
dst->funcs = src->funcs;
|
||||
}
|
||||
|
||||
static BOOL dib_formats_match(const dib_info *d1, const dib_info *d2)
|
||||
{
|
||||
if(d1->bit_count != d2->bit_count) return FALSE;
|
||||
|
||||
switch(d1->bit_count)
|
||||
{
|
||||
case 24: return TRUE;
|
||||
|
||||
case 32:
|
||||
case 16:
|
||||
return (d1->red_mask == d2->red_mask) && (d1->green_mask == d2->green_mask) &&
|
||||
(d1->blue_mask == d2->blue_mask);
|
||||
|
||||
default:
|
||||
ERR("Unexpected depth %d\n", d1->bit_count);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
* convert_dib
|
||||
*
|
||||
|
@ -207,34 +188,22 @@ static BOOL dib_formats_match(const dib_info *d1, const dib_info *d2)
|
|||
*/
|
||||
BOOL convert_dib(dib_info *dst, const dib_info *src)
|
||||
{
|
||||
INT y;
|
||||
BOOL ret;
|
||||
RECT src_rect;
|
||||
|
||||
dst->height = src->height;
|
||||
dst->width = src->width;
|
||||
dst->stride = ((dst->width * dst->bit_count + 31) >> 3) & ~3;
|
||||
dst->bits = NULL;
|
||||
dst->bits = HeapAlloc(GetProcessHeap(), 0, dst->height * dst->stride);
|
||||
|
||||
if(dib_formats_match(src, dst))
|
||||
{
|
||||
dst->bits = HeapAlloc(GetProcessHeap(), 0, dst->height * dst->stride);
|
||||
src_rect.left = src_rect.top = 0;
|
||||
src_rect.right = src->width;
|
||||
src_rect.bottom = src->height;
|
||||
|
||||
if(src->stride > 0)
|
||||
memcpy(dst->bits, src->bits, dst->height * dst->stride);
|
||||
else
|
||||
{
|
||||
BYTE *src_bits = src->bits;
|
||||
BYTE *dst_bits = dst->bits;
|
||||
for(y = 0; y < dst->height; y++)
|
||||
{
|
||||
memcpy(dst_bits, src_bits, dst->stride);
|
||||
dst_bits += dst->stride;
|
||||
src_bits += src->stride;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
FIXME("Format conversion not implemented\n");
|
||||
return FALSE;
|
||||
ret = dst->funcs->convert_to(dst, src, &src_rect);
|
||||
|
||||
if(!ret) free_dib_info(dst, TRUE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -42,6 +42,7 @@ typedef struct primitive_funcs
|
|||
void (* solid_rects)(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor);
|
||||
void (* pattern_rects)(const dib_info *dib, int num, const RECT *rc, const POINT *orign, const dib_info *brush, void *and_bits, void *xor_bits);
|
||||
DWORD (* colorref_to_pixel)(const dib_info *dib, COLORREF color);
|
||||
BOOL (* convert_to)(dib_info *dst, const dib_info *src, const RECT *src_rect);
|
||||
} primitive_funcs;
|
||||
|
||||
extern const primitive_funcs funcs_8888 DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -992,6 +992,8 @@ static BOOL create_pattern_brush_bits(dibdrv_physdev *pdev)
|
|||
assert(pdev->brush_and_bits == NULL);
|
||||
assert(pdev->brush_xor_bits == NULL);
|
||||
|
||||
assert(pdev->brush_dib.stride > 0);
|
||||
|
||||
and_bits = pdev->brush_and_bits = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
xor_bits = pdev->brush_xor_bits = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
|
||||
|
@ -1002,22 +1004,12 @@ static BOOL create_pattern_brush_bits(dibdrv_physdev *pdev)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if(pdev->brush_dib.stride < 0)
|
||||
brush_bits = (DWORD*)((BYTE*)brush_bits + (pdev->brush_dib.height - 1) * pdev->brush_dib.stride);
|
||||
|
||||
while(size)
|
||||
{
|
||||
calc_and_xor_masks(pdev->brush_rop, *brush_bits++, and_bits++, xor_bits++);
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
if(pdev->brush_dib.stride < 0)
|
||||
{
|
||||
/* Update the bits ptrs if the dib is bottom up. The subtraction is because stride is -ve */
|
||||
pdev->brush_and_bits = (BYTE*)pdev->brush_and_bits - (pdev->brush_dib.height - 1) * pdev->brush_dib.stride;
|
||||
pdev->brush_xor_bits = (BYTE*)pdev->brush_xor_bits - (pdev->brush_dib.height - 1) * pdev->brush_dib.stride;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
#include "gdi_private.h"
|
||||
#include "dibdrv.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(dib);
|
||||
|
||||
static inline DWORD *get_pixel_ptr_32(const dib_info *dib, int x, int y)
|
||||
{
|
||||
return (DWORD *)((BYTE*)dib->bits + y * dib->stride + x * 4);
|
||||
|
@ -237,37 +241,330 @@ static DWORD colorref_to_pixel_null(const dib_info *dib, COLORREF color)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static BOOL convert_to_8888(dib_info *dst, const dib_info *src, const RECT *src_rect)
|
||||
{
|
||||
DWORD *dst_start = dst->bits, *dst_pixel, src_val;
|
||||
int x, y;
|
||||
|
||||
switch(src->bit_count)
|
||||
{
|
||||
case 32:
|
||||
{
|
||||
DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top);
|
||||
if(src->funcs == &funcs_8888)
|
||||
{
|
||||
if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
|
||||
memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
|
||||
else
|
||||
{
|
||||
for(y = src_rect->top; y < src_rect->bottom; y++)
|
||||
{
|
||||
memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 4);
|
||||
dst_start += dst->stride / 4;
|
||||
src_start += src->stride / 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Unsupported conversion: 32 -> 8888\n");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 16:
|
||||
{
|
||||
WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
|
||||
if(src->funcs == &funcs_555)
|
||||
{
|
||||
for(y = src_rect->top; y < src_rect->bottom; y++)
|
||||
{
|
||||
dst_pixel = dst_start;
|
||||
src_pixel = src_start;
|
||||
for(x = src_rect->left; x < src_rect->right; x++)
|
||||
{
|
||||
src_val = *src_pixel++;
|
||||
*dst_pixel++ = ((src_val << 9) & 0xf80000) | ((src_val << 4) & 0x070000) |
|
||||
((src_val << 6) & 0x00f800) | ((src_val << 1) & 0x000700) |
|
||||
((src_val << 3) & 0x0000f8) | ((src_val >> 2) & 0x000007);
|
||||
}
|
||||
dst_start += dst->stride / 4;
|
||||
src_start += src->stride / 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Unsupported conversion: 16 -> 8888\n");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
FIXME("Unsupported conversion: %d -> 8888\n", src->bit_count);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL convert_to_32(dib_info *dst, const dib_info *src, const RECT *src_rect)
|
||||
{
|
||||
DWORD *dst_start = dst->bits, *dst_pixel, src_val;
|
||||
int x, y;
|
||||
|
||||
switch(src->bit_count)
|
||||
{
|
||||
case 32:
|
||||
{
|
||||
DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
|
||||
|
||||
if(src->funcs == &funcs_8888)
|
||||
{
|
||||
for(y = src_rect->top; y < src_rect->bottom; y++)
|
||||
{
|
||||
dst_pixel = dst_start;
|
||||
src_pixel = src_start;
|
||||
for(x = src_rect->left; x < src_rect->right; x++)
|
||||
{
|
||||
src_val = *src_pixel++;
|
||||
*dst_pixel++ = put_field((src_val >> 16) & 0xff, dst->red_shift, dst->red_len) |
|
||||
put_field((src_val >> 8) & 0xff, dst->green_shift, dst->green_len) |
|
||||
put_field( src_val & 0xff, dst->blue_shift, dst->blue_len);
|
||||
}
|
||||
dst_start += dst->stride / 4;
|
||||
src_start += src->stride / 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Unsupported conversion: 32 -> 32\n");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 16:
|
||||
{
|
||||
WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
|
||||
if(src->funcs == &funcs_555)
|
||||
{
|
||||
for(y = src_rect->top; y < src_rect->bottom; y++)
|
||||
{
|
||||
dst_pixel = dst_start;
|
||||
src_pixel = src_start;
|
||||
for(x = src_rect->left; x < src_rect->right; x++)
|
||||
{
|
||||
src_val = *src_pixel++;
|
||||
*dst_pixel++ = put_field(((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07), dst->red_shift, dst->red_len) |
|
||||
put_field(((src_val >> 2) & 0xf8) | ((src_val >> 7) & 0x07), dst->green_shift, dst->green_len) |
|
||||
put_field(((src_val << 3) & 0xf8) | ((src_val >> 2) & 0x07), dst->blue_shift, dst->blue_len);
|
||||
}
|
||||
dst_start += dst->stride / 4;
|
||||
src_start += src->stride / 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Unsupported conversion: 16 -> 8888\n");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
FIXME("Unsupported conversion: %d -> 32\n", src->bit_count);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL convert_to_555(dib_info *dst, const dib_info *src, const RECT *src_rect)
|
||||
{
|
||||
WORD *dst_start = dst->bits, *dst_pixel;
|
||||
INT x, y;
|
||||
DWORD src_val;
|
||||
|
||||
switch(src->bit_count)
|
||||
{
|
||||
case 32:
|
||||
{
|
||||
DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
|
||||
|
||||
if(src->funcs == &funcs_8888)
|
||||
{
|
||||
for(y = src_rect->top; y < src_rect->bottom; y++)
|
||||
{
|
||||
dst_pixel = dst_start;
|
||||
src_pixel = src_start;
|
||||
for(x = src_rect->left; x < src_rect->right; x++)
|
||||
{
|
||||
src_val = *src_pixel++;
|
||||
*dst_pixel++ = ((src_val >> 9) & 0x7c00) |
|
||||
((src_val >> 6) & 0x03e0) |
|
||||
((src_val >> 3) & 0x001e);
|
||||
}
|
||||
dst_start += dst->stride / 2;
|
||||
src_start += src->stride / 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Unsupported conversion: 32 -> 555\n");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 16:
|
||||
{
|
||||
WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top);
|
||||
if(src->funcs == &funcs_555)
|
||||
{
|
||||
if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
|
||||
memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
|
||||
else
|
||||
{
|
||||
for(y = src_rect->top; y < src_rect->bottom; y++)
|
||||
{
|
||||
memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 2);
|
||||
dst_start += dst->stride / 2;
|
||||
src_start += src->stride / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Unsupported conversion: 16 -> 555\n");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
FIXME("Unsupported conversion: %d -> 555\n", src->bit_count);
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL convert_to_16(dib_info *dst, const dib_info *src, const RECT *src_rect)
|
||||
{
|
||||
WORD *dst_start = dst->bits, *dst_pixel;
|
||||
INT x, y;
|
||||
DWORD src_val;
|
||||
|
||||
switch(src->bit_count)
|
||||
{
|
||||
case 32:
|
||||
{
|
||||
DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
|
||||
|
||||
if(src->funcs == &funcs_8888)
|
||||
{
|
||||
for(y = src_rect->top; y < src_rect->bottom; y++)
|
||||
{
|
||||
dst_pixel = dst_start;
|
||||
src_pixel = src_start;
|
||||
for(x = src_rect->left; x < src_rect->right; x++)
|
||||
{
|
||||
src_val = *src_pixel++;
|
||||
*dst_pixel++ = put_field((src_val >> 16) & 0xff, dst->red_shift, dst->red_len) |
|
||||
put_field((src_val >> 8) & 0xff, dst->green_shift, dst->green_len) |
|
||||
put_field( src_val & 0xff, dst->blue_shift, dst->blue_len);
|
||||
}
|
||||
dst_start += dst->stride / 2;
|
||||
src_start += src->stride / 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Unsupported conversion: 32 -> 16\n");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 16:
|
||||
{
|
||||
WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
|
||||
if(src->funcs == &funcs_555)
|
||||
{
|
||||
for(y = src_rect->top; y < src_rect->bottom; y++)
|
||||
{
|
||||
dst_pixel = dst_start;
|
||||
src_pixel = src_start;
|
||||
for(x = src_rect->left; x < src_rect->right; x++)
|
||||
{
|
||||
src_val = *src_pixel++;
|
||||
*dst_pixel++ = put_field(((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07), dst->red_shift, dst->red_len) |
|
||||
put_field(((src_val >> 2) & 0xf8) | ((src_val >> 7) & 0x07), dst->green_shift, dst->green_len) |
|
||||
put_field(((src_val << 3) & 0xf8) | ((src_val >> 2) & 0x07), dst->blue_shift, dst->blue_len);
|
||||
}
|
||||
dst_start += dst->stride / 2;
|
||||
src_start += src->stride / 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Unsupported conversion: 16 -> 16\n");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
FIXME("Unsupported conversion: %d -> 16\n", src->bit_count);
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL convert_to_null(dib_info *dst, const dib_info *src, const RECT *src_rect)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const primitive_funcs funcs_8888 =
|
||||
{
|
||||
solid_rects_32,
|
||||
pattern_rects_32,
|
||||
colorref_to_pixel_888
|
||||
colorref_to_pixel_888,
|
||||
convert_to_8888
|
||||
};
|
||||
|
||||
const primitive_funcs funcs_32 =
|
||||
{
|
||||
solid_rects_32,
|
||||
pattern_rects_32,
|
||||
colorref_to_pixel_masks
|
||||
colorref_to_pixel_masks,
|
||||
convert_to_32
|
||||
};
|
||||
|
||||
const primitive_funcs funcs_555 =
|
||||
{
|
||||
solid_rects_16,
|
||||
pattern_rects_16,
|
||||
colorref_to_pixel_555
|
||||
colorref_to_pixel_555,
|
||||
convert_to_555
|
||||
};
|
||||
|
||||
const primitive_funcs funcs_16 =
|
||||
{
|
||||
solid_rects_16,
|
||||
pattern_rects_16,
|
||||
colorref_to_pixel_masks
|
||||
colorref_to_pixel_masks,
|
||||
convert_to_16
|
||||
};
|
||||
|
||||
const primitive_funcs funcs_null =
|
||||
{
|
||||
solid_rects_null,
|
||||
pattern_rects_null,
|
||||
colorref_to_pixel_null
|
||||
colorref_to_pixel_null,
|
||||
convert_to_null
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue