UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
main.c File Reference
#include "dxt_encoder.h"
#include "dxt_decoder.h"
#include "dxt_display.h"
#include <getopt.h>
#include <string.h>
#include <strings.h>
Include dependency graph for main.c:

Go to the source code of this file.

Macros

#define DEBUG
 
#define RUN_MAX   100
 

Functions

const char * get_filename_extension (const char *filename)
 
int main (int argc, char *argv[])
 
int perform_comparison (const char *input, const char *output, enum dxt_type type, int width, int height, enum dxt_format format)
 
int perform_decode (const char *filename_in, const char *filename_out, enum dxt_type type, int width, int height, int display, int run)
 
int perform_display (const char *filename, enum dxt_type type, int width, int height, enum dxt_format format)
 
int perform_encode (const char *filename_in, const char *filename_out, enum dxt_type type, int width, int height, enum dxt_format format, int display, int run)
 
void print_help ()
 
void printf_duration (const char *name, int run)
 

Variables

static float duration [RUN_MAX]
 

Macro Definition Documentation

◆ DEBUG

◆ RUN_MAX

#define RUN_MAX   100

Definition at line 36 of file main.c.

Referenced by main().

Function Documentation

◆ get_filename_extension()

const char * get_filename_extension ( const char * filename)

Definition at line 168 of file main.c.

169{
170 char * ext = strrchr(filename, '.');
171 if ( ext == NULL )
172 return NULL;
173 ext++;
174 return ext;
175}

Referenced by perform_comparison(), and perform_display().

◆ main()

int main ( int argc,
char * argv[] )

Definition at line 269 of file main.c.

