src/video/SDL_yuv.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 29 May 2006 04:04:35 +0000
branchSDL-1.3
changeset 1668 4da1ee79c9af
parent 1662 782fd950bd46
permissions -rw-r--r--
more tweaking indent options
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2006 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 /* This is the implementation of the YUV video surface support */
    25 
    26 #include "SDL_video.h"
    27 #include "SDL_sysvideo.h"
    28 #include "SDL_yuvfuncs.h"
    29 #include "SDL_yuv_sw_c.h"
    30 
    31 
    32 SDL_Overlay *
    33 SDL_CreateYUVOverlay(int w, int h, Uint32 format, SDL_Surface * display)
    34 {
    35     SDL_VideoDevice *_this = SDL_GetVideoDevice();
    36     SDL_Window *window;
    37     const char *yuv_hwaccel;
    38     SDL_Overlay *overlay;
    39 
    40     window = SDL_GetWindowFromSurface(display);
    41     if (window && (window->flags & SDL_WINDOW_OPENGL)) {
    42         SDL_SetError("YUV overlays are not supported in OpenGL mode");
    43         return NULL;
    44     }
    45 
    46     /* Display directly on video surface, if possible */
    47     if (SDL_getenv("SDL_VIDEO_YUV_DIRECT")) {
    48         if (window &&
    49             ((window->surface->format->BytesPerPixel == 2) ||
    50              (window->surface->format->BytesPerPixel == 4))) {
    51             display = window->surface;
    52         }
    53     }
    54     overlay = NULL;
    55     yuv_hwaccel = SDL_getenv("SDL_VIDEO_YUV_HWACCEL");
    56     if (((display->flags & SDL_SCREEN_SURFACE) && _this->CreateYUVOverlay) &&
    57         (!yuv_hwaccel || (SDL_atoi(yuv_hwaccel) > 0))) {
    58         overlay = _this->CreateYUVOverlay(_this, w, h, format, display);
    59     }
    60     /* If hardware YUV overlay failed ... */
    61     if (overlay == NULL) {
    62         overlay = SDL_CreateYUV_SW(_this, w, h, format, display);
    63     }
    64     return overlay;
    65 }
    66 
    67 int
    68 SDL_LockYUVOverlay(SDL_Overlay * overlay)
    69 {
    70     SDL_VideoDevice *_this = SDL_GetVideoDevice();
    71     return overlay->hwfuncs->Lock(_this, overlay);
    72 }
    73 
    74 void
    75 SDL_UnlockYUVOverlay(SDL_Overlay * overlay)
    76 {
    77     SDL_VideoDevice *_this = SDL_GetVideoDevice();
    78     overlay->hwfuncs->Unlock(_this, overlay);
    79 }
    80 
    81 int
    82 SDL_DisplayYUVOverlay(SDL_Overlay * overlay, SDL_Rect * dstrect)
    83 {
    84     SDL_VideoDevice *_this = SDL_GetVideoDevice();
    85     SDL_Rect src, dst;
    86     int srcx, srcy, srcw, srch;
    87     int dstx, dsty, dstw, dsth;
    88 
    89     /* Clip the rectangle to the screen area */
    90     srcx = 0;
    91     srcy = 0;
    92     srcw = overlay->w;
    93     srch = overlay->h;
    94     dstx = dstrect->x;
    95     dsty = dstrect->y;
    96     dstw = dstrect->w;
    97     dsth = dstrect->h;
    98     if (dstx < 0) {
    99         srcw += (dstx * overlay->w) / dstrect->w;
   100         dstw += dstx;
   101         srcx -= (dstx * overlay->w) / dstrect->w;
   102         dstx = 0;
   103     }
   104     if ((dstx + dstw) > SDL_VideoSurface->w) {
   105         int extra = (dstx + dstw - SDL_VideoSurface->w);
   106         srcw -= (extra * overlay->w) / dstrect->w;
   107         dstw -= extra;
   108     }
   109     if (dsty < 0) {
   110         srch += (dsty * overlay->h) / dstrect->h;
   111         dsth += dsty;
   112         srcy -= (dsty * overlay->h) / dstrect->h;
   113         dsty = 0;
   114     }
   115     if ((dsty + dsth) > SDL_VideoSurface->h) {
   116         int extra = (dsty + dsth - SDL_VideoSurface->h);
   117         srch -= (extra * overlay->h) / dstrect->h;
   118         dsth -= extra;
   119     }
   120     if (srcw <= 0 || srch <= 0 || srch <= 0 || dsth <= 0) {
   121         return 0;
   122     }
   123     /* Ugh, I can't wait for SDL_Rect to be int values */
   124     src.x = srcx;
   125     src.y = srcy;
   126     src.w = srcw;
   127     src.h = srch;
   128     dst.x = dstx;
   129     dst.y = dsty;
   130     dst.w = dstw;
   131     dst.h = dsth;
   132     return overlay->hwfuncs->Display(_this, overlay, &src, &dst);
   133 }
   134 
   135 void
   136 SDL_FreeYUVOverlay(SDL_Overlay * overlay)
   137 {
   138     SDL_VideoDevice *_this = SDL_GetVideoDevice();
   139     if (overlay) {
   140         if (overlay->hwfuncs) {
   141             overlay->hwfuncs->FreeHW(_this, overlay);
   142         }
   143         SDL_free(overlay);
   144     }
   145 }
   146 
   147 /* vi: set ts=4 sw=4 expandtab: */