1 /*****************************************************************************
2 * jpeg.c: jpeg decoder module making use of libjpeg.
3 *****************************************************************************
4 * Copyright (C) 2013-2014,2016 VLC authors and VideoLAN
6 * Authors: Maxim Bublis <b@codemonkey.ru>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
27 #include <vlc_common.h>
28 #include <vlc_plugin.h>
29 #include <vlc_codec.h>
30 #include <vlc_charset.h>
35 /* JPEG_SYS_COMMON_MEMBERS:
36 * members common to encoder and decoder descriptors
38 #define JPEG_SYS_COMMON_MEMBERS \
40 /* libjpeg error handler manager */ \
41 struct jpeg_error_mgr err; \
43 /* setjmp buffer for internal libjpeg error handling */ \
44 jmp_buf setjmp_buffer; \
46 vlc_object_t *p_obj; \
50 #define ENC_CFG_PREFIX "sout-jpeg-"
51 #define ENC_QUALITY_TEXT N_("Quality level")
52 #define ENC_QUALITY_LONGTEXT N_("Quality level " \
53 "for encoding (this can enlarge or reduce output image size).")
57 * jpeg common descriptor
61 JPEG_SYS_COMMON_MEMBERS
64 typedef struct jpeg_sys_t jpeg_sys_t
;
67 * jpeg decoder descriptor
71 JPEG_SYS_COMMON_MEMBERS
73 struct jpeg_decompress_struct p_jpeg
;
76 static int OpenDecoder(vlc_object_t
*);
77 static void CloseDecoder(vlc_object_t
*);
79 static int DecodeBlock(decoder_t
*, block_t
*);
82 * jpeg encoder descriptor
86 JPEG_SYS_COMMON_MEMBERS
88 struct jpeg_compress_struct p_jpeg
;
94 static const char * const ppsz_enc_options
[] = {
99 static int OpenEncoder(vlc_object_t
*);
100 static void CloseEncoder(vlc_object_t
*);
102 static block_t
*EncodeBlock(encoder_t
*, picture_t
*);
108 set_category(CAT_INPUT
)
109 set_subcategory(SUBCAT_INPUT_VCODEC
)
110 /* decoder main module */
111 set_description(N_("JPEG image decoder"))
112 set_capability("video decoder", 1000)
113 set_callbacks(OpenDecoder
, CloseDecoder
)
116 /* encoder submodule */
119 set_section(N_("Encoding"), NULL
)
120 set_description(N_("JPEG image encoder"))
121 set_capability("encoder", 1000)
122 set_callbacks(OpenEncoder
, CloseEncoder
)
123 add_integer_with_range(ENC_CFG_PREFIX
"quality", 95, 0, 100,
124 ENC_QUALITY_TEXT
, ENC_QUALITY_LONGTEXT
, true)
129 * Exit error handler for libjpeg
131 static void user_error_exit(j_common_ptr p_jpeg
)
133 jpeg_sys_t
*p_sys
= (jpeg_sys_t
*)p_jpeg
->err
;
134 p_sys
->err
.output_message(p_jpeg
);
135 longjmp(p_sys
->setjmp_buffer
, 1);
139 * Emit message error handler for libjpeg
141 static void user_error_message(j_common_ptr p_jpeg
)
143 char error_msg
[JMSG_LENGTH_MAX
];
145 jpeg_sys_t
*p_sys
= (jpeg_sys_t
*)p_jpeg
->err
;
146 p_sys
->err
.format_message(p_jpeg
, error_msg
);
147 msg_Err(p_sys
->p_obj
, "%s", error_msg
);
151 * Probe the decoder and return score
153 static int OpenDecoder(vlc_object_t
*p_this
)
155 decoder_t
*p_dec
= (decoder_t
*)p_this
;
157 if (p_dec
->fmt_in
.i_codec
!= VLC_CODEC_JPEG
)
162 /* Allocate the memory needed to store the decoder's structure */
163 decoder_sys_t
*p_sys
= malloc(sizeof(decoder_sys_t
));
169 p_dec
->p_sys
= p_sys
;
171 p_sys
->p_obj
= p_this
;
173 p_sys
->p_jpeg
.err
= jpeg_std_error(&p_sys
->err
);
174 p_sys
->err
.error_exit
= user_error_exit
;
175 p_sys
->err
.output_message
= user_error_message
;
178 p_dec
->pf_decode
= DecodeBlock
;
180 p_dec
->fmt_out
.i_codec
= VLC_CODEC_RGB24
;
186 * The following two functions are used to return 16 and 32 bit values from
187 * the EXIF tag structure. That structure is borrowed from TIFF files and may be
188 * in big endian or little endian format. The boolean b_bigEndian parameter
189 * is TRUE if the EXIF data is in big endian format, and FALSE for little endian
190 * Case Little Endian EXIF tag / Little Endian machine
191 * - just memcpy the tag structure into the value to return
192 * Case Little Endian EXIF tag / Big Endian machine
193 * - memcpy the tag structure into value, and bswap it
194 * Case Little Endian EXIF tag / Big Endian machine
195 * - memcpy the tag structure into value, and bswap it
196 * Case Big Endian EXIF tag / Big Endian machine
197 * - just memcpy the tag structure into the value to return
199 * While there are byte manipulation functions in vlc_common.h, none of them
200 * address that format of the data supplied may be either big or little endian.
202 * The claim is made that this is the best way to do it. Can you do better?
205 #define G_LITTLE_ENDIAN 1234
206 #define G_BIG_ENDIAN 4321
208 typedef unsigned int uint
;
209 typedef unsigned short ushort
;
211 LOCAL( unsigned short )
212 de_get16( void * ptr
, uint endian
) {
215 memcpy( &val
, ptr
, sizeof( val
) );
216 if ( endian
== G_BIG_ENDIAN
)
218 #ifndef WORDS_BIGENDIAN
219 val
= bswap16( val
);
224 #ifdef WORDS_BIGENDIAN
225 val
= bswap16( val
);
231 LOCAL( unsigned int )
232 de_get32( void * ptr
, uint endian
) {
235 memcpy( &val
, ptr
, sizeof( val
) );
236 if ( endian
== G_BIG_ENDIAN
)
238 #ifndef WORDS_BIGENDIAN
239 val
= bswap32( val
);
244 #ifdef WORDS_BIGENDIAN
245 val
= bswap32( val
);
251 static bool getRDFFloat(const char *psz_rdf
, float *out
, const char *psz_var
)
253 char *p_start
= strcasestr(psz_rdf
, psz_var
);
257 size_t varlen
= strlen(psz_var
);
261 if (p_start
[0] == '>')
264 p_end
= strchr(p_start
, '<');
266 else if (p_start
[0] == '=' && p_start
[1] == '"')
269 p_end
= strchr(p_start
, '"');
271 if (unlikely(p_end
== NULL
|| p_end
== p_start
+ 1))
274 *out
= us_strtof(p_start
, NULL
);
278 #define EXIF_JPEG_MARKER 0xE1
279 #define EXIF_XMP_STRING "http://ns.adobe.com/xap/1.0/\000"
281 /* read XMP metadata for projection according to
282 * https://developers.google.com/streetview/spherical-metadata */
283 static void jpeg_GetProjection(j_decompress_ptr cinfo
, video_format_t
*fmt
)
285 jpeg_saved_marker_ptr xmp_marker
= NULL
;
286 jpeg_saved_marker_ptr cmarker
= cinfo
->marker_list
;
290 if (cmarker
->marker
== EXIF_JPEG_MARKER
)
292 if(cmarker
->data_length
>= 32 &&
293 !memcmp(cmarker
->data
, EXIF_XMP_STRING
, 29))
295 xmp_marker
= cmarker
;
299 cmarker
= cmarker
->next
;
302 if (xmp_marker
== NULL
)
304 char *psz_rdf
= malloc(xmp_marker
->data_length
- 29 + 1);
305 if (unlikely(psz_rdf
== NULL
))
307 memcpy(psz_rdf
, xmp_marker
->data
+ 29, xmp_marker
->data_length
- 29);
308 psz_rdf
[xmp_marker
->data_length
- 29] = '\0';
310 /* Try to find the string "GSpherical:Spherical" because the v1
311 spherical video spec says the tag must be there. */
312 if (strcasestr(psz_rdf
, "ProjectionType=\"equirectangular\"") ||
313 strcasestr(psz_rdf
, "ProjectionType>equirectangular"))
314 fmt
->projection_mode
= PROJECTION_MODE_EQUIRECTANGULAR
;
318 if (getRDFFloat(psz_rdf
, &value
, "PoseHeadingDegrees"))
319 fmt
->pose
.yaw
= value
;
321 if (getRDFFloat(psz_rdf
, &value
, "PosePitchDegrees"))
322 fmt
->pose
.pitch
= value
;
324 if (getRDFFloat(psz_rdf
, &value
, "PoseRollDegrees"))
325 fmt
->pose
.roll
= value
;
328 if (getRDFFloat(psz_rdf
, &value
, "InitialViewHeadingDegrees"))
329 fmt
->pose
.yaw
= value
;
331 if (getRDFFloat(psz_rdf
, &value
, "InitialViewPitchDegrees"))
332 fmt
->pose
.pitch
= value
;
334 if (getRDFFloat(psz_rdf
, &value
, "InitialViewRollDegrees"))
335 fmt
->pose
.roll
= value
;
337 if (getRDFFloat(psz_rdf
, &value
, "InitialHorizontalFOVDegrees"))
338 fmt
->pose
.fov
= value
;
344 * Look through the meta data in the libjpeg decompress structure to determine
345 * if an EXIF Orientation tag is present. If so return its value (1-8),
348 * This function is based on the function get_orientation in io-jpeg.c, part of
349 * the GdkPixbuf library, licensed under LGPLv2+.
350 * Copyright (C) 1999 Michael Zucchi, The Free Software Foundation
353 jpeg_GetOrientation( j_decompress_ptr cinfo
)
356 uint i
; /* index into working buffer */
357 ushort tag_type
; /* endianed tag type extracted from tiff header */
358 uint ret
; /* Return value */
359 uint offset
; /* de-endianed offset in various situations */
360 uint tags
; /* number of tags in current ifd */
361 uint type
; /* de-endianed type of tag */
362 uint count
; /* de-endianed count of elements in a tag */
363 uint tiff
= 0; /* offset to active tiff header */
364 uint endian
= 0; /* detected endian of data */
366 jpeg_saved_marker_ptr exif_marker
; /* Location of the Exif APP1 marker */
367 jpeg_saved_marker_ptr cmarker
; /* Location to check for Exif APP1 marker */
369 const char leth
[] = { 0x49, 0x49, 0x2a, 0x00 }; /* Little endian TIFF header */
370 const char beth
[] = { 0x4d, 0x4d, 0x00, 0x2a }; /* Big endian TIFF header */
372 #define EXIF_IDENT_STRING "Exif\000\000"
373 #define EXIF_ORIENT_TAGID 0x112
375 /* check for Exif marker (also called the APP1 marker) */
377 cmarker
= cinfo
->marker_list
;
381 if ( cmarker
->data_length
>= 32 &&
382 cmarker
->marker
== EXIF_JPEG_MARKER
)
384 /* The Exif APP1 marker should contain a unique
385 identification string ("Exif\0\0"). Check for it. */
386 if ( !memcmp( cmarker
->data
, EXIF_IDENT_STRING
, 6 ) )
388 exif_marker
= cmarker
;
391 cmarker
= cmarker
->next
;
394 /* Did we find the Exif APP1 marker? */
395 if ( exif_marker
== NULL
)
398 /* Check for TIFF header and catch endianess */
401 /* Just skip data until TIFF header - it should be within 16 bytes from marker start.
402 Normal structure relative to APP1 marker -
403 0x0000: APP1 marker entry = 2 bytes
404 0x0002: APP1 length entry = 2 bytes
405 0x0004: Exif Identifier entry = 6 bytes
406 0x000A: Start of TIFF header (Byte order entry) - 4 bytes
407 - This is what we look for, to determine endianess.
408 0x000E: 0th IFD offset pointer - 4 bytes
410 exif_marker->data points to the first data after the APP1 marker
411 and length entries, which is the exif identification string.
412 The TIFF header should thus normally be found at i=6, below,
413 and the pointer to IFD0 will be at 6+4 = 10.
418 /* Little endian TIFF header */
419 if ( memcmp( &exif_marker
->data
[i
], leth
, 4 ) == 0 )
421 endian
= G_LITTLE_ENDIAN
;
423 /* Big endian TIFF header */
425 if ( memcmp( &exif_marker
->data
[i
], beth
, 4 ) == 0 )
427 endian
= G_BIG_ENDIAN
;
429 /* Keep looking through buffer */
435 /* We have found either big or little endian TIFF header */
440 /* So did we find a TIFF header or did we just hit end of buffer? */
444 /* Read out the offset pointer to IFD0 */
445 offset
= de_get32( &exif_marker
->data
[i
] + 4, endian
);
448 /* Check that we still are within the buffer and can read the tag count */
450 if ( i
> exif_marker
->data_length
- 2 )
453 /* Find out how many tags we have in IFD0. As per the TIFF spec, the first
454 two bytes of the IFD contain a count of the number of tags. */
455 tags
= de_get16( &exif_marker
->data
[i
], endian
);
458 /* Check that we still have enough data for all tags to check. The tags
459 are listed in consecutive 12-byte blocks. The tag ID, type, size, and
460 a pointer to the actual value, are packed into these 12 byte entries. */
461 if ( tags
* 12U > exif_marker
->data_length
- i
)
464 /* Check through IFD0 for tags of interest */
467 tag_type
= de_get16( &exif_marker
->data
[i
], endian
);
468 /* Is this the orientation tag? */
469 if ( tag_type
== EXIF_ORIENT_TAGID
)
471 type
= de_get16( &exif_marker
->data
[i
+ 2], endian
);
472 count
= de_get32( &exif_marker
->data
[i
+ 4], endian
);
474 /* Check that type and count fields are OK. The orientation field
475 will consist of a single (count=1) 2-byte integer (type=3). */
476 if ( type
!= 3 || count
!= 1 )
479 /* Return the orientation value. Within the 12-byte block, the
480 pointer to the actual data is at offset 8. */
481 ret
= de_get16( &exif_marker
->data
[i
+ 8], endian
);
482 return ( ret
<= 8 ) ? ret
: 0;
484 /* move the pointer to the next 12-byte tag field. */
488 return 0; /* No EXIF Orientation tag found */
492 * This function must be fed with a complete compressed frame.
494 static int DecodeBlock(decoder_t
*p_dec
, block_t
*p_block
)
496 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
497 picture_t
*p_pic
= 0;
499 JSAMPARRAY p_row_pointers
= NULL
;
501 if (!p_block
) /* No Drain */
502 return VLCDEC_SUCCESS
;
504 if (p_block
->i_flags
& BLOCK_FLAG_CORRUPTED
)
506 block_Release(p_block
);
507 return VLCDEC_SUCCESS
;
510 /* libjpeg longjmp's there in case of error */
511 if (setjmp(p_sys
->setjmp_buffer
))
516 jpeg_create_decompress(&p_sys
->p_jpeg
);
517 jpeg_mem_src(&p_sys
->p_jpeg
, p_block
->p_buffer
, p_block
->i_buffer
);
518 jpeg_save_markers( &p_sys
->p_jpeg
, EXIF_JPEG_MARKER
, 0xffff );
519 jpeg_read_header(&p_sys
->p_jpeg
, TRUE
);
521 p_sys
->p_jpeg
.out_color_space
= JCS_RGB
;
523 jpeg_start_decompress(&p_sys
->p_jpeg
);
525 /* Set output properties */
526 p_dec
->fmt_out
.video
.i_visible_width
= p_dec
->fmt_out
.video
.i_width
= p_sys
->p_jpeg
.output_width
;
527 p_dec
->fmt_out
.video
.i_visible_height
= p_dec
->fmt_out
.video
.i_height
= p_sys
->p_jpeg
.output_height
;
528 p_dec
->fmt_out
.video
.i_sar_num
= 1;
529 p_dec
->fmt_out
.video
.i_sar_den
= 1;
531 int i_otag
; /* Orientation tag has valid range of 1-8. 1 is normal orientation, 0 = unspecified = normal */
532 i_otag
= jpeg_GetOrientation( &p_sys
->p_jpeg
);
535 msg_Dbg( p_dec
, "Jpeg orientation is %d", i_otag
);
536 p_dec
->fmt_out
.video
.orientation
= ORIENT_FROM_EXIF( i_otag
);
538 jpeg_GetProjection(&p_sys
->p_jpeg
, &p_dec
->fmt_out
.video
);
540 /* Get a new picture */
541 if (decoder_UpdateVideoFormat(p_dec
))
545 p_pic
= decoder_NewPicture(p_dec
);
552 p_row_pointers
= vlc_alloc(p_sys
->p_jpeg
.output_height
, sizeof(JSAMPROW
));
557 for (unsigned i
= 0; i
< p_sys
->p_jpeg
.output_height
; i
++) {
558 p_row_pointers
[i
] = p_pic
->p
->p_pixels
+ p_pic
->p
->i_pitch
* i
;
561 while (p_sys
->p_jpeg
.output_scanline
< p_sys
->p_jpeg
.output_height
)
563 jpeg_read_scanlines(&p_sys
->p_jpeg
,
564 p_row_pointers
+ p_sys
->p_jpeg
.output_scanline
,
565 p_sys
->p_jpeg
.output_height
- p_sys
->p_jpeg
.output_scanline
);
568 jpeg_finish_decompress(&p_sys
->p_jpeg
);
569 jpeg_destroy_decompress(&p_sys
->p_jpeg
);
570 free(p_row_pointers
);
572 p_pic
->date
= p_block
->i_pts
> VLC_TS_INVALID
? p_block
->i_pts
: p_block
->i_dts
;
574 block_Release(p_block
);
575 decoder_QueueVideo( p_dec
, p_pic
);
576 return VLCDEC_SUCCESS
;
580 jpeg_destroy_decompress(&p_sys
->p_jpeg
);
581 free(p_row_pointers
);
583 block_Release(p_block
);
584 return VLCDEC_SUCCESS
;
588 * jpeg decoder destruction
590 static void CloseDecoder(vlc_object_t
*p_this
)
592 decoder_t
*p_dec
= (decoder_t
*)p_this
;
593 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
599 * Probe the encoder and return score
601 static int OpenEncoder(vlc_object_t
*p_this
)
603 encoder_t
*p_enc
= (encoder_t
*)p_this
;
605 config_ChainParse(p_enc
, ENC_CFG_PREFIX
, ppsz_enc_options
, p_enc
->p_cfg
);
607 if (p_enc
->fmt_out
.i_codec
!= VLC_CODEC_JPEG
)
612 /* Allocate the memory needed to store encoder's structure */
613 encoder_sys_t
*p_sys
= malloc(sizeof(encoder_sys_t
));
619 p_enc
->p_sys
= p_sys
;
621 p_sys
->p_obj
= p_this
;
623 p_sys
->p_jpeg
.err
= jpeg_std_error(&p_sys
->err
);
624 p_sys
->err
.error_exit
= user_error_exit
;
625 p_sys
->err
.output_message
= user_error_message
;
627 p_sys
->i_quality
= var_GetInteger(p_enc
, ENC_CFG_PREFIX
"quality");
628 p_sys
->i_blocksize
= 3 * p_enc
->fmt_in
.video
.i_visible_width
* p_enc
->fmt_in
.video
.i_visible_height
;
630 p_enc
->fmt_in
.i_codec
= VLC_CODEC_J420
;
631 p_enc
->pf_encode_video
= EncodeBlock
;
639 static block_t
*EncodeBlock(encoder_t
*p_enc
, picture_t
*p_pic
)
641 encoder_sys_t
*p_sys
= p_enc
->p_sys
;
643 if (unlikely(!p_pic
))
647 block_t
*p_block
= block_Alloc(p_sys
->i_blocksize
);
653 JSAMPIMAGE p_row_pointers
= NULL
;
654 unsigned long size
= p_block
->i_buffer
;
656 /* libjpeg longjmp's there in case of error */
657 if (setjmp(p_sys
->setjmp_buffer
))
662 jpeg_create_compress(&p_sys
->p_jpeg
);
663 jpeg_mem_dest(&p_sys
->p_jpeg
, &p_block
->p_buffer
, &size
);
665 p_sys
->p_jpeg
.image_width
= p_enc
->fmt_in
.video
.i_visible_width
;
666 p_sys
->p_jpeg
.image_height
= p_enc
->fmt_in
.video
.i_visible_height
;
667 p_sys
->p_jpeg
.input_components
= 3;
668 p_sys
->p_jpeg
.in_color_space
= JCS_YCbCr
;
670 jpeg_set_defaults(&p_sys
->p_jpeg
);
671 jpeg_set_colorspace(&p_sys
->p_jpeg
, JCS_YCbCr
);
673 p_sys
->p_jpeg
.raw_data_in
= TRUE
;
674 #if JPEG_LIB_VERSION >= 70
675 p_sys
->p_jpeg
.do_fancy_downsampling
= FALSE
;
678 jpeg_set_quality(&p_sys
->p_jpeg
, p_sys
->i_quality
, TRUE
);
680 jpeg_start_compress(&p_sys
->p_jpeg
, TRUE
);
683 p_row_pointers
= vlc_alloc(p_pic
->i_planes
, sizeof(JSAMPARRAY
));
684 if (p_row_pointers
== NULL
)
689 for (int i
= 0; i
< p_pic
->i_planes
; i
++)
691 p_row_pointers
[i
] = vlc_alloc(p_sys
->p_jpeg
.comp_info
[i
].v_samp_factor
, sizeof(JSAMPROW
) * DCTSIZE
);
694 while (p_sys
->p_jpeg
.next_scanline
< p_sys
->p_jpeg
.image_height
)
696 for (int i
= 0; i
< p_pic
->i_planes
; i
++)
698 int i_offset
= p_sys
->p_jpeg
.next_scanline
* p_sys
->p_jpeg
.comp_info
[i
].v_samp_factor
/ p_sys
->p_jpeg
.max_v_samp_factor
;
700 for (int j
= 0; j
< p_sys
->p_jpeg
.comp_info
[i
].v_samp_factor
* DCTSIZE
; j
++)
702 p_row_pointers
[i
][j
] = p_pic
->p
[i
].p_pixels
+ p_pic
->p
[i
].i_pitch
* (i_offset
+ j
);
705 jpeg_write_raw_data(&p_sys
->p_jpeg
, p_row_pointers
, p_sys
->p_jpeg
.max_v_samp_factor
* DCTSIZE
);
708 jpeg_finish_compress(&p_sys
->p_jpeg
);
709 jpeg_destroy_compress(&p_sys
->p_jpeg
);
711 for (int i
= 0; i
< p_pic
->i_planes
; i
++)
713 free(p_row_pointers
[i
]);
715 free(p_row_pointers
);
717 p_block
->i_buffer
= size
;
718 p_block
->i_dts
= p_block
->i_pts
= p_pic
->date
;
723 jpeg_destroy_compress(&p_sys
->p_jpeg
);
725 if (p_row_pointers
!= NULL
)
727 for (int i
= 0; i
< p_pic
->i_planes
; i
++)
729 free(p_row_pointers
[i
]);
732 free(p_row_pointers
);
734 block_Release(p_block
);
740 * jpeg encoder destruction
742 static void CloseEncoder(vlc_object_t
*p_this
)
744 encoder_t
*p_enc
= (encoder_t
*)p_this
;
745 encoder_sys_t
*p_sys
= p_enc
->p_sys
;