Exemple #1
0
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;
    }
}
Exemple #2
0
status_t GIFTrans::AddData( const void* pData, size_t nLen, bool bFinal )
{
    m_bEOF = bFinal;
    m_cInBuffer.Write( pData, nLen );
    return( 0 );
}
Exemple #3
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;
}