270{
271 struct option longopts[] = {
272 {"help", no_argument, 0, 'h'},
273 {"encode", no_argument, 0, 'e'},
274 {"decode", no_argument, 0, 'd'},
275 {"size", required_argument, 0, 's'},
276 {"input", required_argument, 0, 'i'},
277 {"output", required_argument, 0, 'o'},
278 {"display", no_argument, 0, 1 },
279 {"type", required_argument, 0, 't'},
280 {"format", required_argument, 0, 'f'},
281 {"run", required_argument, 0, 'r'},
282 {"batch", no_argument, 0, 'b'},
283 };
284
285 // Parameters
287 enum dxt_format format = DXT_FORMAT_RGBA; // encoder _internal_ format (!)
288 int width = 512;
289 int height = 512;
290 int encode = 0;
291 int decode = 0;
292 char input[255] = { '\0' };
293 char output[255] = { '\0' };
294 int display = 0;
295 int run = 1;
296 int batch = 0;
297
298 // Parse command line
299 char ch = '\0';
300 int optindex = 0;
301 char* pos = 0;
302 while ( (ch = getopt_long(argc, argv, "heds:i:o:t:f:b", longopts, &optindex)) != -1 ) {
303 switch (ch) {
304 case 'h':
305 print_help();
306 return 0;
307 case 'e':
308 encode = 1;
309 break;
310 case 'd':
311 decode = 1;
312 break;
313 case 's':
314 width = atoi(optarg);
315 pos = strstr(optarg, "x");
316 if ( pos == NULL || width == 0 || (strlen(pos) >= strlen(optarg)) ) {
317 print_help();
318 return -1;
319 }
320 height = atoi(pos + 1);
321 break;
322 case 'i':
323 strncpy(input, optarg, 255);
324 break;
325 case 'o':
326 strncpy(output, optarg, 255);
327 break;
328 case 't':
329 if ( strcasecmp(optarg, "dxt1") == 0 )
331 else if ( strcasecmp(optarg, "dxt5ycocg") == 0 )
333 break;
334 case 'f':
335 if ( strcasecmp(optarg, "rgb") == 0 )
336 format = DXT_FORMAT_RGBA;
337 else if ( strcasecmp(optarg, "yuv") == 0 ) {
338 format = DXT_FORMAT_YUV;
339 fprintf(stderr, "yuv not supported!\n");
340 abort();
341 }
342 break;
343 case 'r':
344 run = atoi(optarg);
345 break;
346 case 1:
347 display = 1;
348 break;
349 case 'b':
350 batch = 1;
351 break;
352 case '?':
353 return -1;
354 default:
355 print_help();
356 return -1;
357 }
358 }
359 argc -= optind;
360 argv += optind;
361
362 if ( run > RUN_MAX ) {
363 printf("Warning: Maximum run times is %d using that number!\n", RUN_MAX);
364 run = RUN_MAX;
365 }
366
367 // Input image must be presented
368 if ( !batch && input[0] == '\0' ) {
369 printf("Please supply input image filename!\n");
370 print_help();
371 return -1;
372 }
373
374 // Output image must be presented for encoding or decoding
375 if ( !batch && output[0] == '\0' && (encode == 1 || decode == 1) ) {
376 printf("Please supply output image filename!\n");
377 print_help();
378 return -1;
379 }
380
381 // Init DXT compressor
382 if ( dxt_init() != 0 )
383 return -1;
384
385 // Perform encode
386 if ( encode == 1 ) {
387 if(batch) {
388 DXT_IMAGE_TYPE* image = NULL;
390 if ( encoder == NULL ) {
391 fprintf(stderr, "Create DXT encoder failed!\n");
392 return -1;
393 }
394
395 unsigned char* image_compressed = NULL;
396 int image_compressed_size = 0;
397 if ( dxt_encoder_buffer_allocate(encoder, &image_compressed, &image_compressed_size) != 0 ) {
398 fprintf(stderr, "DXT encoder allocation failed!\n");
399 return -1;
400 }
401
402 while (argc > 0) {
403 char *in_filename = argv[0];
404 char out_filename[512];
405
406 printf("encoding %s\n", in_filename);
407
408 snprintf(out_filename, 512, "%s.dxt", in_filename);
409 if ( dxt_image_load_from_file(in_filename, width, height, &image) != 0 ) {
410 fprintf(stderr, "Failed to load image [%s]!\n", in_filename);
411 return -1;
412 }
413
414 if ( dxt_encoder_compress(encoder, image, image_compressed) != 0 ) {
415 fprintf(stderr, "DXT encoder compressing failed!\n");
416 return -1;
417 }
418
419 if ( dxt_image_compressed_save_to_file(out_filename, image_compressed, image_compressed_size) != 0 ) {
420 fprintf(stderr, "Failed to save compressed image [%s]!\n", out_filename);
421 return -1;
422 }
423 dxt_image_destroy(image);
424
425 argc--;
426 argv++;
427 }
428
429 dxt_encoder_buffer_free(image_compressed);
431 } else {
432 if ( perform_encode(input, output, type, width, height, format, display, run) != 0 ) {
433 fprintf(stderr, "Failed to encode image [%s]!\n", input);
434 return -1;
435 }
436 }
437 }
438
439 // Setup input and output for decoding (when encoding was performed)
440 if ( encode == 1 && decode == 1 ) {
441 char new_output[255];
442 snprintf(new_output, 255, "decoded_%s", input);
443 strncpy(input, output, 255);
444 strncpy(output, new_output, 255);
445 }
446
447 // Perform decode
448 if ( decode == 1 ) {
449 if ( perform_decode(input, output, type, width, height, display, run) != 0 ) {
450 fprintf(stderr, "Failed to decode image [%s]!\n", input);
451 return -1;
452 }
453 }
454
455 // Only display image
456 if ( display == 1 && encode == 0 && decode == 0 ) {
457 if ( output[0] != '\0' ) {
458 if ( perform_comparison(input, output, type, width, height, format) != 0 ) {
459 fprintf(stderr, "Failed to perform comparison for images [%s, %s]!\n", input, output);
460 return -1;
461 }
462 } else {
463 if ( perform_display(input, type, width, height, format) != 0 ) {
464 fprintf(stderr, "Failed to display image [%s]!\n", input);
465 return -1;
466 }
467 }
468 }
469
470 return 0;
471}
int dxt_image_destroy(DXT_IMAGE_TYPE *image)
Definition dxt_common.c:197
int dxt_image_load_from_file(const char *filename, int width, int height, DXT_IMAGE_TYPE **image)
Definition dxt_common.c:67
int dxt_image_compressed_save_to_file(const char *filename, unsigned char *image, int image_size)
Definition dxt_common.c:173
int dxt_init()
Definition dxt_common.c:32
dxt_format
Definition dxt_common.h:78
@ DXT_FORMAT_RGBA
Definition dxt_common.h:80
@ DXT_FORMAT_YUV
Definition dxt_common.h:81
dxt_type
Definition dxt_common.h:88
@ DXT_TYPE_DXT1
Definition dxt_common.h:89
@ DXT_TYPE_DXT5_YCOCG
Definition dxt_common.h:91
#define DXT_IMAGE_TYPE
Definition dxt_common.h:71
int dxt_encoder_buffer_allocate(struct dxt_encoder *encoder, unsigned char **image_compressed, int *image_compressed_size)
int dxt_encoder_compress(struct dxt_encoder *encoder, DXT_IMAGE_TYPE *image, unsigned char *image_compressed)
struct dxt_encoder * dxt_encoder_create(enum dxt_type type, int width, int height, enum dxt_format format, int legacy)
int dxt_encoder_destroy(struct dxt_encoder *encoder)
int dxt_encoder_buffer_free(unsigned char *image_compressed)
int perform_encode(const char *filename_in, const char *filename_out, enum dxt_type type, int width, int height, enum dxt_format format, int display, int run)
Definition main.c:61
#define RUN_MAX
Definition main.c:36
int perform_decode(const char *filename_in, const char *filename_out, enum dxt_type type, int width, int height, int display, int run)
Definition main.c:114
void print_help()
Definition main.c:251
int perform_comparison(const char *input, const char *output, enum dxt_type type, int width, int height, enum dxt_format format)
Definition main.c:207
int perform_display(const char *filename, enum dxt_type type, int width, int height, enum dxt_format format)
Definition main.c:178
Option::OptType type
Definition settings.cpp:194
This struct represents initialized video display state.
enum dxt_format format
Definition dxt_encoder.c:88

