34 const QString fileName =
"/usr/share/hwdata/pnp.ids"_L1;
36 if (!file.open(QFile::ReadOnly))
41 constexpr int MaxLineSize = 512;
42 char buf[MaxLineSize];
44 while (!file.atEnd()) {
45 auto read = file.readLine(buf, MaxLineSize);
46 if (read < 0 || read == MaxLineSize)
49 QByteArrayView line(buf, read - 1);
53 if (line.startsWith(
'#'))
56 auto tabPosition = line.indexOf(
'\t');
59 if (tabPosition + 1 == line.size())
62 if (line.first(tabPosition) == id) {
63 auto vendor = line.sliced(tabPosition + 1);
64 result = QString::fromUtf8(vendor.data(), vendor.size());
72bool QEdidParser::parse(
const QByteArray &blob)
74 const quint8 *data =
reinterpret_cast<
const quint8 *>(blob.constData());
75 const size_t length = blob.size();
80 if (data[0] != 0x00 || data[1] != 0xff)
84
85
86
87
94 manufacturer = QString();
103 serialNumber = QString::number(serial);
105 serialNumber = QString();
111 if (data[offset] != 0 || data[offset + 1] != 0 || data[offset + 2] != 0)
115 model = parseEdidString(&data[offset + 5]);
117 identifier = parseEdidString(&data[offset + 5]);
119 serialNumber = parseEdidString(&data[offset + 5]);
123 manufacturer = lookupVendorIdInSystemDatabase(pnpId);
125 if (manufacturer.isEmpty()) {
127 const auto compareVendorId = [](
const QEdidVendorId &vendor,
const char *str)
129 return strncmp(vendor.id, str, 3) < 0;
132 const auto b = std::begin(q_edidVendorIds);
133 const auto e = std::end(q_edidVendorIds);
134 auto it = std::lower_bound(b,
139 if (it != e && strncmp(it->id, pnpId, 3) == 0)
140 manufacturer = QString::fromUtf8(q_edidVendorNames + q_edidVendorNamesOffsets[it - b]);
144 if (manufacturer.isEmpty())
145 manufacturer = QString::fromUtf8(pnpId, std::size(pnpId));
152 if (igamma != 0xff) {
153 gamma = 1.0 + (igamma / 100.0f);
179 redChromaticity.setX(rx * (1.0f / 1024.0f));
180 redChromaticity.setY(ry * (1.0f / 1024.0f));
181 greenChromaticity.setX(gx * (1.0f / 1024.0f));
182 greenChromaticity.setY(gy * (1.0f / 1024.0f));
183 blueChromaticity.setX(bx * (1.0f / 1024.0f));
184 blueChromaticity.setY(by * (1.0f / 1024.0f));
185 whiteChromaticity.setX(wx * (1.0f / 1024.0f));
186 whiteChromaticity.setY(wy * (1.0f / 1024.0f));
189 for (uint i = 1; i < length / 128; ++i) {
190 uint extensionId = data[i * 128];
191 if (extensionId == 0x40) {
195 const uchar desc = data[i * 128 + 0x51];
196 const uchar len = desc & 0x3f;
197 if ((desc & 0xc0) == 0x40) {
200 QList<uint16_t> whiteTRC;
201 whiteTRC.reserve(len + 1);
202 for (uint j = 0; j < len; ++j)
203 whiteTRC[j] = data[0x52 + j] * 0x101;
204 whiteTRC[len] = 0xffff;
205 tables.append(whiteTRC);
206 }
else if ((desc & 0xc0) == 0x80) {
209 QList<uint16_t> redTRC;
210 QList<uint16_t> greenTRC;
211 QList<uint16_t> blueTRC;
212 blueTRC.reserve(len + 1);
213 greenTRC.reserve(len + 1);
214 redTRC.reserve(len + 1);
215 for (uint j = 0; j < len; ++j)
216 blueTRC[j] = data[0x52 + j] * 0x101;
217 blueTRC[len] = 0xffff;
218 for (uint j = 0; j < len; ++j)
219 greenTRC[j] = data[0x61 + j] * 0x101;
220 greenTRC[len] = 0xffff;
221 for (uint j = 0; j < len; ++j)
222 redTRC[j] = data[0x70 + j] * 0x101;
223 redTRC[len] = 0xffff;
224 tables.append(redTRC);
225 tables.append(greenTRC);
226 tables.append(blueTRC);