Mercurial > mplayer.hg
annotate libmpcodecs/vd_ijpg.c @ 20997:425ff58ad31b
Move xvid 'grayscale' option close to 'interlacing'
author | gpoirier |
---|---|
date | Sat, 18 Nov 2006 12:26:04 +0000 |
parents | 497ebe3ecc2b |
children | 1767c271d710 |
rev | line source |
---|---|
5029 | 1 |
2 #include <stdio.h> | |
3 #include <stdlib.h> | |
4 | |
5 #include "config.h" | |
6 #include "mp_msg.h" | |
7 | |
8 #include <jpeglib.h> | |
5048 | 9 #define UINT16 IJPG_UINT16 |
10 #define INT16 IJPG_INT16 | |
5029 | 11 |
12 #include <setjmp.h> | |
13 | |
14 #include "bswap.h" | |
15 #include "libvo/fastmemcpy.h" | |
16 | |
17 #include "vd_internal.h" | |
18 | |
19 static vd_info_t info = { | |
20 "JPEG Images decoder", | |
21 "ijpg", | |
22 "Pontscho", | |
23 "based on vd_mpng.c", | |
18604 | 24 "uses Independent JPEG Group's jpeglib" |
5029 | 25 }; |
26 | |
27 LIBVD_EXTERN(ijpg) | |
28 | |
29 static int last_w=-1; | |
30 static int last_h=-1; | |
31 | |
32 // to set/get/query special features/parameters | |
33 static int control(sh_video_t *sh,int cmd,void* arg,...){ | |
34 return CONTROL_UNKNOWN; | |
35 } | |
36 | |
37 // init driver | |
38 static int init(sh_video_t *sh){ | |
39 last_w=-1; | |
40 return 1; | |
41 } | |
42 | |
43 // uninit driver | |
44 static void uninit(sh_video_t *sh){ | |
45 } | |
46 | |
47 //mp_image_t* mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag, int w, int h); | |
48 | |
49 typedef struct | |
50 { | |
51 struct jpeg_source_mgr pub; | |
52 unsigned char * inbuf; | |
53 int bufsize; | |
54 } my_source_mgr; | |
55 | |
56 typedef my_source_mgr * my_src_ptr; | |
57 | |
58 METHODDEF(void) init_source (j_decompress_ptr cinfo) | |
59 { | |
60 } | |
61 | |
62 METHODDEF(boolean) fill_input_buffer (j_decompress_ptr cinfo) | |
63 { | |
64 my_src_ptr src = (my_src_ptr) cinfo->src; | |
65 src->pub.next_input_byte = src->inbuf; | |
66 src->pub.bytes_in_buffer = src->bufsize; | |
67 return TRUE; | |
68 } | |
69 | |
70 METHODDEF(void) skip_input_data (j_decompress_ptr cinfo, long num_bytes) | |
71 { | |
72 my_src_ptr src = (my_src_ptr) cinfo->src; | |
73 | |
74 if (num_bytes > 0) | |
75 { | |
76 while (num_bytes > (long) src->pub.bytes_in_buffer) | |
77 { | |
78 num_bytes -= (long) src->pub.bytes_in_buffer; | |
79 (void) fill_input_buffer(cinfo); | |
80 } | |
81 src->pub.next_input_byte += (size_t) num_bytes; | |
82 src->pub.bytes_in_buffer -= (size_t) num_bytes; | |
83 } | |
84 } | |
85 | |
86 METHODDEF(void) term_source (j_decompress_ptr cinfo) { } | |
87 | |
88 GLOBAL(void) jpeg_buf_src ( j_decompress_ptr cinfo, char * inbuf,int bufsize ) | |
89 { | |
90 my_src_ptr src; | |
91 if (cinfo->src == NULL) cinfo->src=malloc( sizeof( my_source_mgr ) ); | |
92 src = (my_src_ptr) cinfo->src; | |
93 src->pub.init_source = init_source; | |
94 src->pub.fill_input_buffer = fill_input_buffer; | |
95 src->pub.skip_input_data = skip_input_data; | |
96 src->pub.resync_to_restart = jpeg_resync_to_restart; | |
97 src->pub.term_source = term_source; | |
98 src->inbuf = inbuf; | |
99 src->bufsize=bufsize; | |
100 src->pub.bytes_in_buffer = 0; | |
101 src->pub.next_input_byte = NULL; | |
102 } | |
103 | |
104 struct my_error_mgr | |
105 { | |
106 struct jpeg_error_mgr pub; | |
107 jmp_buf setjmp_buffer; | |
108 }; | |
109 | |
110 typedef struct my_error_mgr * my_error_ptr; | |
111 | |
112 METHODDEF(void) my_error_exit (j_common_ptr cinfo) | |
113 { | |
114 my_error_ptr myerr=(my_error_ptr) cinfo->err; | |
115 (*cinfo->err->output_message) (cinfo); | |
116 longjmp(myerr->setjmp_buffer, 1); | |
117 } | |
118 | |
119 static struct jpeg_decompress_struct cinfo; | |
120 static struct my_error_mgr jerr; | |
121 static int row_stride; | |
6097 | 122 static unsigned char *temp_row=NULL; |
123 | |
5029 | 124 // decode a frame |
125 static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){ | |
126 mp_image_t * mpi = NULL; | |
6097 | 127 int width,height,depth,i; |
5029 | 128 |
129 if ( len <= 0 ) return NULL; // skipped frame | |
130 | |
5366 | 131 cinfo.err=jpeg_std_error( &jerr.pub ); |
132 jerr.pub.error_exit=my_error_exit; | |
5029 | 133 if( setjmp( jerr.setjmp_buffer ) ) |
134 { | |
135 mp_msg( MSGT_DECVIDEO,MSGL_ERR,"[ijpg] setjmp error ...\n" ); | |
136 return NULL; | |
137 } | |
138 | |
139 jpeg_create_decompress( &cinfo ); | |
140 jpeg_buf_src( &cinfo,data,len ); | |
141 jpeg_read_header( &cinfo,TRUE ); | |
5365
b87743434e1f
Issue a warning in VDec if disp_w and disp_h weren't set by codec and try workaround.
atmos4
parents:
5124
diff
changeset
|
142 sh->disp_w=width=cinfo.image_width; |
b87743434e1f
Issue a warning in VDec if disp_w and disp_h weren't set by codec and try workaround.
atmos4
parents:
5124
diff
changeset
|
143 sh->disp_h=height=cinfo.image_height; |
5029 | 144 jpeg_start_decompress( &cinfo ); |
145 depth=cinfo.output_components * 8; | |
146 | |
147 switch( depth ) { | |
6097 | 148 case 8: |
149 case 24: break; | |
5029 | 150 default: mp_msg( MSGT_DECVIDEO,MSGL_ERR,"Sorry, unsupported JPEG colorspace: %d.\n",depth ); return NULL; |
151 } | |
152 | |
6097 | 153 if ( last_w!=width || last_h!=height ) |
5029 | 154 { |
6097 | 155 if(!mpcodecs_config_vo( sh,width,height, IMGFMT_RGB24 )) return NULL; |
156 if(temp_row) free(temp_row); | |
157 temp_row=malloc(3*width+16); | |
158 last_w=width; last_h=height; | |
5029 | 159 } |
160 | |
161 mpi=mpcodecs_get_image( sh,MP_IMGTYPE_TEMP,MP_IMGFLAG_ACCEPT_STRIDE,width,height ); | |
162 if ( !mpi ) return NULL; | |
163 | |
164 row_stride=cinfo.output_width * cinfo.output_components; | |
165 | |
166 for ( i=0;i < height;i++ ) | |
167 { | |
6097 | 168 unsigned char * drow = mpi->planes[0] + mpi->stride[0] * i; |
169 unsigned char * row = (mpi->imgfmt==IMGFMT_RGB24 && depth==24) ? drow : temp_row; | |
5042 | 170 jpeg_read_scanlines( &cinfo,(JSAMPLE**)&row,1 ); |
6097 | 171 if(depth==8){ |
172 // grayscale -> rgb/bgr 24/32 | |
173 int x; | |
174 if(mpi->bpp==32) | |
175 for(x=0;x<width;x++) drow[4*x]=0x010101*row[x]; | |
176 else | |
177 for(x=0;x<width;x++) drow[3*x+0]=drow[3*x+1]=drow[3*x+2]=row[x]; | |
178 } else { | |
179 int x; | |
180 switch(mpi->imgfmt){ | |
181 // rgb24 -> bgr24 | |
182 case IMGFMT_BGR24: | |
183 for(x=0;x<3*width;x+=3){ | |
184 drow[x+0]=row[x+2]; | |
185 drow[x+1]=row[x+1]; | |
186 drow[x+2]=row[x+0]; | |
187 } | |
188 break; | |
189 // rgb24 -> bgr32 | |
190 case IMGFMT_BGR32: | |
191 for(x=0;x<width;x++){ | |
18167 | 192 #ifdef WORDS_BIGENDIAN |
193 drow[4*x+1]=row[3*x+0]; | |
194 drow[4*x+2]=row[3*x+1]; | |
195 drow[4*x+3]=row[3*x+2]; | |
196 #else | |
6097 | 197 drow[4*x+0]=row[3*x+2]; |
198 drow[4*x+1]=row[3*x+1]; | |
199 drow[4*x+2]=row[3*x+0]; | |
18167 | 200 #endif |
6097 | 201 } |
202 break; | |
203 } | |
204 } | |
5029 | 205 } |
206 | |
207 jpeg_finish_decompress(&cinfo); | |
208 jpeg_destroy_decompress(&cinfo); | |
209 | |
210 return mpi; | |
211 } |