35 const QString fileName =
"/usr/share/hwdata/pnp.ids"_L1;
37 if (!file.open(QFile::ReadOnly))
42 constexpr int MaxLineSize = 512;
43 char buf[MaxLineSize];
45 while (!file.atEnd()) {
46 auto read = file.readLine(buf, MaxLineSize);
47 if (read < 0 || read == MaxLineSize)
50 QByteArrayView line(buf, read - 1);
54 if (line.startsWith(
'#'))
57 auto tabPosition = line.indexOf(
'\t');
60 if (tabPosition + 1 == line.size())
63 if (line.first(tabPosition) == id) {
64 auto vendor = line.sliced(tabPosition + 1);
65 result = QString::fromUtf8(vendor.data(), vendor.size());
73bool QEdidParser::parse(
const QByteArray &blob)
75 const quint8 *data =
reinterpret_cast<
const quint8 *>(blob.constData());
76 const size_t length = blob.size();
81 if (data[0] != 0x00 || data[1] != 0xff)
85
86
87
88
95 manufacturer = QString();
104 serialNumber = QString::number(serial);
106 serialNumber = QString();
112 if (data[offset] != 0 || data[offset + 1] != 0 || data[offset + 2] != 0)
116 model = parseEdidString(&data[offset + 5]);
118 identifier = parseEdidString(&data[offset + 5]);
120 serialNumber = parseEdidString(&data[offset + 5]);
124 manufacturer = lookupVendorIdInSystemDatabase(pnpId);
126 if (manufacturer.isEmpty()) {
128 const auto compareVendorId = [](
const QEdidVendorId &vendor,
const char *str)
130 return strncmp(vendor.id, str, 3) < 0;
133 const auto b = std::begin(q_edidVendorIds);
134 const auto e = std::end(q_edidVendorIds);
135 auto it = std::lower_bound(b,
140 if (it != e && strncmp(it->id, pnpId, 3) == 0)
141 manufacturer = QString::fromUtf8(q_edidVendorNames + q_edidVendorNamesOffsets[it - b]);
145 if (manufacturer.isEmpty())
146 manufacturer = QString::fromUtf8(pnpId, std::size(pnpId));
153 if (igamma != 0xff) {
154 gamma = 1.0 + (igamma / 100.0f);
180 redChromaticity.setX(rx * (1.0f / 1024.0f));
181 redChromaticity.setY(ry * (1.0f / 1024.0f));
182 greenChromaticity.setX(gx * (1.0f / 1024.0f));
183 greenChromaticity.setY(gy * (1.0f / 1024.0f));
184 blueChromaticity.setX(bx * (1.0f / 1024.0f));
185 blueChromaticity.setY(by * (1.0f / 1024.0f));
186 whiteChromaticity.setX(wx * (1.0f / 1024.0f));
187 whiteChromaticity.setY(wy * (1.0f / 1024.0f));
190 for (uint i = 1; i < length / 128; ++i) {
191 uint extensionId = data[i * 128];
192 if (extensionId == 0x40) {
196 const uchar desc = data[i * 128 + 0x51];
197 const uchar len = desc & 0x3f;
198 if ((desc & 0xc0) == 0x40) {
201 QList<uint16_t> whiteTRC;
202 whiteTRC.reserve(len + 1);
203 for (uint j = 0; j < len; ++j)
204 whiteTRC[j] = data[0x52 + j] * 0x101;
205 whiteTRC[len] = 0xffff;
206 tables.append(whiteTRC);
207 }
else if ((desc & 0xc0) == 0x80) {
210 QList<uint16_t> redTRC;
211 QList<uint16_t> greenTRC;
212 QList<uint16_t> blueTRC;
213 blueTRC.reserve(len + 1);
214 greenTRC.reserve(len + 1);
215 redTRC.reserve(len + 1);
216 for (uint j = 0; j < len; ++j)
217 blueTRC[j] = data[0x52 + j] * 0x101;
218 blueTRC[len] = 0xffff;
219 for (uint j = 0; j < len; ++j)
220 greenTRC[j] = data[0x61 + j] * 0x101;
221 greenTRC[len] = 0xffff;
222 for (uint j = 0; j < len; ++j)
223 redTRC[j] = data[0x70 + j] * 0x101;
224 redTRC[len] = 0xffff;
225 tables.append(redTRC);
226 tables.append(greenTRC);
227 tables.append(blueTRC);