References dxt_encoder_buffer_allocate(), dxt_encoder_buffer_free(), dxt_encoder_compress(), dxt_encoder_create(), dxt_encoder_destroy(), DXT_FORMAT_RGBA, DXT_FORMAT_YUV, dxt_image_compressed_save_to_file(), dxt_image_destroy(), dxt_image_load_from_file(), DXT_IMAGE_TYPE, dxt_init(), DXT_TYPE_DXT1, DXT_TYPE_DXT5_YCOCG, dxt_encoder::format, dxt_encoder::height, perform_comparison(), perform_decode(), perform_display(), perform_encode(), print_help(), RUN_MAX, type, and dxt_encoder::width.

Here is the call graph for this function:

◆ perform_comparison()

int perform_comparison ( const char * input,
const char * output,
enum dxt_type type,
int width,
int height,
enum dxt_format format )

Definition at line 207 of file main.c.

208{
209 // Get file extensions
210 const char * input_ext = get_filename_extension(input);
211 const char * output_ext = get_filename_extension(output);
212
213 // Set proper filenames
214 const char * filename_image = NULL;
215 const char * filename_image_compressed = NULL;
216 if ( strncasecmp(input_ext, "rgb", 3) == 0 )
217 filename_image = input;
218 else
219 filename_image_compressed = input;
220 if ( strncasecmp(output_ext, "rgb", 3) == 0 )
221 filename_image = output;
222 else
223 filename_image_compressed = output;
224
225 if ( filename_image == NULL || filename_image_compressed == NULL ) {
226 fprintf(stderr, "Display comparison can't be performed, one file must be RGB image and one compressed image!\n");
227 return -1;
228 }
229
230 // Load images
231 DXT_IMAGE_TYPE* image = NULL;
232 unsigned char* image_compressed = NULL;
233 int image_compressed_size = 0;
234 if ( dxt_image_load_from_file(filename_image, width, height, &image) != 0 ) {
235 fprintf(stderr, "Failed to load image [%s]!\n", filename_image);
236 return -1;
237 }
238 if ( dxt_image_compressed_load_from_file(filename_image_compressed, &image_compressed, &image_compressed_size) != 0 ) {
239 fprintf(stderr, "Failed to load compressed image [%s]!\n", filename_image_compressed);
240 return -1;
241 }
242
243 dxt_display_image_comparison(image, image_compressed, image_compressed_size, type, width, height);
244 dxt_image_destroy(image);
245 dxt_image_compressed_destroy(image_compressed);
246
247 return 0;
248}
int dxt_image_compressed_load_from_file(const char *filename, unsigned char **data, int *data_size)
Definition dxt_common.c:145
int dxt_image_compressed_destroy(unsigned char *image_compressed)
Definition dxt_common.c:206
int dxt_display_image_comparison(DXT_IMAGE_TYPE *image, unsigned char *image_compressed, int image_compressed_size, enum dxt_type type, int width, int height)
const char * get_filename_extension(const char *filename)
Definition main.c:168

