summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Kost <ensonic@users.sf.net>2009-09-28 16:29:45 +0300
committerStefan Kost <ensonic@users.sf.net>2009-09-28 17:25:35 +0300
commit69c24fb991d5556e83e68d7a236e6526ea3dade5 (patch)
treed30df455ab9e7934a6ae5eb45c62feefbc3cb664
parent0fac7b5347d1cd1f727b697d5be4782de1f56152 (diff)
jpeg: handle more libjpeg return values, add some more branch hints
Also remove unused size variable in _chain().
-rw-r--r--ext/jpeg/gstjpegdec.c84
1 files changed, 50 insertions, 34 deletions
diff --git a/ext/jpeg/gstjpegdec.c b/ext/jpeg/gstjpegdec.c
index f9cc68e74..0f12be765 100644
--- a/ext/jpeg/gstjpegdec.c
+++ b/ext/jpeg/gstjpegdec.c
@@ -518,6 +518,8 @@ add_huff_table (j_decompress_ptr dinfo,
518 if (*htblptr == NULL) 518 if (*htblptr == NULL)
519 *htblptr = jpeg_alloc_huff_table ((j_common_ptr) dinfo); 519 *htblptr = jpeg_alloc_huff_table ((j_common_ptr) dinfo);
520 520
521 g_assert (*htblptr);
522
521 /* Copy the number-of-symbols-of-each-code-length counts */ 523 /* Copy the number-of-symbols-of-each-code-length counts */
522 memcpy ((*htblptr)->bits, bits, sizeof ((*htblptr)->bits)); 524 memcpy ((*htblptr)->bits, bits, sizeof ((*htblptr)->bits));
523 525
@@ -687,37 +689,42 @@ gst_jpeg_dec_decode_indirect (GstJpegDec * dec, guchar * base[3],
687 }; 689 };
688 guchar **scanarray[3] = { y_rows, u_rows, v_rows }; 690 guchar **scanarray[3] = { y_rows, u_rows, v_rows };
689 gint i, j, k; 691 gint i, j, k;
692 gint lines;
690 693
691 GST_DEBUG_OBJECT (dec, 694 GST_DEBUG_OBJECT (dec,
692 "unadvantageous width or r_h, taking slow route involving memcpy"); 695 "unadvantageous width or r_h, taking slow route involving memcpy");
693 696
694 for (i = 0; i < height; i += r_v * DCTSIZE) { 697 for (i = 0; i < height; i += r_v * DCTSIZE) {
695 jpeg_read_raw_data (&dec->cinfo, scanarray, r_v * DCTSIZE); 698 lines = jpeg_read_raw_data (&dec->cinfo, scanarray, r_v * DCTSIZE);
696 for (j = 0, k = 0; j < (r_v * DCTSIZE); j += r_v, k++) { 699 if (G_LIKELY (lines)) {
697 memcpy (base[0], y_rows[j], I420_Y_ROWSTRIDE (width)); 700 for (j = 0, k = 0; j < (r_v * DCTSIZE); j += r_v, k++) {
698 if (base[0] < last[0]) 701 memcpy (base[0], y_rows[j], I420_Y_ROWSTRIDE (width));
699 base[0] += I420_Y_ROWSTRIDE (width);
700 if (r_v == 2) {
701 memcpy (base[0], y_rows[j + 1], I420_Y_ROWSTRIDE (width));
702 if (base[0] < last[0]) 702 if (base[0] < last[0])
703 base[0] += I420_Y_ROWSTRIDE (width); 703 base[0] += I420_Y_ROWSTRIDE (width);
704 } 704 if (G_LIKELY (r_h == 2)) {
705 if (G_LIKELY (r_h == 2)) { 705 memcpy (base[0], y_rows[j + 1], I420_Y_ROWSTRIDE (width));
706 memcpy (base[1], u_rows[k], I420_U_ROWSTRIDE (width)); 706 if (base[0] < last[0])
707 memcpy (base[2], v_rows[k], I420_V_ROWSTRIDE (width)); 707 base[0] += I420_Y_ROWSTRIDE (width);
708 } else if (G_UNLIKELY (r_h == 1)) { 708 }
709 hresamplecpy1 (base[1], u_rows[k], I420_U_ROWSTRIDE (width)); 709 if (G_LIKELY (r_h == 2)) {
710 hresamplecpy1 (base[2], v_rows[k], I420_V_ROWSTRIDE (width)); 710 memcpy (base[1], u_rows[k], I420_U_ROWSTRIDE (width));
711 } else { 711 memcpy (base[2], v_rows[k], I420_V_ROWSTRIDE (width));
712 /* FIXME: implement (at least we avoid crashing by doing nothing) */ 712 } else if (G_UNLIKELY (r_h == 1)) {
713 } 713 hresamplecpy1 (base[1], u_rows[k], I420_U_ROWSTRIDE (width));
714 hresamplecpy1 (base[2], v_rows[k], I420_V_ROWSTRIDE (width));
715 } else {
716 /* FIXME: implement (at least we avoid crashing by doing nothing) */
717 }
714 718
715 if (r_v == 2 || (k & 1) != 0) { 719 if (r_v == 2 || (k & 1) != 0) {
716 if (base[1] < last[1] && base[2] < last[2]) { 720 if (base[1] < last[1] && base[2] < last[2]) {
717 base[1] += I420_U_ROWSTRIDE (width); 721 base[1] += I420_U_ROWSTRIDE (width);
718 base[2] += I420_V_ROWSTRIDE (width); 722 base[2] += I420_V_ROWSTRIDE (width);
723 }
719 } 724 }
720 } 725 }
726 } else {
727 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
721 } 728 }
722 } 729 }
723} 730}
@@ -731,6 +738,7 @@ gst_jpeg_dec_decode_direct (GstJpegDec * dec, guchar * base[3],
731 guchar *u[4 * DCTSIZE]; 738 guchar *u[4 * DCTSIZE];
732 guchar *v[4 * DCTSIZE]; 739 guchar *v[4 * DCTSIZE];
733 gint i, j, k; 740 gint i, j, k;
741 gint lines;
734 742
735 line[0] = y; 743 line[0] = y;
736 line[1] = u; 744 line[1] = u;
@@ -757,7 +765,10 @@ gst_jpeg_dec_decode_direct (GstJpegDec * dec, guchar * base[3],
757 } 765 }
758 } 766 }
759 } 767 }
760 jpeg_read_raw_data (&dec->cinfo, line, r_v * DCTSIZE); 768 lines = jpeg_read_raw_data (&dec->cinfo, line, r_v * DCTSIZE);
769 if (G_UNLIKELY (!lines)) {
770 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
771 }
761 } 772 }
762} 773}
763 774
@@ -840,14 +851,13 @@ gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf)
840 GstFlowReturn ret = GST_FLOW_OK; 851 GstFlowReturn ret = GST_FLOW_OK;
841 GstJpegDec *dec; 852 GstJpegDec *dec;
842 GstBuffer *outbuf; 853 GstBuffer *outbuf;
843 gulong size;
844 guchar *data, *outdata; 854 guchar *data, *outdata;
845 guchar *base[3], *last[3]; 855 guchar *base[3], *last[3];
846 guint img_len, outsize; 856 guint img_len, outsize;
847 gint width, height; 857 gint width, height;
848 gint r_h, r_v; 858 gint r_h, r_v;
849 gint i; 859 gint i;
850 guint code; 860 guint code, hdr_ok;
851 GstClockTime timestamp, duration; 861 GstClockTime timestamp, duration;
852 862
853 dec = GST_JPEG_DEC (GST_PAD_PARENT (pad)); 863 dec = GST_JPEG_DEC (GST_PAD_PARENT (pad));
@@ -909,11 +919,10 @@ gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf)
909 goto skip_decoding; 919 goto skip_decoding;
910 920
911 data = (guchar *) GST_BUFFER_DATA (dec->tempbuf); 921 data = (guchar *) GST_BUFFER_DATA (dec->tempbuf);
912 size = img_len;
913 GST_LOG_OBJECT (dec, "image size = %u", img_len); 922 GST_LOG_OBJECT (dec, "image size = %u", img_len);
914 923
915 dec->jsrc.pub.next_input_byte = data; 924 dec->jsrc.pub.next_input_byte = data;
916 dec->jsrc.pub.bytes_in_buffer = size; 925 dec->jsrc.pub.bytes_in_buffer = img_len;
917 926
918 if (setjmp (dec->jerr.setjmp_buffer)) { 927 if (setjmp (dec->jerr.setjmp_buffer)) {
919 code = dec->jerr.pub.msg_code; 928 code = dec->jerr.pub.msg_code;
@@ -929,7 +938,10 @@ gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf)
929 data[2], data[3]); 938 data[2], data[3]);
930 939
931 /* read header */ 940 /* read header */
932 jpeg_read_header (&dec->cinfo, TRUE); 941 hdr_ok = jpeg_read_header (&dec->cinfo, TRUE);
942 if (G_UNLIKELY (hdr_ok != JPEG_HEADER_OK)) {
943 GST_WARNING_OBJECT (dec, "reading the header failed, %d", hdr_ok);
944 }
933 945
934 r_h = dec->cinfo.cur_comp_info[0]->h_samp_factor; 946 r_h = dec->cinfo.cur_comp_info[0]->h_samp_factor;
935 r_v = dec->cinfo.cur_comp_info[0]->v_samp_factor; 947 r_v = dec->cinfo.cur_comp_info[0]->v_samp_factor;
@@ -938,11 +950,13 @@ gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf)
938 GST_LOG_OBJECT (dec, "num_components=%d, comps_in_scan=%d", 950 GST_LOG_OBJECT (dec, "num_components=%d, comps_in_scan=%d",
939 dec->cinfo.num_components, dec->cinfo.comps_in_scan); 951 dec->cinfo.num_components, dec->cinfo.comps_in_scan);
940 952
953#ifndef GST_DISABLE_GST_DEBUG
941 for (i = 0; i < dec->cinfo.comps_in_scan; ++i) { 954 for (i = 0; i < dec->cinfo.comps_in_scan; ++i) {
942 GST_LOG_OBJECT (dec, "[%d] h_samp_factor=%d, v_samp_factor=%d", i, 955 GST_LOG_OBJECT (dec, "[%d] h_samp_factor=%d, v_samp_factor=%d", i,
943 dec->cinfo.cur_comp_info[i]->h_samp_factor, 956 dec->cinfo.cur_comp_info[i]->h_samp_factor,
944 dec->cinfo.cur_comp_info[i]->v_samp_factor); 957 dec->cinfo.cur_comp_info[i]->v_samp_factor);
945 } 958 }
959#endif
946 960
947 /* prepare for raw output */ 961 /* prepare for raw output */
948 dec->cinfo.do_fancy_upsampling = FALSE; 962 dec->cinfo.do_fancy_upsampling = FALSE;
@@ -953,18 +967,20 @@ gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf)
953 967
954 GST_LOG_OBJECT (dec, "starting decompress"); 968 GST_LOG_OBJECT (dec, "starting decompress");
955 guarantee_huff_tables (&dec->cinfo); 969 guarantee_huff_tables (&dec->cinfo);
956 jpeg_start_decompress (&dec->cinfo); 970 if (!jpeg_start_decompress (&dec->cinfo)) {
971 GST_WARNING_OBJECT (dec, "failed to start decompression cycle");
972 }
957 973
958 width = dec->cinfo.output_width; 974 width = dec->cinfo.output_width;
959 height = dec->cinfo.output_height; 975 height = dec->cinfo.output_height;
960 976
961 if (width < MIN_WIDTH || width > MAX_WIDTH || 977 if (G_UNLIKELY (width < MIN_WIDTH || width > MAX_WIDTH ||
962 height < MIN_HEIGHT || height > MAX_HEIGHT) 978 height < MIN_HEIGHT || height > MAX_HEIGHT))
963 goto wrong_size; 979 goto wrong_size;
964 980
965 if (width != dec->caps_width || height != dec->caps_height || 981 if (G_UNLIKELY (width != dec->caps_width || height != dec->caps_height ||
966 dec->framerate_numerator != dec->caps_framerate_numerator || 982 dec->framerate_numerator != dec->caps_framerate_numerator ||
967 dec->framerate_denominator != dec->caps_framerate_denominator) { 983 dec->framerate_denominator != dec->caps_framerate_denominator)) {
968 GstCaps *caps; 984 GstCaps *caps;
969 985
970 /* framerate == 0/1 is a still frame */ 986 /* framerate == 0/1 is a still frame */
@@ -1007,7 +1023,7 @@ gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf)
1007 1023
1008 ret = gst_pad_alloc_buffer_and_set_caps (dec->srcpad, GST_BUFFER_OFFSET_NONE, 1024 ret = gst_pad_alloc_buffer_and_set_caps (dec->srcpad, GST_BUFFER_OFFSET_NONE,
1009 dec->outsize, GST_PAD_CAPS (dec->srcpad), &outbuf); 1025 dec->outsize, GST_PAD_CAPS (dec->srcpad), &outbuf);
1010 if (ret != GST_FLOW_OK) 1026 if (G_UNLIKELY (ret != GST_FLOW_OK))
1011 goto alloc_failed; 1027 goto alloc_failed;
1012 1028
1013 outdata = GST_BUFFER_DATA (outbuf); 1029 outdata = GST_BUFFER_DATA (outbuf);