{
hb_title_t * title = job->title;
int i;
+ int min_width;
+ int min_height;
+ int modulus;
/* don't do anything unless the title has complete size info */
if ( title->height == 0 || title->width == 0 || title->aspect == 0 )
return;
}
- /* Sanity checks:
- Widths and heights must be multiples of 16 and greater than or
- equal to 16
- Crop values must be multiples of 2, greater than or equal to 0
- and less than half of the dimension */
- job->width = MULTIPLE_16( job->width );
- job->height = MULTIPLE_16( job->height );
- job->width = MAX( 16, job->width );
- job->height = MAX( 16, job->height );
+ // min_width and min_height should be multiples of modulus
+ min_width = 32;
+ min_height = 32;
+ modulus = job->modulus ? job->modulus : 16;
+
for( i = 0; i < 4; i++ )
{
- job->crop[i] = EVEN( job->crop[i] );
- job->crop[i] = MAX( 0, job->crop[i] );
+ // Sanity check crop values are zero or positive multiples of 2
if( i < 2 )
{
- /* Top, bottom */
- job->crop[i] = MIN( job->crop[i], ( title->height / 2 ) - 2 );
+ // Top, bottom
+ job->crop[i] = MIN( EVEN( job->crop[i] ), EVEN( ( title->height / 2 ) - ( min_height / 2 ) ) );
+ job->crop[i] = MAX( 0, job->crop[i] );
}
else
{
- /* Left, right */
- job->crop[i] = MIN( job->crop[i], ( title->width / 2 ) - 2 );
+ // Left, right
+ job->crop[i] = MIN( EVEN( job->crop[i] ), EVEN( ( title->width / 2 ) - ( min_width / 2 ) ) );
+ job->crop[i] = MAX( 0, job->crop[i] );
}
}
double par = (double)title->width / ( (double)title->height * title->aspect );
double cropped_sar = (double)( title->height - job->crop[0] - job->crop[1] ) /
- (double)(title->width - job->crop[2] - job->crop[3] );
+ (double)( title->width - job->crop[2] - job->crop[3] );
double ar = par * cropped_sar;
+
+ // Dimensions must be greater than minimum and multiple of modulus
if( keep == HB_KEEP_WIDTH )
{
- job->height = MULTIPLE_16( (uint64_t)( (double)job->width * ar ) );
- job->height = MAX( 16, job->height );
+ job->width = MULTIPLE_MOD( job->width, modulus );
+ job->width = MAX( min_width, job->width );
+ job->height = MULTIPLE_MOD( (uint64_t)( (double)job->width * ar ), modulus );
+ job->height = MAX( min_height, job->height );
}
else
{
- job->width = MULTIPLE_16( (uint64_t)( (double)job->height / ar ) );
- job->width = MAX( 16, job->width );
+ job->height = MULTIPLE_MOD( job->height, modulus );
+ job->height = MAX( min_height, job->height );
+ job->width = MULTIPLE_MOD( (uint64_t)( (double)job->height / ar ), modulus );
+ job->width = MAX( min_width, job->width );
}
}
**********************************************************************
*
*********************************************************************/
-hb_title_t * hb_title_init( char * dvd, int index )
+hb_title_t * hb_title_init( char * path, int index )
{
hb_title_t * t;
t->list_audio = hb_list_init();
t->list_chapter = hb_list_init();
t->list_subtitle = hb_list_init();
- strcat( t->dvd, dvd );
+ strcat( t->path, path );
// default to decoding mpeg2
t->video_id = 0xE0;
t->video_codec = WORK_DECMPEG2;
}
return retval;
}
+
+char * hb_strdup_printf( char * fmt, ... )
+{
+ int len;
+ va_list ap;
+ int size = 256;
+ char * str;
+ char * tmp;
+
+ str = malloc( size );
+ if ( str == NULL )
+ return NULL;
+
+ while (1)
+ {
+ /* Try to print in the allocated space. */
+ va_start( ap, fmt );
+ len = vsnprintf( str, size, fmt, ap );
+ va_end( ap );
+
+ /* If that worked, return the string. */
+ if ( len > -1 && len < size )
+ {
+ return str;
+ }
+
+ /* Else try again with more space. */
+ if ( len > -1 ) /* glibc 2.1 */
+ size = len + 1; /* precisely what is needed */
+ else /* glibc 2.0 */
+ size *= 2; /* twice the old size */
+ tmp = realloc( str, size );
+ if ( tmp == NULL )
+ {
+ free( str );
+ return NULL;
+ }
+ else
+ str = tmp;
+ }
+}
+
+/**********************************************************************
+ * hb_yuv2rgb
+ **********************************************************************
+ * Converts a YCbCr pixel to an RGB pixel.
+ *
+ * This conversion is lossy (due to rounding and clamping).
+ *
+ * Algorithm:
+ * http://en.wikipedia.org/w/index.php?title=YCbCr&oldid=361987695#Technical_details
+ *********************************************************************/
+int hb_yuv2rgb(int yuv)
+{
+ double y, Cr, Cb;
+ int r, g, b;
+
+ y = (yuv >> 16) & 0xff;
+ Cb = (yuv >> 8) & 0xff;
+ Cr = (yuv ) & 0xff;
+
+ r = 1.164 * (y - 16) + 2.018 * (Cb - 128);
+ g = 1.164 * (y - 16) - 0.813 * (Cr - 128) - 0.391 * (Cb - 128);
+ b = 1.164 * (y - 16) + 1.596 * (Cr - 128);
+
+ r = (r < 0) ? 0 : r;
+ g = (g < 0) ? 0 : g;
+ b = (b < 0) ? 0 : b;
+
+ r = (r > 255) ? 255 : r;
+ g = (g > 255) ? 255 : g;
+ b = (b > 255) ? 255 : b;
+
+ return (r << 16) | (g << 8) | b;
+}
+
+/**********************************************************************
+ * hb_rgb2yuv
+ **********************************************************************
+ * Converts an RGB pixel to a YCbCr pixel.
+ *
+ * This conversion is lossy (due to rounding and clamping).
+ *
+ * Algorithm:
+ * http://en.wikipedia.org/w/index.php?title=YCbCr&oldid=361987695#Technical_details
+ *********************************************************************/
+int hb_rgb2yuv(int rgb)
+{
+ double r, g, b;
+ int y, Cr, Cb;
+
+ r = (rgb >> 16) & 0xff;
+ g = (rgb >> 8) & 0xff;
+ b = (rgb ) & 0xff;
+
+ y = 16. + ( 0.257 * r) + (0.504 * g) + (0.098 * b);
+ Cb = 128. + (-0.148 * r) - (0.291 * g) + (0.439 * b);
+ Cr = 128. + ( 0.439 * r) - (0.368 * g) - (0.071 * b);
+
+ y = (y < 0) ? 0 : y;
+ Cb = (Cb < 0) ? 0 : Cb;
+ Cr = (Cr < 0) ? 0 : Cr;
+
+ y = (y > 255) ? 255 : y;
+ Cb = (Cb > 255) ? 255 : Cb;
+ Cr = (Cr > 255) ? 255 : Cr;
+
+ return (y << 16) | (Cb << 8) | Cr;
+}
+