@@ -1490,6 +1490,71 @@ static _Bool sampling_factor_compare(int count, struct gpujpeg_component_samplin
14901490 return 1 ;
14911491}
14921492
1493+ static int
1494+ gcd (int a , int b )
1495+ {
1496+ assert (b != 0 );
1497+ int c = a % b ;
1498+ while (c != 0 ) {
1499+ a = b ;
1500+ b = c ;
1501+ c = a % b ;
1502+ }
1503+
1504+ return (b );
1505+ }
1506+
1507+ static enum gpujpeg_pixel_format
1508+ get_native_pixel_format (struct gpujpeg_parameters * param )
1509+ {
1510+ if ( param -> comp_count == 1 ) {
1511+ return GPUJPEG_U8 ;
1512+ }
1513+ if ( param -> comp_count == 3 ) {
1514+ // reduce [2, 2; 1, 2; 1, 2] (FFmpeg) to [2, 1; 1, 1; 1, 1]
1515+ int horizontal_gcd = param -> sampling_factor [0 ].horizontal ;
1516+ int vertical_gcd = param -> sampling_factor [0 ].vertical ;
1517+ for (int i = 1 ; i < 3 ; ++ i ) {
1518+ horizontal_gcd = gcd (horizontal_gcd , param -> sampling_factor [i ].horizontal );
1519+ vertical_gcd = gcd (vertical_gcd , param -> sampling_factor [i ].vertical );
1520+ }
1521+ for (int i = 0 ; i < 3 ; ++ i ) {
1522+ param -> sampling_factor [i ].horizontal /= horizontal_gcd ;
1523+ param -> sampling_factor [i ].vertical /= vertical_gcd ;
1524+ }
1525+
1526+ if ( param -> sampling_factor [1 ].horizontal == 1 && param -> sampling_factor [1 ].vertical == 1 &&
1527+ param -> sampling_factor [2 ].horizontal == 1 && param -> sampling_factor [2 ].vertical == 1 ) {
1528+ int sum = param -> interleaved << 16 | param -> sampling_factor [0 ].horizontal << 8 |
1529+ param -> sampling_factor [0 ].vertical ; // NOLINT
1530+ switch (sum ) {
1531+ case 1 <<16 | 1 <<8 | 1 : return GPUJPEG_444_U8_P012 ; break ; // NOLINT
1532+ case 0 <<16 | 1 <<8 | 1 : return GPUJPEG_444_U8_P0P1P2 ; break ; // NOLINT
1533+ case 1 <<16 | 2 <<8 | 1 : return GPUJPEG_422_U8_P1020 ; break ; // NOLINT
1534+ case 0 <<16 | 2 <<8 | 1 : return GPUJPEG_422_U8_P0P1P2 ; break ; // NOLINT
1535+ case 1 <<16 | 2 <<8 | 2 : // we have only one pixfmt for 420, so use for both NOLINT
1536+ case 0 <<16 | 2 <<8 | 2 : return GPUJPEG_420_U8_P0P1P2 ; break ; // NOLINT
1537+ default : break ;
1538+ }
1539+ }
1540+ }
1541+
1542+ if ( param -> comp_count == 4 ) {
1543+ _Bool subsampling_is4444 = 1 ;
1544+ for (int i = 1 ; i < 4 ; ++ i ) {
1545+ if (param -> sampling_factor [i ].horizontal != param -> sampling_factor [0 ].horizontal
1546+ || param -> sampling_factor [i ].vertical != param -> sampling_factor [0 ].vertical ) {
1547+ subsampling_is4444 = 0 ;
1548+ break ;
1549+ }
1550+ }
1551+ if (subsampling_is4444 ) {
1552+ return GPUJPEG_4444_U8_P0123 ;
1553+ }
1554+ }
1555+ return GPUJPEG_PIXFMT_NONE ;
1556+ }
1557+
14931558static enum gpujpeg_pixel_format
14941559adjust_pixel_format (struct gpujpeg_parameters * param , struct gpujpeg_image_parameters * param_image ) {
14951560 assert (param_image -> pixel_format == GPUJPEG_PIXFMT_AUTODETECT || param_image -> pixel_format == GPUJPEG_PIXFMT_STD );
@@ -1661,20 +1726,6 @@ gpujpeg_reader_read_image(struct gpujpeg_decoder* decoder, uint8_t* image, size_
16611726 return 0 ;
16621727}
16631728
1664- static int
1665- gcd (int a , int b )
1666- {
1667- assert (b != 0 );
1668- int c = a % b ;
1669- while (c != 0 ) {
1670- a = b ;
1671- b = c ;
1672- c = a % b ;
1673- }
1674-
1675- return (b );
1676- }
1677-
16781729/* Documented at declaration */
16791730int
16801731gpujpeg_reader_get_image_info (uint8_t * image , size_t image_size , struct gpujpeg_image_info * info , int verbose , unsigned flags )
@@ -1801,56 +1852,11 @@ gpujpeg_reader_get_image_info(uint8_t *image, size_t image_size, struct gpujpeg_
18011852
18021853 info -> param = reader .param ;
18031854 info -> param_image = reader .param_image ;
1804- info -> param_image .pixel_format = GPUJPEG_PIXFMT_NONE ;
18051855 info -> segment_count = segments ;
18061856 info -> header_type = reader .header_type ;
18071857 info -> comment = reader .comment ;
18081858
1809- if ( info -> param .comp_count == 1 ) {
1810- info -> param_image .pixel_format = GPUJPEG_U8 ;
1811- }
1812- if ( info -> param .comp_count == 3 ) {
1813- // reduce [2, 2; 1, 2; 1, 2] (FFmpeg) to [2, 1; 1, 1; 1, 1]
1814- int horizontal_gcd = info -> param .sampling_factor [0 ].horizontal ;
1815- int vertical_gcd = info -> param .sampling_factor [0 ].vertical ;
1816- for (int i = 1 ; i < 3 ; ++ i ) {
1817- horizontal_gcd = gcd (horizontal_gcd , info -> param .sampling_factor [i ].horizontal );
1818- vertical_gcd = gcd (vertical_gcd , info -> param .sampling_factor [i ].vertical );
1819- }
1820- for (int i = 0 ; i < 3 ; ++ i ) {
1821- info -> param .sampling_factor [i ].horizontal /= horizontal_gcd ;
1822- info -> param .sampling_factor [i ].vertical /= vertical_gcd ;
1823- }
1824-
1825- if (info -> param .sampling_factor [1 ].horizontal == 1 && info -> param .sampling_factor [1 ].vertical == 1
1826- && info -> param .sampling_factor [2 ].horizontal == 1 && info -> param .sampling_factor [2 ].vertical == 1 ) {
1827- int sum = info -> param .interleaved << 16 | info -> param .sampling_factor [0 ].horizontal << 8 |
1828- info -> param .sampling_factor [0 ].vertical ; // NOLINT
1829- switch (sum ) {
1830- case 1 <<16 | 1 <<8 | 1 : info -> param_image .pixel_format = GPUJPEG_444_U8_P012 ; break ; // NOLINT
1831- case 0 <<16 | 1 <<8 | 1 : info -> param_image .pixel_format = GPUJPEG_444_U8_P0P1P2 ; break ; // NOLINT
1832- case 1 <<16 | 2 <<8 | 1 : info -> param_image .pixel_format = GPUJPEG_422_U8_P1020 ; break ; // NOLINT
1833- case 0 <<16 | 2 <<8 | 1 : info -> param_image .pixel_format = GPUJPEG_422_U8_P0P1P2 ; break ; // NOLINT
1834- case 1 <<16 | 2 <<8 | 2 : // we have only one pixfmt for 420, so use for both NOLINT
1835- case 0 <<16 | 2 <<8 | 2 : info -> param_image .pixel_format = GPUJPEG_420_U8_P0P1P2 ; break ; // NOLINT
1836- default : break ;
1837- }
1838- }
1839- }
1840-
1841- if ( info -> param .comp_count == 4 ) {
1842- _Bool subsampling_is4444 = 1 ;
1843- for (int i = 1 ; i < 4 ; ++ i ) {
1844- if (info -> param .sampling_factor [i ].horizontal != info -> param .sampling_factor [0 ].horizontal
1845- || info -> param .sampling_factor [i ].vertical != info -> param .sampling_factor [0 ].vertical ) {
1846- subsampling_is4444 = 0 ;
1847- break ;
1848- }
1849- }
1850- if (subsampling_is4444 ) {
1851- info -> param_image .pixel_format = GPUJPEG_4444_U8_P0123 ;
1852- }
1853- }
1859+ info -> param_image .pixel_format = get_native_pixel_format (& reader .param );
18541860
18551861 return 0 ;
18561862}
0 commit comments