VBIDecoder::~VBIDecoder() { // If there's a subtitle image that hasn't been written to the XML file, // do it now. flushPage(currTimestamp); vbi_decoder_delete(decoder); vbi_export_delete(exporter); // Write the xml closing tags, and close the file fprintf(fpxml, "</stream>\n</subpictures>\n"); fflush(fpxml); fclose(fpxml); if (fileIndex == 0) { // We didn't find any CC or Teletext data // Unlink the xml file, print an error message // and exit with non-zero exit code unlink(xmlfile); fflush(fplog); fprintf(stderr, "No CC or Teletext data found\n"); fflush(stderr); exit(1); } }
void MemoryMapped::map(uint64_t from) { PageIndex pageIndex = mapCandidate(); if (pageIndex == InvalidPage) { throw std::exception("Failed to map file, no candidate page."); } MemoryPage & page = m_Pages[pageIndex]; if (!page.data()) { page.data() = reinterpret_cast<uint8_t*>(m_Allocator.getChunk(pageIndex)); } if (page.dirty()) { flushPage(pageIndex); } // allign pages on pageSize so there are no overlaps from = (from / m_PageSize) * m_PageSize; uint64_t mapSize = std::min<uint64_t>(m_PageSize, m_FileSize - from); page.reset(from, mapSize); _fseeki64(m_File, from, SEEK_SET); if (fread(page.data(), 1, mapSize, m_File) != mapSize) { throw std::exception("Failed to map file in memory"); } m_UsedPages = std::min<uint64_t>(m_UsedPages + 1, m_PageCount); }
void printerStream::printText(const QString &txt, bool newLine) { if (fwbdebug) { qDebug("printText -------"); qDebug("pageBody.height(): %d", pageBody.height()); qDebug("yPos: %d", yPos); } if (txt.isEmpty()) return; if (printer->printerState() == QPrinter::Aborted) return; pr.setFont( bodyFont ); QFontMetrics fm = pr.fontMetrics(); QRect br = fm.boundingRect(txt); if (getYSpace()<br.height()) { flushPage(); beginPage(); // resets yPos } if (pageNo>=fromPage && pageNo<=toPage) { pr.setPen(Qt::black); pr.drawText( xmargin, yPos, printer->width()-2*xmargin, br.height(), Qt::TextExpandTabs | Qt::TextDontClip, txt ); } int nlines=1; int i=-1; while ( (i=txt.indexOf("\n",i+1))>=0 ) nlines++; if (newLine) yPos = yPos + nlines*fm.lineSpacing(); }
bool QtopiaPrintEngine::newPage() { flushPage(); clearPage(); ++(d_func()->pageNumber); return true; }
void MemoryMapped::flush() { for (PageIndex c = 0; c < m_PageCount; ++c) { if (m_Pages[c].dirty()) { flushPage(c); } } }
void BufMgr::deleteFrame(int i) { if (bufDescr[i]->dirty) flushPage(bufDescr[i]->pageNum); lhm->erase(bufDescr[i]->pageNum, bufDescr[i]->ts, bufDescr[i]->loved); assert(hashTable->erase(bufDescr[i]->pageNum) == 1); delete bufDescr[i]; }
void printerStream::printPixmap(const QPixmap &pm, bool newLine) { #if 0 QPaintDevice *dev = pr.device(); if (fwbdebug) { qDebug("printPixmap: width=%d height=%d", pm.width(), pm.height()); qDebug("printPixmap: printer->resolution()=%d", printer->resolution()); if (dev) { qDebug("printPixmap: device parameters:"); qDebug(" height=%d width=%d", dev->height(), dev->width()); qDebug(" logicalDpiY=%d logicalDpiX=%d", dev->logicalDpiY(), dev->logicalDpiX()); qDebug(" physicalDpiY=%d physicalDpiX=%d", dev->physicalDpiY(), dev->physicalDpiX()); } } #endif int target_w = (int)(pm.width() * pixmap_scaling_ratio); int target_h = (int)(pm.height() * pixmap_scaling_ratio); int pmYOffset = 0; while ( getYSpace()<(pm.height()-pmYOffset) ) { int yFrag = pageBody.height() - yPos; if (pageNo>=fromPage && pageNo<=toPage) { if (fwbdebug) qDebug("Print pixmap 1: yPos=%d pmYOffset=%d " "yFrag=%d target_w=%d target_h=%d", yPos, pmYOffset, yFrag, target_w, target_h); pr.drawPixmap(xmargin, yPos, target_w, target_h, pm, 0, pmYOffset, -1, yFrag); } pmYOffset = pmYOffset + yFrag; flushPage(); beginPage(); // resets yPos } if (pageNo>=fromPage && pageNo<=toPage) { if (fwbdebug) qDebug("Print pixmap 2: yPos=%d pmYOffset=%d target_w=%d target_h=%d", yPos, pmYOffset, target_w, target_h); pr.drawPixmap(xmargin, yPos, target_w, target_h, pm, 0, pmYOffset, -1, -1); } if (newLine) yPos = yPos + (target_h - pmYOffset); }
void VBIDecoder::writePage(vbi_page* pg, Timestamp& startTS) { if (*fileName != 0) flushPage(startTS); sprintf(fileName, "%ssub%04d.png", prefix, fileIndex++); startTimestamp = startTS; if (!vbi_export_file(exporter, fileName, pg)) { fflush(fplog); fprintf(stderr, "vbi_export_file(file=%s) failed: %s\n", fileName, vbi_export_errstr(exporter)); fflush(stderr); exit(1); } // Copy the page so checkPage can compare it against future pages memcpy(&lastPage, pg, sizeof(lastPage)); fflush(fplog); textBytes = vbi_print_page_region(pg, textBuf, textSize, "UTF-8", TRUE, TRUE, region.mincol, region.minrow, region.maxcol - region.mincol+1, region.maxrow - region.minrow+1); fflush(stderr); if (verbose) { fwrite(textBuf, textBytes, 1, fplog); putc('\n', fplog); } // Check for characters that spumux won't parse // null chars will be changed to space // pairs of dashes will be changed to underscores for (char* ptr = textBuf; ptr < textBuf+textBytes; ptr++) { switch (*ptr) { case 0: *ptr = ' '; break; case '-': if (*(ptr+1) == '-') { *ptr++ = '_'; *ptr = '_'; } break; } } }
bool QtopiaPrintEngine::end() { Q_D(QtopiaPrintEngine); d->paintEngine()->end(); // Flush the last page. flushPage(); // Output the fax data to a file (TODO: send to the print queuing daemon). QString filename; if ( !d->outputFileName.isEmpty() ) filename = QString::fromLocal8Bit(qgetenv("HOME").constData()) + QLatin1String("/Documents/") + d->outputFileName; else filename = QString::fromLocal8Bit(qgetenv("HOME").constData()) + QLatin1String("/tmp/qwsfax.tiff"); setProperty(QPrintEngine::PPK_OutputFileName, filename); QFile file( filename ); if ( !file.open( QIODevice::WriteOnly | QIODevice::Truncate ) ) { qDebug( "Failed to open %s for printer output", filename.toLatin1().constData() ); } else { file.write( d->buffer.data() ); file.close(); } // Free up the memory for the image buffer. d->buffer.clear(); // Finalize the print job. d->printerState = QPrinter::Idle; // call qcop service QMap<QString, QVariant> map; for ( int x = 0; x <= QPrintEngine::PPK_Duplex; x++ ) map.insert( QString::number(x), property((QPrintEngine::PrintEnginePropertyKey)(x))); QVariant variant(map); QByteArray data; QDataStream out(&data, QIODevice::WriteOnly); out << variant; QCopChannel::send(QLatin1String("QPE/Service/Print"), QLatin1String("print(QVariant)"), data); return true; }
Status BufMgr::flushAllPages(){ int* z = new int[numbuf]; for (int i = 0; i < numbuf; i++) z[i] = 1; for (int i = 0; i < freeFrames.size(); i++) z[freeFrames[i]] = 0; for (int i = 0; i < numbuf; i++) if (z[i] && bufDescr[i]->dirty) { Status s = flushPage(bufDescr[i]->pageNum); if (s != OK) { MINIBASE_CHAIN_ERROR(BUFMGR, s); return s; } } return OK; }
int squash(Buffer * buf) { int num; for (num = 0; num < buf->nBufferBlocks; num++) { if (buf->pin[num] == 1) { unPinPage(buf, buf->pages[num].address); } if (buf->dirty[num] == 1) { flushPage(buf, buf->pages[num].address); } } free(buf->database); free(buf->pages); free(buf->cache); free(buf->buffer_timestamp); free(buf->cache_timestamp); free(buf->pin); free(buf->dirty); free(buf->volatileFDs); free(buf->persistentFDs); free(buf); return tfs_unmount(); }
void printerStream::printQTable(QTableView *tbl, bool left_margin, bool top_margin) { if (fwbdebug) { qDebug("printQTable ----------------------------------------------"); qDebug("Size: %dx%d", tbl->width(), tbl->height()); // qDebug("Visible: %dx%d", // tbl->contentsRect().width(), tbl->contentsRect().height()); // qDebug("Viewport: %dx%d", // tbl->viewport()->width(), tbl->viewport()->height()); // qDebug("pageBody.height(): %d", pageBody.height()); qDebug("YSpace: %d", getYSpace()); qDebug("yPos: %d", yPos); } int top_row = 0; int bottom_row = 1; int columnsWidth = 0; int i = 0; while (i < tbl->model()->columnCount()) { columnsWidth += tbl->columnWidth(i); i++; } int rowCount = tbl->model()->rowCount(); while (top_row <= (rowCount-1)) { int row = 0; int tblHeight = (int)( (float)(tbl->horizontalHeader()->height()) * pixmap_scaling_ratio); /* =================================================================== * Row height is screen pixels, getYSpace returns remaining * space in printer resolution units. Keep track of both to * resize pixmap * =================================================================== */ int pixMapHeight = tbl->horizontalHeader()->height(); for (row=top_row; row < rowCount; ++row) { if (tbl->isRowHidden(row)) { // hidden rows count but do not contribute to table height continue; } int nth = tblHeight + (int)((float)(tbl->rowHeight(row)) * pixmap_scaling_ratio); if ( nth==getYSpace() ) break; if ( nth>getYSpace() ) { row--; break; } tblHeight = nth; pixMapHeight += tbl->rowHeight(row); } // if row < top_row then even single row does not fit on the page if (row < top_row) { row = top_row; pixMapHeight = tbl->rowHeight(top_row); } if (row == rowCount) row--; bottom_row = row; int left_hdr_w = 0; if (left_margin && tbl->verticalHeader() != NULL) left_hdr_w = tbl->verticalHeader()->width(); int top_hdr_h = 0; if (top_margin && tbl->horizontalHeader() != NULL) top_hdr_h = tbl->horizontalHeader()->height(); int tblWidth = columnsWidth + left_hdr_w; if (fwbdebug) qDebug("Page %d -- (%d-%d of %d rows) tblWidth: %d tblHeight: %d", pageNo, top_row, bottom_row, rowCount, tblWidth, tblHeight); tbl->resize(tblWidth, pixMapHeight); tbl->verticalHeader()->resize( tbl->verticalHeader()->width(), tbl->height() - tbl->horizontalHeader()->height()); tbl->horizontalHeader()->resize( tbl->width() - tbl->verticalHeader()->width(), tbl->horizontalHeader()->height()); // QTableView::scrollTo() makes row visible, but if there are not enough // rows below it, it appears in the middle of the table. This means the table // shows few rows that belong on the previous page, which is bad. // // tbl->scrollTo(tbl->model()->index(top_row, 0), // QAbstractItemView::PositionAtTop); int top_row_position = tbl->verticalHeader()->sectionPosition(top_row); tbl->verticalHeader()->setOffset(top_row_position); tbl->update(); printPixmap(QPixmap::grabWidget(tbl)); //,0,0,-1,pixMapHeight)); if (bottom_row>=(rowCount-1)) break; flushPage(); beginPage(); top_row = bottom_row + 1; } }
void printerStream::printRuleSetView(RuleSetView *tbl, bool top_margin) { if (fwbdebug) { qDebug("printQTable ----------------------------------------------"); qDebug("Size: %dx%d", tbl->width(), tbl->height()); qDebug("YSpace: %d", getYSpace()); qDebug("yPos: %d", yPos); } int columnsWidth = 0; int i = 0; while (i < tbl->model()->columnCount()) { columnsWidth += tbl->columnWidth(i); i++; } RuleSetModelIterator it = ((RuleSetModel*)tbl->model())->begin(); RuleSetModelIterator end = ((RuleSetModel*)tbl->model())->end(); RuleSetModelIterator bottomIt; while (it.isValid() && it != end) { // Pages iterations int tblHeight = (int)( (float)(tbl->header()->height()) * pixmap_scaling_ratio); /* =================================================================== * Row height is screen pixels, getYSpace returns remaining * space in printer resolution units. Keep track of both to * resize pixmap * =================================================================== */ int pixMapHeight = tbl->header()->height(); RuleSetModelIterator pit = it; while (pit != end) { // Check if current index is collapsed QModelIndex index = pit.index(); QModelIndex parent = index.parent(); if (!parent.isValid() || tbl->isExpanded(parent)) { int nth = tblHeight + (int)((float)(tbl->rowHeight(index)) * pixmap_scaling_ratio); if ( nth==getYSpace() ) break; if ( nth>getYSpace() ) { // if it == pit then even single row does not fit on the page if (it == pit) { pixMapHeight = tbl->rowHeight(index); } else { --pit; } break; } tblHeight = nth; pixMapHeight += tbl->rowHeight(index); } ++pit; } bottomIt = pit; int left_hdr_w = 0; int top_hdr_h = 0; if (top_margin && tbl->header() != NULL) top_hdr_h = tbl->header()->height(); int tblWidth = columnsWidth + left_hdr_w; qDebug("Page %d -- tblWidth: %d tblHeight: %d", pageNo, tblWidth, tblHeight); tbl->resize(tblWidth, pixMapHeight); tbl->updateWidget(); tbl->scrollTo(it.index(), QAbstractItemView::PositionAtTop); printPixmap(QPixmap::grabWidget(tbl)); if (bottomIt == end) break; flushPage(); beginPage(); it = bottomIt; ++it; } }
void DataTerminal::processByte(uint8_t byte) { switch(mState) { case STATE_WAITING: if ( byte == START_TRANSFER_CMD ) { mState = STATE_IN_TRANSFER_HEADER; mByteCount = 0; trace_printf("Receiving metadata\n"); GPIO_SetBits(GPIOB, GPIO_Pin_14); writeCmd(ACK); } else { trace_printf("Bad command: %.2x\n", byte); fail(); } break; case STATE_IN_TRANSFER_HEADER: { //trace_printf("1 byte\n"); char *p = (char*)&mMetadata; memcpy(p + mByteCount, &byte, 1); ++mByteCount; if ( mByteCount == sizeof mMetadata ) { trace_printf("Magick: %.8x\n", mMetadata.magic); // Is the metadata sane? if ( mMetadata.magic == METADATA_MAGIC ) { mState = STATE_IN_TRANSFER_BLOCK; trace_printf("Expecting %d bytes\n", mMetadata.size); printmd5(mMetadata.md5); GPIO_SetBits(GPIOB, GPIO_Pin_14); mByteCount = 0; mWriteAddress = APPLICATION_ADDRESS; MD5Init(&mMD5); unlockFlash(); writeCmd(ACK); } else { trace_printf("Bad metadata \n"); fail(); } } } break; case STATE_IN_TRANSFER_BLOCK: MD5Update(&mMD5, &byte, 1); if ( mByteCount == 0 ) { GPIO_SetBits(GPIOB, GPIO_Pin_15); } size_t offset = mByteCount % FLASH_PAGE_SIZE; assert(offset < sizeof mCurrPage); memcpy(mCurrPage + offset, &byte, 1); ++mByteCount; if ( mByteCount % FLASH_PAGE_SIZE == 0 ) { flushPage(); } // Acknowledge every 1K if ( mByteCount % 1024 == 0 ) { trace_printf("Sending ACK\n"); writeCmd(ACK); } if ( mByteCount == mMetadata.size ) { if ( mMetadata.size % 1024 ) { // We have a partial page to write flushPage(); writeCmd(ACK); } // Last byte! trace_printf("Received %d bytes\n", mMetadata.size); GPIO_ResetBits(GPIOB, GPIO_Pin_14); mState = STATE_WAITING; uint8_t d[16]; MD5Final(d, &mMD5); printmd5(d); if ( memcmp(d, mMetadata.md5, 16) ) { // Bad MD5 trace_printf("MD5 mismatch :( \n"); fail(); } else { // Good transfer trace_printf("MD5 match :) \n"); writeCmd(ACK); flushMetadata(); lockFlash(); NVIC_SystemReset(); } } break; } }
/* returns the index in the buffer array */ int readPage(Buffer * buf, DiskAddress diskPage) { int num, available = 0, toEvict; /* available is set to 1 if there are any unpinned pages */ long oldest = -1; /* check if this file has been opened before in persistent */ if (checkPersistentFiles(buf, diskPage.FD) == -1) { buf->numPersistentFiles += 1; buf->persistentFDs = (int *)realloc(buf->persistentFDs, sizeof(int) * buf->numPersistentFiles); buf->persistentFDs[buf->numPersistentFiles-1] = diskPage.FD; } /* buffer check for page */ for (num = 0; num < buf->nBufferBlocks; num++) { if (buf->buffer_timestamp[num] != -1 && buf->pages[num].address.FD == diskPage.FD && buf->pages[num].address.pageId == diskPage.pageId) { /* found page in buffer */ buf->buffer_timestamp[num] = time(NULL); return num; } } /* if this is reached, then the page is not in the buffer */ num = findEmpty(buf); if (num != -1) { /* bring page to buffer */ tfs_readPage(diskPage.FD, diskPage.pageId, (unsigned char *)buf->pages[num].block); /* sets page metadata */ buf->pages[num].address = diskPage; buf->buffer_timestamp[num] = time(NULL); buf->numBufferOccupied++; return num; } /* * Implement LRU eviction. * all pageslots are full, check if they're all pinned */ for (num = 0; num < buf->nBufferBlocks; num++) { if(buf->pin[num] == 0) { /* if the page is unpinned */ if (oldest == -1) { /* initial timestamp */ oldest = buf->buffer_timestamp[num]; toEvict = num; } else if (oldest > buf->buffer_timestamp[num]) { /* found an older time stamp */ oldest = buf->buffer_timestamp[num]; toEvict = num; } available = 1; } } if (available == 0) { /* all the pages are pinned */ return -1; /* error */ } /* at this point a page needs to be evicted */ flushPage(buf, buf->pages[toEvict].address); /* bring page to buffer */ tfs_readPage(diskPage.FD, diskPage.pageId, (unsigned char *)buf->pages[toEvict].block); /* set other bits*/ buf->pages[toEvict].address = diskPage; buf->buffer_timestamp[toEvict] = time(NULL); return toEvict; }
void VBIDecoder::checkPage(vbi_page* pg) { // Check for blank page, // filling in region to non-blank bounds region.mincol = pg->columns; region.maxcol = 0; region.minrow = pg->rows; region.maxrow = 0; int nonEmpty = 0; int fg = 7; int bg = 0; vbi_char* text = pg->text; for (int row = 0; row < pg->rows; row++) { for (int col = 0; col < pg->columns; col++, text++) { if (text->opacity != VBI_TRANSPARENT_SPACE) { nonEmpty++; if (region.mincol > col) region.mincol = col; if (region.maxcol < col) region.maxcol = col; if (region.minrow > row) region.minrow = row; if (region.maxrow < row) region.maxrow = row; if (verbose && (text->foreground != fg || text->background != bg)) { fg = text->foreground; bg = text->background; fprintf(fplog, "Color change at %dx%d fg=%d bg=%d\n", col, row, fg, bg); } } } } if (nonEmpty == 0) { if (verbose) fprintf(fplog, "Blank page\n"); flushPage(currTimestamp); return; } // If we haven't flushed the last page, // compare it against the current page if (fileName != 0) { if (memcmp(lastPage.text, pg->text, sizeof(lastPage.text)) == 0) { if (verbose) fprintf(fplog, "Identical pages\n"); return; } } writePage(pg, currTimestamp); }
int allocateCachePage(Buffer *buf, DiskAddress diskpage){ int i, bufIndex, oldestCache = 0, oldestBuf = -1; /* check if this file has been opened before in volatile */ if (checkVolatileFiles(buf, diskpage.FD) == -1) { buf->numVolatileFiles += 1; buf->volatileFDs = (int *)realloc(buf->volatileFDs, sizeof(int) * buf->numVolatileFiles); buf->volatileFDs[buf->numVolatileFiles-1] = diskpage.FD; } /* check if this page is already in cache */ i = findPageVolatile(buf, diskpage); if (i != -1) return i; /* check if this page is already in persistent buffer */ bufIndex = findPage(buf, diskpage); //Check if cache is full if(buf->nCacheBlocks == buf->numCacheOccupied){ //Find index of least recently used for eviction for(i = 0; i < buf->nCacheBlocks; i++){ if(buf->cache_timestamp[oldestCache] > buf->cache_timestamp[i]) { oldestCache = i; } } buf->cache_timestamp[oldestCache] = -1; //Check if buffer is full if(buf->nBufferBlocks == buf->numBufferOccupied){ //If it is full find the least recently used unpinned page and write to disk for(i = 0; i < buf->nBufferBlocks; i++){ if(buf->pin[i] == 0 && (oldestBuf == -1 || buf->buffer_timestamp[oldestBuf] > buf->buffer_timestamp[i])) { oldestBuf = i; } } if (oldestBuf == -1) // all pages were pinned return -1; writePage(buf, buf->pages[oldestBuf].address); flushPage(buf, buf->pages[oldestBuf].address); } else { //If it is not full then find empty spot and insert into buffer for(i = 0; i < buf->nBufferBlocks; i++){ if(buf->buffer_timestamp[i] == -1){ oldestBuf = i; buf->numBufferOccupied++; buf->buffer_timestamp[i] = time(NULL); break; } } } //Copy the block from the cache into the buffer memcpy(&(buf->pages[oldestBuf]), &(buf->cache[oldestCache]), sizeof(Block)); buf->pin[oldestBuf] = 1; } //Write the diskapage passed into the now open cache spot for(i = 0; i < buf->nCacheBlocks; i++){ if(buf->cache_timestamp[i] == -1){ buf->cache[i].address.pageId = diskpage.pageId; buf->cache[i].address.FD = diskpage.FD; buf->numCacheOccupied++; buf->cache_timestamp[i] = time(NULL); /* if page was already in persistent buffer, copy its data into this cache spot */ if (bufIndex != -1) { memcpy(buf->cache[i].block, &buf->pages[bufIndex].block, BLOCKSIZE); /* remove page from persistent buffer */ buf->buffer_timestamp[bufIndex] = -1; buf->pin[bufIndex] = 0; buf->numBufferOccupied--; } break; } } return i; }