00001
00002
00003 #include "DisplayResScreen.h"
00004
00005
00006 #include <QStringList>
00007
00008
00009 #include <cmath>
00010
00011 DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh,
00012 double aspectRatio, double refreshRate)
00013 : width(w), height(h), width_mm(mw), height_mm(mh), custom(false)
00014 {
00015 SetAspectRatio(aspectRatio);
00016 if (refreshRate > 0)
00017 refreshRates.push_back(refreshRate);
00018 }
00019
00020 DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh,
00021 const std::vector<double>& rr)
00022 : width(w), height(h), width_mm(mw), height_mm(mh), refreshRates(rr), custom(false)
00023 {
00024 SetAspectRatio(-1.0);
00025 }
00026
00027 DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh,
00028 const std::vector<double>& rr,
00029 const std::map<double, short>& rr2)
00030 : realRates(rr2), width(w), height(h), width_mm(mw), height_mm(mh),
00031 refreshRates(rr), custom(true)
00032 {
00033 SetAspectRatio(-1.0);
00034 }
00035
00036 DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh,
00037 const double* rr, uint rr_length)
00038 : width(w), height(h), width_mm(mw), height_mm(mh), custom(false)
00039 {
00040 SetAspectRatio(-1.0);
00041 for (uint i = 0; i < rr_length; ++i)
00042 refreshRates.push_back(rr[i]);
00043
00044 std::sort(refreshRates.begin(), refreshRates.end());
00045 }
00046
00047 DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh,
00048 const short* rr, uint rr_length)
00049 : width(w), height(h), width_mm(mw), height_mm(mh), custom(false)
00050 {
00051 SetAspectRatio(-1.0);
00052 for (uint i = 0; i < rr_length; ++i)
00053 refreshRates.push_back((double)rr[i]);
00054 std::sort(refreshRates.begin(), refreshRates.end());
00055 }
00056
00057 DisplayResScreen::DisplayResScreen(const QString &str)
00058 : width(0), height(0), width_mm(0), height_mm(0), aspect(-1.0), custom(false)
00059 {
00060 refreshRates.clear();
00061 QStringList slist = str.split(':');
00062 if (slist.size()<4)
00063 slist = str.split(',');
00064 if (slist.size() >= 4)
00065 {
00066 width = slist[0].toInt();
00067 height = slist[1].toInt();
00068 width_mm = slist[2].toInt();
00069 height_mm = slist[3].toInt();
00070 aspect = slist[4].toDouble();
00071 for (int i = 5; i<slist.size(); ++i)
00072 refreshRates.push_back(slist[i].toDouble());
00073 }
00074 }
00075
00076 void DisplayResScreen::SetAspectRatio(double a)
00077 {
00078 if (a>0.0)
00079 aspect = a;
00080 else if (Height_mm())
00081 aspect = ((double)(Width_mm())) / ((double)(Height_mm()));
00082 }
00083
00084 QString DisplayResScreen::toString() const
00085 {
00086 QString str = QString("%1:%2:%3:%4:%5")
00087 .arg(width).arg(height).arg(width_mm).arg(height_mm).arg(aspect);
00088 for (uint i=0; i<refreshRates.size(); ++i)
00089 str.append(QString(":%1").arg(refreshRates[i]));
00090 return str;
00091 }
00092
00093 QStringList DisplayResScreen::Convert(const DisplayResVector& dsr)
00094 {
00095 QStringList slist;
00096 for (uint i=0; i<dsr.size(); ++i)
00097 slist += dsr[i].toString();
00098 return slist;
00099 }
00100
00101 DisplayResVector DisplayResScreen::Convert(const QStringList& slist)
00102 {
00103 std::vector<DisplayResScreen> dsr;
00104 for (int i=0; i<slist.size(); ++i)
00105 dsr.push_back(DisplayResScreen(slist[i]));
00106 return dsr;
00107 }
00108
00109
00110 bool DisplayResScreen::compare_rates(double f1, double f2, double precision)
00111 {
00112 if (((f1 - precision) < f2) &&
00113 ((f1 + precision) > f2))
00114 return true;
00115 else
00116 return false;
00117 }
00118
00119 int DisplayResScreen::FindBestMatch(const DisplayResVector& dsr,
00120 const DisplayResScreen& d,
00121 double& target_rate)
00122 {
00123 double videorate = d.RefreshRate();
00124 bool rate2x = false;
00125 bool end = false;
00126
00127
00128 if ((videorate > 24.5) && (videorate < 30.5))
00129 {
00130 rate2x = true;
00131 videorate *= 2.0;
00132 }
00133
00134
00135 for (uint i=0; i<dsr.size(); ++i)
00136 {
00137 if (dsr[i].Width()==d.Width() && dsr[i].Height()==d.Height())
00138 {
00139 const std::vector<double>& rates = dsr[i].RefreshRates();
00140 if (rates.size() && videorate != 0)
00141 {
00142 while (!end)
00143 {
00144 for (double precision = 0.001;
00145 precision < 1.0;
00146 precision *= 10.0)
00147 {
00148 for (uint j=0; j < rates.size(); ++j)
00149 {
00150
00151 if (compare_rates(videorate,rates[j], precision) ||
00152 (fabs(videorate - fmod(rates[j],videorate))
00153 <= precision) ||
00154 (fmod(rates[j],videorate) <= precision))
00155 {
00156 target_rate = rates[j];
00157 return i;
00158 }
00159 }
00160 }
00161
00162
00163 for (double precision = 0.01;
00164 precision < 2.0;
00165 precision *= 10.0)
00166 {
00167 double rounded = (double) ((int) (videorate + 0.5));
00168 for (uint j=0; j < rates.size(); ++j)
00169 {
00170
00171 if (compare_rates(rounded,rates[j], precision) ||
00172 (fabs(rounded - fmod(rates[j],rounded))
00173 <= precision) ||
00174 (fmod(rates[j],rounded) <= precision))
00175 {
00176 target_rate = rates[j];
00177 return i;
00178 }
00179 }
00180 }
00181 if (rate2x)
00182 {
00183 videorate /= 2.0;
00184 rate2x = false;
00185 }
00186 else
00187 end = true;
00188 }
00189 target_rate = rates[rates.size() - 1];
00190 }
00191 return i;
00192 }
00193 }
00194 return -1;
00195 }
00196
00197 #define extract_key(key) { \
00198 r = (key & ((1<<18) - 1)) / 1000.0; \
00199 h = (key >> 18) & ((1<<16) - 1); \
00200 w = (key >> 34) & ((1<<16) - 1); }
00201
00202 uint64_t DisplayResScreen::FindBestScreen(const DisplayResMap& resmap,
00203 int iwidth, int iheight, double frate)
00204 {
00205 DisplayResMapCIt it;
00206 int w, h;
00207 double r;
00208
00209
00210
00211
00212
00213
00214 for (it = resmap.begin(); it != resmap.end(); ++it)
00215 {
00216 extract_key(it->first);
00217 if (w == iwidth && h == iheight && compare_rates(frate, r, 0.01))
00218 return it->first;
00219 }
00220 for (it = resmap.begin(); it != resmap.end(); ++it)
00221 {
00222 extract_key(it->first);
00223 if (w == iwidth && h == iheight && r == 0)
00224 return it->first;
00225 }
00226 for (it = resmap.begin(); it != resmap.end(); ++it)
00227 {
00228 extract_key(it->first);
00229 if ((w == 0 && h == iheight &&
00230 (compare_rates(frate, r, 0.01) || r == 0)) ||
00231 (w == 0 && h == 0 && compare_rates(frate, r * 2.0, 0.01)) ||
00232 (w == 0 && h == 0 && compare_rates(frate, r, 0.01)))
00233 {
00234 return it->first;
00235 }
00236 }
00237
00238 return 0;
00239 }