@@ -1660,6 +1660,20 @@ gpujpeg_reader_read_image(struct gpujpeg_decoder* decoder, uint8_t* image, size_
16601660 return 0 ;
16611661}
16621662
1663+ static int
1664+ gcd (int a , int b )
1665+ {
1666+ assert (b != 0 );
1667+ int c = a % b ;
1668+ while (c != 0 ) {
1669+ a = b ;
1670+ b = c ;
1671+ c = a % b ;
1672+ }
1673+
1674+ return (b );
1675+ }
1676+
16631677/* Documented at declaration */
16641678int
16651679gpujpeg_reader_get_image_info (uint8_t * image , size_t image_size , struct gpujpeg_image_info * info , int verbose , unsigned flags )
@@ -1672,7 +1686,6 @@ gpujpeg_reader_get_image_info(uint8_t *image, size_t image_size, struct gpujpeg_
16721686
16731687 struct gpujpeg_reader reader = {
16741688 .param .verbose = verbose ,
1675- .param_image .pixel_format = GPUJPEG_PIXFMT_AUTODETECT ,
16761689 .image_end = image + image_size ,
16771690 .metadata = & info -> metadata ,
16781691 };
@@ -1787,10 +1800,57 @@ gpujpeg_reader_get_image_info(uint8_t *image, size_t image_size, struct gpujpeg_
17871800
17881801 info -> param = reader .param ;
17891802 info -> param_image = reader .param_image ;
1803+ info -> param_image .pixel_format = GPUJPEG_PIXFMT_NONE ;
17901804 info -> segment_count = segments ;
17911805 info -> header_type = reader .header_type ;
17921806 info -> comment = reader .comment ;
17931807
1808+ if ( info -> param .comp_count == 1 ) {
1809+ info -> param_image .pixel_format = GPUJPEG_U8 ;
1810+ }
1811+ if ( info -> param .comp_count == 3 ) {
1812+ // reduce [2, 2; 1, 2; 1, 2] (FFmpeg) to [2, 1; 1, 1; 1, 1]
1813+ int horizontal_gcd = info -> param .sampling_factor [0 ].horizontal ;
1814+ int vertical_gcd = info -> param .sampling_factor [0 ].vertical ;
1815+ for (int i = 1 ; i < 3 ; ++ i ) {
1816+ horizontal_gcd = gcd (horizontal_gcd , info -> param .sampling_factor [i ].horizontal );
1817+ vertical_gcd = gcd (vertical_gcd , info -> param .sampling_factor [i ].vertical );
1818+ }
1819+ for (int i = 0 ; i < 3 ; ++ i ) {
1820+ info -> param .sampling_factor [i ].horizontal /= horizontal_gcd ;
1821+ info -> param .sampling_factor [i ].vertical /= vertical_gcd ;
1822+ }
1823+
1824+ if (info -> param .sampling_factor [1 ].horizontal == 1 && info -> param .sampling_factor [1 ].vertical == 1
1825+ && info -> param .sampling_factor [2 ].horizontal == 1 && info -> param .sampling_factor [2 ].vertical == 1 ) {
1826+ int sum = info -> param .interleaved << 16 | info -> param .sampling_factor [0 ].horizontal << 8 |
1827+ info -> param .sampling_factor [0 ].vertical ; // NOLINT
1828+ switch (sum ) {
1829+ case 1 <<16 | 1 <<8 | 1 : info -> param_image .pixel_format = GPUJPEG_444_U8_P012 ; break ; // NOLINT
1830+ case 0 <<16 | 1 <<8 | 1 : info -> param_image .pixel_format = GPUJPEG_444_U8_P0P1P2 ; break ; // NOLINT
1831+ case 1 <<16 | 2 <<8 | 1 : info -> param_image .pixel_format = GPUJPEG_422_U8_P1020 ; break ; // NOLINT
1832+ case 0 <<16 | 2 <<8 | 1 : info -> param_image .pixel_format = GPUJPEG_422_U8_P0P1P2 ; break ; // NOLINT
1833+ case 1 <<16 | 2 <<8 | 2 : // we have only one pixfmt for 420, so use for both NOLINT
1834+ case 0 <<16 | 2 <<8 | 2 : info -> param_image .pixel_format = GPUJPEG_420_U8_P0P1P2 ; break ; // NOLINT
1835+ default : break ;
1836+ }
1837+ }
1838+ }
1839+
1840+ if ( info -> param .comp_count == 4 ) {
1841+ _Bool subsampling_is4444 = 1 ;
1842+ for (int i = 1 ; i < 4 ; ++ i ) {
1843+ if (info -> param .sampling_factor [i ].horizontal != info -> param .sampling_factor [0 ].horizontal
1844+ || info -> param .sampling_factor [i ].vertical != info -> param .sampling_factor [0 ].vertical ) {
1845+ subsampling_is4444 = 0 ;
1846+ break ;
1847+ }
1848+ }
1849+ if (subsampling_is4444 ) {
1850+ info -> param_image .pixel_format = GPUJPEG_4444_U8_P0123 ;
1851+ }
1852+ }
1853+
17941854 return 0 ;
17951855}
17961856
0 commit comments