References dxt_display_image_comparison(), dxt_image_compressed_destroy(), dxt_image_compressed_load_from_file(), dxt_image_destroy(), dxt_image_load_from_file(), DXT_IMAGE_TYPE, get_filename_extension(), dxt_decoder::height, type, and dxt_decoder::width.

Referenced by main().

Here is the call graph for this function:

◆ perform_decode()

int perform_decode ( const char * filename_in,
const char * filename_out,
enum dxt_type type,
int width,
int height,
int display,
int run )

Definition at line 114 of file main.c.

116{
117 unsigned char* image_compressed = NULL;
118 int image_compressed_size = 0;
119 if ( dxt_image_compressed_load_from_file(filename_in, &image_compressed, &image_compressed_size) != 0 ) {
120 fprintf(stderr, "Failed to load compressed image [%s]!\n", filename_in);
121 return -1;
122 }
123
124 if ( display == 1 )
125 dxt_display_image_compressed("Decode Before", image_compressed, image_compressed_size, type, width, height);
126
128 if ( decoder == NULL ) {
129 fprintf(stderr, "Create DXT decoder failed!\n");
130 return -1;
131 }
132
133 DXT_IMAGE_TYPE* image = NULL;
134 int image_size = 0;
135 if ( dxt_decoder_buffer_allocate(decoder, &image, &image_size) != 0 ) {
136 fprintf(stderr, "DXT decoder allocation failed!\n");
137 return -1;
138 }
139
140 TIMER_INIT();
141 for ( int index = 0; index < run; index++ ) {
142 TIMER_START();
143 if ( dxt_decoder_decompress(decoder, image_compressed, image) != 0 ) {
144 fprintf(stderr, "DXT decoder decompressing failed!\n");
145 return -1;
146 }
147 TIMER_STOP();
148 duration[index] = TIMER_DURATION();
149 }
150 printf_duration("Decoding Duration", run);
151
152 if ( display == 1 )
153 dxt_display_image("Decode After", image, width, height);
154
155 if ( dxt_image_save_to_file(filename_out, image, width, height) != 0 ) {
156 fprintf(stderr, "Failed to save image [%s]!\n", filename_out);
157 return -1;
158 }
159
161 dxt_decoder_destroy(decoder);
162 dxt_image_compressed_destroy(image_compressed);
163
164 return 0;
165}
int dxt_image_save_to_file(const char *filename, DXT_IMAGE_TYPE *image, int width, int height)
Definition dxt_common.c:107
#define TIMER_START()
Definition dxt_common.h:56
#define TIMER_INIT()
Definition dxt_common.h:52
#define TIMER_STOP()
Definition dxt_common.h:58
#define TIMER_DURATION()
Definition dxt_common.h:63
int dxt_decoder_buffer_free(unsigned char *image)
struct dxt_decoder * dxt_decoder_create(enum dxt_type type, int width, int height, enum dxt_format out_format, int legacy)
int dxt_decoder_buffer_allocate(struct dxt_decoder *decoder, unsigned char **image, int *image_size)
int dxt_decoder_destroy(struct dxt_decoder *decoder)
int dxt_decoder_decompress(struct dxt_decoder *decoder, unsigned char *image_compressed, DXT_IMAGE_TYPE *image)
int dxt_display_image(const char *title, DXT_IMAGE_TYPE *image, int width, int height)
int dxt_display_image_compressed(const char *title, unsigned char *image_compressed, int image_compressed_size, enum dxt_type type, int width, int height)
steady_clock::duration duration
Definition echo.cpp:67
void printf_duration(const char *name, int run)
Definition main.c:41

