std::shared_ptr<Spec> init_spec_from(const CommandLineOptions& options)
{
    std::shared_ptr<Spec> spec;
    if (!options.empty()) {
        spec = std::make_shared<Spec>();
        for (const auto& kv : options) {
            auto& key = kv.first;
            if (key == _T("-h") || key == _T("--help")) {
                return nullptr;
            }
            else if (key == _T("-v") || key == _T("--verbose")) {
                spec->verbose = true;
            }
            else if (key == _T("-f")) {
                auto& args = kv.second;
                if (args.size() >= 1) {
                    auto& format = args[0];
                    for (int32_t i = 0; i < ARRAYSIZE(kFormats); ++i) {
                        if (format == kFormats[i]) {
                            spec->format = kDXGIFormats[i];
                            break;
                        }
                    }
                }
            }
            else if (key == _T("-l")) {
                auto& args = kv.second;
                if (args.size() >= 1) {
                    auto& level = args[0];
                    for (int32_t i = 0; i < ARRAYSIZE(kLevels); ++i) {
                        if (level == kLevels[i]) {
                            spec->level = static_cast<Level>(i);
                            break;
                        }
                    }
                }
            }
            else if (key == _T("-rgb")) {
                spec->rgb_mode = true;
            }
            else if (key == _T("-dither")) {
                spec->dither = true;
            }
            else if (key == _T("-i")) {
                if (kv.second.size() >= 1) {
                    spec->input_name = kv.second[0];
                }
            }
            else if (key == _T("-o")) {
                if (kv.second.size() >= 1) {
                    spec->output_name = kv.second[0];
                }
            }
        }
    }
    return spec;
}