Mercurial > mplayer.hg
annotate libmpcodecs/vd_ijpg.c @ 33850:934d47636f08
sync with en/mplayer.1 rev. 33893
author | jrash |
---|---|
date | Sat, 30 Jul 2011 03:20:27 +0000 |
parents | 78180f8459a9 |
children |
rev | line source |
---|---|
30421
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
26280
diff
changeset
|
1 /* |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
26280
diff
changeset
|
2 * This file is part of MPlayer. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
26280
diff
changeset
|
3 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
26280
diff
changeset
|
4 * MPlayer is free software; you can redistribute it and/or modify |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
26280
diff
changeset
|
5 * it under the terms of the GNU General Public License as published by |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
26280
diff
changeset
|
6 * the Free Software Foundation; either version 2 of the License, or |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
26280
diff
changeset
|
7 * (at your option) any later version. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
26280
diff
changeset
|
8 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
26280
diff
changeset
|
9 * MPlayer is distributed in the hope that it will be useful, |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
26280
diff
changeset
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
26280
diff
changeset
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
26280
diff
changeset
|
12 * GNU General Public License for more details. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
26280
diff
changeset
|
13 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
26280
diff
changeset
|
14 * You should have received a copy of the GNU General Public License along |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
26280
diff
changeset
|
15 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
26280
diff
changeset
|
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
26280
diff
changeset
|
17 */ |
5029 | 18 |
19 #include <stdio.h> | |
20 #include <stdlib.h> | |
23305
22d3d12c6dfb
Include string.h for memcpy, fastmemcpy.h alone is not enough.
reimar
parents:
21507
diff
changeset
|
21 #include <string.h> |
5029 | 22 |
23 #include "config.h" | |
24 #include "mp_msg.h" | |
25 | |
26 #include <jpeglib.h> | |
5048 | 27 #define UINT16 IJPG_UINT16 |
28 #define INT16 IJPG_INT16 | |
5029 | 29 |
30 #include <setjmp.h> | |
31 | |
21507
fa99b3d31d13
Hack around libavutil/bswap.h compilation problems due to always_inline undefined.
reimar
parents:
21372
diff
changeset
|
32 #include "mpbswap.h" |
5029 | 33 |
34 #include "vd_internal.h" | |
35 | |
30504
cc27da5d7286
Mark all ad_info_t/vd_info_t structure declarations as const.
diego
parents:
30421
diff
changeset
|
36 static const vd_info_t info = { |
5029 | 37 "JPEG Images decoder", |
38 "ijpg", | |
39 "Pontscho", | |
40 "based on vd_mpng.c", | |
18604 | 41 "uses Independent JPEG Group's jpeglib" |
5029 | 42 }; |
43 | |
44 LIBVD_EXTERN(ijpg) | |
45 | |
46 static int last_w=-1; | |
47 static int last_h=-1; | |
25667
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
48 static int last_depth=-1; |
5029 | 49 |
50 // to set/get/query special features/parameters | |
51 static int control(sh_video_t *sh,int cmd,void* arg,...){ | |
25667
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
52 if (cmd == VDCTRL_QUERY_FORMAT) { |
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
53 int format = *(int *)arg; |
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
54 if ((last_depth == 24 && format == IMGFMT_RGB24) || |
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
55 (last_depth == 8 && format == IMGFMT_Y8 )) |
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
56 return CONTROL_TRUE; |
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
57 return CONTROL_FALSE; |
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
58 } |
5029 | 59 return CONTROL_UNKNOWN; |
60 } | |
61 | |
62 // init driver | |
63 static int init(sh_video_t *sh){ | |
64 last_w=-1; | |
65 return 1; | |
66 } | |
67 | |
68 // uninit driver | |
69 static void uninit(sh_video_t *sh){ | |
70 } | |
71 | |
72 //mp_image_t* mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag, int w, int h); | |
73 | |
74 typedef struct | |
75 { | |
76 struct jpeg_source_mgr pub; | |
77 unsigned char * inbuf; | |
78 int bufsize; | |
79 } my_source_mgr; | |
80 | |
81 typedef my_source_mgr * my_src_ptr; | |
82 | |
83 METHODDEF(void) init_source (j_decompress_ptr cinfo) | |
84 { | |
85 } | |
86 | |
87 METHODDEF(boolean) fill_input_buffer (j_decompress_ptr cinfo) | |
88 { | |
25666
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
89 my_src_ptr src = (my_src_ptr) cinfo->src; |
5029 | 90 src->pub.next_input_byte = src->inbuf; |
91 src->pub.bytes_in_buffer = src->bufsize; | |
92 return TRUE; | |
93 } | |
25666
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
94 |
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
95 METHODDEF(void) skip_input_data (j_decompress_ptr cinfo, long num_bytes) |
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
96 { |
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
97 my_src_ptr src = (my_src_ptr) cinfo->src; |
5029 | 98 |
99 if (num_bytes > 0) | |
100 { | |
101 while (num_bytes > (long) src->pub.bytes_in_buffer) | |
102 { | |
103 num_bytes -= (long) src->pub.bytes_in_buffer; | |
104 (void) fill_input_buffer(cinfo); | |
105 } | |
106 src->pub.next_input_byte += (size_t) num_bytes; | |
107 src->pub.bytes_in_buffer -= (size_t) num_bytes; | |
108 } | |
109 } | |
110 | |
25666
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
111 METHODDEF(void) term_source (j_decompress_ptr cinfo) { } |
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
112 |
31197
78180f8459a9
Directly mark jpeg_buf_src() as void instead of using some indirection marcro.
diego
parents:
30555
diff
changeset
|
113 static void jpeg_buf_src (j_decompress_ptr cinfo, char * inbuf, int bufsize) |
5029 | 114 { |
115 my_src_ptr src; | |
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; | |
123 src->inbuf = inbuf; | |
124 src->bufsize=bufsize; | |
125 src->pub.bytes_in_buffer = 0; | |
126 src->pub.next_input_byte = NULL; | |
127 } | |
128 | |
129 struct my_error_mgr | |
130 { | |
131 struct jpeg_error_mgr pub; | |
132 jmp_buf setjmp_buffer; | |
133 }; | |
134 | |
135 typedef struct my_error_mgr * my_error_ptr; | |
136 | |
137 METHODDEF(void) my_error_exit (j_common_ptr cinfo) | |
138 { | |
139 my_error_ptr myerr=(my_error_ptr) cinfo->err; | |
140 (*cinfo->err->output_message) (cinfo); | |
141 longjmp(myerr->setjmp_buffer, 1); | |
142 } | |
143 | |
144 // decode a frame | |
145 static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){ | |
25664 | 146 struct jpeg_decompress_struct cinfo; |
147 struct my_error_mgr jerr; | |
5029 | 148 mp_image_t * mpi = NULL; |
6097 | 149 int width,height,depth,i; |
5029 | 150 |
151 if ( len <= 0 ) return NULL; // skipped frame | |
152 | |
25664 | 153 memset(&cinfo, 0, sizeof(cinfo)); |
154 memset(&jerr, 0, sizeof(jerr)); | |
5366 | 155 cinfo.err=jpeg_std_error( &jerr.pub ); |
156 jerr.pub.error_exit=my_error_exit; | |
5029 | 157 if( setjmp( jerr.setjmp_buffer ) ) |
158 { | |
159 mp_msg( MSGT_DECVIDEO,MSGL_ERR,"[ijpg] setjmp error ...\n" ); | |
160 return NULL; | |
161 } | |
25666
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
162 |
5029 | 163 jpeg_create_decompress( &cinfo ); |
164 jpeg_buf_src( &cinfo,data,len ); | |
165 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
|
166 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
|
167 sh->disp_h=height=cinfo.image_height; |
5029 | 168 jpeg_start_decompress( &cinfo ); |
169 depth=cinfo.output_components * 8; | |
170 | |
171 switch( depth ) { | |
6097 | 172 case 8: |
173 case 24: break; | |
5029 | 174 default: mp_msg( MSGT_DECVIDEO,MSGL_ERR,"Sorry, unsupported JPEG colorspace: %d.\n",depth ); return NULL; |
175 } | |
176 | |
25667
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
177 if ( last_w!=width || last_h!=height || last_depth != depth ) |
5029 | 178 { |
25667
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
179 last_depth = depth; |
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
180 if(!mpcodecs_config_vo( sh,width,height, depth == 8 ? IMGFMT_Y8 : IMGFMT_RGB24 )) return NULL; |
6097 | 181 last_w=width; last_h=height; |
5029 | 182 } |
183 | |
184 mpi=mpcodecs_get_image( sh,MP_IMGTYPE_TEMP,MP_IMGFLAG_ACCEPT_STRIDE,width,height ); | |
185 if ( !mpi ) return NULL; | |
186 | |
187 for ( i=0;i < height;i++ ) | |
188 { | |
6097 | 189 unsigned char * drow = mpi->planes[0] + mpi->stride[0] * i; |
25667
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
190 jpeg_read_scanlines( &cinfo,(JSAMPLE**)&drow,1 ); |
5029 | 191 } |
25666
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
192 |
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
193 jpeg_finish_decompress(&cinfo); |
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
194 jpeg_destroy_decompress(&cinfo); |
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
195 |
5029 | 196 return mpi; |
197 } |