2 * This file is part of MPlayer.
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.
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.
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.
27 #define UINT16 IJPG_UINT16
28 #define INT16 IJPG_INT16
34 #include "vd_internal.h"
36 static const vd_info_t info
= {
37 "JPEG Images decoder",
41 "uses Independent JPEG Group's jpeglib"
48 static int last_depth
=-1;
50 // to set/get/query special features/parameters
51 static int control(sh_video_t
*sh
,int cmd
,void* arg
,...){
52 if (cmd
== VDCTRL_QUERY_FORMAT
) {
53 int format
= *(int *)arg
;
54 if ((last_depth
== 24 && format
== IMGFMT_RGB24
) ||
55 (last_depth
== 8 && format
== IMGFMT_Y8
))
59 return CONTROL_UNKNOWN
;
63 static int init(sh_video_t
*sh
){
69 static void uninit(sh_video_t
*sh
){
72 //mp_image_t* mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag, int w, int h);
76 struct jpeg_source_mgr pub
;
77 unsigned char * inbuf
;
81 typedef my_source_mgr
* my_src_ptr
;
83 METHODDEF(void) init_source (j_decompress_ptr cinfo
)
87 METHODDEF(boolean
) fill_input_buffer (j_decompress_ptr cinfo
)
89 my_src_ptr src
= (my_src_ptr
) cinfo
->src
;
90 src
->pub
.next_input_byte
= src
->inbuf
;
91 src
->pub
.bytes_in_buffer
= src
->bufsize
;
95 METHODDEF(void) skip_input_data (j_decompress_ptr cinfo
, long num_bytes
)
97 my_src_ptr src
= (my_src_ptr
) cinfo
->src
;
101 while (num_bytes
> (long) src
->pub
.bytes_in_buffer
)
103 num_bytes
-= (long) src
->pub
.bytes_in_buffer
;
104 (void) fill_input_buffer(cinfo
);
106 src
->pub
.next_input_byte
+= (size_t) num_bytes
;
107 src
->pub
.bytes_in_buffer
-= (size_t) num_bytes
;
111 METHODDEF(void) term_source (j_decompress_ptr cinfo
) { }
113 static void jpeg_buf_src (j_decompress_ptr cinfo
, char * inbuf
, int bufsize
)
116 if (cinfo
->src
== NULL
) cinfo
->src
=malloc( sizeof( my_source_mgr
) );
117 src
= (my_src_ptr
) cinfo
->src
;
118 src
->pub
.init_source
= init_source
;
119 src
->pub
.fill_input_buffer
= fill_input_buffer
;
120 src
->pub
.skip_input_data
= skip_input_data
;
121 src
->pub
.resync_to_restart
= jpeg_resync_to_restart
;
122 src
->pub
.term_source
= term_source
;
124 src
->bufsize
=bufsize
;
125 src
->pub
.bytes_in_buffer
= 0;
126 src
->pub
.next_input_byte
= NULL
;
131 struct jpeg_error_mgr pub
;
132 jmp_buf setjmp_buffer
;
135 typedef struct my_error_mgr
* my_error_ptr
;
137 METHODDEF(void) my_error_exit (j_common_ptr cinfo
)
139 my_error_ptr myerr
=(my_error_ptr
) cinfo
->err
;
140 (*cinfo
->err
->output_message
) (cinfo
);
141 longjmp(myerr
->setjmp_buffer
, 1);
145 static mp_image_t
* decode(sh_video_t
*sh
,void* data
,int len
,int flags
){
146 struct jpeg_decompress_struct cinfo
;
147 struct my_error_mgr jerr
;
148 mp_image_t
* mpi
= NULL
;
149 int width
,height
,depth
,i
;
151 if ( len
<= 0 ) return NULL
; // skipped frame
153 memset(&cinfo
, 0, sizeof(cinfo
));
154 memset(&jerr
, 0, sizeof(jerr
));
155 cinfo
.err
=jpeg_std_error( &jerr
.pub
);
156 jerr
.pub
.error_exit
=my_error_exit
;
157 if( setjmp( jerr
.setjmp_buffer
) )
159 mp_msg( MSGT_DECVIDEO
,MSGL_ERR
,"[ijpg] setjmp error ...\n" );
163 jpeg_create_decompress( &cinfo
);
164 jpeg_buf_src( &cinfo
,data
,len
);
165 jpeg_read_header( &cinfo
,TRUE
);
166 sh
->disp_w
=width
=cinfo
.image_width
;
167 sh
->disp_h
=height
=cinfo
.image_height
;
168 jpeg_start_decompress( &cinfo
);
169 depth
=cinfo
.output_components
* 8;
174 default: mp_msg( MSGT_DECVIDEO
,MSGL_ERR
,"Sorry, unsupported JPEG colorspace: %d.\n",depth
); return NULL
;
177 if ( last_w
!=width
|| last_h
!=height
|| last_depth
!= depth
)
180 if(!mpcodecs_config_vo( sh
,width
,height
, depth
== 8 ? IMGFMT_Y8
: IMGFMT_RGB24
)) return NULL
;
181 last_w
=width
; last_h
=height
;
184 mpi
=mpcodecs_get_image( sh
,MP_IMGTYPE_TEMP
,MP_IMGFLAG_ACCEPT_STRIDE
,width
,height
);
185 if ( !mpi
) return NULL
;
187 for ( i
=0;i
< height
;i
++ )
189 unsigned char * drow
= mpi
->planes
[0] + mpi
->stride
[0] * i
;
190 jpeg_read_scanlines( &cinfo
,(JSAMPLE
**)&drow
,1 );
193 jpeg_finish_decompress(&cinfo
);
194 jpeg_destroy_decompress(&cinfo
);