// Basic syntactic checks on the command-line arguments. // Returns 1 on valid, 0 otherwise. // Also fills up num_feature_args to be number of feature arguments given. // (e.g. if there are 4 '-frame's and 1 '-loop', then num_feature_args = 5). static int ValidateCommandLine(int argc, const char* argv[], int* num_feature_args) { int num_frame_args; int num_loop_args; int num_bgcolor_args; int ok = 1; assert(num_feature_args != NULL); *num_feature_args = 0; // Simple checks. if (CountOccurrences(argv, argc, "-get") > 1) { ERROR_GOTO1("ERROR: Multiple '-get' arguments specified.\n", ErrValidate); } if (CountOccurrences(argv, argc, "-set") > 1) { ERROR_GOTO1("ERROR: Multiple '-set' arguments specified.\n", ErrValidate); } if (CountOccurrences(argv, argc, "-strip") > 1) { ERROR_GOTO1("ERROR: Multiple '-strip' arguments specified.\n", ErrValidate); } if (CountOccurrences(argv, argc, "-info") > 1) { ERROR_GOTO1("ERROR: Multiple '-info' arguments specified.\n", ErrValidate); } if (CountOccurrences(argv, argc, "-o") > 1) { ERROR_GOTO1("ERROR: Multiple output files specified.\n", ErrValidate); } // Compound checks. num_frame_args = CountOccurrences(argv, argc, "-frame"); num_loop_args = CountOccurrences(argv, argc, "-loop"); num_bgcolor_args = CountOccurrences(argv, argc, "-bgcolor"); if (num_loop_args > 1) { ERROR_GOTO1("ERROR: Multiple loop counts specified.\n", ErrValidate); } if (num_bgcolor_args > 1) { ERROR_GOTO1("ERROR: Multiple background colors specified.\n", ErrValidate); } if ((num_frame_args == 0) && (num_loop_args + num_bgcolor_args > 0)) { ERROR_GOTO1("ERROR: Loop count and background color are relevant only in " "case of animation.\n", ErrValidate); } assert(ok == 1); if (num_frame_args == 0) { // Single argument ('set' action for ICCP/EXIF/XMP, OR a 'get' action). *num_feature_args = 1; } else { // Multiple arguments ('set' action for animation) *num_feature_args = num_frame_args + num_loop_args + num_bgcolor_args; } ErrValidate: return ok; }
static WebPMux* DuplicateMuxHeader(const WebPMux* const mux) { WebPMux* new_mux = WebPMuxNew(); WebPMuxAnimParams p; WebPMuxError err; int i; int ok = 1; if (new_mux == NULL) return NULL; err = WebPMuxGetAnimationParams(mux, &p); if (err == WEBP_MUX_OK) { err = WebPMuxSetAnimationParams(new_mux, &p); if (err != WEBP_MUX_OK) { ERROR_GOTO2("Error (%s) handling animation params.\n", ErrorString(err), End); } } else { /* it might not be an animation. Just keep moving. */ } for (i = 1; i <= 3; ++i) { WebPData metadata; err = WebPMuxGetChunk(mux, kFourccList[i], &metadata); if (err == WEBP_MUX_OK && metadata.size > 0) { err = WebPMuxSetChunk(new_mux, kFourccList[i], &metadata, 1); if (err != WEBP_MUX_OK) { ERROR_GOTO1("Error transferring metadata in DuplicateMux().", End); } } } End: if (!ok) { WebPMuxDelete(new_mux); new_mux = NULL; } return new_mux; }
// Parses command-line arguments to fill up config object. Also performs some // semantic checks. static int ParseCommandLine(int argc, const char* argv[], WebPMuxConfig* config) { int i = 0; int feature_arg_index = 0; int ok = 1; while (i < argc) { Feature* const feature = &config->feature_; FeatureArg* const arg = &feature->args_[feature_arg_index]; if (argv[i][0] == '-') { // One of the action types or output. if (!strcmp(argv[i], "-set")) { if (ACTION_IS_NIL) { config->action_type_ = ACTION_SET; } else { ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse); } ++i; } else if (!strcmp(argv[i], "-get")) { if (ACTION_IS_NIL) { config->action_type_ = ACTION_GET; } else { ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse); } ++i; } else if (!strcmp(argv[i], "-strip")) { if (ACTION_IS_NIL) { config->action_type_ = ACTION_STRIP; feature->arg_count_ = 0; } else { ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse); } ++i; } else if (!strcmp(argv[i], "-frame")) { CHECK_NUM_ARGS_LESS(3, ErrParse); if (ACTION_IS_NIL || config->action_type_ == ACTION_SET) { config->action_type_ = ACTION_SET; } else { ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse); } if (FEATURETYPE_IS_NIL || feature->type_ == FEATURE_ANMF) { feature->type_ = FEATURE_ANMF; } else { ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse); } arg->subtype_ = SUBTYPE_ANMF; arg->filename_ = argv[i + 1]; arg->params_ = argv[i + 2]; ++feature_arg_index; i += 3; } else if (!strcmp(argv[i], "-loop") || !strcmp(argv[i], "-bgcolor")) { CHECK_NUM_ARGS_LESS(2, ErrParse); if (ACTION_IS_NIL || config->action_type_ == ACTION_SET) { config->action_type_ = ACTION_SET; } else { ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse); } if (FEATURETYPE_IS_NIL || feature->type_ == FEATURE_ANMF) { feature->type_ = FEATURE_ANMF; } else { ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse); } arg->subtype_ = !strcmp(argv[i], "-loop") ? SUBTYPE_LOOP : SUBTYPE_BGCOLOR; arg->params_ = argv[i + 1]; ++feature_arg_index; i += 2; } else if (!strcmp(argv[i], "-o")) { CHECK_NUM_ARGS_LESS(2, ErrParse); config->output_ = argv[i + 1]; i += 2; } else if (!strcmp(argv[i], "-info")) { CHECK_NUM_ARGS_NOT_EQUAL(2, ErrParse); if (config->action_type_ != NIL_ACTION) { ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse); } else { config->action_type_ = ACTION_INFO; feature->arg_count_ = 0; config->input_ = argv[i + 1]; } i += 2; } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "-help")) { PrintHelp(); DeleteConfig(config); exit(0); } else if (!strcmp(argv[i], "-version")) { const int version = WebPGetMuxVersion(); printf("%d.%d.%d\n", (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff); DeleteConfig(config); exit(0); } else if (!strcmp(argv[i], "--")) { if (i < argc - 1) { ++i; if (config->input_ == NULL) { config->input_ = argv[i]; } else { ERROR_GOTO2("ERROR at '%s': Multiple input files specified.\n", argv[i], ErrParse); } } break; } else { ERROR_GOTO2("ERROR: Unknown option: '%s'.\n", argv[i], ErrParse); } } else { // One of the feature types or input. if (ACTION_IS_NIL) {