1 /*
2  *			GPAC - Multimedia Framework C SDK
3  *
4  *			Authors: Cyril Concolato
5  *			Copyright (c) Telecom ParisTech 2006-2012
6  *					All rights reserved
7  *
8  *  This file is part of GPAC / load&compare application
9  *
10  *  GPAC is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU Lesser General Public License as published by
12  *  the Free Software Foundation; either version 2, or (at your option)
13  *  any later version.
14  *
15  *  GPAC is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU Lesser General Public License for more details.
19  *
20  *  You should have received a copy of the GNU Lesser General Public
21  *  License along with this library; see the file COPYING.  If not, write to
22  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  */
25 #include <gpac/scene_manager.h>
26 #include <zlib.h>
27 
28 enum {
29 	SVG = 0,
30 	XMT = 1,
31 };
32 
33 typedef struct {
34 	char filename[100];
35 	u32 size;
36 	u32 gpacxml_loadtime;
37 	u32 libxml_loadtime;
38 	u32 gz_size;
39 	u32 gpacxml_gz_loadtime;
40 	u32 libxml_gz_loadtime;
41 	u32 track_size;
42 	u32 track_loadtime;
43 	u32 decoded_size;
44 	u32 decoded_loadtime;
45 } LoadData;
46 
47 typedef struct {
48 	FILE *out;
49 	u32 type;
50 	u32 nbloads;
51 	u32 verbose;
52 	Bool regenerate;
53 	Bool spread_repeat;
54 	u32 repeat_index;
55 	GF_List *data;
56 } GF_LoadCompare;
57 
load_mp4(GF_LoadCompare * lc,GF_ISOFile * mp4,u32 * loadtime)58 GF_Err load_mp4(GF_LoadCompare *lc, GF_ISOFile *mp4, u32 *loadtime)
59 {
60 	GF_Err e = GF_OK;
61 	GF_SceneLoader load;
62 	u32 i, starttime, endtime;
63 	u32 nb;
64 	if (lc->spread_repeat) nb = 1;
65 	else nb = lc->nbloads ;
66 
67 	*loadtime = 0;
68 	for (i = 0; i< nb; i++) {
69 		GF_SceneGraph *sg;
70 		memset(&load, 0, sizeof(GF_SceneLoader));
71 		sg = gf_sg_new();
72 		load.ctx = gf_sm_new(sg);
73 
74 		load.isom = mp4;
75 		starttime = gf_sys_clock();
76 
77 		e = gf_sm_load_init(&load);
78 		if (e) {
79 			fprintf(stderr, "Error loading MP4 file\n");
80 		} else {
81 			e = gf_sm_load_run(&load);
82 			if (e) {
83 				fprintf(stderr, "Error loading MP4 file\n");
84 			} else {
85 				endtime = gf_sys_clock();
86 				*loadtime += endtime-starttime;
87 			}
88 			gf_sm_load_done(&load);
89 		}
90 		gf_sm_del(load.ctx);
91 		gf_sg_del(sg);
92 	}
93 	return e;
94 }
95 
load_progress(void * cbk,u32 done,u32 total)96 void load_progress(void *cbk, u32 done, u32 total) {
97 	fprintf(stdout, "%d/%d\r", done, total);
98 }
99 
gpacctx_load_file(GF_LoadCompare * lc,char * item_path,u32 * loadtime)100 GF_Err gpacctx_load_file(GF_LoadCompare *lc, char *item_path, u32 *loadtime)
101 {
102 	GF_Err e = GF_OK;
103 	GF_SceneLoader load;
104 	u32 i, starttime, endtime;
105 
106 	u32 nb;
107 	if (lc->spread_repeat) nb = 1;
108 	else nb = lc->nbloads ;
109 
110 	*loadtime = 0;
111 
112 	for (i = 0; i<nb; i++) {
113 		GF_SceneGraph *sg;
114 		memset(&load, 0, sizeof(GF_SceneLoader));
115 		sg = gf_sg_new();
116 		load.ctx = gf_sm_new(sg);
117 		load.OnProgress = load_progress;
118 
119 		load.fileName = item_path;
120 		starttime = gf_sys_clock();
121 
122 		e = gf_sm_load_init(&load);
123 		if (e) {
124 			fprintf(stderr, "Error loading file %s\n", item_path);
125 		} else {
126 			e = gf_sm_load_run(&load);
127 			if (e) {
128 				fprintf(stderr, "Error loading file %s\n", item_path);
129 			} else {
130 				endtime = gf_sys_clock();
131 				*loadtime += endtime-starttime;
132 			}
133 			gf_sm_load_done(&load);
134 		}
135 		gf_sm_del(load.ctx);
136 		gf_sg_del(sg);
137 	}
138 	return e;
139 }
140 
get_laser_track_size(GF_ISOFile * mp4,u32 * size)141 GF_Err get_laser_track_size(GF_ISOFile *mp4, u32 *size)
142 {
143 	GF_Err e = GF_OK;
144 	u32 j;
145 	u32 track_id, trackNum;
146 
147 	*size = 0;
148 	track_id = gf_isom_get_track_id(mp4, 1);
149 	trackNum = gf_isom_get_track_by_id(mp4, track_id);
150 	for (j=0; j<gf_isom_get_sample_count(mp4, trackNum); j++) {
151 		GF_ISOSample *samp = gf_isom_get_sample_info(mp4, trackNum, j+1, NULL, NULL);
152 		*size += samp->dataLength;
153 		gf_isom_sample_del(&samp);
154 	}
155 	return e;
156 }
157 
encode_laser(GF_LoadCompare * lc,char * item_path,GF_ISOFile * mp4,GF_SMEncodeOptions * opts)158 GF_Err encode_laser(GF_LoadCompare *lc, char *item_path, GF_ISOFile *mp4, GF_SMEncodeOptions *opts)
159 {
160 	GF_Err e = GF_OK;
161 	GF_SceneLoader load;
162 	GF_SceneManager *ctx;
163 	GF_SceneGraph *sg;
164 	GF_StatManager *statsman = NULL;
165 
166 	memset(&load, 0, sizeof(GF_SceneLoader));
167 	sg = gf_sg_new();
168 	ctx = gf_sm_new(sg);
169 	load.ctx = ctx;
170 	load.fileName = item_path;
171 
172 	e = gf_sm_load_init(&load);
173 	if (e) {
174 		fprintf(stderr, "Error loading file %s\n", item_path);
175 	} else {
176 		e = gf_sm_load_run(&load);
177 		if (e) {
178 			fprintf(stderr, "Error loading file %s\n", item_path);
179 		} else {
180 			if (opts->auto_qant) {
181 				if (lc->verbose) fprintf(stdout, "Analysing Scene for Automatic Quantization\n");
182 				statsman = gf_sm_stats_new();
183 				e = gf_sm_stats_for_scene(statsman, ctx);
184 				if (!e) {
185 					GF_SceneStatistics *stats = gf_sm_stats_get(statsman);
186 					if (opts->resolution > (s32)stats->frac_res_2d) {
187 						if (lc->verbose) fprintf(stdout, " Given resolution %d is (unnecessarily) too high, using %d instead.\n", opts->resolution, stats->frac_res_2d);
188 						opts->resolution = stats->frac_res_2d;
189 					} else if (stats->int_res_2d + opts->resolution <= 0) {
190 						if (lc->verbose) fprintf(stdout, " Given resolution %d is too low, using %d instead.\n", opts->resolution, stats->int_res_2d - 1);
191 						opts->resolution = 1 - stats->int_res_2d;
192 					}
193 					opts->coord_bits = stats->int_res_2d + opts->resolution;
194 					if (lc->verbose) fprintf(stdout, " Coordinates & Lengths encoded using ");
195 					if (opts->resolution < 0) {
196 						if (lc->verbose) fprintf(stdout, "only the %d most significant bits (of %d).\n", opts->coord_bits, stats->int_res_2d);
197 					} else {
198 						if (lc->verbose) fprintf(stdout, "a %d.%d representation\n", stats->int_res_2d, opts->resolution);
199 					}
200 
201 					if (lc->verbose) fprintf(stdout, " Matrix Scale & Skew Coefficients ");
202 					if (opts->coord_bits < stats->scale_int_res_2d) {
203 						opts->scale_bits = stats->scale_int_res_2d - opts->coord_bits;
204 						if (lc->verbose) fprintf(stdout, "encoded using a %d.8 representation\n", stats->scale_int_res_2d);
205 					} else  {
206 						opts->scale_bits = 0;
207 						if (lc->verbose) fprintf(stdout, "not encoded.\n");
208 					}
209 				}
210 				gf_sm_stats_del(statsman);
211 			}
212 
213 			e = gf_sm_encode_to_file(ctx, mp4, opts);
214 			if (e) {
215 				fprintf(stderr, "Error while encoding mp4 file\n");
216 			} else {
217 				e = gf_isom_set_brand_info(mp4, GF_ISOM_BRAND_MP42, 1);
218 				if (!e) e = gf_isom_modify_alternate_brand(mp4, GF_ISOM_BRAND_ISOM, 1);
219 			}
220 
221 			gf_sm_load_done(&load);
222 		}
223 	}
224 	gf_sm_del(ctx);
225 	gf_sg_del(sg);
226 
227 	return e;
228 }
229 
create_laser_mp4(GF_LoadCompare * lc,char * item_name,char * item_path,u32 * size)230 GF_Err create_laser_mp4(GF_LoadCompare *lc, char *item_name, char *item_path, u32 *size)
231 {
232 	char mp4_path[100], *ext;
233 	GF_Err e = GF_OK;
234 	GF_ISOFile *mp4;
235 
236 	*size = 0;
237 
238 	strcpy(mp4_path, item_name);
239 	ext = strrchr(mp4_path, '.');
240 	strcpy(ext, ".mp4");
241 	mp4 = gf_isom_open(mp4_path, GF_ISOM_WRITE_EDIT, NULL);
242 	if (!mp4) {
243 		if (lc->verbose) fprintf(stdout, "Could not open file %s for writing\n", mp4_path);
244 		e = GF_IO_ERR;
245 	} else {
246 		GF_SMEncodeOptions opts;
247 		memset(&opts, 0, sizeof(GF_SMEncodeOptions));
248 		opts.auto_qant = 1;
249 		opts.resolution = 8;
250 		e = encode_laser(lc, item_path, mp4, &opts);
251 		if (e) {
252 			if (lc->verbose) fprintf(stdout, "Could not encode MP4 file from %s\n", item_path);
253 			gf_isom_delete(mp4);
254 		} else {
255 			gf_isom_close(mp4);
256 
257 			mp4 = gf_isom_open(mp4_path, GF_ISOM_OPEN_READ, NULL);
258 			if (!mp4) {
259 				if (lc->verbose) fprintf(stdout, "Could not open file %s for reading\n", mp4_path);
260 				e = GF_IO_ERR;
261 			} else {
262 				e = get_laser_track_size(mp4, size);
263 				if (e) {
264 					if (lc->verbose) fprintf(stdout, "Could not get MP4 file size\n");
265 				}
266 				gf_isom_close(mp4);
267 			}
268 		}
269 	}
270 	return e;
271 }
272 
273 
get_mp4_loadtime(GF_LoadCompare * lc,char * item_name,char * item_path,u32 * loadtime)274 GF_Err get_mp4_loadtime(GF_LoadCompare *lc, char *item_name, char *item_path, u32 *loadtime)
275 {
276 	char mp4_path[100], *ext;
277 	GF_Err e = GF_OK;
278 	GF_ISOFile *mp4;
279 
280 	*loadtime = 0;
281 
282 	strcpy(mp4_path, item_name);
283 	ext = strrchr(mp4_path, '.');
284 	strcpy(ext, ".mp4");
285 	mp4 = gf_isom_open(mp4_path, GF_ISOM_OPEN_READ, NULL);
286 	if (!mp4) {
287 		if (lc->verbose) fprintf(stdout, "Could not open file %s for reading\n", mp4_path);
288 		e = GF_IO_ERR;
289 	} else {
290 		e = load_mp4(lc, mp4, loadtime);
291 		if (e) {
292 			if (lc->verbose) fprintf(stdout, "Could not get MP4 file load time\n");
293 		}
294 	}
295 	gf_isom_close(mp4);
296 	return e;
297 }
298 
decode_svg(GF_LoadCompare * lc,char * item_name,char * item_path,char * svg_out_path)299 GF_Err decode_svg(GF_LoadCompare *lc, char *item_name, char *item_path, char *svg_out_path)
300 {
301 	GF_SceneManager *ctx;
302 	GF_SceneLoader load;
303 	GF_ISOFile *mp4;
304 	GF_Err e = GF_OK;
305 	char mp4_path[256];
306 	char *ext;
307 
308 	strcpy(mp4_path, item_name);
309 	ext = strrchr(mp4_path, '.');
310 	strcpy(ext, ".mp4");
311 	mp4 = gf_isom_open(mp4_path, GF_ISOM_OPEN_READ, NULL);
312 	if (!mp4) {
313 		if (lc->verbose) fprintf(stdout, "Could not open file %s\n", mp4_path);
314 		e = GF_IO_ERR;
315 	} else {
316 		GF_SceneGraph *sg;
317 		sg = gf_sg_new();
318 		ctx = gf_sm_new(sg);
319 		memset(&load, 0, sizeof(GF_SceneLoader));
320 		load.isom = mp4;
321 		load.ctx = ctx;
322 		e = gf_sm_load_init(&load);
323 		if (e) {
324 			fprintf(stderr, "Error loading MP4 file\n");
325 		} else {
326 			e = gf_sm_load_run(&load);
327 			if (e) {
328 				fprintf(stderr, "Error loading MP4 file\n");
329 			} else {
330 				gf_sm_load_done(&load);
331 
332 				ext = strrchr(svg_out_path, '.');
333 				ext[0] = 0;
334 				e = gf_sm_dump(ctx, svg_out_path, GF_SM_DUMP_SVG);
335 				if (e) {
336 					fprintf(stderr, "Error dumping SVG from MP4 file\n");
337 				}
338 			}
339 		}
340 		gf_sm_del(ctx);
341 		gf_sg_del(sg);
342 		gf_isom_close(mp4);
343 	}
344 	return e;
345 }
346 
libxml_load_svg(GF_LoadCompare * lc,char * item_path,u32 * loadtime)347 GF_Err libxml_load_svg(GF_LoadCompare *lc, char *item_path, u32 *loadtime)
348 {
349 	GF_Err e = GF_OK;
350 	u32 i, starttime, endtime;
351 
352 	u32 nb;
353 	if (lc->spread_repeat) nb = 1;
354 	else nb = lc->nbloads ;
355 
356 	*loadtime = 0;
357 
358 	for (i = 0; i<nb; i++) {
359 		void *p;
360 		GF_SceneGraph *sg;
361 		sg = gf_sg_new();
362 
363 		starttime = gf_sys_clock();
364 
365 		p = DANAE_NewSVGParser(item_path, sg);
366 		DANAE_SVGParser_Parse(p);
367 		DANAE_SVGParser_Terminate();
368 
369 		endtime = gf_sys_clock();
370 		if (lc->verbose) fprintf(stdout, "LibXML single parsing: %d\n", endtime-starttime);
371 		*loadtime += endtime-starttime;
372 
373 		gf_sg_del(sg);
374 	}
375 	return e;
376 }
377 
get_size(GF_LoadCompare * lc,char * item_name,char * item_path,u32 * size)378 GF_Err get_size(GF_LoadCompare *lc, char *item_name, char *item_path, u32 *size)
379 {
380 	GF_Err e = GF_OK;
381 	FILE *file = NULL;
382 
383 	*size = 0;
384 
385 	file = gf_fopen(item_path, "rt");
386 	if (!file) {
387 		if (lc->verbose) fprintf(stdout, "Could not open file %s\n", item_path);
388 		e = GF_IO_ERR;
389 	} else {
390 		fseek(file, 0, SEEK_END);
391 		*size = (u32)ftell(file);
392 		gf_fclose(file);
393 		if (*size == 0) {
394 			if (lc->verbose) fprintf(stdout, "File %s has a size of 0\n", item_path);
395 			e = GF_IO_ERR;
396 		}
397 	}
398 	return e;
399 }
400 
get_decoded_svg_loadtime_and_size(GF_LoadCompare * lc,char * item_name,char * item_path,u32 * loadtime,u32 * size)401 GF_Err get_decoded_svg_loadtime_and_size(GF_LoadCompare *lc, char *item_name, char *item_path, u32 *loadtime, u32 *size)
402 {
403 	GF_Err e = GF_OK;
404 	char svg_out_name[256];
405 	char *ext;
406 
407 	strcpy(svg_out_name, item_name);
408 	ext = strrchr(svg_out_name, '.');
409 	strcpy(ext, "_out.svg");
410 
411 	*size = 0;
412 	*loadtime = 0;
413 
414 	e = decode_svg(lc, item_name, item_path, svg_out_name);
415 	if (!e) {
416 		e = get_size(lc, svg_out_name, svg_out_name, size);
417 		if (e) {
418 			return e;
419 		}
420 		e = gpacctx_load_file(lc, svg_out_name, loadtime);
421 	}
422 	return e;
423 }
424 
create_gz_file(GF_LoadCompare * lc,char * item_name,char * item_path,u32 * size)425 GF_Err create_gz_file(GF_LoadCompare *lc, char *item_name, char *item_path, u32 *size)
426 {
427 	char gz_path[256];
428 	GF_Err e = GF_OK;
429 	FILE *file = NULL;
430 	void *gz = NULL;
431 	u32 read;
432 
433 	*size = 0;
434 
435 	strcpy(gz_path, item_name);
436 	strcat(gz_path, "z");
437 	gz = gzopen(gz_path, "wb");
438 	file = gf_fopen(item_path, "rt");
439 
440 	if (!gz || !file) {
441 		if (lc->verbose) fprintf(stdout, "Could not open file %s or %s\n", item_path, gz_path);
442 		e = GF_IO_ERR;
443 	} else {
444 		char buffer[100];
445 		while ((read = fread(buffer, 1, 100, file))) gzwrite(gz, buffer, read);
446 		gf_fclose(file);
447 		gzclose(gz);
448 		file = gf_fopen(gz_path, "rb");
449 		fseek(file, 0, SEEK_END);
450 		*size = (u32)ftell(file);
451 		gf_fclose(file);
452 		if (*size == 0) {
453 			if (lc->verbose) fprintf(stdout, "File %s has a size of 0\n", gz_path);
454 			e = GF_IO_ERR;
455 		}
456 	}
457 	return e;
458 }
459 
get_gz_loadtime(GF_LoadCompare * lc,char * item_name,char * item_path,u32 * loadtime,Bool useLibXML)460 GF_Err get_gz_loadtime(GF_LoadCompare *lc, char *item_name, char *item_path, u32 *loadtime, Bool useLibXML)
461 {
462 	char gz_path[256];
463 	GF_Err e = GF_OK;
464 	*loadtime = 0;
465 
466 	strcpy(gz_path, item_name);
467 	strcat(gz_path, "z");
468 
469 	if (useLibXML) {
470 		e = libxml_load_svg(lc, gz_path, loadtime);
471 	} else {
472 		e = gpacctx_load_file(lc, gz_path, loadtime);
473 	}
474 	return e;
475 }
476 
print_load_data(GF_LoadCompare * lc,LoadData * ld)477 void print_load_data(GF_LoadCompare *lc, LoadData *ld)
478 {
479 	if (lc->verbose) fprintf(stdout, "Processing %s\n", ld->filename);
480 	fprintf(lc->out, "%s\t", ld->filename);
481 
482 	if (lc->verbose) fprintf(stdout, "File Size %d\n", ld->size);
483 	fprintf(lc->out, "%d\t", ld->size);
484 
485 	if (lc->verbose) fprintf(stdout, "GPAC XML Load Time %d\n", ld->gpacxml_loadtime);
486 	fprintf(lc->out, "%d\t", ld->gpacxml_loadtime);
487 
488 	if (lc->verbose) fprintf(stdout, "LibXML Load Time %d \n", ld->libxml_loadtime);
489 	fprintf(lc->out, "%d\t", ld->libxml_loadtime);
490 
491 	if (lc->verbose) fprintf(stdout, "GZ Size %d\n", ld->gz_size);
492 	fprintf(lc->out, "%d\t", ld->gz_size);
493 
494 	if (lc->verbose) fprintf(stdout, "GZ Load Time %d\n", ld->gpacxml_gz_loadtime);
495 	fprintf(lc->out, "%d\t", ld->gpacxml_gz_loadtime);
496 
497 	if (lc->verbose) fprintf(stdout, "LibXML GZ Load Time %d\n", ld->libxml_gz_loadtime);
498 	fprintf(lc->out, "%d\t", ld->libxml_gz_loadtime);
499 
500 	if (lc->verbose) fprintf(stdout, "MP4 Track Size %d\n", ld->track_size);
501 	fprintf(lc->out, "%d\t", ld->track_size);
502 
503 	if (lc->verbose) fprintf(stdout, "MP4 Track Load Time %d\n", ld->track_loadtime);
504 	fprintf(lc->out, "%d\t", ld->track_loadtime);
505 
506 	if (lc->verbose) fprintf(stdout, "Decoded Size %d\n", ld->decoded_size);
507 	fprintf(lc->out, "%d\t", ld->decoded_size);
508 
509 	if (lc->verbose) fprintf(stdout, "Decoded Load Time %d \n", ld->decoded_loadtime);
510 	fprintf(lc->out, "%d\t", ld->decoded_loadtime);
511 
512 	if (lc->verbose) fprintf(stdout, "Done %s\n", ld->filename);
513 	fprintf(lc->out, "\n");
514 	fflush(lc->out);
515 }
516 
loadcompare_one(void * cbck,char * item_name,char * item_path,GF_FileEnumInfo * file_info)517 Bool loadcompare_one(void *cbck, char *item_name, char *item_path, GF_FileEnumInfo *file_info)
518 {
519 	GF_Err e;
520 	GF_LoadCompare *lc = cbck;
521 	u32 loadtime;
522 	LoadData *ld;
523 
524 	if (lc->repeat_index == 0) {
525 		GF_SAFEALLOC(ld, sizeof(LoadData));
526 		gf_list_add(lc->data, ld);
527 		strcpy(ld->filename, item_name);
528 
529 		e = get_size(lc, item_name, item_path, &ld->size);
530 		if (e) return 1;
531 
532 		e = create_gz_file(lc, item_name, item_path, &ld->gz_size);
533 		if (e) return 1;
534 
535 		e = create_laser_mp4(lc, item_name, item_path, &ld->track_size);
536 		if (e) return 1;
537 
538 	} else {
539 		LoadData *tmp;
540 		u32 pos = 0;
541 		ld = NULL;
542 		while (tmp = gf_list_enum(lc->data, &pos)) {
543 			if (!strcmp(tmp->filename, item_name)) {
544 				ld = tmp;
545 				break;
546 			}
547 		}
548 		if (ld == NULL) return 1;
549 	}
550 
551 
552 	if (lc->type == SVG) {
553 		/* GPAC XML loader */
554 		e = gpacctx_load_file(lc, item_path, &loadtime);
555 		if (e) return 1;
556 		ld->gpacxml_loadtime += loadtime;
557 
558 		e = get_gz_loadtime(lc, item_name, item_path, &loadtime, 0);
559 		if (e) return 1;
560 		ld->gpacxml_gz_loadtime += loadtime;
561 
562 		/* LibXML and LibXML GZ loadings */
563 		e = libxml_load_svg(lc, item_path, &loadtime);
564 		if (e) return 1;
565 		ld->libxml_loadtime += loadtime;
566 
567 		e = get_gz_loadtime(lc, item_name, item_path, &loadtime, 1);
568 		if (e) return 1;
569 		ld->libxml_gz_loadtime += loadtime;
570 
571 		/* MP4 Loading */
572 		e = get_mp4_loadtime(lc, item_name, item_path, &loadtime);
573 		if (e) return 1;
574 		ld->track_loadtime += loadtime;
575 
576 		/*		e = get_decoded_svg_loadtime_and_size(lc, item_name, item_path, &loadtime, &ld->decoded_size);
577 				if (e) return 1;
578 				ld->decoded_loadtime += loadtime;*/
579 
580 	} else if (lc->type == XMT) {
581 		e = gpacctx_load_file(lc, item_path, &loadtime);
582 		if (e) return 1;
583 		ld->gpacxml_loadtime += loadtime;
584 	}
585 
586 	if (!lc->spread_repeat) {
587 		print_load_data(lc, ld);
588 		gf_free(ld);
589 	}
590 	return 0;
591 }
592 
usage()593 void usage()
594 {
595 	fprintf(stdout, "Compare LASeR and SVG encoding size and loading time\n");
596 	fprintf(stdout, "usage: (-out output_result) (-single input.svg | -dir dir) (-nloads X) (-verbose X)\n");
597 	fprintf(stdout, "defaults are: stdout, dir=. and X = 1");
598 }
599 
main(int argc,char ** argv)600 int main(int argc, char **argv)
601 {
602 	u32 i;
603 	GF_LoadCompare lc;
604 	Bool single = 0;
605 	char *out = NULL;
606 	char in[256] = ".";
607 
608 	fprintf(stdout, "LASeR and SVG Comparison tool\n");
609 
610 	memset(&lc, 0, sizeof(GF_LoadCompare));
611 	lc.nbloads = 1;
612 	lc.out = stdout;
613 
614 	for (i = 1; i < (u32) argc ; i++) {
615 		char *arg = argv[i];
616 		if (!stricmp(arg, "-out")) {
617 			out = argv[i+1];
618 			i++;
619 		} else if (!stricmp(arg, "-single")) {
620 			single = 1;
621 			strcpy(in, argv[i+1]);
622 			i++;
623 		} else if (!stricmp(arg, "-dir")) {
624 			strcpy(in, argv[i+1]);
625 			i++;
626 		} else if (!stricmp(arg, "-nloads")) {
627 			lc.nbloads = (u32)atoi(argv[i+1]);
628 			i++;
629 		} else if (!stricmp(arg, "-regenerate")) {
630 			lc.regenerate = 1;
631 		} else if (!stricmp(arg, "-xmt")) {
632 			lc.type = XMT;
633 		} else if (!stricmp(arg, "-svg")) {
634 			lc.type = SVG;
635 		} else if (!stricmp(arg, "-spread_repeat")) {
636 			lc.spread_repeat = 1;
637 		} else if (!stricmp(arg, "-verbose")) {
638 			lc.verbose = (u32)atoi(argv[i+1]);
639 			i++;
640 		} else {
641 			usage();
642 			return -1;
643 		}
644 	}
645 
646 	gf_sys_init(GF_MemTrackerNone);
647 	if (out) lc.out = gf_fopen(out, "wt");
648 	if (!lc.out) {
649 		fprintf(stderr, "Cannot open output file %s\n", out);
650 		return -1;
651 	}
652 
653 	if (lc.type == SVG) {
654 		fprintf(lc.out,"File Name\tSVG Size\tSVG Load Time\tLibXML Load Time\tSVGZ Size\tSVGZ Load Time\tLibXML GZ Load Time\tMP4 Size\tMP4 Load Time\tDecoded SVG Size\tDecoded SVG Load Time\n");
655 	} else if (lc.type == XMT) {
656 		fprintf(lc.out,"File Name\tXMT Size\tXMT Load Time\tBT Size\tBT Load Time\n");
657 	}
658 
659 	lc.data = gf_list_new();
660 
661 	if (single) {
662 		LoadData *ld;
663 		char *tmp = strrchr(in, GF_PATH_SEPARATOR);
664 		loadcompare_one(&lc, tmp+1, in);
665 		ld = gf_list_get(lc.data, 0);
666 		print_load_data(&lc, ld);
667 		gf_free(ld);
668 	} else {
669 		if (lc.spread_repeat) {
670 			for (lc.repeat_index = 0; lc.repeat_index < lc.nbloads; lc.repeat_index ++) {
671 				if (lc.verbose) fprintf(stdout, "Loop %d\n", lc.repeat_index);
672 				if (lc.type == SVG) {
673 					gf_enum_directory(in, 0, loadcompare_one, &lc, "svg");
674 				} else if (lc.type == XMT) {
675 					gf_enum_directory(in, 0, loadcompare_one, &lc, "xmt");
676 				}
677 			}
678 			for (i=0; i<gf_list_count(lc.data); i++) {
679 				LoadData *ld = gf_list_get(lc.data, i);
680 				print_load_data(&lc, ld);
681 				gf_free(ld);
682 			}
683 		} else {
684 			if (lc.type == SVG) {
685 				gf_enum_directory(in, 0, loadcompare_one, &lc, "svg");
686 			} else if (lc.type == XMT) {
687 				gf_enum_directory(in, 0, loadcompare_one, &lc, "xmt");
688 			}
689 		}
690 	}
691 	gf_list_del(lc.data);
692 
693 	if (lc.out) gf_fclose(lc.out);
694 	gf_sys_close();
695 	return 0;
696 }
697 
698