qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] sdl zooming


From: Stefano Stabellini
Subject: Re: [Qemu-devel] [PATCH] sdl zooming
Date: Thu, 25 Jun 2009 14:03:38 +0100
User-agent: Thunderbird 2.0.0.14 (X11/20080505)

Blue Swirl wrote:

> On 6/24/09, Stefano Stabellini <address@hidden> wrote:
>> Hi all,
>>  this patch implements zooming capabilities for the sdl interface.
>>  A new sdl_zoom_blit function is added that is able to scale and blit a
>>  portion of a surface into another.
>>  This way we can enable SDL_RESIZABLE and have a real_screen surface with
>>  a different size than the guest surface and let sdl_zoom_blit take care
>>  of the problem.
> 
> As you are already using the template system, for extra performance,
> you could remove 'smooth' as parameter and instantiate separate
> functions for both cases with something like:
> 
> static int glue(glue(sdl_zoom_rgb, BPP), _ ## SMOOTH)(SDL_Surface
> *src, SDL_Surface *dst,
>                                    SDL_Rect *dst_rect)
> 
> Then s/smooth/SMOOTH/g in the function and adjust callers.



I am not sure if this change is going to increase the readability of the
code or the performances by much, but this is the new version of the
patch nonetheless.

At this point I would consider making SMOOTH a compile time only variable.

---

diff --git a/Makefile b/Makefile
index 781e7ed..58faff9 100644
--- a/Makefile
+++ b/Makefile
@@ -162,7 +162,7 @@ OBJS+=$(addprefix audio/, $(AUDIO_OBJS))
 
 OBJS+=keymaps.o
 ifdef CONFIG_SDL
-OBJS+=sdl.o x_keymap.o
+OBJS+=sdl.o sdl_zoom.o x_keymap.o
 endif
 ifdef CONFIG_CURSES
 OBJS+=curses.o
@@ -206,7 +206,9 @@ cocoa.o: cocoa.m
 
 keymaps.o: keymaps.c keymaps.h
 
-sdl.o: sdl.c keymaps.h sdl_keysym.h
+sdl_zoom.o: sdl_zoom.c sdl_zoom.h sdl_zoom_template.h
+
+sdl.o: sdl.c keymaps.h sdl_keysym.h sdl_zoom.h
 
 sdl.o audio/sdlaudio.o: CFLAGS += $(SDL_CFLAGS)
 
diff --git a/console.h b/console.h
index 4172175..3518339 100644
--- a/console.h
+++ b/console.h
@@ -75,6 +75,7 @@ void kbd_put_keysym(int keysym);
 
 #define QEMU_BIG_ENDIAN_FLAG    0x01
 #define QEMU_ALLOCATED_FLAG     0x02
+#define QEMU_REALPIXELS_FLAG    0x04
 
 struct PixelFormat {
     uint8_t bits_per_pixel;
@@ -172,7 +173,8 @@ static inline int is_surface_bgr(DisplaySurface *surface)
 
 static inline int is_buffer_shared(DisplaySurface *surface)
 {
-    return (!(surface->flags & QEMU_ALLOCATED_FLAG));
+    return (!(surface->flags & QEMU_ALLOCATED_FLAG) &&
+            !(surface->flags & QEMU_REALPIXELS_FLAG));
 }
 
 static inline void register_displaychangelistener(DisplayState *ds, 
DisplayChangeListener *dcl)
diff --git a/sdl.c b/sdl.c
index 178b553..d81399e 100644
--- a/sdl.c
+++ b/sdl.c
@@ -32,6 +32,7 @@
 #include "console.h"
 #include "sysemu.h"
 #include "x_keymap.h"
+#include "sdl_zoom.h"
 
 static DisplayChangeListener *dcl;
 static SDL_Surface *real_screen;
@@ -54,20 +55,29 @@ static int guest_cursor = 0;
 static int guest_x, guest_y;
 static SDL_Cursor *guest_sprite = 0;
 static uint8_t allocator;
-static uint8_t hostbpp;
+static SDL_PixelFormat host_format;
+static int scaling_active = 0;
 
 static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
 {
     //    printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
+    SDL_Rect rec;
+    rec.x = x;
+    rec.y = y;
+    rec.w = w;
+    rec.h = h;
+
     if (guest_screen) {
-        SDL_Rect rec;
-        rec.x = x;
-        rec.y = y;
-        rec.w = w;
-        rec.h = h;
-        SDL_BlitSurface(guest_screen, &rec, real_screen, &rec);
-    }
-    SDL_UpdateRect(real_screen, x, y, w, h);
+        if (!scaling_active) {
+            SDL_BlitSurface(guest_screen, &rec, real_screen, &rec);
+        } else {
+            if (sdl_zoom_blit(guest_screen, real_screen, SMOOTHING_ON, &rec) < 
0) {
+                fprintf(stderr, "Zoom blit failed\n");
+                exit(1);
+            }
+        }
+    } 
+    SDL_UpdateRect(real_screen, rec.x, rec.y, rec.w, rec.h);
 }
 
 static void sdl_setdata(DisplayState *ds)
