// // INStatsMgrPimpl::parseCSVScores // // Parse the CSV input file used to save top scores. // void INStatsMgrPimpl::parseCSVScores(char *input) { Collection<qstring> fields; // Go past the first line of input, which consists of column headers while(*input && *input != '\n') ++input; // Parse each remaining line while(*input) { parseCSVLine(input, fields); if(fields.getLength() >= FIELD_NUMFIELDS) { int recordType = E_StrToNumLinear(recordTypeNames, INSTAT_NUMTYPES, fields[FIELD_RECORDTYPE].constPtr()); if(recordType < INSTAT_NUMTYPES) { in_stat_t *newStats = estructalloc(in_stat_t, 1); newStats->levelkey = fields[FIELD_LEVELKEY ].duplicate(PU_STATIC); newStats->playername = fields[FIELD_PLAYERNAME].duplicate(PU_STATIC); newStats->skill = fields[FIELD_SKILL ].toInt(); newStats->value = fields[FIELD_VALUE ].toInt(); newStats->maxValue = fields[FIELD_MAXVALUE ].toInt(); newStats->recordType = recordType; // add to hash tables statsByLevelKey.addObject(newStats); } } } }
void StatisticsObject::readHeaderFromFile() { try { QFile inputFile(p_srcFilePath); if(inputFile.open(QIODevice::ReadOnly) == false) return; // cleanup old types p_statsTypeList.clear(); // scan headerlines first // also count the lines per Frame for more efficient memory allocation // if an ID is used twice, the data of the first gets overwritten bool typeParsingActive = false; StatisticsType aType; while (!inputFile.atEnd()) { // read one line QByteArray aLineByteArray = inputFile.readLine(); QString aLine(aLineByteArray); // get components of this line QStringList rowItemList = parseCSVLine(aLine, ';'); if (rowItemList[0].isEmpty()) continue; // either a new type or a line which is not header finishes the last type if (((rowItemList[1] == "type") || (rowItemList[0][0] != '%')) && typeParsingActive) { // last type is complete p_statsTypeList.append(aType); // start from scratch for next item aType = StatisticsType(); typeParsingActive = false; // if we found a non-header line, stop here if( rowItemList[0][0] != '%' ) return; } if (rowItemList[1] == "type") // new type { aType.typeID = rowItemList[2].toInt(); aType.readFromRow(rowItemList); // get remaining info from row typeParsingActive = true; } else if (rowItemList[1] == "mapColor") { int id = rowItemList[2].toInt(); // assign color unsigned char r = (unsigned char)rowItemList[3].toInt(); unsigned char g = (unsigned char)rowItemList[4].toInt(); unsigned char b = (unsigned char)rowItemList[5].toInt(); unsigned char a = (unsigned char)rowItemList[6].toInt(); aType.colorMap[id] = QColor(r,g,b,a); } else if (rowItemList[1] == "range") { aType.colorRange = new ColorRange(rowItemList); } else if (rowItemList[1] == "defaultRange") { aType.colorRange = new DefaultColorRange(rowItemList); } else if (rowItemList[1] == "vectorColor") { unsigned char r = (unsigned char)rowItemList[2].toInt(); unsigned char g = (unsigned char)rowItemList[3].toInt(); unsigned char b = (unsigned char)rowItemList[4].toInt(); unsigned char a = (unsigned char)rowItemList[5].toInt(); aType.vectorColor = QColor(r,g,b,a); } else if (rowItemList[1] == "gridColor") { unsigned char r = (unsigned char)rowItemList[2].toInt(); unsigned char g = (unsigned char)rowItemList[3].toInt(); unsigned char b = (unsigned char)rowItemList[4].toInt(); unsigned char a = 255; aType.gridColor = QColor(r,g,b,a); } else if (rowItemList[1] == "scaleFactor") { aType.vectorSampling = rowItemList[2].toInt(); } else if (rowItemList[1] == "scaleToBlockSize") { aType.scaleToBlockSize = (rowItemList[2] == "1"); } else if (rowItemList[1] == "seq-specs") { QString seqName = rowItemList[2]; QString layerId = rowItemList[3]; // For now do nothing with this information. // Show the file name for this item instead. if (rowItemList[4].toInt()>0) setWidth(rowItemList[4].toInt()); if (rowItemList[5].toInt()>0) setHeight(rowItemList[5].toInt()); if (rowItemList[6].toDouble()>0.0) setFrameRate(rowItemList[6].toDouble()); } } inputFile.close(); } // try catch ( const char * str ) { std::cerr << "Error while parsing meta data: " << str << '\n'; setErrorState(QString("Error while parsing meta data: ") + QString(str)); return; } catch (...) { std::cerr << "Error while parsing meta data."; setErrorState(QString("Error while parsing meta data.")); return; } return; }
void StatisticsObject::readStatisticsFromFile(int frameIdx, int typeID) { try { QFile inputFile(p_srcFilePath); if(inputFile.open(QIODevice::ReadOnly) == false) return; StatisticsItem anItem; QTextStream in(&inputFile); Q_ASSERT_X(p_pocTypeStartList.contains(frameIdx) && p_pocTypeStartList[frameIdx].contains(typeID), "StatisticsObject::readStatisticsFromFile", "POC/type not found in file. Do not call this function with POC/types that do not exist."); qint64 startPos = p_pocTypeStartList[frameIdx][typeID]; if (bFileSortedByPOC) { // If the statistics file is sorted by POC we have to start at the first entry of this POC and parse the // file until another POC is encountered. If this is not done, some information from a different typeID // could be ignored during parsing. // Get the position of the first line with the given frameIdx startPos = std::numeric_limits<qint64>::max(); QMap<int,qint64>::iterator it; for (it = p_pocTypeStartList[frameIdx].begin(); it != p_pocTypeStartList[frameIdx].end(); it++) if (it.value() < startPos) startPos = it.value(); } // fast forward in.seek(startPos); while (!in.atEnd()) { // read one line QString aLine = in.readLine(); // get components of this line QStringList rowItemList = parseCSVLine(aLine, ';'); if (rowItemList[0].isEmpty()) continue; int poc = rowItemList[0].toInt(); int type = rowItemList[5].toInt(); // if there is a new poc, we are done here! if( poc != frameIdx ) break; // if there is a new type and this is a non interleaved file, we are done here. if ( !bFileSortedByPOC && type != typeID ) break; int value1 = rowItemList[6].toInt(); int value2 = (rowItemList.count()>=8)?rowItemList[7].toInt():0; int posX = rowItemList[1].toInt(); int posY = rowItemList[2].toInt(); unsigned int width = rowItemList[3].toUInt(); unsigned int height = rowItemList[4].toUInt(); // Check if block is within the image range if (posX + width > p_width || posY + height > p_height) { // Block not in image throw("A block is outside of the specified image size in the statistics file."); } StatisticsType *statsType = getStatisticsType(type); Q_ASSERT_X(statsType != NULL, "StatisticsObject::readStatisticsFromFile", "Stat type not found."); anItem.type = ((statsType->visualizationType == colorMapType) || (statsType->visualizationType == colorRangeType)) ? blockType : arrowType; anItem.positionRect = QRect(posX, posY, width, height); anItem.rawValues[0] = value1; anItem.rawValues[1] = value2; anItem.color = QColor(); if (statsType->visualizationType == colorMapType) { ColorMap colorMap = statsType->colorMap; anItem.color = colorMap[value1]; } else if (statsType->visualizationType == colorRangeType) { if (statsType->scaleToBlockSize) anItem.color = statsType->colorRange->getColor((float)value1 / (float)(anItem.positionRect.width() * anItem.positionRect.height())); else anItem.color = statsType->colorRange->getColor((float)value1); } else if (statsType->visualizationType == vectorType) { // find color anItem.color = statsType->vectorColor; // calculate the vector size anItem.vector[0] = (float)value1 / statsType->vectorSampling; anItem.vector[1] = (float)value2 / statsType->vectorSampling; } // set grid color. if unset for this type, use color of type for grid, too if (statsType->gridColor.isValid()) { anItem.gridColor = statsType->gridColor; } else { anItem.gridColor = anItem.color; } p_statsCache[poc][type].append(anItem); } inputFile.close(); } // try catch ( const char * str ) { std::cerr << "Error while parsing: " << str << '\n'; setErrorState(QString("Error while parsing meta data: ") + QString(str)); return; } catch (...) { std::cerr << "Error while parsing."; setErrorState(QString("Error while parsing meta data.")); return; } return; }
void StatisticsObject::readFrameAndTypePositionsFromFile() { try { QFile inputFile(p_srcFilePath); if(inputFile.open(QIODevice::ReadOnly) == false) return; int lastPOC = INT_INVALID; int lastType = INT_INVALID; int numFrames = 0; qint64 nextSignalAtByte = 0; while (!inputFile.atEnd() && !p_cancelBackgroundParser) { qint64 lineStartPos = inputFile.pos(); // read one line QByteArray aLineByteArray = inputFile.readLine(); QString aLine(aLineByteArray); // get components of this line QStringList rowItemList = parseCSVLine(aLine, ';'); // ignore empty stuff if (rowItemList[0].isEmpty()) continue; // ignore headers if (rowItemList[0][0] == '%') continue; // check for POC/type information int poc = rowItemList[0].toInt(); int typeID = rowItemList[5].toInt(); if (lastType == -1 && lastPOC == -1) { // First POC/type line p_pocTypeStartList[poc][typeID] = lineStartPos; lastType = typeID; lastPOC = poc; numFrames++; p_numberFrames=numFrames; } else if (typeID != lastType && poc == lastPOC) { // we found a new type but the POC stayed the same. // This seems to be an interleaved file // Check if we already collected a start position for this type bFileSortedByPOC = true; lastType = typeID; if (p_pocTypeStartList[poc].contains(typeID)) // POC/type start position already collected continue; p_pocTypeStartList[poc][typeID] = lineStartPos; } else if (poc != lastPOC) { // We found a new POC lastPOC = poc; lastType = typeID; if (bFileSortedByPOC) { // There must not be a start position for any type with this POC already. if (p_pocTypeStartList.contains(poc)) throw "The data for each POC must be continuous in an interleaved statistics file."; } else { // There must not be a start position for this POC/type already. if (p_pocTypeStartList.contains(poc) && p_pocTypeStartList[poc].contains(typeID)) throw "The data for each typeID must be continuous in an non interleaved statistics file."; } p_pocTypeStartList[poc][typeID] = lineStartPos; // update number of frames if( poc+1 > numFrames ) { numFrames = poc+1; p_numberFrames = numFrames; p_endFrame = p_numberFrames - 1; } // Update after parsing 5Mb of the file if( lineStartPos > nextSignalAtByte ) { // Set progress text int percent = (int)((double)lineStartPos * 100 / (double)p_numBytes); p_status = QString("Parsing (") + QString::number(percent) + QString("%) ..."); emit informationChanged(); nextSignalAtByte = lineStartPos + 5000000; } } // typeID and POC stayed the same // do nothing } p_status = "OK"; emit informationChanged(); inputFile.close(); } // try catch ( const char * str ) { std::cerr << "Error while parsing meta data: " << str << '\n'; setErrorState(QString("Error while parsing meta data: ") + QString(str)); return; } catch (...) { std::cerr << "Error while parsing meta data."; setErrorState(QString("Error while parsing meta data.")); return; } return; }