summaryrefslogtreecommitdiffstats
path: root/libhb/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'libhb/common.c')
-rw-r--r--libhb/common.c742
1 files changed, 704 insertions, 38 deletions
diff --git a/libhb/common.c b/libhb/common.c
index 821f17e76..80b526c2a 100644
--- a/libhb/common.c
+++ b/libhb/common.c
@@ -306,13 +306,13 @@ const char* hb_mixdown_get_short_name_from_mixdown(int amixdown)
return "";
}
-void hb_autopassthru_apply_settings( hb_job_t * job, hb_title_t * title )
+void hb_autopassthru_apply_settings( hb_job_t * job )
{
int i, j, already_printed;
hb_audio_t * audio;
- for( i = 0, already_printed = 0; i < hb_list_count( title->list_audio ); )
+ for( i = 0, already_printed = 0; i < hb_list_count( job->list_audio ); )
{
- audio = hb_list_item( title->list_audio, i );
+ audio = hb_list_item( job->list_audio, i );
if( audio->config.out.codec == HB_ACODEC_AUTO_PASS )
{
if( !already_printed )
@@ -327,8 +327,8 @@ void hb_autopassthru_apply_settings( hb_job_t * job, hb_title_t * title )
{
hb_log( "Auto Passthru: passthru not possible and no valid fallback specified, dropping track %d",
audio->config.out.track );
- hb_list_rem( title->list_audio, audio );
- free( audio );
+ hb_list_rem( job->list_audio, audio );
+ hb_audio_close( &audio );
continue;
}
audio->config.out.samplerate = audio->config.in.samplerate;
@@ -1157,7 +1157,7 @@ hb_list_t * hb_list_init()
**********************************************************************
* Returns the number of items currently in the list
*********************************************************************/
-int hb_list_count( hb_list_t * l )
+int hb_list_count( const hb_list_t * l )
{
return l->items_count;
}
@@ -1252,7 +1252,7 @@ void hb_list_rem( hb_list_t * l, void * p )
* Returns item at position i, or NULL if there are not that many
* items in the list
*********************************************************************/
-void * hb_list_item( hb_list_t * l, int i )
+void * hb_list_item( const hb_list_t * l, int i )
{
if( i < 0 || i >= l->items_count )
{
@@ -1575,6 +1575,19 @@ void hb_register_error_handler( hb_error_handler_t * handler )
error_handler = handler;
}
+static void hb_update_str( char **dst, const char *src )
+{
+ if ( dst )
+ {
+ free( *dst );
+ *dst = NULL;
+ if ( src )
+ {
+ *dst = strdup( src );
+ }
+ }
+}
+
/**********************************************************************
* hb_title_init
**********************************************************************
@@ -1592,6 +1605,7 @@ hb_title_t * hb_title_init( char * path, int index )
t->list_chapter = hb_list_init();
t->list_subtitle = hb_list_init();
t->list_attachment = hb_list_init();
+ t->metadata = hb_metadata_init();
strcat( t->path, path );
// default to decoding mpeg2
t->video_id = 0xE0;
@@ -1616,65 +1630,252 @@ void hb_title_close( hb_title_t ** _t )
hb_subtitle_t * subtitle;
hb_attachment_t * attachment;
- while( ( audio = hb_list_item( t->list_audio, 0 ) ) )
- {
- hb_list_rem( t->list_audio, audio );
- free( audio );
- }
- hb_list_close( &t->list_audio );
-
while( ( chapter = hb_list_item( t->list_chapter, 0 ) ) )
{
hb_list_rem( t->list_chapter, chapter );
- free( chapter );
+ hb_chapter_close( &chapter );
}
hb_list_close( &t->list_chapter );
+ while( ( audio = hb_list_item( t->list_audio, 0 ) ) )
+ {
+ hb_list_rem( t->list_audio, audio );
+ hb_audio_close( &audio );
+ }
+ hb_list_close( &t->list_audio );
+
while( ( subtitle = hb_list_item( t->list_subtitle, 0 ) ) )
{
hb_list_rem( t->list_subtitle, subtitle );
- if ( subtitle->extradata )
- {
- free( subtitle->extradata );
- subtitle->extradata = NULL;
- }
- free( subtitle );
+ hb_subtitle_close( &subtitle );
}
hb_list_close( &t->list_subtitle );
while( ( attachment = hb_list_item( t->list_attachment, 0 ) ) )
{
hb_list_rem( t->list_attachment, attachment );
- if ( attachment->name )
+ hb_attachment_close( &attachment );
+ }
+ hb_list_close( &t->list_attachment );
+
+ hb_metadata_close( &t->metadata );
+
+ free( t->video_codec_name );
+ free(t->container_name);
+
+#if defined(HB_TITLE_JOBS)
+ hb_job_close( &t->job );
+#endif
+
+ free( t );
+ *_t = NULL;
+}
+
+/*
+ * Create a pristine job structure from a title
+ * title_index is 1 based
+ */
+hb_job_t * hb_job_init_by_index( hb_handle_t * h, int title_index )
+{
+ hb_title_set_t *title_set = hb_get_title_set( h );
+ hb_title_t * title = hb_list_item( title_set->list_title,
+ title_index - 1 );
+ return hb_job_init( title );
+}
+
+hb_job_t * hb_job_init( hb_title_t * title )
+{
+ hb_job_t * job;
+
+ if ( title == NULL )
+ return NULL;
+
+ job = calloc( sizeof( hb_job_t ), 1 );
+
+ job->title = title;
+
+ /* Set defaults settings */
+ job->chapter_start = 1;
+ job->chapter_end = hb_list_count( title->list_chapter );
+ job->list_chapter = hb_chapter_list_copy( title->list_chapter );
+
+ /* Autocrop by default. Gnark gnark */
+ memcpy( job->crop, title->crop, 4 * sizeof( int ) );
+
+ /* Preserve a source's pixel aspect, if it's available. */
+ if( title->pixel_aspect_width && title->pixel_aspect_height )
+ {
+ job->anamorphic.par_width = title->pixel_aspect_width;
+ job->anamorphic.par_height = title->pixel_aspect_height;
+ }
+
+ if( title->aspect != 0 && title->aspect != 1. &&
+ !job->anamorphic.par_width && !job->anamorphic.par_height)
+ {
+ hb_reduce( &job->anamorphic.par_width, &job->anamorphic.par_height,
+ (int)(title->aspect * title->height + 0.5), title->width );
+ }
+
+ job->width = title->width - job->crop[2] - job->crop[3];
+ hb_fix_aspect( job, HB_KEEP_WIDTH );
+ if( job->height > title->height - job->crop[0] - job->crop[1] )
+ {
+ job->height = title->height - job->crop[0] - job->crop[1];
+ hb_fix_aspect( job, HB_KEEP_HEIGHT );
+ }
+
+ job->keep_ratio = 1;
+
+ job->vcodec = HB_VCODEC_FFMPEG_MPEG4;
+ job->vquality = -1.0;
+ job->vbitrate = 1000;
+ job->pass = 0;
+ job->vrate = title->rate;
+ job->vrate_base = title->rate_base;
+
+ job->mux = HB_MUX_MP4;
+
+ job->list_audio = hb_list_init();
+ job->list_subtitle = hb_list_init();
+ job->list_filter = hb_list_init();
+
+ job->list_attachment = hb_attachment_list_copy( title->list_attachment );
+ job->metadata = hb_metadata_copy( title->metadata );
+
+ return job;
+}
+
+/**
+ * Clean up the job structure so that is is ready for setting up a new job.
+ * Should be called by front-ends after hb_add().
+ */
+/**********************************************************************
+ * hb_job_reset
+ **********************************************************************
+ *
+ *********************************************************************/
+void hb_job_reset( hb_job_t * job )
+{
+ if ( job )
+ {
+ hb_audio_t *audio;
+ hb_subtitle_t *subtitle;
+ hb_filter_object_t *filter;
+ hb_title_t * title = job->title;
+
+ // clean up audio list
+ while( ( audio = hb_list_item( job->list_audio, 0 ) ) )
+ {
+ hb_list_rem( job->list_audio, audio );
+ hb_audio_close( &audio );
+ }
+
+ // clean up subtitle list
+ while( ( subtitle = hb_list_item( job->list_subtitle, 0 ) ) )
{
- free( attachment->name );
- attachment->name = NULL;
+ hb_list_rem( job->list_subtitle, subtitle );
+ hb_subtitle_close( &subtitle );
}
- if ( attachment->data )
+
+ // clean up filter list
+ while( ( filter = hb_list_item( job->list_filter, 0 ) ) )
{
- free( attachment->data );
- attachment->data = NULL;
+ hb_list_rem( job->list_filter, filter );
+ hb_filter_close( &filter );
}
- free( attachment );
+
+ hb_metadata_close( &job->metadata );
+ job->metadata = hb_metadata_copy( title->metadata );
}
- hb_list_close( &t->list_attachment );
+}
- if( t->metadata )
+/**********************************************************************
+ * hb_job_close
+ **********************************************************************
+ *
+ *********************************************************************/
+void hb_job_close( hb_job_t ** _j )
+{
+ if (_j)
{
- if( t->metadata->coverart )
+ hb_job_t * job = *_j;
+
+ if (job)
{
- free( t->metadata->coverart );
+ hb_chapter_t *chapter;
+ hb_audio_t *audio;
+ hb_subtitle_t *subtitle;
+ hb_filter_object_t *filter;
+ hb_attachment_t *attachment;
+
+ free(job->file);
+ free(job->advanced_opts);
+
+ // clean up chapter list
+ while( ( chapter = hb_list_item( job->list_chapter, 0 ) ) )
+ {
+ hb_list_rem( job->list_chapter, chapter );
+ hb_chapter_close( &chapter );
+ }
+ hb_list_close( &job->list_chapter );
+
+ // clean up audio list
+ while( ( audio = hb_list_item( job->list_audio, 0 ) ) )
+ {
+ hb_list_rem( job->list_audio, audio );
+ hb_audio_close( &audio );
+ }
+ hb_list_close( &job->list_audio );
+
+ // clean up subtitle list
+ while( ( subtitle = hb_list_item( job->list_subtitle, 0 ) ) )
+ {
+ hb_list_rem( job->list_subtitle, subtitle );
+ hb_subtitle_close( &subtitle );
+ }
+ hb_list_close( &job->list_subtitle );
+
+ // clean up filter list
+ while( ( filter = hb_list_item( job->list_filter, 0 ) ) )
+ {
+ hb_list_rem( job->list_filter, filter );
+ hb_filter_close( &filter );
+ }
+ hb_list_close( &job->list_filter );
+
+ // clean up attachment list
+ while( ( attachment = hb_list_item( job->list_attachment, 0 ) ) )
+ {
+ hb_list_rem( job->list_attachment, attachment );
+ hb_attachment_close( &attachment );
+ }
+ hb_list_close( &job->list_attachment );
+
+ // clean up metadata
+ if ( job->metadata )
+ {
+ hb_metadata_close( &job->metadata );
+ }
+ free( job );
}
- free( t->metadata );
+ _j = NULL;
}
+}
- if ( t->video_codec_name )
+void hb_job_set_file( hb_job_t *job, const char *file )
+{
+ if ( job )
{
- free( t->video_codec_name );
+ hb_update_str( &job->file, file );
}
+}
- free( t );
- *_t = NULL;
+void hb_job_set_advanced_opts( hb_job_t *job, const char *advanced_opts )
+{
+ if ( job )
+ {
+ hb_update_str( &job->advanced_opts, advanced_opts );
+ }
}
hb_filter_object_t * hb_filter_copy( hb_filter_object_t * filter )
@@ -1689,6 +1890,30 @@ hb_filter_object_t * hb_filter_copy( hb_filter_object_t * filter )
return filter_copy;
}
+/**********************************************************************
+ * hb_filter_list_copy
+ **********************************************************************
+ *
+ *********************************************************************/
+hb_list_t *hb_filter_list_copy(const hb_list_t *src)
+{
+ hb_list_t *list = hb_list_init();
+ hb_filter_object_t *filter = NULL;
+ int i;
+
+ if( src )
+ {
+ for( i = 0; i < hb_list_count(src); i++ )
+ {
+ if( ( filter = hb_list_item( src, i ) ) )
+ {
+ hb_list_add( list, hb_filter_copy(filter) );
+ }
+ }
+ }
+ return list;
+}
+
/**
* Gets a filter object with the given type
* @param filter_id The type of filter to get.
@@ -1759,6 +1984,93 @@ void hb_filter_close( hb_filter_object_t ** _f )
}
/**********************************************************************
+ * hb_chapter_copy
+ **********************************************************************
+ *
+ *********************************************************************/
+hb_chapter_t *hb_chapter_copy(const hb_chapter_t *src)
+{
+ hb_chapter_t *chap = NULL;
+
+ if ( src )
+ {
+ chap = calloc( 1, sizeof(*chap) );
+ memcpy( chap, src, sizeof(*chap) );
+ if ( src->title )
+ {
+ chap->title = strdup( src->title );
+ }
+ }
+ return chap;
+}
+
+/**********************************************************************
+ * hb_chapter_list_copy
+ **********************************************************************
+ *
+ *********************************************************************/
+hb_list_t *hb_chapter_list_copy(const hb_list_t *src)
+{
+ hb_list_t *list = hb_list_init();
+ hb_chapter_t *chapter = NULL;
+ int i;
+
+ if( src )
+ {
+ for( i = 0; i < hb_list_count(src); i++ )
+ {
+ if( ( chapter = hb_list_item( src, i ) ) )
+ {
+ hb_list_add( list, hb_chapter_copy(chapter) );
+ }
+ }
+ }
+ return list;
+}
+
+/**********************************************************************
+ * hb_chapter_close
+ **********************************************************************
+ *
+ *********************************************************************/
+void hb_chapter_close(hb_chapter_t **chap)
+{
+ if ( chap && *chap )
+ {
+ free((*chap)->title);
+ free(*chap);
+ *chap = NULL;
+ }
+}
+
+/**********************************************************************
+ * hb_chapter_set_title
+ **********************************************************************
+ *
+ *********************************************************************/
+void hb_chapter_set_title( hb_chapter_t *chapter, const char *title )
+{
+ if ( chapter )
+ {
+ hb_update_str( &chapter->title, title );
+ }
+}
+
+/**********************************************************************
+ * hb_chapter_set_title_by_index
+ **********************************************************************
+ * Applies information from the given job to the official job instance.
+ * @param job Handle to hb_job_t.
+ * @param chapter The chapter to apply the name to (1-based).
+ * @param titel to apply.
+ *********************************************************************/
+void hb_chapter_set_title_by_index( hb_job_t * job, int chapter_index, const char * title )
+{
+ hb_chapter_t * chapter = hb_list_item( job->list_chapter, chapter_index - 1 );
+ hb_chapter_set_title( chapter, title );
+}
+
+/**********************************************************************
* hb_audio_copy
**********************************************************************
*
@@ -1771,11 +2083,54 @@ hb_audio_t *hb_audio_copy(const hb_audio_t *src)
{
audio = calloc(1, sizeof(*audio));
memcpy(audio, src, sizeof(*audio));
+ if ( src->config.out.name )
+ {
+ audio->config.out.name = strdup(src->config.out.name);
+ }
}
return audio;
}
/**********************************************************************
+ * hb_audio_list_copy
+ **********************************************************************
+ *
+ *********************************************************************/
+hb_list_t *hb_audio_list_copy(const hb_list_t *src)
+{
+ hb_list_t *list = hb_list_init();
+ hb_audio_t *audio = NULL;
+ int i;
+
+ if( src )
+ {
+ for( i = 0; i < hb_list_count(src); i++ )
+ {
+ if( ( audio = hb_list_item( src, i ) ) )
+ {
+ hb_list_add( list, hb_audio_copy(audio) );
+ }
+ }
+ }
+ return list;
+}
+
+/**********************************************************************
+ * hb_audio_close
+ **********************************************************************
+ *
+ *********************************************************************/
+void hb_audio_close( hb_audio_t **audio )
+{
+ if ( audio && *audio )
+ {
+ free((*audio)->config.out.name);
+ free(*audio);
+ *audio = NULL;
+ }
+}
+
+/**********************************************************************
* hb_audio_new
**********************************************************************
*
@@ -1878,7 +2233,7 @@ int hb_audio_add(const hb_job_t * job, const hb_audio_config_t * audiocfg)
}
if (audiocfg->out.name && *audiocfg->out.name)
{
- audio->config.out.name = audiocfg->out.name;
+ audio->config.out.name = strdup(audiocfg->out.name);
}
hb_list_add(job->list_audio, audio);
@@ -1918,6 +2273,45 @@ hb_subtitle_t *hb_subtitle_copy(const hb_subtitle_t *src)
}
/**********************************************************************
+ * hb_subtitle_list_copy
+ **********************************************************************
+ *
+ *********************************************************************/
+hb_list_t *hb_subtitle_list_copy(const hb_list_t *src)
+{
+ hb_list_t *list = hb_list_init();
+ hb_subtitle_t *subtitle = NULL;
+ int i;
+
+ if( src )
+ {
+ for( i = 0; i < hb_list_count(src); i++ )
+ {
+ if( ( subtitle = hb_list_item( src, i ) ) )
+ {
+ hb_list_add( list, hb_subtitle_copy(subtitle) );
+ }
+ }
+ }
+ return list;
+}
+
+/**********************************************************************
+ * hb_subtitle_close
+ **********************************************************************
+ *
+ *********************************************************************/
+void hb_subtitle_close( hb_subtitle_t **sub )
+{
+ if ( sub && *sub )
+ {
+ free ((*sub)->extradata);
+ free(*sub);
+ *sub = NULL;
+ }
+}
+
+/**********************************************************************
* hb_subtitle_add
**********************************************************************
*
@@ -2026,6 +2420,238 @@ int hb_subtitle_can_pass( int source, int mux )
}
}
+/**********************************************************************
+ * hb_metadata_init
+ **********************************************************************
+ *
+ *********************************************************************/
+hb_metadata_t *hb_metadata_init()
+{
+ hb_metadata_t *metadata = calloc( 1, sizeof(*metadata) );
+ return metadata;
+}
+
+/**********************************************************************
+ * hb_metadata_copy
+ **********************************************************************
+ *
+ *********************************************************************/
+hb_metadata_t *hb_metadata_copy( const hb_metadata_t *src )
+{
+ hb_metadata_t *metadata = NULL;
+
+ if ( src )
+ {
+ metadata = calloc( 1, sizeof(*metadata) );
+ if ( src->name )
+ {
+ metadata->name = strdup(src->name);
+ }
+ if ( src->artist )
+ {
+ metadata->artist = strdup(src->artist);
+ }
+ if ( src->album_artist )
+ {
+ metadata->album_artist = strdup(src->album_artist);
+ }
+ if ( src->composer )
+ {
+ metadata->composer = strdup(src->composer);
+ }
+ if ( src->release_date )
+ {
+ metadata->release_date = strdup(src->release_date);
+ }
+ if ( src->comment )
+ {
+ metadata->comment = strdup(src->comment);
+ }
+ if ( src->album )
+ {
+ metadata->album = strdup(src->album);
+ }
+ if ( src->genre )
+ {
+ metadata->genre = strdup(src->genre);
+ }
+ if ( src->description )
+ {
+ metadata->description = strdup(src->description);
+ }
+ if ( src->long_description )
+ {
+ metadata->long_description = strdup(src->long_description);
+ }
+ if ( src->list_coverart )
+ {
+ int ii;
+ for ( ii = 0; ii < hb_list_count( src->list_coverart ); ii++ )
+ {
+ hb_coverart_t *art = hb_list_item( src->list_coverart, ii );
+ hb_metadata_add_coverart(
+ metadata, art->data, art->size, art->type );
+ }
+ }
+ }
+ return metadata;
+}
+
+/**********************************************************************
+ * hb_metadata_close
+ **********************************************************************
+ *
+ *********************************************************************/
+void hb_metadata_close( hb_metadata_t **_m )
+{
+ if ( _m && *_m )
+ {
+ hb_metadata_t *m = *_m;
+ hb_coverart_t *art;
+
+ free( m->name );
+ free( m->artist );
+ free( m->composer );
+ free( m->release_date );
+ free( m->comment );
+ free( m->album );
+ free( m->album_artist );
+ free( m->genre );
+ free( m->description );
+ free( m->long_description );
+
+ if ( m->list_coverart )
+ {
+ while( ( art = hb_list_item( m->list_coverart, 0 ) ) )
+ {
+ hb_list_rem( m->list_coverart, art );
+ free( art->data );
+ free( art );
+ }
+ hb_list_close( &m->list_coverart );
+ }
+
+ free( m );
+ *_m = NULL;
+ }
+}
+
+/**********************************************************************
+ * hb_metadata_set_*
+ **********************************************************************
+ *
+ *********************************************************************/
+void hb_metadata_set_name( hb_metadata_t *metadata, const char *name )
+{
+ if ( metadata )
+ {
+ hb_update_str( &metadata->name, name );
+ }
+}
+
+void hb_metadata_set_artist( hb_metadata_t *metadata, const char *artist )
+{
+ if ( metadata )
+ {
+ hb_update_str( &metadata->artist, artist );
+ }
+}
+
+void hb_metadata_set_composer( hb_metadata_t *metadata, const char *composer )
+{
+ if ( metadata )
+ {
+ hb_update_str( &metadata->composer, composer );
+ }
+}
+
+void hb_metadata_set_release_date( hb_metadata_t *metadata, const char *release_date )
+{
+ if ( metadata )
+ {
+ hb_update_str( &metadata->release_date, release_date );
+ }
+}
+
+void hb_metadata_set_comment( hb_metadata_t *metadata, const char *comment )
+{
+ if ( metadata )
+ {
+ hb_update_str( &metadata->comment, comment );
+ }
+}
+
+void hb_metadata_set_genre( hb_metadata_t *metadata, const char *genre )
+{
+ if ( metadata )
+ {
+ hb_update_str( &metadata->genre, genre );
+ }
+}
+
+void hb_metadata_set_album( hb_metadata_t *metadata, const char *album )
+{
+ if ( metadata )
+ {
+ hb_update_str( &metadata->album, album );
+ }
+}
+
+void hb_metadata_set_album_artist( hb_metadata_t *metadata, const char *album_artist )
+{
+ if ( metadata )
+ {
+ hb_update_str( &metadata->album_artist, album_artist );
+ }
+}
+
+void hb_metadata_set_description( hb_metadata_t *metadata, const char *description )
+{
+ if ( metadata )
+ {
+ hb_update_str( &metadata->description, description );
+ }
+}
+
+void hb_metadata_set_long_description( hb_metadata_t *metadata, const char *long_description )
+{
+ if ( metadata )
+ {
+ hb_update_str( &metadata->long_description, long_description );
+ }
+}
+
+void hb_metadata_add_coverart( hb_metadata_t *metadata, const uint8_t *data, int size, int type )
+{
+ if ( metadata )
+ {
+ if ( metadata->list_coverart == NULL )
+ {
+ metadata->list_coverart = hb_list_init();
+ }
+ hb_coverart_t *art = calloc( 1, sizeof(hb_coverart_t) );
+ art->data = malloc( size );
+ memcpy( art->data, data, size );
+ art->size = size;
+ art->type = type;
+ hb_list_add( metadata->list_coverart, art );
+ }
+}
+
+void hb_metadata_rem_coverart( hb_metadata_t *metadata, int idx )
+{
+ if ( metadata )
+ {
+ hb_coverart_t *art = hb_list_item( metadata->list_coverart, idx );
+ if ( art )
+ {
+ hb_list_rem( metadata->list_coverart, art );
+ free( art->data );
+ free( art );
+ }
+ }
+}
+
char * hb_strdup_printf( const char * fmt, ... )
{
int len;
@@ -2119,6 +2745,46 @@ hb_attachment_t *hb_attachment_copy(const hb_attachment_t *src)
}
/**********************************************************************
+ * hb_attachment_list_copy
+ **********************************************************************
+ *
+ *********************************************************************/
+hb_list_t *hb_attachment_list_copy(const hb_list_t *src)
+{
+ hb_list_t *list = hb_list_init();
+ hb_attachment_t *attachment = NULL;
+ int i;
+
+ if( src )
+ {
+ for( i = 0; i < hb_list_count(src); i++ )
+ {
+ if( ( attachment = hb_list_item( src, i ) ) )
+ {
+ hb_list_add( list, hb_attachment_copy(attachment) );
+ }
+ }
+ }
+ return list;
+}
+
+/**********************************************************************
+ * hb_attachment_close
+ **********************************************************************
+ *
+ *********************************************************************/
+void hb_attachment_close( hb_attachment_t **attachment )
+{
+ if ( attachment && *attachment )
+ {
+ free((*attachment)->data);
+ free((*attachment)->name);
+ free(*attachment);
+ *attachment = NULL;
+ }
+}
+
+/**********************************************************************
* hb_yuv2rgb
**********************************************************************
* Converts a YCrCb pixel to an RGB pixel.