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
e4a3ad81
Commit
e4a3ad81
authored
Aug 24, 2009
by
Vincent Povirk
Committed by
Alexandre Julliard
Sep 02, 2009
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdiplus: Use WIC to encode images.
parent
e5d2a693
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
127 additions
and
86 deletions
+127
-86
image.c
dlls/gdiplus/image.c
+127
-86
No files found.
dlls/gdiplus/image.c
View file @
e4a3ad81
...
...
@@ -1623,8 +1623,8 @@ static GpStatus decode_image_olepicture_metafile(IStream* stream, REFCLSID clsid
return
Ok
;
}
typedef
GpStatus
(
*
encode_image_func
)(
LPVOID
bitmap_bits
,
LPBITMAPINFO
bitmap_info
,
void
**
output
,
unsigned
int
*
output_size
);
typedef
GpStatus
(
*
encode_image_func
)(
GpImage
*
image
,
IStream
*
stream
,
GDIPCONST
CLSID
*
clsid
,
GDIPCONST
EncoderParameters
*
params
);
typedef
GpStatus
(
*
decode_image_func
)(
IStream
*
stream
,
REFCLSID
clsid
,
GpImage
**
image
);
...
...
@@ -1771,48 +1771,138 @@ GpStatus WINGDIPAPI GdipSaveImageToFile(GpImage *image, GDIPCONST WCHAR* filenam
#define BITMAP_FORMAT_PNG 0x5089
#define BITMAP_FORMAT_APM 0xcdd7
static
GpStatus
encode_image_
BMP
(
LPVOID
bitmap_bits
,
LPBITMAPINFO
bitmap_info
,
void
**
output
,
unsigned
int
*
output_size
)
static
GpStatus
encode_image_
WIC
(
GpImage
*
image
,
IStream
*
stream
,
GDIPCONST
CLSID
*
clsid
,
GDIPCONST
EncoderParameters
*
params
)
{
int
num_palette_entries
;
BITMAPFILEHEADER
*
bmp_file_hdr
;
BITMAPINFO
*
bmp_info_hdr
;
GpStatus
stat
;
GpBitmap
*
bitmap
;
IWICBitmapEncoder
*
encoder
;
IWICBitmapFrameEncode
*
frameencode
;
IPropertyBag2
*
encoderoptions
;
HRESULT
hr
;
UINT
width
,
height
;
PixelFormat
gdipformat
=
0
;
WICPixelFormatGUID
wicformat
;
GpRect
rc
;
BitmapData
lockeddata
;
HRESULT
initresult
;
UINT
i
;
if
(
bitmap_info
->
bmiHeader
.
biClrUsed
)
{
num_palette_entries
=
bitmap_info
->
bmiHeader
.
biClrUsed
;
if
(
num_palette_entries
>
256
)
num_palette_entries
=
256
;
}
else
{
if
(
bitmap_info
->
bmiHeader
.
biBitCount
<=
8
)
num_palette_entries
=
1
<<
bitmap_info
->
bmiHeader
.
biBitCount
;
else
num_palette_entries
=
0
;
if
(
image
->
type
!=
ImageTypeBitmap
)
return
GenericError
;
bitmap
=
(
GpBitmap
*
)
image
;
GdipGetImageWidth
(
image
,
&
width
);
GdipGetImageHeight
(
image
,
&
height
);
rc
.
X
=
0
;
rc
.
Y
=
0
;
rc
.
Width
=
width
;
rc
.
Height
=
height
;
initresult
=
CoInitialize
(
NULL
);
hr
=
CoCreateInstance
(
clsid
,
NULL
,
CLSCTX_INPROC_SERVER
,
&
IID_IWICBitmapEncoder
,
(
void
**
)
&
encoder
);
if
(
FAILED
(
hr
))
{
if
(
SUCCEEDED
(
initresult
))
CoUninitialize
();
return
hresult_to_status
(
hr
);
}
*
output_size
=
sizeof
(
BITMAPFILEHEADER
)
+
sizeof
(
BITMAPINFOHEADER
)
+
num_palette_entries
*
sizeof
(
RGBQUAD
)
+
bitmap_info
->
bmiHeader
.
biSizeImage
;
hr
=
IWICBitmapEncoder_Initialize
(
encoder
,
stream
,
WICBitmapEncoderNoCache
);
*
output
=
GdipAlloc
(
*
output_size
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
IWICBitmapEncoder_CreateNewFrame
(
encoder
,
&
frameencode
,
&
encoderoptions
);
}
bmp_file_hdr
=
*
output
;
bmp_file_hdr
->
bfType
=
BITMAP_FORMAT_BMP
;
bmp_file_hdr
->
bfSize
=
*
output_size
;
bmp_file_hdr
->
bfOffBits
=
sizeof
(
BITMAPFILEHEADER
)
+
sizeof
(
BITMAPINFOHEADER
)
+
num_palette_entries
*
sizeof
(
RGBQUAD
);
if
(
SUCCEEDED
(
hr
))
/* created frame */
{
hr
=
IWICBitmapFrameEncode_Initialize
(
frameencode
,
encoderoptions
);
bmp_info_hdr
=
(
BITMAPINFO
*
)
((
unsigned
char
*
)(
*
output
)
+
sizeof
(
BITMAPFILEHEADER
));
memcpy
(
bmp_info_hdr
,
bitmap_info
,
sizeof
(
BITMAPINFOHEADER
)
+
num_palette_entries
*
sizeof
(
RGBQUAD
));
memcpy
((
unsigned
char
*
)(
*
output
)
+
sizeof
(
BITMAPFILEHEADER
)
+
sizeof
(
BITMAPINFOHEADER
)
+
num_palette_entries
*
sizeof
(
RGBQUAD
),
bitmap_bits
,
bitmap_info
->
bmiHeader
.
biSizeImage
);
if
(
SUCCEEDED
(
hr
))
hr
=
IWICBitmapFrameEncode_SetSize
(
frameencode
,
width
,
height
);
return
Ok
;
if
(
SUCCEEDED
(
hr
))
/* FIXME: use the resolution from the image */
hr
=
IWICBitmapFrameEncode_SetResolution
(
frameencode
,
96
.
0
,
96
.
0
);
if
(
SUCCEEDED
(
hr
))
{
for
(
i
=
0
;
wic_pixel_formats
[
i
];
i
++
)
{
if
(
wic_gdip_formats
[
i
]
==
bitmap
->
format
)
break
;
}
if
(
wic_pixel_formats
[
i
])
memcpy
(
&
wicformat
,
wic_pixel_formats
[
i
],
sizeof
(
GUID
));
else
memcpy
(
&
wicformat
,
&
GUID_WICPixelFormat32bppBGRA
,
sizeof
(
GUID
));
hr
=
IWICBitmapFrameEncode_SetPixelFormat
(
frameencode
,
&
wicformat
);
for
(
i
=
0
;
wic_pixel_formats
[
i
];
i
++
)
{
if
(
IsEqualGUID
(
&
wicformat
,
wic_pixel_formats
[
i
]))
break
;
}
if
(
wic_pixel_formats
[
i
])
gdipformat
=
wic_gdip_formats
[
i
];
else
{
ERR
(
"cannot provide pixel format %s
\n
"
,
debugstr_guid
(
&
wicformat
));
hr
=
E_FAIL
;
}
}
if
(
SUCCEEDED
(
hr
))
{
stat
=
GdipBitmapLockBits
(
bitmap
,
&
rc
,
ImageLockModeRead
,
gdipformat
,
&
lockeddata
);
if
(
stat
==
Ok
)
{
UINT
row_size
=
(
lockeddata
.
Width
*
PIXELFORMATBPP
(
gdipformat
)
+
7
)
/
8
;
BYTE
*
row
;
/* write one row at a time in case stride is negative */
row
=
lockeddata
.
Scan0
;
for
(
i
=
0
;
i
<
lockeddata
.
Height
;
i
++
)
{
hr
=
IWICBitmapFrameEncode_WritePixels
(
frameencode
,
1
,
row_size
,
row_size
,
row
);
if
(
FAILED
(
hr
))
break
;
row
+=
lockeddata
.
Stride
;
}
GdipBitmapUnlockBits
(
bitmap
,
&
lockeddata
);
}
else
hr
=
E_FAIL
;
}
if
(
SUCCEEDED
(
hr
))
hr
=
IWICBitmapFrameEncode_Commit
(
frameencode
);
IWICBitmapFrameEncode_Release
(
frameencode
);
IPropertyBag2_Release
(
encoderoptions
);
}
if
(
SUCCEEDED
(
hr
))
hr
=
IWICBitmapEncoder_Commit
(
encoder
);
IWICBitmapEncoder_Release
(
encoder
);
if
(
SUCCEEDED
(
initresult
))
CoUninitialize
();
return
hresult_to_status
(
hr
);
}
static
GpStatus
encode_image_BMP
(
GpImage
*
image
,
IStream
*
stream
,
GDIPCONST
CLSID
*
clsid
,
GDIPCONST
EncoderParameters
*
params
)
{
return
encode_image_WIC
(
image
,
stream
,
&
CLSID_WICBmpEncoder
,
params
);
}
/*****************************************************************************
...
...
@@ -1822,30 +1912,14 @@ GpStatus WINGDIPAPI GdipSaveImageToStream(GpImage *image, IStream* stream,
GDIPCONST
CLSID
*
clsid
,
GDIPCONST
EncoderParameters
*
params
)
{
GpStatus
stat
;
HBITMAP
hbmp
;
HBITMAP
old_hbmp
;
HDC
hdc
;
int
bm_is_selected
;
BITMAPINFO
bmp_info
;
LPVOID
bmp_bits
;
encode_image_func
encode_image
;
LPVOID
output
;
unsigned
int
output_size
;
unsigned
int
dummy
;
int
i
;
old_hbmp
=
0
;
output
=
NULL
;
output_size
=
0
;
TRACE
(
"%p %p %p %p
\n
"
,
image
,
stream
,
clsid
,
params
);
if
(
!
image
||
!
stream
)
return
InvalidParameter
;
if
(
image
->
type
!=
ImageTypeBitmap
)
return
GenericError
;
/* select correct encoder */
encode_image
=
NULL
;
for
(
i
=
0
;
i
<
NUM_CODECS
;
i
++
)
{
...
...
@@ -1856,40 +1930,7 @@ GpStatus WINGDIPAPI GdipSaveImageToStream(GpImage *image, IStream* stream,
if
(
encode_image
==
NULL
)
return
UnknownImageFormat
;
hbmp
=
((
GpBitmap
*
)
image
)
->
hbitmap
;
if
(
!
hbmp
)
return
GenericError
;
hdc
=
((
GpBitmap
*
)
image
)
->
hdc
;
bm_is_selected
=
(
hdc
!=
0
);
if
(
!
bm_is_selected
)
{
hdc
=
CreateCompatibleDC
(
0
);
old_hbmp
=
SelectObject
(
hdc
,
hbmp
);
}
/* get bits from HBITMAP */
bmp_info
.
bmiHeader
.
biSize
=
sizeof
(
bmp_info
.
bmiHeader
);
bmp_info
.
bmiHeader
.
biBitCount
=
0
;
GetDIBits
(
hdc
,
hbmp
,
0
,
0
,
NULL
,
&
bmp_info
,
DIB_RGB_COLORS
);
bmp_bits
=
GdipAlloc
(
bmp_info
.
bmiHeader
.
biSizeImage
);
if
(
bmp_bits
)
GetDIBits
(
hdc
,
hbmp
,
0
,
abs
(
bmp_info
.
bmiHeader
.
biHeight
),
bmp_bits
,
&
bmp_info
,
DIB_RGB_COLORS
);
if
(
!
bm_is_selected
)
{
SelectObject
(
hdc
,
old_hbmp
);
DeleteDC
(
hdc
);
}
if
(
!
bmp_bits
)
return
OutOfMemory
;
stat
=
encode_image
(
bmp_bits
,
&
bmp_info
,
&
output
,
&
output_size
);
if
(
stat
==
Ok
)
IStream_Write
(
stream
,
output
,
output_size
,
&
dummy
);
GdipFree
(
output
);
GdipFree
(
bmp_bits
);
stat
=
encode_image
(
image
,
stream
,
clsid
,
params
);
return
stat
;
}
...
...
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