Some linear algebra shows that the final height is given by the formula

where w is the desired global width, bi and hi are the width and height of the i-th image (i = 1,2,…,n); *h$ is the final height.
An implementation using expl3 is almost straightforward. I guess that it's easy also with pgfmath. The macro \manyimages has as first argument the desired width (w in the preceding notation) which can be whatever one wants. In the following example I chose 0.8\textwidth to give the images some room.
\documentclass{article}
\usepackage{graphicx}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\manyimages}{ m m }
{
% #1 is the required width
% #2 is a comma separated list of image names
\manyimages_main:nn { #1 } { #2 }
}
\fp_new:N \l_manyimages_temp_fp
\box_new:N \l_manyimages_temp_box
\dim_new:N \l_manyimages_finalheight_dim
\cs_set_eq:NN \finalheight \l_manyimages_finalheight_dim
\cs_new_protected:Npn \manyimages_main:nn #1 #2
{
% clear the storage bin
\fp_zero:N \l_manyimages_temp_fp
\clist_map_inline:nn { #2 }
{
% set a temporary box for measuring the current image
\hbox_set:Nn \l_manyimages_temp_box { \includegraphics{##1} }
% compute the ratio width/height and add it to the storage bin
\fp_add:Nn \l_manyimages_temp_fp
{
\dim_to_fp:n { \box_wd:N \l_manyimages_temp_box }
/
\dim_to_fp:n { \box_ht:N \l_manyimages_temp_box }
}
}
% now set \finalheight to the ratio w/(computed sum)
\dim_set:Nn \l_manyimages_finalheight_dim
{
\fp_to_dim:n { \dim_to_fp:n { #1 } / \l_manyimages_temp_fp }
}
}
\ExplSyntaxOff
\begin{document}
\begin{flushleft}
\manyimages{0.8\textwidth}{
example-image,
example-image-10x16,
example-image-golden,
example-image-golden-upright
}
\includegraphics[height=\finalheight]{example-image}\hfill
\includegraphics[height=\finalheight]{example-image-10x16}\hfill
\includegraphics[height=\finalheight]{example-image-golden}\hfill
\includegraphics[height=\finalheight]{example-image-golden-upright}
\bigskip
For control
\bigskip
\resizebox{\textwidth}{!}{%
\includegraphics{example-image}
\includegraphics{example-image-10x16}
\includegraphics{example-image-golden}
\includegraphics{example-image-golden-upright}%
}
\end{flushleft}
\end{document}
I have used some images in the mwe suite. The second row is just for control and shows the images at their (uniformly scaled) original proportions.

Here is a full featured solution for subfig. For typesetting a row of images we use the manysubfloats environment, which contains one or more \subimage commands. The mandatory argument to manysubfloats is a dimension; use whatever you want, but recall that using \textwidth would push all the images together.
You can have more than one manysubfloats environments, each one will print a row of subfloats.
Each \subimage command has two arguments: the first is an optional list of key-value pairs, the second is the file name. In the key-value pairs one can specify
file= for the file name;
path= for a non standard path;
caption= for setting the subcaption;
listcaption= for a possibly different subcaption in the list of figures;
label= for a label referring to the subfloat.
Why a key file? If the file name has special characters or is too long, a symbolic name for the mandatory argument is to be preferred. The mandatory argument is used for internal purposes only. The file= key is probably not necessary, as most of the time the file name can be safely used.
\documentclass{article}
\usepackage{graphicx,subfig}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentEnvironment{manysubfloats}{ m }
{ \clist_clear:N \l_manyimages_row_clist }
{ \manyimages_display:n { #1 } }
\NewDocumentCommand{\subimage}{ O{} m }
{% #1 is a key-value list, #2 is a symbolic name or the file name
\manyimages_subimage:nn { #2 } { #1 }
}
\keys_define:nn { manyimages }
{
file .tl_set:N = \l_manyimages_file_tl,
path .tl_set:N = \l_manyimages_path_tl,
caption .tl_set:N = \l_manyimages_caption_tl,
listcaption .tl_set:N = \l_manyimages_listcaption_tl,
label .tl_set:N = \l_manyimages_label_tl
}
\fp_new:N \l_manyimages_temp_fp
\box_new:N \l_manyimages_temp_box
\dim_new:N \l_manyimages_finalheight_dim
\clist_new:N \l_manyimages_row_clist
\tl_new:N \l_manyimages_output_tl
\tl_new:N \l_manyimages_tmpa_tl
\tl_new:N \l_manyimages_tmpb_tl
% a constant property list
\prop_new:N \c_manyimages_proto_prop
\prop_gput:Nnn \c_manyimages_proto_prop { file } { }
\prop_gput:Nnn \c_manyimages_proto_prop { path } { }
\prop_gput:Nnn \c_manyimages_proto_prop { caption } { }
\prop_gput:Nnn \c_manyimages_proto_prop { listcaption } { }
\prop_gput:Nnn \c_manyimages_proto_prop { label } { }
\cs_new_protected:Npn \manyimages_main:n #1
{
% clear the storage bin
\fp_zero:N \l_manyimages_temp_fp
\clist_map_inline:Nn \l_manyimages_row_clist
{
% set a temporary box for measuring the current image
\__manyimages_prop_get:nnN { ##1 } { path } \l_manyimages_tmpa_tl
\__manyimages_prop_get:nnN { ##1 } { file } \l_manyimages_tmpb_tl
\hbox_set:Nn \l_manyimages_temp_box
{
\includegraphics
{
\tl_if_empty:NF \l_manyimages_tmpa_tl { \l_manyimages_tmpa_tl / }
\l_manyimages_tmpb_tl
}
}
% compute the ratio width/height and add it to the storage bin
\fp_add:Nn \l_manyimages_temp_fp
{
\dim_to_fp:n { \box_wd:N \l_manyimages_temp_box }
/
\dim_to_fp:n { \box_ht:N \l_manyimages_temp_box }
}
}
% now set \finalheight to the ratio w/(computed sum)
\dim_set:Nn \l_manyimages_finalheight_dim
{
\fp_to_dim:n { \dim_to_fp:n { #1 } / \l_manyimages_temp_fp }
}
}
\cs_new_protected:Npn \manyimages_subimage:nn #1 #2
{% add the item to the clist
\clist_put_right:Nn \l_manyimages_row_clist { #1 }
% clear the property list for #1 (symbolic name or file name)
\prop_clear_new:c { l_manyimages_\tl_to_str:n { #1 }_prop }
% fill in the property list with empty values
\prop_set_eq:cN { l_manyimages_\tl_to_str:n { #1 }_prop } \c_manyimages_proto_prop
\keys_set:nn { manyimages }
{% empty the variables and evaluate the given ones
file = {},
path = {},
caption = {},
listcaption = {},
label = {},
#2
}
\tl_if_empty:NTF \l_manyimages_file_tl
{
\__manyimages_prop_put:nnn { #1 } { file } { #1 }
}
{
\__manyimages_prop_put:nnV { #1 } { file } \l_manyimages_file_tl
}
\__manyimages_prop_put:nnV { #1 } { path } \l_manyimages_path_tl
\__manyimages_prop_put:nnV { #1 } { caption } \l_manyimages_caption_tl
\__manyimages_prop_put:nnV { #1 } { listcaption } \l_manyimages_listcaption_tl
\__manyimages_prop_put:nnV { #1 } { label } \l_manyimages_label_tl
}
%%% syntactic sugar
% a personal version of \prop_put:cnn
\cs_new_protected:Npn \__manyimages_prop_put:nnn #1 #2 #3
{
\prop_put:cnn { l_manyimages_\tl_to_str:n { #1 }_prop } { #2 } { #3 }
}
\cs_generate_variant:Nn \__manyimages_prop_put:nnn { nnV }
% a personal version of \prop_get:cnN
\cs_new_protected:Npn \__manyimages_prop_get:nnN #1 #2 #3
{
\prop_get:cnN { l_manyimages_\tl_to_str:n { #1 }_prop } { #2 } #3
}
%%% use \subfloat
\cs_new_protected:Npn \manyimages_display:n #1
{% compute the final height
\manyimages_main:n { #1 }
% output the subfloats
\clist_map_inline:Nn \l_manyimages_row_clist
{
\tl_set:Nn \l_manyimages_output_tl { \subfloat }
\__manyimages_prop_get:nnN { ##1 } { listcaption } \l_tmpa_tl
\tl_if_empty:NF \l_tmpa_tl
{
\tl_put_right:Nn \l_manyimages_output_tl { [ }
\tl_put_right:NV \l_manyimages_output_tl \l_tmpa_tl
\tl_put_right:Nn \l_manyimages_output_tl { ] }
}
\__manyimages_prop_get:nnN { ##1 } { caption } \l_tmpa_tl
\tl_put_right:Nn \l_manyimages_output_tl { [ }
\tl_if_empty:NF \l_tmpa_tl
{
\tl_put_right:NV \l_manyimages_output_tl \l_tmpa_tl
}
\tl_put_right:Nn \l_manyimages_output_tl { ] }
\__manyimages_prop_get:nnN { ##1 } { label } \l_tmpa_tl
\__manyimages_prop_get:nnN { ##1 } { path } \l_manyimages_tmpa_tl
\__manyimages_prop_get:nnN { ##1 } { file } \l_manyimages_tmpb_tl
\tl_put_right:Nx \l_manyimages_output_tl
{
{
\exp_not:N \includegraphics
[height=\l_manyimages_finalheight_dim]
{
\tl_if_empty:NF \l_manyimages_tmpa_tl { \l_manyimages_tmpa_tl / }
\l_manyimages_tmpb_tl
}
\tl_if_empty:NF \l_tmpa_tl { \exp_not:N \label { \l_tmpa_tl } }
}
}
\tl_use:N \l_manyimages_output_tl\hfill
}
\unskip
}
\ExplSyntaxOff
\setcounter{lofdepth}{2}
\begin{document}
\listoffigures
\begin{figure}[htp]
\centering
\begin{manysubfloats}{.9\textwidth}
\subimage{example-image}
\subimage[
file=example-image-10x16
]{10x16}
\subimage[
caption=Yikes,
listcaption=Ouch,
path=images
]{example-image-golden}
\subimage[
label=subfig:upright
]{example-image-golden-upright}
\end{manysubfloats}
\caption{Cumulative caption}
\end{figure}
A reference: \subref{subfig:upright}
\end{document}
