Image Interpolation with Contour Stencils
|
00001 00016 #include <math.h> 00017 #include <string.h> 00018 #include <ctype.h> 00019 #include "nninterp.h" 00020 00021 #define VERBOSE 0 00022 00023 00025 typedef struct 00026 { 00028 uint32_t *Data; 00030 int Width; 00032 int Height; 00033 } image; 00034 00035 00037 typedef struct 00038 { 00040 char *InputFile; 00042 char *OutputFile; 00044 int JpegQuality; 00046 int CenteredGrid; 00048 float ScaleFactor; 00049 } programparams; 00050 00051 00052 int ParseParams(programparams *Param, int argc, char *argv[]); 00053 00054 00056 void PrintHelpMessage() 00057 { 00058 printf("Nearest neighbor interpolation utility, P. Getreuer 2011\n\n"); 00059 printf("Usage: nninterp [options] <input file> <output file>\n\n" 00060 "Only " READIMAGE_FORMATS_SUPPORTED " images are supported.\n\n"); 00061 printf("Options:\n"); 00062 printf(" -x <number> the interpolation factor\n"); 00063 printf(" -g <grid> grid to use for resampling, choices for <grid> are\n" 00064 " centered grid with centered alignment (default)\n" 00065 " topleft the top-left anchored grid\n\n"); 00066 #ifdef LIBJPEG_SUPPORT 00067 printf(" -q <number> quality for saving JPEG images (0 to 100)\n\n"); 00068 #endif 00069 printf("Example: interpolate by factor 2.5\n" 00070 " nninterp -x 2.5 frog.bmp coarse.bmp\n"); 00071 } 00072 00073 00074 int main(int argc, char *argv[]) 00075 { 00076 programparams Param; 00077 image u = {NULL, 0, 0}, v = {NULL, 0, 0}; 00078 int Status = 1; 00079 00080 00081 if(!ParseParams(&Param, argc, argv)) 00082 return 0; 00083 00084 /* Read the input image */ 00085 if(!(v.Data = (uint32_t *)ReadImage(&v.Width, &v.Height, Param.InputFile, 00086 IMAGEIO_U8 | IMAGEIO_RGBA))) 00087 goto Catch; 00088 00089 /* Allocate the output image */ 00090 u.Width = (int)ceil(v.Width * Param.ScaleFactor); 00091 u.Height = (int)ceil(v.Height * Param.ScaleFactor); 00092 #if VERBOSE > 0 00093 printf("%dx%d input --> %dx%d output\n", v.Width, v.Height, u.Width, u.Height); 00094 #endif 00095 00096 if(!(u.Data = (uint32_t *)Malloc(sizeof(uint32_t)* 00097 ((long int)u.Width)*((long int)u.Height)))) 00098 { 00099 fprintf(stderr, "Memory allocation failed.\n"); 00100 goto Catch; 00101 } 00102 00103 NearestInterp(u.Data, u.Width, u.Height, 00104 v.Data, v.Width, v.Height, 00105 Param.ScaleFactor, Param.CenteredGrid); 00106 00107 /* Write the output image */ 00108 if(!WriteImage(u.Data, u.Width, u.Height, Param.OutputFile, 00109 IMAGEIO_U8 | IMAGEIO_RGBA, Param.JpegQuality)) 00110 goto Catch; 00111 #if VERBOSE > 0 00112 else 00113 printf("Output written to \"%s\".\n", Param.OutputFile); 00114 #endif 00115 00116 Status = 0; /* Finished successfully, set exit status to zero. */ 00117 Catch: 00118 Free(u.Data); 00119 Free(v.Data); 00120 return Status; 00121 } 00122 00123 00124 int ParseParams(programparams *Param, int argc, char *argv[]) 00125 { 00126 static char *DefaultOutputFile = (char *)"out.bmp"; 00127 char *OptionString; 00128 char OptionChar; 00129 int i; 00130 00131 00132 if(argc < 2) 00133 { 00134 PrintHelpMessage(); 00135 return 0; 00136 } 00137 00138 /* Set parameter defaults */ 00139 Param->InputFile = 0; 00140 Param->OutputFile = DefaultOutputFile; 00141 Param->JpegQuality = 99; 00142 Param->ScaleFactor = 1; 00143 Param->CenteredGrid = 1; 00144 00145 for(i = 1; i < argc;) 00146 { 00147 if(argv[i] && argv[i][0] == '-') 00148 { 00149 if((OptionChar = argv[i][1]) == 0) 00150 { 00151 ErrorMessage("Invalid parameter format.\n"); 00152 return 0; 00153 } 00154 00155 if(argv[i][2]) 00156 OptionString = &argv[i][2]; 00157 else if(++i < argc) 00158 OptionString = argv[i]; 00159 else 00160 { 00161 ErrorMessage("Invalid parameter format.\n"); 00162 return 0; 00163 } 00164 00165 switch(OptionChar) 00166 { 00167 case 'x': 00168 Param->ScaleFactor = (float)atof(OptionString); 00169 00170 if(Param->ScaleFactor < 0) 00171 { 00172 ErrorMessage("Invalid scale factor.\n"); 00173 return 0; 00174 } 00175 break; 00176 case 'g': 00177 if(!strcmp(OptionString, "centered") 00178 || !strcmp(OptionString, "center")) 00179 Param->CenteredGrid = 1; 00180 else if(!strcmp(OptionString, "topleft") 00181 || !strcmp(OptionString, "top-left")) 00182 Param->CenteredGrid = 0; 00183 else 00184 { 00185 ErrorMessage("Grid must be either \"centered\" or \"topleft\".\n"); 00186 return 0; 00187 } 00188 break; 00189 00190 #ifdef LIBJPEG_SUPPORT 00191 case 'q': 00192 Param->JpegQuality = atoi(OptionString); 00193 00194 if(Param->JpegQuality <= 0 || Param->JpegQuality > 100) 00195 { 00196 ErrorMessage("JPEG quality must be between 0 and 100.\n"); 00197 return 0; 00198 } 00199 break; 00200 #endif 00201 case '-': 00202 PrintHelpMessage(); 00203 return 0; 00204 default: 00205 if(isprint(OptionChar)) 00206 ErrorMessage("Unknown option \"-%c\".\n", OptionChar); 00207 else 00208 ErrorMessage("Unknown option.\n"); 00209 00210 return 0; 00211 } 00212 00213 i++; 00214 } 00215 else 00216 { 00217 if(!Param->InputFile) 00218 Param->InputFile = argv[i]; 00219 else 00220 Param->OutputFile = argv[i]; 00221 00222 i++; 00223 } 00224 } 00225 00226 if(!Param->InputFile) 00227 { 00228 PrintHelpMessage(); 00229 return 0; 00230 } 00231 00232 return 1; 00233 }