Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
1ed39c29
Commit
1ed39c29
authored
Aug 27, 2010
by
Vincent Povirk
Committed by
Alexandre Julliard
Aug 30, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
windowscodecs: Implement IWICStream::InitializeFromIStreamRegion.
parent
0b532eb8
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
321 additions
and
3 deletions
+321
-3
stream.c
dlls/windowscodecs/stream.c
+320
-2
stream.c
dlls/windowscodecs/tests/stream.c
+1
-1
No files found.
dlls/windowscodecs/stream.c
View file @
1ed39c29
...
@@ -259,6 +259,298 @@ const IStreamVtbl StreamOnMemory_Vtbl =
...
@@ -259,6 +259,298 @@ const IStreamVtbl StreamOnMemory_Vtbl =
};
};
/******************************************
/******************************************
* StreamOnStreamRange implementation
*
* Used by IWICStream_InitializeFromIStreamRegion
*
*/
typedef
struct
StreamOnStreamRange
{
const
IStreamVtbl
*
lpVtbl
;
LONG
ref
;
IStream
*
stream
;
ULARGE_INTEGER
pos
;
ULARGE_INTEGER
offset
;
ULARGE_INTEGER
max_size
;
CRITICAL_SECTION
lock
;
}
StreamOnStreamRange
;
static
HRESULT
WINAPI
StreamOnStreamRange_QueryInterface
(
IStream
*
iface
,
REFIID
iid
,
void
**
ppv
)
{
TRACE
(
"(%p,%s,%p)
\n
"
,
iface
,
debugstr_guid
(
iid
),
ppv
);
if
(
!
ppv
)
return
E_INVALIDARG
;
if
(
IsEqualIID
(
&
IID_IUnknown
,
iid
)
||
IsEqualIID
(
&
IID_IStream
,
iid
)
||
IsEqualIID
(
&
IID_ISequentialStream
,
iid
))
{
*
ppv
=
iface
;
IUnknown_AddRef
((
IUnknown
*
)
*
ppv
);
return
S_OK
;
}
else
{
*
ppv
=
NULL
;
return
E_NOINTERFACE
;
}
}
static
ULONG
WINAPI
StreamOnStreamRange_AddRef
(
IStream
*
iface
)
{
StreamOnStreamRange
*
This
=
(
StreamOnStreamRange
*
)
iface
;
ULONG
ref
=
InterlockedIncrement
(
&
This
->
ref
);
TRACE
(
"(%p) refcount=%u
\n
"
,
iface
,
ref
);
return
ref
;
}
static
ULONG
WINAPI
StreamOnStreamRange_Release
(
IStream
*
iface
)
{
StreamOnStreamRange
*
This
=
(
StreamOnStreamRange
*
)
iface
;
ULONG
ref
=
InterlockedDecrement
(
&
This
->
ref
);
TRACE
(
"(%p) refcount=%u
\n
"
,
iface
,
ref
);
if
(
ref
==
0
)
{
This
->
lock
.
DebugInfo
->
Spare
[
0
]
=
0
;
DeleteCriticalSection
(
&
This
->
lock
);
IStream_Release
(
This
->
stream
);
HeapFree
(
GetProcessHeap
(),
0
,
This
);
}
return
ref
;
}
static
HRESULT
WINAPI
StreamOnStreamRange_Read
(
IStream
*
iface
,
void
*
pv
,
ULONG
cb
,
ULONG
*
pcbRead
)
{
StreamOnStreamRange
*
This
=
(
StreamOnStreamRange
*
)
iface
;
ULONG
uBytesRead
=
0
;
HRESULT
hr
;
ULARGE_INTEGER
OldPosition
;
LARGE_INTEGER
SetPosition
;
TRACE
(
"(%p)
\n
"
,
This
);
if
(
!
pv
)
return
E_INVALIDARG
;
EnterCriticalSection
(
&
This
->
lock
);
SetPosition
.
QuadPart
=
0
;
hr
=
IStream_Seek
(
This
->
stream
,
SetPosition
,
STREAM_SEEK_CUR
,
&
OldPosition
);
if
(
SUCCEEDED
(
hr
))
{
SetPosition
.
QuadPart
=
This
->
pos
.
QuadPart
+
This
->
offset
.
QuadPart
;
hr
=
IStream_Seek
(
This
->
stream
,
SetPosition
,
STREAM_SEEK_CUR
,
NULL
);
}
if
(
SUCCEEDED
(
hr
))
{
if
(
This
->
pos
.
QuadPart
+
cb
>
This
->
max_size
.
QuadPart
)
{
/* This would read past the end of the stream. */
if
(
This
->
pos
.
QuadPart
>
This
->
max_size
.
QuadPart
)
cb
=
0
;
else
cb
=
This
->
max_size
.
QuadPart
-
This
->
pos
.
QuadPart
;
}
hr
=
IStream_Read
(
This
->
stream
,
pv
,
cb
,
&
uBytesRead
);
SetPosition
.
QuadPart
=
OldPosition
.
QuadPart
;
IStream_Seek
(
This
->
stream
,
SetPosition
,
STREAM_SEEK_SET
,
NULL
);
}
if
(
SUCCEEDED
(
hr
))
This
->
pos
.
QuadPart
+=
uBytesRead
;
LeaveCriticalSection
(
&
This
->
lock
);
if
(
pcbRead
)
*
pcbRead
=
uBytesRead
;
return
hr
;
}
static
HRESULT
WINAPI
StreamOnStreamRange_Write
(
IStream
*
iface
,
void
const
*
pv
,
ULONG
cb
,
ULONG
*
pcbWritten
)
{
StreamOnStreamRange
*
This
=
(
StreamOnStreamRange
*
)
iface
;
HRESULT
hr
;
ULARGE_INTEGER
OldPosition
;
LARGE_INTEGER
SetPosition
;
ULONG
uBytesWritten
=
0
;
TRACE
(
"(%p)
\n
"
,
This
);
if
(
!
pv
)
return
E_INVALIDARG
;
EnterCriticalSection
(
&
This
->
lock
);
SetPosition
.
QuadPart
=
0
;
hr
=
IStream_Seek
(
This
->
stream
,
SetPosition
,
STREAM_SEEK_CUR
,
&
OldPosition
);
if
(
SUCCEEDED
(
hr
))
{
SetPosition
.
QuadPart
=
This
->
pos
.
QuadPart
+
This
->
offset
.
QuadPart
;
hr
=
IStream_Seek
(
This
->
stream
,
SetPosition
,
STREAM_SEEK_CUR
,
NULL
);
}
if
(
SUCCEEDED
(
hr
))
{
if
(
This
->
pos
.
QuadPart
+
cb
>
This
->
max_size
.
QuadPart
)
{
/* This would read past the end of the stream. */
if
(
This
->
pos
.
QuadPart
>
This
->
max_size
.
QuadPart
)
cb
=
0
;
else
cb
=
This
->
max_size
.
QuadPart
-
This
->
pos
.
QuadPart
;
}
hr
=
IStream_Write
(
This
->
stream
,
pv
,
cb
,
&
uBytesWritten
);
SetPosition
.
QuadPart
=
OldPosition
.
QuadPart
;
IStream_Seek
(
This
->
stream
,
SetPosition
,
STREAM_SEEK_SET
,
NULL
);
}
if
(
SUCCEEDED
(
hr
))
This
->
pos
.
QuadPart
+=
uBytesWritten
;
LeaveCriticalSection
(
&
This
->
lock
);
if
(
pcbWritten
)
*
pcbWritten
=
uBytesWritten
;
return
hr
;
}
static
HRESULT
WINAPI
StreamOnStreamRange_Seek
(
IStream
*
iface
,
LARGE_INTEGER
dlibMove
,
DWORD
dwOrigin
,
ULARGE_INTEGER
*
plibNewPosition
)
{
StreamOnStreamRange
*
This
=
(
StreamOnStreamRange
*
)
iface
;
ULARGE_INTEGER
NewPosition
,
actual_size
;
HRESULT
hr
=
S_OK
;
STATSTG
statstg
;
TRACE
(
"(%p)
\n
"
,
This
);
EnterCriticalSection
(
&
This
->
lock
);
actual_size
=
This
->
max_size
;
if
(
dwOrigin
==
STREAM_SEEK_SET
)
NewPosition
.
QuadPart
=
dlibMove
.
QuadPart
;
else
if
(
dwOrigin
==
STREAM_SEEK_CUR
)
NewPosition
.
QuadPart
=
This
->
pos
.
QuadPart
+
dlibMove
.
QuadPart
;
else
if
(
dwOrigin
==
STREAM_SEEK_END
)
{
hr
=
IStream_Stat
(
This
->
stream
,
&
statstg
,
STATFLAG_NONAME
);
if
(
SUCCEEDED
(
hr
))
{
if
(
This
->
max_size
.
QuadPart
+
This
->
offset
.
QuadPart
>
statstg
.
cbSize
.
QuadPart
)
actual_size
.
QuadPart
=
statstg
.
cbSize
.
QuadPart
-
This
->
offset
.
QuadPart
;
NewPosition
.
QuadPart
=
dlibMove
.
QuadPart
+
actual_size
.
QuadPart
;
}
}
else
hr
=
E_INVALIDARG
;
if
(
SUCCEEDED
(
hr
)
&&
(
NewPosition
.
u
.
HighPart
!=
0
||
NewPosition
.
QuadPart
>
actual_size
.
QuadPart
))
hr
=
WINCODEC_ERR_VALUEOUTOFRANGE
;
if
(
SUCCEEDED
(
hr
))
{
This
->
pos
.
QuadPart
=
NewPosition
.
QuadPart
;
if
(
plibNewPosition
)
plibNewPosition
->
QuadPart
=
This
->
pos
.
QuadPart
;
}
LeaveCriticalSection
(
&
This
->
lock
);
return
hr
;
}
/* SetSize isn't implemented in the native windowscodecs DLL either */
static
HRESULT
WINAPI
StreamOnStreamRange_SetSize
(
IStream
*
iface
,
ULARGE_INTEGER
libNewSize
)
{
TRACE
(
"(%p)
\n
"
,
iface
);
return
E_NOTIMPL
;
}
/* CopyTo isn't implemented in the native windowscodecs DLL either */
static
HRESULT
WINAPI
StreamOnStreamRange_CopyTo
(
IStream
*
iface
,
IStream
*
pstm
,
ULARGE_INTEGER
cb
,
ULARGE_INTEGER
*
pcbRead
,
ULARGE_INTEGER
*
pcbWritten
)
{
TRACE
(
"(%p)
\n
"
,
iface
);
return
E_NOTIMPL
;
}
/* Commit isn't implemented in the native windowscodecs DLL either */
static
HRESULT
WINAPI
StreamOnStreamRange_Commit
(
IStream
*
iface
,
DWORD
grfCommitFlags
)
{
TRACE
(
"(%p)
\n
"
,
iface
);
return
E_NOTIMPL
;
}
/* Revert isn't implemented in the native windowscodecs DLL either */
static
HRESULT
WINAPI
StreamOnStreamRange_Revert
(
IStream
*
iface
)
{
TRACE
(
"(%p)
\n
"
,
iface
);
return
E_NOTIMPL
;
}
/* LockRegion isn't implemented in the native windowscodecs DLL either */
static
HRESULT
WINAPI
StreamOnStreamRange_LockRegion
(
IStream
*
iface
,
ULARGE_INTEGER
libOffset
,
ULARGE_INTEGER
cb
,
DWORD
dwLockType
)
{
TRACE
(
"(%p)
\n
"
,
iface
);
return
E_NOTIMPL
;
}
/* UnlockRegion isn't implemented in the native windowscodecs DLL either */
static
HRESULT
WINAPI
StreamOnStreamRange_UnlockRegion
(
IStream
*
iface
,
ULARGE_INTEGER
libOffset
,
ULARGE_INTEGER
cb
,
DWORD
dwLockType
)
{
TRACE
(
"(%p)
\n
"
,
iface
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
StreamOnStreamRange_Stat
(
IStream
*
iface
,
STATSTG
*
pstatstg
,
DWORD
grfStatFlag
)
{
StreamOnStreamRange
*
This
=
(
StreamOnStreamRange
*
)
iface
;
HRESULT
hr
;
TRACE
(
"(%p)
\n
"
,
This
);
if
(
!
pstatstg
)
return
E_INVALIDARG
;
EnterCriticalSection
(
&
This
->
lock
);
hr
=
IStream_Stat
(
This
->
stream
,
pstatstg
,
grfStatFlag
);
if
(
SUCCEEDED
(
hr
))
{
pstatstg
->
cbSize
.
QuadPart
-=
This
->
offset
.
QuadPart
;
if
(
This
->
max_size
.
QuadPart
<
pstatstg
->
cbSize
.
QuadPart
)
pstatstg
->
cbSize
.
QuadPart
=
This
->
max_size
.
QuadPart
;
}
LeaveCriticalSection
(
&
This
->
lock
);
return
hr
;
}
/* Clone isn't implemented in the native windowscodecs DLL either */
static
HRESULT
WINAPI
StreamOnStreamRange_Clone
(
IStream
*
iface
,
IStream
**
ppstm
)
{
TRACE
(
"(%p)
\n
"
,
iface
);
return
E_NOTIMPL
;
}
const
IStreamVtbl
StreamOnStreamRange_Vtbl
=
{
/*** IUnknown methods ***/
StreamOnStreamRange_QueryInterface
,
StreamOnStreamRange_AddRef
,
StreamOnStreamRange_Release
,
/*** ISequentialStream methods ***/
StreamOnStreamRange_Read
,
StreamOnStreamRange_Write
,
/*** IStream methods ***/
StreamOnStreamRange_Seek
,
StreamOnStreamRange_SetSize
,
StreamOnStreamRange_CopyTo
,
StreamOnStreamRange_Commit
,
StreamOnStreamRange_Revert
,
StreamOnStreamRange_LockRegion
,
StreamOnStreamRange_UnlockRegion
,
StreamOnStreamRange_Stat
,
StreamOnStreamRange_Clone
,
};
/******************************************
* IWICStream implementation
* IWICStream implementation
*
*
*/
*/
...
@@ -516,8 +808,34 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromMemory(IWICStream *iface,
...
@@ -516,8 +808,34 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromMemory(IWICStream *iface,
static
HRESULT
WINAPI
IWICStreamImpl_InitializeFromIStreamRegion
(
IWICStream
*
iface
,
static
HRESULT
WINAPI
IWICStreamImpl_InitializeFromIStreamRegion
(
IWICStream
*
iface
,
IStream
*
pIStream
,
ULARGE_INTEGER
ulOffset
,
ULARGE_INTEGER
ulMaxSize
)
IStream
*
pIStream
,
ULARGE_INTEGER
ulOffset
,
ULARGE_INTEGER
ulMaxSize
)
{
{
FIXME
(
"(%p): stub
\n
"
,
iface
);
IWICStreamImpl
*
This
=
(
IWICStreamImpl
*
)
iface
;
return
E_NOTIMPL
;
StreamOnStreamRange
*
pObject
;
TRACE
(
"(%p,%p)
\n
"
,
iface
,
pIStream
);
if
(
!
pIStream
)
return
E_INVALIDARG
;
if
(
This
->
pStream
)
return
WINCODEC_ERR_WRONGSTATE
;
pObject
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
StreamOnStreamRange
));
if
(
!
pObject
)
return
E_OUTOFMEMORY
;
pObject
->
lpVtbl
=
&
StreamOnStreamRange_Vtbl
;
pObject
->
ref
=
1
;
IStream_AddRef
(
pIStream
);
pObject
->
stream
=
pIStream
;
pObject
->
pos
.
QuadPart
=
0
;
pObject
->
offset
=
ulOffset
;
pObject
->
max_size
=
ulMaxSize
;
InitializeCriticalSection
(
&
pObject
->
lock
);
pObject
->
lock
.
DebugInfo
->
Spare
[
0
]
=
(
DWORD_PTR
)(
__FILE__
": StreamOnStreamRange.lock"
);
if
(
InterlockedCompareExchangePointer
((
void
**
)
&
This
->
pStream
,
pObject
,
NULL
))
{
/* Some other thread set the stream first. */
IStream_Release
((
IStream
*
)
pObject
);
return
WINCODEC_ERR_WRONGSTATE
;
}
return
S_OK
;
}
}
...
...
dlls/windowscodecs/tests/stream.c
View file @
1ed39c29
...
@@ -359,7 +359,7 @@ static void test_StreamOnStreamRange(void)
...
@@ -359,7 +359,7 @@ static void test_StreamOnStreamRange(void)
uNewPos
.
QuadPart
=
20
;
uNewPos
.
QuadPart
=
20
;
uSize
.
QuadPart
=
20
;
uSize
.
QuadPart
=
20
;
hr
=
IWICStream_InitializeFromIStreamRegion
(
pSubStream
,
(
IStream
*
)
pStream
,
uNewPos
,
uSize
);
hr
=
IWICStream_InitializeFromIStreamRegion
(
pSubStream
,
(
IStream
*
)
pStream
,
uNewPos
,
uSize
);
todo_wine
ok
(
hr
==
S_OK
,
"InitializeFromIStreamRegion returned with %#x, expected %#x
\n
"
,
hr
,
S_OK
);
ok
(
hr
==
S_OK
,
"InitializeFromIStreamRegion returned with %#x, expected %#x
\n
"
,
hr
,
S_OK
);
if
(
FAILED
(
hr
))
{
if
(
FAILED
(
hr
))
{
skip
(
"InitializeFromIStreamRegion unimplemented
\n
"
);
skip
(
"InitializeFromIStreamRegion unimplemented
\n
"
);
IWICStream_Release
(
pSubStream
);
IWICStream_Release
(
pSubStream
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment