Mercurial > mplayer.hg
view Gui/bitmap.c @ 13738:39004f891def
seeking based on the largest timestamp in an mpeg stream
It is often more accurate than the current seeking and it has the
additional benefit of giving the (almost) precise total time of the movie.
patch by Michael Behrisch < behrisch at informatik.hu-berlin.de >
author | aurel |
---|---|
date | Sat, 23 Oct 2004 00:05:38 +0000 |
parents | 46badb3d0b1c |
children | c30e193ac112 |
line wrap: on
line source
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <png.h> #include "../../mp_msg.h" #include "bitmap.h" int pngRead( unsigned char * fname,txSample * bf ) { unsigned char header[8]; png_structp png; png_infop info; png_infop endinfo; png_bytep * row_p; png_bytep palette = NULL; int color; png_uint_32 i; FILE *fp=fopen( fname,"rb" ); if ( !fp ) { mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] file read error ( %s ).\n",fname ); return 1; } fread( header,1,8,fp ); if ( !png_check_sig( header,8 ) ) return 1; png=png_create_read_struct( PNG_LIBPNG_VER_STRING,NULL,NULL,NULL ); info=png_create_info_struct( png ); endinfo=png_create_info_struct( png ); png_init_io( png,fp ); png_set_sig_bytes( png,8 ); png_read_info( png,info ); png_get_IHDR( png,info,&bf->Width,&bf->Height,&bf->BPP,&color,NULL,NULL,NULL ); row_p=(png_bytep *)malloc( sizeof( png_bytep ) * bf->Height ); if ( !row_p ) { mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] Not enough memory for row buffer.\n" ); return 2; } bf->Image=(png_bytep)malloc( png_get_rowbytes( png,info ) * bf->Height ); if ( !bf->Image ) { mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] Not enough memory for image buffer.\n" ); return 2; } for ( i=0; i < bf->Height; i++ ) row_p[i]=&bf->Image[png_get_rowbytes( png,info ) * i]; png_read_image( png,row_p ); free( row_p ); #if 0 if ( color == PNG_COLOR_TYPE_PALETTE ) { int cols; png_get_PLTE( png,info,(png_colorp *)&palette,&cols ); } #endif if ( color&PNG_COLOR_MASK_ALPHA ) { if ( color&PNG_COLOR_MASK_PALETTE || color == PNG_COLOR_TYPE_GRAY_ALPHA ) bf->BPP*=2; else bf->BPP*=4; } else { if ( color&PNG_COLOR_MASK_PALETTE || color == PNG_COLOR_TYPE_GRAY ) bf->BPP*=1; else bf->BPP*=3; } png_read_end( png,endinfo ); png_destroy_read_struct( &png,&info,&endinfo ); if ( fclose( fp ) != 0 ) { free( bf->Image ); free( palette ); return 1; } bf->ImageSize=bf->Width * bf->Height * ( bf->BPP / 8 ); mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] filename: %s.\n",fname ); mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] size: %dx%d bits: %d\n",bf->Width,bf->Height,bf->BPP ); mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] imagesize: %lu\n",bf->ImageSize ); return 0; } int conv24to32( txSample * bf ) { unsigned char * tmpImage; int i,c; if ( bf->BPP == 24 ) { tmpImage=bf->Image; bf->ImageSize=bf->Width * bf->Height * 4; bf->BPP=32; if ( ( bf->Image=malloc( bf->ImageSize ) ) == NULL ) { mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[bitmap] Not enough memory for image.\n" ); return 1; } memset( bf->Image,0,bf->ImageSize ); for ( c=0,i=0;i < (int)(bf->Width * bf->Height * 3); ) { bf->Image[c++]=tmpImage[i++]; //red bf->Image[c++]=tmpImage[i++]; //green bf->Image[c++]=tmpImage[i++]; c++; //blue } free( tmpImage ); } return 0; } void bgr2rgb( txSample * bf ) { unsigned char c; int i; for ( i=0;i < (int)bf->ImageSize;i+=4 ) { c=bf->Image[i]; bf->Image[i]=bf->Image[i+2]; bf->Image[i+2]=c; } } void Normalize( txSample * bf ) { int i; #ifndef WORDS_BIGENDIAN for ( i=0;i < (int)bf->ImageSize;i+=4 ) bf->Image[i+3]=0; #else for ( i=0;i < (int)bf->ImageSize;i+=4 ) bf->Image[i]=0; #endif } unsigned char tmp[512]; unsigned char * fExist( unsigned char * fname ) { FILE * fl; unsigned char ext[][6] = { ".png\0",".PNG\0" }; int i; fl=fopen( fname,"rb" ); if ( fl != NULL ) { fclose( fl ); return fname; } for ( i=0;i<2;i++ ) { snprintf( tmp,511,"%s%s",fname,ext[i] ); fl=fopen( tmp,"rb" ); if ( fl != NULL ) { fclose( fl ); return tmp; } } return NULL; } int bpRead( char * fname, txSample * bf ) { fname=fExist( fname ); if ( fname == NULL ) return -2; if ( pngRead( fname,bf ) ) { mp_dbg( MSGT_GPLAYER,MSGL_FATAL,"[bitmap] Unknown file type ( %s ).\n",fname ); return -5; } if ( bf->BPP < 24 ) { mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[bitmap] Sorry, only 24 and 32 bpp bitmaps are supported.\n" ); return -1; } if ( conv24to32( bf ) ) return -8; #ifdef WORDS_BIGENDIAN swab(bf->Image, bf->Image, bf->ImageSize); #endif bgr2rgb( bf ); Normalize( bf ); return 0; } void Convert32to1( txSample * in,txSample * out,int adaptivlimit ) { out->Width=in->Width; out->Height=in->Height; out->BPP=1; out->ImageSize=(out->Width * out->Height + 7) / 8; mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[c32to1] imagesize: %d\n",out->ImageSize ); out->Image=(char *)calloc( 1,out->ImageSize ); if ( out->Image == NULL ) mp_msg( MSGT_GPLAYER,MSGL_STATUS,"[c32to1] Not enough memory for image.\n" ); { int i,b,c=0; unsigned int * buf = NULL; unsigned char tmp = 0; int nothaveshape = 1; buf=(unsigned int *)in->Image; for ( b=0,i=0;i < (int)(out->Width * out->Height);i++ ) { if ( (int)buf[i] != adaptivlimit ) tmp=( tmp >> 1 )|128; else { tmp=tmp >> 1; buf[i]=nothaveshape=0; } if ( b++ == 7 ) { out->Image[c++]=tmp; tmp=b=0; } } if ( b ) out->Image[c]=tmp; if ( nothaveshape ) { free( out->Image ); out->Image=NULL; } } } void Convert1to32( txSample * in,txSample * out ) { if ( in->Image == NULL ) return; out->Width=in->Width; out->Height=in->Height; out->BPP=32; out->ImageSize=out->Width * out->Height * 4; out->Image=(char *)calloc( 1,out->ImageSize ); mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[c1to32] imagesize: %d\n",out->ImageSize ); if ( out->Image == NULL ) mp_msg( MSGT_GPLAYER,MSGL_STATUS,"[c1to32] Not enough memory for image.\n" ); { int i,b,c=0; unsigned int * buf = NULL; unsigned char tmp = 0; buf=(unsigned int *)out->Image; for ( c=0,i=0;i < (int)(in->Width * in->Height / 8);i++ ) { tmp=in->Image[i]; for ( b=0;b<8;b++ ) { buf[c]=0; if ( tmp&0x1 ) buf[c]=0xffffffff; c++; tmp=tmp>>1; } } } }