@@ -260,243 +260,244 @@ static avifBool convertCropToClap(uint32_t srcW, uint32_t srcH, avifPixelFormat
260260 return AVIF_TRUE ;
261261}
262262
263+ #define CHECK (condition , reason ) \
264+ do { \
265+ if (!(condition)) { \
266+ fprintf(stderr, "ERROR: Failed reading progressive config: %s\n", reason); \
267+ return AVIF_FALSE; \
268+ } \
269+ } while (0)
270+
263271struct avifEncoderLayerConfig
264272{
265- uint8_t layerCount ; // Image layers for color sub image; 0 to disable layer image (default).
273+ uint8_t layerCount ; // Image layers for color sub image; 0 to disable layer image (default).
266274 uint8_t layerCountAlpha ; // Image layers for alpha sub image; 0 to disable layer image (default).
267275 avifLayerConfig layers [MAX_AV1_LAYER_COUNT ];
268276 avifLayerConfig layersAlpha [MAX_AV1_LAYER_COUNT ];
269277};
270278
271- struct avifOptionEnumList
272- {
273- const char * name ;
274- int val ;
275- };
276-
277- static const struct avifOptionEnumList scalingModeList [] = { //
278- { "1/2" , AVIF_SCALING_ONETWO }, { "1/4" , AVIF_SCALING_ONEFOUR },
279- { "1/8" , AVIF_SCALING_ONEEIGHT }, { "3/4" , AVIF_SCALING_THREEFOUR },
280- { "3/5" , AVIF_SCALING_THREEFIVE }, { "4/5" , AVIF_SCALING_FOURFIVE },
281- { "1" , AVIF_SCALING_NORMAL }, { NULL , 0 }
282- };
279+ static const avifScalingMode avifScalingModeNormal = { 1 , 1 };
283280
284281static avifBool avifParseScalingMode (const char * * pArg , avifScalingMode * mode )
285282{
286- const struct avifOptionEnumList * listptr ;
287- for (listptr = scalingModeList ; listptr -> name ; ++ listptr ) {
288- size_t matchLength = strlen (listptr -> name );
289- if (!strncmp (* pArg , listptr -> name , matchLength )) {
290- * mode = (avifScalingMode )listptr -> val ;
291- * pArg += matchLength ;
283+ char * end ;
284+ uint64_t value = strtoull (* pArg , & end , 10 );
285+ CHECK (errno != ERANGE , "overflowed while reading scale nominator" );
286+ CHECK (end != * pArg , "can't parse scale nominator" );
287+ if (* end != '/' ) {
288+ if (value == 1 ) {
289+ * mode = avifScalingModeNormal ;
290+ * pArg = end ;
292291 return AVIF_TRUE ;
293292 }
293+ return AVIF_FALSE ;
294294 }
295-
296- return AVIF_FALSE ;
295+ mode -> numerator = value ;
296+ * pArg = end + 1 ;
297+ value = strtoull (* pArg , & end , 10 );
298+ CHECK (errno != ERANGE , "overflowed while reading scale denominator" );
299+ CHECK (end != * pArg , "can't parse scale denominator" );
300+ mode -> denominator = value ;
301+ * pArg = end ;
302+ return AVIF_TRUE ;
297303}
298304
299- #define FAIL_IF (condition , reason ) \
300- do { \
301- if (condition) { \
302- failReason = reason; \
303- goto finish; \
304- } \
305- } while (0)
305+ enum avifProgressiveConfigScannerState
306+ {
307+ AVIF_PROGRESSIVE_SCANNER_STATE_VALUE ,
308+ AVIF_PROGRESSIVE_SCANNER_STATE_COMMA ,
309+ AVIF_PROGRESSIVE_SCANNER_STATE_HYPHEN ,
310+ AVIF_PROGRESSIVE_SCANNER_STATE_COLON ,
311+ AVIF_PROGRESSIVE_SCANNER_STATE_SEMICOLON
312+ };
313+
314+ enum avifProgressiveConfigValueType
315+ {
316+ AVIF_PROGRESSIVE_VALUE_TYPE_NONE ,
317+ AVIF_PROGRESSIVE_VALUE_TYPE_MIN_Q ,
318+ AVIF_PROGRESSIVE_VALUE_TYPE_MAX_Q ,
319+ AVIF_PROGRESSIVE_VALUE_TYPE_H_SCALE ,
320+ AVIF_PROGRESSIVE_VALUE_TYPE_V_SCALE ,
321+ };
306322
307323static avifBool avifParseProgressiveConfig (struct avifEncoderLayerConfig * config , const char * arg )
308324{
309325 uint8_t * currLayerCount = & config -> layerCount ;
310326 avifLayerConfig * currLayers = config -> layers ;
311327 uint8_t currLayer = 0 ;
312- const char * failReason = NULL ;
313-
314- enum scanState
315- {
316- VALUE ,
317- COMMA ,
318- HYPHEN ,
319- COLON ,
320- SEMICOLON
321- };
322- enum scanState currState = * arg == ';' ? SEMICOLON : VALUE ;
323- enum scanState targetState = SEMICOLON ;
324-
325- enum
326- {
327- NONE ,
328- MIN_Q ,
329- MAX_Q ,
330- H_SCALE ,
331- V_SCALE ,
332- } prevReadValue = NONE ;
328+
329+ enum avifProgressiveConfigScannerState currState = * arg == ';' ? AVIF_PROGRESSIVE_SCANNER_STATE_SEMICOLON
330+ : AVIF_PROGRESSIVE_SCANNER_STATE_VALUE ;
331+ enum avifProgressiveConfigScannerState targetState = AVIF_PROGRESSIVE_SCANNER_STATE_SEMICOLON ;
332+
333+ enum avifProgressiveConfigValueType prevReadValue = AVIF_PROGRESSIVE_VALUE_TYPE_NONE ;
333334
334335 for (;;) {
335336 switch (currState ) {
336- case VALUE : {
337+ case AVIF_PROGRESSIVE_SCANNER_STATE_VALUE : {
337338 int64_t value ;
338339 avifScalingMode mode ;
339340 char * end ;
340341 switch (prevReadValue ) {
341- case NONE :
342+ case AVIF_PROGRESSIVE_VALUE_TYPE_NONE :
342343 value = strtoll (arg , & end , 10 );
343- FAIL_IF (errno = = ERANGE , "overflowed while reading min quantizer" );
344- FAIL_IF (end = = arg , "can't parse min quantizer" );
345- FAIL_IF (value > 63 , "min quantizer too big" );
344+ CHECK (errno ! = ERANGE , "overflowed while reading min quantizer" );
345+ CHECK (end ! = arg , "can't parse min quantizer" );
346+ CHECK (value <= 63 , "min quantizer too big" );
346347
347348 arg = end ;
348349 currLayers [currLayer ].minQuantizer = (int )value ;
349- currState = COMMA ;
350- prevReadValue = MIN_Q ;
350+ currState = AVIF_PROGRESSIVE_SCANNER_STATE_COMMA ;
351+ prevReadValue = AVIF_PROGRESSIVE_VALUE_TYPE_MIN_Q ;
351352 break ;
352353
353- case MIN_Q :
354+ case AVIF_PROGRESSIVE_VALUE_TYPE_MIN_Q :
354355 value = strtoll (arg , & end , 10 );
355- FAIL_IF (errno = = ERANGE , "overflowed while reading max quantizer" );
356- FAIL_IF (end = = arg , "can't parse max quantizer" );
357- FAIL_IF (value > 63 , "max quantizer too big" );
356+ CHECK (errno ! = ERANGE , "overflowed while reading max quantizer" );
357+ CHECK (end ! = arg , "can't parse max quantizer" );
358+ CHECK (value <= 63 , "max quantizer too big" );
358359
359360 arg = end ;
360361 currLayers [currLayer ].maxQuantizer = (int )value ;
361- currState = HYPHEN ;
362- prevReadValue = MAX_Q ;
362+ currState = AVIF_PROGRESSIVE_SCANNER_STATE_HYPHEN ;
363+ prevReadValue = AVIF_PROGRESSIVE_VALUE_TYPE_MAX_Q ;
363364 break ;
364365
365- case MAX_Q :
366- FAIL_IF (! avifParseScalingMode (& arg , & mode ), "unknown scaling mode" );
366+ case AVIF_PROGRESSIVE_VALUE_TYPE_MAX_Q :
367+ CHECK ( avifParseScalingMode (& arg , & mode ), "unknown scaling mode" );
367368
368369 currLayers [currLayer ].horizontalMode = mode ;
369- currState = COMMA ;
370- prevReadValue = H_SCALE ;
370+ currState = AVIF_PROGRESSIVE_SCANNER_STATE_COMMA ;
371+ prevReadValue = AVIF_PROGRESSIVE_VALUE_TYPE_H_SCALE ;
371372 break ;
372373
373- case H_SCALE :
374- FAIL_IF (! avifParseScalingMode (& arg , & mode ), "unknown scaling mode" );
374+ case AVIF_PROGRESSIVE_VALUE_TYPE_H_SCALE :
375+ CHECK ( avifParseScalingMode (& arg , & mode ), "unknown scaling mode" );
375376
376377 currLayers [currLayer ].verticalMode = mode ;
377- currState = COLON ;
378- prevReadValue = V_SCALE ;
378+ currState = AVIF_PROGRESSIVE_SCANNER_STATE_COLON ;
379+ prevReadValue = AVIF_PROGRESSIVE_VALUE_TYPE_V_SCALE ;
379380 break ;
380381
381- case V_SCALE :
382- FAIL_IF ( AVIF_TRUE , "too many values in layer config" );
382+ case AVIF_PROGRESSIVE_VALUE_TYPE_V_SCALE :
383+ CHECK ( AVIF_FALSE , "too many values in layer config" );
383384 }
384385 break ;
385386 }
386387
387- case COMMA :
388- case HYPHEN :
389- case COLON :
390- case SEMICOLON :
388+ case AVIF_PROGRESSIVE_SCANNER_STATE_COMMA :
389+ case AVIF_PROGRESSIVE_SCANNER_STATE_HYPHEN :
390+ case AVIF_PROGRESSIVE_SCANNER_STATE_COLON :
391+ case AVIF_PROGRESSIVE_SCANNER_STATE_SEMICOLON :
391392 switch (* arg ) {
392393 case ',' :
393- targetState = COMMA ;
394+ targetState = AVIF_PROGRESSIVE_SCANNER_STATE_COMMA ;
394395 break ;
395396 case '-' :
396- targetState = HYPHEN ;
397+ targetState = AVIF_PROGRESSIVE_SCANNER_STATE_HYPHEN ;
397398 break ;
398399 case ':' :
399- targetState = COLON ;
400+ targetState = AVIF_PROGRESSIVE_SCANNER_STATE_COLON ;
400401 break ;
401402 case ';' :
402403 case '\0' :
403- targetState = SEMICOLON ;
404+ targetState = AVIF_PROGRESSIVE_SCANNER_STATE_SEMICOLON ;
404405 break ;
405406 default :
406- FAIL_IF ( AVIF_TRUE , "unexpected separator" );
407+ CHECK ( AVIF_FALSE , "unexpected separator" );
407408 }
408409
409- FAIL_IF (currState > targetState , "too many config entries" );
410+ CHECK (currState <= targetState , "too many config entries" );
410411
411412 avifBool earlyEnd = currState < targetState ;
412413 switch (targetState ) {
413- case VALUE :
414- FAIL_IF ( AVIF_TRUE , "unknown state" );
414+ case AVIF_PROGRESSIVE_SCANNER_STATE_VALUE :
415+ CHECK ( AVIF_FALSE , "unknown state" );
415416 break ;
416417
417- case COMMA :
418- FAIL_IF ( earlyEnd , "unknown state" );
418+ case AVIF_PROGRESSIVE_SCANNER_STATE_COMMA :
419+ CHECK (! earlyEnd , "unknown state" );
419420 break ;
420421
421- case HYPHEN :
422+ case AVIF_PROGRESSIVE_SCANNER_STATE_HYPHEN :
422423 if (!earlyEnd ) {
423- FAIL_IF (prevReadValue != MAX_Q , "unknown state" );
424+ CHECK (prevReadValue == AVIF_PROGRESSIVE_VALUE_TYPE_MAX_Q , "unknown state" );
424425 break ;
425426 }
426427
427- FAIL_IF (prevReadValue != MIN_Q , "unknown state" );
428+ CHECK (prevReadValue == AVIF_PROGRESSIVE_VALUE_TYPE_MIN_Q , "unknown state" );
428429 currLayers [currLayer ].maxQuantizer = currLayers [currLayer ].minQuantizer ;
429- prevReadValue = MAX_Q ;
430+ prevReadValue = AVIF_PROGRESSIVE_VALUE_TYPE_MAX_Q ;
430431 break ;
431432
432- case COLON :
433+ case AVIF_PROGRESSIVE_SCANNER_STATE_COLON :
433434 if (earlyEnd ) {
434435 switch (prevReadValue ) {
435- case MIN_Q :
436+ case AVIF_PROGRESSIVE_VALUE_TYPE_MIN_Q :
436437 currLayers [currLayer ].maxQuantizer = currLayers [currLayer ].minQuantizer ;
437- currLayers [currLayer ].horizontalMode = AVIF_SCALING_NORMAL ;
438- currLayers [currLayer ].verticalMode = AVIF_SCALING_NORMAL ;
438+ currLayers [currLayer ].horizontalMode = avifScalingModeNormal ;
439+ currLayers [currLayer ].verticalMode = avifScalingModeNormal ;
439440 break ;
440441
441- case MAX_Q :
442- currLayers [currLayer ].horizontalMode = AVIF_SCALING_NORMAL ;
443- currLayers [currLayer ].verticalMode = AVIF_SCALING_NORMAL ;
442+ case AVIF_PROGRESSIVE_VALUE_TYPE_MAX_Q :
443+ currLayers [currLayer ].horizontalMode = avifScalingModeNormal ;
444+ currLayers [currLayer ].verticalMode = avifScalingModeNormal ;
444445 break ;
445446
446- case H_SCALE :
447- currLayers [currLayer ].verticalMode = AVIF_SCALING_NORMAL ;
447+ case AVIF_PROGRESSIVE_VALUE_TYPE_H_SCALE :
448+ currLayers [currLayer ].verticalMode = currLayers [ currLayer ]. horizontalMode ;
448449 break ;
449450
450- case V_SCALE :
451- case NONE :
452- FAIL_IF ( AVIF_TRUE , "unknown state" );
451+ case AVIF_PROGRESSIVE_VALUE_TYPE_V_SCALE :
452+ case AVIF_PROGRESSIVE_VALUE_TYPE_NONE :
453+ CHECK ( AVIF_FALSE , "unknown state" );
453454 }
454455 }
455456
456457 ++ currLayer ;
457- FAIL_IF (currLayer >= MAX_AV1_LAYER_COUNT , "too many layers" );
458- prevReadValue = NONE ;
458+ CHECK (currLayer < MAX_AV1_LAYER_COUNT , "too many layers" );
459+ prevReadValue = AVIF_PROGRESSIVE_VALUE_TYPE_NONE ;
459460 break ;
460461
461- case SEMICOLON :
462+ case AVIF_PROGRESSIVE_SCANNER_STATE_SEMICOLON :
462463 if (earlyEnd ) {
463464 switch (prevReadValue ) {
464- case MIN_Q :
465+ case AVIF_PROGRESSIVE_VALUE_TYPE_MIN_Q :
465466 currLayers [currLayer ].maxQuantizer = currLayers [currLayer ].minQuantizer ;
466- currLayers [currLayer ].horizontalMode = AVIF_SCALING_NORMAL ;
467- currLayers [currLayer ].verticalMode = AVIF_SCALING_NORMAL ;
467+ currLayers [currLayer ].horizontalMode = avifScalingModeNormal ;
468+ currLayers [currLayer ].verticalMode = avifScalingModeNormal ;
468469 break ;
469470
470- case MAX_Q :
471- currLayers [currLayer ].horizontalMode = AVIF_SCALING_NORMAL ;
472- currLayers [currLayer ].verticalMode = AVIF_SCALING_NORMAL ;
471+ case AVIF_PROGRESSIVE_VALUE_TYPE_MAX_Q :
472+ currLayers [currLayer ].horizontalMode = avifScalingModeNormal ;
473+ currLayers [currLayer ].verticalMode = avifScalingModeNormal ;
473474 break ;
474475
475- case H_SCALE :
476- currLayers [currLayer ].verticalMode = AVIF_SCALING_NORMAL ;
476+ case AVIF_PROGRESSIVE_VALUE_TYPE_H_SCALE :
477+ currLayers [currLayer ].verticalMode = currLayers [ currLayer ]. horizontalMode ;
477478 break ;
478479
479- case V_SCALE :
480+ case AVIF_PROGRESSIVE_VALUE_TYPE_V_SCALE :
480481 break ;
481482
482- case NONE :
483- FAIL_IF ( AVIF_TRUE , "unknown state" );
483+ case AVIF_PROGRESSIVE_VALUE_TYPE_NONE :
484+ CHECK ( AVIF_FALSE , "unknown state" );
484485 }
485486
486487 ++ currLayer ;
487488 }
488489
489490 * currLayerCount = currLayer ;
490491 if (* arg == ';' ) {
491- FAIL_IF (currLayers ! = config -> layers , "too many sub image configurations" );
492+ CHECK (currLayers = = config -> layers , "too many sub image configurations" );
492493 currLayers = config -> layersAlpha ;
493494 currLayerCount = & config -> layerCountAlpha ;
494495
495496 if (* (arg + 1 ) == '\0' ) {
496497 goto finish ;
497498 }
498499
499- prevReadValue = NONE ;
500+ prevReadValue = AVIF_PROGRESSIVE_VALUE_TYPE_NONE ;
500501 currLayer = 0 ;
501502 } else {
502503 // reached \0
@@ -511,18 +512,13 @@ static avifBool avifParseProgressiveConfig(struct avifEncoderLayerConfig * confi
511512 }
512513
513514 ++ arg ;
514- currState = VALUE ;
515+ currState = AVIF_PROGRESSIVE_SCANNER_STATE_VALUE ;
515516 break ;
516517 }
517518 }
518519
519520finish :
520- if (failReason == NULL ) {
521- return AVIF_TRUE ;
522- }
523-
524- fprintf (stderr , "ERROR: Failed reading progressive config: %s" , failReason );
525- return AVIF_FALSE ;
521+ return AVIF_TRUE ;
526522}
527523
528524static avifInputFile * avifInputGetNextFile (avifInput * input )
0 commit comments