References dxt_decoder_buffer_allocate(), dxt_decoder_buffer_free(), dxt_decoder_create(), dxt_decoder_decompress(), dxt_decoder_destroy(), dxt_display_image(), dxt_display_image_compressed(), DXT_FORMAT_RGBA, dxt_image_compressed_destroy(), dxt_image_compressed_load_from_file(), dxt_image_save_to_file(), DXT_IMAGE_TYPE, dxt_decoder::height, dxt_encoder::height, printf_duration(), TIMER_DURATION, TIMER_INIT, TIMER_START, TIMER_STOP, type, dxt_decoder::width, and dxt_encoder::width.

Referenced by main().

Here is the call graph for this function:

◆ perform_display()

int perform_display ( const char * filename,
enum dxt_type type,
int width,
int height,
enum dxt_format format )

Definition at line 178 of file main.c.

179{
180 // Get file extension
181 const char * ext = get_filename_extension(filename);
182
183 // Display image in RGB format
184 if ( strncasecmp(ext, "rgb", 3) == 0 ) {
185 DXT_IMAGE_TYPE* image = NULL;
186 if ( dxt_image_load_from_file(filename, width, height, &image) != 0 ) {
187 fprintf(stderr, "Failed to load image [%s]!\n", filename);
188 return -1;
189 }
190 dxt_display_image("Display RGB Image", image, width, height);
191 dxt_image_destroy(image);
192 }
193 // Display image in DXT buffer format
194 else {
195 unsigned char* image_compressed = NULL;
196 int image_compressed_size = 0;
197 if ( dxt_image_compressed_load_from_file(filename, &image_compressed, &image_compressed_size) != 0 ) {
198 fprintf(stderr, "Failed to load compressed image [%s]!\n", filename);
199 return -1;
200 }
201 dxt_display_image_compressed("Display DXT Compressed Image", image_compressed, image_compressed_size, type, width, height);
202 dxt_image_compressed_destroy(image_compressed);
203 }
204}

References dxt_display_image(), dxt_display_image_compressed(), dxt_image_compressed_destroy(), dxt_image_compressed_load_from_file(), dxt_image_destroy(), dxt_image_load_from_file(), DXT_IMAGE_TYPE, get_filename_extension(), dxt_decoder::height, type, and dxt_decoder::width.

Referenced by main().

Here is the call graph for this function:

◆ perform_encode()

int perform_encode ( const char * filename_in,
const char * filename_out,
enum dxt_type type,
int width,
int height,
enum dxt_format format,
int display,
int run )

Definition at line 61 of file main.c.

