I have a std::vector<> of IWICBitmapSource and trying to create an animated gif:
void SaveGif()
{
CComPtr<IWICBitmapEncoder> wicBitmapEncoder;
auto hr =
fact->CreateEncoder(
GUID_ContainerFormatGif,
nullptr, // No preferred codec vendor.
&wicBitmapEncoder
);
VectorStream stream;
hr =
wicBitmapEncoder->Initialize(
&stream,
WICBitmapEncoderNoCache
);
for (auto& gox : Gifs)
{
CComPtr<IWICBitmapFrameEncode> wicFrameEncode;
hr =
wicBitmapEncoder->CreateNewFrame(
&wicFrameEncode,
0
);
hr =
wicFrameEncode->Initialize(bag2);
auto g2 = GUID_WICPixelFormat24bppRGB;
wicFrameEncode->SetPixelFormat(&g2);
WICRect wr = {};
UINT wi, he;
gox.second->GetSize(&wi,&he);
wr.Width = wi;
wr.Height = he;
hr = wicFrameEncode->WriteSource(gox.second, &wr);
hr = wicFrameEncode->Commit();
}
// save stream to gif file
}
All functions succeed, the final file is animating, but not looping. It stops at the last frame.
How can I tell it to loop indefinitely?
Using the links in Simon Mourier's comment, I came up with this snippet and it seems to be working (for my single testcase):
CComPtr<IWICMetadataQueryWriter> meta; // Get a metadata writer
wicBitmapEncoder->GetMetadataQueryWriter(&meta);
PROPVARIANT app = { 0 };
PROPVARIANT data = { 0 };
const char *appext = "NETSCAPE2.0"; // application that defined the extension
struct LoopCount // the data that is needed for the extension (see Simon's links)
{
unsigned char block_size = 3;
unsigned char block_id = 1;
unsigned short loopcount = 0;
} bData;
// Setup the PROPVARIANTS
PropVariantInit(&app);
PropVariantInit(&data);
data.vt = VT_UI1|VT_VECTOR;
app.vt = VT_UI1|VT_VECTOR;
app.cac.cElems = strlen(appext);
app.cac.pElems = (char *)appext;
data.cac.cElems = sizeof(LoopCount);
data.cac.pElems = (char *)&bData;
meta->SetMetadataByName(L"/appext/application", &app); // Write the metadata
meta->SetMetadataByName(L"/appext/data", &data);