From 9fd1ec632720fa684b3e38c2f90833c71c6876a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Thu, 25 Apr 2019 09:12:25 +0200 Subject: [PATCH] avifile.dll16: Correctly convert result of AVIStreamGetFrame to a segptr. Signed-off-by: Vijay Kiran Kamuju Signed-off-by: Alexandre Julliard --- dlls/avifile.dll16/Makefile.in | 3 + dlls/avifile.dll16/avifile.dll16.spec | 6 +- dlls/avifile.dll16/main.c | 133 ++++++++++++++++++++++++++ 3 files changed, 139 insertions(+), 3 deletions(-) create mode 100644 dlls/avifile.dll16/main.c diff --git a/dlls/avifile.dll16/Makefile.in b/dlls/avifile.dll16/Makefile.in index 6050c6c52dc..4152c2f9f2a 100644 --- a/dlls/avifile.dll16/Makefile.in +++ b/dlls/avifile.dll16/Makefile.in @@ -1,3 +1,6 @@ MODULE = avifile.dll16 IMPORTS = avifil32 EXTRADLLFLAGS = -m16 -Wb,--main-module,avifil32.dll + +C_SRCS = \ + main.c diff --git a/dlls/avifile.dll16/avifile.dll16.spec b/dlls/avifile.dll16/avifile.dll16.spec index 239d3a4a48f..2b5fb910342 100644 --- a/dlls/avifile.dll16/avifile.dll16.spec +++ b/dlls/avifile.dll16/avifile.dll16.spec @@ -20,9 +20,9 @@ 105 stub AVIMAKECOMPRESSEDSTREAM 106 stub AVIMAKEFILEFROMSTREAMS 107 stub AVIMAKESTREAMFROMCLIPBOARD -110 pascal AVIStreamGetFrame(long long) AVIStreamGetFrame -111 pascal AVIStreamGetFrameClose(long) AVIStreamGetFrameClose -112 pascal AVIStreamGetFrameOpen(long ptr) AVIStreamGetFrameOpen +110 pascal AVIStreamGetFrame(long long) AVIStreamGetFrame16 +111 pascal AVIStreamGetFrameClose(long) AVIStreamGetFrameClose16 +112 pascal AVIStreamGetFrameOpen(long ptr) AVIStreamGetFrameOpen16 120 stub _AVISAVE 121 stub AVISAVEV 122 stub AVISAVEOPTIONS diff --git a/dlls/avifile.dll16/main.c b/dlls/avifile.dll16/main.c new file mode 100644 index 00000000000..9e1faac2295 --- /dev/null +++ b/dlls/avifile.dll16/main.c @@ -0,0 +1,133 @@ +/* + * Wrapper for 16 bit avifile functions + * + * Copyright 2016 Michael Müller + * + * 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.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "wine/winbase16.h" +#include "winternl.h" +#include "wingdi.h" +#include "vfw.h" + +struct frame_wrapper16 +{ + PGETFRAME pg; + PVOID ptr; + DWORD size; + WORD sel; + WORD count; +}; + +static void free_segptr_frame(struct frame_wrapper16 *wrapper) +{ + int i; + + if (!wrapper->sel) + return; + + for (i = 0; i < wrapper->count; i++) + FreeSelector16(wrapper->sel + (i << __AHSHIFT)); + + wrapper->sel = 0; +} + +static SEGPTR alloc_segptr_frame(struct frame_wrapper16 *wrapper, void *ptr, DWORD size) +{ + int i; + + if (wrapper->sel) + { + if (wrapper->ptr == ptr && wrapper->size == size) + return MAKESEGPTR(wrapper->sel, 0); + free_segptr_frame(wrapper); + } + + wrapper->ptr = ptr; + wrapper->size = size; + wrapper->count = (size + 0xffff) / 0x10000; + wrapper->sel = AllocSelectorArray16(wrapper->count); + if (!wrapper->sel) + return 0; + + for (i = 0; i < wrapper->count; i++) + { + SetSelectorBase(wrapper->sel + (i << __AHSHIFT), (DWORD)ptr + i * 0x10000); + SetSelectorLimit16(wrapper->sel + (i << __AHSHIFT), size - 1); + size -= 0x10000; + } + + return MAKESEGPTR(wrapper->sel, 0); +} + +/*********************************************************************** + * AVIStreamGetFrameOpen (AVIFILE.112) + */ +PGETFRAME WINAPI AVIStreamGetFrameOpen16(PAVISTREAM pstream, LPBITMAPINFOHEADER lpbiWanted) +{ + struct frame_wrapper16 *wrapper; + PGETFRAME pg; + + pg = AVIStreamGetFrameOpen(pstream, lpbiWanted); + if (!pg) return NULL; + + wrapper = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wrapper)); + if (!wrapper) + { + AVIStreamGetFrameClose(pg); + return NULL; + } + + wrapper->pg = pg; + return (PGETFRAME)wrapper; +} + +/*********************************************************************** + * AVIStreamGetFrame (AVIFILE.110) + */ +SEGPTR WINAPI AVIStreamGetFrame16(PGETFRAME pg, LONG pos) +{ + struct frame_wrapper16 *wrapper = (void *)pg; + BITMAPINFOHEADER *bih; + + if (!pg) return 0; + + bih = AVIStreamGetFrame(wrapper->pg, pos); + if (bih) + { + DWORD size = bih->biSize + bih->biSizeImage; + return alloc_segptr_frame(wrapper, bih, size); + } + + return 0; +} + + +/*********************************************************************** + * AVIStreamGetFrameClose (AVIFILE.111) + */ +HRESULT WINAPI AVIStreamGetFrameClose16(PGETFRAME pg) +{ + struct frame_wrapper16 *wrapper = (void *)pg; + HRESULT hr; + + if (!pg) return S_OK; + + hr = AVIStreamGetFrameClose(wrapper->pg); + free_segptr_frame(wrapper); + HeapFree(GetProcessHeap(), 0, wrapper); + return hr; +}