63{
64 DXT_IMAGE_TYPE* image = NULL;
65 if ( dxt_image_load_from_file(filename_in, width, height, &image) != 0 ) {
66 fprintf(stderr, "Failed to load image [%s]!\n", filename_in);
67 return -1;
68 }
69
70 if ( display == 1 )
71 dxt_display_image("Encode Before", image, width, height);
72
74 if ( encoder == NULL ) {
75 fprintf(stderr, "Create DXT encoder failed!\n");
76 return -1;
77 }
78
79 unsigned char* image_compressed = NULL;
80 int image_compressed_size = 0;
81 if ( dxt_encoder_buffer_allocate(encoder, &image_compressed, &image_compressed_size) != 0 ) {
82 fprintf(stderr, "DXT encoder allocation failed!\n");
83 return -1;
84 }
85
86 TIMER_INIT();
87 for ( int index = 0; index < run; index++ ) {
89 if ( dxt_encoder_compress(encoder, image, image_compressed) != 0 ) {
90 fprintf(stderr, "DXT encoder compressing failed!\n");
91 return -1;
92 }
93 TIMER_STOP();
94 duration[index] = TIMER_DURATION();
95 }
96 printf_duration("Encoding Duration", run);
97
98 if ( display == 1 )
99 dxt_display_image_compressed("Encode After", image_compressed, image_compressed_size, type, width, height);
100
101 if ( dxt_image_compressed_save_to_file(filename_out, image_compressed, image_compressed_size) != 0 ) {
102 fprintf(stderr, "Failed to save compressed image [%s]!\n", filename_out);
103 return -1;
104 }
105
106 dxt_encoder_buffer_free(image_compressed);
108 dxt_image_destroy(image);
109
110 return 0;
111}

References dxt_display_image(), dxt_display_image_compressed(), dxt_encoder_buffer_allocate(), dxt_encoder_buffer_free(), dxt_encoder_compress(), dxt_encoder_create(), dxt_encoder_destroy(), dxt_image_compressed_save_to_file(), dxt_image_destroy(), dxt_image_load_from_file(), DXT_IMAGE_TYPE, dxt_encoder::format, dxt_encoder::height, printf_duration(), TIMER_DURATION, TIMER_INIT, TIMER_START, TIMER_STOP, type, and dxt_encoder::width.

Referenced by main().

Here is the call graph for this function:

◆ print_help()

void print_help ( )

Definition at line 251 of file main.c.

252{
253 printf(
254 "dxt_compress [options]\n"
255 " -h, --help\t\tprint help\n"
256 " -e, --encode\t\tencode image from RGB format to DXT data buffer\n"
257 " -d, --decode\t\tdecode image from DXT data buffer to RGB format\n"
258 " -s, --size\t\timage size in pixels, e.g. 1920x1080\n"
259 " -i, --input\t\tinput image in RGB format\n"
260 " -o, --output\t\toutput image in RGB format\n"
261 " --display\tdisplay image or compare images\n"
262 " -t, --type\t\tdxt type 'dxt1' or 'dxt5ycocg' (default 'dxt5ycocg')\n"
263 " -f, --format\t\tcolor format 'rgb' or 'yuv' (default 'rgb')\n"
264 " -r, --run\t\tmultiple run times for debugging (default 1)\n"
265 );
266}

Referenced by main().

◆ printf_duration()

void printf_duration ( const char * name,
int run )

Definition at line 41 of file main.c.

42{
43 float min = 999999.0f;
44 float max = 0.0f;
45 float middle = 0.0f;
46 float avg = 0.0f;
47 for ( int index = 0; index < run; index++ ) {
48 if ( duration[index] < min )
49 min = duration[index];
50 if ( duration[index] > max )
51 max = duration[index];
52 avg += duration[index];
53 }
54 avg /= (float)run;
55 middle = duration[run / 2];
56
57 printf("%s: %0.2f ms (med %0.1f ms, min %0.1f ms, max %0.1f ms)\n", name, avg, middle, min, max);
58}
const char * name
Definition settings.cpp:193

References name.

Referenced by perform_decode(), and perform_encode().

Variable Documentation

◆ duration

float duration[RUN_MAX]
static

Definition at line 38 of file main.c.