ReactOS 0.4.15-dev-7998-gdb93cb1
anime.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Picture and Fax Viewer
3 * LICENSE: GPL-2.0 (https://spdx.org/licenses/GPL-2.0)
4 * PURPOSE: Animation of shimgvw.dll
5 * COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
6 */
7
8#include "shimgvw.h"
9
10#define ANIME_TIMER_ID 9999
11
13{
14 if (pAnime->m_pDelayItem)
15 {
16 QuickFree(pAnime->m_pDelayItem);
17 pAnime->m_pDelayItem = NULL;
18 }
19 pAnime->m_nFrameIndex = 0;
20 pAnime->m_nFrameCount = 0;
21 pAnime->m_nLoopIndex = 0;
22 pAnime->m_nLoopCount = (UINT)-1;
23}
24
25void Anime_SetTimerWnd(PANIME pAnime, HWND hwndTimer)
26{
27 pAnime->m_hwndTimer = hwndTimer;
28}
29
30void Anime_Pause(PANIME pAnime)
31{
33}
34
35void Anime_Start(PANIME pAnime, DWORD dwDelay)
36{
37 if (pAnime->m_pDelayItem)
38 SetTimer(pAnime->m_hwndTimer, ANIME_TIMER_ID, dwDelay, NULL);
39}
40
42{
43 if (nFrameIndex < pAnime->m_nFrameCount && pAnime->m_pDelayItem)
44 {
45 return ((DWORD *)pAnime->m_pDelayItem->value)[pAnime->m_nFrameIndex] * 10;
46 }
47 return 0;
48}
49
50BOOL Anime_Step(PANIME pAnime, DWORD *pdwDelay)
51{
52 *pdwDelay = INFINITE;
53 if (pAnime->m_nLoopCount == (UINT)-1)
54 return FALSE;
55
56 if (pAnime->m_nFrameIndex + 1 < pAnime->m_nFrameCount)
57 {
58 *pdwDelay = Anime_GetFrameDelay(pAnime, pAnime->m_nFrameIndex);
59 Anime_SetFrameIndex(pAnime, pAnime->m_nFrameIndex);
60 ++pAnime->m_nFrameIndex;
61 return TRUE;
62 }
63
64 if (pAnime->m_nLoopCount == 0 || pAnime->m_nLoopIndex < pAnime->m_nLoopCount)
65 {
66 *pdwDelay = Anime_GetFrameDelay(pAnime, pAnime->m_nFrameIndex);
67 Anime_SetFrameIndex(pAnime, pAnime->m_nFrameIndex);
68 pAnime->m_nFrameIndex = 0;
69 ++pAnime->m_nLoopIndex;
70 return TRUE;
71 }
72
73 return FALSE;
74}
75
77{
78 DWORD dwDelay;
79
81 return FALSE;
82
83 Anime_Pause(pAnime);
84 if (Anime_Step(pAnime, &dwDelay))
85 Anime_Start(pAnime, dwDelay);
86 return TRUE;
87}
88
90{
91 UINT nDimCount = 0;
92 UINT cbItem;
94
95 Anime_Pause(pAnime);
96 Anime_FreeInfo(pAnime);
97
98 if (!g_pImage)
99 return FALSE;
100
102 if (nDimCount)
103 {
104 GUID *dims = (GUID *)QuickAlloc(nDimCount * sizeof(GUID), TRUE);
105 if (dims)
106 {
109 pAnime->m_nFrameCount = result;
110 QuickFree(dims);
111 }
112 }
113
114 result = 0;
116 cbItem = result;
117 if (cbItem)
118 {
119 pAnime->m_pDelayItem = (PropertyItem *)QuickAlloc(cbItem, FALSE);
121 }
122
123 result = 0;
125 cbItem = result;
126 if (cbItem)
127 {
128 PropertyItem *pItem = (PropertyItem *)QuickAlloc(cbItem, FALSE);
129 if (pItem)
130 {
131 if (GdipGetPropertyItem(g_pImage, PropertyTagLoopCount, cbItem, pItem) == Ok)
132 {
133 pAnime->m_nLoopCount = *(WORD *)pItem->value;
134 }
135 QuickFree(pItem);
136 }
137 }
138
139 Anime_Start(pAnime, 0);
140
141 return pAnime->m_pDelayItem != NULL;
142}
143
144void Anime_SetFrameIndex(PANIME pAnime, UINT nFrameIndex)
145{
146 if (nFrameIndex < pAnime->m_nFrameCount)
147 {
148 GUID guid = FrameDimensionTime;
149 if (Ok != GdipImageSelectActiveFrame(g_pImage, &guid, nFrameIndex))
150 {
151 guid = FrameDimensionPage;
153 }
154 }
155 pAnime->m_nFrameIndex = nFrameIndex;
156}
BOOL Anime_LoadInfo(PANIME pAnime)
Definition: anime.c:89
void Anime_Start(PANIME pAnime, DWORD dwDelay)
Definition: anime.c:35
BOOL Anime_Step(PANIME pAnime, DWORD *pdwDelay)
Definition: anime.c:50
DWORD Anime_GetFrameDelay(PANIME pAnime, UINT nFrameIndex)
Definition: anime.c:41
BOOL Anime_OnTimer(PANIME pAnime, WPARAM wParam)
Definition: anime.c:76
void Anime_SetTimerWnd(PANIME pAnime, HWND hwndTimer)
Definition: anime.c:25
void Anime_FreeInfo(PANIME pAnime)
Definition: anime.c:12
void Anime_Pause(PANIME pAnime)
Definition: anime.c:30
void Anime_SetFrameIndex(PANIME pAnime, UINT nFrameIndex)
Definition: anime.c:144
#define ANIME_TIMER_ID
Definition: anime.c:10
WPARAM wParam
Definition: combotst.c:138
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
GpStatus WINGDIPAPI GdipImageGetFrameCount(GpImage *image, GDIPCONST GUID *dimensionID, UINT *count)
Definition: image.c:2913
GpStatus WINGDIPAPI GdipImageGetFrameDimensionsCount(GpImage *image, UINT *count)
Definition: image.c:2933
GpStatus WINGDIPAPI GdipImageSelectActiveFrame(GpImage *image, GDIPCONST GUID *dimensionID, UINT frame)
Definition: image.c:4350
GpStatus WINGDIPAPI GdipGetPropertyItem(GpImage *image, PROPID propid, UINT size, PropertyItem *buffer)
Definition: image.c:2682
GpStatus WINGDIPAPI GdipGetPropertyItemSize(GpImage *image, PROPID propid, UINT *size)
Definition: image.c:2536
GpStatus WINGDIPAPI GdipImageGetFrameDimensionsList(GpImage *image, GUID *dimensionIDs, UINT count)
Definition: image.c:2948
#define INFINITE
Definition: serial.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
#define PropertyTagFrameDelay
#define PropertyTagLoopCount
@ Ok
Definition: gdiplustypes.h:26
GLuint64EXT * result
Definition: glext.h:11304
const GUID * guid
unsigned int UINT
Definition: ndis.h:50
GpImage * g_pImage
Definition: shimgvw.c:28
static LPVOID QuickAlloc(SIZE_T cbSize, BOOL bZero)
Definition: shimgvw.h:72
static VOID QuickFree(LPVOID ptr)
Definition: shimgvw.h:77
UINT m_nLoopCount
Definition: shimgvw.h:59
UINT m_nFrameIndex
Definition: shimgvw.h:56
HWND m_hwndTimer
Definition: shimgvw.h:61
UINT m_nLoopIndex
Definition: shimgvw.h:58
PropertyItem * m_pDelayItem
Definition: shimgvw.h:60
UINT m_nFrameCount
Definition: shimgvw.h:57
UINT_PTR WPARAM
Definition: windef.h:207
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)