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; } }
status_t GIFTrans::AddData( const void* pData, size_t nLen, bool bFinal ) { m_bEOF = bFinal; m_cInBuffer.Write( pData, nLen ); return( 0 ); }
void GIFTrans::DecodeData() { if ( m_psGIFStruct != NULL ) { return; } m_psGIFStruct = DGifOpen( this, get_input ); int ImageNum = 0; GifPixelType* pLineBuffer = new GifPixelType[m_psGIFStruct->SWidth * 4]; GifRecordType RecordType; do { if (DGifGetRecordType( m_psGIFStruct, &RecordType) == GIF_ERROR) { goto error; } switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: { if ( DGifGetImageDesc( m_psGIFStruct ) == GIF_ERROR ) { goto error; } int Row = m_psGIFStruct->Image.Top; /* Image Position relative to Screen. */ int Col = m_psGIFStruct->Image.Left; int Width = m_psGIFStruct->Image.Width; int Height = m_psGIFStruct->Image.Height; m_sBitmapHeader.bh_header_size = sizeof( m_sBitmapHeader ); m_sBitmapHeader.bh_data_size = 0; m_sBitmapHeader.bh_bounds = IRect( 0, 0, Width - 1, Height - 1 ); m_sBitmapHeader.bh_frame_count = 1; m_sBitmapHeader.bh_bytes_per_row = Width * 4; m_sBitmapHeader.bh_color_space = CS_RGB32; m_bTopHeaderValid = true; ImageNum++; if (m_psGIFStruct->Image.Left + m_psGIFStruct->Image.Width > m_psGIFStruct->SWidth || m_psGIFStruct->Image.Top + m_psGIFStruct->Image.Height > m_psGIFStruct->SHeight) { fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n",ImageNum); goto error; } if (m_psGIFStruct->Image.Interlace) { int InterlacedOffset[] = { 0, 4, 2, 1 }; /* The way Interlaced image should. */ int InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */ /* Need to perform 4 passes on the images: */ for ( int i = 0; i < 4; i++) { for ( int j = Row + InterlacedOffset[i]; j < Row + Height ; j += InterlacedJumps[i] ) { memset( pLineBuffer, 255/* m_psGIFStruct->SBackGroundColor*/, m_psGIFStruct->SWidth ); if (DGifGetLine(m_psGIFStruct, pLineBuffer + Col, Width) != GIF_ERROR) { AddLine( (m_psGIFStruct->Image.ColorMap ? m_psGIFStruct->Image.ColorMap : m_psGIFStruct->SColorMap), j, pLineBuffer ); } else { goto error; } } } } else { m_sCurrentFrame.bf_header_size = sizeof(m_sCurrentFrame); m_sCurrentFrame.bf_time_stamp = 0; m_sCurrentFrame.bf_color_space = m_sBitmapHeader.bh_color_space; m_sCurrentFrame.bf_frame = Rect( m_psGIFStruct->Image.Left, m_psGIFStruct->Image.Top, m_psGIFStruct->Image.Left + m_psGIFStruct->Image.Width - 1, m_psGIFStruct->Image.Top + m_psGIFStruct->Image.Height - 1 ); m_sCurrentFrame.bf_bytes_per_row = (m_sCurrentFrame.bf_frame.Width() + 1) * 4; m_sCurrentFrame.bf_data_size = m_sCurrentFrame.bf_bytes_per_row * (m_sCurrentFrame.bf_frame.Height() + 1); m_cOutBuffer.Write( &m_sCurrentFrame, sizeof(m_sCurrentFrame) ); for ( int i = 0; i < Height; i++ ) { memset( pLineBuffer, m_psGIFStruct->SBackGroundColor, m_psGIFStruct->SWidth ); if ( DGifGetLine(m_psGIFStruct, pLineBuffer + Col, Width) != GIF_ERROR ) { AddLine( (m_psGIFStruct->Image.ColorMap ? m_psGIFStruct->Image.ColorMap : m_psGIFStruct->SColorMap), Row++, pLineBuffer ); } else { goto error; } } } break; } case EXTENSION_RECORD_TYPE: { GifByteType *Extension; int ExtCode; /* Skip any extension blocks in file: */ if (DGifGetExtension(m_psGIFStruct, &ExtCode, &Extension) == GIF_ERROR) { goto error; } if ( ExtCode == GRAPHICS_EXT_FUNC_CODE ) { // if (DGifGetExtensionNext(m_psGIFStruct, &Extension) == GIF_ERROR) { // goto error; // } if ( Extension[1] & 0x01 ) { m_nTransCol = Extension[4]; } } while (Extension != NULL) { if (DGifGetExtensionNext(m_psGIFStruct, &Extension) == GIF_ERROR) { goto error; } } break; } case TERMINATE_RECORD_TYPE: break; default: /* Should be traps by DGifGetRecordType. */ break; } } while (RecordType != TERMINATE_RECORD_TYPE && ImageNum == 0); delete[] pLineBuffer; DGifCloseFile( m_psGIFStruct ); return; error: DGifCloseFile( m_psGIFStruct ); delete[] pLineBuffer; return; }