gdk: add high-depth RGB image drawing
Add RGB48 and RGBX64 drawing APIs with direct conversion for common 15-, 16-, 24-, 30- and 32-bit TrueColor visuals. Preserve the existing GdkRGB path as a fallback for unsupported visuals and maximum dithering.
This commit is contained in:
parent
8984300bba
commit
73183e1a30
6 changed files with 799 additions and 0 deletions
|
|
@ -335,6 +335,10 @@ gdk_draw_indexed_image
|
|||
gdk_draw_gray_image
|
||||
gdk_draw_rgb_32_image
|
||||
gdk_draw_rgb_32_image_dithalign
|
||||
gdk_draw_rgb_48_image
|
||||
gdk_draw_rgb_48_image_dithalign
|
||||
gdk_draw_rgbx_64_image
|
||||
gdk_draw_rgbx_64_image_dithalign
|
||||
GdkRgbDither
|
||||
|
||||
<SUBSECTION>
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ gdk_c_sources = \
|
|||
gdkrectangle.c \
|
||||
gdkregion-generic.c \
|
||||
gdkrgb.c \
|
||||
gdkrgb16.c \
|
||||
gdkscreen.c \
|
||||
gdkselection.c \
|
||||
gdkvisual.c \
|
||||
|
|
|
|||
|
|
@ -1118,6 +1118,15 @@ gdk_draw_rgb_image_dithalign
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_RGB_H__)
|
||||
#if IN_FILE(__GDK_RGB16_C__)
|
||||
gdk_draw_rgb_48_image
|
||||
gdk_draw_rgb_48_image_dithalign
|
||||
gdk_draw_rgbx_64_image
|
||||
gdk_draw_rgbx_64_image_dithalign
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_SCREEN_H__)
|
||||
#if IN_FILE(__GDK_SCREEN_C__)
|
||||
gdk_screen_get_type G_GNUC_CONST
|
||||
|
|
|
|||
42
gdk/gdkrgb.h
42
gdk/gdkrgb.h
|
|
@ -147,6 +147,48 @@ gboolean gdk_rgb_colormap_ditherable (GdkColormap *cmap);
|
|||
#endif
|
||||
#endif /* GDK_DISABLE_DEPRECATED */
|
||||
|
||||
void gdk_draw_rgb_48_image (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dith,
|
||||
const guint16 *rgb_buf,
|
||||
gint rowstride);
|
||||
void gdk_draw_rgb_48_image_dithalign (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dith,
|
||||
const guint16 *rgb_buf,
|
||||
gint rowstride,
|
||||
gint xdith,
|
||||
gint ydith);
|
||||
void gdk_draw_rgbx_64_image (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dith,
|
||||
const guint16 *rgbx_buf,
|
||||
gint rowstride);
|
||||
void gdk_draw_rgbx_64_image_dithalign
|
||||
(GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dith,
|
||||
const guint16 *rgbx_buf,
|
||||
gint rowstride,
|
||||
gint xdith,
|
||||
gint ydith);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
|
|
|
|||
742
gdk/gdkrgb16.c
Normal file
742
gdk/gdkrgb16.c
Normal file
|
|
@ -0,0 +1,742 @@
|
|||
/* GTK - The GIMP Toolkit
|
||||
* High-precision GdkRGB image conversion
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkrgb.h"
|
||||
#include "gdkscreen.h"
|
||||
#include "gdkalias.h"
|
||||
|
||||
typedef void (*GdkRgb16ConvFunc) (GdkImage *image,
|
||||
gint x0,
|
||||
gint y0,
|
||||
gint width,
|
||||
gint height,
|
||||
const guint16 *buf,
|
||||
gint rowstride);
|
||||
|
||||
#define GDK_RGB16_STORE_RGB(p, r, g, b, a) G_STMT_START { \
|
||||
(p)[0] = (r) >> 8; \
|
||||
(p)[1] = (g) >> 8; \
|
||||
(p)[2] = (b) >> 8; \
|
||||
(p) += 3; \
|
||||
} G_STMT_END
|
||||
|
||||
#define GDK_RGB16_STORE_BGR(p, r, g, b, a) G_STMT_START { \
|
||||
(p)[0] = (b) >> 8; \
|
||||
(p)[1] = (g) >> 8; \
|
||||
(p)[2] = (r) >> 8; \
|
||||
(p) += 3; \
|
||||
} G_STMT_END
|
||||
|
||||
#define GDK_RGB16_STORE_BGRA(p, r, g, b, a) G_STMT_START { \
|
||||
(p)[0] = (b) >> 8; \
|
||||
(p)[1] = (g) >> 8; \
|
||||
(p)[2] = (r) >> 8; \
|
||||
(p)[3] = 0xff; \
|
||||
(p) += 4; \
|
||||
} G_STMT_END
|
||||
|
||||
#define GDK_RGB16_STORE_ARGB(p, r, g, b, a) G_STMT_START { \
|
||||
(p)[0] = 0xff; \
|
||||
(p)[1] = (r) >> 8; \
|
||||
(p)[2] = (g) >> 8; \
|
||||
(p)[3] = (b) >> 8; \
|
||||
(p) += 4; \
|
||||
} G_STMT_END
|
||||
|
||||
#define GDK_RGB16_STORE_RGB0_NATIVE(p, r, g, b, a) G_STMT_START { \
|
||||
guint32 pixel__ = (((b) >> 8) << 16) | \
|
||||
(((g) >> 8) << 8) | \
|
||||
((r) >> 8); \
|
||||
memcpy ((p), &pixel__, sizeof (pixel__)); \
|
||||
(p) += 4; \
|
||||
} G_STMT_END
|
||||
|
||||
#define GDK_RGB16_STORE_565(p, r, g, b, a) G_STMT_START { \
|
||||
guint16 pixel__ = ((r) & 0xf800) | \
|
||||
(((g) & 0xfc00) >> 5) | \
|
||||
((b) >> 11); \
|
||||
memcpy ((p), &pixel__, sizeof (pixel__)); \
|
||||
(p) += 2; \
|
||||
} G_STMT_END
|
||||
|
||||
#define GDK_RGB16_STORE_565_BR(p, r, g, b, a) G_STMT_START { \
|
||||
guint16 pixel__ = ((r) & 0xf800) | \
|
||||
(((g) & 0xfc00) >> 5) | \
|
||||
((b) >> 11); \
|
||||
pixel__ = (pixel__ >> 8) | (pixel__ << 8); \
|
||||
memcpy ((p), &pixel__, sizeof (pixel__)); \
|
||||
(p) += 2; \
|
||||
} G_STMT_END
|
||||
|
||||
#define GDK_RGB16_STORE_555(p, r, g, b, a) G_STMT_START { \
|
||||
guint16 pixel__ = (((r) & 0xf800) >> 1) | \
|
||||
(((g) & 0xf800) >> 6) | \
|
||||
((b) >> 11); \
|
||||
memcpy ((p), &pixel__, sizeof (pixel__)); \
|
||||
(p) += 2; \
|
||||
} G_STMT_END
|
||||
|
||||
#define GDK_RGB16_STORE_555_BR(p, r, g, b, a) G_STMT_START { \
|
||||
guint16 pixel__ = (((r) & 0xf800) >> 1) | \
|
||||
(((g) & 0xf800) >> 6) | \
|
||||
((b) >> 11); \
|
||||
pixel__ = (pixel__ >> 8) | (pixel__ << 8); \
|
||||
memcpy ((p), &pixel__, sizeof (pixel__)); \
|
||||
(p) += 2; \
|
||||
} G_STMT_END
|
||||
|
||||
#define GDK_RGB16_STORE_101010_R_LOW_LE(p, r, g, b, a) \
|
||||
G_STMT_START { \
|
||||
guint32 pixel__ = (a) | \
|
||||
(((b) >> 6) << 20) | \
|
||||
(((g) >> 6) << 10) | \
|
||||
((r) >> 6); \
|
||||
pixel__ = GUINT32_TO_LE (pixel__); \
|
||||
memcpy ((p), &pixel__, sizeof (pixel__)); \
|
||||
(p) += 4; \
|
||||
} G_STMT_END
|
||||
|
||||
#define GDK_RGB16_STORE_101010_B_LOW_LE(p, r, g, b, a) \
|
||||
G_STMT_START { \
|
||||
guint32 pixel__ = (a) | \
|
||||
(((r) >> 6) << 20) | \
|
||||
(((g) >> 6) << 10) | \
|
||||
((b) >> 6); \
|
||||
pixel__ = GUINT32_TO_LE (pixel__); \
|
||||
memcpy ((p), &pixel__, sizeof (pixel__)); \
|
||||
(p) += 4; \
|
||||
} G_STMT_END
|
||||
|
||||
#define GDK_RGB16_STORE_101010_R_LOW_BE(p, r, g, b, a) \
|
||||
G_STMT_START { \
|
||||
guint32 pixel__ = (a) | \
|
||||
(((b) >> 6) << 20) | \
|
||||
(((g) >> 6) << 10) | \
|
||||
((r) >> 6); \
|
||||
pixel__ = GUINT32_TO_BE (pixel__); \
|
||||
memcpy ((p), &pixel__, sizeof (pixel__)); \
|
||||
(p) += 4; \
|
||||
} G_STMT_END
|
||||
|
||||
#define GDK_RGB16_STORE_101010_B_LOW_BE(p, r, g, b, a) \
|
||||
G_STMT_START { \
|
||||
guint32 pixel__ = (a) | \
|
||||
(((r) >> 6) << 20) | \
|
||||
(((g) >> 6) << 10) | \
|
||||
((b) >> 6); \
|
||||
pixel__ = GUINT32_TO_BE (pixel__); \
|
||||
memcpy ((p), &pixel__, sizeof (pixel__)); \
|
||||
(p) += 4; \
|
||||
} G_STMT_END
|
||||
|
||||
#define DEFINE_GDK_RGB16_CONVERTER(name, words, pixel_bytes, store) \
|
||||
static void \
|
||||
name (GdkImage *image, \
|
||||
gint x0, \
|
||||
gint y0, \
|
||||
gint width, \
|
||||
gint height, \
|
||||
const guint16 *buf, \
|
||||
gint rowstride) \
|
||||
{ \
|
||||
const guchar *row; \
|
||||
const guint16 *src; \
|
||||
guchar *dst_row; \
|
||||
guchar *dst; \
|
||||
guint32 r, g, b; \
|
||||
guint32 alpha_mask; \
|
||||
gint x, y; \
|
||||
\
|
||||
row = (const guchar *) buf; \
|
||||
dst_row = ((guchar *) image->mem) + \
|
||||
y0 * image->bpl + x0 * (pixel_bytes); \
|
||||
alpha_mask = image->depth == 32 ? 0xc0000000U : 0; \
|
||||
(void) alpha_mask; \
|
||||
\
|
||||
for (y = 0; y < height; y++) \
|
||||
{ \
|
||||
src = (const guint16 *) row; \
|
||||
dst = dst_row; \
|
||||
\
|
||||
for (x = 0; x < width; x++) \
|
||||
{ \
|
||||
r = src[0]; \
|
||||
g = src[1]; \
|
||||
b = src[2]; \
|
||||
src += (words); \
|
||||
store (dst, r, g, b, alpha_mask); \
|
||||
} \
|
||||
\
|
||||
row += rowstride; \
|
||||
dst_row += image->bpl; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DEFINE_GDK_RGB16_PAIR(suffix, pixel_bytes, store) \
|
||||
DEFINE_GDK_RGB16_CONVERTER (gdk_rgb48_convert_ ## suffix, \
|
||||
3, pixel_bytes, store) \
|
||||
DEFINE_GDK_RGB16_CONVERTER (gdk_rgbx64_convert_ ## suffix, \
|
||||
4, pixel_bytes, store)
|
||||
|
||||
DEFINE_GDK_RGB16_PAIR (rgb, 3, GDK_RGB16_STORE_RGB)
|
||||
DEFINE_GDK_RGB16_PAIR (bgr, 3, GDK_RGB16_STORE_BGR)
|
||||
DEFINE_GDK_RGB16_PAIR (bgra, 4, GDK_RGB16_STORE_BGRA)
|
||||
DEFINE_GDK_RGB16_PAIR (argb, 4, GDK_RGB16_STORE_ARGB)
|
||||
DEFINE_GDK_RGB16_PAIR (rgb0_native, 4, GDK_RGB16_STORE_RGB0_NATIVE)
|
||||
DEFINE_GDK_RGB16_PAIR (565, 2, GDK_RGB16_STORE_565)
|
||||
DEFINE_GDK_RGB16_PAIR (565_br, 2, GDK_RGB16_STORE_565_BR)
|
||||
DEFINE_GDK_RGB16_PAIR (555, 2, GDK_RGB16_STORE_555)
|
||||
DEFINE_GDK_RGB16_PAIR (555_br, 2, GDK_RGB16_STORE_555_BR)
|
||||
DEFINE_GDK_RGB16_PAIR (101010_r_low_le, 4,
|
||||
GDK_RGB16_STORE_101010_R_LOW_LE)
|
||||
DEFINE_GDK_RGB16_PAIR (101010_b_low_le, 4,
|
||||
GDK_RGB16_STORE_101010_B_LOW_LE)
|
||||
DEFINE_GDK_RGB16_PAIR (101010_r_low_be, 4,
|
||||
GDK_RGB16_STORE_101010_R_LOW_BE)
|
||||
DEFINE_GDK_RGB16_PAIR (101010_b_low_be, 4,
|
||||
GDK_RGB16_STORE_101010_B_LOW_BE)
|
||||
|
||||
#undef DEFINE_GDK_RGB16_PAIR
|
||||
#undef DEFINE_GDK_RGB16_CONVERTER
|
||||
|
||||
#undef GDK_RGB16_STORE_RGB
|
||||
#undef GDK_RGB16_STORE_BGR
|
||||
#undef GDK_RGB16_STORE_BGRA
|
||||
#undef GDK_RGB16_STORE_ARGB
|
||||
#undef GDK_RGB16_STORE_RGB0_NATIVE
|
||||
#undef GDK_RGB16_STORE_565
|
||||
#undef GDK_RGB16_STORE_565_BR
|
||||
#undef GDK_RGB16_STORE_555
|
||||
#undef GDK_RGB16_STORE_555_BR
|
||||
#undef GDK_RGB16_STORE_101010_R_LOW_LE
|
||||
#undef GDK_RGB16_STORE_101010_B_LOW_LE
|
||||
#undef GDK_RGB16_STORE_101010_R_LOW_BE
|
||||
#undef GDK_RGB16_STORE_101010_B_LOW_BE
|
||||
|
||||
static GdkRgb16ConvFunc
|
||||
gdk_rgb16_select_converter (GdkDrawable *drawable,
|
||||
gboolean is_rgbx,
|
||||
GdkRgbDither dith)
|
||||
{
|
||||
GdkVisual *visual;
|
||||
GdkByteOrder byte_order;
|
||||
GdkScreen *screen;
|
||||
guint32 red_mask, green_mask, blue_mask;
|
||||
gint depth;
|
||||
gint bits_per_pixel;
|
||||
gboolean byte_reversed;
|
||||
gboolean mask_rgb;
|
||||
gboolean mask_bgr;
|
||||
|
||||
#define SELECT_PAIR(suffix) \
|
||||
return is_rgbx ? gdk_rgbx64_convert_ ## suffix \
|
||||
: gdk_rgb48_convert_ ## suffix
|
||||
|
||||
/*
|
||||
* Preserve the existing GdkRGB dither path for maximum dithering
|
||||
* and for unknown future values.
|
||||
*/
|
||||
if (dith != GDK_RGB_DITHER_NONE &&
|
||||
dith != GDK_RGB_DITHER_NORMAL)
|
||||
return NULL;
|
||||
|
||||
visual = gdk_drawable_get_visual (drawable);
|
||||
if (visual == NULL)
|
||||
return NULL;
|
||||
|
||||
if (gdk_visual_get_visual_type (visual) != GDK_VISUAL_TRUE_COLOR)
|
||||
return NULL;
|
||||
|
||||
screen = gdk_visual_get_screen (visual);
|
||||
depth = gdk_visual_get_depth (visual);
|
||||
byte_order = gdk_visual_get_byte_order (visual);
|
||||
|
||||
gdk_visual_get_red_pixel_details (visual, &red_mask, NULL, NULL);
|
||||
gdk_visual_get_green_pixel_details (visual, &green_mask, NULL, NULL);
|
||||
gdk_visual_get_blue_pixel_details (visual, &blue_mask, NULL, NULL);
|
||||
|
||||
bits_per_pixel = _gdk_windowing_get_bits_for_depth
|
||||
(gdk_screen_get_display (screen), depth);
|
||||
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
byte_reversed = byte_order == GDK_LSB_FIRST;
|
||||
#else
|
||||
byte_reversed = byte_order == GDK_MSB_FIRST;
|
||||
#endif
|
||||
|
||||
mask_rgb = red_mask == 0xff0000 &&
|
||||
green_mask == 0x00ff00 &&
|
||||
blue_mask == 0x0000ff;
|
||||
|
||||
mask_bgr = red_mask == 0x0000ff &&
|
||||
green_mask == 0x00ff00 &&
|
||||
blue_mask == 0xff0000;
|
||||
|
||||
if (bits_per_pixel == 16 &&
|
||||
depth == 16 &&
|
||||
red_mask == 0xf800 &&
|
||||
green_mask == 0x07e0 &&
|
||||
blue_mask == 0x001f)
|
||||
{
|
||||
if (byte_reversed)
|
||||
SELECT_PAIR (565_br);
|
||||
|
||||
SELECT_PAIR (565);
|
||||
}
|
||||
|
||||
if (bits_per_pixel == 16 &&
|
||||
depth == 15 &&
|
||||
red_mask == 0x7c00 &&
|
||||
green_mask == 0x03e0 &&
|
||||
blue_mask == 0x001f)
|
||||
{
|
||||
if (byte_reversed)
|
||||
SELECT_PAIR (555_br);
|
||||
|
||||
SELECT_PAIR (555);
|
||||
}
|
||||
|
||||
if (bits_per_pixel == 24 &&
|
||||
depth == 24 &&
|
||||
((mask_rgb && byte_order == GDK_LSB_FIRST) ||
|
||||
(mask_bgr && byte_order == GDK_MSB_FIRST)))
|
||||
SELECT_PAIR (bgr);
|
||||
|
||||
if (bits_per_pixel == 24 &&
|
||||
depth == 24 &&
|
||||
((mask_rgb && byte_order == GDK_MSB_FIRST) ||
|
||||
(mask_bgr && byte_order == GDK_LSB_FIRST)))
|
||||
SELECT_PAIR (rgb);
|
||||
|
||||
if (bits_per_pixel == 32 &&
|
||||
(depth == 24 || depth == 32) &&
|
||||
mask_rgb &&
|
||||
byte_order == GDK_MSB_FIRST)
|
||||
SELECT_PAIR (argb);
|
||||
|
||||
if (bits_per_pixel == 32 &&
|
||||
(depth == 24 || depth == 32) &&
|
||||
mask_rgb &&
|
||||
byte_order == GDK_LSB_FIRST)
|
||||
SELECT_PAIR (bgra);
|
||||
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
if (bits_per_pixel == 32 &&
|
||||
depth == 24 &&
|
||||
mask_bgr &&
|
||||
byte_order == GDK_MSB_FIRST)
|
||||
SELECT_PAIR (rgb0_native);
|
||||
#else
|
||||
if (bits_per_pixel == 32 &&
|
||||
depth == 24 &&
|
||||
mask_bgr &&
|
||||
byte_order == GDK_LSB_FIRST)
|
||||
SELECT_PAIR (rgb0_native);
|
||||
#endif
|
||||
|
||||
if (bits_per_pixel == 32 &&
|
||||
(depth == 30 || depth == 32) &&
|
||||
byte_order == GDK_LSB_FIRST &&
|
||||
red_mask == 0x000003ff &&
|
||||
green_mask == 0x000ffc00 &&
|
||||
blue_mask == 0x3ff00000)
|
||||
SELECT_PAIR (101010_r_low_le);
|
||||
|
||||
if (bits_per_pixel == 32 &&
|
||||
(depth == 30 || depth == 32) &&
|
||||
byte_order == GDK_LSB_FIRST &&
|
||||
red_mask == 0x3ff00000 &&
|
||||
green_mask == 0x000ffc00 &&
|
||||
blue_mask == 0x000003ff)
|
||||
SELECT_PAIR (101010_b_low_le);
|
||||
|
||||
if (bits_per_pixel == 32 &&
|
||||
(depth == 30 || depth == 32) &&
|
||||
byte_order == GDK_MSB_FIRST &&
|
||||
red_mask == 0x000003ff &&
|
||||
green_mask == 0x000ffc00 &&
|
||||
blue_mask == 0x3ff00000)
|
||||
SELECT_PAIR (101010_r_low_be);
|
||||
|
||||
if (bits_per_pixel == 32 &&
|
||||
(depth == 30 || depth == 32) &&
|
||||
byte_order == GDK_MSB_FIRST &&
|
||||
red_mask == 0x3ff00000 &&
|
||||
green_mask == 0x000ffc00 &&
|
||||
blue_mask == 0x000003ff)
|
||||
SELECT_PAIR (101010_b_low_be);
|
||||
|
||||
#undef SELECT_PAIR
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_rgb16_draw_direct (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height,
|
||||
const guint16 *buf,
|
||||
gint pixel_words,
|
||||
gint rowstride,
|
||||
GdkRgb16ConvFunc converter)
|
||||
{
|
||||
GdkScreen *screen;
|
||||
GdkImage *image;
|
||||
const guint16 *tile;
|
||||
gint depth;
|
||||
gint x0, y0;
|
||||
gint xs0, ys0;
|
||||
gint width1, height1;
|
||||
|
||||
screen = gdk_drawable_get_screen (drawable);
|
||||
depth = gdk_drawable_get_depth (drawable);
|
||||
|
||||
for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT)
|
||||
{
|
||||
height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT);
|
||||
|
||||
for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH)
|
||||
{
|
||||
width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
|
||||
|
||||
tile = (const guint16 *)
|
||||
((const guchar *) buf +
|
||||
y0 * rowstride +
|
||||
x0 * pixel_words * sizeof (guint16));
|
||||
|
||||
image = _gdk_image_get_scratch (screen,
|
||||
width1,
|
||||
height1,
|
||||
depth,
|
||||
&xs0,
|
||||
&ys0);
|
||||
|
||||
converter (image,
|
||||
xs0,
|
||||
ys0,
|
||||
width1,
|
||||
height1,
|
||||
tile,
|
||||
rowstride);
|
||||
|
||||
gdk_draw_image (drawable,
|
||||
gc,
|
||||
image,
|
||||
xs0,
|
||||
ys0,
|
||||
x + x0,
|
||||
y + y0,
|
||||
width1,
|
||||
height1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_rgb16_draw_fallback (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dith,
|
||||
const guint16 *buf,
|
||||
gint pixel_words,
|
||||
gint rowstride,
|
||||
gint xdith,
|
||||
gint ydith)
|
||||
{
|
||||
const guchar *input_row;
|
||||
const guint16 *input;
|
||||
guchar *stage;
|
||||
guchar *output;
|
||||
gint stage_rowstride;
|
||||
gint x0, y0;
|
||||
gint x1, y1;
|
||||
gint width1, height1;
|
||||
|
||||
stage = g_malloc (MIN (width, GDK_SCRATCH_IMAGE_WIDTH) *
|
||||
MIN (height, GDK_SCRATCH_IMAGE_HEIGHT) * 3);
|
||||
|
||||
for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT)
|
||||
{
|
||||
height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT);
|
||||
|
||||
for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH)
|
||||
{
|
||||
width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
|
||||
stage_rowstride = width1 * 3;
|
||||
|
||||
input_row = (const guchar *) buf +
|
||||
y0 * rowstride +
|
||||
x0 * pixel_words * sizeof (guint16);
|
||||
output = stage;
|
||||
|
||||
for (y1 = 0; y1 < height1; y1++)
|
||||
{
|
||||
input = (const guint16 *) input_row;
|
||||
|
||||
for (x1 = 0; x1 < width1; x1++)
|
||||
{
|
||||
*output++ = input[0] >> 8;
|
||||
*output++ = input[1] >> 8;
|
||||
*output++ = input[2] >> 8;
|
||||
input += pixel_words;
|
||||
}
|
||||
|
||||
input_row += rowstride;
|
||||
}
|
||||
|
||||
gdk_draw_rgb_image_dithalign (drawable,
|
||||
gc,
|
||||
x + x0,
|
||||
y + y0,
|
||||
width1,
|
||||
height1,
|
||||
dith,
|
||||
stage,
|
||||
stage_rowstride,
|
||||
xdith,
|
||||
ydith);
|
||||
}
|
||||
}
|
||||
|
||||
g_free (stage);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_draw_rgb16_image (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dith,
|
||||
const guint16 *buf,
|
||||
gint rowstride,
|
||||
gint xdith,
|
||||
gint ydith,
|
||||
gboolean is_rgbx)
|
||||
{
|
||||
GdkRgb16ConvFunc converter;
|
||||
gint pixel_words;
|
||||
|
||||
g_return_if_fail (GDK_IS_DRAWABLE (drawable));
|
||||
g_return_if_fail (GDK_IS_GC (gc));
|
||||
g_return_if_fail (buf != NULL);
|
||||
g_return_if_fail ((((guintptr) buf) & 1) == 0);
|
||||
g_return_if_fail ((rowstride & 1) == 0);
|
||||
|
||||
if (width <= 0 || height <= 0)
|
||||
return;
|
||||
|
||||
pixel_words = is_rgbx ? 4 : 3;
|
||||
converter = gdk_rgb16_select_converter (drawable, is_rgbx, dith);
|
||||
|
||||
if (converter != NULL)
|
||||
gdk_rgb16_draw_direct (drawable,
|
||||
gc,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
buf,
|
||||
pixel_words,
|
||||
rowstride,
|
||||
converter);
|
||||
else
|
||||
gdk_rgb16_draw_fallback (drawable,
|
||||
gc,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
dith,
|
||||
buf,
|
||||
pixel_words,
|
||||
rowstride,
|
||||
xdith,
|
||||
ydith);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_draw_rgb_48_image:
|
||||
* @drawable: a #GdkDrawable
|
||||
* @gc: a #GdkGC
|
||||
* @x: destination X coordinate
|
||||
* @y: destination Y coordinate
|
||||
* @width: image width
|
||||
* @height: image height
|
||||
* @dith: dithering mode
|
||||
* @rgb_buf: host-endian RGB data with three 16-bit channels per pixel
|
||||
* @rowstride: number of bytes between consecutive rows
|
||||
*
|
||||
* Draws 48-bit RGB image data.
|
||||
**/
|
||||
void
|
||||
gdk_draw_rgb_48_image (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dith,
|
||||
const guint16 *rgb_buf,
|
||||
gint rowstride)
|
||||
{
|
||||
gdk_draw_rgb16_image (drawable,
|
||||
gc,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
dith,
|
||||
rgb_buf,
|
||||
rowstride,
|
||||
0,
|
||||
0,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_draw_rgb_48_image_dithalign:
|
||||
* @drawable: a #GdkDrawable
|
||||
* @gc: a #GdkGC
|
||||
* @x: destination X coordinate
|
||||
* @y: destination Y coordinate
|
||||
* @width: image width
|
||||
* @height: image height
|
||||
* @dith: dithering mode
|
||||
* @rgb_buf: host-endian RGB data with three 16-bit channels per pixel
|
||||
* @rowstride: number of bytes between consecutive rows
|
||||
* @xdith: X dither offset
|
||||
* @ydith: Y dither offset
|
||||
*
|
||||
* Draws 48-bit RGB image data with explicit dither alignment.
|
||||
**/
|
||||
void
|
||||
gdk_draw_rgb_48_image_dithalign (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dith,
|
||||
const guint16 *rgb_buf,
|
||||
gint rowstride,
|
||||
gint xdith,
|
||||
gint ydith)
|
||||
{
|
||||
gdk_draw_rgb16_image (drawable,
|
||||
gc,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
dith,
|
||||
rgb_buf,
|
||||
rowstride,
|
||||
xdith,
|
||||
ydith,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_draw_rgbx_64_image:
|
||||
* @drawable: a #GdkDrawable
|
||||
* @gc: a #GdkGC
|
||||
* @x: destination X coordinate
|
||||
* @y: destination Y coordinate
|
||||
* @width: image width
|
||||
* @height: image height
|
||||
* @dith: dithering mode
|
||||
* @rgbx_buf: host-endian RGBX data with four 16-bit channels per pixel
|
||||
* @rowstride: number of bytes between consecutive rows
|
||||
*
|
||||
* Draws 64-bit RGBX image data. The X channel is ignored.
|
||||
**/
|
||||
void
|
||||
gdk_draw_rgbx_64_image (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dith,
|
||||
const guint16 *rgbx_buf,
|
||||
gint rowstride)
|
||||
{
|
||||
gdk_draw_rgb16_image (drawable,
|
||||
gc,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
dith,
|
||||
rgbx_buf,
|
||||
rowstride,
|
||||
0,
|
||||
0,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_draw_rgbx_64_image_dithalign:
|
||||
* @drawable: a #GdkDrawable
|
||||
* @gc: a #GdkGC
|
||||
* @x: destination X coordinate
|
||||
* @y: destination Y coordinate
|
||||
* @width: image width
|
||||
* @height: image height
|
||||
* @dith: dithering mode
|
||||
* @rgbx_buf: host-endian RGBX data with four 16-bit channels per pixel
|
||||
* @rowstride: number of bytes between consecutive rows
|
||||
* @xdith: X dither offset
|
||||
* @ydith: Y dither offset
|
||||
*
|
||||
* Draws 64-bit RGBX image data with explicit dither alignment.
|
||||
* The X channel is ignored.
|
||||
**/
|
||||
void
|
||||
gdk_draw_rgbx_64_image_dithalign (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dith,
|
||||
const guint16 *rgbx_buf,
|
||||
gint rowstride,
|
||||
gint xdith,
|
||||
gint ydith)
|
||||
{
|
||||
gdk_draw_rgb16_image (drawable,
|
||||
gc,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
dith,
|
||||
rgbx_buf,
|
||||
rowstride,
|
||||
xdith,
|
||||
ydith,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
#define __GDK_RGB16_C__
|
||||
#include "gdkaliasdef.c"
|
||||
|
|
@ -92,6 +92,7 @@ gdk_OBJECTS = \
|
|||
gdkrectangle.obj \
|
||||
gdkregion-generic.obj \
|
||||
gdkrgb.obj \
|
||||
gdkrgb16.obj \
|
||||
gdkscreen.obj \
|
||||
gdkselection.obj \
|
||||
gdkvisual.obj \
|
||||
|
|
|
|||
Loading…
Reference in a new issue