#include #include #include #include #include #include #include #include #include #include extern "C" { #include } #include "OutputOptions.h" #include "GFile_TIFF.h" #include "GFile_JPEG.h" /* Program to convert .kdc images to .tif or .jpg format. The name of the * binary and/or the name of the output file are used to determine what * image format the output file will be in. * * Written by: Chris Studholme * Last Update: 6-Dec-2003 * Copyright: GPL (http://www.fsf.org/copyleft/gpl.html) */ //#define __SHOW_WHITE_BALANCE // global variables #define TO_TIFF_PROGNAME1 "kdc2tiff" #define TO_TIFF_PROGNAME2 "kdc2tif" #define TO_JPEG_PROGNAME1 "kdc2jpeg" #define TO_JPEG_PROGNAME2 "kdc2jpg" #define TO_TIFF_EXT1 ".tiff" #define TO_TIFF_EXT2 ".tif" #define TO_JPEG_EXT1 ".jpeg" #define TO_JPEG_EXT2 ".jpg" const char* progname=0; bool FileExists(const char* path) { struct stat sbuf; if (stat(path,&sbuf)==0) return true; if (errno==ENOENT) return false; fprintf(stderr,"error checking for file %s\n",path); exit(1); } TIFF* CreateTiffFile(OutputOptions& options) { TIFF* tiffimage = TIFFOpen(options.outputname,"w"); TIFFSetField(tiffimage,TIFFTAG_IMAGEWIDTH,(uint32)options.outputwidth); TIFFSetField(tiffimage,TIFFTAG_IMAGELENGTH,(uint32)options.outputheight); TIFFSetField(tiffimage,TIFFTAG_BITSPERSAMPLE,(uint16)8); TIFFSetField(tiffimage,TIFFTAG_SAMPLESPERPIXEL,(uint16)3); TIFFSetField(tiffimage,TIFFTAG_PHOTOMETRIC,PHOTOMETRIC_RGB); TIFFSetField(tiffimage,TIFFTAG_ORIENTATION,ORIENTATION_TOPLEFT); TIFFSetField(tiffimage,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG); TIFFSetField(tiffimage,TIFFTAG_FILLORDER,FILLORDER_LSB2MSB); // this is not correct, should use options.compresstype TIFFSetField(tiffimage,TIFFTAG_COMPRESSION,COMPRESSION_NONE); if (options.rowsperstrip==0) { options.rowsperstrip=8192/3/options.outputwidth; if (options.rowsperstrip<1) options.rowsperstrip=1; } TIFFSetField(tiffimage,TIFFTAG_ROWSPERSTRIP,(uint32)options.rowsperstrip); TIFFSetField(tiffimage,TIFFTAG_RESOLUTIONUNIT,RESUNIT_CENTIMETER); // print approx. 20cm x 15cm TIFFSetField(tiffimage,TIFFTAG_XRESOLUTION,(float)options.outputwidth/20); TIFFSetField(tiffimage,TIFFTAG_YRESOLUTION,(float)options.outputwidth/20); if (options.kdcfile) { if (options.kdcfile->ImageDescription!=NULL) TIFFSetField(tiffimage,TIFFTAG_DOCUMENTNAME, options.kdcfile->ImageDescription); if (options.kdcfile->DateTime!=NULL) TIFFSetField(tiffimage,TIFFTAG_DATETIME,options.kdcfile->DateTime); if (options.kdcfile->Make!=NULL) TIFFSetField(tiffimage,TIFFTAG_MAKE,options.kdcfile->Make); if (options.kdcfile->Model!=NULL) TIFFSetField(tiffimage,TIFFTAG_MODEL,options.kdcfile->Model); } // if (options.copyright!=NULL) // TIFFSetField(tiffimage,TIFFTAG_COPYRIGHT,options.copyright); // TIFFTAG_ARTIST 315 /* creator of image */ // TIFFTAG_HOSTCOMPUTER 316 /* machine where created */ // TIFFTAG_IMAGEDESCRIPTION 270 /* info about image */ // TIFFTAG_SOFTWARE 305 /* name & release */ return tiffimage; } void WriteTiffImage(OutputOptions& options) { TIFF* tiffimage = CreateTiffFile(options); unsigned char rgb[options.outputwidth*3]; #ifdef __SHOW_WHITE_BALANCE unsigned long rmean=0; unsigned long gmean=0; unsigned long bmean=0; #endif // create image for (int y=0; yDateTime?strlen(options.kdcfile->DateTime):0) + (options.kdcfile->Model?strlen(options.kdcfile->Model):0) + (options.copyright?strlen(options.copyright):0); char* comment_text = new char[len_needed]; *comment_text=0; if (options.kdcfile->Model) { strcat(comment_text,"Model: "); strcat(comment_text,options.kdcfile->Model); strcat(comment_text,"\n"); } if (options.kdcfile->DateTime) { strcat(comment_text,"DateTime: "); strcat(comment_text,options.kdcfile->DateTime); } if (options.copyright) { strcat(comment_text,"\n"); strcat(comment_text,"Copyright: "); strcat(comment_text,options.copyright); } jpeg_write_marker(&cinfo, JPEG_COM, (const JOCTET*) comment_text, strlen(comment_text)); } unsigned char rgb[options.outputwidth*3]; JSAMPROW row_pointer[1]; row_pointer[0] = rgb; // create image for (int y=0; y0) { options.outputname = *argv++; --argc; } return argv; } main (int argc, char*argv[]) { // set program name progname = *argv++; --argc; if (strrchr(progname,'/')!=NULL) progname=strrchr(progname,'/')+1; // global options OutputOptions globaloptions; argv = ParseGlobalOptions(globaloptions, argc, argv); if (argv==0) { Usage(); return 1; } // read a little input file to figure out what it is FILE* input = fopen(globaloptions.inputname,"r"); if (input==NULL) { fprintf(stderr,"failed to open input file %s\n",globaloptions.inputname); return 1; } const char* inputfile = strrchr(globaloptions.inputname,'/'); inputfile = inputfile ? ++inputfile : globaloptions.inputname; // check file type if (GFile_JPEG::supportsFile(input)) { fprintf(stderr,"Reading JPEG file %s...\n",inputfile); globaloptions.srcimage = new GFile_JPEG(globaloptions.inputname,globaloptions.fastdebayer); } else if (GFile_TIFF::supportsFile(input)) { // check for DC120 file if (GFile_DC120::supportsFile(input)) { KDCFile* kdcfile = new KDCFile(globaloptions.inputname); if (!kdcfile->isOK()) { fprintf(stderr,"error reading input file %s\n",globaloptions.inputname); return 1; } fprintf(stderr,"Reading KDC file %s from DC120...\n",inputfile); fprintf(stderr," Description: %s\n",kdcfile->ImageDescription); fprintf(stderr," DateTime: %s\n",kdcfile->DateTime); fprintf(stderr," Make: %s\n",kdcfile->Make); fprintf(stderr," Model: %s\n",kdcfile->Model); fprintf(stderr," Software: %s\n",kdcfile->Software); globaloptions.kdcfile = kdcfile; globaloptions.srcimage = new GFile_DC120(*kdcfile,globaloptions.fastdebayer); } // standard TIFF file else { fprintf(stderr,"Reading TIFF file %s...\n",inputfile); globaloptions.srcimage = new GFile_TIFF(globaloptions.inputname,globaloptions.fastdebayer); } } else { fprintf(stderr,"unrecognized image format\n"); fclose(input); return 1; } fclose(input); if (!globaloptions.srcimage->isOK()) { fprintf(stderr,"error reading input file %s\n",globaloptions.inputname); return 1; } // grain reduction messes with the source image (hence: global only option) if (globaloptions.grainreduction) { bool extra=globaloptions.grainreduction>1; fprintf(stderr,"Reducing image graininess%s... ",extra?" (extra)":""); int count = globaloptions.srcimage->ReduceGrain(extra); int totalpixels = globaloptions.srcimage->getWidth()*globaloptions.srcimage->getHeight(); fprintf(stderr,"%.1f%% grain... done.\n",((float)count*100)/totalpixels); } // parse local options and write output files do { fprintf(stderr,"\n"); OutputOptions options(globaloptions); argv = ParseLocalOptions(options, argc, argv); if (argv==0) { Usage(); return 1; } const char* outputextension = options.outputname ? strrchr(options.outputname,'.') : 0; // figure out if we are to output TIFF or JPEG if ((strcasecmp(progname,TO_TIFF_PROGNAME1)==0)|| (strcasecmp(progname,TO_TIFF_PROGNAME2)==0)) options.outputtiff=true; else if ((strcasecmp(progname,TO_JPEG_PROGNAME1)==0)|| (strcasecmp(progname,TO_JPEG_PROGNAME2)==0)) options.outputjpeg=true; else if ((outputextension)&& ((strcasecmp(outputextension,TO_TIFF_EXT1)==0)|| (strcasecmp(outputextension,TO_TIFF_EXT2)==0))) options.outputtiff=true; else if ((outputextension)&& ((strcasecmp(outputextension,TO_JPEG_EXT1)==0)|| (strcasecmp(outputextension,TO_JPEG_EXT2)==0))) options.outputjpeg=true; else if ((options.compresstype)||(options.rowsperstrip)) options.outputtiff=true; else if (options.quality!=DEFAULT_JPEG_QUALITY) options.outputjpeg=true; else { fprintf(stderr,"\nCannot figure out whether to write a TIFF or JPEG. Please name the binary\none of: %s, %s, %s or %s;",TO_TIFF_PROGNAME1,TO_TIFF_PROGNAME2,TO_JPEG_PROGNAME1,TO_JPEG_PROGNAME2); fprintf(stderr," set an output filename with\nan extension of one of: %s, %s, %s or %s; or set a TIFF specific\nor JPEG specific option.\n\n",TO_TIFF_EXT1,TO_TIFF_EXT2,TO_JPEG_EXT1,TO_JPEG_EXT2); return 1; } options.SetOutputParameters(); options.SetOutputFilename(); const char* outputfile = strrchr(options.outputname,'/'); outputfile = outputfile ? ++outputfile : options.outputname; // do not overwrite destination unless "-o" was specified if (!options.overwrite && FileExists(options.outputname)) { fprintf(stderr,"NO OUTPUT WRITTEN!\n"); fprintf(stderr,"output file '%s' exists and -o not specified\n", options.outputname); continue; } // write output image if (options.outputtiff) { fprintf(stderr,"Writing TIFF file %s... ",outputfile); WriteTiffImage(options); fprintf(stderr,"done.\n"); } else if (options.outputjpeg) { fprintf(stderr,"Writing JPEG file %s... ",outputfile); WriteJpegImage(options); fprintf(stderr,"done.\n"); } else fprintf(stderr,"NO OUTPUT WRITTEN!\n"); } while (argc>0); // clean up delete globaloptions.srcimage; delete globaloptions.kdcfile; return 0; }