@@ -92,7 +102,7 @@ static void do_sdl_resize(int new_width, int new_height, int 
bpp)
 
     //    printf("resizing to %d %d\n", w, h);
 
-    flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
+    flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL|SDL_RESIZABLE;
     if (gui_fullscreen)
         flags |= SDL_FULLSCREEN;
     if (gui_noframe)
@@ -110,7 +120,10 @@ static void do_sdl_resize(int new_width, int new_height, 
int bpp)
 static void sdl_resize(DisplayState *ds)
 {
     if  (!allocator) {
-        do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0);
+        if (!scaling_active)
+            do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0);
+        else if (real_screen->format->BitsPerPixel != 
ds_get_bits_per_pixel(ds))
+            do_sdl_resize(real_screen->w, real_screen->h, 
ds_get_bits_per_pixel(ds));
         sdl_setdata(ds);
     } else {
         if (guest_screen != NULL) {
@@ -163,8 +176,26 @@ static DisplaySurface* sdl_create_displaysurface(int 
width, int height)
 
     surface->width = width;
     surface->height = height;
+    
+    if (scaling_active) {
+        if (host_format.BytesPerPixel != 2 && host_format.BytesPerPixel != 4) {
+            surface->linesize = width * 4;
+            surface->pf = qemu_default_pixelformat(32);
+        } else {
+            surface->linesize = width * host_format.BytesPerPixel;
+            surface->pf = sdl_to_qemu_pixelformat(&host_format);
+        }
+#ifdef WORDS_BIGENDIAN
+        surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG;
+#else
+        surface->flags = QEMU_ALLOCATED_FLAG;
+#endif
+        surface->data = (uint8_t*) qemu_mallocz(surface->linesize * 
surface->height);
+
+        return surface;
+    }
 
-    if (hostbpp == 16)
+    if (host_format.BitsPerPixel == 16)
         do_sdl_resize(width, height, 16);
     else
         do_sdl_resize(width, height, 32);
@@ -174,9 +205,9 @@ static DisplaySurface* sdl_create_displaysurface(int width, 
int height)
     surface->data = real_screen->pixels;
 
 #ifdef WORDS_BIGENDIAN
-    surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG;
+    surface->flags = QEMU_REALPIXELS_FLAG | QEMU_BIG_ENDIAN_FLAG;
 #else
-    surface->flags = QEMU_ALLOCATED_FLAG;
+    surface->flags = QEMU_REALPIXELS_FLAG;
 #endif
     allocator = 1;
 
@@ -188,6 +219,9 @@ static void sdl_free_displaysurface(DisplaySurface *surface)
     allocator = 0;
     if (surface == NULL)
         return;
+
+    if (surface->flags & QEMU_ALLOCATED_FLAG)
+        qemu_free(surface->data);
     qemu_free(surface);
 }
 
@@ -482,8 +516,8 @@ static void sdl_send_mouse_event(int dx, int dy, int dz, 
int x, int y, int state
 static void toggle_full_screen(DisplayState *ds)
 {
     gui_fullscreen = !gui_fullscreen;
-    do_sdl_resize(real_screen->w, real_screen->h, 
real_screen->format->BitsPerPixel);
     if (gui_fullscreen) {
+        scaling_active = 0;
         gui_saved_grab = gui_grab;
         sdl_grab_start();
     } else {
@@ -675,6 +709,18 @@ static void sdl_refresh(DisplayState *ds)
                 }
             }
             break;
+       case SDL_VIDEORESIZE:
+        {
+           SDL_ResizeEvent *rev = &ev->resize;
+            int bpp = real_screen->format->BitsPerPixel;
+            if (bpp != 16 && bpp != 32)
+                bpp = 32;
+            do_sdl_resize(rev->w, rev->h, bpp);
+            scaling_active = 1;
+            vga_hw_invalidate();
+            vga_hw_update();
+            break;
+        }
         default:
             break;
         }
@@ -783,7 +829,7 @@ void sdl_display_init(DisplayState *ds, int full_screen, 
int no_frame)
         exit(1);
     }
     vi = SDL_GetVideoInfo();
