void ViewHistory::Update(DataHistory* history, int32 width, int32 resolution, bigtime_t toTime, bigtime_t step, bigtime_t refresh) { if (width > 16384) { // ignore this - it seems the view hasn't been layouted yet return; } // Check if we need to invalidate the existing values if ((int32)fValues.Size() != width || fResolution != resolution || fRefresh != refresh) { fValues.SetSize(width); fResolution = resolution; fRefresh = refresh; fLastTime = 0; } // Compute how many new values we need to retrieve if (fLastTime < history->Start()) fLastTime = history->Start(); if (fLastTime > history->End()) return; int32 updateWidth = int32((toTime - fLastTime) / step); if (updateWidth < 1) return; if (updateWidth > (int32)fValues.Size()) { updateWidth = fValues.Size(); fLastTime = toTime - updateWidth * step; } for (int32 i = 0; i < updateWidth; i++) { int64 value = history->ValueAt(fLastTime += step); if (step > refresh) { uint32 count = 1; for (bigtime_t offset = refresh; offset < step; offset += refresh) { // TODO: handle int64 overflow correctly! value += history->ValueAt(fLastTime + offset); count++; } value /= count; } fValues.AddItem(value); } }
status_t PNGTrans::AddData( const void* pData, size_t nLen, bool bFinal ) { if( !m_bWriteMode ) { // dbprintf("PNG-Read: AddData()\n"); if ( setjmp( m_psPNGStruct->jmpbuf ) ) { png_destroy_read_struct( &m_psPNGStruct, &m_psPNGInfo, (png_infopp)NULL ); return -1; } png_process_data( m_psPNGStruct, m_psPNGInfo, (png_bytep)pData, nLen ); return 0; } else { m_cInBuffer.Write( pData, nLen ); // dbprintf("PNG-Write: Data added!\n"); if( m_eState == STATE_INIT && m_cInBuffer.Size() > (ssize_t)sizeof( BitmapHeader ) ) { m_cInBuffer.Read( &m_sBitmapHeader, sizeof( m_sBitmapHeader ) ); m_eState = STATE_FRAMEHDR; } if( m_eState == STATE_FRAMEHDR && m_cInBuffer.Size() > (ssize_t)sizeof( BitmapFrameHeader ) ) { m_cInBuffer.Read( &m_sCurrentFrame, sizeof( m_sCurrentFrame ) ); // TODO: Verify depth, convert if not RGB32 png_set_IHDR( m_psPNGStruct, m_psPNGInfo, m_sCurrentFrame.bf_frame.right - m_sCurrentFrame.bf_frame.left + 1, m_sCurrentFrame.bf_frame.bottom - m_sCurrentFrame.bf_frame.top + 1, 8, PNG_COLOR_TYPE_RGB, //_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE ); // png_set_filler( m_psPNGStruct, 0xff, PNG_FILLER_AFTER); png_set_bgr( m_psPNGStruct ); png_write_info( m_psPNGStruct, m_psPNGInfo ); AllocRowBuffer( m_sCurrentFrame.bf_frame.right - m_sCurrentFrame.bf_frame.left + 1 ); m_eState = STATE_READING; } while( m_eState == STATE_READING && m_cInBuffer.Size() ) { if( AppendToRowBuffer() ) { // Overflow = one row is ready // dbprintf("PNG-Write: Found Row\n"); png_write_rows( m_psPNGStruct, &m_pRowBuffer, 1); } } if( bFinal ) { png_write_end( m_psPNGStruct, m_psPNGInfo); } return 0; } }
bool PNGTrans::AppendToRowBuffer( void ) { uint8 buffer[1024]; // Free space in rowbuffer uint32 nSize = m_nRowSize - m_nRowPos; // Adjust to available amount of data (so we don't get a deadlock) nSize = nSize > (uint32)m_cInBuffer.Size() ? m_cInBuffer.Size() : nSize; // Longword alignment, 24 bpp => 32 bpp size conversion nSize = ((int)( nSize / 3 )) * 4; // Adjust to available buffer size nSize = nSize > sizeof( buffer ) ? sizeof(buffer) : nSize; // dbprintf("pos: %ld, size: %ld\n", m_nRowPos, m_nRowSize); // Read and convert RGB32 => RGB24 // dbprintf("m_cInBuffer.Read( %p, %ld )...", buffer, nSize); m_cInBuffer.Read( buffer, nSize ); // dbprintf("Done!\n"); int i, j; for( i = 0, j = 0; i < nSize; i+=4, j+=3 ) { m_pRowBuffer[ m_nRowPos + j ] = buffer[ i ]; m_pRowBuffer[ m_nRowPos + j + 1 ] = buffer[ i + 1 ]; m_pRowBuffer[ m_nRowPos + j + 2 ] = buffer[ i + 2 ]; } m_nRowPos += (nSize/4)*3; if( m_nRowPos >= m_nRowSize ) { // dbprintf("New row\n"); m_nRowPos = 0; return true; } else { return false; } }
ssize_t PNGTrans::AvailableDataSize() { return( m_cOutBuffer.Size() ); }