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
4d55359f
Commit
4d55359f
authored
Sep 16, 2010
by
Vincent Povirk
Committed by
Alexandre Julliard
Sep 22, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
windowscodecs: Use the BMP decoder to decode ICO frames.
parent
870afcdd
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
165 additions
and
354 deletions
+165
-354
icoformat.c
dlls/windowscodecs/icoformat.c
+164
-353
icoformat.c
dlls/windowscodecs/tests/icoformat.c
+1
-1
No files found.
dlls/windowscodecs/icoformat.c
View file @
4d55359f
...
@@ -68,8 +68,7 @@ typedef struct {
...
@@ -68,8 +68,7 @@ typedef struct {
typedef
struct
{
typedef
struct
{
const
IWICBitmapFrameDecodeVtbl
*
lpVtbl
;
const
IWICBitmapFrameDecodeVtbl
*
lpVtbl
;
LONG
ref
;
LONG
ref
;
ICONDIRENTRY
entry
;
UINT
width
,
height
;
IcoDecoder
*
parent
;
BYTE
*
bits
;
BYTE
*
bits
;
}
IcoFrameDecode
;
}
IcoFrameDecode
;
...
@@ -116,7 +115,6 @@ static ULONG WINAPI IcoFrameDecode_Release(IWICBitmapFrameDecode *iface)
...
@@ -116,7 +115,6 @@ static ULONG WINAPI IcoFrameDecode_Release(IWICBitmapFrameDecode *iface)
if
(
ref
==
0
)
if
(
ref
==
0
)
{
{
IUnknown_Release
((
IUnknown
*
)
This
->
parent
);
HeapFree
(
GetProcessHeap
(),
0
,
This
->
bits
);
HeapFree
(
GetProcessHeap
(),
0
,
This
->
bits
);
HeapFree
(
GetProcessHeap
(),
0
,
This
);
HeapFree
(
GetProcessHeap
(),
0
,
This
);
}
}
...
@@ -129,8 +127,8 @@ static HRESULT WINAPI IcoFrameDecode_GetSize(IWICBitmapFrameDecode *iface,
...
@@ -129,8 +127,8 @@ static HRESULT WINAPI IcoFrameDecode_GetSize(IWICBitmapFrameDecode *iface,
{
{
IcoFrameDecode
*
This
=
(
IcoFrameDecode
*
)
iface
;
IcoFrameDecode
*
This
=
(
IcoFrameDecode
*
)
iface
;
*
puiWidth
=
This
->
entry
.
bWidth
?
This
->
entry
.
bWidth
:
256
;
*
puiWidth
=
This
->
width
;
*
puiHeight
=
This
->
entry
.
bHeight
?
This
->
entry
.
bHeight
:
256
;
*
puiHeight
=
This
->
height
;
TRACE
(
"(%p) -> (%i,%i)
\n
"
,
iface
,
*
puiWidth
,
*
puiHeight
);
TRACE
(
"(%p) -> (%i,%i)
\n
"
,
iface
,
*
puiWidth
,
*
puiHeight
);
...
@@ -158,416 +156,193 @@ static HRESULT WINAPI IcoFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
...
@@ -158,416 +156,193 @@ static HRESULT WINAPI IcoFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
return
WINCODEC_ERR_PALETTEUNAVAILABLE
;
return
WINCODEC_ERR_PALETTEUNAVAILABLE
;
}
}
static
inline
void
pixel_set_trans
(
DWORD
*
pixel
,
BOOL
transparent
)
static
HRESULT
WINAPI
IcoFrameDecode_CopyPixels
(
IWICBitmapFrameDecode
*
iface
,
const
WICRect
*
prc
,
UINT
cbStride
,
UINT
cbBufferSize
,
BYTE
*
pbBuffer
)
{
{
if
(
transparent
)
*
pixel
=
0
;
IcoFrameDecode
*
This
=
(
IcoFrameDecode
*
)
iface
;
else
*
pixel
|=
0xff000000
;
TRACE
(
"(%p,%p,%u,%u,%p)
\n
"
,
iface
,
prc
,
cbStride
,
cbBufferSize
,
pbBuffer
);
return
copy_pixels
(
32
,
This
->
bits
,
This
->
width
,
This
->
height
,
This
->
width
*
4
,
prc
,
cbStride
,
cbBufferSize
,
pbBuffer
);
}
}
static
HRESULT
IcoFrameDecode_ReadPixels
(
IcoFrameDecode
*
This
)
static
HRESULT
WINAPI
IcoFrameDecode_GetMetadataQueryReader
(
IWICBitmapFrameDecode
*
iface
,
IWICMetadataQueryReader
**
ppIMetadataQueryReader
)
{
{
BITMAPINFOHEADER
bih
;
TRACE
(
"(%p,%p)
\n
"
,
iface
,
ppIMetadataQueryReader
);
DWORD
colors
[
256
];
return
WINCODEC_ERR_UNSUPPORTEDOPERATION
;
UINT
colorcount
=
0
;
}
LARGE_INTEGER
seek
;
ULONG
bytesread
;
HRESULT
hr
;
BYTE
*
tempdata
=
NULL
;
BYTE
*
bits
=
NULL
;
UINT
bitsStride
;
UINT
bitsSize
;
UINT
width
,
height
;
width
=
This
->
entry
.
bWidth
?
This
->
entry
.
bWidth
:
256
;
height
=
This
->
entry
.
bHeight
?
This
->
entry
.
bHeight
:
256
;
/* read the BITMAPINFOHEADER */
seek
.
QuadPart
=
This
->
entry
.
dwDIBOffset
;
hr
=
IStream_Seek
(
This
->
parent
->
stream
,
seek
,
STREAM_SEEK_SET
,
NULL
);
if
(
FAILED
(
hr
))
goto
fail
;
hr
=
IStream_Read
(
This
->
parent
->
stream
,
&
bih
,
sizeof
(
BITMAPINFOHEADER
),
&
bytesread
);
if
(
FAILED
(
hr
)
||
bytesread
!=
sizeof
(
BITMAPINFOHEADER
))
goto
fail
;
if
(
bih
.
biBitCount
<=
8
)
{
/* read the palette */
colorcount
=
bih
.
biClrUsed
?
bih
.
biClrUsed
:
1
<<
bih
.
biBitCount
;
hr
=
IStream_Read
(
This
->
parent
->
stream
,
colors
,
sizeof
(
RGBQUAD
)
*
colorcount
,
&
bytesread
);
static
HRESULT
WINAPI
IcoFrameDecode_GetColorContexts
(
IWICBitmapFrameDecode
*
iface
,
if
(
FAILED
(
hr
)
||
bytesread
!=
sizeof
(
RGBQUAD
)
*
colorcount
)
goto
fail
;
UINT
cCount
,
IWICColorContext
**
ppIColorContexts
,
UINT
*
pcActualCount
)
}
{
TRACE
(
"(%p,%u,%p,%p)
\n
"
,
iface
,
cCount
,
ppIColorContexts
,
pcActualCount
);
return
WINCODEC_ERR_UNSUPPORTEDOPERATION
;
}
bitsStride
=
width
*
4
;
static
HRESULT
WINAPI
IcoFrameDecode_GetThumbnail
(
IWICBitmapFrameDecode
*
iface
,
bitsSize
=
bitsStride
*
height
;
IWICBitmapSource
**
ppIThumbnail
)
{
TRACE
(
"(%p,%p)
\n
"
,
iface
,
ppIThumbnail
);
return
WINCODEC_ERR_CODECNOTHUMBNAIL
;
}
/* read the XOR data */
static
const
IWICBitmapFrameDecodeVtbl
IcoFrameDecode_Vtbl
=
{
switch
(
bih
.
biBitCount
)
IcoFrameDecode_QueryInterface
,
{
IcoFrameDecode_AddRef
,
case
1
:
IcoFrameDecode_Release
,
{
IcoFrameDecode_GetSize
,
UINT
xorBytesPerRow
=
(
width
+
31
)
/
32
*
4
;
IcoFrameDecode_GetPixelFormat
,
UINT
xorBytes
=
xorBytesPerRow
*
height
;
IcoFrameDecode_GetResolution
,
INT
xorStride
;
IcoFrameDecode_CopyPalette
,
BYTE
*
xorRow
;
IcoFrameDecode_CopyPixels
,
BYTE
*
bitsRow
;
IcoFrameDecode_GetMetadataQueryReader
,
UINT
x
,
y
;
IcoFrameDecode_GetColorContexts
,
IcoFrameDecode_GetThumbnail
};
tempdata
=
HeapAlloc
(
GetProcessHeap
(),
0
,
xorBytes
);
static
inline
void
pixel_set_trans
(
DWORD
*
pixel
,
BOOL
transparent
)
if
(
!
tempdata
)
{
{
if
(
transparent
)
*
pixel
=
0
;
hr
=
E_OUTOFMEMORY
;
else
*
pixel
|=
0xff000000
;
goto
fail
;
}
}
hr
=
IStream_Read
(
This
->
parent
->
stream
,
tempdata
,
xorBytes
,
&
bytesread
);
static
HRESULT
ReadIcoDib
(
IStream
*
stream
,
IcoFrameDecode
*
result
)
if
(
FAILED
(
hr
)
||
bytesread
!=
xorBytes
)
goto
fail
;
{
HRESULT
hr
;
IWICBitmapDecoder
*
decoder
;
IWICBitmapFrameDecode
*
framedecode
;
WICPixelFormatGUID
pixelformat
;
IWICBitmapSource
*
source
;
int
has_alpha
=
FALSE
;
/* if TRUE, alpha data might be in the image data */
WICRect
rc
;
if
(
bih
.
biHeight
>
0
)
/* bottom-up DIB */
hr
=
IcoDibDecoder_CreateInstance
(
NULL
,
&
IID_IWICBitmapDecoder
,
(
void
**
)
&
decoder
);
if
(
SUCCEEDED
(
hr
))
{
{
xorStride
=
-
xorBytesPerRow
;
hr
=
IWICBitmapDecoder_Initialize
(
decoder
,
stream
,
WICDecodeMetadataCacheOnLoad
);
xorRow
=
tempdata
+
(
height
-
1
)
*
xorBytesPerRow
;
}
else
/* top-down DIB */
{
xorStride
=
xorBytesPerRow
;
xorRow
=
tempdata
;
}
bits
=
HeapAlloc
(
GetProcessHeap
(),
0
,
bitsSize
);
if
(
SUCCEEDED
(
hr
))
hr
=
IWICBitmapDecoder_GetFrame
(
decoder
,
0
,
&
framedecode
);
/* palette-map the 1-bit data */
bitsRow
=
bits
;
for
(
y
=
0
;
y
<
height
;
y
++
)
{
BYTE
*
xorByte
=
xorRow
;
DWORD
*
bitsPixel
=
(
DWORD
*
)
bitsRow
;
for
(
x
=
0
;
x
<
width
;
x
+=
8
)
{
BYTE
xorVal
;
xorVal
=*
xorByte
++
;
*
bitsPixel
++
=
colors
[
xorVal
>>
7
];
if
(
x
+
1
<
width
)
*
bitsPixel
++
=
colors
[
xorVal
>>
6
&
1
];
if
(
x
+
2
<
width
)
*
bitsPixel
++
=
colors
[
xorVal
>>
5
&
1
];
if
(
x
+
3
<
width
)
*
bitsPixel
++
=
colors
[
xorVal
>>
4
&
1
];
if
(
x
+
4
<
width
)
*
bitsPixel
++
=
colors
[
xorVal
>>
3
&
1
];
if
(
x
+
5
<
width
)
*
bitsPixel
++
=
colors
[
xorVal
>>
2
&
1
];
if
(
x
+
6
<
width
)
*
bitsPixel
++
=
colors
[
xorVal
>>
1
&
1
];
if
(
x
+
7
<
width
)
*
bitsPixel
++
=
colors
[
xorVal
&
1
];
}
xorRow
+=
xorStride
;
bitsRow
+=
bitsStride
;
}
HeapFree
(
GetProcessHeap
(),
0
,
tempdata
);
if
(
SUCCEEDED
(
hr
))
break
;
}
case
4
:
{
{
UINT
xorBytesPerRow
=
(
width
+
7
)
/
8
*
4
;
hr
=
IWICBitmapFrameDecode_GetSize
(
framedecode
,
&
result
->
width
,
&
result
->
height
);
UINT
xorBytes
=
xorBytesPerRow
*
height
;
INT
xorStride
;
BYTE
*
xorRow
;
BYTE
*
bitsRow
;
UINT
x
,
y
;
tempdata
=
HeapAlloc
(
GetProcessHeap
(),
0
,
xorBytes
);
if
(
SUCCEEDED
(
hr
))
if
(
!
tempdata
)
{
{
hr
=
E_OUTOFMEMORY
;
result
->
bits
=
HeapAlloc
(
GetProcessHeap
(),
0
,
result
->
width
*
result
->
height
*
4
)
;
goto
fail
;
if
(
!
result
->
bits
)
hr
=
E_OUTOFMEMORY
;
}
}
hr
=
IStream_Read
(
This
->
parent
->
stream
,
tempdata
,
xorBytes
,
&
bytesread
);
if
(
SUCCEEDED
(
hr
))
if
(
FAILED
(
hr
)
||
bytesread
!=
xorBytes
)
goto
fail
;
hr
=
IWICBitmapFrameDecode_GetPixelFormat
(
framedecode
,
&
pixelformat
)
;
if
(
bih
.
biHeight
>
0
)
/* bottom-up DIB */
if
(
IsEqualGUID
(
&
pixelformat
,
&
GUID_WICPixelFormat32bppBGR
)
||
IsEqualGUID
(
&
pixelformat
,
&
GUID_WICPixelFormat32bppBGRA
))
{
{
xorStride
=
-
xorBytesPerRow
;
source
=
(
IWICBitmapSource
*
)
framedecode
;
xorRow
=
tempdata
+
(
height
-
1
)
*
xorBytesPerRow
;
IWICBitmapSource_AddRef
(
source
);
has_alpha
=
TRUE
;
}
}
else
/* top-down DIB */
else
{
{
xorStride
=
xorBytesPerRow
;
hr
=
WICConvertBitmapSource
(
&
GUID_WICPixelFormat32bppBGRA
,
xorRow
=
tempdata
;
(
IWICBitmapSource
*
)
framedecode
,
&
source
);
has_alpha
=
FALSE
;
}
}
bits
=
HeapAlloc
(
GetProcessHeap
(),
0
,
bitsSize
);
if
(
SUCCEEDED
(
hr
))
/* palette-map the 4-bit data */
bitsRow
=
bits
;
for
(
y
=
0
;
y
<
height
;
y
++
)
{
BYTE
*
xorByte
=
xorRow
;
DWORD
*
bitsPixel
=
(
DWORD
*
)
bitsRow
;
for
(
x
=
0
;
x
<
width
;
x
+=
2
)
{
BYTE
xorVal
;
xorVal
=*
xorByte
++
;
*
bitsPixel
++
=
colors
[
xorVal
>>
4
];
if
(
x
+
1
<
width
)
*
bitsPixel
++
=
colors
[
xorVal
&
0xf
];
}
xorRow
+=
xorStride
;
bitsRow
+=
bitsStride
;
}
HeapFree
(
GetProcessHeap
(),
0
,
tempdata
);
break
;
}
case
8
:
{
{
UINT
xorBytesPerRow
=
(
width
+
3
)
/
4
*
4
;
rc
.
X
=
0
;
UINT
xorBytes
=
xorBytesPerRow
*
height
;
rc
.
Y
=
0
;
INT
xorStride
;
rc
.
Width
=
result
->
width
;
BYTE
*
xorRow
;
rc
.
Height
=
result
->
height
;
BYTE
*
bitsRow
;
hr
=
IWICBitmapSource_CopyPixels
(
source
,
&
rc
,
result
->
width
*
4
,
UINT
x
,
y
;
result
->
width
*
result
->
height
*
4
,
result
->
bits
)
;
tempdata
=
HeapAlloc
(
GetProcessHeap
(),
0
,
xorBytes
);
IWICBitmapSource_Release
(
source
);
if
(
!
tempdata
)
{
hr
=
E_OUTOFMEMORY
;
goto
fail
;
}
}
hr
=
IStream_Read
(
This
->
parent
->
stream
,
tempdata
,
xorBytes
,
&
bytesread
);
IWICBitmapFrameDecode_Release
(
framedecode
);
if
(
FAILED
(
hr
)
||
bytesread
!=
xorBytes
)
goto
fail
;
if
(
bih
.
biHeight
>
0
)
/* bottom-up DIB */
{
xorStride
=
-
xorBytesPerRow
;
xorRow
=
tempdata
+
(
height
-
1
)
*
xorBytesPerRow
;
}
else
/* top-down DIB */
{
xorStride
=
xorBytesPerRow
;
xorRow
=
tempdata
;
}
}
bits
=
HeapAlloc
(
GetProcessHeap
(),
0
,
bitsSize
);
if
(
SUCCEEDED
(
hr
)
&&
!
has_alpha
)
/* palette-map the 8-bit data */
bitsRow
=
bits
;
for
(
y
=
0
;
y
<
height
;
y
++
)
{
BYTE
*
xorByte
=
xorRow
;
DWORD
*
bitsPixel
=
(
DWORD
*
)
bitsRow
;
for
(
x
=
0
;
x
<
width
;
x
++
)
*
bitsPixel
++
=
colors
[
*
xorByte
++
];
xorRow
+=
xorStride
;
bitsRow
+=
bitsStride
;
}
HeapFree
(
GetProcessHeap
(),
0
,
tempdata
);
break
;
}
case
24
:
{
{
UINT
xorBytesPerRow
=
(
width
*
3
+
3
)
/
4
*
4
;
/* set alpha data based on the AND mask */
UINT
xorBytes
=
xorBytesPerRow
*
height
;
UINT
andBytesPerRow
=
(
result
->
width
+
31
)
/
32
*
4
;
INT
xorStride
;
UINT
andBytes
=
andBytesPerRow
*
result
->
height
;
BYTE
*
xorRow
;
INT
andStride
;
BYTE
*
tempdata
=
NULL
;
BYTE
*
andRow
;
BYTE
*
bitsRow
;
BYTE
*
bitsRow
;
UINT
bitsStride
=
result
->
width
*
4
;
UINT
x
,
y
;
UINT
x
,
y
;
ULONG
offset
;
ULONG
bytesread
;
LARGE_INTEGER
seek
;
int
topdown
;
tempdata
=
HeapAlloc
(
GetProcessHeap
(),
0
,
xorBytes
);
BmpDecoder_FindIconMask
(
decoder
,
&
offset
,
&
topdown
);
if
(
!
tempdata
)
{
hr
=
E_OUTOFMEMORY
;
goto
fail
;
}
hr
=
IStream_Read
(
This
->
parent
->
stream
,
tempdata
,
xorBytes
,
&
bytesread
);
if
(
FAILED
(
hr
)
||
bytesread
!=
xorBytes
)
goto
fail
;
if
(
bih
.
biHeight
>
0
)
/* bottom-up DIB */
{
xorStride
=
-
xorBytesPerRow
;
xorRow
=
tempdata
+
(
height
-
1
)
*
xorBytesPerRow
;
}
else
/* top-down DIB */
{
xorStride
=
xorBytesPerRow
;
xorRow
=
tempdata
;
}
bits
=
HeapAlloc
(
GetProcessHeap
(),
0
,
bitsSize
);
/* copy BGR->BGRA */
bitsRow
=
bits
;
for
(
y
=
0
;
y
<
height
;
y
++
)
{
BYTE
*
xorByte
=
xorRow
;
BYTE
*
bitsByte
=
bitsRow
;
for
(
x
=
0
;
x
<
width
;
x
++
)
{
*
bitsByte
++
=
*
xorByte
++
;
/* blue */
*
bitsByte
++
=
*
xorByte
++
;
/* green */
*
bitsByte
++
=
*
xorByte
++
;
/* red */
bitsByte
++
;
/* alpha */
}
xorRow
+=
xorStride
;
bitsRow
+=
bitsStride
;
}
HeapFree
(
GetProcessHeap
(),
0
,
tempdata
);
break
;
}
case
32
:
{
UINT
xorBytesPerRow
=
width
*
4
;
UINT
xorBytes
=
xorBytesPerRow
*
height
;
bits
=
HeapAlloc
(
GetProcessHeap
(),
0
,
xorBytes
);
if
(
offset
)
if
(
!
bits
)
{
{
hr
=
E_OUTOFMEMORY
;
seek
.
QuadPart
=
offset
;
goto
fail
;
}
if
(
bih
.
biHeight
>
0
)
/* bottom-up DIB */
hr
=
IStream_Seek
(
stream
,
seek
,
STREAM_SEEK_SET
,
0
);
{
/* read the rows backwards so we get a top-down DIB */
UINT
i
;
BYTE
*
xorRow
=
bits
+
xorBytesPerRow
*
(
height
-
1
);
for
(
i
=
0
;
i
<
height
;
i
++
)
if
(
SUCCEEDED
(
hr
))
{
hr
=
IStream_Read
(
This
->
parent
->
stream
,
xorRow
,
xorBytesPerRow
,
&
bytesread
);
if
(
FAILED
(
hr
)
||
bytesread
!=
xorBytesPerRow
)
goto
fail
;
xorRow
-=
xorBytesPerRow
;
}
}
else
/* top-down DIB */
{
{
hr
=
IStream_Read
(
This
->
parent
->
stream
,
bits
,
xorBytes
,
&
bytesread
);
if
(
FAILED
(
hr
)
||
bytesread
!=
xorBytes
)
goto
fail
;
}
break
;
}
default:
FIXME
(
"unsupported bitcount: %u
\n
"
,
bih
.
biBitCount
);
goto
fail
;
}
if
(
bih
.
biBitCount
<
32
)
{
/* set alpha data based on the AND mask */
UINT
andBytesPerRow
=
(
width
+
31
)
/
32
*
4
;
UINT
andBytes
=
andBytesPerRow
*
height
;
INT
andStride
;
BYTE
*
andRow
;
BYTE
*
bitsRow
;
UINT
x
,
y
;
tempdata
=
HeapAlloc
(
GetProcessHeap
(),
0
,
andBytes
);
tempdata
=
HeapAlloc
(
GetProcessHeap
(),
0
,
andBytes
);
if
(
!
tempdata
)
if
(
!
tempdata
)
hr
=
E_OUTOFMEMORY
;
{
hr
=
E_OUTOFMEMORY
;
goto
fail
;
}
}
hr
=
IStream_Read
(
This
->
parent
->
stream
,
tempdata
,
andBytes
,
&
bytesread
);
if
(
SUCCEEDED
(
hr
))
if
(
FAILED
(
hr
)
||
bytesread
!=
andBytes
)
goto
fail
;
hr
=
IStream_Read
(
stream
,
tempdata
,
andBytes
,
&
bytesread
)
;
if
(
bih
.
biHeight
>
0
)
/* bottom-up DIB */
if
(
SUCCEEDED
(
hr
)
&&
bytesread
==
andBytes
)
{
{
andStride
=
-
andBytesPerRow
;
if
(
topdown
)
andRow
=
tempdata
+
(
height
-
1
)
*
andBytesPerRow
;
}
else
/* top-down DIB */
{
{
andStride
=
andBytesPerRow
;
andStride
=
andBytesPerRow
;
andRow
=
tempdata
;
andRow
=
tempdata
;
}
}
else
{
andStride
=
-
andBytesPerRow
;
andRow
=
tempdata
+
(
result
->
height
-
1
)
*
andBytesPerRow
;
}
bitsRow
=
bits
;
bitsRow
=
result
->
bits
;
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
y
=
0
;
y
<
result
->
height
;
y
++
)
{
BYTE
*
andByte
=
andRow
;
BYTE
*
andByte
=
andRow
;
DWORD
*
bitsPixel
=
(
DWORD
*
)
bitsRow
;
DWORD
*
bitsPixel
=
(
DWORD
*
)
bitsRow
;
for
(
x
=
0
;
x
<
width
;
x
+=
8
)
{
for
(
x
=
0
;
x
<
result
->
width
;
x
+=
8
)
{
BYTE
andVal
=*
andByte
++
;
BYTE
andVal
=*
andByte
++
;
pixel_set_trans
(
bitsPixel
++
,
andVal
>>
7
&
1
);
pixel_set_trans
(
bitsPixel
++
,
andVal
>>
7
&
1
);
if
(
x
+
1
<
width
)
pixel_set_trans
(
bitsPixel
++
,
andVal
>>
6
&
1
);
if
(
x
+
1
<
result
->
width
)
pixel_set_trans
(
bitsPixel
++
,
andVal
>>
6
&
1
);
if
(
x
+
2
<
width
)
pixel_set_trans
(
bitsPixel
++
,
andVal
>>
5
&
1
);
if
(
x
+
2
<
result
->
width
)
pixel_set_trans
(
bitsPixel
++
,
andVal
>>
5
&
1
);
if
(
x
+
3
<
width
)
pixel_set_trans
(
bitsPixel
++
,
andVal
>>
4
&
1
);
if
(
x
+
3
<
result
->
width
)
pixel_set_trans
(
bitsPixel
++
,
andVal
>>
4
&
1
);
if
(
x
+
4
<
width
)
pixel_set_trans
(
bitsPixel
++
,
andVal
>>
3
&
1
);
if
(
x
+
4
<
result
->
width
)
pixel_set_trans
(
bitsPixel
++
,
andVal
>>
3
&
1
);
if
(
x
+
5
<
width
)
pixel_set_trans
(
bitsPixel
++
,
andVal
>>
2
&
1
);
if
(
x
+
5
<
result
->
width
)
pixel_set_trans
(
bitsPixel
++
,
andVal
>>
2
&
1
);
if
(
x
+
6
<
width
)
pixel_set_trans
(
bitsPixel
++
,
andVal
>>
1
&
1
);
if
(
x
+
6
<
result
->
width
)
pixel_set_trans
(
bitsPixel
++
,
andVal
>>
1
&
1
);
if
(
x
+
7
<
width
)
pixel_set_trans
(
bitsPixel
++
,
andVal
&
1
);
if
(
x
+
7
<
result
->
width
)
pixel_set_trans
(
bitsPixel
++
,
andVal
&
1
);
}
}
andRow
+=
andStride
;
andRow
+=
andStride
;
bitsRow
+=
bitsStride
;
bitsRow
+=
bitsStride
;
}
}
HeapFree
(
GetProcessHeap
(),
0
,
tempdata
);
}
}
This
->
bits
=
bits
;
return
S_OK
;
fail:
HeapFree
(
GetProcessHeap
(),
0
,
tempdata
);
HeapFree
(
GetProcessHeap
(),
0
,
tempdata
);
HeapFree
(
GetProcessHeap
(),
0
,
bits
);
if
(
SUCCEEDED
(
hr
))
hr
=
E_FAIL
;
TRACE
(
"<-- %x
\n
"
,
hr
);
return
hr
;
}
static
HRESULT
WINAPI
IcoFrameDecode_CopyPixels
(
IWICBitmapFrameDecode
*
iface
,
const
WICRect
*
prc
,
UINT
cbStride
,
UINT
cbBufferSize
,
BYTE
*
pbBuffer
)
{
IcoFrameDecode
*
This
=
(
IcoFrameDecode
*
)
iface
;
HRESULT
hr
=
S_OK
;
UINT
width
,
height
,
stride
;
TRACE
(
"(%p,%p,%u,%u,%p)
\n
"
,
iface
,
prc
,
cbStride
,
cbBufferSize
,
pbBuffer
);
EnterCriticalSection
(
&
This
->
parent
->
lock
);
if
(
!
This
->
bits
)
{
hr
=
IcoFrameDecode_ReadPixels
(
This
);
}
}
LeaveCriticalSection
(
&
This
->
parent
->
lock
);
}
if
(
FAILED
(
hr
))
return
hr
;
width
=
This
->
entry
.
bWidth
?
This
->
entry
.
bWidth
:
256
;
height
=
This
->
entry
.
bHeight
?
This
->
entry
.
bHeight
:
256
;
stride
=
width
*
4
;
return
copy_pixels
(
32
,
This
->
bits
,
width
,
height
,
stride
,
prc
,
cbStride
,
cbBufferSize
,
pbBuffer
);
}
static
HRESULT
WINAPI
IcoFrameDecode_GetMetadataQueryReader
(
IWICBitmapFrameDecode
*
iface
,
IWICMetadataQueryReader
**
ppIMetadataQueryReader
)
{
TRACE
(
"(%p,%p)
\n
"
,
iface
,
ppIMetadataQueryReader
);
return
WINCODEC_ERR_UNSUPPORTEDOPERATION
;
}
static
HRESULT
WINAPI
IcoFrameDecode_GetColorContexts
(
IWICBitmapFrameDecode
*
iface
,
IWICBitmapDecoder_Release
(
decoder
);
UINT
cCount
,
IWICColorContext
**
ppIColorContexts
,
UINT
*
pcActualCount
)
}
{
TRACE
(
"(%p,%u,%p,%p)
\n
"
,
iface
,
cCount
,
ppIColorContexts
,
pcActualCount
);
return
WINCODEC_ERR_UNSUPPORTEDOPERATION
;
}
static
HRESULT
WINAPI
IcoFrameDecode_GetThumbnail
(
IWICBitmapFrameDecode
*
iface
,
return
hr
;
IWICBitmapSource
**
ppIThumbnail
)
{
TRACE
(
"(%p,%p)
\n
"
,
iface
,
ppIThumbnail
);
return
WINCODEC_ERR_CODECNOTHUMBNAIL
;
}
}
static
const
IWICBitmapFrameDecodeVtbl
IcoFrameDecode_Vtbl
=
{
IcoFrameDecode_QueryInterface
,
IcoFrameDecode_AddRef
,
IcoFrameDecode_Release
,
IcoFrameDecode_GetSize
,
IcoFrameDecode_GetPixelFormat
,
IcoFrameDecode_GetResolution
,
IcoFrameDecode_CopyPalette
,
IcoFrameDecode_CopyPixels
,
IcoFrameDecode_GetMetadataQueryReader
,
IcoFrameDecode_GetColorContexts
,
IcoFrameDecode_GetThumbnail
};
static
HRESULT
WINAPI
IcoDecoder_QueryInterface
(
IWICBitmapDecoder
*
iface
,
REFIID
iid
,
static
HRESULT
WINAPI
IcoDecoder_QueryInterface
(
IWICBitmapDecoder
*
iface
,
REFIID
iid
,
void
**
ppv
)
void
**
ppv
)
{
{
...
@@ -736,8 +511,12 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface,
...
@@ -736,8 +511,12 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface,
IcoDecoder
*
This
=
(
IcoDecoder
*
)
iface
;
IcoDecoder
*
This
=
(
IcoDecoder
*
)
iface
;
IcoFrameDecode
*
result
=
NULL
;
IcoFrameDecode
*
result
=
NULL
;
LARGE_INTEGER
seek
;
LARGE_INTEGER
seek
;
ULARGE_INTEGER
offset
,
length
;
HRESULT
hr
;
HRESULT
hr
;
ULONG
bytesread
;
ULONG
bytesread
;
ICONDIRENTRY
entry
;
IWICStream
*
substream
=
NULL
;
DWORD
magic
;
TRACE
(
"(%p,%u,%p)
\n
"
,
iface
,
index
,
ppIBitmapFrame
);
TRACE
(
"(%p,%u,%p)
\n
"
,
iface
,
index
,
ppIBitmapFrame
);
EnterCriticalSection
(
&
This
->
lock
);
EnterCriticalSection
(
&
This
->
lock
);
...
@@ -763,7 +542,6 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface,
...
@@ -763,7 +542,6 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface,
result
->
lpVtbl
=
&
IcoFrameDecode_Vtbl
;
result
->
lpVtbl
=
&
IcoFrameDecode_Vtbl
;
result
->
ref
=
1
;
result
->
ref
=
1
;
result
->
parent
=
This
;
result
->
bits
=
NULL
;
result
->
bits
=
NULL
;
/* read the icon entry */
/* read the icon entry */
...
@@ -771,10 +549,42 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface,
...
@@ -771,10 +549,42 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface,
hr
=
IStream_Seek
(
This
->
stream
,
seek
,
STREAM_SEEK_SET
,
0
);
hr
=
IStream_Seek
(
This
->
stream
,
seek
,
STREAM_SEEK_SET
,
0
);
if
(
FAILED
(
hr
))
goto
fail
;
if
(
FAILED
(
hr
))
goto
fail
;
hr
=
IStream_Read
(
This
->
stream
,
&
result
->
entry
,
sizeof
(
ICONDIRENTRY
),
&
bytesread
);
hr
=
IStream_Read
(
This
->
stream
,
&
entry
,
sizeof
(
ICONDIRENTRY
),
&
bytesread
);
if
(
FAILED
(
hr
)
||
bytesread
!=
sizeof
(
ICONDIRENTRY
))
goto
fail
;
if
(
FAILED
(
hr
)
||
bytesread
!=
sizeof
(
ICONDIRENTRY
))
goto
fail
;
IWICBitmapDecoder_AddRef
(
iface
);
/* create a stream object for this icon */
hr
=
StreamImpl_Create
(
&
substream
);
if
(
FAILED
(
hr
))
goto
fail
;
offset
.
QuadPart
=
entry
.
dwDIBOffset
;
length
.
QuadPart
=
entry
.
dwDIBSize
;
hr
=
IWICStream_InitializeFromIStreamRegion
(
substream
,
This
->
stream
,
offset
,
length
);
if
(
FAILED
(
hr
))
goto
fail
;
/* read the bitmapinfo size or magic number */
hr
=
IWICStream_Read
(
substream
,
&
magic
,
sizeof
(
magic
),
&
bytesread
);
if
(
FAILED
(
hr
)
||
bytesread
!=
sizeof
(
magic
))
goto
fail
;
/* forward to the appropriate decoding function based on the magic number */
switch
(
magic
)
{
case
sizeof
(
BITMAPCOREHEADER
):
case
64
:
/* sizeof(BITMAPCOREHEADER2) */
case
sizeof
(
BITMAPINFOHEADER
):
case
sizeof
(
BITMAPV4HEADER
):
case
sizeof
(
BITMAPV5HEADER
):
hr
=
ReadIcoDib
((
IStream
*
)
substream
,
result
);
break
;
case
0x474e5089
:
FIXME
(
"PNG decoding not supported
\n
"
);
hr
=
E_FAIL
;
break
;
default:
FIXME
(
"Unrecognized ICO frame magic: %x
\n
"
,
magic
);
hr
=
E_FAIL
;
break
;
}
if
(
FAILED
(
hr
))
goto
fail
;
*
ppIBitmapFrame
=
(
IWICBitmapFrameDecode
*
)
result
;
*
ppIBitmapFrame
=
(
IWICBitmapFrameDecode
*
)
result
;
...
@@ -785,6 +595,7 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface,
...
@@ -785,6 +595,7 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface,
fail:
fail:
LeaveCriticalSection
(
&
This
->
lock
);
LeaveCriticalSection
(
&
This
->
lock
);
HeapFree
(
GetProcessHeap
(),
0
,
result
);
HeapFree
(
GetProcessHeap
(),
0
,
result
);
if
(
substream
)
IStream_Release
(
substream
);
if
(
SUCCEEDED
(
hr
))
hr
=
E_FAIL
;
if
(
SUCCEEDED
(
hr
))
hr
=
E_FAIL
;
TRACE
(
"<-- %x
\n
"
,
hr
);
TRACE
(
"<-- %x
\n
"
,
hr
);
return
hr
;
return
hr
;
...
...
dlls/windowscodecs/tests/icoformat.c
View file @
4d55359f
...
@@ -136,7 +136,7 @@ static void test_bad_icondirentry_size(void)
...
@@ -136,7 +136,7 @@ static void test_bad_icondirentry_size(void)
UINT
width
=
0
,
height
=
0
;
UINT
width
=
0
,
height
=
0
;
hr
=
IWICBitmapFrameDecode_GetSize
(
framedecode
,
&
width
,
&
height
);
hr
=
IWICBitmapFrameDecode_GetSize
(
framedecode
,
&
width
,
&
height
);
ok
(
hr
==
S_OK
,
"GetFrameSize failed, hr=%x
\n
"
,
hr
);
ok
(
hr
==
S_OK
,
"GetFrameSize failed, hr=%x
\n
"
,
hr
);
todo_wine
ok
(
width
==
16
&&
height
==
16
,
"framesize=%ux%u
\n
"
,
width
,
height
);
ok
(
width
==
16
&&
height
==
16
,
"framesize=%ux%u
\n
"
,
width
,
height
);
IWICBitmapFrameDecode_Release
(
framedecode
);
IWICBitmapFrameDecode_Release
(
framedecode
);
}
}
...
...
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