11/**
2- * @file encode_raw .c
2+ * @file encode_file .c
33 *
44 * Example showing GPUJPEG encode either raw RGB or raw grayscale image.
5+ *
6+ * Changelog:
7+ * - 2023-06-28 - initial implementation
8+ * - 2024-03-26 - updated to new API (ch_count omitted)
9+ * - 2026-02-18 - simplified (get the image props from img if possible), support for PNG etc.; rename to encode_file
510 */
11+ #include <libgpujpeg/gpujpeg_common.h>
612#include <libgpujpeg/gpujpeg_encoder.h>
713#include <stdbool.h>
814#include <stdio.h>
1521
1622static void usage (const char * progname ) {
1723 printf ("Usage:\n" );
18- printf ("\t%s <width> <height> file.rgb|file.r\n" , progname );
19- }
20-
21- static enum gpujpeg_image_file_format get_filetype (int argc , char * argv []) {
22- if (argc != 4 || strrchr (argv [3 ], '.' ) == NULL ) {
23- return GPUJPEG_IMAGE_FILE_UNKNOWN ;
24- }
25- const char * ext = strrchr (argv [3 ], '.' ) + 1 ;
26- return strcasecmp (ext , "rgb" ) == 0 ? GPUJPEG_IMAGE_FILE_RGB
27- : strcasecmp (ext , "r" ) == 0 ? GPUJPEG_IMAGE_FILE_GRAY
28- : GPUJPEG_IMAGE_FILE_UNKNOWN ;
24+ printf ("\t%s <image_name> [<width> <height>]\n" , progname );
25+ printf ("\nwidth and height must be specified if not deducible from file itself (RAW files)\n" );
2926}
3027
3128// to simplify deletion of allocated items on all paths
@@ -35,30 +32,35 @@ struct encode_data {
3532 uint8_t * input_image ;
3633};
3734
38- static int encode (int width , int height , int ch_count , const char * input_filename , struct encode_data * d )
35+ /// @retval 0 success; 1 failure; 2 show help
36+ static int encode (int argc , char * argv [], struct encode_data * d )
3937{
38+ const char * ifname = argv [1 ];
39+ // enum gpujpeg_image_file_format ftype = gpujpeg_image_get_file_format(argv[1]);
40+
4041 // set default encode parametrs, after calling, parameters can be tuned (eg. quality)
4142 struct gpujpeg_parameters param ;
4243 gpujpeg_set_default_parameters (& param );
4344
4445 // here we set image parameters
4546 struct gpujpeg_image_parameters param_image ;
4647 gpujpeg_image_set_default_parameters (& param_image );
47- param_image .width = width ;
48- param_image .height = height ;
49- param_image .color_space =
50- ch_count == 1 ? GPUJPEG_YCBCR_JPEG : GPUJPEG_RGB ;
51- param_image .pixel_format =
52- ch_count == 1 ? GPUJPEG_U8 : GPUJPEG_444_U8_P012 ;
53-
48+ gpujpeg_image_get_properties (ifname , & param_image , true);
49+ if (param_image .width == 0 && param_image .height == 0 ) {
50+ if (argc != 4 ) {
51+ return 2 ;
52+ }
53+ param_image .width = atoi (argv [2 ]);
54+ param_image .height = atoi (argv [3 ]);
55+ }
5456 // create encoder
5557 if ((d -> encoder = gpujpeg_encoder_create (0 )) == NULL ) {
5658 return 1 ;
5759 }
5860
5961 // load image and set it as the encoder input buffer
6062 size_t input_image_size = 0 ;
61- if (gpujpeg_image_load_from_file (input_filename , & d -> input_image , & input_image_size ) != 0 ) {
63+ if (gpujpeg_image_load_from_file (ifname , & d -> input_image , & input_image_size ) != 0 ) {
6264 return 1 ;
6365 }
6466 struct gpujpeg_encoder_input encoder_input ;
@@ -72,8 +74,8 @@ static int encode(int width, int height, int ch_count, const char *input_filenam
7274 }
7375
7476 // write the encoded image
75- d -> out_filename = malloc (strlen (input_filename ) + 1 );
76- strcpy (d -> out_filename , input_filename );
77+ d -> out_filename = malloc (strlen (ifname ) + 1 );
78+ strcpy (d -> out_filename , ifname );
7779 strcpy (strrchr (d -> out_filename , '.' ) + 1 , "jpg" );
7880 if (gpujpeg_image_save_to_file (d -> out_filename , image_compressed , image_compressed_size , & param_image ) != 0 ) {
7981 return 1 ;
@@ -82,34 +84,30 @@ static int encode(int width, int height, int ch_count, const char *input_filenam
8284 return 0 ;
8385}
8486
87+ static void cleanup (const struct encode_data * d ) {
88+ free (d -> out_filename );
89+ gpujpeg_image_destroy (d -> input_image );
90+ if (d -> encoder != NULL ) {
91+ gpujpeg_encoder_destroy (d -> encoder );
92+ }
93+ }
94+
8595int main (int argc , char * argv []) {
86- enum gpujpeg_image_file_format ftype = get_filetype (argc , argv );
87- int ch_count = 0 ;
88- switch (ftype ) {
89- case GPUJPEG_IMAGE_FILE_RGB :
90- ch_count = 3 ;
91- break ;
92- case GPUJPEG_IMAGE_FILE_GRAY :
93- ch_count = 1 ;
94- break ;
95- default :
96+ if (argc != 2 && argc != 4 ) {
9697 usage (argv [0 ]);
97- return 1 ;
98+ return 2 ;
9899 }
99-
100100 struct encode_data d = { 0 };
101- int rc = encode (atoi (argv [1 ]), atoi (argv [2 ]), ch_count , argv [3 ], & d );
102- if (rc == 0 ) {
101+ int rc = encode (argc , argv , & d );
102+ if (rc == 2 ) {
103+ usage (argv [0 ]);
104+ } else if (rc == 0 ) {
103105 printf ("Written: %s\n" , d .out_filename );
106+ puts ("Success\n" );
107+ } else {
108+ puts ("FAILURE\n" );
104109 }
105-
106- free (d .out_filename );
107- gpujpeg_image_destroy (d .input_image );
108- if (d .encoder != NULL ) {
109- gpujpeg_encoder_destroy (d .encoder );
110- }
111-
112- puts (rc == 0 ? "Success\n" : "FAILURE\n" );
110+ cleanup (& d );
113111
114112 return rc ;
115113}
0 commit comments