comparison tools/gfxconv.c @ 2565:d56a0e86067a

Improve error handling.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 28 Feb 2022 11:49:58 +0200
parents acaf678a2129
children d75431bf1a7d
comparison
equal deleted inserted replaced
2564:2cf4e995b50c 2565:d56a0e86067a
2572 DMConvFormat inFormat, outFormat; 2572 DMConvFormat inFormat, outFormat;
2573 DMC64Image *inC64Image = NULL, *outC64Image = NULL; 2573 DMC64Image *inC64Image = NULL, *outC64Image = NULL;
2574 DMImage *inImage = NULL, *outImage = NULL; 2574 DMImage *inImage = NULL, *outImage = NULL;
2575 Uint8 *dataBuf = NULL, *dataBufOrig = NULL; 2575 Uint8 *dataBuf = NULL, *dataBufOrig = NULL;
2576 size_t dataSize, dataSizeOrig, dataRealOffs; 2576 size_t dataSize, dataSizeOrig, dataRealOffs;
2577 int i, n, res; 2577 int i, n, res = DMERR_OK;
2578 2578
2579 // Default color mapping 2579 // Default color mapping
2580 for (i = 0; i < D64_NCOLORS; i++) 2580 for (i = 0; i < D64_NCOLORS; i++)
2581 optColorMap[i] = i; 2581 optColorMap[i] = i;
2582 2582
2586 // Initialize list of additional conversion formats 2586 // Initialize list of additional conversion formats
2587 if ((res = dmLib64GFXInit()) != DMERR_OK) 2587 if ((res = dmLib64GFXInit()) != DMERR_OK)
2588 { 2588 {
2589 dmErrorMsg("Could not initialize lib64gfx: %s\n", 2589 dmErrorMsg("Could not initialize lib64gfx: %s\n",
2590 dmErrorStr(res)); 2590 dmErrorStr(res));
2591 goto exit; 2591 goto out;
2592 } 2592 }
2593 2593
2594 nconvFormatList = ndmImageFormatList + ndmPaletteFormatList + nbaseFormatList; 2594 nconvFormatList = ndmImageFormatList + ndmPaletteFormatList + nbaseFormatList;
2595 convFormatList = dmCalloc(nconvFormatList, sizeof(DMConvFormat)); 2595 convFormatList = dmCalloc(nconvFormatList, sizeof(DMConvFormat));
2596 2596
2623 // Initialize and parse commandline 2623 // Initialize and parse commandline
2624 dmInitProg("gfxconv", "Simple graphics converter", "0.95", NULL, NULL); 2624 dmInitProg("gfxconv", "Simple graphics converter", "0.95", NULL, NULL);
2625 2625
2626 if (!dmArgsProcess(argc, argv, optList, optListN, 2626 if (!dmArgsProcess(argc, argv, optList, optListN,
2627 argHandleOpt, argHandleFile, OPTH_BAILOUT)) 2627 argHandleOpt, argHandleFile, OPTH_BAILOUT))
2628 exit(1); 2628 goto out;
2629 2629
2630 switch (optShowHelp) 2630 switch (optShowHelp)
2631 { 2631 {
2632 case 1: 2632 case 1:
2633 argShowHelp(); 2633 argShowHelp();
2634 exit(0); 2634 goto out;
2635 break;
2636 2635
2637 case 2: 2636 case 2:
2638 argShowHelp(); 2637 argShowHelp();
2639 argShowFormats(); 2638 argShowFormats();
2640 argShowC64Formats(stdout, TRUE, TRUE); 2639 argShowC64Formats(stdout, TRUE, TRUE);
2644 { 2643 {
2645 const char *str = argGetHelpTopic(optList[n].id); 2644 const char *str = argGetHelpTopic(optList[n].id);
2646 if (str != NULL) 2645 if (str != NULL)
2647 fprintf(stdout, "\n%s\n", str); 2646 fprintf(stdout, "\n%s\n", str);
2648 } 2647 }
2649 exit(0); 2648 goto out;
2650 break;
2651 2649
2652 case 3: 2650 case 3:
2653 argShowFormats(); 2651 argShowFormats();
2654 argShowC64Formats(stdout, TRUE, dmVerbosity > 0); 2652 argShowC64Formats(stdout, TRUE, dmVerbosity > 0);
2655 exit(0); 2653 goto out;
2656 break;
2657 } 2654 }
2658 2655
2659 // Determine input format, if not specified 2656 // Determine input format, if not specified
2660 if (optInType == FFMT_AUTO && optInFilename != NULL) 2657 if (optInType == FFMT_AUTO && optInFilename != NULL)
2661 { 2658 {
2675 { 2672 {
2676 if (optInType == FFMT_AUTO) 2673 if (optInType == FFMT_AUTO)
2677 { 2674 {
2678 dmErrorMsg("Standard input cannot be used without specifying input format.\n"); 2675 dmErrorMsg("Standard input cannot be used without specifying input format.\n");
2679 dmErrorMsg("Perhaps you should try --help or --longhelp\n"); 2676 dmErrorMsg("Perhaps you should try --help or --longhelp\n");
2680 goto exit; 2677 goto out;
2681 } 2678 }
2682 inFile = stdin; 2679 inFile = stdin;
2683 optInFilename = "stdin"; 2680 optInFilename = "stdin";
2684 } 2681 }
2685 else 2682 else
2686 if ((inFile = fopen(optInFilename, "rb")) == NULL) 2683 if ((inFile = fopen(optInFilename, "rb")) == NULL)
2687 { 2684 {
2688 res = dmGetErrno(); 2685 res = dmGetErrno();
2689 dmErrorMsg("Error opening input file '%s': %s\n", 2686 dmErrorMsg("Error opening input file '%s': %s\n",
2690 optInFilename, dmErrorStr(res)); 2687 optInFilename, dmErrorStr(res));
2691 goto exit; 2688 goto out;
2692 } 2689 }
2693 2690
2694 // Determine output format, if not specified 2691 // Determine output format, if not specified
2695 if (optOutType == FFMT_AUTO && optOutFilename != NULL) 2692 if (optOutType == FFMT_AUTO && optOutFilename != NULL)
2696 { 2693 {
2713 dmMsg(1, "Reading input from '%s'.\n", optInFilename); 2710 dmMsg(1, "Reading input from '%s'.\n", optInFilename);
2714 2711
2715 if ((res = dmReadDataFile(inFile, NULL, &dataBufOrig, &dataSizeOrig)) != DMERR_OK) 2712 if ((res = dmReadDataFile(inFile, NULL, &dataBufOrig, &dataSizeOrig)) != DMERR_OK)
2716 { 2713 {
2717 dmErrorMsg("Could not read input: %s.\n", dmErrorStr(res)); 2714 dmErrorMsg("Could not read input: %s.\n", dmErrorStr(res));
2718 goto exit; 2715 goto out;
2719 } 2716 }
2720 2717
2721 fclose(inFile); 2718 fclose(inFile);
2722 2719
2723 // Check and compute the input skip 2720 // Check and compute the input skip
2724 if (optInSkip > dataSizeOrig) 2721 if (optInSkip > dataSizeOrig)
2725 { 2722 {
2726 dmErrorMsg("Input skip value %d (0x%x) is larger than input size %" DM_PRIu_SIZE_T ".\n", 2723 dmErrorMsg("Input skip value %d (0x%x) is larger than input size %" DM_PRIu_SIZE_T ".\n",
2727 optInSkip, optInSkip, dataSizeOrig); 2724 optInSkip, optInSkip, dataSizeOrig);
2728 goto exit; 2725 goto out;
2729 } 2726 }
2730 2727
2731 if (optInSkipNeg) 2728 if (optInSkipNeg)
2732 { 2729 {
2733 dataBuf = dataBufOrig + dataSizeOrig - optInSkip; 2730 dataBuf = dataBufOrig + dataSizeOrig - optInSkip;
2785 } 2782 }
2786 else 2783 else
2787 if (res != DMERR_OK && (forced != NULL || optInType == FFMT_BITMAP)) 2784 if (res != DMERR_OK && (forced != NULL || optInType == FFMT_BITMAP))
2788 { 2785 {
2789 dmErrorMsg("Could not decode input image: %s.\n", dmErrorStr(res)); 2786 dmErrorMsg("Could not decode input image: %s.\n", dmErrorStr(res));
2790 goto exit; 2787 goto out;
2791 } 2788 }
2792 } 2789 }
2793 2790
2794 if (optInType == FFMT_AUTO || optInType == FFMT_IMAGE) 2791 if (optInType == FFMT_AUTO || optInType == FFMT_IMAGE)
2795 { 2792 {
2820 } 2817 }
2821 2818
2822 if (optInType == FFMT_AUTO) 2819 if (optInType == FFMT_AUTO)
2823 { 2820 {
2824 dmErrorMsg("No input format specified, and could not be determined automatically.\n"); 2821 dmErrorMsg("No input format specified, and could not be determined automatically.\n");
2825 goto exit; 2822 goto out;
2826 } 2823 }
2827 2824
2828 if (dmGetConvFormat(optInType, optInFormat, &inFormat) && 2825 if (dmGetConvFormat(optInType, optInFormat, &inFormat) &&
2829 dmGetConvFormat(optOutType, optOutFormat, &outFormat)) 2826 dmGetConvFormat(optOutType, optOutFormat, &outFormat))
2830 { 2827 {
2862 } 2859 }
2863 2860
2864 // Handle palette stuff that is generic for different operation modes 2861 // Handle palette stuff that is generic for different operation modes
2865 if (optPaletteFile != NULL && 2862 if (optPaletteFile != NULL &&
2866 (res = dmHandleExternalPalette(optPaletteFile, &optPaletteData)) != DMERR_OK) 2863 (res = dmHandleExternalPalette(optPaletteFile, &optPaletteData)) != DMERR_OK)
2867 goto exit; 2864 goto out;
2868 2865
2869 switch (optInType) 2866 switch (optInType)
2870 { 2867 {
2871 case FFMT_SPRITE: 2868 case FFMT_SPRITE:
2872 case FFMT_CHAR: 2869 case FFMT_CHAR:
2882 2879
2883 if ((res = dmC64PaletteFromC64Palette(&optPaletteData, optC64Palette, FALSE)) != DMERR_OK) 2880 if ((res = dmC64PaletteFromC64Palette(&optPaletteData, optC64Palette, FALSE)) != DMERR_OK)
2884 { 2881 {
2885 dmErrorMsg("Could not set up palette: %s.\n", 2882 dmErrorMsg("Could not set up palette: %s.\n",
2886 dmErrorStr(res)); 2883 dmErrorStr(res));
2887 goto exit; 2884 goto out;
2888 } 2885 }
2889 } 2886 }
2890 2887
2891 if (optPaletteData->ncolors < D64_NCOLORS) 2888 if (optPaletteData->ncolors < D64_NCOLORS)
2892 { 2889 {
2893 dmErrorMsg("Palette does not have enough colors (%d < %d)\n", 2890 dmErrorMsg("Palette does not have enough colors (%d < %d)\n",
2894 optPaletteData->ncolors, D64_NCOLORS); 2891 optPaletteData->ncolors, D64_NCOLORS);
2895 goto exit; 2892 goto out;
2896 } 2893 }
2897 2894
2898 if (optPaletteData->ncolors > D64_NCOLORS) 2895 if (optPaletteData->ncolors > D64_NCOLORS)
2899 { 2896 {
2900 dmMsg(1, "Palette has %d colors, using only first %d.\n", 2897 dmMsg(1, "Palette has %d colors, using only first %d.\n",
2912 2909
2913 if ((res = dmC64PaletteFromC64Palette(&optPaletteData, optC64Palette, FALSE)) != DMERR_OK) 2910 if ((res = dmC64PaletteFromC64Palette(&optPaletteData, optC64Palette, FALSE)) != DMERR_OK)
2914 { 2911 {
2915 dmErrorMsg("Could not set up palette: %s.\n", 2912 dmErrorMsg("Could not set up palette: %s.\n",
2916 dmErrorStr(res)); 2913 dmErrorStr(res));
2917 goto exit; 2914 goto out;
2918 } 2915 }
2919 } 2916 }
2920 } 2917 }
2921 2918
2922 switch (optInType) 2919 switch (optInType)
2932 DMResource *fp; 2929 DMResource *fp;
2933 2930
2934 if (optOutFilename == NULL) 2931 if (optOutFilename == NULL)
2935 { 2932 {
2936 dmErrorMsg("Output filename not set, required for palette formats.\n"); 2933 dmErrorMsg("Output filename not set, required for palette formats.\n");
2937 goto exit; 2934 goto out;
2938 } 2935 }
2939 2936
2940 // Read palette file 2937 // Read palette file
2941 if ((res = dmf_open_memio(NULL, optInFilename, dataBuf, dataSize, &fp)) != DMERR_OK) 2938 if ((res = dmf_open_memio(NULL, optInFilename, dataBuf, dataSize, &fp)) != DMERR_OK)
2942 { 2939 {
2943 dmErrorMsg("Could not create MemIO handle for input.\n"); 2940 dmErrorMsg("Could not create MemIO handle for input.\n");
2944 goto exit; 2941 goto out;
2945 } 2942 }
2946 2943
2947 // Read input 2944 // Read input
2948 if (pfmt->read != NULL) 2945 if (pfmt->read != NULL)
2949 res = pfmt->read(fp, &optPaletteData); 2946 res = pfmt->read(fp, &optPaletteData);
2953 dmf_close(fp); 2950 dmf_close(fp);
2954 2951
2955 if (res != DMERR_OK) 2952 if (res != DMERR_OK)
2956 { 2953 {
2957 dmErrorMsg("Palette could not be read.\n"); 2954 dmErrorMsg("Palette could not be read.\n");
2958 goto exit; 2955 goto out;
2959 } 2956 }
2960 } 2957 }
2961 2958
2962 if (optPaletteData == NULL) 2959 if (optPaletteData == NULL)
2963 goto exit; 2960 goto out;
2964 2961
2965 switch (optOutType) 2962 switch (optOutType)
2966 { 2963 {
2967 case FFMT_PALETTE: 2964 case FFMT_PALETTE:
2968 res = dmWritePalette(optOutFilename, optPaletteData, &dmPaletteFormatList[optOutFormat]); 2965 res = dmWritePalette(optOutFilename, optPaletteData, &dmPaletteFormatList[optOutFormat]);
2973 if ((inImage = dmImageAlloc(16, 16, DM_PIXFMT_PALETTE, 2970 if ((inImage = dmImageAlloc(16, 16, DM_PIXFMT_PALETTE,
2974 dmGetNPlanesFromNColors(optPaletteData->ncolors))) == NULL) 2971 dmGetNPlanesFromNColors(optPaletteData->ncolors))) == NULL)
2975 { 2972 {
2976 res = dmError(DMERR_MALLOC, 2973 res = dmError(DMERR_MALLOC,
2977 "Could not allocate memory for image.\n"); 2974 "Could not allocate memory for image.\n");
2978 goto exit; 2975 goto out;
2979 } 2976 }
2980 2977
2981 if ((res = dmPaletteCopy(&inImage->pal, optPaletteData)) != DMERR_OK) 2978 if ((res = dmPaletteCopy(&inImage->pal, optPaletteData)) != DMERR_OK)
2982 { 2979 {
2983 dmErrorMsg("Could not allocate image palette: %s\n", 2980 dmErrorMsg("Could not allocate image palette: %s\n",
2984 dmErrorStr(res)); 2981 dmErrorStr(res));
2985 goto exit; 2982 goto out;
2986 } 2983 }
2987 2984
2988 res = dmWriteImage(optOutFilename, inImage, &optSpec, 2985 res = dmWriteImage(optOutFilename, inImage, &optSpec,
2989 &dmImageFormatList[optOutFormat]); 2986 &dmImageFormatList[optOutFormat]);
2990 break; 2987 break;
2997 2994
2998 case FFMT_BITMAP: 2995 case FFMT_BITMAP:
2999 if (optOutFilename == NULL) 2996 if (optOutFilename == NULL)
3000 { 2997 {
3001 dmErrorMsg("Output filename not set, required for bitmap formats.\n"); 2998 dmErrorMsg("Output filename not set, required for bitmap formats.\n");
3002 goto exit; 2999 goto out;
3003 } 3000 }
3004 3001
3005 switch (optOutType) 3002 switch (optOutType)
3006 { 3003 {
3007 case FFMT_IMAGE: 3004 case FFMT_IMAGE:
3023 &inC64Image->charData[0].data, 3020 &inC64Image->charData[0].data,
3024 &inC64Image->charData[0].size)) != DMERR_OK) 3021 &inC64Image->charData[0].size)) != DMERR_OK)
3025 { 3022 {
3026 dmErrorMsg("Could not read character ROM from '%s'.\n", 3023 dmErrorMsg("Could not read character ROM from '%s'.\n",
3027 optCharROMFilename); 3024 optCharROMFilename);
3028 goto exit; 3025 goto out;
3029 } 3026 }
3030 } 3027 }
3031 3028
3032 // Convert the image 3029 // Convert the image
3033 res = dmC64ConvertBMP2Image(&outImage, inC64Image, &optC64Spec); 3030 res = dmC64ConvertBMP2Image(&outImage, inC64Image, &optC64Spec);
3034 3031
3035 if (res != DMERR_OK || outImage == NULL) 3032 if (res != DMERR_OK || outImage == NULL)
3036 { 3033 {
3037 dmErrorMsg("Error in bitmap to image conversion: %s.\n", 3034 dmErrorMsg("Error in bitmap to image conversion: %s.\n",
3038 dmErrorStr(res)); 3035 dmErrorStr(res));
3039 goto exit; 3036 goto out;
3040 } 3037 }
3041 3038
3042 switch (optOutType) 3039 switch (optOutType)
3043 { 3040 {
3044 case FFMT_IMAGE: 3041 case FFMT_IMAGE:
3065 case FFMT_BITMAP: 3062 case FFMT_BITMAP:
3066 if ((res = dmConvertC64Bitmap(&outC64Image, inC64Image, 3063 if ((res = dmConvertC64Bitmap(&outC64Image, inC64Image,
3067 &dmC64ImageFormats[optOutFormat], inC64Fmt)) != DMERR_OK) 3064 &dmC64ImageFormats[optOutFormat], inC64Fmt)) != DMERR_OK)
3068 { 3065 {
3069 dmErrorMsg("Error in bitmap format conversion.\n"); 3066 dmErrorMsg("Error in bitmap format conversion.\n");
3070 goto exit; 3067 goto out;
3071 } 3068 }
3072 if (dmVerbosity >= 2) 3069 if (dmVerbosity >= 2)
3073 { 3070 {
3074 dmPrint(0, "INPUT:\n"); dmC64ImageDump(stderr, inC64Image, inC64Fmt, " "); 3071 dmPrint(0, "INPUT:\n"); dmC64ImageDump(stderr, inC64Image, inC64Fmt, " ");
3075 dmPrint(0, "OUTPUT:\n"); dmC64ImageDump(stderr, outC64Image, &dmC64ImageFormats[optOutFormat], " "); 3072 dmPrint(0, "OUTPUT:\n"); dmC64ImageDump(stderr, outC64Image, &dmC64ImageFormats[optOutFormat], " ");
3089 DMResource *fp; 3086 DMResource *fp;
3090 3087
3091 if (optOutFilename == NULL) 3088 if (optOutFilename == NULL)
3092 { 3089 {
3093 dmErrorMsg("Output filename not set, required for image formats.\n"); 3090 dmErrorMsg("Output filename not set, required for image formats.\n");
3094 goto exit; 3091 goto out;
3095 } 3092 }
3096 3093
3097 if ((res = dmf_open_memio(NULL, optInFilename, dataBuf, dataSize, &fp)) != DMERR_OK) 3094 if ((res = dmf_open_memio(NULL, optInFilename, dataBuf, dataSize, &fp)) != DMERR_OK)
3098 { 3095 {
3099 dmErrorMsg("Could not create MemIO handle for input.\n"); 3096 dmErrorMsg("Could not create MemIO handle for input.\n");
3100 goto exit; 3097 goto out;
3101 } 3098 }
3102 3099
3103 // Read input 3100 // Read input
3104 if (ifmt->read != NULL) 3101 if (ifmt->read != NULL)
3105 res = ifmt->read(fp, &inImage); 3102 res = ifmt->read(fp, &inImage);
3107 dmErrorMsg("Unsupported input image format for image conversion.\n"); 3104 dmErrorMsg("Unsupported input image format for image conversion.\n");
3108 3105
3109 dmf_close(fp); 3106 dmf_close(fp);
3110 3107
3111 if (res != DMERR_OK || inImage == NULL) 3108 if (res != DMERR_OK || inImage == NULL)
3112 goto exit; 3109 goto out;
3113 3110
3114 switch (optOutType) 3111 switch (optOutType)
3115 { 3112 {
3116 case FFMT_IMAGE: 3113 case FFMT_IMAGE:
3117 res = dmWriteImage(optOutFilename, inImage, &optSpec, 3114 res = dmWriteImage(optOutFilename, inImage, &optSpec,
3120 3117
3121 case FFMT_PALETTE: 3118 case FFMT_PALETTE:
3122 if (inImage->pal == NULL || inImage->pixfmt != DM_PIXFMT_PALETTE) 3119 if (inImage->pal == NULL || inImage->pixfmt != DM_PIXFMT_PALETTE)
3123 { 3120 {
3124 dmErrorMsg("Source image is not a paletted format or has no palette.\n"); 3121 dmErrorMsg("Source image is not a paletted format or has no palette.\n");
3125 goto exit; 3122 goto out;
3126 } 3123 }
3127 res = dmWritePalette(optOutFilename, inImage->pal, &dmPaletteFormatList[optOutFormat]); 3124 res = dmWritePalette(optOutFilename, inImage->pal, &dmPaletteFormatList[optOutFormat]);
3128 break; 3125 break;
3129 3126
3130 case FFMT_CHAR: 3127 case FFMT_CHAR:
3142 if (res != DMERR_OK || tmpC64Image == NULL) 3139 if (res != DMERR_OK || tmpC64Image == NULL)
3143 { 3140 {
3144 dmC64ImageFree(tmpC64Image); 3141 dmC64ImageFree(tmpC64Image);
3145 dmErrorMsg("Error in image to bitmap conversion: %s.\n", 3142 dmErrorMsg("Error in image to bitmap conversion: %s.\n",
3146 dmErrorStr(res)); 3143 dmErrorStr(res));
3147 goto exit; 3144 goto out;
3148 } 3145 }
3149 3146
3150 if ((res = dmConvertC64Bitmap(&outC64Image, tmpC64Image, 3147 if ((res = dmConvertC64Bitmap(&outC64Image, tmpC64Image,
3151 &dmC64ImageFormats[optOutFormat], &dmC64ImageFormats[optOutFormat])) != DMERR_OK) 3148 &dmC64ImageFormats[optOutFormat], &dmC64ImageFormats[optOutFormat])) != DMERR_OK)
3152 { 3149 {
3153 dmC64ImageFree(tmpC64Image); 3150 dmC64ImageFree(tmpC64Image);
3154 dmErrorMsg("Error in bitmap format conversion: %s.\n", 3151 dmErrorMsg("Error in bitmap format conversion: %s.\n",
3155 dmErrorStr(res)); 3152 dmErrorStr(res));
3156 goto exit; 3153 goto out;
3157 } 3154 }
3158 3155
3159 res = dmWriteBitmap(optOutFilename, outC64Image, &dmC64ImageFormats[optOutFormat]); 3156 res = dmWriteBitmap(optOutFilename, outC64Image, &dmC64ImageFormats[optOutFormat]);
3160 dmC64ImageFree(tmpC64Image); 3157 dmC64ImageFree(tmpC64Image);
3161 } 3158 }
3173 { 3170 {
3174 dmErrorMsg("Error writing output data: %s\n", 3171 dmErrorMsg("Error writing output data: %s\n",
3175 dmErrorStr(res)); 3172 dmErrorStr(res));
3176 } 3173 }
3177 3174
3178 exit: 3175 out:
3179 // Cleanup 3176 // Cleanup
3180 dmFree(convFormatList); 3177 dmFree(convFormatList);
3181 dmFree(dataBufOrig); 3178 dmFree(dataBufOrig);
3182 dmPaletteFree(optPaletteData); 3179 dmPaletteFree(optPaletteData);
3183 dmC64ImageFree(inC64Image); 3180 dmC64ImageFree(inC64Image);
3184 dmC64ImageFree(outC64Image); 3181 dmC64ImageFree(outC64Image);
3185 dmImageFree(inImage); 3182 dmImageFree(inImage);
3186 dmImageFree(outImage); 3183 dmImageFree(outImage);
3187 dmLib64GFXClose(); 3184 dmLib64GFXClose();
3188 3185
3189 return 0; 3186 return res;
3190 } 3187 }