-    hostbpp = vi->vfmt->BitsPerPixel;
+    host_format = *(vi->vfmt);
 
     dcl = qemu_mallocz(sizeof(DisplayChangeListener));
     dcl->dpy_update = sdl_update;
diff --git a/sdl_zoom.c b/sdl_zoom.c
new file mode 100644
index 0000000..a9e82a4
--- /dev/null
+++ b/sdl_zoom.c
@@ -0,0 +1,110 @@
+/*
+ * SDL_zoom - surface scaling
+ * 
+ * Copyright (c) 2009 Citrix Systems, Inc.
+ *
+ * Derived from: SDL_rotozoom,  LGPL (c) A. Schiffler from the SDL_gfx library.
+ * Modifications by Stefano Stabellini.
+ *
+ * This work is licensed under the terms of the GNU GPL version 2.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "sdl_zoom.h"
+#include "osdep.h"
+#include <stdint.h>
+
+static int sdl_zoom_rgb16_smooth(SDL_Surface *src, SDL_Surface *dst, SDL_Rect 
*dst_rect);
+static int sdl_zoom_rgb32_smooth(SDL_Surface *src, SDL_Surface *dst, SDL_Rect 
*dst_rect);
+static int sdl_zoom_rgb16_fast(SDL_Surface *src, SDL_Surface *dst, SDL_Rect 
*dst_rect);
+static int sdl_zoom_rgb32_fast(SDL_Surface *src, SDL_Surface *dst, SDL_Rect 
*dst_rect);
+
+#define SMOOTH 1
+#define BPP 32
+#include  "sdl_zoom_template.h"
+#undef BPP
+#define BPP 16
+#include  "sdl_zoom_template.h"
+#undef BPP
+#undef SMOOTH
+#define SMOOTH 0
+#define BPP 32
+#include  "sdl_zoom_template.h"
+#undef BPP
+#define BPP 16
+#include  "sdl_zoom_template.h"
+#undef BPP
+#undef SMOOTH
+
+int sdl_zoom_blit(SDL_Surface *src_sfc, SDL_Surface *dst_sfc, int smooth,
+                  SDL_Rect *in_rect)
+{
+    SDL_Rect zoom, src_rect;
+    int extra;
+
+    /* Grow the size of the modified rectangle to avoid edge artefacts */
+    src_rect.x = (in_rect->x > 0) ? (in_rect->x - 1) : 0;
+    src_rect.y = (in_rect->y > 0) ? (in_rect->y - 1) : 0;
+
+    src_rect.w = in_rect->w + 1;
+    if (src_rect.x + src_rect.w > src_sfc->w)
+        src_rect.w = src_sfc->w - src_rect.x;
+
+    src_rect.h = in_rect->h + 1;
+    if (src_rect.y + src_rect.h > src_sfc->h)
+        src_rect.h = src_sfc->h - src_rect.y;
+
+    /* (x,y) : round down */
+    zoom.x = (int)(((float)(src_rect.x * dst_sfc->w)) / (float)(src_sfc->w));
+    zoom.y = (int)(((float)(src_rect.y * dst_sfc->h)) / (float)(src_sfc->h));
+
+    /* (w,h) : round up */
+    zoom.w = (int)( ((double)((src_rect.w * dst_sfc->w) + (src_sfc->w - 1))) /
+                     (double)(src_sfc->w));
+
+    zoom.h = (int)( ((double)((src_rect.h * dst_sfc->h) + (src_sfc->h - 1))) /
+                     (double)(src_sfc->h));
+
+    /* Account for any (x,y) rounding by adding one-source-pixel's worth
+     * of destination pixels and then edge checking.
+     */
+
+    extra = ((dst_sfc->w-1) / src_sfc->w) + 1;
+
+    if ((zoom.x + zoom.w) < (dst_sfc->w - extra))
+        zoom.w += extra;
+    else
+        zoom.w = dst_sfc->w - zoom.x;
+
+    extra = ((dst_sfc->h-1) / src_sfc->h) + 1;
+
+    if ((zoom.y + zoom.h) < (dst_sfc->h - extra))
+        zoom.h += extra;
+    else
+        zoom.h = dst_sfc->h - zoom.y;
+
+    /* The rectangle (zoom.x, zoom.y, zoom.w, zoom.h) is the area on the
+     * destination surface that needs to be updated.
+     */
+    if (src_sfc->format->BitsPerPixel == 32) {
+        if (smooth)
+            sdl_zoom_rgb32_smooth(src_sfc, dst_sfc, &zoom);
+        else
+            sdl_zoom_rgb32_fast(src_sfc, dst_sfc, &zoom);
+    } else if (src_sfc->format->BitsPerPixel == 16) {
+        if (smooth)
+            sdl_zoom_rgb16_smooth(src_sfc, dst_sfc, &zoom);
+        else
+            sdl_zoom_rgb16_fast(src_sfc, dst_sfc, &zoom);
+    } else {
+        fprintf(stderr, "pixel format not supported\n");
+        return -1;
+    }
+
+    /* Return the rectangle of the update to the caller */
+    *in_rect = zoom;
+
+    return 0;
+}
+
diff --git a/sdl_zoom.h b/sdl_zoom.h
new file mode 100644
index 0000000..33dc634
--- /dev/null
+++ b/sdl_zoom.h
@@ -0,0 +1,25 @@
+/*
+ * SDL_zoom - surface scaling
+ * 
+ * Copyright (c) 2009 Citrix Systems, Inc.
+ *
+ * Derived from: SDL_rotozoom,  LGPL (c) A. Schiffler from the SDL_gfx library.
+ * Modifications by Stefano Stabellini.
+ *
+ * This work is licensed under the terms of the GNU GPL version 2.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef _SDL_zoom_h
+#define _SDL_zoom_h
+
+#include <SDL/SDL.h>
+
+#define SMOOTHING_OFF          0
+#define SMOOTHING_ON           1
+
+int sdl_zoom_blit(SDL_Surface *src_sfc, SDL_Surface *dst_sfc,
+                  int smooth, SDL_Rect *src_rect);
+
+#endif /* _SDL_zoom_h */
diff --git a/sdl_zoom_template.h b/sdl_zoom_template.h
new file mode 100644
index 0000000..bc440ad
--- /dev/null
+++ b/sdl_zoom_template.h
@@ -0,0 +1,233 @@
+/*
+ * SDL_zoom_template - surface scaling
+ * 
+ * Copyright (c) 2009 Citrix Systems, Inc.
+ *
+ * Derived from: SDL_rotozoom,  LGPL (c) A. Schiffler from the SDL_gfx library.
+ * Modifications by Stefano Stabellini.
+ *
+ * This work is licensed under the terms of the GNU GPL version 2.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#if BPP == 16
+#define SDL_TYPE Uint16
+#elif BPP == 32
+#define SDL_TYPE Uint32
+#else
+#error unsupport depth
+#endif
+
+#if SMOOTH == 1
+#define ALG _smooth
+#else
+#define ALG _fast
+#endif
+
+/*  
+ *  Simple helper functions to make the code looks nicer
+ *
+ *  Assume spf = source SDL_PixelFormat
+ *         dpf = dest SDL_PixelFormat
+ *
+ */
+#define getRed(color)   (((color) & spf->Rmask) >> spf->Rshift)
+#define getGreen(color) (((color) & spf->Gmask) >> spf->Gshift)
+#define getBlue(color)  (((color) & spf->Bmask) >> spf->Bshift)
+#define getAlpha(color) (((color) & spf->Amask) >> spf->Ashift)
+
+#define setRed(r, pcolor) do { \
+    *pcolor = ((*pcolor) & (~(dpf->Rmask))) + \
+              (((r) & (dpf->Rmask >> dpf->Rshift)) << dpf->Rshift); \
+} while (0);
+
+#define setGreen(g, pcolor) do { \
+    *pcolor = ((*pcolor) & (~(dpf->Gmask))) + \
+              (((g) & (dpf->Gmask >> dpf->Gshift)) << dpf->Gshift); \
+} while (0);
+
+#define setBlue(b, pcolor) do { \
+    *pcolor = ((*pcolor) & (~(dpf->Bmask))) + \
+              (((b) & (dpf->Bmask >> dpf->Bshift)) << dpf->Bshift); \
+} while (0);
+
+#define setAlpha(a, pcolor) do { \
+    *pcolor = ((*pcolor) & (~(dpf->Amask))) + \
+              (((a) & (dpf->Amask >> dpf->Ashift)) << dpf->Ashift); \
+} while (0);
+
+static int glue(glue(sdl_zoom_rgb, BPP), ALG)(SDL_Surface *src,
+                                                      SDL_Surface *dst,
+                                                      SDL_Rect *dst_rect)
+{
+    int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy, sstep, sstep_jump;
+    SDL_TYPE *sp, *csp, *dp;
+    int d_gap;
+
+#if SMOOTH == 1
+    int ex, ey, t1, t2;
+    SDL_TYPE *c00, *c01, *c10, *c11;
+    SDL_PixelFormat *spf = src->format;
+    SDL_PixelFormat *dpf = dst->format;
+
+    /* For interpolation: assume source dimension is one pixel.
+     * Smaller here to avoid overflow on right and bottom edge.
+     */
+    sx = (int) (65536.0 * (float) (src->w - 1) / (float) dst->w);
+    sy = (int) (65536.0 * (float) (src->h - 1) / (float) dst->h);
+#else
+    sx = (int) (65536.0 * (float) src->w / (float) dst->w);
+    sy = (int) (65536.0 * (float) src->h / (float) dst->h);
+#endif
+
+    if ((sax = (int *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) {
+        return (-1);
+    }
+    if ((say = (int *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) {
+        free(sax);
+        return (-1);
+    }
+
+    sp = csp = (SDL_TYPE *) src->pixels;
+    dp = (SDL_TYPE *) (dst->pixels + dst_rect->y * dst->pitch +
+                       dst_rect->x * dst->format->BytesPerPixel);
+
+    csx = 0;
+    csax = sax;
+    for (x = 0; x <= dst->w; x++) {
+        *csax = csx;
+        csax++;
+        csx &= 0xffff;
+        csx += sx;
+    }
+    csy = 0;
+    csay = say;
+    for (y = 0; y <= dst->h; y++) {
+        *csay = csy;
+        csay++;
+        csy &= 0xffff;
+        csy += sy;
+    }
+
+    d_gap = dst->pitch - dst_rect->w * dst->format->BytesPerPixel;
+
+#if SMOOTH == 1
+    csay = say;
+    for (y = 0; y < dst_rect->y; y++) {
+        csay++;
+        sstep = (*csay >> 16) * src->pitch;
+        csp = (SDL_TYPE *) ((Uint8 *) csp + sstep);
+    }
+
+    /* Calculate sstep_jump */
+    csax = sax; 
+    sstep_jump = 0;
+    for (x = 0; x < dst_rect->x; x++) {
+        csax++; 
+        sstep = (*csax >> 16);
+        sstep_jump += sstep;
+    }
+
+    for (y = 0; y < dst_rect->h ; y++) {
+        /* Setup colour source pointers */
+        c00 = csp + sstep_jump;
+        c01 = c00 + 1;
+        c10 = (SDL_TYPE *) ((Uint8 *) csp + src->pitch) + sstep_jump;
+        c11 = c10 + 1;
+        csax = sax + dst_rect->x; 
+
+        for (x = 0; x < dst_rect->w; x++) {
+
+            /* Interpolate colours */
+            ex = (*csax & 0xffff);
+            ey = (*csay & 0xffff);
+            t1 = ((((getRed(*c01) - getRed(*c00)) * ex) >> 16) +
+                    getRed(*c00)) & (dpf->Rmask >> dpf->Rshift);
+            t2 = ((((getRed(*c11) - getRed(*c10)) * ex) >> 16) +
+                    getRed(*c10)) & (dpf->Rmask >> dpf->Rshift);
+            setRed((((t2 - t1) * ey) >> 16) + t1, dp);
+            t1 = ((((getGreen(*c01) - getGreen(*c00)) * ex) >> 16) +
+                    getGreen(*c00)) & (dpf->Gmask >> dpf->Gshift);
+            t2 = ((((getGreen(*c11) - getGreen(*c10)) * ex) >> 16) +
+                    getGreen(*c10)) & (dpf->Gmask >> dpf->Gshift);
+            setGreen((((t2 - t1) * ey) >> 16) + t1, dp);
+            t1 = ((((getBlue(*c01) - getBlue(*c00)) * ex) >> 16) +
+                    getBlue(*c00)) & (dpf->Bmask >> dpf->Bshift);
+            t2 = ((((getBlue(*c11) - getBlue(*c10)) * ex) >> 16) +
+                    getBlue(*c10)) & (dpf->Bmask >> dpf->Bshift);
+            setBlue((((t2 - t1) * ey) >> 16) + t1, dp);
+            t1 = ((((getAlpha(*c01) - getAlpha(*c00)) * ex) >> 16) +
+                    getAlpha(*c00)) & (dpf->Amask >> dpf->Ashift);
+            t2 = ((((getAlpha(*c11) - getAlpha(*c10)) * ex) >> 16) +
+                    getAlpha(*c10)) & (dpf->Amask >> dpf->Ashift);
+            setAlpha((((t2 - t1) * ey) >> 16) + t1, dp); 
+
+            /* Advance source pointers */
+            csax++; 
+            sstep = (*csax >> 16);
+            c00 += sstep;
+            c01 += sstep;
+            c10 += sstep;
+            c11 += sstep;
+            /* Advance destination pointer */
+            dp++;
+        }
+        /* Advance source pointer */
+        csay++;
+        csp = (SDL_TYPE *) ((Uint8 *) csp + (*csay >> 16) * src->pitch);
+        /* Advance destination pointers */
+        dp = (SDL_TYPE *) ((Uint8 *) dp + d_gap);
+    }
+#else
+    csay = say;
+
+    for (y = 0; y < dst_rect->y; y++) {
+        csay++;
+        sstep = (*csay >> 16) * src->pitch;
+        csp = (SDL_TYPE *) ((Uint8 *) csp + sstep);
+    }
+
+    /* Calculate sstep_jump */
+    csax = sax; 
+    sstep_jump = 0;
+    for (x = 0; x < dst_rect->x; x++) {
+        csax++; 
+        sstep = (*csax >> 16);
+        sstep_jump += sstep;
+    }
+
+    for (y = 0 ; y < dst_rect->h ; y++) {
+        sp = csp + sstep_jump;
+        csax = sax + dst_rect->x;
+
+        for (x = 0; x < dst_rect->w; x++) {
+
+            /* Draw */
+            *dp = *sp;
+
+            /* Advance source pointers */
+            csax++;
+            sstep = (*csax >> 16);
+            sp += sstep;
+
+            /* Advance destination pointer */
+            dp++;
+        }
+        /* Advance source pointers */
+        csay++;
+        sstep = (*csay >> 16) * src->pitch;
+        csp = (SDL_TYPE *) ((Uint8 *) csp + sstep);
+
+        /* Advance destination pointer */
+        dp = (SDL_TYPE *) ((Uint8 *) dp + d_gap);
+    }
+#endif
+
+    free(sax);
+    free(say);
+    return (0);
+}
+
+#undef SDL_TYPE
+#undef ALG




reply via email to

[Prev in Thread] Current Thread [Next in Thread]