bool WicFile::Read(RasterImage &imgDst, unsigned int frameNo) { ::IWICBitmapFrameDecode *frame(nullptr); ::IWICFormatConverter *format_converter(nullptr); try { // Get a frame. if (FAILED(decoder->GetFrame(frameNo, &frame))) throw std::runtime_error("Failed to get a frame."); // Create a format converter, // and convert the source image frame to 32bit BGRA regardless of original format. if (FAILED(this->factory->CreateFormatConverter(&format_converter))) throw std::runtime_error("Failed to create a format converter."); if (FAILED(format_converter->Initialize(frame, ::GUID_WICPixelFormat32bppPBGRA, ::WICBitmapDitherTypeNone, nullptr, 0.0, ::WICBitmapPaletteTypeCustom))) throw std::runtime_error("Failed to convert the source image frame."); // Copy image data to the destination. // Set the size with unsigned int instead of ::size_t because ::size_t (== unsigned long) // can be wider than unsigned int. unsigned int w, h; if (FAILED(format_converter->GetSize(&w, &h))) throw std::runtime_error("Failed to get the size of the source image frame."); unsigned int sz = w * h * 4; imgDst.Resize(1, 4, w, h); if (FAILED(format_converter->CopyPixels(nullptr, w * 4, sz, imgDst.data.data()))) throw std::runtime_error("Failed to copy pixels from the source image frame."); } catch (const std::exception &ex) { SafeRelease(format_converter); SafeRelease(frame); throw ex; // Re-throw the exception. } SafeRelease(format_converter); SafeRelease(frame); return true; // redundant response to maintain the class protocol. }