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
297c10a2
Commit
297c10a2
authored
Aug 14, 2012
by
Vincent Povirk
Committed by
Alexandre Julliard
Aug 15, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
windowscodecs: Implement IWICBitmap::Lock.
parent
3e36f1e4
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
201 additions
and
36 deletions
+201
-36
bitmap.c
dlls/windowscodecs/bitmap.c
+164
-2
bitmap.c
dlls/windowscodecs/tests/bitmap.c
+37
-34
No files found.
dlls/windowscodecs/bitmap.c
View file @
297c10a2
...
...
@@ -38,13 +38,151 @@ typedef struct BitmapImpl {
LONG
ref
;
IWICPalette
*
palette
;
int
palette_set
;
LONG
lock
;
/* 0 if not locked, -1 if locked for writing, count if locked for reading */
}
BitmapImpl
;
typedef
struct
BitmapLockImpl
{
IWICBitmapLock
IWICBitmapLock_iface
;
LONG
ref
;
BitmapImpl
*
parent
;
}
BitmapLockImpl
;
static
inline
BitmapImpl
*
impl_from_IWICBitmap
(
IWICBitmap
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
BitmapImpl
,
IWICBitmap_iface
);
}
static
inline
BitmapLockImpl
*
impl_from_IWICBitmapLock
(
IWICBitmapLock
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
BitmapLockImpl
,
IWICBitmapLock_iface
);
}
static
BOOL
BitmapImpl_AcquireLock
(
BitmapImpl
*
This
,
int
write
)
{
if
(
write
)
{
return
0
==
InterlockedCompareExchange
(
&
This
->
lock
,
-
1
,
0
);
}
else
{
while
(
1
)
{
LONG
prev_val
=
This
->
lock
;
if
(
prev_val
==
-
1
)
return
FALSE
;
if
(
prev_val
==
InterlockedCompareExchange
(
&
This
->
lock
,
prev_val
+
1
,
prev_val
))
return
TRUE
;
}
}
}
static
void
BitmapImpl_ReleaseLock
(
BitmapImpl
*
This
)
{
while
(
1
)
{
LONG
prev_val
=
This
->
lock
,
new_val
;
if
(
prev_val
==
-
1
)
new_val
=
0
;
else
new_val
=
prev_val
-
1
;
if
(
prev_val
==
InterlockedCompareExchange
(
&
This
->
lock
,
new_val
,
prev_val
))
break
;
}
}
static
HRESULT
WINAPI
BitmapLockImpl_QueryInterface
(
IWICBitmapLock
*
iface
,
REFIID
iid
,
void
**
ppv
)
{
BitmapLockImpl
*
This
=
impl_from_IWICBitmapLock
(
iface
);
TRACE
(
"(%p,%s,%p)
\n
"
,
iface
,
debugstr_guid
(
iid
),
ppv
);
if
(
!
ppv
)
return
E_INVALIDARG
;
if
(
IsEqualIID
(
&
IID_IUnknown
,
iid
)
||
IsEqualIID
(
&
IID_IWICBitmapLock
,
iid
))
{
*
ppv
=
&
This
->
IWICBitmapLock_iface
;
}
else
{
*
ppv
=
NULL
;
return
E_NOINTERFACE
;
}
IUnknown_AddRef
((
IUnknown
*
)
*
ppv
);
return
S_OK
;
}
static
ULONG
WINAPI
BitmapLockImpl_AddRef
(
IWICBitmapLock
*
iface
)
{
BitmapLockImpl
*
This
=
impl_from_IWICBitmapLock
(
iface
);
ULONG
ref
=
InterlockedIncrement
(
&
This
->
ref
);
TRACE
(
"(%p) refcount=%u
\n
"
,
iface
,
ref
);
return
ref
;
}
static
ULONG
WINAPI
BitmapLockImpl_Release
(
IWICBitmapLock
*
iface
)
{
BitmapLockImpl
*
This
=
impl_from_IWICBitmapLock
(
iface
);
ULONG
ref
=
InterlockedDecrement
(
&
This
->
ref
);
TRACE
(
"(%p) refcount=%u
\n
"
,
iface
,
ref
);
if
(
ref
==
0
)
{
BitmapImpl_ReleaseLock
(
This
->
parent
);
IWICBitmap_Release
(
&
This
->
parent
->
IWICBitmap_iface
);
HeapFree
(
GetProcessHeap
(),
0
,
This
);
}
return
ref
;
}
static
HRESULT
WINAPI
BitmapLockImpl_GetSize
(
IWICBitmapLock
*
iface
,
UINT
*
puiWidth
,
UINT
*
puiHeight
)
{
FIXME
(
"(%p,%p,%p)
\n
"
,
iface
,
puiWidth
,
puiHeight
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
BitmapLockImpl_GetStride
(
IWICBitmapLock
*
iface
,
UINT
*
pcbStride
)
{
FIXME
(
"(%p,%p)
\n
"
,
iface
,
pcbStride
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
BitmapLockImpl_GetDataPointer
(
IWICBitmapLock
*
iface
,
UINT
*
pcbBufferSize
,
BYTE
**
ppbData
)
{
FIXME
(
"(%p,%p,%p)
\n
"
,
iface
,
pcbBufferSize
,
ppbData
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
BitmapLockImpl_GetPixelFormat
(
IWICBitmapLock
*
iface
,
WICPixelFormatGUID
*
pPixelFormat
)
{
FIXME
(
"(%p,%p)
\n
"
,
iface
,
pPixelFormat
);
return
E_NOTIMPL
;
}
static
const
IWICBitmapLockVtbl
BitmapLockImpl_Vtbl
=
{
BitmapLockImpl_QueryInterface
,
BitmapLockImpl_AddRef
,
BitmapLockImpl_Release
,
BitmapLockImpl_GetSize
,
BitmapLockImpl_GetStride
,
BitmapLockImpl_GetDataPointer
,
BitmapLockImpl_GetPixelFormat
};
static
HRESULT
WINAPI
BitmapImpl_QueryInterface
(
IWICBitmap
*
iface
,
REFIID
iid
,
void
**
ppv
)
{
...
...
@@ -142,9 +280,32 @@ static HRESULT WINAPI BitmapImpl_CopyPixels(IWICBitmap *iface,
static
HRESULT
WINAPI
BitmapImpl_Lock
(
IWICBitmap
*
iface
,
const
WICRect
*
prcLock
,
DWORD
flags
,
IWICBitmapLock
**
ppILock
)
{
FIXME
(
"(%p,%p,%x,%p)
\n
"
,
iface
,
prcLock
,
flags
,
ppILock
);
BitmapImpl
*
This
=
impl_from_IWICBitmap
(
iface
);
BitmapLockImpl
*
result
;
return
E_NOTIMPL
;
TRACE
(
"(%p,%p,%x,%p)
\n
"
,
iface
,
prcLock
,
flags
,
ppILock
);
if
(
!
(
flags
&
(
WICBitmapLockRead
|
WICBitmapLockWrite
))
||
!
ppILock
)
return
E_INVALIDARG
;
result
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
BitmapLockImpl
));
if
(
!
result
)
return
E_OUTOFMEMORY
;
if
(
!
BitmapImpl_AcquireLock
(
This
,
flags
&
WICBitmapLockWrite
))
{
HeapFree
(
GetProcessHeap
(),
0
,
result
);
return
WINCODEC_ERR_ALREADYLOCKED
;
}
result
->
IWICBitmapLock_iface
.
lpVtbl
=
&
BitmapLockImpl_Vtbl
;
result
->
ref
=
1
;
result
->
parent
=
This
;
IWICBitmap_AddRef
(
&
This
->
IWICBitmap_iface
);
*
ppILock
=
&
result
->
IWICBitmapLock_iface
;
return
S_OK
;
}
static
HRESULT
WINAPI
BitmapImpl_SetPalette
(
IWICBitmap
*
iface
,
IWICPalette
*
pIPalette
)
...
...
@@ -211,6 +372,7 @@ HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight,
This
->
ref
=
1
;
This
->
palette
=
NULL
;
This
->
palette_set
=
0
;
This
->
lock
=
0
;
*
ppIBitmap
=
&
This
->
IWICBitmap_iface
;
...
...
dlls/windowscodecs/tests/bitmap.c
View file @
297c10a2
...
...
@@ -90,31 +90,30 @@ static void test_createbitmap(void)
for
(
i
=
0
;
i
<
27
;
i
++
)
ok
(
returned_data
[
i
]
==
0
,
"returned_data[%i] == %i
\n
"
,
i
,
returned_data
[
i
]);
todo_wine
{
/* Invalid lock rects */
rc
.
X
=
rc
.
Y
=
0
;
rc
.
Width
=
4
;
rc
.
Height
=
3
;
hr
=
IWICBitmap_Lock
(
bitmap
,
&
rc
,
WICBitmapLockRead
,
&
lock
);
ok
(
hr
==
E_INVALIDARG
,
"IWICBitmap_Lock failed hr=%x
\n
"
,
hr
);
todo_wine
ok
(
hr
==
E_INVALIDARG
,
"IWICBitmap_Lock failed hr=%x
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
IWICBitmapLock_Release
(
lock
);
rc
.
Width
=
3
;
rc
.
Height
=
4
;
hr
=
IWICBitmap_Lock
(
bitmap
,
&
rc
,
WICBitmapLockRead
,
&
lock
);
ok
(
hr
==
E_INVALIDARG
,
"IWICBitmap_Lock failed hr=%x
\n
"
,
hr
);
todo_wine
ok
(
hr
==
E_INVALIDARG
,
"IWICBitmap_Lock failed hr=%x
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
IWICBitmapLock_Release
(
lock
);
rc
.
Height
=
3
;
rc
.
X
=
4
;
hr
=
IWICBitmap_Lock
(
bitmap
,
&
rc
,
WICBitmapLockRead
,
&
lock
);
ok
(
hr
==
E_INVALIDARG
,
"IWICBitmap_Lock failed hr=%x
\n
"
,
hr
);
todo_wine
ok
(
hr
==
E_INVALIDARG
,
"IWICBitmap_Lock failed hr=%x
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
IWICBitmapLock_Release
(
lock
);
rc
.
X
=
0
;
rc
.
Y
=
4
;
hr
=
IWICBitmap_Lock
(
bitmap
,
&
rc
,
WICBitmapLockRead
,
&
lock
);
ok
(
hr
==
E_INVALIDARG
,
"IWICBitmap_Lock failed hr=%x
\n
"
,
hr
);
todo_wine
ok
(
hr
==
E_INVALIDARG
,
"IWICBitmap_Lock failed hr=%x
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
IWICBitmapLock_Release
(
lock
);
/* NULL lock rect */
...
...
@@ -125,9 +124,9 @@ todo_wine {
{
/* entire bitmap is locked */
hr
=
IWICBitmapLock_GetSize
(
lock
,
&
width
,
&
height
);
ok
(
hr
==
S_OK
,
"IWICBitmapLock_GetSize failed hr=%x
\n
"
,
hr
);
ok
(
width
==
3
,
"got %d, expected 3
\n
"
,
width
);
ok
(
height
==
3
,
"got %d, expected 3
\n
"
,
height
);
todo_wine
ok
(
hr
==
S_OK
,
"IWICBitmapLock_GetSize failed hr=%x
\n
"
,
hr
);
todo_wine
ok
(
width
==
3
,
"got %d, expected 3
\n
"
,
width
);
todo_wine
ok
(
height
==
3
,
"got %d, expected 3
\n
"
,
height
);
IWICBitmapLock_Release
(
lock
);
}
...
...
@@ -141,25 +140,25 @@ todo_wine {
if
(
SUCCEEDED
(
hr
))
{
hr
=
IWICBitmapLock_GetStride
(
lock
,
&
lock_buffer_stride
);
ok
(
hr
==
S_OK
,
"IWICBitmapLock_GetStride failed hr=%x
\n
"
,
hr
);
todo_wine
ok
(
hr
==
S_OK
,
"IWICBitmapLock_GetStride failed hr=%x
\n
"
,
hr
);
/* stride is divisible by 4 */
ok
(
lock_buffer_stride
==
12
,
"got %i, expected 12
\n
"
,
lock_buffer_stride
);
todo_wine
ok
(
lock_buffer_stride
==
12
,
"got %i, expected 12
\n
"
,
lock_buffer_stride
);
hr
=
IWICBitmapLock_GetDataPointer
(
lock
,
&
lock_buffer_size
,
&
lock_buffer
);
ok
(
hr
==
S_OK
,
"IWICBitmapLock_GetDataPointer failed hr=%x
\n
"
,
hr
);
todo_wine
ok
(
hr
==
S_OK
,
"IWICBitmapLock_GetDataPointer failed hr=%x
\n
"
,
hr
);
/* buffer size does not include padding from the last row */
ok
(
lock_buffer_size
==
33
,
"got %i, expected 33
\n
"
,
lock_buffer_size
);
ok
(
lock_buffer
!=
NULL
,
"got NULL data pointer
\n
"
);
todo_wine
ok
(
lock_buffer_size
==
33
,
"got %i, expected 33
\n
"
,
lock_buffer_size
);
todo_wine
ok
(
lock_buffer
!=
NULL
,
"got NULL data pointer
\n
"
);
base_lock_buffer
=
lock_buffer
;
hr
=
IWICBitmapLock_GetPixelFormat
(
lock
,
&
pixelformat
);
ok
(
hr
==
S_OK
,
"IWICBitmapLock_GetPixelFormat failed hr=%x
\n
"
,
hr
);
ok
(
IsEqualGUID
(
&
pixelformat
,
&
GUID_WICPixelFormat24bppBGR
),
"unexpected pixel format
\n
"
);
todo_wine
ok
(
hr
==
S_OK
,
"IWICBitmapLock_GetPixelFormat failed hr=%x
\n
"
,
hr
);
todo_wine
ok
(
IsEqualGUID
(
&
pixelformat
,
&
GUID_WICPixelFormat24bppBGR
),
"unexpected pixel format
\n
"
);
hr
=
IWICBitmapLock_GetSize
(
lock
,
&
width
,
&
height
);
ok
(
hr
==
S_OK
,
"IWICBitmapLock_GetSize failed hr=%x
\n
"
,
hr
);
ok
(
width
==
3
,
"got %d, expected 3
\n
"
,
width
);
ok
(
height
==
3
,
"got %d, expected 3
\n
"
,
height
);
todo_wine
ok
(
hr
==
S_OK
,
"IWICBitmapLock_GetSize failed hr=%x
\n
"
,
hr
);
todo_wine
ok
(
width
==
3
,
"got %d, expected 3
\n
"
,
width
);
todo_wine
ok
(
height
==
3
,
"got %d, expected 3
\n
"
,
height
);
/* We can have multiple simultaneous read locks */
hr
=
IWICBitmap_Lock
(
bitmap
,
&
rc
,
WICBitmapLockRead
,
&
lock2
);
...
...
@@ -168,8 +167,8 @@ todo_wine {
if
(
SUCCEEDED
(
hr
))
{
hr
=
IWICBitmapLock_GetDataPointer
(
lock2
,
&
lock_buffer_size
,
&
lock_buffer
);
ok
(
hr
==
S_OK
,
"IWICBitmapLock_GetDataPointer failed hr=%x
\n
"
,
hr
);
ok
(
lock_buffer_size
==
33
,
"got %i, expected 33
\n
"
,
lock_buffer_size
);
todo_wine
ok
(
hr
==
S_OK
,
"IWICBitmapLock_GetDataPointer failed hr=%x
\n
"
,
hr
);
todo_wine
ok
(
lock_buffer_size
==
33
,
"got %i, expected 33
\n
"
,
lock_buffer_size
);
ok
(
lock_buffer
==
base_lock_buffer
,
"got %p, expected %p
\n
"
,
lock_buffer
,
base_lock_buffer
);
IWICBitmapLock_Release
(
lock2
);
...
...
@@ -183,18 +182,21 @@ todo_wine {
}
/* But we don't need a write lock to write */
for
(
i
=
0
;
i
<
3
;
i
++
)
memcpy
(
base_lock_buffer
+
lock_buffer_stride
*
i
,
bitmap_data
+
i
*
9
,
9
);
if
(
base_lock_buffer
)
{
for
(
i
=
0
;
i
<
3
;
i
++
)
memcpy
(
base_lock_buffer
+
lock_buffer_stride
*
i
,
bitmap_data
+
i
*
9
,
9
);
}
IWICBitmapLock_Release
(
lock
);
}
/* test that the data we wrote is returned by CopyPixels */
hr
=
IWICBitmap_CopyPixels
(
bitmap
,
NULL
,
9
,
27
,
returned_data
);
ok
(
hr
==
S_OK
,
"IWICBitmap_CopyPixels failed hr=%x
\n
"
,
hr
);
todo_wine
ok
(
hr
==
S_OK
,
"IWICBitmap_CopyPixels failed hr=%x
\n
"
,
hr
);
for
(
i
=
0
;
i
<
27
;
i
++
)
ok
(
returned_data
[
i
]
==
bitmap_data
[
i
],
"returned_data[%i] == %i
\n
"
,
i
,
returned_data
[
i
]);
todo_wine
ok
(
returned_data
[
i
]
==
bitmap_data
[
i
],
"returned_data[%i] == %i
\n
"
,
i
,
returned_data
[
i
]);
/* try a valid partial rect, and write mode */
rc
.
X
=
2
;
...
...
@@ -217,26 +219,27 @@ todo_wine {
}
hr
=
IWICBitmapLock_GetStride
(
lock
,
&
lock_buffer_stride
);
ok
(
hr
==
S_OK
,
"IWICBitmapLock_GetStride failed hr=%x
\n
"
,
hr
);
ok
(
lock_buffer_stride
==
12
,
"got %i, expected 12
\n
"
,
lock_buffer_stride
);
todo_wine
ok
(
hr
==
S_OK
,
"IWICBitmapLock_GetStride failed hr=%x
\n
"
,
hr
);
todo_wine
ok
(
lock_buffer_stride
==
12
,
"got %i, expected 12
\n
"
,
lock_buffer_stride
);
hr
=
IWICBitmapLock_GetDataPointer
(
lock
,
&
lock_buffer_size
,
&
lock_buffer
);
ok
(
hr
==
S_OK
,
"IWICBitmapLock_GetDataPointer failed hr=%x
\n
"
,
hr
);
ok
(
lock_buffer_size
==
15
,
"got %i, expected 15
\n
"
,
lock_buffer_size
);
ok
(
lock_buffer
==
base_lock_buffer
+
6
,
"got %p, expected %p+6
\n
"
,
lock_buffer
,
base_lock_buffer
);
todo_wine
ok
(
hr
==
S_OK
,
"IWICBitmapLock_GetDataPointer failed hr=%x
\n
"
,
hr
);
todo_wine
ok
(
lock_buffer_size
==
15
,
"got %i, expected 15
\n
"
,
lock_buffer_size
);
todo_wine
ok
(
lock_buffer
==
base_lock_buffer
+
6
,
"got %p, expected %p+6
\n
"
,
lock_buffer
,
base_lock_buffer
);
hr
=
IWICBitmapLock_GetPixelFormat
(
lock
,
&
pixelformat
);
ok
(
hr
==
S_OK
,
"IWICBitmapLock_GetPixelFormat failed hr=%x
\n
"
,
hr
);
ok
(
IsEqualGUID
(
&
pixelformat
,
&
GUID_WICPixelFormat24bppBGR
),
"unexpected pixel format
\n
"
);
todo_wine
ok
(
hr
==
S_OK
,
"IWICBitmapLock_GetPixelFormat failed hr=%x
\n
"
,
hr
);
todo_wine
ok
(
IsEqualGUID
(
&
pixelformat
,
&
GUID_WICPixelFormat24bppBGR
),
"unexpected pixel format
\n
"
);
hr
=
IWICBitmapLock_GetSize
(
lock
,
&
width
,
&
height
);
ok
(
hr
==
S_OK
,
"IWICBitmapLock_GetSize failed hr=%x
\n
"
,
hr
);
ok
(
width
==
1
,
"got %d, expected 1
\n
"
,
width
);
ok
(
height
==
2
,
"got %d, expected 2
\n
"
,
height
);
todo_wine
ok
(
hr
==
S_OK
,
"IWICBitmapLock_GetSize failed hr=%x
\n
"
,
hr
);
todo_wine
ok
(
width
==
1
,
"got %d, expected 1
\n
"
,
width
);
todo_wine
ok
(
height
==
2
,
"got %d, expected 2
\n
"
,
height
);
IWICBitmapLock_Release
(
lock
);
}
todo_wine
{
hr
=
IWICBitmap_GetPixelFormat
(
bitmap
,
&
pixelformat
);
ok
(
hr
==
S_OK
,
"IWICBitmap_GetPixelFormat failed hr=%x
\n
"
,
hr
);
ok
(
IsEqualGUID
(
&
pixelformat
,
&
GUID_WICPixelFormat24bppBGR
),
"unexpected pixel format
\n
"
);
...
...
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