Update to MPlayer SVN rev 29473 and FFmpeg SVN rev 19572.
[vaapi:athaifas-mplayer.git] / gui / .svn / text-base / bitmap.c.svn-base
1 /*
2  * This file is part of MPlayer.
3  *
4  * MPlayer is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * MPlayer is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #include "mp_msg.h"
24 #include "help_mp.h"
25 #include "bitmap.h"
26 #include "libavcodec/avcodec.h"
27 #include "libavutil/intreadwrite.h"
28 #include "libvo/fastmemcpy.h"
29
30 static int pngRead( unsigned char * fname,txSample * bf )
31 {
32  int             decode_ok;
33  void           *data;
34  int             len;
35  AVCodecContext *avctx;
36  AVFrame        *frame;
37
38  FILE *fp=fopen( fname,"rb" );
39  if ( !fp )
40   {
41    mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] file read error ( %s )\n",fname );
42    return 1;
43   }
44
45  fseek(fp, 0, SEEK_END);
46  len = ftell(fp);
47  if (len > 50 * 1024 * 1024) return 2;
48  data = malloc(len + FF_INPUT_BUFFER_PADDING_SIZE);
49  fseek(fp, 0, SEEK_SET);
50  fread(data, len, 1, fp);
51  fclose(fp);
52  avctx = avcodec_alloc_context();
53  frame = avcodec_alloc_frame();
54  avcodec_register_all();
55  avcodec_open(avctx, avcodec_find_decoder(CODEC_ID_PNG));
56  avcodec_decode_video(avctx, frame, &decode_ok, data, len);
57  memset(bf, 0, sizeof(*bf));
58  switch (avctx->pix_fmt) {
59    case PIX_FMT_GRAY8:    bf->BPP =  8; break;
60    case PIX_FMT_GRAY16BE: bf->BPP = 16; break;
61    case PIX_FMT_RGB24:    bf->BPP = 24; break;
62    case PIX_FMT_RGB32:    bf->BPP = 32; break;
63    default:               bf->BPP =  0; break;
64  }
65  if (decode_ok && bf->BPP) {
66    int bpl;
67    bf->Width = avctx->width; bf->Height = avctx->height;
68    bpl = bf->Width * (bf->BPP / 8);
69    bf->ImageSize = bpl * bf->Height;
70    bf->Image = malloc(bf->ImageSize);
71    memcpy_pic(bf->Image, frame->data[0], bpl, bf->Height, bpl, frame->linesize[0]);
72  }
73  avcodec_close(avctx);
74  av_freep(&frame);
75  av_freep(&avctx);
76
77  mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] filename: %s.\n",fname );
78  mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png]  size: %dx%d bits: %d\n",bf->Width,bf->Height,bf->BPP );
79  mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png]  imagesize: %lu\n",bf->ImageSize );
80  return !(decode_ok && bf->BPP);
81 }
82
83 static int conv24to32( txSample * bf )
84 {
85  unsigned char * tmpImage;
86  int             i,c;
87
88  if ( bf->BPP == 24 )
89   {
90    tmpImage=bf->Image;
91    bf->ImageSize=bf->Width * bf->Height * 4;
92    bf->BPP=32;
93    if ( ( bf->Image=calloc( 1, bf->ImageSize ) ) == NULL )
94     {
95      free( tmpImage );
96      mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[bitmap] not enough memory for image\n" );
97      return 1;
98     }
99    for ( c=0,i=0; c < bf->ImageSize; c += 4, i += 3)
100     {
101      *(uint32_t *)&bf->Image[c] = AV_RB24(&tmpImage[i]);
102     }
103    free( tmpImage );
104   }
105  return 0;
106 }
107
108 static void Normalize( txSample * bf )
109 {
110  int           i;
111 #if !HAVE_BIGENDIAN
112  for ( i=0;i < (int)bf->ImageSize;i+=4 ) bf->Image[i+3]=0;
113 #else
114  for ( i=0;i < (int)bf->ImageSize;i+=4 ) bf->Image[i]=0;
115 #endif
116 }
117
118 static unsigned char tmp[512];
119
120 static unsigned char * fExist( unsigned char * fname )
121 {
122  FILE          * fl;
123  unsigned char   ext[][6] = { ".png\0",".PNG\0" };
124  int             i;
125
126  fl=fopen( fname,"rb" );
127  if ( fl != NULL )
128   {
129    fclose( fl );
130    return fname;
131   }
132  for ( i=0;i<2;i++ )
133   {
134    snprintf( tmp,511,"%s%s",fname,ext[i] );
135    fl=fopen( tmp,"rb" );
136    if ( fl != NULL )
137     {
138      fclose( fl );
139      return tmp;
140     }
141   }
142  return NULL;
143 }
144
145 int bpRead( char * fname, txSample * bf )
146 {
147  fname=fExist( fname );
148  if ( fname == NULL ) return -2;
149  if ( pngRead( fname,bf ) )
150   {
151    mp_dbg( MSGT_GPLAYER,MSGL_FATAL,"[bitmap] unknown file type ( %s )\n",fname );
152    return -5;
153   }
154  if ( bf->BPP < 24 )
155   {
156    mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[bitmap] Sorry, only 24 and 32 bpp bitmaps are supported.\n" );
157    return -1;
158   }
159  if ( conv24to32( bf ) ) return -8;
160  Normalize( bf );
161  return 0;
162 }
163
164 void Convert32to1( txSample * in,txSample * out,int adaptivlimit )
165 {
166  out->Width=in->Width;
167  out->Height=in->Height;
168  out->BPP=1;
169  out->ImageSize=(out->Width * out->Height + 7) / 8;
170  mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[c32to1] imagesize: %d\n",out->ImageSize );
171  out->Image=calloc( 1,out->ImageSize );
172  if ( out->Image == NULL ) mp_msg( MSGT_GPLAYER,MSGL_WARN,MSGTR_NotEnoughMemoryC32To1 );
173  {
174   int i,b,c=0; unsigned int * buf = NULL; unsigned char tmp = 0; int nothaveshape = 1;
175   buf=(unsigned int *)in->Image;
176   for ( b=0,i=0;i < (int)(out->Width * out->Height);i++ )
177    {
178     if ( (int)buf[i] != adaptivlimit ) tmp=( tmp >> 1 )|128;
179      else { tmp=tmp >> 1; buf[i]=nothaveshape=0; }
180     if ( b++ == 7 ) { out->Image[c++]=tmp; tmp=b=0; }
181    }
182   if ( b ) out->Image[c]=tmp;
183   if ( nothaveshape ) { free( out->Image ); out->Image=NULL; }
184  }
185 }