parse_encrypt_options(
    int argc, char* argv[], int& cur_arg,
    std::string& user_password, std::string& owner_password, int& keylen,
    bool& r2_print, bool& r2_modify, bool& r2_extract, bool& r2_annotate,
    bool& r3_accessibility, bool& r3_extract,
    qpdf_r3_print_e& r3_print, qpdf_r3_modify_e& r3_modify,
    bool& force_V4, bool& cleartext_metadata, bool& use_aes,
    bool& force_R5)
{
    if (cur_arg + 3 >= argc)
    {
	usage("insufficient arguments to --encrypt");
    }
    user_password = argv[cur_arg++];
    owner_password = argv[cur_arg++];
    std::string len_str = argv[cur_arg++];
    if (len_str == "40")
    {
	keylen = 40;
    }
    else if (len_str == "128")
    {
	keylen = 128;
    }
    else if (len_str == "256")
    {
	keylen = 256;
        use_aes = true;
    }
    else
    {
	usage("encryption key length must be 40, 128, or 256");
    }
    while (1)
    {
	char* arg = argv[cur_arg];
	if (arg == 0)
	{
	    usage("insufficient arguments to --encrypt");
	}
	else if (strcmp(arg, "--") == 0)
	{
	    return;
	}
	if (arg[0] == '-')
	{
	    ++arg;
	    if (arg[0] == '-')
	    {
		++arg;
	    }
	}
	else
	{
	    usage(std::string("invalid encryption parameter ") + arg);
	}
	++cur_arg;
	char* parameter = strchr(arg, '=');
	if (parameter)
	{
	    *parameter++ = 0;
	}
	if (strcmp(arg, "print") == 0)
	{
	    if (parameter == 0)
	    {
		usage("--print must be given as --print=option");
	    }
	    std::string val = parameter;
	    if (keylen == 40)
	    {
		if (val == "y")
		{
		    r2_print = true;
		}
		else if (val == "n")
		{
		    r2_print = false;
		}
		else
		{
		    usage("invalid 40-bit -print parameter");
		}
	    }
	    else
	    {
		if (val == "full")
		{
		    r3_print = qpdf_r3p_full;
		}
		else if (val == "low")
		{
		    r3_print = qpdf_r3p_low;
		}
		else if (val == "none")
		{
		    r3_print = qpdf_r3p_none;
		}
		else
		{
		    usage("invalid 128-bit -print parameter");
		}
	    }
	}
	else if (strcmp(arg, "modify") == 0)
	{
	    if (parameter == 0)
	    {
		usage("--modify must be given as --modify=option");
	    }
	    std::string val = parameter;
	    if (keylen == 40)
	    {
		if (val == "y")
		{
		    r2_modify = true;
		}
		else if (val == "n")
		{
		    r2_modify = false;
		}
		else
		{
		    usage("invalid 40-bit -modify parameter");
		}
	    }
	    else
	    {
		if (val == "all")
		{
		    r3_modify = qpdf_r3m_all;
		}
		else if (val == "annotate")
		{
		    r3_modify = qpdf_r3m_annotate;
		}
		else if (val == "form")
		{
		    r3_modify = qpdf_r3m_form;
		}
		else if (val == "assembly")
		{
		    r3_modify = qpdf_r3m_assembly;
		}
		else if (val == "none")
		{
		    r3_modify = qpdf_r3m_none;
		}
		else
		{
		    usage("invalid 128-bit -modify parameter");
		}
	    }
	}
	else if (strcmp(arg, "extract") == 0)
	{
	    if (parameter == 0)
	    {
		usage("--extract must be given as --extract=option");
	    }
	    std::string val = parameter;
	    bool result = false;
	    if (val == "y")
	    {
		result = true;
	    }
	    else if (val == "n")
	    {
		result = false;
	    }
	    else
	    {
		usage("invalid -extract parameter");
	    }
	    if (keylen == 40)
	    {
		r2_extract = result;
	    }
	    else
	    {
		r3_extract = result;
	    }
	}
	else if (strcmp(arg, "annotate") == 0)
	{
	    if (parameter == 0)
	    {
		usage("--annotate must be given as --annotate=option");
	    }
	    std::string val = parameter;
	    bool result = false;
	    if (val == "y")
	    {
		result = true;
	    }
	    else if (val == "n")
	    {
		result = false;
	    }
	    else
	    {
		usage("invalid -annotate parameter");
	    }
	    if (keylen == 40)
	    {
		r2_annotate = result;
	    }
	    else
	    {
		usage("-annotate invalid for 128-bit keys");
	    }
	}
	else if (strcmp(arg, "accessibility") == 0)
	{
	    if (parameter == 0)
	    {
		usage("--accessibility must be given as"
		      " --accessibility=option");
	    }
	    std::string val = parameter;
	    bool result = false;
	    if (val == "y")
	    {
		result = true;
	    }
	    else if (val == "n")
	    {
		result = false;
	    }
	    else
	    {
		usage("invalid -accessibility parameter");
	    }
	    if (keylen == 40)
	    {
		usage("-accessibility invalid for 40-bit keys");
	    }
	    else
	    {
		r3_accessibility = result;
	    }
	}
	else if (strcmp(arg, "cleartext-metadata") == 0)
	{
	    if (parameter)
	    {
		usage("--cleartext-metadata does not take a parameter");
	    }
	    if (keylen == 40)
	    {
		usage("--cleartext-metadata is invalid for 40-bit keys");
	    }
	    else
	    {
		cleartext_metadata = true;
	    }
	}
	else if (strcmp(arg, "force-V4") == 0)
	{
	    if (parameter)
	    {
		usage("--force-V4 does not take a parameter");
	    }
	    if (keylen != 128)
	    {
		usage("--force-V4 is invalid only for 128-bit keys");
	    }
	    else
	    {
		force_V4 = true;
	    }
	}
	else if (strcmp(arg, "force-R5") == 0)
	{
	    if (parameter)
	    {
		usage("--force-R5 does not take a parameter");
	    }
	    if (keylen != 256)
	    {
		usage("--force-R5 is invalid only for 256-bit keys");
	    }
	    else
	    {
		force_R5 = true;
	    }
	}
	else if (strcmp(arg, "use-aes") == 0)
	{
	    if (parameter == 0)
	    {
		usage("--use-aes must be given as --extract=option");
	    }
	    std::string val = parameter;
	    bool result = false;
	    if (val == "y")
	    {
		result = true;
	    }
	    else if (val == "n")
	    {
		result = false;
	    }
	    else
	    {
		usage("invalid -use-aes parameter");
	    }
	    if ((keylen == 40) && result)
	    {
		usage("use-aes is invalid for 40-bit keys");
	    }
            else if ((keylen == 256) && (! result))
            {
                // qpdf would happily create files encrypted with RC4
                // using /V=5, but Adobe reader can't read them.
                usage("use-aes can't be disabled with 256-bit keys");
            }
	    else
	    {
		use_aes = result;
	    }
	}
	else
	{
	    usage(std::string("invalid encryption parameter --") + arg);
	}
    }
}