Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
e7f31ddb
Commit
e7f31ddb
authored
Jun 13, 2012
by
Vincent Povirk
Committed by
Alexandre Julliard
Jun 28, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
windowscodecs: Implement BitmapScaler_CopyPixels.
parent
22383aa6
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
199 additions
and
6 deletions
+199
-6
main.c
dlls/windowscodecs/main.c
+25
-0
scaler.c
dlls/windowscodecs/scaler.c
+172
-6
wincodecs_private.h
dlls/windowscodecs/wincodecs_private.h
+2
-0
No files found.
dlls/windowscodecs/main.c
View file @
e7f31ddb
...
...
@@ -17,6 +17,7 @@
*/
#define COBJMACROS
#include "config.h"
#include <stdarg.h>
...
...
@@ -136,3 +137,27 @@ void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT
}
}
}
HRESULT
get_pixelformat_bpp
(
const
GUID
*
pixelformat
,
UINT
*
bpp
)
{
HRESULT
hr
;
IWICComponentInfo
*
info
;
IWICPixelFormatInfo
*
formatinfo
;
hr
=
CreateComponentInfo
(
pixelformat
,
&
info
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
IWICComponentInfo_QueryInterface
(
info
,
&
IID_IWICPixelFormatInfo
,
(
void
**
)
&
formatinfo
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
IWICPixelFormatInfo_GetBitsPerPixel
(
formatinfo
,
bpp
);
IWICPixelFormatInfo_Release
(
formatinfo
);
}
IWICComponentInfo_Release
(
info
);
}
return
hr
;
}
dlls/windowscodecs/scaler.c
View file @
e7f31ddb
...
...
@@ -38,7 +38,11 @@ typedef struct BitmapScaler {
LONG
ref
;
IWICBitmapSource
*
source
;
UINT
width
,
height
;
UINT
src_width
,
src_height
;
WICBitmapInterpolationMode
mode
;
UINT
bpp
;
void
(
*
fn_get_required_source_rect
)(
struct
BitmapScaler
*
,
UINT
,
UINT
,
WICRect
*
);
void
(
*
fn_copy_scanline
)(
struct
BitmapScaler
*
,
UINT
,
UINT
,
UINT
,
BYTE
**
,
UINT
,
UINT
,
BYTE
*
);
CRITICAL_SECTION
lock
;
/* must be held when initialized */
}
BitmapScaler
;
...
...
@@ -162,12 +166,138 @@ static HRESULT WINAPI BitmapScaler_CopyPalette(IWICBitmapScaler *iface,
return
IWICBitmapSource_CopyPalette
(
This
->
source
,
pIPalette
);
}
static
void
NearestNeighbor_GetRequiredSourceRect
(
BitmapScaler
*
This
,
UINT
x
,
UINT
y
,
WICRect
*
src_rect
)
{
src_rect
->
X
=
x
*
This
->
src_width
/
This
->
width
;
src_rect
->
Y
=
y
*
This
->
src_height
/
This
->
height
;
src_rect
->
Width
=
src_rect
->
Height
=
1
;
}
static
void
NearestNeighbor_CopyScanline
(
BitmapScaler
*
This
,
UINT
dst_x
,
UINT
dst_y
,
UINT
dst_width
,
BYTE
**
src_data
,
UINT
src_data_x
,
UINT
src_data_y
,
BYTE
*
pbBuffer
)
{
int
i
;
UINT
bytesperpixel
=
This
->
bpp
/
8
;
UINT
src_x
,
src_y
;
src_y
=
dst_y
*
This
->
src_height
/
This
->
height
-
src_data_y
;
for
(
i
=
0
;
i
<
dst_width
;
i
++
)
{
src_x
=
(
dst_x
+
i
)
*
This
->
src_width
/
This
->
width
-
src_data_x
;
memcpy
(
pbBuffer
+
bytesperpixel
*
i
,
src_data
[
src_y
]
+
bytesperpixel
*
src_x
,
bytesperpixel
);
}
}
static
HRESULT
WINAPI
BitmapScaler_CopyPixels
(
IWICBitmapScaler
*
iface
,
const
WICRect
*
prc
,
UINT
cbStride
,
UINT
cbBufferSize
,
BYTE
*
pbBuffer
)
{
FIXME
(
"(%p,%p,%u,%u,%p): stub
\n
"
,
iface
,
prc
,
cbStride
,
cbBufferSize
,
pbBuffer
);
BitmapScaler
*
This
=
impl_from_IWICBitmapScaler
(
iface
);
HRESULT
hr
;
WICRect
dest_rect
;
WICRect
src_rect_ul
,
src_rect_br
,
src_rect
;
BYTE
**
src_rows
;
BYTE
*
src_bits
;
ULONG
bytesperrow
;
ULONG
src_bytesperrow
;
ULONG
buffer_size
;
UINT
y
;
TRACE
(
"(%p,%p,%u,%u,%p)
\n
"
,
iface
,
prc
,
cbStride
,
cbBufferSize
,
pbBuffer
);
EnterCriticalSection
(
&
This
->
lock
);
if
(
!
This
->
source
)
{
hr
=
WINCODEC_ERR_WRONGSTATE
;
goto
end
;
}
if
(
prc
)
dest_rect
=
*
prc
;
else
{
dest_rect
.
X
=
dest_rect
.
Y
=
0
;
dest_rect
.
Width
=
This
->
width
;
dest_rect
.
Height
=
This
->
height
;
}
if
(
dest_rect
.
X
<
0
||
dest_rect
.
Y
<
0
||
dest_rect
.
X
+
dest_rect
.
Width
>
This
->
width
||
dest_rect
.
Y
+
dest_rect
.
Height
>
This
->
height
)
{
hr
=
E_INVALIDARG
;
goto
end
;
}
bytesperrow
=
((
This
->
bpp
*
dest_rect
.
Width
)
+
7
)
/
8
;
if
(
cbStride
<
bytesperrow
)
{
hr
=
E_INVALIDARG
;
goto
end
;
}
return
E_NOTIMPL
;
if
((
cbStride
*
dest_rect
.
Height
)
>
cbBufferSize
)
{
hr
=
E_INVALIDARG
;
goto
end
;
}
/* MSDN recommends calling CopyPixels once for each scanline from top to
* bottom, and claims codecs optimize for this. Ideally, when called in this
* way, we should avoid requesting a scanline from the source more than
* once, by saving the data that will be useful for the next scanline after
* the call returns. The GetRequiredSourceRect/CopyScanline functions are
* designed to make it possible to do this in a generic way, but for now we
* just grab all the data we need in each call. */
This
->
fn_get_required_source_rect
(
This
,
dest_rect
.
X
,
dest_rect
.
Y
,
&
src_rect_ul
);
This
->
fn_get_required_source_rect
(
This
,
dest_rect
.
X
+
dest_rect
.
Width
-
1
,
dest_rect
.
Y
+
dest_rect
.
Height
-
1
,
&
src_rect_br
);
src_rect
.
X
=
src_rect_ul
.
X
;
src_rect
.
Y
=
src_rect_ul
.
Y
;
src_rect
.
Width
=
src_rect_br
.
Width
+
src_rect_br
.
X
-
src_rect_ul
.
X
;
src_rect
.
Height
=
src_rect_br
.
Height
+
src_rect_br
.
Y
-
src_rect_ul
.
Y
;
src_bytesperrow
=
(
src_rect
.
Width
*
This
->
bpp
+
7
)
/
8
;
buffer_size
=
src_bytesperrow
*
src_rect
.
Height
;
src_rows
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
BYTE
*
)
*
src_rect
.
Height
);
src_bits
=
HeapAlloc
(
GetProcessHeap
(),
0
,
buffer_size
);
if
(
!
src_rows
||
!
src_bits
)
{
HeapFree
(
GetProcessHeap
(),
0
,
src_rows
);
HeapFree
(
GetProcessHeap
(),
0
,
src_bits
);
hr
=
E_OUTOFMEMORY
;
goto
end
;
}
for
(
y
=
0
;
y
<
src_rect
.
Height
;
y
++
)
src_rows
[
y
]
=
src_bits
+
y
*
src_bytesperrow
;
hr
=
IWICBitmapSource_CopyPixels
(
This
->
source
,
&
src_rect
,
src_bytesperrow
,
buffer_size
,
src_bits
);
if
(
SUCCEEDED
(
hr
))
{
for
(
y
=
0
;
y
<
dest_rect
.
Height
;
y
++
)
{
This
->
fn_copy_scanline
(
This
,
dest_rect
.
X
,
dest_rect
.
Y
+
y
,
dest_rect
.
Width
,
src_rows
,
src_rect
.
X
,
src_rect
.
Y
,
pbBuffer
+
cbStride
*
y
);
}
}
HeapFree
(
GetProcessHeap
(),
0
,
src_rows
);
HeapFree
(
GetProcessHeap
(),
0
,
src_bits
);
end:
LeaveCriticalSection
(
&
This
->
lock
);
return
hr
;
}
static
HRESULT
WINAPI
BitmapScaler_Initialize
(
IWICBitmapScaler
*
iface
,
...
...
@@ -175,7 +305,8 @@ static HRESULT WINAPI BitmapScaler_Initialize(IWICBitmapScaler *iface,
WICBitmapInterpolationMode
mode
)
{
BitmapScaler
*
This
=
impl_from_IWICBitmapScaler
(
iface
);
HRESULT
hr
=
S_OK
;
HRESULT
hr
;
GUID
src_pixelformat
;
TRACE
(
"(%p,%p,%u,%u,%u)
\n
"
,
iface
,
pISource
,
uiWidth
,
uiHeight
,
mode
);
...
...
@@ -187,13 +318,45 @@ static HRESULT WINAPI BitmapScaler_Initialize(IWICBitmapScaler *iface,
goto
end
;
}
IWICBitmapSource_AddRef
(
pISource
);
This
->
source
=
pISource
;
This
->
width
=
uiWidth
;
This
->
height
=
uiHeight
;
This
->
mode
=
mode
;
hr
=
IWICBitmapSource_GetSize
(
pISource
,
&
This
->
src_width
,
&
This
->
src_height
);
if
(
SUCCEEDED
(
hr
))
hr
=
IWICBitmapSource_GetPixelFormat
(
pISource
,
&
src_pixelformat
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
get_pixelformat_bpp
(
&
src_pixelformat
,
&
This
->
bpp
);
}
if
(
SUCCEEDED
(
hr
))
{
switch
(
mode
)
{
default:
FIXME
(
"unsupported mode %i
\n
"
,
mode
);
/* fall-through */
case
WICBitmapInterpolationModeNearestNeighbor
:
if
((
This
->
bpp
%
8
)
==
0
)
{
IWICBitmapSource_AddRef
(
pISource
);
This
->
source
=
pISource
;
}
else
{
hr
=
WICConvertBitmapSource
(
&
GUID_WICPixelFormat32bppBGRA
,
pISource
,
&
This
->
source
);
This
->
bpp
=
32
;
}
This
->
fn_get_required_source_rect
=
NearestNeighbor_GetRequiredSourceRect
;
This
->
fn_copy_scanline
=
NearestNeighbor_CopyScanline
;
break
;
}
}
end:
LeaveCriticalSection
(
&
This
->
lock
);
...
...
@@ -224,7 +387,10 @@ HRESULT BitmapScaler_Create(IWICBitmapScaler **scaler)
This
->
source
=
NULL
;
This
->
width
=
0
;
This
->
height
=
0
;
This
->
src_width
=
0
;
This
->
src_height
=
0
;
This
->
mode
=
0
;
This
->
bpp
=
0
;
InitializeCriticalSection
(
&
This
->
lock
);
This
->
lock
.
DebugInfo
->
Spare
[
0
]
=
(
DWORD_PTR
)(
__FILE__
": BitmapScaler.lock"
);
...
...
dlls/windowscodecs/wincodecs_private.h
View file @
e7f31ddb
...
...
@@ -55,6 +55,8 @@ extern HRESULT copy_pixels(UINT bpp, const BYTE *srcbuffer,
extern
void
reverse_bgr8
(
UINT
bytesperpixel
,
LPBYTE
bits
,
UINT
width
,
UINT
height
,
INT
stride
)
DECLSPEC_HIDDEN
;
extern
HRESULT
get_pixelformat_bpp
(
const
GUID
*
pixelformat
,
UINT
*
bpp
)
DECLSPEC_HIDDEN
;
extern
HRESULT
CreatePropertyBag2
(
IPropertyBag2
**
ppPropertyBag2
)
DECLSPEC_HIDDEN
;
extern
HRESULT
CreateComponentInfo
(
REFCLSID
clsid
,
IWICComponentInfo
**
ppIInfo
)
DECLSPEC_HIDDEN
;
...
...
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