Malvar-He-Cutler Linear Image Demosaicking
|
00001 00022 #include <math.h> 00023 #include <string.h> 00024 #include <ctype.h> 00025 00026 #include "imageio.h" 00027 #include "dmbilinear.h" 00028 #include "dmmalvar.h" 00029 00030 00032 typedef struct 00033 { 00035 char *InputFile; 00037 char *OutputFile; 00039 int JpegQuality; 00041 int RedX; 00043 int RedY; 00044 } programparams; 00045 00046 00047 static int ParseParams(programparams *Param, int argc, char *argv[]); 00048 00049 00050 static void PrintHelpMessage() 00051 { 00052 printf("Malvar-He-Cutler demosaicing demo, P. Getreuer 2010-2011\n\n"); 00053 printf("Usage: dmmalvar [options] <input file> <output file>\n\n" 00054 "Only " READIMAGE_FORMATS_SUPPORTED " images are supported.\n\n"); 00055 printf("Options:\n"); 00056 printf(" -p <pattern> CFA pattern, choices for <pattern> are\n"); 00057 printf(" RGGB upperleftmost red pixel is at (0,0)\n"); 00058 printf(" GRBG upperleftmost red pixel is at (1,0)\n"); 00059 printf(" GBRG upperleftmost red pixel is at (0,1)\n"); 00060 printf(" BGGR upperleftmost red pixel is at (1,1)\n"); 00061 #ifdef LIBJPEG_SUPPORT 00062 printf(" -q <number> Quality for saving JPEG images (0 to 100)\n\n"); 00063 #endif 00064 printf("Example:\n" 00065 " dmmalvar -p RGGB frog.bmp frog-dm.bmp\n"); 00066 } 00067 00068 00069 int main(int argc, char *argv[]) 00070 { 00071 programparams Param; 00072 float *Input = NULL, *Output = NULL; 00073 int Width, Height, Status = 1; 00074 00075 00076 if(!ParseParams(&Param, argc, argv)) 00077 return 0; 00078 00079 /* Read the input image */ 00080 if(!(Input = (float *)ReadImage(&Width, &Height, 00081 Param.InputFile, IMAGEIO_FLOAT | IMAGEIO_RGB | IMAGEIO_PLANAR))) 00082 goto Catch; 00083 00084 if(Width < 4 || Height < 4) 00085 { 00086 ErrorMessage("Image is too small (%dx%d).\n", Width, Height); 00087 goto Catch; 00088 } 00089 00090 if(!(Output = (float *)Malloc(sizeof(float)*3* 00091 ((long int)Width)*((long int)Height)))) 00092 goto Catch; 00093 00094 /* Flatten the input to a 2D array */ 00095 CfaFlatten(Input, Input, Width, Height, Param.RedX, Param.RedY); 00096 /* Perform demosaicing */ 00097 MalvarDemosaic(Output, Input, Width, Height, Param.RedX, Param.RedY); 00098 00099 /* Write the output image */ 00100 if(!WriteImage(Output, Width, Height, Param.OutputFile, 00101 IMAGEIO_FLOAT | IMAGEIO_RGB | IMAGEIO_PLANAR, Param.JpegQuality)) 00102 goto Catch; 00103 00104 Status = 0; /* Finished successfully, set exit status to zero. */ 00105 Catch: 00106 Free(Output); 00107 Free(Input); 00108 return Status; 00109 } 00110 00111 00112 static int ParseParams(programparams *Param, int argc, char *argv[]) 00113 { 00114 static char *DefaultOutputFile = (char *)"out.bmp"; 00115 char *OptionString; 00116 char OptionChar; 00117 int i; 00118 00119 00120 if(argc < 2) 00121 { 00122 PrintHelpMessage(); 00123 return 0; 00124 } 00125 00126 /* Set parameter defaults */ 00127 Param->InputFile = 0; 00128 Param->OutputFile = DefaultOutputFile; 00129 Param->JpegQuality = 80; 00130 Param->RedX = 0; 00131 Param->RedY = 0; 00132 00133 for(i = 1; i < argc;) 00134 { 00135 if(argv[i] && argv[i][0] == '-') 00136 { 00137 if((OptionChar = argv[i][1]) == 0) 00138 { 00139 ErrorMessage("Invalid parameter format.\n"); 00140 return 0; 00141 } 00142 00143 if(argv[i][2]) 00144 OptionString = &argv[i][2]; 00145 else if(++i < argc) 00146 OptionString = argv[i]; 00147 else 00148 { 00149 ErrorMessage("Invalid parameter format.\n"); 00150 return 0; 00151 } 00152 00153 switch(OptionChar) 00154 { 00155 case 'p': 00156 if(!strcmp(OptionString, "RGGB") 00157 || !strcmp(OptionString, "rggb")) 00158 { 00159 Param->RedX = 0; 00160 Param->RedY = 0; 00161 } 00162 else if(!strcmp(OptionString, "GRBG") 00163 || !strcmp(OptionString, "grbg")) 00164 { 00165 Param->RedX = 1; 00166 Param->RedY = 0; 00167 } 00168 else if(!strcmp(OptionString, "GBRG") 00169 || !strcmp(OptionString, "gbrg")) 00170 { 00171 Param->RedX = 0; 00172 Param->RedY = 1; 00173 } 00174 else if(!strcmp(OptionString, "BGGR") 00175 || !strcmp(OptionString, "bggr")) 00176 { 00177 Param->RedX = 1; 00178 Param->RedY = 1; 00179 } 00180 else 00181 ErrorMessage("CFA pattern must be RGGB, GRBG, GBRG, or BGGR\n"); 00182 break; 00183 #ifdef LIBJPEG_SUPPORT 00184 case 'q': 00185 Param->JpegQuality = atoi(OptionString); 00186 00187 if(Param->JpegQuality <= 0 || Param->JpegQuality > 100) 00188 { 00189 ErrorMessage("JPEG quality must be between 0 and 100.\n"); 00190 return 0; 00191 } 00192 break; 00193 #endif 00194 case '-': 00195 PrintHelpMessage(); 00196 return 0; 00197 default: 00198 if(isprint(OptionChar)) 00199 ErrorMessage("Unknown option \"-%c\".\n", OptionChar); 00200 else 00201 ErrorMessage("Unknown option.\n"); 00202 00203 return 0; 00204 } 00205 00206 i++; 00207 } 00208 else 00209 { 00210 if(!Param->InputFile) 00211 Param->InputFile = argv[i]; 00212 else 00213 Param->OutputFile = argv[i]; 00214 00215 i++; 00216 } 00217 } 00218 00219 if(!Param->InputFile) 00220 { 00221 PrintHelpMessage(); 00222 return 0; 00223 } 00224 00225 return 1; 00226 }