0a1bb60dcc6c4bdbc1ab248e13d3bd2cb65cc2c3
[platform/upstream/gst-plugins-good.git] / ext / jpeg / gstjpegdec.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library 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 GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 #include <string.h>
25
26 /*#define DEBUG_ENABLED*/
27 #include "gstjpegdec.h"
28 #include <gst/video/video.h>
29
30 /* elementfactory information */
31 GstElementDetails gst_jpegdec_details = {
32   "JPEG image decoder",
33   "Codec/Decoder/Image",
34   "Decode images from JPEG format",
35   "Wim Taymans <wim.taymans@tvd.be>",
36 };
37
38 /* JpegDec signals and args */
39 enum {
40   /* FILL ME */
41   LAST_SIGNAL
42 };
43
44 enum {
45   ARG_0,
46   /* FILL ME */
47 };
48
49 static void     gst_jpegdec_base_init   (gpointer g_class);
50 static void     gst_jpegdec_class_init  (GstJpegDec *klass);
51 static void     gst_jpegdec_init        (GstJpegDec *jpegdec);
52
53 static void     gst_jpegdec_chain       (GstPad *pad, GstData *_data);
54 static GstPadLinkReturn
55                 gst_jpegdec_link        (GstPad *pad, const GstCaps *caps);
56
57 static GstElementClass *parent_class = NULL;
58 /*static guint gst_jpegdec_signals[LAST_SIGNAL] = { 0 }; */
59
60 GType
61 gst_jpegdec_get_type(void) {
62   static GType jpegdec_type = 0;
63   
64   if (!jpegdec_type) {
65     static const GTypeInfo jpegdec_info = {
66       sizeof(GstJpegDec),
67       gst_jpegdec_base_init,
68       NULL,
69       (GClassInitFunc)gst_jpegdec_class_init,
70       NULL,
71       NULL,
72       sizeof(GstJpegDec),
73       0,
74       (GInstanceInitFunc)gst_jpegdec_init,
75     };
76     jpegdec_type = g_type_register_static(GST_TYPE_ELEMENT, "GstJpegDec", &jpegdec_info, 0);
77   }
78   return jpegdec_type;
79 }
80
81 static GstStaticPadTemplate gst_jpegdec_src_pad_template =
82 GST_STATIC_PAD_TEMPLATE (
83     "src",
84     GST_PAD_SRC,
85     GST_PAD_ALWAYS,
86     GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV("I420"))
87 );
88
89 static GstStaticPadTemplate gst_jpegdec_sink_pad_template =
90 GST_STATIC_PAD_TEMPLATE (
91     "sink",
92     GST_PAD_SINK,
93     GST_PAD_ALWAYS,
94     GST_STATIC_CAPS ("image/jpeg, "
95       "width = (int) [ 16, 4096 ], " 
96       "height = (int) [ 16, 4096 ], "
97       "framerate = (double) [ 1, MAX ]"
98     )
99 );
100
101 static void
102 gst_jpegdec_base_init (gpointer g_class)
103 {
104   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
105   
106   gst_element_class_add_pad_template (element_class,
107       gst_static_pad_template_get (&gst_jpegdec_src_pad_template));
108   gst_element_class_add_pad_template (element_class,
109       gst_static_pad_template_get (&gst_jpegdec_sink_pad_template));
110   gst_element_class_set_details (element_class, &gst_jpegdec_details);
111 }
112
113 static void
114 gst_jpegdec_class_init (GstJpegDec *klass)
115 {
116   GstElementClass *gstelement_class;
117
118   gstelement_class = (GstElementClass*)klass;
119
120   parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
121 }
122
123 static void
124 gst_jpegdec_init_source (j_decompress_ptr cinfo)
125 {
126   GST_DEBUG ("gst_jpegdec_chain: init_source");
127 }
128 static gboolean
129 gst_jpegdec_fill_input_buffer (j_decompress_ptr cinfo)
130 {
131   GST_DEBUG ("gst_jpegdec_chain: fill_input_buffer");
132   return TRUE;
133 }
134
135 static void
136 gst_jpegdec_skip_input_data (j_decompress_ptr cinfo, glong num_bytes)
137 {
138   GST_DEBUG ("gst_jpegdec_chain: skip_input_data");
139 }
140
141 static gboolean
142 gst_jpegdec_resync_to_restart (j_decompress_ptr cinfo, gint desired)
143 {
144   GST_DEBUG ("gst_jpegdec_chain: resync_to_start");
145   return TRUE;
146 }
147
148 static void
149 gst_jpegdec_term_source (j_decompress_ptr cinfo)
150 {
151   GST_DEBUG ("gst_jpegdec_chain: term_source");
152 }
153
154 static void
155 gst_jpegdec_init (GstJpegDec *jpegdec)
156 {
157   GST_DEBUG ("gst_jpegdec_init: initializing");
158   /* create the sink and src pads */
159
160   jpegdec->sinkpad = gst_pad_new_from_template (
161       gst_static_pad_template_get (&gst_jpegdec_sink_pad_template), "sink");
162   gst_element_add_pad(GST_ELEMENT(jpegdec),jpegdec->sinkpad);
163   gst_pad_set_chain_function(jpegdec->sinkpad,gst_jpegdec_chain);
164   gst_pad_set_link_function(jpegdec->sinkpad, gst_jpegdec_link);
165
166   jpegdec->srcpad = gst_pad_new_from_template (
167       gst_static_pad_template_get (&gst_jpegdec_src_pad_template), "src");
168   gst_pad_use_explicit_caps (jpegdec->srcpad);
169   gst_element_add_pad(GST_ELEMENT(jpegdec),jpegdec->srcpad);
170
171   /* initialize the jpegdec decoder state */
172   jpegdec->next_time = 0;
173
174   /* reset the initial video state */
175   jpegdec->format = -1;
176   jpegdec->width = -1;
177   jpegdec->height = -1;
178
179   jpegdec->line[0] = NULL;
180   jpegdec->line[1] = NULL;
181   jpegdec->line[2] = NULL;
182
183   /* setup jpeglib */
184   memset(&jpegdec->cinfo, 0, sizeof(jpegdec->cinfo));
185   memset(&jpegdec->jerr, 0, sizeof(jpegdec->jerr));
186   jpegdec->cinfo.err = jpeg_std_error(&jpegdec->jerr);
187   jpeg_create_decompress(&jpegdec->cinfo);
188
189   jpegdec->jsrc.init_source = gst_jpegdec_init_source;
190   jpegdec->jsrc.fill_input_buffer = gst_jpegdec_fill_input_buffer;
191   jpegdec->jsrc.skip_input_data = gst_jpegdec_skip_input_data;
192   jpegdec->jsrc.resync_to_restart = gst_jpegdec_resync_to_restart;
193   jpegdec->jsrc.term_source = gst_jpegdec_term_source;
194   jpegdec->cinfo.src = &jpegdec->jsrc;
195
196 }
197
198 static GstPadLinkReturn
199 gst_jpegdec_link (GstPad *pad, const GstCaps *caps)
200 {
201   GstJpegDec *jpegdec = GST_JPEGDEC (gst_pad_get_parent (pad));
202   GstStructure *structure;
203   GstCaps *srccaps;
204
205   structure = gst_caps_get_structure (caps, 0);
206
207   gst_structure_get_double (structure, "framerate", &jpegdec->fps);
208   gst_structure_get_int (structure, "width",     &jpegdec->width);
209   gst_structure_get_int (structure, "height",    &jpegdec->height);
210
211   srccaps = gst_caps_new_simple ("video/x-raw-yuv",
212       "format",    GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I','4','2','0'),
213       "width",     G_TYPE_INT, jpegdec->width,
214       "height",    G_TYPE_INT, jpegdec->height,
215       "framerate", G_TYPE_DOUBLE, jpegdec->fps,
216       NULL);
217
218   /* at this point, we're pretty sure that this will be the output
219    * format, so we'll set it. */
220   gst_pad_set_explicit_caps (jpegdec->srcpad, srccaps);
221
222   return GST_PAD_LINK_OK;
223 }
224
225 /* shamelessly ripped from jpegutils.c in mjpegtools */
226 static void add_huff_table (j_decompress_ptr dinfo,
227                             JHUFF_TBL **htblptr, 
228                             const UINT8 *bits, const UINT8 *val)
229 /* Define a Huffman table */
230 {
231   int nsymbols, len;
232
233   if (*htblptr == NULL)
234     *htblptr = jpeg_alloc_huff_table((j_common_ptr) dinfo);
235
236   /* Copy the number-of-symbols-of-each-code-length counts */
237   memcpy((*htblptr)->bits, bits, sizeof((*htblptr)->bits));
238
239   /* Validate the counts.  We do this here mainly so we can copy the right
240    * number of symbols from the val[] array, without risking marching off
241    * the end of memory.  jchuff.c will do a more thorough test later.
242    */
243   nsymbols = 0;
244   for (len = 1; len <= 16; len++)
245     nsymbols += bits[len];
246   if (nsymbols < 1 || nsymbols > 256)
247     g_error("jpegutils.c:  add_huff_table failed badly. ");
248
249   memcpy((*htblptr)->huffval, val, nsymbols * sizeof(UINT8));
250 }
251
252
253
254 static void std_huff_tables (j_decompress_ptr dinfo)
255 /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
256 /* IMPORTANT: these are only valid for 8-bit data precision! */
257 {
258   static const UINT8 bits_dc_luminance[17] =
259     { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
260   static const UINT8 val_dc_luminance[] =
261     { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
262   
263   static const UINT8 bits_dc_chrominance[17] =
264     { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
265   static const UINT8 val_dc_chrominance[] =
266     { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
267   
268   static const UINT8 bits_ac_luminance[17] =
269     { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
270   static const UINT8 val_ac_luminance[] =
271     { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
272       0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
273       0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
274       0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
275       0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
276       0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
277       0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
278       0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
279       0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
280       0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
281       0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
282       0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
283       0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
284       0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
285       0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
286       0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
287       0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
288       0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
289       0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
290       0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
291       0xf9, 0xfa };
292   
293   static const UINT8 bits_ac_chrominance[17] =
294     { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
295   static const UINT8 val_ac_chrominance[] =
296     { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
297       0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
298       0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
299       0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
300       0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
301       0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
302       0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
303       0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
304       0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
305       0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
306       0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
307       0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
308       0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
309       0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
310       0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
311       0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
312       0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
313       0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
314       0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
315       0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
316       0xf9, 0xfa };
317   
318   add_huff_table(dinfo, &dinfo->dc_huff_tbl_ptrs[0],
319                  bits_dc_luminance, val_dc_luminance);
320   add_huff_table(dinfo, &dinfo->ac_huff_tbl_ptrs[0],
321                  bits_ac_luminance, val_ac_luminance);
322   add_huff_table(dinfo, &dinfo->dc_huff_tbl_ptrs[1],
323                  bits_dc_chrominance, val_dc_chrominance);
324   add_huff_table(dinfo, &dinfo->ac_huff_tbl_ptrs[1],
325                  bits_ac_chrominance, val_ac_chrominance);
326 }
327
328
329
330 static void guarantee_huff_tables(j_decompress_ptr dinfo)
331 {
332   if ( (dinfo->dc_huff_tbl_ptrs[0] == NULL) &&
333        (dinfo->dc_huff_tbl_ptrs[1] == NULL) &&
334        (dinfo->ac_huff_tbl_ptrs[0] == NULL) &&
335        (dinfo->ac_huff_tbl_ptrs[1] == NULL) ) {
336     GST_DEBUG (
337                "Generating standard Huffman tables for this frame.");
338     std_huff_tables(dinfo);
339   }
340 }
341
342 static void
343 gst_jpegdec_chain (GstPad *pad, GstData *_data)
344 {
345   GstBuffer *buf = GST_BUFFER (_data);
346   GstJpegDec *jpegdec;
347   guchar *data, *outdata;
348   gulong size, outsize;
349   GstBuffer *outbuf;
350   /*GstMeta *meta;*/
351   gint width, height, width2;
352   guchar *base[3];
353   gint i,j, k;
354   gint r_h, r_v;
355
356   g_return_if_fail(pad != NULL);
357   g_return_if_fail(GST_IS_PAD(pad));
358   g_return_if_fail(buf != NULL);
359   /*g_return_if_fail(GST_IS_BUFFER(buf));*/
360
361   jpegdec = GST_JPEGDEC (GST_OBJECT_PARENT (pad));
362
363   if (!GST_PAD_IS_LINKED (jpegdec->srcpad)) {
364     gst_buffer_unref (buf);
365     return;
366   }
367
368   data = (guchar *)GST_BUFFER_DATA(buf);
369   size = GST_BUFFER_SIZE(buf);
370   GST_DEBUG ("gst_jpegdec_chain: got buffer of %ld bytes in '%s'",size,
371           GST_OBJECT_NAME (jpegdec));
372
373   jpegdec->jsrc.next_input_byte = data;
374   jpegdec->jsrc.bytes_in_buffer = size;
375                                   
376
377   GST_DEBUG ("gst_jpegdec_chain: reading header %08lx", *(gulong *)data);
378   jpeg_read_header(&jpegdec->cinfo, TRUE);
379
380   r_h = jpegdec->cinfo.cur_comp_info[0]->h_samp_factor;
381   r_v = jpegdec->cinfo.cur_comp_info[0]->v_samp_factor;
382
383   /*g_print ("%d %d\n", r_h, r_v);*/
384   /*g_print ("%d %d\n", jpegdec->cinfo.cur_comp_info[1]->h_samp_factor, jpegdec->cinfo.cur_comp_info[1]->v_samp_factor);*/
385   /*g_print ("%d %d\n", jpegdec->cinfo.cur_comp_info[2]->h_samp_factor, jpegdec->cinfo.cur_comp_info[2]->v_samp_factor);*/
386
387   jpegdec->cinfo.do_fancy_upsampling = FALSE;
388   jpegdec->cinfo.do_block_smoothing = FALSE;
389   jpegdec->cinfo.out_color_space = JCS_YCbCr;
390   jpegdec->cinfo.dct_method = JDCT_IFAST;
391   jpegdec->cinfo.raw_data_out = TRUE;
392   GST_DEBUG ("gst_jpegdec_chain: starting decompress");
393   guarantee_huff_tables(&jpegdec->cinfo);
394   jpeg_start_decompress(&jpegdec->cinfo);
395   width = jpegdec->cinfo.output_width;
396   height = jpegdec->cinfo.output_height;
397   GST_DEBUG ("gst_jpegdec_chain: width %d, height %d", width, height);
398
399   outbuf = gst_buffer_new();
400   outsize = GST_BUFFER_SIZE(outbuf) = width*height +
401                                       width*height / 2;
402   outdata = GST_BUFFER_DATA(outbuf) = g_malloc(outsize);
403   GST_BUFFER_TIMESTAMP(outbuf) = GST_BUFFER_TIMESTAMP(buf);
404
405   if (jpegdec->height != height || jpegdec->line[0] == NULL) {
406     GstCaps *caps;
407
408     jpegdec->line[0] = g_realloc(jpegdec->line[0], height*sizeof(char*));
409     jpegdec->line[1] = g_realloc(jpegdec->line[1], height*sizeof(char*));
410     jpegdec->line[2] = g_realloc(jpegdec->line[2], height*sizeof(char*));
411     jpegdec->height = height;
412
413     caps = gst_caps_new_simple ("video/x-raw-yuv",
414           "format",    GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I','4','2','0'),
415           "width",     G_TYPE_INT, width,
416           "height",    G_TYPE_INT, height,
417           "framerate", G_TYPE_DOUBLE, jpegdec->fps,
418           NULL);
419     gst_pad_set_explicit_caps (jpegdec->srcpad, caps);
420     gst_caps_free (caps);
421   }
422
423   /* mind the swap, jpeglib outputs blue chroma first */
424   base[0] = outdata;
425   base[1] = base[0]+width*height;
426   base[2] = base[1]+width*height/4;
427
428   width2 = width >> 1;
429
430   GST_DEBUG ("gst_jpegdec_chain: decompressing %u", jpegdec->cinfo.rec_outbuf_height);
431   for (i = 0; i < height; i += r_v*DCTSIZE) {
432     for (j=0, k=0; j< (r_v*DCTSIZE); j += r_v, k++) {
433       jpegdec->line[0][j]   = base[0]; base[0] += width;
434       if (r_v == 2) {
435          jpegdec->line[0][j+1] = base[0]; base[0] += width;
436       }
437       jpegdec->line[1][k]   = base[1]; 
438       jpegdec->line[2][k]   = base[2];
439       if (r_v == 2 || k&1) {
440          base[1] += width2; base[2] += width2;
441       }
442     }
443     /*g_print ("%d\n", jpegdec->cinfo.output_scanline);*/
444     jpeg_read_raw_data(&jpegdec->cinfo, jpegdec->line, r_v*DCTSIZE);
445   }
446
447   GST_DEBUG ("gst_jpegdec_chain: decompressing finished");
448   jpeg_finish_decompress(&jpegdec->cinfo);
449
450   GST_DEBUG ("gst_jpegdec_chain: sending buffer");
451   gst_pad_push(jpegdec->srcpad, GST_DATA (outbuf));
452
453   gst_buffer_unref(buf);
454 }
455