void NetPanzerFileStruct::save(const std::string& filename) { if (impl->tilemap.is_null()) return; unsigned char netp_id_header[64]; strcpy(reinterpret_cast<char*>(netp_id_header), impl->id_header.c_str()); unsigned short id = 0; // ? char name[256]; strcpy(name, impl->name.c_str()); char description[1024]; strcpy(description, impl->description.c_str()); unsigned short x_size = impl->tilemap.get_width(); unsigned short y_size = impl->tilemap.get_height(); char tile_set[256] = "summer12mb.tls"; unsigned short thumbnail_x_pix = impl->tilemap.get_width(); unsigned short thumbnail_y_pix = impl->tilemap.get_height(); std::ofstream out(filename.c_str()); // FIXME: Not endian clean out.write(reinterpret_cast<char*>(&netp_id_header), sizeof(netp_id_header)); out.write(reinterpret_cast<char*>(&id), sizeof(short)); out.write(reinterpret_cast<char*>(&name), sizeof(name)); out.write(reinterpret_cast<char*>(&description), sizeof(description)); out.write(reinterpret_cast<char*>(&x_size), sizeof(short)); out.write(reinterpret_cast<char*>(&y_size), sizeof(short)); out.write(reinterpret_cast<char*>(&tile_set), sizeof(tile_set)); out.write(reinterpret_cast<char*>(&thumbnail_x_pix), sizeof(short)); out.write(reinterpret_cast<char*>(&thumbnail_y_pix), sizeof(short)); std::vector<unsigned short> vec(x_size * y_size); int tile_count = impl->tilemap.get_tileset().get_tiles().size(); Field<int>* field = impl->tilemap.get_field(); for(int i = 0; i < x_size * y_size; ++i) { // Fill everything that isn't a valid tile with grass if ((*field)[i] >= 0 && (*field)[i] < tile_count) vec[i] = (*field)[i]; else vec[i] = 8097 + rand()%16; } out.write(reinterpret_cast<char*>(&(*vec.begin())), sizeof(unsigned short)*vec.size()); // Generate thumbnail std::vector<unsigned char> thumbnail(x_size * y_size); for(int i = 0; i < int(thumbnail.size()); ++i) { Tile* tile = impl->tileset.create((*field)[i]); if (tile) thumbnail[i] = find_nearest_color(NetPanzerData::instance()->get_palette(), tile->get_color()); } out.write(reinterpret_cast<char*>(&(*thumbnail.begin())), sizeof(unsigned char)*thumbnail.size()); }
TiAnalyticsObject::TiAnalyticsObject(NativeObjectFactory* objectFactory) : TiProxy("Analytics"), sequence_(1) { objectFactory_ = objectFactory; // if analytics is false just return bool analytics = defaultSettings.value("analytics").toBool(); if (analytics == true) { // get unique application id QString aguid = defaultSettings.value("aguid").toString(); aguid_ = aguid.toLocal8Bit(); // get unique mobile device id bb::device::HardwareInfo hdi; QString mid = hdi.pin(); mid_ = mid.toLocal8Bit(); // generate the session id QString sid = QUuid::createUuid().toString(); sid.replace("{", ""); sid.replace("}", ""); sid_ = sid.toLocal8Bit(); // get deploy type if development or production QString deployType = defaultSettings.value("deploytype").toString(); deployType_ = deployType.toLocal8Bit(); // application version QString appVersion = defaultSettings.value("version").toString(); appVersion_ = appVersion.toLocal8Bit(); QUrl analyticsSite("https://api.appcelerator.net/p/v3/mobile-track/" + aguid); request_.setUrl(analyticsSite); // Async callbacks to notify application of HTTP events eventHandler_ = new TiAnalyticsHandler(this); QObject::connect(&networkAccessManager_, SIGNAL(finished(QNetworkReply*)), eventHandler_, SLOT(finished(QNetworkReply*))); QObject::connect(&networkAccessManager_, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)), eventHandler_, SLOT(errors(QNetworkReply*))); // Hook application life cycle events QObject::connect(bb::cascades::Application::instance(), SIGNAL(thumbnail()), eventHandler_, SLOT(thumbnail())); QObject::connect(bb::cascades::Application::instance(), SIGNAL(fullscreen()), eventHandler_, SLOT(fullscreen())); QObject::connect(bb::cascades::Application::instance(), SIGNAL(manualExit()), eventHandler_, SLOT(manualExit())); if (createAnalyticsDatabase()) { addAnalyticsEvent("ti.enroll"); } addAnalyticsEvent("ti.start"); sendPendingAnalyticsEvents(); // Set up timer and every 10 minutes send out analytics events if any are pending TiAnalyticsHandler* eventHandler = new TiAnalyticsHandler(this); timer_ = new QTimer(eventHandler); QObject::connect(timer_, SIGNAL(timeout()), eventHandler, SLOT(sendPendingRequests())); timer_->start(60000*10); }
const QPixmap ImageItem::pixmap() { if (!lock.tryLock()) return QPixmap(); thumbnail(); if (!thumb.valid()) { lock.unlock(); return QPixmap(); } else if (!pix) { QImage thumbQ(thumb(0,0), 640, 480, QImage::Format_RGB888); pix.reset(new QPixmap(QPixmap::fromImage(thumbQ))); } lock.unlock(); return *pix; }
void ThemeCreationWizard::on_pushButton_clicked() { QString fileName = QFileDialog::getOpenFileName(this, "Choose a thumbnail image", QtHelpers::DesktopLocation(), "PNG File (*.png)"); if (fileName == "") return; QPixmap thumbnail(fileName); if (thumbnail.isNull() || thumbnail.width() != 64 || thumbnail.height() != 64) { QMessageBox::warning(this, "Invalid Image", "Thumbnail must be a 64x64 PNG image."); return; } ui->imgThumbnail->setPixmap(thumbnail); }
QVariant CQSpreadsheetListModel::data(const QModelIndex& index, int role) const { if (!index.isValid() || !d->map) { return QVariant(); } switch(role) { case SheetNameRole: return d->map->sheet(index.row())->sheetName(); case ThumbnailRole: { if (d->thumbnails.contains(index.row())) { return d->thumbnails.value(index.row()); } QPixmap thumbnail(d->thumbnailSize); QRect rect(QPoint(0,0), d->thumbnailSize); QPainter p(&thumbnail); p.fillRect(rect, Qt::white); Calligra::Sheets::SheetView sheetView(d->map->sheet(index.row())); qreal zoom = 0.5; KoZoomHandler zoomHandler; zoomHandler.setZoom(zoom); p.setClipRect(rect); p.scale(zoom, zoom); sheetView.setViewConverter(&zoomHandler); QRectF area = zoomHandler.viewToDocument(rect); QRect range = sheetView.sheet()->documentToCellCoordinates(area).adjusted(0, 0, 2, 2); sheetView.setPaintCellRange(range); sheetView.paintCells(p, area, QPointF(0,0)); d->thumbnails.insert(index.row(), thumbnail); return thumbnail; } default: break; } return QVariant(); }
void ImageItem::load() { if (error) return; lock.lock(); if (src.valid() || fname.size() == 0) { lock.unlock(); return; } FCam::DNGFrame frame = FCam::loadDNG(this->fullPath().toStdString()); src = frame; thumb = frame.thumbnail(); if (src.valid() && !thumb.valid()) thumbnail(); if (!src.valid()) error = true; saved = true; loaded = true; loadedThumb = true; loading = false; loadingThumb = false; lock.unlock(); }
QVector<QImage> CSThumbProviderWords::createThumbnails(const QSize &thumbSize) { KWCanvasItem *canvasItem = static_cast<KWCanvasItem*>(m_doc->documentPart()->canvasItem(m_doc)); KoZoomHandler zoomHandler; while (!m_doc->layoutFinishedAtleastOnce()) { QCoreApplication::processEvents(); if (!QCoreApplication::hasPendingEvents()) break; } KWPageManager *pageManager = m_doc->pageManager(); KoShapeManager *shapeManager = canvasItem->shapeManager(); QVector<QImage> thumbnails; foreach(const KWPage &page, pageManager->pages()) { QRectF pRect(page.rect()); KoPageLayout layout; layout.width = pRect.width(); layout.height = pRect.height(); KoPAUtil::setZoom(layout, thumbSize, zoomHandler); QRect pageRect = KoPAUtil::pageRect(layout, thumbSize, zoomHandler); QImage thumbnail(thumbSize, QImage::Format_RGB32); thumbnail.fill(QColor(Qt::white).rgb()); QPainter p(&thumbnail); QImage img = page.thumbnail(pageRect.size(), shapeManager); p.drawImage(pageRect, img); p.setPen(Qt::black); p.drawRect(pageRect); thumbnails.append(thumbnail); } return thumbnails; }
int main( int argc, char **argv ) { GOptionContext *context; GError *error = NULL; int i; if( im_init_world( argv[0] ) ) error_exit( "unable to start VIPS" ); textdomain( GETTEXT_PACKAGE ); setlocale( LC_ALL, "" ); context = g_option_context_new( _( "- thumbnail generator" ) ); g_option_context_add_main_entries( context, options, GETTEXT_PACKAGE ); g_option_context_add_group( context, im_get_option_group() ); if( !g_option_context_parse( context, &argc, &argv, &error ) ) { if( error ) { fprintf( stderr, "%s\n", error->message ); g_error_free( error ); } error_exit( "try \"%s --help\"", g_get_prgname() ); } g_option_context_free( context ); for( i = 1; i < argc; i++ ) if( thumbnail( argv[i] ) ) { fprintf( stderr, "%s: unable to thumbnail %s\n", argv[0], argv[i] ); fprintf( stderr, "%s", im_error_buffer() ); im_error_clear(); } vips_shutdown(); return( 0 ); }
void StartPageModel::reloadTile(const QModelIndex &index, bool full) { const QUrl url(index.data(BookmarksModel::UrlRole).toUrl()); if (url.isValid()) { QSize size; if (SettingsManager::getValue(SettingsManager::StartPage_TileBackgroundModeOption) == QLatin1String("thumbnail")) { size.setWidth(SettingsManager::getValue(SettingsManager::StartPage_TileWidthOption).toInt()); size.setHeight(SettingsManager::getValue(SettingsManager::StartPage_TileHeightOption).toInt()); } else if (!full) { return; } if (url.scheme() == QLatin1String("about")) { const AddonsManager::SpecialPageInformation information(AddonsManager::getSpecialPage(url.path())); QPixmap thumbnail(size); thumbnail.fill(); QPainter painter(&thumbnail); information.icon.paint(&painter, QRect(QPoint(0, 0), size)); m_reloads[index.data(BookmarksModel::UrlRole).toUrl()] = qMakePair(index.data(BookmarksModel::IdentifierRole).toULongLong(), full); thumbnailCreated(url, thumbnail, information.getTitle()); } else if (AddonsManager::getWebBackend()->requestThumbnail(url, size)) { m_reloads[index.data(BookmarksModel::UrlRole).toUrl()] = qMakePair(index.data(BookmarksModel::IdentifierRole).toULongLong(), full); } } }
void DeleteJob::deleteImages() { int total = m_images.count(); int deleted = 1; foreach(QModelIndex image, m_images) { QString fileName = image.data(ImageModel::ImageFilepathRole).toString(); QString thumbName = image.data(ImageModel::ImageThumbnailPathRole).toString(); QString name = image.data(ImageModel::ImageNameRole).toString(); QImage thumbnail(thumbName); emit progress(deleted, total, name, thumbnail); if (!QFile::remove(thumbName) || !QFile::remove(fileName)) { emit failed(tr("Couldn't deleted the image %1.").arg(name), ErrorHandler::Warning); } else { MetaDataManager::self()->unregisterImage(image.data(ImageModel::IdRole).toInt(), image.parent().data(ImageModel::IdRole).toInt()); emit remove(image); } deleted++; }
void AndroidRetracer::run() { m_androidUtils.reloadAdb(); QString errorStr; bool setupRet; QMetaObject::invokeMethod(this, "setup", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, setupRet), Q_ARG(QString *, &errorStr)); if (!setupRet) { emit finished(errorStr); return; } if (!m_androidUtils.runAdb(QStringList() << _("shell") << _("am") << _("start") << _("-n") << packageName + activityName)) { emit finished(tr("Can't start apitrace application")); return; } QByteArray which; if (!m_androidUtils.runAdb(QStringList() << _("shell") << _("readlink") << _("$(which ps)") , &which)) { emit finished(tr("Can't start adb")); return; } bool isBusyBox = which.startsWith("busybox"); QStringList psArgs; psArgs << _("shell") << _("ps"); if (isBusyBox) psArgs << _("-w"); qint64 processPID; bool wasStarted = false; QTime startTime; startTime.start(); QTcpSocket stdoutSocket; QTcpSocket stderrSocket; ImageHash thumbnails; QVariantMap parsedJson; trace::Profile* profile = isProfiling() ? new trace::Profile() : NULL; QList<ApiTraceError> errors; QRegExp regexp("(^\\d+): +(\\b\\w+\\b): ([^\\r\\n]+)[\\r\\n]*$"); QString msg = QLatin1String("Replay finished!"); QByteArray ubjsonBuffer; QByteArray outputBuffer; bool keepGoing = true; while(keepGoing) { if (!wasStarted || startTime.elapsed() > 1000) { QByteArray psOut; m_androidUtils.runAdb(psArgs, &psOut); processPID = extractPid(psOut); if (wasStarted) startTime.restart(); } if (processPID == -1) { if (wasStarted) { break; } else { if (startTime.elapsed() > 3000) { // wait 3 seconds to start emit finished(tr("Unable to start retrace on device.")); return; } } msleep(100); continue; } // we have a valid pid, it means the application started if (!wasStarted) { // connect the sockets int tries = 0; do { stdoutSocket.connectToHost(QHostAddress::LocalHost, m_stdoutPort); } while (!stdoutSocket.waitForConnected(100) && ++tries < 10); if (stdoutSocket.state() != QAbstractSocket::ConnectedState) { emit finished(tr("Can't connect to stdout socket.")); return; } // Android doesn't suport GPU and PPD profiling (at leats not on my devices) //setProfiling(false, isProfilingCpu(), false); QString args = (retraceArguments() << m_androdiFileName).join(" ") + _("\n"); stdoutSocket.write(args.toUtf8()); if (!stdoutSocket.waitForBytesWritten()) { emit finished(tr("Can't send params.")); return; } stderrSocket.connectToHost(QHostAddress::LocalHost, m_stderrPort); stderrSocket.waitForConnected(100); if (stderrSocket.state() != QAbstractSocket::ConnectedState) { emit finished(tr("Can't connect to stderr socket.")); return; } wasStarted = true; } // We are going to read both channels at the same time // read stdout channel if (stdoutSocket.waitForReadyRead(100)) { if (captureState()) ubjsonBuffer.append(stdoutSocket.readAll()); else if (captureThumbnails()) { // read one image image::PNMInfo info; QByteArray header; int headerLines = 3; // assume no optional comment line for (int headerLine = 0; headerLine < headerLines; ++headerLine) { QByteArray line = readLine(stdoutSocket); if (line.isEmpty()) { keepGoing = false; break; } header += line; // if header actually contains optional comment line, ... if (headerLine == 1 && line[0] == '#') { ++headerLines; } } const char *headerEnd = image::readPNMHeader(header.constData(), header.size(), info); // if invalid PNM header was encountered, ... if (headerEnd == NULL || info.channelType != image::TYPE_UNORM8) { qDebug() << "error: invalid snapshot stream encountered"; keepGoing = false; break; } unsigned channels = info.channels; unsigned width = info.width; unsigned height = info.height; // qDebug() << "channels: " << channels << ", width: " << width << ", height: " << height"; QImage snapshot = QImage(width, height, channels == 1 ? QImage::Format_Mono : QImage::Format_RGB888); int rowBytes = channels * width; for (int y = 0; y < height; ++y) { unsigned char *scanLine = snapshot.scanLine(y); if (!read(stdoutSocket, (char *) scanLine, rowBytes)) { keepGoing = false; break; } } QImage thumb = thumbnail(snapshot); thumbnails.insert(info.commentNumber, thumb); } else if (isProfiling()) { QByteArray line = readLine(stdoutSocket); if (line.isEmpty()) { keepGoing = false; break; } line.append('\0'); trace::Profiler::parseLine(line.constData(), profile); } else { outputBuffer.append(stdoutSocket.readAll()); } } // read stderr channel if (stderrSocket.waitForReadyRead(5) && stderrSocket.canReadLine()) { QString line = stderrSocket.readLine(); if (regexp.indexIn(line) != -1) { ApiTraceError error; error.callIndex = regexp.cap(1).toInt(); error.type = regexp.cap(2); error.message = regexp.cap(3); errors.append(error); } else if (!errors.isEmpty()) { // Probably a multiligne message ApiTraceError &previous = errors.last(); if (line.endsWith("\n")) { line.chop(1); } previous.message.append('\n'); previous.message.append(line); } } } if (outputBuffer.size() < 80) msg = outputBuffer; if (captureState()) { QBuffer io(&ubjsonBuffer); io.open(QIODevice::ReadOnly); parsedJson = decodeUBJSONObject(&io).toMap(); ApiTraceState *state = new ApiTraceState(parsedJson); emit foundState(state); } if (captureThumbnails() && !thumbnails.isEmpty()) { emit foundThumbnails(thumbnails); } if (isProfiling() && profile) { emit foundProfile(profile); } if (!errors.isEmpty()) { emit retraceErrors(errors); } emit finished(msg); }
bool TelegramImageElement::thumbnailDownloaded() const { return !thumbnail().isEmpty(); }
void VersionInfo::init() { setMinimumSize(QSize(16,400)); QFont boldFont = this->font(); boldFont.setBold(true); QDesktopWidget *desktop = QApplication::desktop(); double imageScale = ((double)desktop->availableGeometry(desktop->screenNumber(this)).width())/400.0; if (imageScale > 1.0) imageScale = 1.0; int imageSize = (int)(55 * imageScale); int finalSize = (int)(60 * imageScale); QVBoxLayout *vBoxLayout = new QVBoxLayout(this); vBoxLayout->setMargin( 0 ); vBoxLayout->setSpacing( 0 ); QGridLayout *gridLayout1 = new QGridLayout; gridLayout1->setSpacing( 4 ); gridLayout1->setMargin( 0 ); gridLayout1->setColumnMinimumWidth(0, 20 ); QLabel *qtopiaLogo = new QLabel(this); QThumbnail thumbnail(":image/qpe-logo"); qtopiaLogo->setPixmap(thumbnail.pixmap(QSize(imageSize, imageSize))); qtopiaLogo->setFixedSize( finalSize, finalSize ); gridLayout1->addWidget(qtopiaLogo, 0, 0, 1, 1); QVBoxLayout *vBoxLayout1 = new QVBoxLayout; vBoxLayout1->setMargin( 0 ); vBoxLayout1->setSpacing( 3 ); QLabel *qtopiaName = new QLabel(this); qtopiaName->setFont(boldFont); qtopiaName->setText(tr("QtMoko")); vBoxLayout1->addWidget(qtopiaName); QLabel *qtopiaVersion = new QLabel(this); qtopiaVersion->setWordWrap(true); qtopiaVersion->setText(tr("Version:") + ' ' + Qtopia::version() + '\n' + tr("Qt version:") + ' ' + QT_VERSION_STR); vBoxLayout1->addWidget(qtopiaVersion); vBoxLayout1->addSpacing( 10 ); QLabel *qtopiaCopyright = new QLabel(this); qtopiaCopyright->setText(tr( "Copyright \251 %1", "%1 = 'year'" ).arg(QT_EXTENDED_COPYRIGHT_YEAR)); vBoxLayout1->addWidget(qtopiaCopyright); QLabel* qtopiaCopyright1 = new QLabel( this ); qtopiaCopyright1->setWordWrap( true ); qtopiaCopyright1->setText( QT_EXTENDED_COPYRIGHT_COMPANY ); vBoxLayout1->addWidget(qtopiaCopyright1); vBoxLayout1->addSpacing( 10 ); QLabel *qtopiaBuild = new QLabel(this); qtopiaBuild->setWordWrap( true ); QString builder( BUILDER ); int atIndex = builder.indexOf( QChar('@') ); int dotIndex = -1; if ( atIndex >= 0 ) dotIndex = builder.indexOf( QChar('.'), atIndex ); if ( dotIndex >= 0 ) builder = builder.left( dotIndex ); qtopiaBuild->setText(tr("Built by\n%1", "%1 = name").arg(builder)); vBoxLayout1->addWidget(qtopiaBuild); qtopiaBuild = new QLabel(this); qtopiaBuild->setText(tr("Built on %1","1=date").arg(__DATE__)); vBoxLayout1->addWidget(qtopiaBuild); QSpacerItem *spacerItem = new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding); vBoxLayout1->addItem(spacerItem); gridLayout1->addLayout(vBoxLayout1, 0, 1, 2, 1); vBoxLayout->addLayout(gridLayout1); QGridLayout *gridLayout2 = new QGridLayout; gridLayout2->setColumnMinimumWidth(0, 20 ); gridLayout2->setSpacing( 4 ); gridLayout2->setMargin( 0 ); QLabel *linuxLogo = new QLabel(this); QThumbnail thumbnail2(":image/tux-logo"); linuxLogo->setPixmap(thumbnail2.pixmap(QSize(imageSize, imageSize))); linuxLogo->setFixedSize( finalSize, finalSize ); gridLayout2->addWidget(linuxLogo, 0, 0, 1, 1); QVBoxLayout *vBoxLayout2 = new QVBoxLayout; vBoxLayout2->setMargin( 0 ); vBoxLayout2->setSpacing( 3 ); QLabel *linuxName = new QLabel(this); linuxName->setFont(boldFont); linuxName->setText(tr("Linux Kernel")); vBoxLayout2->addWidget(linuxName); QString kernelVersionString; QString compiledByString; QFile file("/proc/version"); if(file.open(QFile::ReadOnly)) { QTextStream t( &file ); QString v; t >> v; t >> v; t >> v; kernelVersionString = v.left( 20 ); t >> v; compiledByString = v; file.close(); }
void ApiSurface::contentsFromBase64(const QByteArray &base64) { QByteArray dataArray = QByteArray::fromBase64(base64); m_image.loadFromData(dataArray, "png"); m_thumb = thumbnail(m_image); }
void RetraceProcess::replayFinished(int exitCode, QProcess::ExitStatus exitStatus) { QString msg; if (exitStatus != QProcess::NormalExit) { msg = QLatin1String("Process crashed"); } else if (exitCode != 0) { msg = QLatin1String("Process exited with non zero exit code"); } else { if (m_captureState || m_captureThumbnails) { if (m_captureState) { bool ok = false; m_process->setReadChannel(QProcess::StandardOutput); QVariantMap parsedJson = m_jsonParser->parse(m_process, &ok).toMap(); ApiTraceState *state = new ApiTraceState(parsedJson); emit foundState(state); msg = tr("State fetched."); } if (m_captureThumbnails) { m_process->setReadChannel(QProcess::StandardOutput); QList<QImage> thumbnails; while (!m_process->atEnd()) { unsigned channels = 0; unsigned width = 0; unsigned height = 0; char header[512]; qint64 headerSize = 0; int headerLines = 3; // assume no optional comment line for (int headerLine = 0; headerLine < headerLines; ++headerLine) { qint64 headerRead = m_process->readLine(&header[headerSize], sizeof(header) - headerSize); // if header actually contains optional comment line, ... if (headerLine == 1 && header[headerSize] == '#') { ++headerLines; } headerSize += headerRead; } const char *headerEnd = image::readPNMHeader(header, headerSize, &channels, &width, &height); // if invalid PNM header was encountered, ... if (header == headerEnd) { qDebug() << "error: invalid snapshot stream encountered\n"; break; } //qDebug() << "channels: " << channels << ", width: " << width << ", height: " << height << "\n"; QImage snapshot = QImage(width, height, channels == 1 ? QImage::Format_Mono : QImage::Format_RGB888); int rowBytes = channels * width; for (int y = 0; y < height; ++y) { unsigned char *scanLine = snapshot.scanLine(y); m_process->read((char *) scanLine, rowBytes); } QImage thumb = thumbnail(snapshot); thumbnails.append(thumb); } emit foundThumbnails(thumbnails); msg = tr("Thumbnails fetched."); } } else { QByteArray output; output = m_process->readAllStandardOutput(); msg = QString::fromUtf8(output); } } m_process->setReadChannel(QProcess::StandardError); QList<ApiTraceError> errors; QRegExp regexp("(^\\d+): +(\\b\\w+\\b): ([^\\r\\n]+)[\\r\\n]*$"); while (!m_process->atEnd()) { QString line = m_process->readLine(); if (regexp.indexIn(line) != -1) { ApiTraceError error; error.callIndex = regexp.cap(1).toInt(); error.type = regexp.cap(2); error.message = regexp.cap(3); errors.append(error); } } if (!errors.isEmpty()) { emit retraceErrors(errors); } emit finished(msg); }
/** * Starting point for the retracing thread. * * Overrides QThread::run(). */ void Retracer::run() { QString msg = QLatin1String("Replay finished!"); /* * Construct command line */ QString prog; QStringList arguments; switch (m_api) { case trace::API_GL: prog = QLatin1String("glretrace"); break; case trace::API_EGL: prog = QLatin1String("eglretrace"); break; case trace::API_DX: case trace::API_D3D7: case trace::API_D3D8: case trace::API_D3D9: case trace::API_DXGI: #ifdef Q_OS_WIN prog = QLatin1String("d3dretrace"); #else prog = QLatin1String("wine"); arguments << QLatin1String("d3dretrace.exe"); #endif break; default: emit finished(QLatin1String("Unsupported API")); return; } if (m_singlethread) { arguments << QLatin1String("--singlethread"); } if (m_captureState) { arguments << QLatin1String("-D"); arguments << QString::number(m_captureCall); } else if (m_captureThumbnails) { arguments << QLatin1String("-s"); // emit snapshots arguments << QLatin1String("-"); // emit to stdout } else if (isProfiling()) { if (m_profileGpu) { arguments << QLatin1String("--pgpu"); } if (m_profileCpu) { arguments << QLatin1String("--pcpu"); } if (m_profilePixels) { arguments << QLatin1String("--ppd"); } } else { if (m_doubleBuffered) { arguments << QLatin1String("--db"); } else { arguments << QLatin1String("--sb"); } if (m_benchmarking) { arguments << QLatin1String("-b"); } } arguments << m_fileName; /* * Support remote execution on a separate target. */ if (m_remoteTarget.length() != 0) { arguments.prepend(prog); arguments.prepend(m_remoteTarget); prog = QLatin1String("ssh"); } /* * Start the process. */ QProcess process; process.start(prog, arguments, QIODevice::ReadOnly); if (!process.waitForStarted(-1)) { emit finished(QLatin1String("Could not start process")); return; } /* * Process standard output */ QList<QImage> thumbnails; QVariantMap parsedJson; trace::Profile* profile = NULL; process.setReadChannel(QProcess::StandardOutput); if (process.waitForReadyRead(-1)) { BlockingIODevice io(&process); if (m_captureState) { /* * Parse JSON from the output. * * XXX: QJSON's scanner is inneficient as it abuses single * character QIODevice::peek (not cheap), instead of maintaining a * lookahead character on its own. */ bool ok = false; QJson::Parser jsonParser; // Allow Nan/Infinity jsonParser.allowSpecialNumbers(true); #if 0 parsedJson = jsonParser.parse(&io, &ok).toMap(); #else /* * XXX: QJSON expects blocking IO, and it looks like * BlockingIODevice does not work reliably in all cases. */ process.waitForFinished(-1); parsedJson = jsonParser.parse(&process, &ok).toMap(); #endif if (!ok) { msg = QLatin1String("failed to parse JSON"); } } else if (m_captureThumbnails) { /* * Parse concatenated PNM images from output. */ while (!io.atEnd()) { unsigned channels = 0; unsigned width = 0; unsigned height = 0; char header[512]; qint64 headerSize = 0; int headerLines = 3; // assume no optional comment line for (int headerLine = 0; headerLine < headerLines; ++headerLine) { qint64 headerRead = io.readLine(&header[headerSize], sizeof(header) - headerSize); // if header actually contains optional comment line, ... if (headerLine == 1 && header[headerSize] == '#') { ++headerLines; } headerSize += headerRead; } const char *headerEnd = image::readPNMHeader(header, headerSize, &channels, &width, &height); // if invalid PNM header was encountered, ... if (header == headerEnd) { qDebug() << "error: invalid snapshot stream encountered"; break; } // qDebug() << "channels: " << channels << ", width: " << width << ", height: " << height"; QImage snapshot = QImage(width, height, channels == 1 ? QImage::Format_Mono : QImage::Format_RGB888); int rowBytes = channels * width; for (int y = 0; y < height; ++y) { unsigned char *scanLine = snapshot.scanLine(y); qint64 readBytes = io.read((char *) scanLine, rowBytes); Q_ASSERT(readBytes == rowBytes); (void)readBytes; } QImage thumb = thumbnail(snapshot); thumbnails.append(thumb); } Q_ASSERT(process.state() != QProcess::Running); } else if (isProfiling()) { profile = new trace::Profile(); while (!io.atEnd()) { char line[256]; qint64 lineLength; lineLength = io.readLine(line, 256); if (lineLength == -1) break; trace::Profiler::parseLine(line, profile); } } else { QByteArray output; output = process.readAllStandardOutput(); if (output.length() < 80) { msg = QString::fromUtf8(output); } } } /* * Wait for process termination */ process.waitForFinished(-1); if (process.exitStatus() != QProcess::NormalExit) { msg = QLatin1String("Process crashed"); } else if (process.exitCode() != 0) { msg = QLatin1String("Process exited with non zero exit code"); } /* * Parse errors. */ QList<ApiTraceError> errors; process.setReadChannel(QProcess::StandardError); QRegExp regexp("(^\\d+): +(\\b\\w+\\b): ([^\\r\\n]+)[\\r\\n]*$"); while (!process.atEnd()) { QString line = process.readLine(); if (regexp.indexIn(line) != -1) { ApiTraceError error; error.callIndex = regexp.cap(1).toInt(); error.type = regexp.cap(2); error.message = regexp.cap(3); errors.append(error); } else if (!errors.isEmpty()) { // Probably a multiligne message ApiTraceError &previous = errors.last(); if (line.endsWith("\n")) { line.chop(1); } previous.message.append('\n'); previous.message.append(line); } } /* * Emit signals */ if (m_captureState) { ApiTraceState *state = new ApiTraceState(parsedJson); emit foundState(state); } if (m_captureThumbnails && !thumbnails.isEmpty()) { emit foundThumbnails(thumbnails); } if (isProfiling() && profile) { emit foundProfile(profile); } if (!errors.isEmpty()) { emit retraceErrors(errors); } emit finished(msg); }
/** * Starting point for the retracing thread. * * Overrides QThread::run(). */ void Retracer::run() { QString msg = QLatin1String("Replay finished!"); /* * Construct command line */ QString prog; QStringList arguments; switch (m_api) { case trace::API_GL: prog = QLatin1String("glretrace"); break; case trace::API_EGL: prog = QLatin1String("eglretrace"); break; case trace::API_DX: case trace::API_D3D7: case trace::API_D3D8: case trace::API_D3D9: case trace::API_DXGI: #ifdef Q_OS_WIN prog = QLatin1String("d3dretrace"); #else prog = QLatin1String("wine"); arguments << QLatin1String("d3dretrace.exe"); #endif break; default: emit finished(QLatin1String("Unsupported API")); return; } arguments << retraceArguments() << m_fileName; /* * Support remote execution on a separate target. */ if (m_remoteTarget.length() != 0) { arguments.prepend(prog); arguments.prepend(m_remoteTarget); prog = QLatin1String("ssh"); } /* * Start the process. */ { QDebug debug(QtDebugMsg); debug << "Running:"; debug << prog; foreach (const QString &argument, arguments) { debug << argument; } } QProcess process; process.start(prog, arguments, QIODevice::ReadOnly); if (!process.waitForStarted(-1)) { emit finished(QLatin1String("Could not start process")); return; } /* * Process standard output */ ImageHash thumbnails; QVariantMap parsedJson; trace::Profile* profile = NULL; process.setReadChannel(QProcess::StandardOutput); if (process.waitForReadyRead(-1)) { BlockingIODevice io(&process); if (m_captureState) { parsedJson = decodeUBJSONObject(&io).toMap(); process.waitForFinished(-1); } else if (m_captureThumbnails) { /* * Parse concatenated PNM images from output. */ while (!io.atEnd()) { image::PNMInfo info; char header[512]; qint64 headerSize = 0; int headerLines = 3; // assume no optional comment line for (int headerLine = 0; headerLine < headerLines; ++headerLine) { qint64 headerRead = io.readLine(&header[headerSize], sizeof(header) - headerSize); // if header actually contains optional comment line, ... if (headerLine == 1 && header[headerSize] == '#') { ++headerLines; } headerSize += headerRead; } const char *headerEnd = image::readPNMHeader(header, headerSize, info); // if invalid PNM header was encountered, ... if (headerEnd == NULL || info.channelType != image::TYPE_UNORM8) { qDebug() << "error: invalid snapshot stream encountered"; break; } unsigned channels = info.channels; unsigned width = info.width; unsigned height = info.height; // qDebug() << "channels: " << channels << ", width: " << width << ", height: " << height"; QImage snapshot = QImage(width, height, channels == 1 ? QImage::Format_Mono : QImage::Format_RGB888); int rowBytes = channels * width; for (int y = 0; y < height; ++y) { unsigned char *scanLine = snapshot.scanLine(y); qint64 readBytes = io.read((char *) scanLine, rowBytes); Q_ASSERT(readBytes == rowBytes); (void)readBytes; } QImage thumb = thumbnail(snapshot); thumbnails.insert(info.commentNumber, thumb); } Q_ASSERT(process.state() != QProcess::Running); } else if (isProfiling()) { profile = new trace::Profile(); while (!io.atEnd()) { char line[256]; qint64 lineLength; lineLength = io.readLine(line, 256); if (lineLength == -1) break; trace::Profiler::parseLine(line, profile); } } else { QByteArray output; output = process.readAllStandardOutput(); if (output.length() < 80) { msg = QString::fromUtf8(output); } } } /* * Wait for process termination */ process.waitForFinished(-1); if (process.exitStatus() != QProcess::NormalExit) { msg = QLatin1String("Process crashed"); } else if (process.exitCode() != 0) { msg = QLatin1String("Process exited with non zero exit code"); } /* * Parse errors. */ QList<ApiTraceError> errors; process.setReadChannel(QProcess::StandardError); QRegExp regexp("(^\\d+): +(\\b\\w+\\b): ([^\\r\\n]+)[\\r\\n]*$"); while (!process.atEnd()) { QString line = process.readLine(); if (regexp.indexIn(line) != -1) { ApiTraceError error; error.callIndex = regexp.cap(1).toInt(); error.type = regexp.cap(2); error.message = regexp.cap(3); errors.append(error); } else if (!errors.isEmpty()) { // Probably a multiligne message ApiTraceError &previous = errors.last(); if (line.endsWith("\n")) { line.chop(1); } previous.message.append('\n'); previous.message.append(line); } } /* * Emit signals */ if (m_captureState) { ApiTraceState *state = new ApiTraceState(parsedJson); emit foundState(state); } if (m_captureThumbnails && !thumbnails.isEmpty()) { emit foundThumbnails(thumbnails); } if (isProfiling() && profile) { emit foundProfile(profile); } if (!errors.isEmpty()) { emit retraceErrors(errors); } emit finished(msg); }